all: Massive change: new way for window management, use frame

This commit is contained in:
Martin Duquesnoy 2008-11-08 20:32:11 +01:00
parent 0da49d84b4
commit ba425f172f
14 changed files with 374 additions and 367 deletions

View File

@ -38,7 +38,7 @@ set(wmfs_src
src/bar.c
src/draw.c
src/client.c
src/titlebar.c
src/frame.c
src/infobar.c)
# Set the executable from the wmfs_src

View File

@ -79,11 +79,11 @@ bar_delete(BarWindow *bw)
void
bar_map(BarWindow *bw)
{
if(!bw->mapped)
{
XMapRaised(dpy, bw->win);
bw->mapped = True;
}
CHECK(!bw->mapped);
XMapRaised(dpy, bw->win);
bw->mapped = True;
return;
}
@ -91,11 +91,10 @@ bar_map(BarWindow *bw)
void
bar_unmap(BarWindow *bw)
{
if(bw->mapped)
{
XUnmapWindow(dpy, bw->win);
bw->mapped = False;
}
CHECK(bw->mapped);
XUnmapWindow(dpy, bw->win);
bw->mapped = False;
return;
}

View File

@ -119,20 +119,24 @@ uicb_client_next(uicb_t cmd)
void
client_focus(Client *c)
{
Client *cc;
if(sel && sel != c)
{
sel->colors.frame = conf.client.bordernormal;
sel->colors.titlebar = conf.titlebar.fg_normal;
sel->colors.resizecorner = conf.client.resizecorner_normal;
frame_update(sel);
mouse_grabbuttons(sel, False);
XSetWindowBorder(dpy, sel->win, conf.client.bordernormal);
}
selbytag[seltag] = sel = c;
if(c)
{
c->colors.frame = conf.client.borderfocus;
c->colors.titlebar = conf.titlebar.fg_focus;
c->colors.resizecorner = conf.client.resizecorner_focus;
frame_update(c);
mouse_grabbuttons(c, True);
XSetWindowBorder(dpy, c->win, conf.client.borderfocus);
if(conf.raisefocus)
client_raise(c);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
@ -140,11 +144,6 @@ client_focus(Client *c)
else
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
/* Update all visible titlebar */
for(cc = clients; cc; cc = cc->next)
if(!ishide(cc))
titlebar_update(cc);
return;
}
@ -158,6 +157,19 @@ client_get(Window w)
return c;
}
void
client_get_name(Client *c)
{
XFetchName(dpy, c->win, &(c->title));
if(!c->title)
c->title = strdup("WMFS");
frame_update(c);
return;
}
void
client_hide(Client *c)
{
@ -182,8 +194,7 @@ uicb_client_kill(uicb_t cmd)
{
XEvent ev;
if(!sel)
return;
CHECK(sel);
ev.type = ClientMessage;
ev.xclient.window = sel->win;
@ -199,16 +210,10 @@ uicb_client_kill(uicb_t cmd)
void
client_map(Client *c)
{
if(!c)
return;
CHECK(c);
XMapWindow(dpy, c->win);
XMapSubwindows(dpy, c->win);
if(conf.titlebar.exist)
{
XMapWindow(dpy, c->tbar->win);
bar_refresh(c->tbar);
}
XMapWindow(dpy, c->frame);
XMapSubwindows(dpy, c->frame);
return;
}
@ -219,7 +224,6 @@ client_manage(Window w, XWindowAttributes *wa)
Client *c, *t = NULL;
Window trans;
Status rettrans;
XWindowChanges winc;
c = emalloc(1, sizeof(Client));
c->win = w;
@ -228,33 +232,24 @@ client_manage(Window w, XWindowAttributes *wa)
c->geo.width = wa->width;
c->geo.height = wa->height;
c->tag = seltag;
c->border = conf.client.borderheight;
/* Create titlebar */
if(conf.titlebar.exist)
titlebar_create(c);
frame_create(c);
winc.border_width = c->border;
XConfigureWindow(dpy, w, CWBorderWidth, &winc);
XSetWindowBorder(dpy, w, conf.client.bordernormal);
XSelectInput(dpy, c->win, PropertyChangeMask | StructureNotifyMask);
mouse_grabbuttons(c, False);
XSelectInput(dpy, w, EnterWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask);
client_size_hints(c);
titlebar_update(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;
if(t) c->tag = t->tag;
if(!c->free) c->free = (rettrans == Success) || c->hint;
efree(t);
client_attach(c);
XMoveResizeWindow(dpy, c->win, c->geo.x, c->geo.y, c->geo.width, c->geo.height);
client_map(c);
client_get_name(c);
client_raise(c);
setwinstate(c->win, NormalState);
client_focus(c);
setwinstate(c->win, NormalState);
arrange();
return;
@ -263,8 +258,7 @@ client_manage(Window w, XWindowAttributes *wa)
void
client_moveresize(Client *c, XRectangle geo, bool r)
{
if(!c)
return;
CHECK(c);
/* Resize hints {{{ */
if(r)
@ -319,13 +313,8 @@ client_moveresize(Client *c, XRectangle geo, bool r)
|| c->geo.height != geo.height)
{
c->geo = geo;
XMoveResizeWindow(dpy, c->win, geo.x, geo.y,
geo.width, geo.height);
if(conf.titlebar.exist)
titlebar_update_position(c);
titlebar_update(c);
frame_moveresize(c, geo);
XResizeWindow(dpy, c->win, geo.width, geo.height);
XSync(dpy, False);
}
@ -409,12 +398,7 @@ client_raise(Client *c)
if(!c || c->max || c->tile)
return;
XRaiseWindow(dpy, c->win);
if(conf.titlebar.exist)
{
XRaiseWindow(dpy, c->tbar->win);
titlebar_update(c);
}
XRaiseWindow(dpy, c->frame);
return;
}
@ -457,8 +441,10 @@ client_unmanage(Client *c)
* and set the withdraw state */
client_detach(c);
setwinstate(c->win, WithdrawnState);
if(conf.titlebar.exist)
titlebar_delete(c);
XDestroySubwindows(dpy, c->frame);
XDestroyWindow(dpy, c->frame);
XFree(c->title);
efree(c);
XSync(dpy, False);
arrange();
@ -469,13 +455,10 @@ client_unmanage(Client *c)
void
client_unmap(Client *c)
{
if(!c)
return;
CHECK(c);
XUnmapWindow(dpy, c->win);
XUnmapSubwindows(dpy, c->win);
if(conf.titlebar.exist)
XUnmapWindow(dpy, c->tbar->win);
XUnmapWindow(dpy, c->frame);
XUnmapSubwindows(dpy, c->frame);
return;
}

View File

@ -204,13 +204,9 @@ init_conf(void)
static cfg_opt_t titlebar_opts[] =
{
CFG_STR("position", "top", CFGF_NONE),
CFG_INT("height", 0, CFGF_NONE),
CFG_STR("bg_normal", "#090909", CFGF_NONE),
CFG_STR("bg_focus", "#090909", CFGF_NONE),
CFG_STR("fg_focus", "#FFFFFF", CFGF_NONE),
CFG_STR("fg_normal", "#FFFFFF", CFGF_NONE),
CFG_STR("text_align", "left", CFGF_NONE),
CFG_SEC("mouse", mouse_button_opts, CFGF_MULTI),
CFG_END()
};
@ -220,8 +216,11 @@ init_conf(void)
CFG_INT("border_height", 1, CFGF_NONE),
CFG_STR("border_normal", "#354B5C", CFGF_NONE),
CFG_STR("border_focus", "#6286A1", CFGF_NONE),
CFG_STR("resize_corner_normal", "#ff0000", CFGF_NONE),
CFG_STR("resize_corner_focus", "#ff0000", CFGF_NONE),
CFG_STR("modifier", "Alt", CFGF_NONE),
CFG_SEC("mouse", mouse_button_opts, CFGF_MULTI),
CFG_SEC("titlebar", titlebar_opts, CFGF_NONE),
CFG_END()
};
@ -294,7 +293,6 @@ init_conf(void)
CFG_SEC("misc", misc_opts, CFGF_NONE),
CFG_SEC("variables", variables_opts, CFGF_NONE),
CFG_SEC("root", root_opts, CFGF_NONE),
CFG_SEC("titlebar", titlebar_opts, CFGF_NONE),
CFG_SEC("client", client_opts, CFGF_NONE),
CFG_SEC("bar", bar_opts, CFGF_NONE),
CFG_SEC("layouts", layouts_opts, CFGF_NONE),
@ -308,15 +306,13 @@ init_conf(void)
cfg_t *cfg_bar;
cfg_t *cfg_variables;
cfg_t *cfg_root;
cfg_t *cfg_titlebar;
cfg_t *cfg_client;
cfg_t *cfg_layouts;
cfg_t *cfg_tags;
cfg_t *cfg_keys;
cfg_t *cfgtmp;
cfg_t *cfgtmp, *cfgtmp2;
char final_path[128];
char sfinal_path[128];
char buf[256] = {0};
int ret, i, j, l;
@ -338,7 +334,6 @@ init_conf(void)
cfg_misc = cfg_getsec(cfg, "misc");
cfg_variables = cfg_getsec(cfg, "variables");
cfg_root = cfg_getsec(cfg, "root");
cfg_titlebar = cfg_getsec(cfg, "titlebar");
cfg_client = cfg_getsec(cfg, "client");
cfg_bar = cfg_getsec(cfg, "bar");
cfg_layouts = cfg_getsec(cfg, "layouts");
@ -381,47 +376,15 @@ init_conf(void)
conf.root.mouse[i].cmd = strdup(var_to_str(cfg_getstr(cfgtmp, "cmd")));
}
/* titlebar */
strcpy(buf, var_to_str(cfg_getstr(cfg_titlebar, "position")));
if(strcmp(buf, "bottom") == 0)
conf.titlebar.pos = Bottom;
else if(strcmp(buf, "top") == 0)
conf.titlebar.pos = Top;
conf.titlebar.height = cfg_getint(cfg_titlebar, "height");
conf.titlebar.exist = conf.titlebar.height ? True : False;
conf.titlebar.bg_normal = getcolor(var_to_str(cfg_getstr(cfg_titlebar, "bg_normal")));
conf.titlebar.bg_focus = getcolor(var_to_str(cfg_getstr(cfg_titlebar, "bg_focus")));
conf.titlebar.fg_focus = var_to_str(cfg_getstr(cfg_titlebar, "fg_focus"));
conf.titlebar.fg_normal = var_to_str(cfg_getstr(cfg_titlebar, "fg_normal"));
strcpy(buf, var_to_str(cfg_getstr(cfg_titlebar, "text_align")));
if(strcmp(buf, "center") == 0)
conf.titlebar.text_align = Center;
else if(strcmp(buf, "right") == 0)
conf.titlebar.text_align = Right;
else if(strcmp(buf, "left") == 0)
conf.titlebar.text_align = Left;
conf.titlebar.nmouse = cfg_size(cfg_titlebar, "mouse");
conf.titlebar.mouse = emalloc(conf.titlebar.nmouse, sizeof(MouseBinding));
for(i = 0; i < conf.titlebar.nmouse; ++i)
{
cfgtmp = cfg_getnsec(cfg_titlebar, "mouse", i);
conf.titlebar.mouse[i].button = char_to_button(cfg_getstr(cfgtmp, "button"));
conf.titlebar.mouse[i].func = name_to_func(cfg_getstr(cfgtmp, "func"), func_list);
conf.titlebar.mouse[i].cmd = strdup(var_to_str(cfg_getstr(cfgtmp, "cmd")));
}
/* client */
conf.client.borderheight = cfg_getint(cfg_client, "border_height");
conf.client.bordernormal = getcolor(var_to_str(cfg_getstr(cfg_client, "border_normal")));
conf.client.borderfocus = getcolor(var_to_str(cfg_getstr(cfg_client, "border_focus")));
conf.client.mod |= char_to_modkey(cfg_getstr(cfg_client, "modifier"));
conf.client.nmouse = cfg_size(cfg_titlebar, "mouse");
conf.client.mouse = emalloc(conf.client.nmouse, sizeof(MouseBinding));
conf.client.borderheight = cfg_getint(cfg_client, "border_height");
conf.client.bordernormal = getcolor(var_to_str(cfg_getstr(cfg_client, "border_normal")));
conf.client.borderfocus = getcolor(var_to_str(cfg_getstr(cfg_client, "border_focus")));
conf.client.resizecorner_normal = getcolor(var_to_str(cfg_getstr(cfg_client, "resize_corner_normal")));
conf.client.resizecorner_focus = getcolor(var_to_str(cfg_getstr(cfg_client, "resize_corner_focus")));
conf.client.mod |= char_to_modkey(cfg_getstr(cfg_client, "modifier"));
conf.client.nmouse = cfg_size(cfg_client, "mouse");
conf.client.mouse = emalloc(conf.client.nmouse, sizeof(MouseBinding));
for(i = 0; i < conf.client.nmouse; ++i)
{
@ -431,6 +394,22 @@ init_conf(void)
conf.client.mouse[i].cmd = strdup(var_to_str(cfg_getstr(cfgtmp, "cmd")));
}
/* titlebar (in client) */
cfgtmp = cfg_getsec(cfg_client, "titlebar");
conf.titlebar.height = cfg_getint(cfgtmp, "height");
conf.titlebar.fg_focus = var_to_str(cfg_getstr(cfgtmp, "fg_focus"));
conf.titlebar.fg_normal = var_to_str(cfg_getstr(cfgtmp, "fg_normal"));
conf.titlebar.nmouse = cfg_size(cfgtmp, "mouse");
conf.titlebar.mouse = emalloc(conf.titlebar.nmouse, sizeof(MouseBinding));
for(i = 0; i < conf.titlebar.nmouse; ++i)
{
cfgtmp2 = cfg_getnsec(cfgtmp, "mouse", i);
conf.titlebar.mouse[i].button = char_to_button(cfg_getstr(cfgtmp2, "button"));
conf.titlebar.mouse[i].func = name_to_func(cfg_getstr(cfgtmp2, "func"), func_list);
conf.titlebar.mouse[i].cmd = strdup(var_to_str(cfg_getstr(cfgtmp2, "cmd")));
}
/* layout */
conf.colors.layout_fg = strdup(var_to_str(cfg_getstr(cfg_layouts, "fg")));

