X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=sys-x11.c;h=adb4eae71d8270c5de1883749b8fbeaac11fab60;hb=a3a2c5e71711482dfce333a6a8b5724f3c5f84bf;hp=1da24dd9e17ab204ce5579cb4b0992eb9cd3f559;hpb=8c12aa9eade6ed7a1f56e8512fcd25eb26f40c8c;p=wmpus diff --git a/sys-x11.c b/sys-x11.c index 1da24dd..adb4eae 100644 --- a/sys-x11.c +++ b/sys-x11.c @@ -40,7 +40,6 @@ struct win_sys { struct { int left, right, top, bottom; } strut; - state_t state; }; typedef struct { @@ -51,6 +50,7 @@ typedef struct { typedef enum { WM_PROTO, WM_FOCUS, WM_DELETE, NET_STATE, NET_FULL, NET_STRUT, + NET_TYPE, NET_DIALOG, NATOMS } atom_t; @@ -210,8 +210,12 @@ static int strut_del(win_t *root, win_t *win) } /* Window functions */ +static Atom win_prop(win_t *win, atom_t prop); +static win_t *win_find(Display *dpy, Window xid, int create); + static win_t *win_new(Display *dpy, Window xid) { + Window trans; XWindowAttributes attr; if (XGetWindowAttributes(dpy, xid, &attr)) if (attr.override_redirect) @@ -224,9 +228,14 @@ static win_t *win_new(Display *dpy, Window xid) win->sys = new0(win_sys_t); win->sys->dpy = dpy; win->sys->xid = xid; - printf("win_new: %p = %p, %d (%d,%d %dx%d)\n", + if (win_prop(win, NET_TYPE) == atoms[NET_DIALOG]) + win->type = TYPE_DIALOG; + if (XGetTransientForHint(dpy, xid, &trans)) + win->parent = win_find(dpy, trans, 0); + printf("win_new: %p = %p, %d (%d,%d %dx%d) - %s\n", win, dpy, (int)xid, - win->x, win->y, win->w, win->h); + win->x, win->y, win->w, win->h, + win->type ? "dialog" : "normal"); return win; } @@ -300,27 +309,19 @@ static int win_msg(win_t *win, atom_t msg) return 1; } -#if 0 -static int win_full(win_t *win) +static Atom win_prop(win_t *win, atom_t prop) { - Atom ret_type; - int ret_size; - unsigned long ret_items, bytes_left; - unsigned char *xdata; - int status = XGetWindowProperty(win->sys->dpy, win->sys->xid, - atoms[NET_FULL], 0L, 1L, False, XA_ATOM, - &ret_type, &ret_size, &ret_items, &bytes_left, &xdata); - printf("is_fullscreen:\n"); - printf("\t%d\n", status); - printf("\t%d\n", ret_size); - printf("\t%ld\n", ret_items); - printf("\t%p\n", xdata); - if (xdata) - printf("\t%d\n", xdata[0]); - return status == Success && ret_size == 32 && ret_items == 1 && - xdata[0] == atoms[NET_FULL]; -} -#endif + int format; + unsigned long nitems, bytes; + unsigned char *buf = NULL; + Atom atom, type = XA_ATOM; + if (XGetWindowProperty(win->sys->dpy, win->sys->xid, atoms[prop], + 0L, sizeof(Atom), False, type, &type, &format, &nitems, &bytes, &buf) || !buf) + return 0; + atom = *(Atom *)buf; + XFree(buf); + return atom; +} /* Drawing functions */ static unsigned long get_color(Display *dpy, const char *name) @@ -400,12 +401,12 @@ static void process_event(int type, XEvent *xe, win_t *root) } else if (type == UnmapNotify) { if ((win = win_find(dpy,xe->xunmap.window,0)) && - win->sys->state != ST_HIDE) { + win->state != ST_HIDE) { if (!strut_del(root, win)) wm_remove(win); else wm_update(); - win->sys->state = ST_HIDE; + win->state = ST_HIDE; } } else if (type == DestroyNotify) { @@ -418,7 +419,7 @@ static void process_event(int type, XEvent *xe, win_t *root) printf("configure_req: %d - %x, (0x%lx) %dx%d @ %d,%d\n", type, (int)cre->window, cre->value_mask, cre->height, cre->width, cre->x, cre->y); - if ((win = win_find(dpy,xe->xmaprequest.window,1))) { + if ((win = win_find(dpy,xe->xconfigurerequest.window,1))) { XSendEvent(dpy, cre->window, False, StructureNotifyMask, &(XEvent){ .xconfigure.type = ConfigureNotify, .xconfigure.display = win->sys->dpy, @@ -435,14 +436,17 @@ static void process_event(int type, XEvent *xe, win_t *root) } else if (type == MapRequest) { printf("map_req: %d\n", type); - if ((win = win_find(dpy,xe->xmaprequest.window,1))) { + if ((win = win_find(dpy,xe->xmaprequest.window,1)) && + win->state == ST_HIDE) { + if (win_prop(win, NET_STATE) == atoms[NET_FULL]) + win->state = ST_FULL; XSelectInput(win->sys->dpy, win->sys->xid, PropertyChangeMask); if (!strut_add(root, win)) wm_insert(win); else wm_update(); - } - XMapWindow(dpy, xe->xmaprequest.window); + } else + sys_show(win, ST_SHOW); } else if (type == ClientMessage) { XClientMessageEvent *cme = &xe->xclient; @@ -454,12 +458,11 @@ static void process_event(int type, XEvent *xe, win_t *root) (cme->message_type == atoms[NET_STATE]) && (cme->data.l[1] == atoms[NET_FULL] || cme->data.l[2] == atoms[NET_FULL])) { - if (cme->data.l[0] == 1 || /* _NET_WM_STATE_ADD */ - (cme->data.l[0] == 2 && /* _NET_WM_STATE_TOGGLE */ - win->sys->state != ST_FULL)) - sys_show(win, ST_FULL); - else - sys_show(win, ST_SHOW); + state_t next = (cme->data.l[0] == 1 || /* _NET_WM_STATE_ADD */ + (cme->data.l[0] == 2 && /* _NET_WM_STATE_TOGGLE */ + win->state != ST_FULL)) ? ST_FULL : ST_SHOW; + wm_handle_state(win, win->state, next); + sys_show(win, next); } } else if (type == PropertyNotify) { @@ -543,16 +546,24 @@ void sys_focus(win_t *win) void sys_show(win_t *win, state_t state) { switch (state) { + case ST_HIDE: + printf("sys_show: hide %p\n", win); + XUnmapWindow(win->sys->dpy, win->sys->xid); + break; case ST_SHOW: - printf("sys_show: show\n"); - if (win->sys->state == ST_FULL) + printf("sys_show: show %p\n", win); + if (win->state == ST_FULL) sys_move(win, win->x, win->y, win->w, win->h); XSetWindowBorderWidth(win->sys->dpy, win->sys->xid, border); XMapWindow(win->sys->dpy, win->sys->xid); XSync(win->sys->dpy, False); break; + case ST_MAX: + printf("sys_show: max %p\n", win); + XMapWindow(win->sys->dpy, win->sys->xid); + break; case ST_FULL: - printf("sys_show: full\n"); + printf("sys_show: full %p\n", win); win_t *screen = NULL; for (list_t *cur = screens; cur; cur = cur->next) { screen = cur->data; @@ -570,18 +581,14 @@ void sys_show(win_t *win, state_t state) XRaiseWindow(win->sys->dpy, win->sys->xid); break; case ST_SHADE: - printf("sys_show: shade\n"); + printf("sys_show: shade %p\n", win); XMapWindow(win->sys->dpy, win->sys->xid); break; case ST_ICON: - printf("sys_show: icon\n"); - break; - case ST_HIDE: - printf("sys_show: hide\n"); - XUnmapWindow(win->sys->dpy, win->sys->xid); + printf("sys_show: icon %p\n", win); break; case ST_CLOSE: - printf("sys_show: close\n"); + printf("sys_show: close %p\n", win); if (!win_msg(win, WM_DELETE)) { XGrabServer(win->sys->dpy); XSetErrorHandler(xnoerror); @@ -594,7 +601,7 @@ void sys_show(win_t *win, state_t state) XDestroyWindow(win->sys->dpy, win->sys->xid); break; } - win->sys->state = state; + win->state = state; } void sys_watch(win_t *win, event_t ev, mod_t mod) @@ -668,12 +675,14 @@ win_t *sys_init(void) error("Unable to get root window"); /* Setup X11 data */ - atoms[WM_PROTO] = XInternAtom(dpy, "WM_PROTOCOLS", False); - atoms[WM_FOCUS] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); - atoms[WM_DELETE] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - atoms[NET_STATE] = XInternAtom(dpy, "_NET_WM_STATE", False); - atoms[NET_FULL] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); - atoms[NET_STRUT] = XInternAtom(dpy, "_NET_WM_STRUT", False); + atoms[WM_PROTO] = XInternAtom(dpy, "WM_PROTOCOLS", False); + atoms[WM_FOCUS] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); + atoms[WM_DELETE] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + atoms[NET_STATE] = XInternAtom(dpy, "_NET_WM_STATE", False); + atoms[NET_FULL] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); + atoms[NET_STRUT] = XInternAtom(dpy, "_NET_WM_STRUT", False); + atoms[NET_TYPE] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); + atoms[NET_DIALOG] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); colors[CLR_FOCUS] = get_color(dpy, "#a0a0ff"); colors[CLR_UNFOCUS] = get_color(dpy, "#101066");