From 7014506f150e9ad65138478be77e7a06a84c9ae2 Mon Sep 17 00:00:00 2001 From: seanpringle Date: Tue, 25 Sep 2012 15:58:40 +1000 Subject: [PATCH 1/3] misc cleanup --- action.c | 1 + setup.c | 16 ++++++------ spot.c | 38 +++++++++++------------------ textbox.c | 73 +++++++++++++++---------------------------------------- 4 files changed, 42 insertions(+), 86 deletions(-) diff --git a/action.c b/action.c index 683961b..dc925c2 100644 --- a/action.c +++ b/action.c @@ -146,6 +146,7 @@ void action_rollback(void *data, int num, client *cli) } } client_free(c); + c = NULL; } if (a) { diff --git a/setup.c b/setup.c index f728f53..1a36b3c 100644 --- a/setup.c +++ b/setup.c @@ -25,16 +25,13 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ typedef struct { - long left, right, top, bottom, - ly1, ly2, ry1, ry3, - tx1, tx2, bx1, bx2; + // _NET_WM_STRUT_PARTIAL + long left, right, top, bottom, ly1, ly2, ry1, ry3, tx1, tx2, bx1, bx2; } wm_strut; void setup() { int i, j; client *c; monitor *m; - wm_strut struts; memset(&struts, 0, sizeof(wm_strut)); - int screen_w = WidthOfScreen(DefaultScreenOfDisplay(display)); int screen_h = HeightOfScreen(DefaultScreenOfDisplay(display)); @@ -67,6 +64,7 @@ void setup() for_monitors(j, m) { + // convert _NET_WM_STRUT to _PARTIAL if (v1) { strut.ly1 = m->y; strut.ly2 = m->y + m->h; @@ -126,6 +124,7 @@ void setup() } continue; } + // normal wide screen int width_spot1 = (double)w / 100 * MIN(90, MAX(10, SPOT1_WIDTH_PCT)); int height_spot2 = (double)h / 100 * MIN(90, MAX(10, SPOT2_HEIGHT_PCT)); for_spots(j) @@ -161,10 +160,9 @@ void setup() // figure out NumlockMask XModifierKeymap *modmap = XGetModifierMapping(display); - for (i = 0; i < 8; i++) - for (j = 0; j < (int)modmap->max_keypermod; j++) - if (modmap->modifiermap[i*modmap->max_keypermod+j] == XKeysymToKeycode(display, XK_Num_Lock)) - { NumlockMask = (1<max_keypermod; j++) + if (modmap->modifiermap[i*modmap->max_keypermod+j] == XKeysymToKeycode(display, XK_Num_Lock)) + { NumlockMask = (1<manage && o->spot == spot && o->monitor == mon) { if (!c) c = o; - char *name = NULL; + char *name = NULL, *tmp = NULL; if (!(name = window_get_text_prop(o->window, atoms[_NET_WM_NAME]))) - { - char *tmp; if (XFetchName(display, o->window, &tmp)) - { name = strdup(tmp); - XFree(tmp); - } - } if (name) { - if (TITLE_ELLIPSIS && strlen(name) > TITLE_ELLIPSIS) + if (TITLE_ELLIPSIS > 0 && strlen(name) > TITLE_ELLIPSIS) { name = realloc(name, strlen(name)+4); strcpy(name+TITLE_ELLIPSIS, "..."); } - len += snprintf(title+len, MAX(0, lim-len), " [%d] %s ", n++, name); + len += snprintf(title+len, MAX(0, SPOT_BUFF-len), " [%d] %s ", n++, name); free(name); } + if (tmp) XFree(tmp); } - if (c && !c->full && title && m->bars[spot]) + if (c && !c->full && *title && m->bars[spot]) { int focus = c->window == current || (spot == current_spot && mon == current_mon); char *color = focus && c->window == current ? TITLE_FOCUS : TITLE_BLUR; @@ -69,27 +64,22 @@ void spot_update_bar(int spot, int mon) else if (m->bars[spot]) textbox_hide(m->bars[spot]); - free(title); } void update_bars() { int i, j; monitor *m; - for_monitors(i, m) for_spots(j) - spot_update_bar(j, i); + for_monitors(i, m) for_spots(j) spot_update_bar(j, i); } Window spot_focus_top_window(int spot, int mon, Window except) { int i; client *c; - for_windows(i, c) + for_windows(i, c) if (c->window != except && c->manage && c->spot == spot && c->monitor == mon) { - if (c->window != except && c->manage && c->spot == spot && c->monitor == mon) - { - client_raise_family(c); - client_set_focus(c); - return c->window; - } + client_raise_family(c); + client_set_focus(c); + return c->window; } return None; } diff --git a/textbox.c b/textbox.c index ff13cca..050c2d7 100644 --- a/textbox.c +++ b/textbox.c @@ -34,8 +34,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. typedef struct { unsigned long flags; Window window, parent; - short x, y, w, h; - short cursor; + short x, y, w, h, cursor; XftFont *font; XftColor color_fg, color_bg; char *text, *prompt; @@ -180,7 +179,6 @@ void textbox_draw(textbox *tb) int text_len = strlen(text); int length = text_len; int line_height = tb->font->ascent + tb->font->descent; - int line_width = 0; int cursor_x = 0; int cursor_offset = 0; @@ -208,7 +206,7 @@ void textbox_draw(textbox *tb) // calc full input text width XftTextExtents8(display, tb->font, (unsigned char*)line, length, &extents); - line_width = extents.width; + int line_width = extents.width; int x = 0, y = tb->font->ascent; if (tb->flags & TB_RIGHT) x = tb->w - line_width; @@ -315,60 +313,29 @@ void textbox_cursor_bkspc(textbox *tb) // -1 = handled and return pressed (finished) int textbox_keypress(textbox *tb, XEvent *ev) { - KeySym key; Status stat; - char pad[32]; int len; - if (!(tb->flags & TB_EDITABLE)) return 0; - len = XmbLookupString(tb->xic, &ev->xkey, pad, sizeof(pad), &key, &stat); + KeySym key; Status stat; char pad[32]; + + int len = XmbLookupString(tb->xic, &ev->xkey, pad, sizeof(pad), &key, &stat); pad[len] = 0; - if (key == XK_Left) + switch (key) { - textbox_cursor_dec(tb); - return 1; - } - else - if (key == XK_Right) - { - textbox_cursor_inc(tb); - return 1; - } - else - if (key == XK_Home) - { - textbox_cursor_home(tb); - return 1; - } - else - if (key == XK_End) - { - textbox_cursor_end(tb); - return 1; - } - else - if (key == XK_Delete) - { - textbox_cursor_del(tb); - return 1; - } - else - if (key == XK_BackSpace) - { - textbox_cursor_bkspc(tb); - return 1; - } - else - if (key == XK_Return) - { - return -1; - } - else - if (!iscntrl(*pad)) - { - textbox_insert(tb, tb->cursor, pad); - textbox_cursor_inc(tb); - return 1; + case XK_Left : textbox_cursor_dec(tb); return 1; + case XK_Right : textbox_cursor_inc(tb); return 1; + case XK_Home : textbox_cursor_home(tb); return 1; + case XK_End : textbox_cursor_end(tb); return 1; + case XK_Delete : textbox_cursor_del(tb); return 1; + case XK_BackSpace : textbox_cursor_bkspc(tb); return 1; + case XK_Return : return -1; + default: + if (!iscntrl(*pad)) + { + textbox_insert(tb, tb->cursor, pad); + textbox_cursor_inc(tb); + return 1; + } } return 0; } From 1508e1a74849ee3081783b2590a8ee3edf76fc51 Mon Sep 17 00:00:00 2001 From: seanpringle Date: Thu, 25 Oct 2012 02:01:36 +1000 Subject: [PATCH 2/3] 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); From 5d6b0fc6878b305dffdd80388a7ca6444e3e8058 Mon Sep 17 00:00:00 2001 From: seanpringle Date: Thu, 25 Oct 2012 02:05:48 +1000 Subject: [PATCH 3/3] protect config.h --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..5f327fd --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +config.h merge=ours