View File

@ -40,13 +40,16 @@ buttonpress(XEvent ev)
int i;
char s[6];
/* Titlebar */
if(conf.titlebar.exist)
if((c = titlebar_get(ev.xbutton.window)))
for(i = 0; i < conf.titlebar.nmouse; ++i)
if(ev.xbutton.button == conf.titlebar.mouse[i].button)
if(conf.titlebar.mouse[i].func)
conf.titlebar.mouse[i].func(conf.titlebar.mouse[i].cmd);
/* Frame & titlebar */
if((c = frame_get_titlebar(ev.xbutton.window)))
for(i = 0; i < conf.titlebar.nmouse; ++i)
if(ev.xbutton.button == conf.titlebar.mouse[i].button)
if(conf.titlebar.mouse[i].func)
conf.titlebar.mouse[i].func(conf.titlebar.mouse[i].cmd);
/* Frame Resize Area */
if((c = frame_get_resize(ev.xbutton.window)))
mouse_resize(c);
/* Client */
if((c = client_get(ev.xbutton.window)))
@ -123,9 +126,11 @@ configurerequest(XEvent ev)
Client *c;
XWindowChanges wc;
XRectangle geo;
if((c = client_get(ev.xconfigurerequest.window)))
if(c->tile || c->lmax)
if(c->tile || c->lmax)
return;
geo.x = wc.x = ev.xconfigurerequest.x;
geo.y = wc.y = ev.xconfigurerequest.y;
geo.width = wc.width = ev.xconfigurerequest.width;
@ -133,11 +138,18 @@ configurerequest(XEvent ev)
wc.border_width = ev.xconfigurerequest.border_width;
wc.sibling = ev.xconfigurerequest.above;
wc.stack_mode = ev.xconfigurerequest.detail;
XConfigureWindow(dpy, ev.xconfigurerequest.window,
ev.xconfigurerequest.value_mask, &wc);
if((c = client_get(ev.xconfigurerequest.window)))
if(wc.y < MAXW && wc.x < MAXH)
client_moveresize(c, geo, True);
{
client_moveresize(c, geo, True);
XReparentWindow(dpy, c->win, c->frame,
conf.client.borderheight,
conf.titlebar.height + conf.client.borderheight);
}
XSync(dpy, False);
return;
}
@ -163,7 +175,9 @@ enternotify(XEvent ev)
|| ev.xcrossing.detail == NotifyInferior)
return;
if((c = client_get(ev.xcrossing.window))
|| (c = titlebar_get(ev.xcrossing.window)))
|| (c = frame_get(ev.xcrossing.window))
|| (c = frame_get_titlebar(ev.xcrossing.window))
|| (c = frame_get_resize(ev.xcrossing.window)))
client_focus(c);
else
client_focus(NULL);
@ -181,10 +195,9 @@ expose(XEvent ev)
&& (ev.xexpose.window == infobar.bar->win))
infobar_draw();
if(conf.titlebar.exist)
for(c = clients; c; c = c->next)
if(ev.xexpose.window == c->tbar->win)
titlebar_update(c);
for(c = clients; c; c = c->next)
if(ev.xexpose.window == c->titlebar)
frame_update(c);
return;
}
@ -253,10 +266,8 @@ maprequest(XEvent ev)
{
XWindowAttributes at;
if(!XGetWindowAttributes(dpy, ev.xmaprequest.window, &at))
return;
if(at.override_redirect)
return;
CHECK(XGetWindowAttributes(dpy, ev.xmaprequest.window, &at));
CHECK(!at.override_redirect);
if(!client_get(ev.xmaprequest.window))
client_manage(ev.xmaprequest.window, &at);
@ -289,7 +300,7 @@ propertynotify(XEvent ev)
}
if(ev.xproperty.atom == XA_WM_NAME
|| ev.xproperty.atom == net_atom[NetWMName])
titlebar_update(c);
client_get_name(c);
}
return;

