[ALL] Clean & arrange all files, Add client.c, remove titlebar button

This commit is contained in:
Martin Duquesnoy 2008-10-13 22:05:35 +02:00
parent 6e450e3608
commit daa0f1b724
11 changed files with 690 additions and 749 deletions

View File

@ -32,7 +32,8 @@ set(wmfs_src
layout.c
tag.c
bar.c
draw.c)
draw.c
client.c)
# Set the executable from the wmfs_src
add_executable(wmfs ${wmfs_src})

498
client.c Normal file
View File

@ -0,0 +1,498 @@
/*
* client.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"
int
clientpertag(int tag)
{
Client *c;
int i = 0;
for(c = clients; c; c = c->next)
if(c->tag == tag)
++i;
return i;
}
void
client_attach(Client *c)
{
if(clients)
clients->prev = c;
c->next = clients;
clients = c;
return;
}
void
client_detach(Client *c)
{
Client **cc;
for(cc = &clients; *cc && *cc != c; cc = &(*cc)->next);
*cc = c->next;
return;
}
/* True : next
* False : prev */
void
client_switch(Bool b)
{
Client *c;
if(!sel || ishide(sel))
return;
if(b)
{
for(c = sel->next; c && ishide(c); c = c->next);
if(!c)
for(c = clients; c && ishide(c); c = c->next);
if(c)
{
client_focus(c);
if(!c->tile)
raiseclient(c);
}
}
else
{
for(c = sel->prev; c && ishide(c); c = c->prev);
if(!c)
{
for(c = clients; c && c->next; c = c->next);
for(; c && ishide(c); c = c->prev);
}
if(c)
{
client_focus(c);
if(!c->tile)
raiseclient(c);
}
}
arrange();
return;
}
void
uicb_client_prev(uicb_t cmd)
{
client_switch(False);
return;
}
void
uicb_client_next(uicb_t cmd)
{
client_switch(True);
return;
}
void
client_focus(Client *c)
{
Client *cc;
if(sel && sel != c)
{
grabbuttons(sel, False);
draw_border(sel->win, conf.colors.bordernormal);
if(conf.ttbarheight)
draw_border(sel->tbar->win, conf.colors.bordernormal);
}
if(c)
grabbuttons(c, True);
sel = c;
selbytag[seltag] = sel;
if(c)
{
draw_border(c->win, conf.colors.borderfocus);
if(conf.ttbarheight)
draw_border(c->tbar->win, conf.colors.borderfocus);
if(conf.raisefocus)
raiseclient(c);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
updatetitlebar(c);
}
else
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
for(cc = clients; cc; cc = cc->next)
if(!ishide(cc))
updatetitlebar(cc);
return;
}
Client*
getclient(Window w)
{
Client *c;
for(c = clients; c && c->win != w; c = c->next);
return c;
}
Client*
client_gettbar(Window w)
{
Client *c;
if(!conf.ttbarheight)
return NULL;
for(c = clients; c && c->tbar->win != w; c = c->next);
return c;
}
void
client_hide(Client *c)
{
if(!c)
return;
XMoveWindow(dpy, c->win, c->x, c->y+mh*2);
if(conf.ttbarheight)
bar_moveresize(c->tbar, c->x, c->y+mh*2, c->w, c->h);
//unmapclient(c);
setwinstate(c->win, IconicState);
c->hide = True;
return;
}
Bool
ishide(Client *c)
{
int i;
for(i = 0; i < conf.ntag + 1; ++i)
if(c->tag == i && seltag == i)
return False;
return True;
}
void
uicb_killclient(uicb_t cmd)
{
XEvent ev;
if(!sel)
return;
ev.type = ClientMessage;
ev.xclient.window = sel->win;
ev.xclient.message_type = wm_atom[WMProtocols];
ev.xclient.format = 32;
ev.xclient.data.l[0] = wm_atom[WMDelete];
ev.xclient.data.l[1] = CurrentTime;
XSendEvent(dpy, sel->win, False, NoEventMask, &ev);
return;
}
void
mapclient(Client *c)
{
if(!c)
return;
XMapWindow(dpy, c->win);
if(conf.ttbarheight)
{
XMapWindow(dpy, c->tbar->win);
bar_refresh(c->tbar);
}
return;
}
void
client_manage(Window w, XWindowAttributes *wa)
{
Client *c, *t = NULL;
Window trans;
Status rettrans;
XWindowChanges winc;
c = emalloc(1, sizeof(Client));
c->win = w;
c->x = wa->x;
c->y = wa->y + conf.ttbarheight + barheight;
c->w = wa->width;
c->h = wa->height;
c->tag = seltag;
/* Create titlebar */
if(conf.ttbarheight)
c->tbar = bar_create(c->x, c->y - conf.ttbarheight,
c->w, conf.ttbarheight, conf.borderheight,
conf.colors.bar, True);
XConfigureWindow(dpy, w, CWBorderWidth, &winc);
draw_border(w, conf.colors.bordernormal);
grabbuttons(c, False);
XSelectInput(dpy, w, EnterWindowMask | FocusChangeMask
| PropertyChangeMask | StructureNotifyMask);
client_size_hints(c);
updatetitlebar(c);
if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success))
for(t = clients; t && t->win != trans; t = t->next);
if(t)
c->tag = t->tag;
if(!c->free)
c->free = (rettrans == Success) || c->hint;
else
raiseclient(c);
client_attach(c);
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
mapclient(c);
setwinstate(c->win, NormalState);
client_focus(c);
arrange();
return;
}
void
client_moveresize(Client *c, int x, int y, int w, int h, bool r)
{
if(!c)
return;
/* Resize hints {{{ */
if(r)
{
/* minimum possible */
if (w < 1)
w = 1;
if (h < 1)
h = 1;
/* base */
w -= c->basew;
h -= c->baseh;
/* aspect */
if (c->minay > 0 && c->maxay > 0
&& c->minax > 0 && c->maxax > 0)
{
if (w * c->maxay > h * c->maxax)
w = h * c->maxax / c->maxay;
else if (w * c->minay < h * c->minax)
h = w * c->minay / c->minax;
}
/* incremental */
if(c->incw)
w -= w % c->incw;
if(c->inch)
h -= h % c->inch;
/* base dimension */
w += c->basew;
h += c->baseh;
if(c->minw > 0 && w < c->minw)
w = c->minw;
if(c->minh > 0 && h < c->minh)
h = c->minh;
if(c->maxw > 0 && w > c->maxw)
w = c->maxw;
if(c->maxh > 0 && h > c->maxh)
h = c->maxh;
if(w <= 0 || h <= 0)
return;
}
/* }}} */
c->max = False;
if(c->x != x || c->y != y
|| c->w != w || c->h != h)
{
c->x = x; c->y = y;
c->w = w; c->h = h;
XMoveResizeWindow(dpy, c->win, x, y, w ,h);
if(conf.ttbarheight)
bar_moveresize(c->tbar, x, y - conf.ttbarheight, w, conf.ttbarheight);
updatetitlebar(c);
XSync(dpy, False);
}
return;
}
void
client_size_hints(Client *c)
{
long msize;
XSizeHints size;
if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags)
size.flags = PSize;
/* base */
if(size.flags & PBaseSize)
{
c->basew = size.base_width;
c->baseh = size.base_height;
}
else if(size.flags & PMinSize)
{
c->basew = size.min_width;
c->baseh = size.min_height;
}
else
c->basew = c->baseh = 0;
/* inc */
if(size.flags & PResizeInc)
{
c->incw = size.width_inc;
c->inch = size.height_inc;
}
else
c->incw = c->inch = 0;
/* max */
if(size.flags & PMaxSize)
{
c->maxw = size.max_width;
c->maxh = size.max_height;
}
else
c->maxw = c->maxh = 0;
/* min */
if(size.flags & PMinSize)
{
c->minw = size.min_width;
c->minh = size.min_height;
}
else if(size.flags & PBaseSize)
{
c->minw = size.base_width;
c->minh = size.base_height;
}
else
c->minw = c->minh = 0;
/* aspect */
if(size.flags & PAspect)
{
c->minax = size.min_aspect.x;
c->maxax = size.max_aspect.x;
c->minay = size.min_aspect.y;
c->maxay = size.max_aspect.y;
}
else
c->minax = c->maxax = c->minay = c->maxay = 0;
c->hint = (c->maxw && c->minw && c->maxh && c->minh
&& c->maxw == c->minw && c->maxh == c->minh);
return;
}
void
raiseclient(Client *c)
{
if(!c)
return;
XRaiseWindow(dpy, c->win);
if(conf.ttbarheight)
{
XRaiseWindow(dpy, c->tbar->win);
updatetitlebar(c);
}
return;
}
void
client_unhide(Client *c)
{
if(!c)
return;
XMoveWindow(dpy, c->win, c->x, c->y);
if(conf.ttbarheight)
bar_moveresize(c->tbar, c->x, c->y - conf.ttbarheight, c->w, conf.ttbarheight);
//mapclient(c);
setwinstate(c->win, NormalState);
c->hide = False;
return;
}
void
client_unmanage(Client *c)
{
XGrabServer(dpy);
XSetErrorHandler(errorhandlerdummy);
sel = ((sel == c) ? ((c->next) ? c->next : NULL) : NULL);
if(sel && sel->tag == seltag)
selbytag[seltag] = sel;
else
selbytag[seltag] = NULL;
client_detach(c);
if(conf.ttbarheight)
bar_delete(c->tbar);
setwinstate(c->win, WithdrawnState);
free(c);
XSync(dpy, False);
XUngrabServer(dpy);
arrange();
return;
}
void
unmapclient(Client *c)
{
if(!c)
return;
XUnmapWindow(dpy, c->win);
if(conf.ttbarheight)
XUnmapWindow(dpy, c->tbar->win);
return;
}

