Merge pull request #53 from linkdd/sticky-window
Fix manage of sticky windows (Closes #52)
This commit is contained in:
commit
59af606147
@ -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;
|
||||||
|
|||||||
@ -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))
|
||||||
|
|||||||
55
src/ewmh.c
55
src/ewmh.c
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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 */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user