From 151dc9f9f12464a3d01520752dacac84b6d24e0d Mon Sep 17 00:00:00 2001 From: David Delassus Date: Sat, 5 May 2012 15:42:07 +0200 Subject: [PATCH] Fix manage of sticky windows --- src/client.c | 4 +--- src/event.c | 3 ++- src/ewmh.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++------ src/ewmh.h | 2 +- src/layout.c | 2 +- src/wmfs.h | 1 - 6 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/client.c b/src/client.c index 1ae6e72..f96869a 100644 --- a/src/client.c +++ b/src/client.c @@ -972,14 +972,12 @@ client_new(Window w, XWindowAttributes *wa, bool scan) client_apply_rule(c); } - ewmh_manage_state_sticky(c); - /* * Conf option set per client, for possibility * to config only one client */ c->border = c->theme->client_border_width; - if(!(c->tbarw = c->theme->client_titlebar_width) || (c->flags & CLIENT_STICKY)) + if(!(c->tbarw = c->theme->client_titlebar_width)) c->tbarw = c->border; c->ncol = c->theme->client_n; diff --git a/src/event.c b/src/event.c index ace1ee8..9fb62fe 100644 --- a/src/event.c +++ b/src/event.c @@ -245,7 +245,8 @@ event_maprequest(XEvent *e) /* Which windows to manage */ if(!XGetWindowAttributes(EVDPY(e), ev->window, &at) || at.override_redirect - || ewmh_manage_window_type_desktop(ev->window)) + || ewmh_manage_window_type_desktop(ev->window) + || ewmh_manage_state_sticky(ev->window)) return; if(!client_gb_win(ev->window)) diff --git a/src/ewmh.c b/src/ewmh.c index 417a09f..8666a91 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -230,15 +230,16 @@ ewmh_manage_state(long data[], struct client *c) } -void -ewmh_manage_state_sticky(struct client *c) +bool +ewmh_manage_state_sticky(Window win) { Atom *atom, rf; int f; unsigned long n, il, i; unsigned char *data = NULL; + bool is_sticky = false; - if(XGetWindowProperty(W->dpy, c->win, W->net_atom[net_wm_state], 0L, 0x7FFFFFFFL, false, + if(XGetWindowProperty(W->dpy, win, W->net_atom[net_wm_state], 0L, 0x7FFFFFFFL, false, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n) { atom = (Atom*)data; @@ -248,17 +249,59 @@ ewmh_manage_state_sticky(struct client *c) /* manage _NET_WM_STATE_STICKY */ if(atom[i] == W->net_atom[net_wm_state_sticky]) { - c->flags |= CLIENT_STICKY; - c->flags |= CLIENT_FREE; + XWindowAttributes at; - client_place_at_mouse(c); + XMapWindow(W->dpy, win); + XMapSubwindows(W->dpy, win); + if(XGetWindowAttributes(W->dpy, win, &at)) + { + struct geo g; + + if(at.x < W->screen->ugeo.x) + g.x = W->screen->ugeo.x; + else if((at.x + at.width) > W->screen->ugeo.w) + g.x = W->screen->ugeo.w - at.width; + else + g.x = at.x; + + if(at.y < W->screen->ugeo.y) + g.y = W->screen->ugeo.y; + else if((at.y + at.height) > W->screen->ugeo.h) + g.y = W->screen->ugeo.h - at.height; + else + g.y = at.y; + + XMoveWindow(W->dpy, win, g.x, g.y); + } + + if(W->client) + { + XUngrabButton(W->dpy, AnyButton, AnyModifier, W->client->win); + XGrabButton(W->dpy, AnyButton, AnyModifier, W->client->win, False, + ButtonMask, GrabModeAsync, GrabModeSync, None, None); + + client_frame_update(W->client, &W->client->ncol); + + W->client = NULL; + } + + + XRaiseWindow(W->dpy, win); + + XSetInputFocus(W->dpy, win, RevertToPointerRoot, CurrentTime); + XChangeProperty(W->dpy, W->root, W->net_atom[net_active_window], XA_WINDOW, 32, + PropModeReplace, (unsigned char *)&win, 1); + + is_sticky = true; break; } } XFree(data); } + + return is_sticky; } void diff --git a/src/ewmh.h b/src/ewmh.h index 9f8c958..885ee35 100644 --- a/src/ewmh.h +++ b/src/ewmh.h @@ -124,7 +124,7 @@ void ewmh_get_client_list(void); long ewmh_get_xembed_state(Window win); void ewmh_update_wmfs_props(void); void ewmh_manage_state(long data[], struct client *c); -void ewmh_manage_state_sticky(struct client *c); +bool ewmh_manage_state_sticky(Window win); void ewmh_manage_window_type(struct client *c); bool ewmh_manage_window_type_desktop(Window win); diff --git a/src/layout.c b/src/layout.c index 3d92dae..b73cea6 100644 --- a/src/layout.c +++ b/src/layout.c @@ -631,7 +631,7 @@ layout_client(struct client *c) return; } - if(c->flags & (CLIENT_FREE | CLIENT_STICKY)) + if(c->flags & CLIENT_FREE) { layout_split_arrange_closed(c); c->flags ^= CLIENT_TILED; diff --git a/src/wmfs.h b/src/wmfs.h index 6479387..d754f78 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -217,7 +217,6 @@ struct client #define CLIENT_TILED 0x2000 #define CLIENT_MOUSE 0x4000 #define CLIENT_IGNORE_TAG 0x8000 -#define CLIENT_STICKY 0x10000 Flags flags; Window win, frame, tmp; SLIST_ENTRY(client) next; /* Global list */