Fix manage of sticky windows

This commit is contained in:
David Delassus 2012-05-05 15:42:07 +02:00
parent 643d2a6b26
commit 151dc9f9f1
6 changed files with 54 additions and 13 deletions

View File

@ -972,14 +972,12 @@ client_new(Window w, XWindowAttributes *wa, bool scan)
client_apply_rule(c); client_apply_rule(c);
} }
ewmh_manage_state_sticky(c);
/* /*
* Conf option set per client, for possibility * Conf option set per client, for possibility
* to config only one client * to config only one client
*/ */
c->border = c->theme->client_border_width; 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->tbarw = c->border;
c->ncol = c->theme->client_n; c->ncol = c->theme->client_n;

View File

@ -245,7 +245,8 @@ event_maprequest(XEvent *e)
/* Which windows to manage */ /* Which windows to manage */
if(!XGetWindowAttributes(EVDPY(e), ev->window, &at) if(!XGetWindowAttributes(EVDPY(e), ev->window, &at)
|| at.override_redirect || at.override_redirect
|| ewmh_manage_window_type_desktop(ev->window)) || ewmh_manage_window_type_desktop(ev->window)
|| ewmh_manage_state_sticky(ev->window))
return; return;
if(!client_gb_win(ev->window)) if(!client_gb_win(ev->window))

View File

@ -230,15 +230,16 @@ ewmh_manage_state(long data[], struct client *c)
} }
void bool
ewmh_manage_state_sticky(struct client *c) ewmh_manage_state_sticky(Window win)
{ {
Atom *atom, rf; Atom *atom, rf;
int f; int f;
unsigned long n, il, i; unsigned long n, il, i;
unsigned char *data = NULL; 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) XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
{ {
atom = (Atom*)data; atom = (Atom*)data;
@ -248,17 +249,59 @@ ewmh_manage_state_sticky(struct client *c)
/* manage _NET_WM_STATE_STICKY */ /* manage _NET_WM_STATE_STICKY */
if(atom[i] == W->net_atom[net_wm_state_sticky]) if(atom[i] == W->net_atom[net_wm_state_sticky])
{ {
c->flags |= CLIENT_STICKY; XWindowAttributes at;
c->flags |= CLIENT_FREE;
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; break;
} }
} }
XFree(data); XFree(data);
} }
return is_sticky;
} }
void void

View File

@ -124,7 +124,7 @@ void ewmh_get_client_list(void);
long ewmh_get_xembed_state(Window win); long ewmh_get_xembed_state(Window win);
void ewmh_update_wmfs_props(void); void ewmh_update_wmfs_props(void);
void ewmh_manage_state(long data[], struct client *c); 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); void ewmh_manage_window_type(struct client *c);
bool ewmh_manage_window_type_desktop(Window win); bool ewmh_manage_window_type_desktop(Window win);

View File

@ -631,7 +631,7 @@ layout_client(struct client *c)
return; return;
} }
if(c->flags & (CLIENT_FREE | CLIENT_STICKY)) if(c->flags & CLIENT_FREE)
{ {
layout_split_arrange_closed(c); layout_split_arrange_closed(c);
c->flags ^= CLIENT_TILED; c->flags ^= CLIENT_TILED;

View File

@ -217,7 +217,6 @@ struct client
#define CLIENT_TILED 0x2000 #define CLIENT_TILED 0x2000
#define CLIENT_MOUSE 0x4000 #define CLIENT_MOUSE 0x4000
#define CLIENT_IGNORE_TAG 0x8000 #define CLIENT_IGNORE_TAG 0x8000
#define CLIENT_STICKY 0x10000
Flags flags; Flags flags;
Window win, frame, tmp; Window win, frame, tmp;
SLIST_ENTRY(client) next; /* Global list */ SLIST_ENTRY(client) next; /* Global list */