173
src/frame.c Normal file
View File

@ -0,0 +1,173 @@
/*
* frame.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"
void
frame_create(Client *c)
{
XSetWindowAttributes at;
at.background_pixel = conf.client.bordernormal;
at.background_pixmap = ParentRelative;
at.override_redirect = True;
at.event_mask = SubstructureRedirectMask | SubstructureNotifyMask |
ExposureMask | VisibilityChangeMask | EnterWindowMask |
FocusChangeMask | KeyMask | ButtonMask | MouseMask;
/* Set size */
c->frame_geo.x = c->geo.x - conf.client.borderheight;
c->frame_geo.y = c->geo.y - conf.titlebar.height;
c->frame_geo.width = FRAMEW(c->geo.width);
c->frame_geo.height = FRAMEH(c->geo.height);
c->colors.frame = conf.client.bordernormal;
c->colors.resizecorner = conf.client.resizecorner_normal;
c->colors.titlebar = conf.titlebar.fg_normal;
/* Create frame window */
c->frame = XCreateWindow(dpy, root,
c->frame_geo.x,
c->frame_geo.y,
c->frame_geo.width,
c->frame_geo.height, 0,
CopyFromParent, InputOutput, CopyFromParent,
CWOverrideRedirect|CWBackPixmap|CWEventMask, &at);
/* Create titlebar window */
c->titlebar = XCreateWindow(dpy, c->frame, 0, 0,
c->frame_geo.width,
TBARH + BORDH, 0,
CopyFromParent, InputOutput, CopyFromParent,
CWEventMask|CWBackPixel, &at);
/* Create resize area */
at.cursor = cursor[CurResize];
c->resize = XCreateWindow(dpy, c->frame,
c->frame_geo.width - RESHW,
c->frame_geo.height - RESHW,
RESHW, RESHW, 0, CopyFromParent,
InputOutput, CopyFromParent,
CWEventMask|CWBackPixel|CWCursor, &at);
/* Color it */
XSetWindowBackground(dpy, c->resize, c->colors.resizecorner);
XSetWindowBackground(dpy, c->titlebar, c->colors.frame);
XSetWindowBackground(dpy, c->frame, c->colors.frame);
/* Reparent window with the frame */
XReparentWindow(dpy, c->win, c->frame,
conf.client.borderheight,
conf.titlebar.height + conf.client.borderheight);
return;
}
void
frame_moveresize(Client *c, XRectangle geo)
{
c->frame_geo.x = geo.x - conf.client.borderheight;
c->frame_geo.y = geo.y - conf.titlebar.height;
c->frame_geo.width = FRAMEW(geo.width);
c->frame_geo.height = FRAMEH(geo.height);
/* Frame */
XMoveResizeWindow(dpy, c->frame,
c->frame_geo.x,
c->frame_geo.y,
c->frame_geo.width,
c->frame_geo.height);
/* Titlebar */
XResizeWindow(dpy, c->titlebar, c->frame_geo.width, TBARH + BORDH);
/* Resize area */
XMoveWindow(dpy, c->resize, c->frame_geo.width - RESHW, c->frame_geo.height - RESHW);
return;
}
void
frame_update(Client *c)
{
int px, py;
XSetWindowBackground(dpy, c->frame, c->colors.frame);
XSetWindowBackground(dpy, c->titlebar, c->colors.frame);
XSetWindowBackground(dpy, c->resize, c->colors.resizecorner);
XClearWindow(dpy, c->frame);
XClearWindow(dpy, c->titlebar);
XClearWindow(dpy, c->resize);
/* Draw the client title \in the titlebar *logeek* */
if((conf.titlebar.height + BORDH + 1) > font->height)
{
/* x position of the text (center) */
px = (c->frame_geo.width / 2) - (textw(c->title) / 2);
/* y position of the text (center too) */
py = (font->height - (font->descent )) + (((TBARH + BORDH) - font->height) / 2);
draw_text(c->titlebar, px, py, c->colors.titlebar, c->colors.frame, 0, c->title);
}
return;
}
Client*
frame_get(Window w)
{
Client *c;
for(c = clients; c && c->frame != w; c = c->next);
return c;
}
Client*
frame_get_titlebar(Window w)
{
Client *c;
for(c = clients; c && c->titlebar != w; c = c->next);
return c;
}
Client*
frame_get_resize(Window w)
{
Client *c;
for(c = clients; c && c->resize != w; c = c->next);
return c;
}

