New feature: EWMH Support ! #1

This commit is contained in:
Martin Duquesnoy 2008-12-14 15:43:21 +01:00
parent 199a148689
commit f8d1049240
17 changed files with 410 additions and 107 deletions

View File

@ -33,6 +33,7 @@ set(wmfs_src
src/config.c
src/draw.c
src/event.c
src/ewmh.c
src/frame.c
src/infobar.c
src/init.c

View File

@ -68,10 +68,10 @@ barwin_create(Window parent,
at.event_mask |= EnterWindowMask|LeaveWindowMask|FocusChangeMask;
/* Create window */
bw->win = XCreateWindow(dpy, parent, x, y, w, h, 0, DefaultDepth(dpy, screen),
CopyFromParent, DefaultVisual(dpy, screen),
bw->win = XCreateWindow(dpy, parent, x, y, w, h, 0, DefaultDepth(dpy, SCREEN),
CopyFromParent, DefaultVisual(dpy, SCREEN),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &at);
bw->dr = XCreatePixmap(dpy, parent, w, h, DefaultDepth(dpy, screen));
bw->dr = XCreatePixmap(dpy, parent, w, h, DefaultDepth(dpy, SCREEN));
/* His border */
CWIN(bw->border.left, bw->win, 0, 0, SHADH, h, 0, CWBackPixel, color_enlight(color), &at);
@ -211,7 +211,7 @@ barwin_resize(BarWindow *bw, uint w, uint h)
XFreePixmap(dpy, bw->dr);
/* Frame */
bw->dr = XCreatePixmap(dpy, root, w - SHADH, h - SHADH, DefaultDepth(dpy, screen));
bw->dr = XCreatePixmap(dpy, ROOT, w - SHADH, h - SHADH, DefaultDepth(dpy, SCREEN));
XResizeWindow(dpy, bw->win, w, h);
/* Border */

View File

@ -161,7 +161,7 @@ client_focus(Client *c)
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
}
else
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
XSetInputFocus(dpy, ROOT, RevertToPointerRoot, CurrentTime);
return;
}
@ -369,7 +369,7 @@ client_manage(Window w, XWindowAttributes *wa)
uint duint;
Window dw;
XQueryPointer(dpy, root, &dw, &dw, &mx, &my, &dint, &dint, &duint);
XQueryPointer(dpy, ROOT, &dw, &dw, &mx, &my, &dint, &dint, &duint);
mx += BORDH;
my += TBARH;
@ -393,12 +393,11 @@ client_manage(Window w, XWindowAttributes *wa)
my += sgeo[selscreen].y - TBARH - INFOBARH;
}
}
c->ogeo.x = c->geo.x = mx;
c->ogeo.y = c->geo.y = my;
c->ogeo.width = c->geo.width = wa->width;
c->ogeo.height = c->geo.height = wa->height;
c->tag = seltag[c->screen];
at.event_mask = PropertyChangeMask;
@ -419,6 +418,7 @@ client_manage(Window w, XWindowAttributes *wa)
client_raise(c);
client_focus(c);
setwinstate(c->win, NormalState);
ewmh_manage_window_type(c);
arrange();
return;
@ -487,7 +487,7 @@ client_moveresize(Client *c, XRectangle geo, bool r)
|| c->geo.width != geo.width
|| c->geo.height != geo.height)
{
c->geo = geo;
c->geo = c->ogeo = geo;
/* Set the client screen */
c->screen = screen_get_with_geo(geo.x, geo.y);
@ -501,6 +501,38 @@ client_moveresize(Client *c, XRectangle geo, bool r)
return;
}
/** Maximize a client
* \param c Client pointer
*/
void
client_maximize(Client *c)
{
CHECK(c);
XRectangle geo;
c->screen = screen_get_with_geo(c->geo.x, c->geo.y);
geo.x = sgeo[c->screen].x;
geo.y = sgeo[c->screen].y;
geo.width = sgeo[c->screen].width - BORDH * 2;
geo.height = sgeo[c->screen].height - BORDH * 2;
if(c->state_fullscreen)
{
geo.y -= TBARH + INFOBARH + BORDH;
geo.height += TBARH + INFOBARH + (BORDH * 2);
client_moveresize(c, geo, False);
XMoveResizeWindow(dpy, c->win, 0, BORDH + TBARH, c->geo.width + BORDH * 2, c->geo.height);
}
else
client_moveresize(c, geo, False);
client_raise(c);
return;
}
/** Get client size hints
* \param c Client pointer
*/
@ -580,7 +612,7 @@ client_size_hints(Client *c)
void
client_raise(Client *c)
{
if(!c || c->max || c->tile)
if(!c || c->tile)
return;
XRaiseWindow(dpy, c->frame);
@ -622,7 +654,7 @@ client_unmanage(Client *c)
{
XGrabServer(dpy);
XSetErrorHandler(errorhandlerdummy);
XReparentWindow(dpy, c->win, root, c->geo.x, c->geo.y);
XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
if(sel == c)
client_focus(NULL);

View File

@ -47,17 +47,17 @@ draw_text(Drawable d, int x, int y, char* fg, int pad, char *str)
XftDraw *xftd;
/* Transform X Drawable -> Xft Drawable */
xftd = XftDrawCreate(dpy, d, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen));
xftd = XftDrawCreate(dpy, d, DefaultVisual(dpy, SCREEN), DefaultColormap(dpy, SCREEN));
/* Alloc text color */
XftColorAllocName(dpy, DefaultVisual(dpy, screen),
DefaultColormap(dpy, screen), fg, &xftcolor);
XftColorAllocName(dpy, DefaultVisual(dpy, SCREEN),
DefaultColormap(dpy, SCREEN), fg, &xftcolor);
/* Draw the text */
XftDrawStringUtf8(xftd, &xftcolor, font, x, y, (FcChar8 *)str, strlen(str));
/* Free the text color and XftDraw */
XftColorFree(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), &xftcolor);
XftColorFree(dpy, DefaultVisual(dpy, SCREEN), DefaultColormap(dpy, SCREEN), &xftcolor);
XftDrawDestroy(xftd);

