wmfs: NEW IMPORTANT FEATURE: Add multi-head support #1

This commit is contained in:
Martin Duquesnoy 2008-11-30 03:01:30 +01:00
parent 3f22499bd2
commit 8f5fee389d
16 changed files with 431 additions and 272 deletions

View File

@ -38,6 +38,7 @@ set(wmfs_src
src/init.c src/init.c
src/layout.c src/layout.c
src/mouse.c src/mouse.c
src/screen.c
src/tag.c src/tag.c
src/util.c src/util.c
src/wmfs.c) src/wmfs.c)
@ -78,7 +79,8 @@ set(LIBRARIES_TO_LINK
${FREETYPE_LIBRARIES} ${FREETYPE_LIBRARIES}
${X11_LIBRARIES} ${X11_LIBRARIES}
confuse confuse
Xft) Xft
Xinerama)
target_link_libraries(wmfs ${LIBRARIES_TO_LINK}) target_link_libraries(wmfs ${LIBRARIES_TO_LINK})

View File

@ -249,7 +249,8 @@ barwin_refresh_color(BarWindow *bw)
void void
barwin_refresh(BarWindow *bw) barwin_refresh(BarWindow *bw)
{ {
CHECK(bw); if(!bw || !bw->dr || !bw->win)
return;
XCopyArea(dpy, bw->dr, bw->win, gc, 0, 0, bw->geo.width, bw->geo.height, 0, 0); XCopyArea(dpy, bw->dr, bw->win, gc, 0, 0, bw->geo.width, bw->geo.height, 0, 0);

View File

@ -107,7 +107,6 @@ uicb_client_prev(uicb_t cmd)
client_focus(c); client_focus(c);
client_raise(c); client_raise(c);
} }
arrange();
return; return;
} }
@ -131,7 +130,6 @@ uicb_client_next(uicb_t cmd)
client_focus(c); client_focus(c);
client_raise(c); client_raise(c);
} }
arrange();
return; return;
} }
@ -150,7 +148,7 @@ client_focus(Client *c)
mouse_grabbuttons(sel, False); mouse_grabbuttons(sel, False);
} }
selbytag[seltag] = sel = c; sel = c;
if(c) if(c)
{ {
@ -168,8 +166,8 @@ client_focus(Client *c)
return; return;
} }
/* The following function are the same point : /* The following function have the same point :
* find a client membere with a Window {{{ * find a client member with a Window {{{
*/ */
/* Get Client with a window */ /* Get Client with a window */
@ -227,6 +225,7 @@ client_focus(Client *c)
return c; return c;
} }
/* }}} */ /* }}} */
/** Get a client name /** Get a client name
@ -266,7 +265,7 @@ client_hide(Client *c)
Bool Bool
ishide(Client *c) ishide(Client *c)
{ {
if(c->tag && c->tag == seltag) if(c->tag && c->tag == seltag[screen_get_sel()])
return False; return False;
return True; return True;
} }
@ -360,11 +359,12 @@ client_manage(Window w, XWindowAttributes *wa)
c = emalloc(1, sizeof(Client)); c = emalloc(1, sizeof(Client));
c->win = w; c->win = w;
c->screen = screen_get_sel();
c->ogeo.x = c->geo.x = wa->x; c->ogeo.x = c->geo.x = wa->x;
c->ogeo.y = c->geo.y = wa->y + sgeo.y; c->ogeo.y = c->geo.y = wa->y + TBARH + INFOBARH;
c->ogeo.width = c->geo.width = wa->width; c->ogeo.width = c->geo.width = wa->width;
c->ogeo.height = c->geo.height = wa->height; c->ogeo.height = c->geo.height = wa->height;
c->tag = seltag; c->tag = seltag[c->screen];
at.event_mask = PropertyChangeMask; at.event_mask = PropertyChangeMask;
frame_create(c); frame_create(c);
@ -399,6 +399,8 @@ client_moveresize(Client *c, XRectangle geo, bool r)
{ {
CHECK(c); CHECK(c);
int i;
/* Resize hints {{{ */ /* Resize hints {{{ */
if(r) if(r)
{ {
@ -452,6 +454,13 @@ client_moveresize(Client *c, XRectangle geo, bool r)
|| c->geo.height != geo.height) || c->geo.height != geo.height)
{ {
c->geo = geo; c->geo = geo;
/* Set the client screen */
for(i = 0; i < screen_count(); ++i)
if(geo.x >= screen_get_geo(i).x
&& geo.x < screen_get_geo(i).x + screen_get_geo(i).width)
c->screen = i;
frame_moveresize(c, geo); frame_moveresize(c, geo);
XMoveResizeWindow(dpy, c->win, BORDH, BORDH + TBARH, geo.width, geo.height); XMoveResizeWindow(dpy, c->win, BORDH, BORDH + TBARH, geo.width, geo.height);
XSync(dpy, False); XSync(dpy, False);

View File

@ -484,10 +484,18 @@ init_conf(void)
} }
} }
seltag = 1;
prevtag = 0; seltag = emalloc(screen_count(), sizeof(int));
for(i = 0; i < conf.ntag; ++i)
tags[i + 1] = conf.tag[i]; //tags = emalloc(screen_count(), sizeof(Tag*));
for(j = 0; j < screen_count(); ++j)
{
//tags[j] = emalloc(conf.ntag, sizeof(Tag));
seltag[j] = 1;
for(i = 0; i < conf.ntag; ++i)
tags[j][i + 1] = conf.tag[i];
}
/* keybind */ /* keybind */
conf.nkeybind = cfg_size(cfg_keys, "key"); conf.nkeybind = cfg_size(cfg_keys, "key");

View File