View File

@ -190,9 +190,10 @@ uicb_infobar_togglepos(uicb_t cmd)
{
conf.bartop = !conf.bartop;
if(conf.bartop)
sgeo.y = conf.titlebar.pos ? infobar.geo.height : infobar.geo.height + conf.titlebar.height;
sgeo.y = infobar.geo.height + TBARH;
else
sgeo.y = conf.titlebar.pos ? 0 : conf.titlebar.height;
sgeo.y = TBARH;
infobar.geo.y = (conf.bartop) ? 0 : MAXH - infobar.geo.height;
bar_move(infobar.bar, 0, infobar.geo.y);
infobar_draw();

View File

@ -49,7 +49,7 @@ init(void)
grabkeys();
/* Warning about font */
if(conf.titlebar.height < font->height)
if(TBARH + BORDH < font->height)
fprintf(stderr, "WMFS Warning: Font too big, can't draw any text in the titlebar.\n");
return;
@ -122,7 +122,6 @@ init_root(void)
SubstructureRedirectMask | SubstructureNotifyMask |
EnterWindowMask | LeaveWindowMask | StructureNotifyMask ;
at.cursor = cursor[CurNormal];
at.override_redirect = 1;
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &at);
if(conf.root.background_command)
uicb_spawn(conf.root.background_command);
@ -133,18 +132,16 @@ init_root(void)
void
init_geometry(void)
{
sgeo.y = sgeo.x = 0;
sgeo.x = BORDH;
sgeo.y = infobar.geo.height;
if(conf.bartop)
sgeo.y = (conf.titlebar.pos)
? infobar.geo.height
: infobar.geo.height + conf.titlebar.height;
sgeo.y += TBARH;
else
if(conf.titlebar.pos)
sgeo.y = conf.titlebar.height;
sgeo.y = TBARH;
sgeo.width = MAXW;
sgeo.height = MAXH - (infobar.geo.height + conf.titlebar.height);
sgeo.height = MAXH - infobar.geo.height - TBARH;
return;
}