View File

@ -31,7 +31,6 @@
*/
#include "wmfs.h"
#include "structs.h"
#define FILE_NAME ".config/wmfs/wmfsrc"
@ -185,8 +184,6 @@ init_conf(void)
CFG_STR("layout_bg", "#292929", CFGF_NONE),
CFG_STR("titlebar_text_focus", "#FFFFFF", CFGF_NONE),
CFG_STR("titlebar_text_normal", "#FFFFFF", CFGF_NONE),
CFG_STR("button", "#6286A1", CFGF_NONE),
CFG_STR("button_border", "#354B5C", CFGF_NONE),
CFG_END()
};
@ -354,9 +351,6 @@ init_conf(void)
conf.colors.layout_bg = getcolor(var_to_str(cfg_getstr(cfg_colors, "layout_bg")));
conf.colors.ttbar_text_focus = strdup(var_to_str(cfg_getstr(cfg_colors, "titlebar_text_focus")));
conf.colors.ttbar_text_normal = strdup(var_to_str(cfg_getstr(cfg_colors, "titlebar_text_normal")));
conf.colors.button = getcolor(var_to_str(cfg_getstr(cfg_colors, "button")));
conf.colors.button_border = getcolor(var_to_str(cfg_getstr(cfg_colors, "button_border")));
/* layout */
if((conf.nlayout = cfg_size(cfg_layouts, "layout")) > MAXLAYOUT

12
draw.c
View File

@ -152,6 +152,18 @@ get_image_attribute(char *file)
return ret;
}
void
draw_border(Window win, int color)
{
if(!win)
return;
XSetWindowBorder(dpy, win, color);
XSetWindowBorderWidth(dpy, win, conf.borderheight);
return;
}
ushort
textw(const char *text)
{

140
event.c
View File

@ -49,7 +49,7 @@ buttonpress(XEvent ev)
/* TITLEBAR */
/* ******** */
{
if((c = gettbar(ev.xbutton.window)))
if((c = client_gettbar(ev.xbutton.window)))
{
raiseclient(c);
/* BUTTON 1 */
@ -76,32 +76,6 @@ buttonpress(XEvent ev)
}
/* ****** */
/* BUTTON */
/* ****** */
{
if((c = getbutton(ev.xbutton.window)))
{
/* BUTTON 1 */
{
if(ev.xbutton.button == Button1)
uicb_killclient(NULL);
}
/* BUTTON 2 AND 3 */
{
if(ev.xbutton.button == Button2
|| ev.xbutton.button == Button3)
{
if(tags[seltag].layout.func == tile)
uicb_tile_switch(NULL);
else
uicb_togglemax(NULL);
}
}
}
}
}
/* ****** */
@ -266,7 +240,7 @@ configurerequest(XEvent ev)
ev.xconfigurerequest.value_mask, &wc);
if((c = getclient(ev.xconfigurerequest.window)))
if(wc.y < mw && wc.x < mh)
moveresize(c, wc.x, wc.y, wc.width, wc.height, True);
client_moveresize(c, wc.x, wc.y, wc.width, wc.height, True);
return;
}
@ -278,9 +252,9 @@ destroynotify(XEvent ev)
Client *c;
if((c = getclient(ev.xdestroywindow.window)))
unmanage(c);
client_unmanage(c);
return;
return;
}
/* ENTERNOTIFY */
@ -293,10 +267,10 @@ enternotify(XEvent ev)
|| ev.xcrossing.detail == NotifyInferior)
return;
if((c = getclient(ev.xcrossing.window))
|| (c = gettbar(ev.xcrossing.window)))
focus(c);
|| (c = client_gettbar(ev.xcrossing.window)))
client_focus(c);
else
focus(NULL);
client_focus(NULL);
return;
}
@ -329,6 +303,47 @@ focusin(XEvent ev)
return;
}
void
grabbuttons(Client *c, Bool focused)
{
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
if(focused)
{
/* Window */
XGrabButton(dpy, Button1, ALT, c->win, False, ButtonMask, GrabModeAsync,GrabModeSync, None, None);
XGrabButton(dpy, Button1, ALT|LockMask, c->win, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, ALT, c->win, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, ALT|LockMask, c->win, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, ALT, c->win, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, ALT|LockMask, c->win, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
}
else
XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
return;
}
void
grabkeys(void)
{
uint i;
KeyCode code;
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|numlockmask, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod|LockMask, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod|LockMask|numlockmask, root, True, GrabModeAsync, GrabModeAsync);
}
return;
}
/* KEYPRESS */
void
keypress(XEvent ev)
@ -370,8 +385,59 @@ maprequest(XEvent ev)
return;
if(!getclient(ev.xmaprequest.window))
{
focus(NULL);
manage(ev.xmaprequest.window, &at);
client_focus(NULL);
client_manage(ev.xmaprequest.window, &at);
}
return;
}
/* If the type is 0, this function will move, else,
* this will resize */
void
mouseaction(Client *c, int x, int y, int type)
{
int ocx, ocy;
XEvent ev;
if(c->max || c->tile || c->lmax)
return;
ocx = c->x;
ocy = c->y;
if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
None, cursor[((type) ?CurResize:CurMove)], CurrentTime) != GrabSuccess)
return;
if(type)
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
for(;;)
{
XMaskEvent(dpy, MouseMask | ExposureMask | SubstructureRedirectMask, &ev);
if(ev.type == ButtonRelease)
{
if(type)
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
XUngrabPointer(dpy, CurrentTime);
updatebar();
return;
}
else if(ev.type == MotionNotify)
{
XSync(dpy, False);
/* Resize */
if(type)
client_moveresize(c, c->x, c->y,
((ev.xmotion.x - ocx <= 0) ? 1 : ev.xmotion.x - ocx),
((ev.xmotion.y - ocy <= 0) ? 1 : ev.xmotion.y - ocy), True);
/* Move */
else
client_moveresize(c, (ocx + (ev.xmotion.x - x)),
(ocy + (ev.xmotion.y - y)),
c->w, c->h, True);
}
else if(ev.type == Expose)
expose(ev);
}
return;
@ -397,7 +463,7 @@ propertynotify(XEvent ev)
arrange();
break;
case XA_WM_NORMAL_HINTS:
setsizehints(c);
client_size_hints(c);
break;
}
if(ev.xproperty.atom == XA_WM_NAME
@ -416,7 +482,7 @@ unmapnotify(XEvent ev)
if((c = getclient(ev.xunmap.window)))
if(!c->hide)
unmanage(c);
client_unmanage(c);
return;
}

