diff --git a/src/client.c b/src/client.c index 80764f3..7c629be 100644 --- a/src/client.c +++ b/src/client.c @@ -982,9 +982,10 @@ client_moveresize(struct client *c, struct geo *g) c->rgeo.x, c->rgeo.y, c->rgeo.w, c->rgeo.h); - XMoveResizeWindow(W->dpy, c->win, - c->wgeo.x, c->wgeo.y, - c->wgeo.w, c->wgeo.h); + if(!(c->flags & CLIENT_FULLSCREEN)) + XMoveResizeWindow(W->dpy, c->win, + c->wgeo.x, c->wgeo.y, + c->wgeo.w, c->wgeo.h); c->flags &= ~CLIENT_DID_WINSIZE; diff --git a/src/client.h b/src/client.h index 8cc3f92..e65a09d 100644 --- a/src/client.h +++ b/src/client.h @@ -102,6 +102,7 @@ client_map(struct client *c) if(!(c->flags & CLIENT_MAPPED)) { WIN_STATE(c->frame, Map); + WIN_STATE(c->win, Map); ewmh_set_wm_state(c->win, NormalState); c->flags ^= CLIENT_MAPPED; } @@ -113,6 +114,7 @@ client_unmap(struct client *c) if(c->flags & CLIENT_MAPPED) { WIN_STATE(c->frame, Unmap); + WIN_STATE(c->win, Unmap); ewmh_set_wm_state(c->win, IconicState); c->flags ^= CLIENT_MAPPED; } diff --git a/src/event.c b/src/event.c index 2fae263..57e1ac2 100644 --- a/src/event.c +++ b/src/event.c @@ -59,9 +59,29 @@ event_enternotify(XEvent *e) static void event_clientmessageevent(XEvent *e) { - (void)e; - /* XClientMessageEvent *ev = &e->xclient; - client *c;*/ + XClientMessageEvent *ev = &e->xclient; + struct client *c; + int type = 0; + + while(type < net_last && W->net_atom[type] != ev->message_type) + ++type; + + switch(type) + { + /* _NET_WM_STATE */ + case net_wm_state: + if((c = client_gb_win(ev->window))) + ewmh_manage_state(ev->data.l, c); + break; + /* _NET_CLOSE_WINDOW */ + case net_close_window: + if((c = client_gb_win(ev->window))) + client_close(c); + break; + /* _NET_WM_DESKTOP */ + case net_wm_desktop: + break; + } } static void diff --git a/src/ewmh.c b/src/ewmh.c index 0a221fa..0439219 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -6,6 +6,12 @@ #include "ewmh.h" #include "util.h" #include "screen.h" +#include "client.h" + +/* Taken From standards.freedesktop.org */ +#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ +#define _NET_WM_STATE_ADD 1 /* add/set property */ +#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ void ewmh_init(void) @@ -112,10 +118,11 @@ ewmh_update_wmfs_props(void) cts = xcalloc(ns, sizeof(long)); + for(i = 0; i < ns; ++i) { s = screen_gb_id(i); - cts[i] = s->seltag->id; + cts[i] = (s->seltag ? s->seltag->id : 0); } XChangeProperty(W->dpy, W->root, W->net_atom[wmfs_current_tag], XA_CARDINAL, 32, @@ -128,3 +135,32 @@ ewmh_update_wmfs_props(void) free(cts); } +void +ewmh_manage_state(long data[], struct client *c) +{ + /* _NET_WM_STATE_FULLSCREEN */ + if(data[1] == (long)W->net_atom[net_wm_state_fullscreen]) + { + if(data[0] == _NET_WM_STATE_ADD + || (data[0] == _NET_WM_STATE_TOGGLE && !(c->flags & CLIENT_FULLSCREEN))) + { + c->flags |= CLIENT_FULLSCREEN; + + XReparentWindow(W->dpy, c->win, W->root, c->screen->geo.x, c->screen->geo.y); + XResizeWindow(W->dpy, c->win, c->screen->geo.w, c->screen->geo.h); + + client_focus(c); + + XRaiseWindow(W->dpy, c->win); + } + else if(data[0] == _NET_WM_STATE_REMOVE + || (data[0] == _NET_WM_STATE_TOGGLE && c->flags & CLIENT_FULLSCREEN)) + { + c->flags &= ~CLIENT_FULLSCREEN; + + XReparentWindow(W->dpy, c->win, c->frame, c->wgeo.x, c->wgeo.y); + client_moveresize(c, &c->geo); + } + } +} + diff --git a/src/ewmh.h b/src/ewmh.h index b99409a..da29f3d 100644 --- a/src/ewmh.h +++ b/src/ewmh.h @@ -75,5 +75,6 @@ enum void ewmh_init(void); void ewmh_set_wm_state(Window w, int state); void ewmh_update_wmfs_props(void); +void ewmh_manage_state(long data[], struct client *c); #endif /* EWMH_H */ diff --git a/src/wmfs.h b/src/wmfs.h index 4875b59..fd012b5 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -166,6 +166,7 @@ struct client #define CLIENT_DYING 0x100 /* Saddest flag ever */ #define CLIENT_REMOVEALL 0x200 #define CLIENT_MAPPED 0x400 +#define CLIENT_FULLSCREEN 0x800 Flags flags; Window win, frame, tmp; SLIST_ENTRY(client) next; /* Global list */