View File

@ -179,8 +179,7 @@ uicb_set_mwfact(uicb_t cmd)
{
double c;
if(!(sscanf(cmd, "%lf", &c)))
return;
CHECK((sscanf(cmd, "%lf", &c)));
if(tags[seltag].mwfact + c > 0.95
|| tags[seltag].mwfact + c < 0.05)
@ -216,11 +215,10 @@ grid(void)
Client *c;
XRectangle cgeo = {sgeo.x, sgeo.y, 0, 0};
unsigned int i, n, cols, rows, cpcols = 0;
unsigned int border = conf.client.borderheight * 2;
unsigned int border = BORDH * 2;
for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next), ++n);
if(!n)
return;
CHECK(n);
for(rows = 0; rows <= n / 2; ++rows)
if(rows * rows >= n)
@ -248,13 +246,13 @@ grid(void)
/* Last column's client remainder */
if(i >= rows * (cols - 1))
cgeo.width = sgeo.width - cgeo.x - border;
cgeo.width = sgeo.width - cgeo.x - BORDH;
/* Resize */
client_moveresize(c, cgeo, tags[seltag].resizehint);
/* Set all the other size with current client info */
cgeo.y = c->geo.y + c->geo.height + border + conf.titlebar.height;
cgeo.y = c->geo.y + c->geo.height + border + TBARH;
if(cpcols + 1 > rows)
{
cpcols = 0;
@ -273,11 +271,10 @@ multi_tile(Position type)
XRectangle mastergeo = {sgeo.x, sgeo.y, 0, 0};
XRectangle cgeo = {sgeo.x, sgeo.y, 0, 0};
uint i , n, tilesize, mwfact, nmaster = tags[seltag].nmaster;
uint border = conf.client.borderheight * 2;
uint border = BORDH * 2;
for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next), ++n);
if(!n)
return;
CHECK(n);
/* FIX NMASTER */
nmaster = (n < nmaster) ? n : nmaster;
@ -292,13 +289,13 @@ multi_tile(Position type)
{
if(type == Top)
mastergeo.y = (n <= nmaster) ? sgeo.y : sgeo.y + (sgeo.height - mwfact) - border;
mastergeo.width = (sgeo.width / nmaster) - border;
mastergeo.height = (n <= nmaster) ? sgeo.height - border : mwfact;
mastergeo.width = (sgeo.width / nmaster) - BORDH;
mastergeo.height = (n <= nmaster) ? sgeo.height - BORDH : mwfact;
}
else
{
if(type == Left)
mastergeo.x = (n <= nmaster) ? sgeo.x : sgeo.width - mwfact - border;
mastergeo.x = (n <= nmaster) ? sgeo.x : sgeo.width - mwfact - BORDH;
mastergeo.width = (n <= nmaster) ? sgeo.width - border : mwfact;
mastergeo.height = (sgeo.height / nmaster) - border;
}
@ -332,7 +329,7 @@ multi_tile(Position type)
else
{
cgeo.x = mastergeo.x;
cgeo.height -= (conf.titlebar.height + border);
cgeo.height -= (TBARH + border);
}
}
@ -349,7 +346,7 @@ multi_tile(Position type)
cgeo.x = sgeo.x;
break;
case Bottom:
cgeo.y += mastergeo.height + conf.titlebar.height + border;
cgeo.y += mastergeo.height + TBARH + border;
cgeo.x = sgeo.x;
break;
default:
@ -363,13 +360,13 @@ multi_tile(Position type)
{
cgeo.width = tilesize;
cgeo.width -= border;
cgeo.height = sgeo.height - mastergeo.height - conf.titlebar.height - border*2;
cgeo.height = sgeo.height - mastergeo.height - TBARH - border*2;
}
else
{
cgeo.width = sgeo.width - mastergeo.width - border*2;
cgeo.height = tilesize;
cgeo.height -= border + conf.titlebar.height;
cgeo.height -= border + TBARH;
}
}
@ -377,7 +374,7 @@ multi_tile(Position type)
if(i + 1 == n || i + 1 == (n < nmaster ? n : nmaster))
{
if(type == Top || type == Bottom)
cgeo.width = sgeo.width - cgeo.x - border;
cgeo.width = sgeo.width - cgeo.x - BORDH;
else
cgeo.height = (sgeo.y + sgeo.height) - cgeo.y - border;
}