View File

@ -63,7 +63,7 @@ buttonpress(XButtonEvent *ev)
conf.client.mouse[i].func(conf.client.mouse[i].cmd);
/* Root */
if(ev->window == root)
if(ev->window == ROOT)
for(i = 0; i < conf.root.nmouse; ++i)
if(conf.root.mouse[i].tag == seltag[conf.root.mouse[i].screen]
|| conf.root.mouse[i].tag < 0)
@ -102,6 +102,45 @@ buttonpress(XButtonEvent *ev)
return;
}
/* ClientMessage handle event
*\param ev XClientMessageEvent pointer
*/
void
clientmessageevent(XClientMessageEvent *ev)
{
Client *c;
int i, mess_t = 0;
if(ev->format != 32)
return;
for(i = 0; i < net_last; ++i)
if(net_atom[i] == ev->message_type)
mess_t = i;
if(ev->window == ROOT)
{
/* Manage _NET_CURRENT_DESKTOP */
if(mess_t == net_current_desktop)
ewmh_get_current_desktop();
/* Manage _NET_ACTIVE_WINDOW */
if(mess_t == net_active_window)
if((c = client_gb_win(ev->data.l[0])))
client_focus(c);
}
if((c = client_gb_win(ev->window)))
{
/* Manage _NET_WM_STATE */
if(mess_t == net_wm_state)
ewmh_manage_net_wm_state(ev->data.l, c);
/* Manage _NET_CLOSE_WINDOW */
if(mess_t == net_close_window)
client_kill(c);
}
return;
}
/** ConfigureRequest & ConfigureNotify handle event
* \param ev XEvent pointer
*/
@ -246,14 +285,14 @@ grabkeys(void)
uint i;
KeyCode code;
XUngrabKey(dpy, AnyKey, AnyModifier, root);
XUngrabKey(dpy, AnyKey, AnyModifier, ROOT);
for(i = 0; i < conf.nkeybind; ++i)
{
code = XKeysymToKeycode(dpy, keys[i].keysym);
XGrabKey(dpy, code, keys[i].mod, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod|LockMask, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod|numlockmask, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod|LockMask|numlockmask, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod, ROOT, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod|LockMask, ROOT, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod|numlockmask, ROOT, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod|LockMask|numlockmask, ROOT, True, GrabModeAsync, GrabModeAsync);
}
return;
@ -368,12 +407,12 @@ unmapnotify(XUnmapEvent *ev)
void
getevent(XEvent ev)
{
int st;
switch (ev.type)
{
case ButtonPress: buttonpress(&ev.xbutton); break;
case ClientMessage: clientmessageevent(&ev.xclient); break;
case ConfigureRequest: configureevent(&ev); break;
case DestroyNotify: destroynotify(&ev.xdestroywindow); break;
case EnterNotify: enternotify(&ev.xcrossing); break;
@ -386,6 +425,7 @@ getevent(XEvent ev)
case UnmapNotify: unmapnotify(&ev.xunmap); break;
}
//ewmh_get_current_desktop();
wait(&st);
return;

232
src/ewmh.c Normal file
View File

@ -0,0 +1,232 @@
/*
* ewmh.c
* Copyright © 2008 Martin Duquesnoy <xorg62@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wmfs.h"
/* Took 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 */
/** Init ewmh atoms
*/
void
ewmh_init_hints(void)
{
net_atom[net_supported] = ATOM("_NET_SUPPORTED");
net_atom[net_number_of_desktops] = ATOM("_NET_NUMBER_OF_DESKTOPS");
net_atom[net_current_desktop] = ATOM("_NET_CURRENT_DESKTOP");
net_atom[net_desktop_names] = ATOM("_NET_DESKTOP_NAMES");
net_atom[net_active_window] = ATOM("_NET_ACTIVE_WINDOW");
net_atom[net_close_window] = ATOM("_NET_CLOSE_WINDOW");
net_atom[net_wm_name] = ATOM("_NET_WM_NAME");
net_atom[net_wm_icon_name] = ATOM("_NET_WM_ICON_NAME");
net_atom[net_wm_window_type] = ATOM("_NET_WM_WINDOW_TYPE");
net_atom[net_wm_window_type_normal] = ATOM("_NET_WM_WINDOW_TYPE_NORMAL");
net_atom[net_wm_window_type_dock] = ATOM("_NET_WM_WINDOW_TYPE_DOCK");
net_atom[net_wm_window_type_splash] = ATOM("_NET_WM_WINDOW_TYPE_SPLASH");
net_atom[net_wm_window_type_dialog] = ATOM("_NET_WM_WINDOW_TYPE_DIALOG");
net_atom[net_wm_icon] = ATOM("_NET_WM_ICON");
net_atom[net_wm_state] = ATOM("_NET_WM_STATE");
net_atom[net_wm_state_sticky] = ATOM("_NET_WM_STATE_STICKY");
net_atom[net_wm_state_skip_taskbar] = ATOM("_NET_WM_STATE_SKIP_TASKBAR");
net_atom[net_wm_state_fullscreen] = ATOM("_NET_WM_STATE_FULLSCREEN");
net_atom[net_wm_state_demands_attention] = ATOM("_NET_WM_STATE_DEMANDS_ATTENTION");
XChangeProperty(dpy, ROOT, net_atom[net_supported], XA_ATOM, 32,
PropModeReplace, (uchar*)net_atom, net_last);
return;
}
/** Get the number of desktop (tag)
*/
void
ewmh_get_number_of_desktop(void)
{
int c = 0, i;
for(i = 0; i < screen_count(); ++i)
c += conf.ntag[i];
XChangeProperty(dpy, ROOT, net_atom[net_number_of_desktops], XA_CARDINAL, 32,
PropModeReplace, (uchar*)&c, 1);
return;
}
/** Get the current desktop
*/
void
ewmh_get_current_desktop(void)
{
screen_get_sel();
/* Get current desktop (tag) */
XChangeProperty(dpy, ROOT, net_atom[net_current_desktop], XA_CARDINAL, 32,
PropModeReplace, (uchar*)&seltag[selscreen], 1);
return;
}
/** The desktop names
*/
void
ewmh_get_desktop_names(void)
{
char *str = NULL;
int s, i, len = 0, pos = 0;
for(s = 0 ; s < screen_count(); ++s)
for(i = 1; i < conf.ntag[s] + 1; ++i)
len += strlen(tags[s][i].name);
str = emalloc(len + i + 1, sizeof(char*));
for(s = 0; s < screen_count(); ++s)
for(i = 1; i < conf.ntag[s] + 1; ++i, ++pos)
{
strncpy(str + pos, tags[s][i].name, strlen(tags[s][i].name));
pos += strlen(tags[s][i].name);
str[pos] = '\0';
}
XChangeProperty(dpy, ROOT, net_atom[net_desktop_names], XA_STRING, 8,
PropModeReplace, (uchar*)str, pos);
free(str);
return;
}
/** Manage _NET_WM_STATE_* ewmh
*/
void
ewmh_manage_net_wm_state(long data_l[], Client *c)
{
/* Manage _NET_WM_STATE_FULLSCREEN */
if(data_l[1] == net_atom[net_wm_state_fullscreen])
{
if(data_l[0] == _NET_WM_STATE_ADD && !c->state_fullscreen)
{
c->state_fullscreen = True;
c->tmp_geo = c->geo;
if(c->free)
c->ogeo = c->geo;
client_maximize(c);
}
else if(data_l[0] == _NET_WM_STATE_REMOVE && c->state_fullscreen)
{
c->state_fullscreen = False;
client_moveresize(c, c->tmp_geo, False);
tags[selscreen][seltag[selscreen]].layout.func();
}
}
/* Manage _NET_WM_STATE_DEMANDS_ATTENTION */
else if(data_l[1] == net_atom[net_wm_state_demands_attention])
{
if(data_l[0] == _NET_WM_STATE_ADD)
client_focus(c);
if(data_l[0] == _NET_WM_STATE_REMOVE)
if(c == sel)
client_focus(NULL);
}
return;
}
/** Manage the client hints
*\param c Client pointer
*/
void
ewmh_manage_window_type(Client *c)
{
Atom *atom, rf;
int i, f;
ulong n, il;
uchar *data = NULL;
if(XGetWindowProperty(dpy, c->win, net_atom[net_wm_window_type], 0L, 0x7FFFFFFFL,
False, XA_ATOM, &rf, &f, &n, &il, &data) == Success && n)
{
atom = (Atom*)data;
for(i = 0; i < n; ++i)
{
/* Manage _NET_WM_WINDOW_TYPE_DOCK & _NET_WM_WINDOW_TYPE_SPLASH */
if(atom[i] == net_atom[net_wm_window_type_dock]
|| atom[i] == net_atom[net_wm_window_type_splash])
{
XReparentWindow(dpy, c->win, ROOT, c->geo.x, c->geo.y);
XUnmapSubwindows(dpy, c->frame);
XUnmapWindow(dpy, c->frame);
XRaiseWindow(dpy, c->win);
}
/* MANAGE _NET_WM_WINDOW_TYPE_DIALOG */
else if(atom[i] == net_atom[net_wm_window_type_dialog])
{
c->free = True;
sel->tile = sel->max = sel->lmax = False;
client_moveresize(sel, sel->ogeo, True);
client_focus(c);
tags[selscreen][seltag[selscreen]].layout.func();
}
}
XFree(data);
}
return;
}
/** Get a Window WM State
* \param win Window
* \return The state
*/
long
ewmh_get_wm_state(Window win)
{
Atom rt;
int rf;
long ret = WithdrawnState;
ulong ir, il;
uchar *data;
if(XGetWindowProperty(dpy, win, net_atom[net_wm_state], 0L, 2L,
False, net_atom[net_wm_state], &rt,
&rf, &ir, &il, &data) == Success && ir)
{
ret = *(long *)data;
XFree(data);
}
return ret;
}

View File

@ -59,7 +59,7 @@ frame_create(Client *c)
c->colors.resizecorner = conf.client.resizecorner_normal;
/* Create frame window */
CWIN(c->frame, root,
CWIN(c->frame, ROOT,
c->frame_geo.x,
c->frame_geo.y,
c->frame_geo.width,

View File

@ -51,7 +51,7 @@ infobar_init(void)
: sgeo[sc].height - INFOBARH;
/* Create infobar barwindow */
infobar[sc].bar = barwin_create(root, sgeo[sc].x - BORDH, infobar[sc].geo.y,
infobar[sc].bar = barwin_create(ROOT, sgeo[sc].x - BORDH, infobar[sc].geo.y,
sgeo[sc].width, infobar[sc].geo.height, conf.colors.bar, False);
/* Create tags window */

View File

@ -38,13 +38,13 @@ void
init(void)
{
/* First init */
gc = DefaultGC(dpy, screen);
screen = DefaultScreen(dpy);
gc = DefaultGC(dpy, SCREEN);
init_font();
init_cursor();
init_key();
init_root();
screen_init_geo();
ewmh_init_hints();
infobar_init();
grabkeys();
@ -60,11 +60,11 @@ init(void)
void
init_font(void)
{
font = XftFontOpenName(dpy, screen, conf.font);
font = XftFontOpenName(dpy, SCREEN, conf.font);
if(!font)
{
fprintf(stderr, "WMFS Error: Cannot initialize font\n");
font = XftFontOpenName(dpy, screen, "sans-10");
font = XftFontOpenName(dpy, SCREEN, "sans-10");
}
}
@ -105,21 +105,19 @@ void
init_root(void)
{
XSetWindowAttributes at;
Atom data[] = { ATOM("_NET_SUPPORTED"), ATOM("_NET_WM_NAME") };
root = RootWindow(dpy, screen);
at.event_mask = KeyMask|ButtonMask|MouseMask
|SubstructureRedirectMask|SubstructureNotifyMask
|EnterWindowMask|LeaveWindowMask|StructureNotifyMask;
at.cursor = cursor[CurNormal];
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &at);
XChangeWindowAttributes(dpy, ROOT, CWEventMask | CWCursor, &at);
if(conf.root.background_command)
uicb_spawn(conf.root.background_command);
XChangeProperty(dpy, root, ATOM("_NET_SUPPORTED"), XA_ATOM, 32,
PropModeReplace, (uchar*)data, NetLast);
ewmh_init_hints();
ewmh_get_number_of_desktop();
ewmh_get_desktop_names();
return;
}

View File

@ -137,19 +137,12 @@ void
maxlayout(void)
{
Client *c;
XRectangle geo;
XRectangle sg = sgeo[selscreen];
for(c = nexttiled(clients); c; c = nexttiled(c->next))
{
c->tile = False;
c->lmax = True;
geo.x = sg.x;
geo.y = sg.y;
geo.width = sg.width - BORDH * 2;
geo.height = sg.height - BORDH * 2;
client_moveresize(c, geo, False);
client_maximize(c);
}
return;
@ -163,7 +156,11 @@ maxlayout(void)
Client*
nexttiled(Client *c)
{
for(; c && (c->max || c->free || c->screen != selscreen || ishide(c)); c = c->next);
for(;c && (c->max
|| c->free
|| c->screen != selscreen
|| c->state_fullscreen
|| ishide(c)); c = c->next);
return c;
}
@ -449,7 +446,7 @@ uicb_tile_switch(uicb_t cmd)
screen_get_sel();
if(!sel || sel->hint || !sel->tile)
if(!sel || sel->hint || !sel->tile || sel->state_fullscreen)
return;
if((c = sel) == nexttiled(clients))
CHECK((c = nexttiled(c->next)));
@ -467,51 +464,44 @@ uicb_tile_switch(uicb_t cmd)
void
uicb_togglefree(uicb_t cmd)
{
CHECK(sel);
if(!sel || sel->screen != screen_get_sel())
if(!sel || sel->screen != screen_get_sel() || sel->state_fullscreen)
return;
sel->free = !sel->free;
sel->tile = False;
sel->max = False;
sel->lmax = False;
client_moveresize(sel, sel->ogeo, True);
if(sel->free)
{
sel->tile = sel->max = sel->lmax = False;
client_moveresize(sel, sel->ogeo, True);
}
else
sel->ogeo = sel->geo;
tags[selscreen][seltag[selscreen]].layout.func();
return;
}
/** Toggle the selected client to max
* \param cmd uicb_t type unused
*/
void
uicb_togglemax(uicb_t cmd)
{
XRectangle geo;
XRectangle sg = sgeo[screen_get_sel()];
if(!sel || ishide(sel) || sel->hint)
if(!sel || ishide(sel) || sel->hint || sel->state_fullscreen)
return;
if(!sel->max)
{
geo.x = sg.x;
geo.y = sg.y;
geo.width = sg.width - BORDH * 2;
geo.height = sg.height - BORDH * 2;
client_moveresize(sel, geo, False);
client_raise(sel);
sel->tile = sel->free = False;
client_maximize(sel);
sel->max = True;
}
else if(sel->max)
{
geo.x = sel->ogeo.x;
geo.y = sel->ogeo.y;
geo.width = sel->ogeo.width;
geo.height = sel->ogeo.height;
client_moveresize(sel, geo, False);
sel->max = False;
tags[selscreen][seltag[selscreen]].layout.func();
}
return;

View File

@ -49,11 +49,11 @@ mouse_move(Client *c)
if(c->max || c->tile || c->lmax)
return;
if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
if(XGrabPointer(dpy, ROOT, False, MouseMask, GrabModeAsync, GrabModeAsync,
None, cursor[CurMove], CurrentTime) != GrabSuccess)
return;
XQueryPointer(dpy, root, &dw, &dw, &mx, &my, &dint, &dint, &duint);
XQueryPointer(dpy, ROOT, &dw, &dw, &mx, &my, &dint, &dint, &duint);
for(;;)
{
@ -94,8 +94,8 @@ mouse_resize(Client *c)
if(c->max || c->lmax || c->tile)
return;
if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
None, cursor[CurResize], CurrentTime) != GrabSuccess)
if(XGrabPointer(dpy, ROOT, False, MouseMask, GrabModeAsync, GrabModeAsync,
None, cursor[CurResize], CurrentTime) != GrabSuccess)
return;
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->geo.width + conf.client.borderheight, c->geo.height);

View File

@ -114,7 +114,7 @@ screen_get_sel(void)
Window w;
int d, u, x, y;
XQueryPointer(dpy, root, &w, &w, &x, &y, &d, &d, (uint *)&u);
XQueryPointer(dpy, ROOT, &w, &w, &x, &y, &d, &d, (uint *)&u);
selscreen = screen_get_with_geo(x, y);
}

View File

@ -48,8 +48,30 @@ typedef unsigned char uchar;
/* Enum */
enum { CurNormal, CurResize, CurMove, CurLast };
enum { WMState, WMProtocols, WMName, WMDelete, WMLast };
enum { NetSupported, NetWMName, NetLast };
/* Ewmh hints list */
enum
{
net_supported,
net_wm_name,
net_number_of_desktops,
net_current_desktop,
net_desktop_names,
net_active_window,
net_close_window,
net_wm_icon_name,
net_wm_window_type,
net_wm_window_type_normal,
net_wm_window_type_dock,
net_wm_window_type_splash,
net_wm_window_type_dialog,
net_wm_icon,
net_wm_state,
net_wm_state_sticky,
net_wm_state_skip_taskbar,
net_wm_state_fullscreen,
net_wm_state_demands_attention,
net_last
};
typedef enum { Top, Bottom, Right, Left, Center, PositionLast } Position;
/*
@ -84,6 +106,7 @@ struct Client
int screen;
/* Window attribute */
XRectangle geo;
XRectangle tmp_geo;
XRectangle frame_geo;
/* Old window attribute */
XRectangle ogeo;
@ -105,7 +128,7 @@ struct Client
} colors;
/* Client Layout Information */
Bool max, tile, free, hide;
Bool hint, lmax, unmapped;
Bool hint, lmax, unmapped, state_fullscreen;
/* Struct in chains */
Client *next;
Client *prev;

View File

@ -72,6 +72,7 @@ uicb_tag(uicb_t cmd)
seltag[selscreen] = tmp;
}
}
ewmh_get_current_desktop();
arrange();
client_focus(NULL);

