X-Git-Url: http://pileus.org/git/?p=wmpus;a=blobdiff_plain;f=sys-x11.c;h=1e35845db4403b101442366696f394f4dbfec301;hp=2120ee07931b427dc4be43c6486655f3c0f73197;hb=b1d6aee69be4c1cfe6c085936620d8c60769c991;hpb=7b1461df6049d172f3c95f3adca510b528c9f390 diff --git a/sys-x11.c b/sys-x11.c index 2120ee0..1e35845 100644 --- a/sys-x11.c +++ b/sys-x11.c @@ -32,6 +32,7 @@ /* Configuration */ static int border = 2; static int no_capture = 0; +static int stack = 25; /* Internal structures */ struct win_sys { @@ -50,6 +51,7 @@ typedef struct { typedef enum { WM_PROTO, WM_FOCUS, WM_DELETE, NET_STATE, NET_FULL, NET_STRUT, + NET_TYPE, NET_DIALOG, NATOMS } atom_t; @@ -58,6 +60,7 @@ typedef enum { } color_t; /* Global data */ +static win_t *root; static int running; static void *cache; static Atom atoms[NATOMS]; @@ -188,10 +191,10 @@ static int strut_add(win_t *root, win_t *win) if (status != Success || ret_size != 32 || ret_items != 4) return 0; - win->sys->strut.left = ((int*)xdata)[0]; - win->sys->strut.right = ((int*)xdata)[1]; - win->sys->strut.top = ((int*)xdata)[2]; - win->sys->strut.bottom = ((int*)xdata)[3]; + win->sys->strut.left = ((long*)xdata)[0]; + win->sys->strut.right = ((long*)xdata)[1]; + win->sys->strut.top = ((long*)xdata)[2]; + win->sys->strut.bottom = ((long*)xdata)[3]; struts = list_insert(struts, win); for (list_t *cur = screens; cur; cur = cur->next) strut_copy(cur->data, win, 1); @@ -209,12 +212,17 @@ 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) return NULL; + win_t *win = new0(win_t); win->x = attr.x; win->y = attr.y; @@ -223,9 +231,33 @@ 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", - win, dpy, (int)xid, - win->x, win->y, win->w, win->h); + + if (root) { + if (strut_add(root, win)) + win->type = TYPE_TOOLBAR; + + if (win_prop(win, NET_TYPE) == atoms[NET_DIALOG]) + win->type = TYPE_DIALOG; + + if (win_prop(win, NET_STATE) == atoms[NET_FULL]) + win->state = ST_FULL; + + if (XGetTransientForHint(dpy, xid, &trans)) + win->parent = win_find(dpy, trans, 0); + + XSelectInput(dpy, xid, PropertyChangeMask); + } + + printf("win_new: win=%p x11=(%p,%d) state=%x pos=(%d,%d %dx%d) type=%s\n", + win, dpy, (int)xid, win->state, + win->x, win->y, win->w, win->h, + win->type == TYPE_NORMAL ? "normal" : + win->type == TYPE_DIALOG ? "dialog" : + win->type == TYPE_TOOLBAR ? "toolbar" : "unknown"); + + if (root) + wm_insert(win); + return win; } @@ -262,14 +294,18 @@ static void win_free(win_t *win) static void win_remove(win_t *win) { + if (win != root) { + strut_del(root, win); + wm_remove(win); + } tdelete(win, &cache, win_cmp); win_free(win); } -static int win_viewable(win_t *win) +static int win_viewable(Display *dpy, Window xid) { XWindowAttributes attr; - if (XGetWindowAttributes(win->sys->dpy, win->sys->xid, &attr)) + if (XGetWindowAttributes(dpy, xid, &attr)) return attr.map_state == IsViewable; else return True; @@ -299,27 +335,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) @@ -354,12 +382,12 @@ static void process_event(int type, XEvent *xe, win_t *root) /* Split based on event */ if (type == KeyPress) { while (XCheckTypedEvent(dpy, KeyPress, xe)); - KeySym sym = XKeycodeToKeysym(dpy, xe->xkey.keycode, 0); - printf("got xe %c %hhx\n", xk2ev(sym), mod2int(mod)); + KeySym sym = XLookupKeysym(&xe->xkey, 0); + //printf("got xe %c %hhx\n", xk2ev(sym), mod2int(mod)); wm_handle_event(win, xk2ev(sym), mod, ptr); } else if (type == KeyRelease) { - //printf("release: %d\n", type); + //printf("release: %lx\n", xe->xkey.window); } else if (type == ButtonPress) { if (wm_handle_event(win, xb2ev(xe->xbutton.button), mod, ptr)) { @@ -380,42 +408,41 @@ static void process_event(int type, XEvent *xe, win_t *root) wm_handle_ptr(win, ptr); } else if (type == EnterNotify || type == LeaveNotify) { - printf("%s: %d\n", type==EnterNotify?"enter":"leave", type); + printf("%s: %lx\n", type==EnterNotify?"enter":"leave", + xe->xcrossing.window); event_t ev = type == EnterNotify ? EV_ENTER : EV_LEAVE; if ((win = win_find(dpy,xe->xcrossing.window,0))) wm_handle_event(win, ev, MOD(), PTR()); } else if (type == FocusIn || type == FocusOut) { - //printf("focus: %d\n", type); - event_t ev = FocusIn ? EV_FOCUS : EV_UNFOCUS; + //printf("focus: %lx\n", xe->xfocus.window); + event_t ev = type == FocusIn ? EV_FOCUS : EV_UNFOCUS; if ((win = win_find(dpy,xe->xfocus.window,0))) wm_handle_event(win, ev, MOD(), PTR()); } else if (type == ConfigureNotify) { - printf("configure: %d\n", type); + //printf("configure: %lx\n", xe->xconfigure.window); } else if (type == MapNotify) { - printf("map: %d\n", type); + printf("map: %lx\n", xe->xmap.window); } else if (type == UnmapNotify) { if ((win = win_find(dpy,xe->xunmap.window,0)) && win->state != ST_HIDE) { - if (!strut_del(root, win)) - wm_remove(win); - else - wm_update(); + printf("unmap: %lx\n", xe->xunmap.window); + wm_handle_state(win, win->state, ST_HIDE); win->state = ST_HIDE; } } else if (type == DestroyNotify) { - //printf("destroy: %d\n", type); + printf("destroy: %lx\n", xe->xdestroywindow.window); if ((win = win_find(dpy,xe->xdestroywindow.window,0))) win_remove(win); } else if (type == ConfigureRequest) { XConfigureRequestEvent *cre = &xe->xconfigurerequest; - printf("configure_req: %d - %x, (0x%lx) %dx%d @ %d,%d\n", - type, (int)cre->window, cre->value_mask, + printf("configure_req: %lx - (0x%lx) %dx%d @ %d,%d\n", + cre->window, cre->value_mask, cre->height, cre->width, cre->x, cre->y); if ((win = win_find(dpy,xe->xconfigurerequest.window,1))) { XSendEvent(dpy, cre->window, False, StructureNotifyMask, &(XEvent){ @@ -433,21 +460,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)) && - win->state == ST_HIDE) { - XSelectInput(win->sys->dpy, win->sys->xid, PropertyChangeMask); - if (!strut_add(root, win)) - wm_insert(win); - else - wm_update(); - } - sys_show(win, ST_SHOW); + printf("map_req: %lx\n", xe->xmaprequest.window); + win = win_find(dpy,xe->xmaprequest.window,1); + // fixme, for hide -> max, etc + if (win->state == ST_HIDE) + win->state = ST_SHOW; + sys_show(win, win->state); } else if (type == ClientMessage) { XClientMessageEvent *cme = &xe->xclient; - printf("msg: %d - %ld %ld,%ld,%ld,%ld,%ld\n", - type, cme->message_type, + printf("client_msg: %lx - %ld %ld,%ld,%ld,%ld,%ld\n", + cme->window, cme->message_type, cme->data.l[0], cme->data.l[1], cme->data.l[2], cme->data.l[3], cme->data.l[4]); if ((win = win_find(dpy,cme->window,0)) && @@ -457,12 +480,13 @@ static void process_event(int type, XEvent *xe, win_t *root) 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; + printf("client_msg: fullscreen %x -> %x", win->state, next); wm_handle_state(win, win->state, next); sys_show(win, next); } } else if (type == PropertyNotify) { - printf("prop: %d - %d\n", type, xe->xproperty.state); + printf("prop: %lx - %d\n", xe->xproperty.window, xe->xproperty.state); } else { printf("unknown event: %d\n", type); @@ -523,7 +547,7 @@ void sys_raise(win_t *win) void sys_focus(win_t *win) { - printf("sys_focus: %p\n", win); + //printf("sys_focus: %p\n", win); /* Set actual focus */ XSetInputFocus(win->sys->dpy, win->sys->xid, @@ -578,6 +602,8 @@ void sys_show(win_t *win, state_t state) break; case ST_SHADE: printf("sys_show: shade %p\n", win); + XConfigureWindow(win->sys->dpy, win->sys->xid, CWHeight, + &(XWindowChanges){ .height = stack }); XMapWindow(win->sys->dpy, win->sys->xid); break; case ST_ICON: @@ -661,6 +687,7 @@ win_t *sys_init(void) Window xid; /* Load configuration */ + stack = conf_get_int("main.stack", stack); border = conf_get_int("main.border", border); no_capture = conf_get_int("main.no-capture", no_capture); @@ -671,12 +698,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"); @@ -687,7 +716,7 @@ win_t *sys_init(void) XSelectInput(dpy, xid, SubstructureRedirectMask|SubstructureNotifyMask); xerrorxlib = XSetErrorHandler(xerror); - return win_find(dpy, xid, 1); + return root = win_find(dpy, xid, 1); } void sys_run(win_t *root) @@ -698,14 +727,11 @@ void sys_run(win_t *root) Window par, xid, *kids = NULL; if (XQueryTree(root->sys->dpy, root->sys->xid, &par, &xid, &kids, &nkids)) { - for(int i = 0; i < nkids; i++) { - win_t *win = win_find(root->sys->dpy, kids[i], 1); - if (win && win_viewable(win) && !strut_add(root,win)) - wm_insert(win); - } + for(int i = 0; i < nkids; i++) + if (win_viewable(root->sys->dpy, kids[i])) + win_find(root->sys->dpy, kids[i], 1); XFree(kids); } - wm_update(); // For struts } /* Main loop */