@ -42,6 +42,8 @@ buttonpress(XButtonEvent *ev)
int i; int i;
char s[6]; char s[6];
screen_get_sel();
/* Titlebar */ /* Titlebar */
if((c = client_gb_titlebar(ev->window))) if((c = client_gb_titlebar(ev->window)))
for(i = 0; i < conf.titlebar.nmouse; ++i) for(i = 0; i < conf.titlebar.nmouse; ++i)
@ -63,7 +65,7 @@ buttonpress(XButtonEvent *ev)
/* Root */ /* Root */
if(ev->window == root) if(ev->window == root)
for(i = 0; i < conf.root.nmouse; ++i) for(i = 0; i < conf.root.nmouse; ++i)
if(conf.root.mouse[i].tag == seltag if(conf.root.mouse[i].tag == seltag[selscreen]
|| conf.root.mouse[i].tag < 0) || conf.root.mouse[i].tag < 0)
if(ev->button == conf.root.mouse[i].button) if(ev->button == conf.root.mouse[i].button)
if(conf.root.mouse[i].func) if(conf.root.mouse[i].func)
@ -73,7 +75,7 @@ buttonpress(XButtonEvent *ev)
for(i = 1; i < conf.ntag + 1; ++i) for(i = 1; i < conf.ntag + 1; ++i)
{ {
ITOA(s, i); ITOA(s, i);
if(ev->window == infobar->tags[i]->win) if(ev->window == infobar[screen_get_sel()].tags[i]->win)
{ {
if(ev->button == Button1) if(ev->button == Button1)
uicb_tag(s); uicb_tag(s);
@ -87,7 +89,7 @@ buttonpress(XButtonEvent *ev)
} }
/* Layout button */ /* Layout button */
if(ev->window == infobar->layout_button->win) if(ev->window == infobar[screen_get_sel()].layout_button->win)
{ {
if(ev->button == Button1 if(ev->button == Button1
|| ev->button == Button4) || ev->button == Button4)
@ -202,18 +204,21 @@ void
expose(XExposeEvent *ev) expose(XExposeEvent *ev)
{ {
Client *c; Client *c;
int i; int i, sc;
if(ev->count == 0
&& (ev->window == infobar->bar->win))
barwin_refresh(infobar->bar);
for(i = 1; i < conf.ntag + 1; ++i) for(sc = 0; sc > screen_count(); ++sc)
if(ev->window == infobar->tags[i]->win) {
barwin_refresh(infobar->tags[i]); if(ev->window == infobar[sc].bar->win)
barwin_refresh(infobar[sc].bar);
if(ev->window == infobar->layout_button->win) for(i = 1; i < conf.ntag + 1; ++i)
barwin_refresh(infobar->layout_button); if(ev->window == infobar[sc].tags[i]->win)
barwin_refresh(infobar[sc].tags[i]);
if(ev->window == infobar[sc].layout_button->win)
barwin_refresh(infobar[sc].layout_button);
}
if((c = client_gb_titlebar(ev->window))) if((c = client_gb_titlebar(ev->window)))
frame_update(c); frame_update(c);
@ -239,25 +244,17 @@ focusin(XFocusChangeEvent *ev)
void void
grabkeys(void) grabkeys(void)
{ {
uint i, j; uint i;
KeyCode code; KeyCode code;
uint ml[] =
{
LockMask,
numlockmask,
scrolllockmask,
numlockmask|scrolllockmask,
LockMask|scrolllockmask,
LockMask|numlockmask,
LockMask|numlockmask|scrolllockmask
};
XUngrabKey(dpy, AnyKey, AnyModifier, root); XUngrabKey(dpy, AnyKey, AnyModifier, root);
for(i = 0; i < conf.nkeybind; ++i) for(i = 0; i < conf.nkeybind; ++i)
{ {
code = XKeysymToKeycode(dpy, keys[i].keysym); code = XKeysymToKeycode(dpy, keys[i].keysym);
for(j = 0; j < (sizeof ml / sizeof ml[0]); ++j) XGrabKey(dpy, code, keys[i].mod, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, keys[i].mod|ml[j], 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; return;
@ -275,8 +272,8 @@ keypress(XKeyPressedEvent *ev)
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
for(i = 0; i < conf.nkeybind; ++i) for(i = 0; i < conf.nkeybind; ++i)
if(keysym == keys[i].keysym if(keysym == keys[i].keysym
&& (keys[i].mod & ~(numlockmask | LockMask | scrolllockmask)) && (keys[i].mod & ~(numlockmask | LockMask))
== (ev->state & ~(numlockmask | LockMask | scrolllockmask)) == (ev->state & ~(numlockmask | LockMask))
&& keys[i].func) && keys[i].func)
keys[i].func(keys[i].cmd); keys[i].func(keys[i].cmd);
@ -372,6 +369,7 @@ unmapnotify(XUnmapEvent *ev)
void void
getevent(XEvent ev) getevent(XEvent ev)
{ {
int st; int st;
switch (ev.type) switch (ev.type)

View File

@ -87,7 +87,7 @@ frame_create(Client *c)
CWIN(c->left, c->frame, 0, 0, SHADH, c->frame_geo.height, 0, CWBackPixel, color_enlight(c->colors.frame), &at); CWIN(c->left, c->frame, 0, 0, SHADH, c->frame_geo.height, 0, CWBackPixel, color_enlight(c->colors.frame), &at);
CWIN(c->top, c->frame, 0, 0, c->frame_geo.width, SHADH, 0, CWBackPixel, color_enlight(c->colors.frame), &at); CWIN(c->top, c->frame, 0, 0, c->frame_geo.width, SHADH, 0, CWBackPixel, color_enlight(c->colors.frame), &at);
CWIN(c->bottom, c->frame, 0, c->frame_geo.height - SHADH, c->frame_geo.width, SHADH, 0, CWBackPixel, SHADC, &at); CWIN(c->bottom, c->frame, 0, c->frame_geo.height - SHADH, c->frame_geo.width, SHADH, 0, CWBackPixel, SHADC, &at);
CWIN(c->right, c->frame, c->frame_geo.width - SHADH, 0, SHADH, c->frame_geo.height, 0, CWBackPixel, SHADC, &at); CWIN(c->right, c->frame, c->frame_geo.width - SHADH, 0, SHADH, c->frame_geo.height, 0, CWBackPixel, SHADC, &at);
/* Reparent window with the frame */ /* Reparent window with the frame */
XReparentWindow(dpy, c->win, c->frame, BORDH, BORDH + TBARH); XReparentWindow(dpy, c->win, c->frame, BORDH, BORDH + TBARH);
@ -122,6 +122,8 @@ frame_delete(Client *c)
void void
frame_moveresize(Client *c, XRectangle geo) frame_moveresize(Client *c, XRectangle geo)
{ {
CHECK(c);
c->frame_geo.x = (geo.x) ? geo.x - BORDH : c->frame_geo.x; c->frame_geo.x = (geo.x) ? geo.x - BORDH : c->frame_geo.x;
c->frame_geo.y = (geo.y) ? geo.y - TBARH : c->frame_geo.y; c->frame_geo.y = (geo.y) ? geo.y - TBARH : c->frame_geo.y;
c->frame_geo.width = (geo.width) ? FRAMEW(geo.width) : c->frame_geo.width; c->frame_geo.width = (geo.width) ? FRAMEW(geo.width) : c->frame_geo.width;
@ -157,6 +159,8 @@ frame_moveresize(Client *c, XRectangle geo)
void void
frame_update(Client *c) frame_update(Client *c)
{ {
CHECK(c);
if(TBARH) if(TBARH)
{ {
c->titlebar->color = c->colors.frame; c->titlebar->color = c->colors.frame;
@ -179,6 +183,7 @@ frame_update(Client *c)
if(TBARH && (TBARH + BORDH + 1) > font->height) if(TBARH && (TBARH + BORDH + 1) > font->height)
{ {
draw_text(c->titlebar->dr, draw_text(c->titlebar->dr,
(c->frame_geo.width / 2) - (textw(c->title) / 2), (c->frame_geo.width / 2) - (textw(c->title) / 2),
(font->height - (font->descent)) + (((TBARH + BORDH) - font->height) / 2), (font->height - (font->descent)) + (((TBARH + BORDH) - font->height) / 2),

View File

@ -37,61 +37,68 @@
void void
infobar_init(void) infobar_init(void)
{ {
int i, j = 0; int sc, i, j;
if(!infobar) if(!infobar)
infobar = emalloc(1, sizeof(InfoBar)); infobar = emalloc(screen_count(), sizeof(InfoBar));
infobar->geo.height = font->height * 1.5;
infobar->geo.y = (conf.bartop) ? 0 : MAXH - infobar->geo.height;
/* Create infobar barwindow */ for(sc = 0; sc < screen_count(); ++sc)
infobar->bar = barwin_create(root, 0, infobar->geo.y, MAXW, infobar->geo.height, conf.colors.bar, False);
/* Create tags window */
for(i = 1; i < conf.ntag + 1; ++i)
{ {
infobar->tags[i] = barwin_create(infobar->bar->win, j, 0, textw(tags[i].name) + PAD, j = 0;
infobar->geo.height, conf.colors.bar, False); infobar[sc].geo.height = INFOBARH;
j += textw(tags[i].name) + PAD; infobar[sc].geo.y = (conf.bartop)
barwin_map_subwin(infobar->tags[i]); ? screen_get_geo(sc).y - INFOBARH - TBARH
: screen_get_geo(sc).height - infobar[sc].geo.height;
/* Create infobar barwindow */
infobar[sc].bar = barwin_create(root, screen_get_geo(sc).x - BORDH, infobar[sc].geo.y,
screen_get_geo(sc).width, infobar[sc].geo.height, conf.colors.bar, False);
/* Create tags window */
for(i = 1; i < conf.ntag + 1; ++i)
{
infobar[sc].tags[i] = barwin_create(infobar[sc].bar->win, j, 0, textw(tags[sc][i].name) + PAD,
infobar[sc].geo.height, conf.colors.bar, False);
j += textw(tags[sc][i].name) + PAD;
barwin_map_subwin(infobar[sc].tags[i]);
}
/* Create layout switch & layout type switch barwindow */
infobar[sc].layout_button = barwin_create(infobar[sc].bar->win, j + PAD / 2, 0,
textw(tags[sc][seltag[sc]].layout.symbol) + PAD,
infobar[sc].geo.height, conf.colors.layout_bg, False);
/* Map/Refresh all */
barwin_map(infobar[sc].bar);
barwin_map_subwin(infobar[sc].bar);
barwin_map_subwin(infobar[sc].layout_button);
barwin_refresh_color(infobar[sc].bar);
barwin_refresh(infobar[sc].bar);
strcpy(infobar[sc].statustext, "WMFS-" WMFS_VERSION);
infobar_draw(sc);
} }
/* Create layout switch & layout type switch barwindow */
infobar->layout_button = barwin_create(infobar->bar->win, j + PAD / 2, 0,
textw(tags[seltag].layout.symbol) + PAD,
infobar->geo.height, conf.colors.layout_bg, False);
/* Map/Refresh all */
barwin_map(infobar->bar);
barwin_map_subwin(infobar->bar);
barwin_map_subwin(infobar->layout_button);
barwin_refresh_color(infobar->bar);
barwin_refresh(infobar->bar);
strcpy(infobar->statustext, "WMFS-" WMFS_VERSION);
infobar_draw();
return; return;
} }
/** Draw the Infobar /** Draw the Infobar
*/ */
void void
infobar_draw(void) infobar_draw(int sc)
{ {
infobar_draw_taglist(); infobar_draw_taglist(sc);
infobar_draw_layout(); infobar_draw_layout(sc);
barwin_refresh_color(infobar->bar); barwin_refresh_color(infobar[sc].bar);
/* Draw status text */ /* Draw status text */
draw_text(infobar->bar->dr, draw_text(infobar[sc].bar->dr,
(MAXW - SHADH) - textw(infobar->statustext), (MAXW - SHADH) - textw(infobar[sc].statustext),
font->height, font->height,
conf.colors.text, 0, conf.colors.text, 0,
infobar->statustext); infobar[sc].statustext);
barwin_refresh(infobar->bar); barwin_refresh(infobar[sc].bar);
return; return;
} }
@ -99,13 +106,13 @@ infobar_draw(void)
/** Draw the layout button in the InfoBar /** Draw the layout button in the InfoBar
*/ */
void void
infobar_draw_layout(void) infobar_draw_layout(int sc)
{ {
barwin_resize(infobar->layout_button, textw(tags[seltag].layout.symbol) + PAD, infobar->geo.height); barwin_resize(infobar[sc].layout_button, textw(tags[sc][seltag[sc]].layout.symbol) + PAD, infobar[sc].geo.height);
barwin_refresh_color(infobar->layout_button); barwin_refresh_color(infobar[sc].layout_button);
draw_text(infobar->layout_button->dr, PAD / 2, font->height, draw_text(infobar[sc].layout_button->dr, PAD / 2, font->height,
conf.colors.layout_fg, 0, tags[seltag].layout.symbol); conf.colors.layout_fg, 0, tags[sc][seltag[sc]].layout.symbol);
barwin_refresh(infobar->layout_button); barwin_refresh(infobar[sc].layout_button);
return; return;
} }
@ -113,18 +120,17 @@ infobar_draw_layout(void)
/** Draw the taglist in the InfoBar /** Draw the taglist in the InfoBar
*/ */
void void
infobar_draw_taglist(void) infobar_draw_taglist(int sc)
{ {
int i; int i;
for(i = 1; i < conf.ntag + 1; ++i) for(i = 1; i < conf.ntag + 1; ++i)
{ {
infobar->tags[i]->color = ((i == seltag) ? conf.colors.tagselbg : conf.colors.bar); infobar[sc].tags[i]->color = ((i == seltag[sc]) ? conf.colors.tagselbg : conf.colors.bar);
barwin_refresh_color(infobar->tags[i]); barwin_refresh_color(infobar[sc].tags[i]);
draw_text(infobar->tags[i]->dr, PAD / 2, font->height, draw_text(infobar[sc].tags[i]->dr, PAD / 2, font->height,
((i == seltag) ? conf.colors.tagselfg : conf.colors.text), ((i == seltag[sc]) ? conf.colors.tagselfg : conf.colors.text), 0, tags[sc][i].name);
0, tags[i].name); barwin_refresh(infobar[sc].tags[i]);
barwin_refresh(infobar->tags[i]);
} }
return; return;
@ -135,17 +141,20 @@ infobar_draw_taglist(void)
void void
infobar_destroy(void) infobar_destroy(void)
{ {
int i; int sc, i;
barwin_delete(infobar->bar); for(sc = 0; sc < screen_count(); ++sc)
barwin_delete(infobar->layout_button);
barwin_delete_subwin(infobar->layout_button);
for(i = 1; i < conf.ntag + 1; ++i)
{ {
barwin_delete_subwin(infobar->tags[i]); barwin_delete(infobar[sc].layout_button);
barwin_delete(infobar->tags[i]); barwin_delete_subwin(infobar[sc].layout_button);
for(i = 1; i < conf.ntag + 1; ++i)
{
barwin_delete_subwin(infobar[sc].tags[i]);
barwin_delete(infobar[sc].tags[i]);
}
barwin_delete_subwin(infobar[sc].bar);
barwin_delete(infobar[sc].bar);
} }
barwin_delete_subwin(infobar->bar);
return; return;
} }
@ -157,16 +166,18 @@ infobar_destroy(void)
void void
uicb_infobar_togglepos(uicb_t cmd) uicb_infobar_togglepos(uicb_t cmd)
{ {
XRectangle sg = screen_get_geo(screen_get_sel());
conf.bartop = !conf.bartop; conf.bartop = !conf.bartop;
if(conf.bartop) if(conf.bartop)
sgeo.y = infobar->geo.height + TBARH; sg.y = infobar[selscreen].geo.height + TBARH;
else else
sgeo.y = TBARH; sg.y = TBARH;
infobar->geo.y = (conf.bartop) ? 0 : MAXH - infobar->geo.height; infobar[selscreen].geo.y = (conf.bartop) ? sg.y : MAXH - infobar[selscreen].geo.height;
barwin_move(infobar->bar, 0, infobar->geo.y); barwin_move(infobar[selscreen].bar, sg.y, infobar[selscreen].geo.y);
infobar_draw(); infobar_draw(selscreen);
arrange(); arrange();
return; return;

View File

@ -46,7 +46,7 @@ init(void)
init_root(); init_root();
init_atom(); init_atom();
infobar_init(); infobar_init();
init_geometry(); screen_init();
grabkeys(); grabkeys();
/* Warning about font */ /* Warning about font */
@ -91,14 +91,10 @@ init_key(void)
for(i = 0; i < 8; i++) for(i = 0; i < 8; i++)
for(j = 0; j < modmap->max_keypermod; ++j) for(j = 0; j < modmap->max_keypermod; ++j)
{
if(modmap->modifiermap[i * modmap->max_keypermod + j] if(modmap->modifiermap[i * modmap->max_keypermod + j]
== XKeysymToKeycode(dpy, XK_Num_Lock)) == XKeysymToKeycode(dpy, XK_Num_Lock))
numlockmask = (1 << i); numlockmask = (1 << i);
if(modmap->modifiermap[i * modmap->max_keypermod + j]
== XKeysymToKeycode(dpy, XK_Scroll_Lock))
scrolllockmask = (1 << i);
}
XFreeModifiermap(modmap); XFreeModifiermap(modmap);
return; return;
@ -113,9 +109,10 @@ init_root(void)
root = RootWindow(dpy, screen); root = RootWindow(dpy, screen);
at.event_mask = KeyMask | ButtonPressMask | ButtonReleaseMask | at.event_mask = KeyMask|ButtonMask|MouseMask
SubstructureRedirectMask | SubstructureNotifyMask | |SubstructureRedirectMask|SubstructureNotifyMask
EnterWindowMask | LeaveWindowMask | StructureNotifyMask ; |EnterWindowMask|LeaveWindowMask|StructureNotifyMask;
at.cursor = cursor[CurNormal]; at.cursor = cursor[CurNormal];
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &at); XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &at);
if(conf.root.background_command) if(conf.root.background_command)
@ -142,21 +139,3 @@ init_atom(void)
return; return;
} }
/** Init screen geometry
*/
void
init_geometry(void)
{
sgeo.x = BORDH;
sgeo.y = infobar->geo.height;
if(conf.bartop)
sgeo.y += TBARH;
else
sgeo.y = TBARH;
sgeo.width = MAXW;
sgeo.height = MAXH - infobar->geo.height - TBARH;
return;
}

View File

@ -39,20 +39,22 @@ arrange(void)
{ {
Client *c; Client *c;
screen_get_sel();
for(c = clients; c; c = c->next) for(c = clients; c; c = c->next)
if(!ishide(c)) if(c->screen == selscreen)
client_unhide(c); {
else if(!ishide(c))
client_hide(c); client_unhide(c);
else
client_hide(c);
}
tags[seltag].layout.func(); tags[selscreen][seltag[selscreen]].layout.func();
if(selbytag[seltag] != NULL) client_focus(NULL);
client_focus(selbytag[seltag]);
else
client_focus(NULL);
infobar_draw(); infobar_draw(selscreen);
return; return;
} }
@ -67,7 +69,7 @@ freelayout(void)
for(c = clients; c; c = c->next) for(c = clients; c; c = c->next)
{ {
if(!ishide(c)) if(!ishide(c) && c->screen == screen_get_sel())
{ {
if(c->tile || c->lmax) if(c->tile || c->lmax)
{ {
@ -92,15 +94,17 @@ layoutswitch(Bool b)
{ {
int i; int i;
screen_get_sel();
for(i = 0; i < conf.nlayout; ++i) for(i = 0; i < conf.nlayout; ++i)
{ {
if(tags[seltag].layout.symbol == conf.layout[i].symbol if(tags[selscreen][seltag[selscreen]].layout.symbol == conf.layout[i].symbol
&& tags[seltag].layout.func == conf.layout[i].func) && tags[selscreen][seltag[selscreen]].layout.func == conf.layout[i].func)
{ {
if(b) if(b)
tags[seltag].layout = conf.layout[(i + 1) % conf.nlayout]; tags[selscreen][seltag[selscreen]].layout = conf.layout[(i + 1) % conf.nlayout];
else else
tags[seltag].layout = conf.layout[(i + conf.nlayout - 1) % conf.nlayout]; tags[selscreen][seltag[selscreen]].layout = conf.layout[(i + conf.nlayout - 1) % conf.nlayout];
break; break;
} }
} }
@ -138,6 +142,7 @@ maxlayout(void)
{ {
Client *c; Client *c;
XRectangle geo; XRectangle geo;
XRectangle sg = screen_get_geo(screen_get_sel());
for(c = nexttiled(clients); c; c = nexttiled(c->next)) for(c = nexttiled(clients); c; c = nexttiled(c->next))
{ {
@ -148,9 +153,10 @@ maxlayout(void)
c->ogeo.width = c->geo.width; c->ogeo.width = c->geo.width;
c->ogeo.height = c->geo.height; c->ogeo.height = c->geo.height;
geo.x = sgeo.x; geo.y = sgeo.y; geo.x = sg.x;
geo.width = sgeo.width - BORDH * 2; geo.y = sg.y;
geo.height = sgeo.height - BORDH * 2; geo.width = sg.width - BORDH * 2;
geo.height = sg.height - BORDH * 2;
client_moveresize(c, geo, False); client_moveresize(c, geo, False);
} }
@ -166,7 +172,7 @@ maxlayout(void)
Client* Client*
nexttiled(Client *c) nexttiled(Client *c)
{ {
for(; c && (c->max || c->free || ishide(c)); c = c->next); for(; c && (c->max || c->free || c->screen != screen_get_sel() || ishide(c)); c = c->next);
return c; return c;
} }
@ -179,14 +185,16 @@ uicb_set_mwfact(uicb_t cmd)
{ {
double c; double c;
screen_get_sel();
CHECK((sscanf(cmd, "%lf", &c))); CHECK((sscanf(cmd, "%lf", &c)));
if(tags[seltag].mwfact + c > 0.95 if(tags[selscreen][seltag[selscreen]].mwfact + c > 0.95
|| tags[seltag].mwfact + c < 0.05) || tags[selscreen][seltag[selscreen]].mwfact + c < 0.05)
return; return;
tags[seltag].mwfact += c; tags[selscreen][seltag[selscreen]].mwfact += c;
tags[seltag].layout.func(); tags[selscreen][seltag[selscreen]].layout.func();
return; return;
} }
@ -200,14 +208,16 @@ uicb_set_nmaster(uicb_t cmd)
int nc, n = atoi(cmd); int nc, n = atoi(cmd);
Client *c; Client *c;
screen_get_sel();
for(nc = 0, c = nexttiled(clients); c; c = nexttiled(c->next), ++nc); for(nc = 0, c = nexttiled(clients); c; c = nexttiled(c->next), ++nc);
if(!nc || tags[seltag].nmaster + n == 0 if(!nc || tags[selscreen][seltag[selscreen]].nmaster + n == 0
|| tags[seltag].nmaster + n > nc) || tags[selscreen][seltag[selscreen]].nmaster + n > nc)
return; return;
tags[seltag].nmaster += n; tags[selscreen][seltag[selscreen]].nmaster += n;
tags[seltag].layout.func(); tags[selscreen][seltag[selscreen]].layout.func();
return; return;
} }
@ -218,7 +228,8 @@ void
grid(void) grid(void)
{ {
Client *c; Client *c;
XRectangle cgeo = {sgeo.x, sgeo.y, 0, 0}; XRectangle sg = screen_get_geo(screen_get_sel());
XRectangle cgeo = {sg.x, sg.y, 0, 0};
unsigned int i, n, cols, rows, cpcols = 0; unsigned int i, n, cols, rows, cpcols = 0;
unsigned int border = BORDH * 2; unsigned int border = BORDH * 2;
@ -242,19 +253,19 @@ grid(void)
c->ogeo.width = c->geo.width; c->ogeo.height = c->geo.height; c->ogeo.width = c->geo.width; c->ogeo.height = c->geo.height;
++cpcols; ++cpcols;
cgeo.width = (sgeo.width / cols) - border; cgeo.width = (sg.width / cols) - border;
cgeo.height = (sgeo.height / rows) - border; cgeo.height = (sg.height / rows) - border;
/* Last row's and last client remainder */ /* Last row's and last client remainder */
if(cpcols == rows || i + 1 == n) if(cpcols == rows || i + 1 == n)
cgeo.height = (sgeo.y + sgeo.height) - cgeo.y - border; cgeo.height = sg.y + sg.height - cgeo.y - border;
/* Last column's client remainder */ /* Last column's client remainder */
if(i >= rows * (cols - 1)) if(i >= rows * (cols - 1))
cgeo.width = sgeo.width - cgeo.x - BORDH; cgeo.width = sg.width - (cgeo.x - (sg.x - border));
/* Resize */ /* Resize */
client_moveresize(c, cgeo, tags[seltag].resizehint); client_moveresize(c, cgeo, tags[selscreen][seltag[selscreen]].resizehint);
/* Set all the other size with current client info */ /* Set all the other size with current client info */
cgeo.y = c->geo.y + c->geo.height + border + TBARH; cgeo.y = c->geo.y + c->geo.height + border + TBARH;
@ -262,7 +273,7 @@ grid(void)
{ {
cpcols = 0; cpcols = 0;
cgeo.x = c->geo.x + c->geo.width + border; cgeo.x = c->geo.x + c->geo.width + border;
cgeo.y = sgeo.y; cgeo.y = sg.y;
} }
} }
@ -276,9 +287,10 @@ void
multi_tile(Position type) multi_tile(Position type)
{ {
Client *c; Client *c;
XRectangle mastergeo = {sgeo.x, sgeo.y, 0, 0}; XRectangle sg = screen_get_geo(screen_get_sel());
XRectangle cgeo = {sgeo.x, sgeo.y, 0, 0}; XRectangle mastergeo = {sg.x, sg.y, 0, 0};
uint i , n, tilesize, mwfact, nmaster = tags[seltag].nmaster; XRectangle cgeo = {sg.x, sg.y, 0, 0};
uint i , n, tilesize, mwfact, nmaster = tags[selscreen][seltag[selscreen]].nmaster;
uint border = BORDH * 2; uint border = BORDH * 2;
for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next), ++n); for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next), ++n);
@ -289,32 +301,32 @@ multi_tile(Position type)
/* SET MWFACT */ /* SET MWFACT */
mwfact = (type == Top || type == Bottom) mwfact = (type == Top || type == Bottom)
? tags[seltag].mwfact * sgeo.height ? tags[selscreen][seltag[selscreen]].mwfact * sg.height
: tags[seltag].mwfact * sgeo.width; : tags[selscreen][seltag[selscreen]].mwfact * sg.width;
/* MASTER SIZE */ /* MASTER SIZE */
if(type == Top || type == Bottom) if(type == Top || type == Bottom)
{ {
if(type == Top) if(type == Top)
mastergeo.y = (n <= nmaster) ? sgeo.y : sgeo.y + (sgeo.height - mwfact) - border; mastergeo.y = (n <= nmaster) ? sg.y : sg.y + (sg.height - mwfact) - border;
mastergeo.width = (sgeo.width / nmaster) - (border * 2); mastergeo.width = (sg.width / nmaster) - (border * 2);
mastergeo.height = (n <= nmaster) ? sgeo.height - border : mwfact; mastergeo.height = (n <= nmaster) ? sg.height - border : mwfact;
} }
else else
{ {
if(type == Left) if(type == Left)
mastergeo.x = (n <= nmaster) ? sgeo.x : sgeo.width - mwfact - BORDH; mastergeo.x = (n <= nmaster) ? sg.x : (sg.x + sg.width) - mwfact - border;
mastergeo.width = (n <= nmaster) ? sgeo.width - border : mwfact; mastergeo.width = (n <= nmaster) ? sg.width - border : mwfact;
mastergeo.height = (sgeo.height / nmaster) - border; mastergeo.height = (sg.height / nmaster) - border;
} }
/* TILED SIZE */ /* TILED SIZE */
if(n > nmaster) if(n > nmaster)
{ {
if(type == Top || type == Bottom) if(type == Top || type == Bottom)
tilesize = sgeo.width / (n - nmaster) - border; tilesize = sg.width / (n - nmaster) - border;
else else
tilesize = sgeo.height / (n - nmaster) - border; tilesize = sg.height / (n - nmaster) - border;
} }
@ -350,17 +362,17 @@ multi_tile(Position type)
{ {
case Top: case Top:
case Left: case Left:
cgeo.y = sgeo.y; cgeo.y = sg.y;
cgeo.x = sgeo.x; cgeo.x = sg.x;
break; break;
case Bottom: case Bottom:
cgeo.y += mastergeo.height + TBARH + border; cgeo.y += mastergeo.height + TBARH + border;
cgeo.x = sgeo.x; cgeo.x = sg.x;
break; break;
default: default:
case Right: case Right:
cgeo.x += mastergeo.width + border; cgeo.x += mastergeo.width + border;
cgeo.y = sgeo.y; cgeo.y = sg.y;
break; break;
} }
} }
@ -368,11 +380,11 @@ multi_tile(Position type)
{ {
cgeo.width = tilesize; cgeo.width = tilesize;
cgeo.width -= border; cgeo.width -= border;
cgeo.height = sgeo.height - mastergeo.height - TBARH - border*2; cgeo.height = sg.height - mastergeo.height - TBARH - border*2;
} }
else else
{ {
cgeo.width = sgeo.width - mastergeo.width - border*2; cgeo.width = sg.width - mastergeo.width - border*2;
cgeo.height = tilesize; cgeo.height = tilesize;
cgeo.height -= border + TBARH; cgeo.height -= border + TBARH;
} }
@ -382,13 +394,13 @@ multi_tile(Position type)
if(i + 1 == n || i + 1 == (n < nmaster ? n : nmaster)) if(i + 1 == n || i + 1 == (n < nmaster ? n : nmaster))
{ {
if(type == Top || type == Bottom) if(type == Top || type == Bottom)
cgeo.width = sgeo.width - cgeo.x - BORDH; cgeo.width = sg.width - (cgeo.x - (sg.x - border));
else else
cgeo.height = (sgeo.y + sgeo.height) - cgeo.y - border; cgeo.height = (sg.y + sg.height) - cgeo.y - border;
} }
/* Magic instant */ /* Magic instant */
client_moveresize(c, cgeo, tags[seltag].resizehint); client_moveresize(c, cgeo, tags[selscreen][seltag[selscreen]].resizehint);
/* Set the position of the next client */ /* Set the position of the next client */
if(type == Top || type == Bottom) if(type == Top || type == Bottom)
@ -449,6 +461,8 @@ uicb_tile_switch(uicb_t cmd)
{ {
Client *c; Client *c;
screen_get_sel();
if(!sel || sel->hint || !sel->tile) if(!sel || sel->hint || !sel->tile)
return; return;
if((c = sel) == nexttiled(clients)) if((c = sel) == nexttiled(clients))
@ -456,7 +470,7 @@ uicb_tile_switch(uicb_t cmd)
client_detach(c); client_detach(c);
client_attach(c); client_attach(c);
client_focus(c); client_focus(c);
tags[seltag].layout.func(); tags[selscreen][seltag[selscreen]].layout.func();
return; return;
} }
@ -469,12 +483,14 @@ uicb_togglefree(uicb_t cmd)
{ {
CHECK(sel); CHECK(sel);
screen_get_sel();
sel->free = !sel->free; sel->free = !sel->free;
sel->tile = False; sel->tile = False;
sel->max = False; sel->max = False;
sel->lmax = False; sel->lmax = False;
client_moveresize(sel, sel->ogeo, True); client_moveresize(sel, sel->ogeo, True);
tags[seltag].layout.func(); tags[selscreen][seltag[selscreen]].layout.func();
return; return;
} }
@ -486,6 +502,7 @@ void
uicb_togglemax(uicb_t cmd) uicb_togglemax(uicb_t cmd)
{ {
XRectangle geo; XRectangle geo;
XRectangle sg = screen_get_geo(screen_get_sel());
if(!sel || ishide(sel) || sel->hint) if(!sel || ishide(sel) || sel->hint)
return; return;
@ -496,9 +513,10 @@ uicb_togglemax(uicb_t cmd)
sel->ogeo.width = sel->geo.width; sel->ogeo.width = sel->geo.width;
sel->ogeo.height = sel->geo.height; sel->ogeo.height = sel->geo.height;
geo.x = sgeo.x; geo.y = sgeo.y; geo.x = sg.x;
geo.width = sgeo.width - BORDH * 2; geo.y = sg.y;
geo.height = sgeo.height - BORDH * 2; geo.width = sg.width - BORDH * 2;
geo.height = sg.height - BORDH * 2;
client_moveresize(sel, geo, False); client_moveresize(sel, geo, False);
client_raise(sel); client_raise(sel);

View File

@ -40,7 +40,7 @@ mouse_move(Client *c)
{ {
int ocx = c->geo.x; int ocx = c->geo.x;
int ocy = c->geo.y; int ocy = c->geo.y;
int mx, my, dint; int mx = 0, my = 0, dint;
uint duint; uint duint;
Window dw; Window dw;
XRectangle geo; XRectangle geo;
@ -57,7 +57,7 @@ mouse_move(Client *c)
for(;;) for(;;)
{ {
XMaskEvent(dpy, MouseMask | ExposureMask | SubstructureRedirectMask, &ev); XMaskEvent(dpy, ButtonMask | MouseMask | ExposureMask | SubstructureRedirectMask, &ev);
if(ev.type == ButtonRelease) if(ev.type == ButtonRelease)
{ {
@ -89,9 +89,10 @@ mouse_resize(Client *c)
{ {
int ocx = c->geo.x; int ocx = c->geo.x;
int ocy = c->geo.y; int ocy = c->geo.y;
int my = sgeo.y, mx = 0;
double fy, fx, mwf; double fy, fx, mwf;
XRectangle geo; XRectangle geo;
XRectangle sg = screen_get_geo(screen_get_sel());
int my = sg.y, mx = 0;
XEvent ev; XEvent ev;
if(c->max || c->lmax) if(c->max || c->lmax)
@ -107,21 +108,21 @@ mouse_resize(Client *c)
/* Warp pointer for mwfact resize {{{ */ /* Warp pointer for mwfact resize {{{ */
if(c->tile) if(c->tile)
{ {
if(tags[seltag].layout.func == tile) if(tags[selscreen][seltag[selscreen]].layout.func == tile)
mx = tags[seltag].mwfact * sgeo.width; mx = tags[selscreen][seltag[selscreen]].mwfact * sg.width;
else if(tags[seltag].layout.func == tile_left) else if(tags[selscreen][seltag[selscreen]].layout.func == tile_left)
mx = sgeo.width - (tags[seltag].mwfact * sgeo.width); mx = sg.width - (tags[selscreen][seltag[selscreen]].mwfact * sg.width);
else if(tags[seltag].layout.func == tile_top) else if(tags[selscreen][seltag[selscreen]].layout.func == tile_top)
{ {
mx = ev.xmotion.x_root; mx = sg.width / 2;
my = sgeo.height - (tags[seltag].mwfact * sgeo.height); my = sg.height - (tags[selscreen][seltag[selscreen]].mwfact * sg.height);
} }
else if(tags[seltag].layout.func == tile_bottom) else if(tags[selscreen][seltag[selscreen]].layout.func == tile_bottom)
{ {
mx = ev.xmotion.x_root; mx = sg.width / 2;
my = tags[seltag].mwfact * sgeo.height; my = tags[selscreen][seltag[selscreen]].mwfact * sg.height;
} }
XWarpPointer(dpy, None, root, 0, 0, 0, 0, mx, my); XWarpPointer(dpy, None, root, 0, 0, 0, 0, sg.x + mx, sg.y + my);
} }
/* }}} */ /* }}} */
@ -148,22 +149,22 @@ mouse_resize(Client *c)
} }
else else
{ {
fy = (round(((ev.xmotion.y * 50) / sgeo.height))) / 50; fy = (round(((ev.xmotion.y * 50) / sg.height))) / 50;
fx = (round(((ev.xmotion.x * 50) / sgeo.width))) / 50; fx = (round(((ev.xmotion.x * 50) / sg.width))) / 50;
if(tags[seltag].layout.func == tile) if(tags[selscreen][seltag[selscreen]].layout.func == tile)
mwf = fx; mwf = sg.x + fx;
else if(tags[seltag].layout.func == tile_left) else if(tags[selscreen][seltag[selscreen]].layout.func == tile_left)
mwf = 1 - fx; mwf = 1 - (sg.x + fx);
else if(tags[seltag].layout.func == tile_top) else if(tags[selscreen][seltag[selscreen]].layout.func == tile_top)
mwf = 1 - fy; mwf = 1 - fy;
else if(tags[seltag].layout.func == tile_bottom) else if(tags[selscreen][seltag[selscreen]].layout.func == tile_bottom)
mwf = fy; mwf = fy;
else else
mwf = tags[seltag].mwfact; mwf = tags[selscreen][seltag[selscreen]].mwfact;
tags[seltag].mwfact = (mwf < 0.05) ? 0.05 : ((mwf > 0.95) ? 0.95 : mwf); tags[selscreen][seltag[selscreen]].mwfact = (mwf < 0.05) ? 0.05 : ((mwf > 0.95) ? 0.95 : mwf);
tags[seltag].layout.func(); tags[selscreen][seltag[selscreen]].layout.func();
} }
if(!c->tile) if(!c->tile)
@ -184,27 +185,22 @@ mouse_resize(Client *c)
void void
mouse_grabbuttons(Client *c, Bool focused) mouse_grabbuttons(Client *c, Bool focused)
{ {
int i, j; int i;
uint mod = conf.client.mod; uint but[] = {Button1, Button2, Button3, Button4, Button5};
uint bl[] = {Button1, Button2, Button3, Button4, Button5};
uint ml[] =
{
mod, mod|LockMask,
mod|numlockmask,
mod|scrolllockmask,
mod|numlockmask|scrolllockmask,
mod|LockMask|scrolllockmask,
mod|LockMask|numlockmask,
mod|LockMask|numlockmask|scrolllockmask
};
XUngrabButton(dpy, AnyButton, AnyModifier, c->win); XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
if(focused) if(focused)
for(i = 0; i < (sizeof bl / sizeof bl[0]); ++i) for(i = 0; i < (sizeof but / sizeof but[0]); ++i)
for(j = 0; j < (sizeof ml / sizeof ml[0]); ++j) {
XGrabButton(dpy, bl[i], ml[j], c->win, False, XGrabButton(dpy, but[i], conf.client.mod, c->win, False,
ButtonMask, GrabModeAsync,GrabModeSync, None, None); ButtonMask, GrabModeAsync,GrabModeSync, None, None);
XGrabButton(dpy, but[i], conf.client.mod|LockMask, c->win, False,
ButtonMask, GrabModeAsync,GrabModeSync, None, None);
XGrabButton(dpy, but[i], conf.client.mod|numlockmask, c->win, False,
ButtonMask, GrabModeAsync,GrabModeSync, None, None);
XGrabButton(dpy, but[i], conf.client.mod|LockMask|numlockmask, c->win, False,
ButtonMask, GrabModeAsync,GrabModeSync, None, None);
}
else else
XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
ButtonMask, GrabModeAsync, GrabModeSync, None, None); ButtonMask, GrabModeAsync, GrabModeSync, None, None);

118
src/screen.c Normal file
View File

@ -0,0 +1,118 @@
/*
* screen.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"
/** Count the screens
*\return the number of screen
*/
int
screen_count(void)
{
int n = 0;
if(XineramaIsActive(dpy))
XineramaQueryScreens(dpy, &n);
else
n = ScreenCount(dpy);
return n;
}
/** Get screen geometry by number
*\param s Screen number
*\return XRectangle struct
*/
XRectangle
screen_get_geo(int s)
{
int n = 0;
XineramaScreenInfo *xsi;
XRectangle geo;
if(XineramaIsActive(dpy))
{
xsi = XineramaQueryScreens(dpy, &n);
geo.x = xsi[s].x_org + BORDH;
geo.y = (conf.bartop)
? xsi[s].y_org + INFOBARH + TBARH
: xsi[s].y_org + TBARH;
geo.height = xsi[s].height - INFOBARH - TBARH;
geo.width = xsi[s].width;
efree(xsi);
}
else
{
geo.x = BORDH;
geo.y = (conf.bartop) ? INFOBARH + TBARH : TBARH; ;
geo.height = MAXH - INFOBARH - TBARH;
geo.width = MAXW;
}
return geo;
}
/** Get and set the selected screen
*\return The number of the selected screen
*/
int
screen_get_sel(void)
{
if(XineramaIsActive(dpy))
{
Window w;
uint du;
int x, y, d, i = 0;
XQueryPointer(dpy, root, &w, &w, &x, &y, &d, &d, &du);
for(i = 0; i < screen_count(); ++i)
if(x >= screen_get_geo(i).x
&& x < screen_get_geo(i).x + screen_get_geo(i).width)
selscreen = i;
return selscreen;
}
else
return 0;
}
/** Init screen geometry
*/
void
screen_init(void)
{
screen_get_sel();
return;
}

View File

@ -80,6 +80,8 @@ struct Client
char *title; char *title;
/* Tag num */ /* Tag num */
int tag; int tag;
/* Screen */
int screen;
/* Window attribute */ /* Window attribute */
XRectangle geo; XRectangle geo;
XRectangle frame_geo; XRectangle frame_geo;

View File

@ -40,24 +40,24 @@ uicb_tag(uicb_t cmd)
{ {
int tmp = atoi(cmd); int tmp = atoi(cmd);
screen_get_sel();
if(!tmp) if(!tmp)
tmp = 1; tmp = 1;
if(cmd[0] == '+' || cmd[0] == '-') if(cmd[0] == '+' || cmd[0] == '-')
{ {
if(tmp + seltag < 1 if(tmp + seltag[selscreen] < 1
|| tmp + seltag > conf.ntag) || tmp + seltag[selscreen] > conf.ntag)
return; return;
prevtag = seltag; seltag[selscreen] += tmp;
seltag += tmp;
} }
else else
{ {
if(tmp == seltag if(tmp == seltag[selscreen]
|| tmp > conf.ntag) || tmp > conf.ntag)
return; return;
prevtag = seltag; seltag[selscreen] = tmp;
seltag = tmp;
} }
arrange(); arrange();
@ -95,15 +95,15 @@ uicb_tagtransfert(uicb_t cmd)
{ {
int n = atoi(cmd); int n = atoi(cmd);
if(!sel || n == seltag) screen_get_sel();
if(!sel || n == seltag[selscreen])
return; return;
if(!n) if(!n)
n = 1; n = 1;
sel->tag = n; sel->tag = n;
selbytag[n] = sel;
selbytag[seltag] = NULL;
arrange(); arrange();

View File

@ -69,7 +69,7 @@ getcolor(char *color)
{ {
XColor xcolor; 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); fprintf(stderr,"WMFS Error: cannot allocate color \"%s\"\n", color);
return xcolor.pixel; return xcolor.pixel;
} }
@ -81,14 +81,13 @@ getcolor(char *color)
ulong ulong
color_enlight(ulong col) color_enlight(ulong col)
{ {
ulong ret = col;
if((col + 0x330000) < 0xffffff if((col + 0x330000) < 0xffffff
&& (col + 0x003300) < 0xffffff && (col + 0x003300) < 0xffffff
&& (col + 0x000033) < 0xffffff) && (col + 0x000033) < 0xffffff)
ret += 0x333333; return col + 0x333333;
else
return col;
return ret;
} }
/** Get a Window WM State /** Get a Window WM State

View File

@ -47,9 +47,15 @@ errorhandler(Display *d, XErrorEvent *event)
} }
/* Ignore focus change error for unmapped client */ /* Ignore focus change error for unmapped client */
if((c = client_gb_win(event->resourceid)) /* Too lemmy to add Xproto.h so:
&& c->unmapped * 42 = X_SetInputFocus
&& event->request_code == 42) /* 42: X_SetInputFocus (Xproto.h) */ * 28 = X_GrabButton
*/
if((c = client_gb_win(event->resourceid)))
if(event->error_code == BadWindow
|| (event->error_code == BadMatch && event->request_code == 42)
|| event->request_code == 28)
return 0; return 0;
@ -96,6 +102,8 @@ quit(void)
XFreeCursor(dpy, cursor[CurResize]); XFreeCursor(dpy, cursor[CurResize]);
infobar_destroy(); infobar_destroy();
efree(infobar); efree(infobar);
efree(seltag);
efree(tags);
efree(keys); efree(keys);
efree(conf.titlebar.mouse); efree(conf.titlebar.mouse);
efree(conf.client.mouse); efree(conf.client.mouse);
@ -112,13 +120,15 @@ void
mainloop(void) mainloop(void)
{ {
fd_set fd; fd_set fd;
char sbuf[sizeof infobar->statustext], *p; int len, r, offset = 0, sc = screen_count() - 1;
int len, r, offset = 0; char sbuf[sizeof infobar[sc].statustext], *p;
Bool readstdin = True; Bool readstdin = True;
XEvent ev; XEvent ev;
len = sizeof infobar->statustext - 1;
sbuf[len] = infobar->statustext[len] = '\0';
len = sizeof infobar[sc].statustext - 1;
sbuf[len] = infobar[sc].statustext[len] = '\0';
while(!exiting) while(!exiting)
{ {
@ -137,7 +147,7 @@ mainloop(void)
if(*p == '\n') if(*p == '\n')
{ {
*p = '\0'; *p = '\0';
strncpy(infobar->statustext, sbuf, len); strncpy(infobar[sc].statustext, sbuf, len);
p += r - 1; p += r - 1;
for(r = 0; *(p - r) && *(p - r) != '\n'; ++r); for(r = 0; *(p - r) && *(p - r) != '\n'; ++r);
offset = r; offset = r;
@ -149,10 +159,10 @@ mainloop(void)
} }
else else
{ {
strncpy(infobar->statustext, sbuf, strlen(sbuf)); strncpy(infobar[sc].statustext, sbuf, strlen(sbuf));
readstdin = False; readstdin = False;
} }
infobar_draw(); infobar_draw(screen_get_sel());
} }
while(XPending(dpy)) while(XPending(dpy))
{ {

View File

@ -50,6 +50,7 @@
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/cursorfont.h> #include <X11/cursorfont.h>
#include <X11/Xft/Xft.h> #include <X11/Xft/Xft.h>
#include <X11/extensions/Xinerama.h>
/* Local headers */ /* Local headers */
#include "config.h" #include "config.h"
@ -67,7 +68,7 @@
#define MAXH DisplayHeight(dpy, screen) #define MAXH DisplayHeight(dpy, screen)
#define MAXW DisplayWidth(dpy, screen) #define MAXW DisplayWidth(dpy, screen)
#define INFOBARH font->height * 1.5
#define SHADH 1 #define SHADH 1
#define SHADC 0x000000 /* 'Cause i don't know how darken a color yet */ #define SHADC 0x000000 /* 'Cause i don't know how darken a color yet */
#define BORDH conf.client.borderheight #define BORDH conf.client.borderheight
@ -100,9 +101,9 @@ ushort textw(const char *text);
/* infobar.c */ /* infobar.c */
void infobar_init(void); void infobar_init(void);
void infobar_draw(void); void infobar_draw(int sc);
void infobar_draw_layout(void); void infobar_draw_layout(int sc);
void infobar_draw_taglist(void); void infobar_draw_taglist(int sc);
void infobar_destroy(void); void infobar_destroy(void);
void uicb_infobar_togglepos(uicb_t cmd); void uicb_infobar_togglepos(uicb_t cmd);
@ -180,6 +181,12 @@ void uicb_tag_next(uicb_t);
void uicb_tag_prev(uicb_t); void uicb_tag_prev(uicb_t);
void uicb_tagtransfert(uicb_t); void uicb_tagtransfert(uicb_t);
/* screen */
int screen_count(void);
XRectangle screen_get_geo(int s);
int screen_get_sel(void);
void screen_init(void);
/* layout.c */ /* layout.c */
void arrange(void); void arrange(void);
void freelayout(void); void freelayout(void);
@ -226,8 +233,8 @@ void uicb_reload(uicb_t cmd);
Display *dpy; Display *dpy;
GC gc; GC gc;
Window root; Window root;
XRectangle sgeo;
int screen; int screen;
int selscreen;
Conf conf; Conf conf;
Key *keys; Key *keys;
Bool exiting; Bool exiting;
@ -242,19 +249,15 @@ XftFont *font;
/* InfoBar */ /* InfoBar */
InfoBar *infobar; InfoBar *infobar;
Tag tags[MAXTAG]; Tag tags[32][MAXTAG];
int taglen[MAXTAG]; int *seltag;
int seltag;
int prevtag;
/* Important Client */ /* Important Client */
Client *clients; Client *clients;
Client *sel; Client *sel;
Client *selbytag[MAXTAG];
/* Other */ /* Other */
uint numlockmask; uint numlockmask;
uint scrolllockmask;
Variable confvar[256]; Variable confvar[256];
#endif /* WMFS_H */ #endif /* WMFS_H */