View File

@ -96,7 +96,7 @@ mouse_resize(Client *c)
return;
if(!c->tile)
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->geo.width, c->geo.height);
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->geo.width + conf.client.borderheight, c->geo.height);
/* Warp pointer for mwfact resize {{{ */
if(c->tile)
@ -126,7 +126,7 @@ mouse_resize(Client *c)
if(ev.type == ButtonRelease)
{
if(!c->tile)
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->geo.width, c->geo.height);
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->geo.width + conf.client.borderheight, c->geo.height);
XUngrabPointer(dpy, CurrentTime);
return;
}
@ -142,7 +142,7 @@ mouse_resize(Client *c)
}
else
{
fy = (round(((ev.xmotion.y * 50) / sgeo.height))) / 50;
fy = (round(((ev.xmotion.y * 50) / sgeo.height))) / 50;
fx = (round(((ev.xmotion.x * 50) / sgeo.width))) / 50;
if(tags[seltag].layout.func == tile)
@ -200,8 +200,8 @@ mouse_grabbuttons(Client *c, Bool focused)
void
uicb_mouse_move(uicb_t cmd)
{
if(sel)
mouse_move(sel);
CHECK(sel);
mouse_move(sel);
return;
}
@ -209,8 +209,8 @@ uicb_mouse_move(uicb_t cmd)
void
uicb_mouse_resize(uicb_t cmd)
{
if(sel)
mouse_resize(sel);
CHECK(sel);
mouse_resize(sel);
return;
}

View File

@ -37,7 +37,6 @@
#define NBUTTON 8
#define MAXTAG 36
#define NUM_OF_LAYOUT 7
/* Typedef */
@ -75,16 +74,23 @@ struct Client
int tag;
/* Window attribute */
XRectangle geo;
XRectangle frame_geo;
/* Old window attribute */
XRectangle ogeo;
/* For resizehint usage */
int basew, baseh, incw, inch;
int maxw, maxh, minw, minh;
int minax, maxax, minay, maxay;
/* Window */
/* Client composant */
Window win;
/* Titlebar */
BarWindow *tbar;
Window frame;
Window resize, titlebar;
struct
{
uint frame;
uint resizecorner;
char *titlebar;
} colors;
/* Border */
int border;
/* Client Layout Information */
@ -185,20 +191,17 @@ typedef struct
int borderheight;
uint bordernormal;
uint borderfocus;
uint resizecorner_normal;
uint resizecorner_focus;
uint mod;
MouseBinding *mouse;
int nmouse;
} client;
struct
{
Bool exist;
Position pos;
int height;
uint bg_normal;
uint bg_focus;
char *fg_focus;
char *fg_normal;
Position text_align;
MouseBinding *mouse;
int nmouse;
} titlebar;