View File

@ -57,7 +57,7 @@ getcolor(char *color)
{
XColor xcolor;
if(!XAllocNamedColor(dpy, DefaultColormap(dpy, screen), color, &xcolor, &xcolor))
if(!XAllocNamedColor(dpy, DefaultColormap(dpy, SCREEN), color, &xcolor, &xcolor))
fprintf(stderr,"WMFS Error: cannot allocate color \"%s\"\n", color);
return xcolor.pixel;
}
@ -78,30 +78,6 @@ color_enlight(ulong col)
}
/** Get a Window WM State
* \param win Window
* \return The state
*/
long
getwinstate(Window win)
{
int f;
long ret = -1;
ulong n, e;
uchar *p = NULL;
Atom at;
if(XGetWindowProperty(dpy, win, ATOM("WM_STATE"), 0L, 2L, False,
ATOM("WM_STATE"), &at, &f, &n, &e, (uchar **)&p) != Success)
return -1;
if(n != 0)
ret = *p;
XFree(p);
return ret;
}
/** Round function
* \param x double type
* \return the round of x

View File

@ -199,7 +199,7 @@ scan(void)
XWindowAttributes wa;
Window usl, usl2, *w = NULL;
if(XQueryTree(dpy, root, &usl, &usl2, &w, &n))
if(XQueryTree(dpy, ROOT, &usl, &usl2, &w, &n))
for(i = 0; i < n; ++i)
if(XGetWindowAttributes(dpy, w[i], &wa)
&& !(wa.override_redirect || XGetTransientForHint(dpy, w[i], &usl))

View File

@ -48,6 +48,7 @@
#include <confuse.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xmd.h>
#include <X11/cursorfont.h>
#include <X11/Xft/Xft.h>
#include <X11/extensions/Xinerama.h>
@ -66,8 +67,10 @@
InputOutput, CopyFromParent, mask, at); \
XSetWindowBackground(dpy, win, col);
#define MAXH DisplayHeight(dpy, screen)
#define MAXW DisplayWidth(dpy, screen)
#define SCREEN DefaultScreen(dpy)
#define ROOT RootWindow(dpy, SCREEN)
#define MAXH DisplayHeight(dpy, DefaultScreen(dpy))
#define MAXW DisplayWidth(dpy, DefaultScreen(dpy))
#define ATOM(a) XInternAtom(dpy, a, False)
#define INFOBARH font->height * 1.5
#define SHADH 1
@ -126,6 +129,7 @@ Bool ishide(Client *c);
void client_map(Client *c);
void client_manage(Window w, XWindowAttributes *wa);
void client_moveresize(Client *c, XRectangle geo, bool r);
void client_maximize(Client *c);
void client_size_hints(Client *c);
void client_raise(Client *c);
void client_unhide(Client *c);
@ -136,6 +140,15 @@ void uicb_client_prev(uicb_t);
void uicb_client_next(uicb_t);
void uicb_client_kill(uicb_t);
/* ewmh.c */
void ewmh_init_hints(void);
void ewmh_get_number_of_desktop(void);
void ewmh_get_current_desktop(void);
void ewmh_get_desktop_names(void);
void ewmh_manage_net_wm_state(long data_l[], Client *c);
void ewmh_manage_window_type(Client *c);
long ewmh_get_wm_state(Window win);
/* frame.c */
void frame_create(Client *c);
void frame_delete(Client *c);
@ -178,8 +191,6 @@ void uicb_mouse_resize(uicb_t);
ulong color_enlight(ulong col);
void *emalloc(uint element, uint size);
ulong getcolor(char *color);
long getwinstate(Window win);
double round(double x);
void setwinstate(Window win, long state);
/* Conf usage {{{ */
void* name_to_func(char *name, func_name_list_t l[]);
@ -247,8 +258,6 @@ void uicb_reload(uicb_t);
/* Principal */
Display *dpy;
GC gc;
Window root;
int screen;
int selscreen;
Conf conf;
Key *keys;
@ -259,6 +268,7 @@ Cursor cursor[CurLast];
/* Fonts */
XftFont *font;
Atom net_atom[net_last];
/* InfoBar */
InfoBar *infobar;