From 1508e1a74849ee3081783b2590a8ee3edf76fc51 Mon Sep 17 00:00:00 2001 From: seanpringle Date: Thu, 25 Oct 2012 02:01:36 +1000 Subject: [PATCH] tweakage --- action.c | 7 +++---- client.c | 63 ++++++++++++++++++++++++++++---------------------------- config.h | 6 ++++-- event.c | 19 +++++++---------- setup.c | 40 +++++++++++++++++++++-------------- spot.c | 15 ++++++++++++++ xoat.c | 8 +++---- 7 files changed, 90 insertions(+), 68 deletions(-) diff --git a/action.c b/action.c index dc925c2..a5130e4 100644 --- a/action.c +++ b/action.c @@ -40,12 +40,12 @@ void action_move_direction(void *data, int num, client *cli) void action_focus(void *data, int num, client *cli) { - spot_focus_top_window(num, current_mon, None); + spot_try_focus_top_window(num, current_mon, None); } void action_focus_direction(void *data, int num, client *cli) { - spot_focus_top_window(spot_choose_by_direction(current_spot, current_mon, num), current_mon, None); + spot_try_focus_top_window(spot_choose_by_direction(current_spot, current_mon, num), current_mon, None); } void action_close(void *data, int num, client *cli) @@ -123,8 +123,7 @@ void action_above(void *data, int num, client *cli) void action_snapshot(void *data, int num, client *cli) { - int i; client *c; - STACK_FREE(&snapshot); + int i; client *c; STACK_FREE(&snapshot); for_windows(i, c) if (c->manage && c->class) snapshot.clients[snapshot.depth++] = window_build_client(c->window); } diff --git a/client.c b/client.c index d07a1f3..c44f8bd 100644 --- a/client.c +++ b/client.c @@ -62,9 +62,7 @@ client* window_build_client(Window win) if (XGetWindowAttributes(display, c->window, &c->attr)) { c->visible = c->attr.map_state == IsViewable ? 1:0; - XGetTransientForHint(display, c->window, &c->transient); if (!GETPROP_ATOM(win, atoms[_NET_WM_WINDOW_TYPE], &c->type, 1)) c->type = 0; - if (!GETPROP_WIND(win, atoms[WM_CLIENT_LEADER], &c->leader, 1)) c->leader = None; c->manage = !c->attr.override_redirect && c->type != atoms[_NET_WM_WINDOW_TYPE_DESKTOP] @@ -73,40 +71,43 @@ client* window_build_client(Window win) && c->type != atoms[_NET_WM_WINDOW_TYPE_SPLASH] ? 1:0; - c->spot = SPOT1; m = &monitors[0]; - - for_monitors(i, m) - if (INTERSECT(m->x, m->y, m->w, m->h, c->attr.x + c->attr.width/2, c->attr.y+c->attr.height/2, 1, 1)) - { c->monitor = i; break; } - - for_spots_rev(i) - if (INTERSECT(m->spots[i].x, m->spots[i].y, m->spots[i].w, m->spots[i].h, - c->attr.x + c->attr.width/2, c->attr.y+c->attr.height/2, 1, 1)) - { c->spot = i; break; } + for_monitors(i, m) for_spots(j) + if (m->bars[j] && m->bars[j]->window == c->window) + { c->ours = 1; c->manage = 0; break; } if (c->manage) - for_monitors(i, m) for_spots(j) - if (m->bars[j] && m->bars[j]->window == c->window) - c->manage = 0; - - if (c->visible) { - if (!GETPROP_ATOM(c->window, atoms[_NET_WM_STATE], c->states, ATOMLIST)) - memset(c->states, 0, sizeof(Atom) * ATOMLIST); - c->urgent = client_has_state(c, atoms[_NET_WM_STATE_DEMANDS_ATTENTION]); - c->full = client_has_state(c, atoms[_NET_WM_STATE_FULLSCREEN]); - c->above = client_has_state(c, atoms[_NET_WM_STATE_ABOVE]); + XGetTransientForHint(display, c->window, &c->transient); + if (!GETPROP_WIND(win, atoms[WM_CLIENT_LEADER], &c->leader, 1)) c->leader = None; + c->spot = SPOT1; m = &monitors[0]; - if ((hints = XGetWMHints(display, c->window))) + for_monitors(i, m) + if (INTERSECT(m->x, m->y, m->w, m->h, c->attr.x + c->attr.width/2, c->attr.y+c->attr.height/2, 1, 1)) + { c->monitor = i; break; } + + for_spots_rev(i) + if (INTERSECT(m->spots[i].x, m->spots[i].y, m->spots[i].w, m->spots[i].h, c->attr.x + c->attr.width/2, c->attr.y+c->attr.height/2, 1, 1)) + { c->spot = i; break; } + + if (c->visible) { - c->input = hints->flags & InputHint && hints->input ? 1:0; - c->urgent = c->urgent || hints->flags & XUrgencyHint ? 1:0; - XFree(hints); - } - if (XGetClassHint(display, c->window, &chint)) - { - c->class = strdup(chint.res_class); - XFree(chint.res_class); XFree(chint.res_name); + if (!GETPROP_ATOM(c->window, atoms[_NET_WM_STATE], c->states, ATOMLIST)) + memset(c->states, 0, sizeof(Atom) * ATOMLIST); + c->urgent = client_has_state(c, atoms[_NET_WM_STATE_DEMANDS_ATTENTION]); + c->full = client_has_state(c, atoms[_NET_WM_STATE_FULLSCREEN]); + c->above = client_has_state(c, atoms[_NET_WM_STATE_ABOVE]); + + if ((hints = XGetWMHints(display, c->window))) + { + c->input = hints->flags & InputHint && hints->input ? 1:0; + c->urgent = c->urgent || hints->flags & XUrgencyHint ? 1:0; + XFree(hints); + } + if (XGetClassHint(display, c->window, &chint)) + { + c->class = strdup(chint.res_class); + XFree(chint.res_class); XFree(chint.res_name); + } } } return c; diff --git a/config.h b/config.h index 8ff790d..b7f42c4 100644 --- a/config.h +++ b/config.h @@ -8,10 +8,10 @@ #define GAP 2 // Title bar xft font -#define TITLE "sans:bold:size=10" +#define TITLE "sans:size=8" #define TITLE_BLUR "Black" #define TITLE_FOCUS "White" -#define TITLE_ELLIPSIS 30 +#define TITLE_ELLIPSIS 32 // There are three static tiles called SPOT1, SPOT2, and SPOT3. // Want more tiles? Different layouts? Floating? Go away ;) @@ -143,4 +143,6 @@ binding keys[] = { { .mod = AnyModifier, .key = XK_F2, .act = action_find_or_start, .data = "uzbl-tabbed" }, { .mod = AnyModifier, .key = XK_F3, .act = action_find_or_start, .data = "pcmanfm" }, { .mod = AnyModifier, .key = XK_F4, .act = action_find_or_start, .data = "kate" }, + + { .mod = AnyModifier, .key = XK_Menu, .act = action_command, .data = "xowl" }, }; diff --git a/event.c b/event.c index 889f39e..b3d76ec 100644 --- a/event.c +++ b/event.c @@ -135,22 +135,21 @@ void key_press(XEvent *ev) client *cli = window_build_client(current); bind->act(bind->data, bind->num, cli); client_free(cli); + update_bars(); } } void button_press(XEvent *ev) { + int i, j; monitor *m; XButtonEvent *e = &ev->xbutton; latest = e->time; client *c = window_build_client(e->subwindow); if (c && c->manage) client_activate(c); else - { - int i, j; monitor *m; for_monitors(i, m) for_spots(j) if (m->bars[j]->window == e->subwindow) spot_focus_top_window(j, i, None); - } client_free(c); XAllowEvents(display, ReplayPointer, CurrentTime); } @@ -183,17 +182,15 @@ void property_notify(XEvent *ev) client *c = window_build_client(e->window); if (c && c->visible && c->manage) + { client_update_border(c); + if (e->atom == atoms[WM_NAME] || e->atom == atoms[_NET_WM_NAME]) + spot_update_bar(c->spot, c->monitor); + } client_free(c); - if (e->atom == atoms[WM_NAME] || e->atom == atoms[_NET_WM_NAME]) - update_bars(); - - // clients that rapidly update stuff (eg, title) can spam events. - // consume as many as possible of the same window, type, and atom... - Atom atom = e->atom; - while (XCheckTypedWindowEvent(display, ev->xproperty.window, PropertyNotify, ev)) - if (ev->xproperty.atom != atom) { XPutBackEvent(display, ev); break; } + // prevent spam + while (XCheckTypedWindowEvent(display, ev->xproperty.window, PropertyNotify, ev)); } void expose(XEvent *e) diff --git a/setup.c b/setup.c index 1a36b3c..9d7397a 100644 --- a/setup.c +++ b/setup.c @@ -55,6 +55,9 @@ void setup() } // detect and adjust for panel struts + monitor padded[MONITORS]; + memmove(padded, monitors, sizeof(monitor) * MONITORS); + for_windows(i, c) { wm_strut strut; memset(&strut, 0, sizeof(wm_strut)); @@ -64,6 +67,7 @@ void setup() for_monitors(j, m) { + monitor *p = &padded[j]; // convert _NET_WM_STRUT to _PARTIAL if (v1) { @@ -72,30 +76,37 @@ void setup() strut.tx1 = m->x; strut.tx2 = m->x + m->w; strut.bx1 = m->x; strut.bx2 = m->x + m->w; } + // monitor left side of root window? if (strut.left > 0 && !m->x && INTERSECT(0, strut.ly1, strut.left, strut.ly2 - strut.ly1, m->x, m->y, m->w, m->h)) { - m->x += strut.left; - m->w -= strut.left; + p->x = MAX(p->x, strut.left); + p->w = MIN(p->w, m->x + m->w - strut.left); } + else + // monitor right side of root window? if (strut.right > 0 && m->x + m->w == screen_w && INTERSECT(screen_w - strut.right, strut.ry1, strut.right, strut.ry3 - strut.ry1, m->x, m->y, m->w, m->h)) { - m->w -= strut.right; + p->w = MIN(p->w, m->x + m->w - strut.right); } + // monitor top side of root window? if (strut.top > 0 && !m->y && INTERSECT(strut.tx1, 0, strut.tx2 - strut.tx1, strut.top, m->x, m->y, m->w, m->h)) { - m->y += strut.top; - m->h -= strut.top; + p->y = MAX(p->y, strut.top); + p->h = MIN(p->h, m->y + m->h - strut.top); } + else + // monitor bottom side of root window? if (strut.bottom > 0 && m->y + m->h == screen_h && INTERSECT(strut.bx1, screen_h - strut.bottom, strut.bx2 - strut.bx1, strut.bottom, m->x, m->y, m->w, m->h)) { - m->h -= strut.bottom; + p->h = MIN(p->h, m->y + m->h - strut.bottom); } } } + memmove(monitors, padded, sizeof(monitor) * MONITORS); // calculate spot boxes for_monitors(i, m) @@ -182,18 +193,15 @@ void setup() // create title bars STACK_FREE(&windows); - for_monitors(i, m) + for_monitors(i, m) for_spots(j) { - for_spots(j) - { - m->bars[j] = textbox_create(root, TB_AUTOHEIGHT|TB_LEFT, m->spots[j].x, m->spots[j].y, m->spots[j].w, 0, - TITLE, TITLE_BLUR, BORDER_BLUR, NULL, NULL); - XSelectInput(display, m->bars[j]->window, ExposureMask); + m->bars[j] = textbox_create(root, TB_AUTOHEIGHT|TB_LEFT, m->spots[j].x, m->spots[j].y, m->spots[j].w, 0, + TITLE, TITLE_BLUR, BORDER_BLUR, NULL, NULL); + XSelectInput(display, m->bars[j]->window, ExposureMask); - m->spots[j].y += m->bars[j]->h; - m->spots[j].h -= m->bars[j]->h; - spot_update_bar(j, i); - } + m->spots[j].y += m->bars[j]->h; + m->spots[j].h -= m->bars[j]->h; + spot_update_bar(j, i); } // setup existing managable windows diff --git a/spot.c b/spot.c index e465729..4616a90 100644 --- a/spot.c +++ b/spot.c @@ -84,6 +84,21 @@ Window spot_focus_top_window(int spot, int mon, Window except) return None; } +Window spot_try_focus_top_window(int spot, int mon, Window except) +{ + Window w = spot_focus_top_window(spot, mon, except); + if (w == None) + { + current = None; + current_mon = mon; + current_spot = spot; + update_bars(); + + XSetInputFocus(display, PointerRoot, RevertToPointerRoot, CurrentTime); + } + return w; +} + int spot_choose_by_direction(int spot, int mon, int dir) { monitor *m = &monitors[mon]; diff --git a/xoat.c b/xoat.c index 5bf01fd..b2377c3 100644 --- a/xoat.c +++ b/xoat.c @@ -77,7 +77,7 @@ typedef struct { XWindowAttributes attr; Window transient, leader; Atom type, states[ATOMLIST+1]; - short monitor, visible, manage, input, urgent, full, above; + short monitor, visible, manage, input, urgent, full, above, ours; unsigned long spot; char *class; } client; @@ -191,10 +191,10 @@ void (*handlers[LASTEvent])(XEvent*) = { int oops(Display *d, XErrorEvent *ee) { if (ee->error_code == BadWindow - || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) + || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch) - || (ee->request_code == X_GrabButton && ee->error_code == BadAccess) - || (ee->request_code == X_GrabKey && ee->error_code == BadAccess) + || (ee->request_code == X_GrabButton && ee->error_code == BadAccess) + || (ee->request_code == X_GrabKey && ee->error_code == BadAccess) ) return 0; fprintf(stderr, "error: request code=%d, error code=%d\n", ee->request_code, ee->error_code); return xerror(display, ee);