View File

@ -1,147 +0,0 @@
/*
* titlebar.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"
void
titlebar_create(Client *c)
{
c->tbar = bar_create(c->geo.x, c->geo.y, c->geo.width,
conf.titlebar.height - conf.client.borderheight,
0, conf.titlebar.bg_normal, True);
titlebar_update_position(c);
return;
}
void
titlebar_delete(Client *c)
{
if(c->title)
XFree(c->title);
bar_delete(c->tbar);
c->tbar = NULL;
return;
}
Client*
titlebar_get(Window w)
{
Client *c;
if(!conf.titlebar.exist)
return NULL;
for(c = clients; c && c->tbar->win != w; c = c->next);
return c;
}
void
titlebar_update_position(Client *c)
{
int y;
/* Set titlebar position : Top/Bottom */
switch(conf.titlebar.pos)
{
default:
case Top:
y = c->geo.y - conf.titlebar.height;
break;
case Bottom:
y = c->geo.y + c->geo.height + conf.client.borderheight;
break;
}
bar_move(c->tbar, c->geo.x, y);
bar_resize(c->tbar, c->geo.width + c->border * 2, conf.titlebar.height);
return;
}
void
titlebar_update(Client *c)
{
int pos_y, pos_x;
uint bg;
char *fg;
/* Get the window name, will be free by XFree later... */
XFetchName(dpy, c->win, &(c->title));
if(!c->title)
c->title = strdup("WMFS");
if(!conf.titlebar.exist)
return;
/* Set titlebar color */
bg = (c == sel)
? conf.titlebar.bg_focus
: conf.titlebar.bg_normal;
fg = (c == sel)
? conf.titlebar.fg_focus
: conf.titlebar.fg_normal;
c->tbar->color = bg;
/* Refresh titlebar color */
bar_refresh_color(c->tbar);
/* Draw the client title in the titlebar *logeek* */
if(conf.titlebar.height + 1 > font->height)
{
/* Set the text alignement */
switch(conf.titlebar.text_align)
{
case Center:
pos_x = (c->geo.width / 2) - (textw(c->title) / 2);
break;
case Right:
pos_x = c->geo.width - textw(c->title) - 2;
break;
default:
case Left:
pos_x = 2;
break;
}
/* Set y text position (always at the middle) and fg color */
pos_y = (font->height - (font->descent )) + ((conf.titlebar.height - font->height) / 2);
/* Draw title */
draw_text(c->tbar->dr, pos_x, pos_y, fg, bg, 0, c->title);
}
bar_refresh(c->tbar);
return;
}