View File

@ -32,6 +32,30 @@
#include "wmfs.h"
void
arrange(void)
{
Client *c;
for(c = clients; c; c = c->next)
if(!ishide(c))
client_unhide(c);
else
client_hide(c);
if(sel)
tags[seltag].layout.func();
if(selbytag[seltag])
client_focus(selbytag[seltag]);
else
client_focus(NULL);
updatebar();
return;
}
void
freelayout(void)
{
@ -43,7 +67,7 @@ freelayout(void)
{
if(c->tile || c->lmax)
{
moveresize(c, c->ox, c->oy, c->ow, c->oh, True);
client_moveresize(c, c->ox, c->oy, c->ow, c->oh, True);
c->tile = False;
c->lmax = False;
}
@ -103,7 +127,7 @@ maxlayout(void)
c->ox = c->x; c->oy = c->y;
c->ow = c->w; c->oh = c->h;
moveresize(c, 0, (conf.ttbarheight + ((conf.bartop) ? barheight : 0)),
client_moveresize(c, 0, (conf.ttbarheight + ((conf.bartop) ? barheight : 0)),
(mw - (conf.borderheight * 2)),
(mh - (conf.borderheight * 2) - conf.ttbarheight - barheight), False);
@ -218,7 +242,7 @@ tile(void)
else
h = th - (bord + conf.ttbarheight) - bord*2;
}
moveresize(c, x, y, w, h, tags[seltag].resizehint);
client_moveresize(c, x, y, w, h, tags[seltag].resizehint);
if(n > nm && th != mht)
y = c->y + c->h + bord + conf.ttbarheight;
}
@ -236,9 +260,9 @@ uicb_tile_switch(uicb_t cmd)
if((c = sel) == nexttiled(clients))
if(!(c = nexttiled(c->next)))
return;
detach(c);
attach(c);
focus(c);
client_detach(c);
client_attach(c);
client_focus(c);
arrange();
return;
@ -253,15 +277,15 @@ uicb_togglemax(uicb_t cmd)
{
sel->ox = sel->x; sel->oy = sel->y;
sel->ow = sel->w; sel->oh = sel->h;
moveresize(sel, 0, (conf.ttbarheight + ((conf.bartop) ? barheight: 0)),
(mw - (conf.borderheight * 2)),
(mh - (conf.borderheight * 2)- conf.ttbarheight - barheight), False);
client_moveresize(sel, 0, (conf.ttbarheight + ((conf.bartop) ? barheight: 0)),
(mw - (conf.borderheight * 2)),
(mh - (conf.borderheight * 2)- conf.ttbarheight - barheight), False);
raiseclient(sel);
sel->max = True;
}
else if(sel->max)
{
moveresize(sel, sel->ox, sel->oy, sel->ow, sel->oh, False);
client_moveresize(sel, sel->ox, sel->oy, sel->ow, sel->oh, False);
sel->max = False;
}
arrange();
@ -269,3 +293,4 @@ uicb_togglemax(uicb_t cmd)
return;
}

