New feature: EWMH Support ! #1
This commit is contained in:
parent
199a148689
commit
f8d1049240
@ -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
|
||||
|
||||
@ -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 */
|
||||
|
||||
46
src/client.c
46
src/client.c
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
54
src/event.c
54
src/event.c
@ -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
232
src/ewmh.c
Normal 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;
|
||||
}
|
||||
@ -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,
|
||||
|
||||
@ -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 */
|
||||
|
||||
18
src/init.c
18
src/init.c
@ -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;
|
||||
}
|
||||
|
||||
56
src/layout.c
56
src/layout.c
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -72,6 +72,7 @@ uicb_tag(uicb_t cmd)
|
||||
seltag[selscreen] = tmp;
|
||||
}
|
||||
}
|
||||
ewmh_get_current_desktop();
|
||||
|
||||
arrange();
|
||||
client_focus(NULL);
|
||||
|
||||
26
src/util.c
26
src/util.c
@ -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
|
||||
|
||||
@ -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))
|
||||
|
||||
22
src/wmfs.h
22
src/wmfs.h
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user