View File

@ -53,12 +53,21 @@
#include "config.h"
#include "structs.h"
/* Defines */
/* MACRO */
#define ButtonMask (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask)
#define MouseMask (ButtonMask | PointerMotionMask)
#define KeyMask (KeyPressMask | KeyReleaseMask)
#define MAXH DisplayHeight(dpy, screen)
#define MAXW DisplayWidth(dpy, screen)
#define FRAMEW(w) w + conf.client.borderheight * 2
#define FRAMEH(h) h + (conf.client.borderheight * 2) + conf.titlebar.height
#define BORDH conf.client.borderheight
#define TBARH conf.titlebar.height
#define RESHW 15
#define CHECK(x) if(!x) return
#define ITOA(p ,n) sprintf(p, "%d", n)
#define debug(p) fprintf(stderr, "debug: %d\n", p)
#define PAD 8
@ -91,6 +100,7 @@ void client_attach(Client *c);
void client_detach(Client *c);
void client_focus(Client *c);
Client *client_get(Window w);
void client_get_name(Client *c);
void client_hide(Client *c);
Bool ishide(Client *c);
void client_map(Client *c);
@ -106,6 +116,15 @@ void uicb_client_prev(uicb_t);
void uicb_client_next(uicb_t);
void uicb_client_kill(uicb_t);
/* frame.c */
void frame_create(Client *c);
void frame_moveresize(Client *c, XRectangle geo);
Client* frame_get(Window w);
void frame_update(Client *c);
void frame_set_color(Client *c, uint bg);
Client* frame_get_titlebar(Window w);
Client* frame_get_resize(Window w);
/* config.c */
void init_conf(void);
@ -146,13 +165,6 @@ void uicb_tag_next(uicb_t);
void uicb_tag_prev(uicb_t);
void uicb_tagtransfert(uicb_t);
/* titlebar.c */
void titlebar_create(Client *c);
void titlebar_delete(Client *c);
Client* titlebar_get(Window w);
void titlebar_update_position(Client *c);
void titlebar_update(Client *c);
/* layout.c */
void arrange(void);
void freelayout(void);
@ -160,14 +172,13 @@ void layoutswitch(Bool b);
void layout_tile_switch(Bool b);
void maxlayout(void);
Client *nexttiled(Client *c);
/* tile */
void grid(void);
void tile(void);
void tile_left(void);
void tile_top(void);
void tile_bottom(void);
/* tile {{{ */
void grid(void);
void tile(void);
void tile_left(void);
void tile_top(void);
void tile_bottom(void);
/* }}} */
void uicb_tile_switch(uicb_t);
void uicb_togglemax(uicb_t);
void uicb_layout_prev(uicb_t);

40
wmfsrc
View File

@ -66,34 +66,34 @@ root
client
{
border_height = 2
border_normal = "#191919"
border_focus = "#003366"
modifier = "Alt"
border_height = 3
border_normal = "#191919"
border_focus = "#003366"
resize_corner_normal = "#191919"
resize_corner_focus = "#771103"
modifier = "Alt"
mouse { button = "1" func = "client_raise" }
mouse { button = "1" func = "mouse_move" }
mouse { button = "2" func = "tile_switch" }
mouse { button = "3" func = "client_raise" }
mouse { button = "3" func = "mouse_resize" }
titlebar
{
height = 11
fg_normal = "#B4B4B4"
fg_focus = "#D4D4D4"
mouse { button = "1" func = "client_raise" }
mouse { button = "1" func = "mouse_move" }
mouse { button = "2" func = "tile_switch" }
mouse { button = "3" func = "client_raise" }
mouse { button = "3" func = "mouse_resize" }
}
}
titlebar
{
position = "top"
height = 12
bg_normal = "#191919"
bg_focus = "#003366"
fg_normal = "#D4D4D4"
fg_focus = "#B4B4B4"
text_align = "center"
mouse { button = "1" func = "client_raise" }
mouse { button = "1" func = "mouse_move" }
mouse { button = "2" func = "client_kill" }
mouse { button = "3" func = "client_raise" }
mouse { button = "3" func = "mouse_resize" }
}
keys
{