View File

@ -79,8 +79,6 @@ struct Client
Window win;
/* Titlebar */
BarWindow *tbar;
/* Titlebar Button */
Window button;
/* Client Layout Information */
Bool max, tile, free;
Bool hint, hide, lmax;
@ -157,8 +155,6 @@ typedef struct
uint layout_bg;
char *ttbar_text_focus;
char *ttbar_text_normal;
uint button;
uint button_border;
} colors;
Tag tag[MAXTAG];
Layout layout[MAXLAYOUT];

11
util.c
View File

@ -53,6 +53,17 @@ getcolor(char *color)
return xcolor.pixel;
}
void
setwinstate(Window win, long state)
{
long data[] = {state, None};
XChangeProperty(dpy, win, wm_atom[WMState], wm_atom[WMState], 32,
PropModeReplace, (unsigned char *)data, 2);
return;
}
void
uicb_spawn(uicb_t cmd)
{

657
wmfs.c
View File

@ -32,123 +32,6 @@
#include "wmfs.h"
void
arrange(void)
{
Client *c;
for(c = clients; c; c = c->next)
if(!ishide(c))
unhide(c);
else
hide(c);
if(sel)
tags[seltag].layout.func();
if(selbytag[seltag])
focus(selbytag[seltag]);
else
focus(NULL);
updatebar();
return;
}
void
attach(Client *c)
{
if(clients)
clients->prev = c;
c->next = clients;
clients = c;
return;
}
int
clientpertag(int tag)
{
Client *c;
int i = 0;
for(c = clients; c; c = c->next)
if(c->tag == tag)
++i;
return i;
}
/* True : next
* False : prev */
void
client_switch(Bool b)
{
Client *c;
if(!sel || ishide(sel))
return;
if(b)
{
for(c = sel->next; c && ishide(c); c = c->next);
if(!c)
for(c = clients; c && ishide(c); c = c->next);
if(c)
{
focus(c);
if(!c->tile)
raiseclient(c);
}
}
else
{
for(c = sel->prev; c && ishide(c); c = c->prev);
if(!c)
{
for(c = clients; c && c->next; c = c->next);
for(; c && ishide(c); c = c->prev);
}
if(c)
{
focus(c);
if(!c->tile)
raiseclient(c);
}
}
arrange();
return;
}
void
uicb_client_prev(uicb_t cmd)
{
client_switch(False);
return;
}
void
uicb_client_next(uicb_t cmd)
{
client_switch(True);
return;
}
void
detach(Client *c)
{
Client **cc;
for(cc = &clients; *cc && *cc != c; cc = &(*cc)->next);
*cc = c->next;
return;
}
int
errorhandler(Display *d, XErrorEvent *event)
{
@ -171,146 +54,6 @@ errorhandlerdummy(Display *d, XErrorEvent *event)
return 0;
}
void
focus(Client *c)
{
Client *cc;
if(sel && sel != c)
{
grabbuttons(sel, False);
setborder(sel->win, conf.colors.bordernormal);
if(conf.ttbarheight)
setborder(sel->tbar->win, conf.colors.bordernormal);
}
if(c)
grabbuttons(c, True);
sel = c;
selbytag[seltag] = sel;
if(c)
{
setborder(c->win, conf.colors.borderfocus);
if(conf.ttbarheight)
setborder(c->tbar->win, conf.colors.borderfocus);
if(conf.raisefocus)
raiseclient(c);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
updatetitlebar(c);
}
else
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
for(cc = clients; cc; cc = cc->next)
if(!ishide(cc))
updatetitlebar(cc);
return;
}
Client*
getbutton(Window w)
{
Client *c;
for(c = clients; c && c->button != w; c = c->next);
return c;
}
Client*
getclient(Window w)
{
Client *c;
for(c = clients; c && c->win != w; c = c->next);
return c;
}
Client*
getnext(Client *c)
{
for(; c; c = c->prev);
return c;
}
Client*
gettbar(Window w)
{
Client *c;
if(!conf.ttbarheight)
return NULL;
for(c = clients; c && c->tbar->win != w; c = c->next);
return c;
}
void
grabbuttons(Client *c, Bool focused)
{
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
if(focused)
{
/* Window */
XGrabButton(dpy, Button1, ALT, c->win, False, ButtonMask, GrabModeAsync,GrabModeSync, None, None);
XGrabButton(dpy, Button1, ALT|LockMask, c->win, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, ALT, c->win, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, ALT|LockMask, c->win, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, ALT, c->win, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, ALT|LockMask, c->win, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
}
else
XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, ButtonMask, GrabModeAsync, GrabModeSync, None, None);
return;
}
void
grabkeys(void)
{
uint i;
KeyCode code;
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|numlockmask, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod|LockMask, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod|LockMask|numlockmask, root, True, GrabModeAsync, GrabModeAsync);
}
return;
}
void
hide(Client *c)
{
if(!c)
return;
XMoveWindow(dpy, c->win, c->x, c->y+mh*2);
if(conf.ttbarheight)
{
bar_moveresize(c->tbar, c->x, c->y+mh*2, c->w, c->h);
if(conf.ttbarheight > 5)
XMoveWindow(dpy, c->button, c->x, c->y+mh*2);
}
//unmapclient(c);
setwinstate(c->win, IconicState);
c->hide = True;
return;
}
void
init(void)
{
@ -386,36 +129,6 @@ init(void)
return;
}
Bool
ishide(Client *c)
{
int i;
for(i = 0; i < conf.ntag + 1; ++i)
if(c->tag == i && seltag == i)
return False;
return True;
}
void
uicb_killclient(uicb_t cmd)
{
XEvent ev;
if(!sel)
return;
ev.type = ClientMessage;
ev.xclient.window = sel->win;
ev.xclient.message_type = wm_atom[WMProtocols];
ev.xclient.format = 32;
ev.xclient.data.l[0] = wm_atom[WMDelete];
ev.xclient.data.l[1] = CurrentTime;
XSendEvent(dpy, sel->win, False, NoEventMask, &ev);
return;
}
void
mainloop(void)
{
@ -471,202 +184,6 @@ mainloop(void)
return;
}
void
mapclient(Client *c)
{
if(!c)
return;
XMapWindow(dpy, c->win);
if(conf.ttbarheight)
{
XMapWindow(dpy, c->tbar->win);
bar_refresh(c->tbar);
if(conf.ttbarheight > 5)
XMapWindow(dpy, c->button);
}
return;
}
void
manage(Window w, XWindowAttributes *wa)
{
Client *c, *t = NULL;
Window trans;
Status rettrans;
XWindowChanges winc;
c = emalloc(1, sizeof(Client));
c->win = w;
c->x = wa->x;
c->y = wa->y + conf.ttbarheight + barheight;
c->w = wa->width;
c->h = wa->height;
c->tag = seltag;
/* Create titlebar & button */
if(conf.ttbarheight)
{
c->tbar = bar_create(c->x, c->y - conf.ttbarheight,
c->w, conf.ttbarheight, conf.borderheight,
conf.colors.bar, True);
/* Basic window for close button... */
if(conf.ttbarheight > 5)
c->button = XCreateSimpleWindow(dpy, root, BUTX(c->x, c->w), BUTY(c->y),
((BUTH) ? BUTH : 1), ((BUTH) ? BUTH : 1),
1, conf.colors.button_border,
conf.colors.button);
}
XConfigureWindow(dpy, w, CWBorderWidth, &winc);
setborder(w, conf.colors.bordernormal);
grabbuttons(c, False);
XSelectInput(dpy, w, EnterWindowMask | FocusChangeMask
| PropertyChangeMask | StructureNotifyMask);
setsizehints(c);
updatetitlebar(c);
if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success))
for(t = clients; t && t->win != trans; t = t->next);
if(t)
c->tag = t->tag;
if(!c->free)
c->free = (rettrans == Success) || c->hint;
else
raiseclient(c);
attach(c);
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
mapclient(c);
setwinstate(c->win, NormalState);
focus(c);
arrange();
return;
}
/* If the type is 0, this function will move, else,
* this will resize */
void
mouseaction(Client *c, int x, int y, int type)
{
int ocx, ocy;
XEvent ev;
if(c->max || c->tile || c->lmax)
return;
ocx = c->x;
ocy = c->y;
if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
None, cursor[((type) ?CurResize:CurMove)], CurrentTime) != GrabSuccess)
return;
if(type)
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
for(;;)
{
XMaskEvent(dpy, MouseMask | ExposureMask | SubstructureRedirectMask, &ev);
if(ev.type == ButtonRelease)
{
if(type)
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
XUngrabPointer(dpy, CurrentTime);
updatebar();
return;
}
else if(ev.type == MotionNotify)
{
XSync(dpy, False);
/* Resize */
if(type)
moveresize(c, c->x, c->y,
((ev.xmotion.x - ocx <= 0) ? 1 : ev.xmotion.x - ocx),
((ev.xmotion.y - ocy <= 0) ? 1 : ev.xmotion.y - ocy), True);
/* Move */
else
moveresize(c,
(ocx + (ev.xmotion.x - x)),
(ocy + (ev.xmotion.y - y)),
c->w, c->h, True);
}
else if(ev.type == Expose)
expose(ev);
}
return;
}
void
moveresize(Client *c, int x, int y, int w, int h, bool r)
{
if(!c)
return;
/* Resize hints {{{ */
if(r)
{
/* minimum possible */
if (w < 1)
w = 1;
if (h < 1)
h = 1;
/* base */
w -= c->basew;
h -= c->baseh;
/* aspect */
if (c->minay > 0 && c->maxay > 0
&& c->minax > 0 && c->maxax > 0)
{
if (w * c->maxay > h * c->maxax)
w = h * c->maxax / c->maxay;
else if (w * c->minay < h * c->minax)
h = w * c->minay / c->minax;
}
/* incremental */
if(c->incw)
w -= w % c->incw;
if(c->inch)
h -= h % c->inch;
/* base dimension */
w += c->basew;
h += c->baseh;
if(c->minw > 0 && w < c->minw)
w = c->minw;
if(c->minh > 0 && h < c->minh)
h = c->minh;
if(c->maxw > 0 && w > c->maxw)
w = c->maxw;
if(c->maxh > 0 && h > c->maxh)
h = c->maxh;
if(w <= 0 || h <= 0)
return;
}
/* }}} */
c->max = False;
if(c->x != x || c->y != y
|| c->w != w || c->h != h)
{
c->x = x; c->y = y;
c->w = w; c->h = h;
XMoveResizeWindow(dpy, c->win, x, y, w ,h);
if(conf.ttbarheight)
{
bar_moveresize(c->tbar, x, y - conf.ttbarheight, w, conf.ttbarheight);
if(conf.ttbarheight > 5)
XMoveWindow(dpy, c->button, BUTX(x, w), BUTY(y));
}
updatetitlebar(c);
XSync(dpy, False);
}
return;
}
void
uicb_quit(uicb_t cmd)
{
@ -675,24 +192,6 @@ uicb_quit(uicb_t cmd)
return;
}
void
raiseclient(Client *c)
{
if(!c)
return;
XRaiseWindow(dpy, c->win);
if(conf.ttbarheight)
{
XRaiseWindow(dpy, c->tbar->win);
if(conf.ttbarheight > 5)
XRaiseWindow(dpy, c->button);
updatetitlebar(c);
}
return;
}
/* scan all the client who was in X before wmfs */
void
scan(void)
@ -711,7 +210,7 @@ scan(void)
if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
continue;
if(wa.map_state == IsViewable)
manage(wins[i], &wa);
client_manage(wins[i], &wa);
}
}
if(wins)
@ -722,160 +221,6 @@ scan(void)
return;
}
void
setborder(Window win, int color)
{
if(!win)
return;
XSetWindowBorder(dpy, win, color);
XSetWindowBorderWidth(dpy, win, conf.borderheight);
return;
}
void
setwinstate(Window win, long state)
{
long data[] = {state, None};
XChangeProperty(dpy, win, wm_atom[WMState], wm_atom[WMState], 32,
PropModeReplace, (unsigned char *)data, 2);
return;
}
void
setsizehints(Client *c)
{
long msize;
XSizeHints size;
if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags)
size.flags = PSize;
/* base */
if(size.flags & PBaseSize)
{
c->basew = size.base_width;
c->baseh = size.base_height;
}
else if(size.flags & PMinSize)
{
c->basew = size.min_width;
c->baseh = size.min_height;
}
else
c->basew = c->baseh = 0;
/* inc */
if(size.flags & PResizeInc)
{
c->incw = size.width_inc;
c->inch = size.height_inc;
}
else
c->incw = c->inch = 0;
/* max */
if(size.flags & PMaxSize)
{
c->maxw = size.max_width;
c->maxh = size.max_height;
}
else
c->maxw = c->maxh = 0;
/* min */
if(size.flags & PMinSize)
{
c->minw = size.min_width;
c->minh = size.min_height;
}
else if(size.flags & PBaseSize)
{
c->minw = size.base_width;
c->minh = size.base_height;
}
else
c->minw = c->minh = 0;
/* aspect */
if(size.flags & PAspect)
{
c->minax = size.min_aspect.x;
c->maxax = size.max_aspect.x;
c->minay = size.min_aspect.y;
c->maxay = size.max_aspect.y;
}
else
c->minax = c->maxax = c->minay = c->maxay = 0;
c->hint = (c->maxw && c->minw && c->maxh && c->minh
&& c->maxw == c->minw && c->maxh == c->minh);
return;
}
void
unhide(Client *c)
{
if(!c)
return;
XMoveWindow(dpy, c->win, c->x, c->y);
if(conf.ttbarheight)
{
bar_moveresize(c->tbar, c->x, c->y - conf.ttbarheight, c->w, conf.ttbarheight);
if(conf.ttbarheight > 5)
XMoveWindow(dpy, c->button, BUTX(c->x, c->w), BUTY(c->y));
}
//mapclient(c);
setwinstate(c->win, NormalState);
c->hide = False;
return;
}
void
unmanage(Client *c)
{
XGrabServer(dpy);
XSetErrorHandler(errorhandlerdummy);
sel = ((sel == c) ? ((c->next) ? c->next : NULL) : NULL);
if(sel && sel->tag == seltag)
selbytag[seltag] = sel;
else
selbytag[seltag] = NULL;
detach(c);
if(conf.ttbarheight)
{
bar_delete(c->tbar);
if(conf.ttbarheight > 5)
{
XUnmapWindow(dpy, c->button);
XDestroyWindow(dpy, c->button);
}
}
setwinstate(c->win, WithdrawnState);
free(c);
XSync(dpy, False);
XUngrabServer(dpy);
arrange();
return;
}
void
unmapclient(Client *c)
{
if(!c)
return;
XUnmapWindow(dpy, c->win);
if(conf.ttbarheight)
{
XUnmapWindow(dpy, c->tbar->win);
if(conf.ttbarheight > 5)
XUnmapWindow(dpy, c->button);
}
return;
}
int
main(int argc, char **argv)
{

59
wmfs.h
View File

@ -64,9 +64,6 @@
#define ALT Mod1Mask
#define ITOA(p ,n) sprintf(p, "%i", n)
#define debug(p) fprintf(stderr, "debug: %i\n", p)
#define BUTY(y) y - conf.ttbarheight + 3
#define BUTH conf.ttbarheight - 6
#define BUTX(x, w) x + w - BUTH/400
#define PAD 8
#define BPAD 2
@ -88,8 +85,31 @@ void draw_taglist(Drawable dr);
void draw_layout(int x, int y);
void draw_rectangle(Drawable dr, int x, int y, uint w, uint h, uint color);
XImage* get_image_attribute(char *file);
void draw_border(Window win, int color);
ushort textw(const char *text);
/* client.c */
int clientpertag(int tag);
void client_attach(Client *c);
void client_detach(Client *c);
void client_switch(Bool c);
void client_focus(Client *c);
Client *getclient(Window w);
Client* client_gettbar(Window w);
void client_hide(Client *c);
Bool ishide(Client *c);
void mapclient(Client *c);
void client_manage(Window w, XWindowAttributes *wa);
void client_moveresize(Client *c, int x, int y, int w, int h, bool r);
void client_size_hints(Client *c);
void raiseclient(Client *c);
void client_unhide(Client *c);
void client_unmanage(Client *c);
void unmapclient(Client *c);
void uicb_client_prev(uicb_t);
void uicb_client_next(uicb_t);
void uicb_killclient(uicb_t);
/* config.c */
void init_conf(void);
@ -100,9 +120,12 @@ void destroynotify(XEvent ev);
void enternotify(XEvent ev);
void expose(XEvent ev);
void focusin(XEvent ev);
void grabbuttons(Client *c, Bool focused);
void grabkeys(void);
void keypress(XEvent ev);
void mapnotify(XEvent ev);
void maprequest(XEvent ev);
void mouseaction(Client *c, int x, int y, int type);
void propertynotify(XEvent ev);
void unmapnotify(XEvent ev);
void getevent(void);
@ -110,6 +133,7 @@ void getevent(void);
/* util.c */
void *emalloc(uint elemet, uint size);
ulong getcolor(char *color);
void setwinstate(Window win, long state);
void uicb_spawn(uicb_t);
/* tag.c */
@ -119,6 +143,7 @@ void uicb_tag_prev(uicb_t);
void uicb_tagtransfert(uicb_t);
/* layout.c */
void arrange(void);
void freelayout(void);
void layoutswitch(Bool b);
void maxlayout(void);
@ -132,39 +157,11 @@ void uicb_set_mwfact(uicb_t);
void uicb_set_nmaster(uicb_t);
/* wmfs.c */
void arrange(void);
void attach(Client *c);
int clientpertag(int tag);
void client_switch(Bool c);
void detach(Client *c);
int errorhandler(Display *d, XErrorEvent *event);
int errorhandlerdummy(Display *d, XErrorEvent *event);
void focus(Client *c);
Client* getbutton(Window w);
Client* getclient(Window w);
Client* getnext(Client *c);
Client* gettbar(Window w);
void grabbuttons(Client *c, Bool focused);
void grabkeys(void);
void hide(Client *c);
void init(void);
Bool ishide(Client *c);
void mainloop(void);
void mapclient(Client *c);
void manage(Window w, XWindowAttributes *wa);
void mouseaction(Client *c, int x, int y, int type);
void moveresize(Client *c, int x, int y, int w, int h, bool r);
void raiseclient(Client *c);
void scan(void);
void setborder(Window win, int color);
void setwinstate(Window win, long state);
void setsizehints(Client *c);
void unhide(Client *c);
void unmanage(Client *c);
void unmapclient(Client *c);
void uicb_client_prev(uicb_t);
void uicb_client_next(uicb_t);
void uicb_killclient(uicb_t);
void uicb_quit(uicb_t);
/* Variables */

4
wmfsrc
View File

@ -38,10 +38,6 @@ colors
#Titlebar
titlebar_text_focus = "#D4D4D4"
titlebar_text_normal = "#D4D4D4"
#Button
button = "#7E89A2"
button_border = "#3F485E"
}
layouts