From 455361d11232a3e48d0d82d135f13a0317725d95 Mon Sep 17 00:00:00 2001 From: seanpringle Date: Wed, 7 Nov 2012 17:32:51 +1000 Subject: [PATCH 1/6] remove snapshot stuff. not useful. --- action.c | 34 ---------------------------------- config.h | 4 ---- xoat.c | 4 +--- 3 files changed, 1 insertion(+), 41 deletions(-) diff --git a/action.c b/action.c index a5130e4..d30b013 100644 --- a/action.c +++ b/action.c @@ -120,37 +120,3 @@ void action_above(void *data, int num, client *cli) client_update_border(cli); client_raise_family(cli); } - -void action_snapshot(void *data, int num, client *cli) -{ - 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); -} - -void action_rollback(void *data, int num, client *cli) -{ - int i; client *c = NULL, *s, *a = NULL; - for (i = snapshot.depth-1; i > -1; i--) - { - if ((s = snapshot.clients[i]) && (c = window_build_client(s->window)) - && c->class && !strcmp(s->class, c->class) && c->visible && c->manage) - { - client_place_spot(c, s->spot, s->monitor, 1); - client_raise_family(c); - if (s->spot == current_spot && s->monitor == current_mon) - { - client_free(a); - a = c; c = NULL; - } - } - client_free(c); - c = NULL; - } - if (a) - { - client_set_focus(a); - client_free(a); - } -} - diff --git a/config.h b/config.h index 44f20d9..615b306 100644 --- a/config.h +++ b/config.h @@ -133,10 +133,6 @@ binding keys[] = { // Launcher { .mod = Mod4Mask, .key = XK_x, .act = action_command, .data = "dmenu_run" }, - // Snapshot state - { .mod = Mod4Mask, .key = XK_s, .act = action_snapshot }, - { .mod = Mod4Mask, .key = XK_r, .act = action_rollback }, - // Find or start apps by WM_CLASS (lower case match). // Only works for apps that use some form of their binary name as their class... { .mod = AnyModifier, .key = XK_F1, .act = action_find_or_start, .data = "xterm" }, diff --git a/xoat.c b/xoat.c index b2377c3..25afc4b 100644 --- a/xoat.c +++ b/xoat.c @@ -111,8 +111,6 @@ void action_move_monitor(void*, int, client*); void action_focus_monitor(void*, int, client*); void action_fullscreen(void*, int, client*); void action_above(void*, int, client*); -void action_snapshot(void*, int, client*); -void action_rollback(void*, int, client*); #include "config.h" @@ -147,7 +145,7 @@ monitor monitors[MONITORS]; int nmonitors = 1; short current_spot, current_mon; Window root, ewmh, current = None; -stack windows, snapshot; +stack windows; static int (*xerror)(Display *, XErrorEvent *); void catch_exit(int sig) From ca715481e895b5ef2f7dbad3d0ec8ec38fc906a2 Mon Sep 17 00:00:00 2001 From: seanpringle Date: Wed, 7 Nov 2012 17:40:29 +1000 Subject: [PATCH 2/6] remove NET_WM_STATE_ABOVE support. not useful in this context. --- action.c | 8 -------- atom.c | 1 - client.c | 8 +------- config.h | 7 ------- xoat.1 | 17 ----------------- xoat.c | 2 +- xoat.md | 9 --------- 7 files changed, 2 insertions(+), 50 deletions(-) diff --git a/action.c b/action.c index d30b013..42c96df 100644 --- a/action.c +++ b/action.c @@ -112,11 +112,3 @@ void action_fullscreen(void *data, int num, client *cli) client_update_border(cli); client_raise_family(cli); } - -void action_above(void *data, int num, client *cli) -{ - if (!cli) return; - client_toggle_state(cli, atoms[_NET_WM_STATE_ABOVE]); - client_update_border(cli); - client_raise_family(cli); -} diff --git a/atom.c b/atom.c index c1a0f20..ce1b3ea 100644 --- a/atom.c +++ b/atom.c @@ -49,7 +49,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. X(_NET_WM_WINDOW_TYPE_DIALOG),\ X(_NET_WM_STATE),\ X(_NET_WM_STATE_FULLSCREEN),\ - X(_NET_WM_STATE_ABOVE),\ X(_NET_WM_STATE_DEMANDS_ATTENTION),\ X(WM_NAME),\ X(WM_DELETE_WINDOW),\ diff --git a/client.c b/client.c index c44f8bd..6aec31e 100644 --- a/client.c +++ b/client.c @@ -46,7 +46,6 @@ int client_toggle_state(client *c, Atom state) } SETPROP_ATOM(c->window, atoms[_NET_WM_STATE], c->states, j); if (state == atoms[_NET_WM_STATE_FULLSCREEN]) c->full = rc; - if (state == atoms[_NET_WM_STATE_ABOVE]) c->above = rc; if (state == atoms[_NET_WM_STATE_DEMANDS_ATTENTION]) c->urgent = rc; return rc; } @@ -95,7 +94,6 @@ client* window_build_client(Window win) 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))) { @@ -126,7 +124,7 @@ void client_free(client *c) void client_update_border(client *c) { XColor color; Colormap map = DefaultColormap(display, DefaultScreen(display)); - char *colorname = c->window == current ? BORDER_FOCUS: (c->urgent ? BORDER_URGENT: (c->above ? BORDER_ABOVE: BORDER_BLUR)); + char *colorname = c->window == current ? BORDER_FOCUS: (c->urgent ? BORDER_URGENT: BORDER_BLUR); XSetWindowBorder(display, c->window, XAllocNamedColor(display, map, colorname, &color, &color) ? color.pixel: None); XSetWindowBorderWidth(display, c->window, c->full ? 0: BORDER); } @@ -240,10 +238,6 @@ void client_raise_family(client *c) for_windows(i, o) if (o->type == atoms[_NET_WM_WINDOW_TYPE_DOCK]) client_stack_family(o, &raise); - // above only counts for fullscreen windows - if (c->full) for_windows(i, o) if (o->above) - client_stack_family(o, &raise); - while (c->transient && (o = window_build_client(c->transient))) c = family.clients[family.depth++] = o; diff --git a/config.h b/config.h index 615b306..994d52a 100644 --- a/config.h +++ b/config.h @@ -4,7 +4,6 @@ #define BORDER_BLUR "Dark Gray" #define BORDER_FOCUS "Royal Blue" #define BORDER_URGENT "Red" -#define BORDER_ABOVE "Dark Green" #define GAP 2 // Title bar xft font @@ -77,9 +76,6 @@ // action_move_monitor // action_focus_monitor // action_fullscreen -// action_above -// action_snapshot -// action_rollback // If you use "AnyModifier" place those keys at the end of the array. binding keys[] = { @@ -119,9 +115,6 @@ binding keys[] = { // Toggle current window full screen. { .mod = Mod4Mask, .key = XK_f, .act = action_fullscreen }, - // Toggle current window above. - { .mod = Mod4Mask, .key = XK_a, .act = action_above }, - // Switch focus between monitors. { .mod = Mod4Mask, .key = XK_Next, .act = action_focus_monitor, .num = +1 }, { .mod = Mod4Mask, .key = XK_Prior, .act = action_focus_monitor, .num = -1 }, diff --git a/xoat.1 b/xoat.1 index befba7a..757940e 100644 --- a/xoat.1 +++ b/xoat.1 @@ -72,11 +72,6 @@ While in fullscreen mode, an window is considered to be in tile 1. .RS .RE .TP -.B Mod4-a -Toggle state above (only placed above fullscreen windows). -.RS -.RE -.TP .B Mod4-Next (Page Down) Focus next monitor. .RS @@ -106,18 +101,6 @@ Launch dmenu_run Launch urxvt .RS .RE -.TP -.B Mod4-s -Snapshot current window positions and stacking order. -.RS -.RE -.TP -.B Mod4-r -Rollback to snapshot. -Windows closed since the snapshot will not be reopened. -Newer windows not in the snapshot will be lowered. -.RS -.RE .SH OPTIONS .PP All configuration is done via config.h. diff --git a/xoat.c b/xoat.c index 25afc4b..db0841c 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, ours; + short monitor, visible, manage, input, urgent, full, ours; unsigned long spot; char *class; } client; diff --git a/xoat.md b/xoat.md index d995153..64ffa3c 100644 --- a/xoat.md +++ b/xoat.md @@ -53,9 +53,6 @@ Mod4-Escape Mod4-f : Toggle state fullscreen. While in fullscreen mode, an window is considered to be in tile 1. -Mod4-a -: Toggle state above (only placed above fullscreen windows). - Mod4-Next (Page Down) : Focus next monitor. @@ -74,12 +71,6 @@ Shift-Mod4-x F1 : Launch urxvt -Mod4-s -: Snapshot current window positions and stacking order. - -Mod4-r -: Rollback to snapshot. Windows closed since the snapshot will not be reopened. Newer windows not in the snapshot will be lowered. - # OPTIONS All configuration is done via config.h. From b9eacb9f505b0f50ece9048ce23267a911f42e16 Mon Sep 17 00:00:00 2001 From: seanpringle Date: Wed, 7 Nov 2012 17:51:18 +1000 Subject: [PATCH 3/6] docs --- config.h | 1 - xoat.1 | 4 ++-- xoat.md | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/config.h b/config.h index 994d52a..c2b6d76 100644 --- a/config.h +++ b/config.h @@ -70,7 +70,6 @@ // action_focus_direction .num = UP/DOWN/LEFT/RIGHT // action_close // action_cycle -// action_other // action_command // action_find_or_start // action_move_monitor diff --git a/xoat.1 b/xoat.1 index 757940e..3d0b782 100644 --- a/xoat.1 +++ b/xoat.1 @@ -92,13 +92,13 @@ Move window to previous monitor. .RS .RE .TP -.B Shift-Mod4-x +.B Mod4-x Launch dmenu_run .RS .RE .TP .B F1 -Launch urxvt +Launch xterm .RS .RE .SH OPTIONS diff --git a/xoat.md b/xoat.md index 64ffa3c..670f12c 100644 --- a/xoat.md +++ b/xoat.md @@ -65,11 +65,11 @@ Shift-Mod4-Next Shift-Mod4-Prior : Move window to previous monitor. -Shift-Mod4-x +Mod4-x : Launch dmenu_run F1 -: Launch urxvt +: Launch xterm # OPTIONS From 019d6c210bd73d31fb8125b34d761456b88aca20 Mon Sep 17 00:00:00 2001 From: seanpringle Date: Wed, 7 Nov 2012 18:01:28 +1000 Subject: [PATCH 4/6] remove focus ignore/steal stuff. use apps that behave. --- config.h | 6 ------ event.c | 4 +--- xoat.c | 1 - 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/config.h b/config.h index c2b6d76..ce30658 100644 --- a/config.h +++ b/config.h @@ -57,12 +57,6 @@ // If on multi-head, place windows on monitor holding current window. #define MONITOR_START MONITOR_CURRENT -// Should new windows be automatically focused, or ignored until focused manually? -// IGNORE means new windows only steal focus if they obscure the current window. -// STEAL means new windows always steal focus. -//#define FOCUS_START FOCUS_IGNORE -#define FOCUS_START FOCUS_STEAL - // Available actions... // action_move .num = SPOT1/2/3 // action_focus .num = SPOT1/2/3 diff --git a/event.c b/event.c index b3d76ec..71c3d2d 100644 --- a/event.c +++ b/event.c @@ -99,9 +99,7 @@ void map_notify(XEvent *e) { client_raise_family(c); client_update_border(c); - // if no current window, or new window has opened in the current spot, focus it - if (FOCUS_START == FOCUS_STEAL || !(a = window_build_client(current)) || (a && a->spot == c->spot)) - client_set_focus(c); + client_set_focus(c); client_free(a); ewmh_client_list(); update_bars(); diff --git a/xoat.c b/xoat.c index db0841c..3db47a5 100644 --- a/xoat.c +++ b/xoat.c @@ -59,7 +59,6 @@ Display *display; #define ATOMLIST 10 enum { MONITOR_CURRENT=-1 }; enum { SPOT1=1, SPOT2, SPOT3, SPOT_CURRENT, SPOT_SMART, SPOT1_LEFT, SPOT1_RIGHT }; -enum { FOCUS_IGNORE=1, FOCUS_STEAL, }; enum { LEFT=1, RIGHT, UP, DOWN }; typedef struct { From 4197ad0bfccfe389538024cdce8247f25c2a8dc3 Mon Sep 17 00:00:00 2001 From: seanpringle Date: Wed, 7 Nov 2012 18:05:52 +1000 Subject: [PATCH 5/6] remove monitor_start. does not play that well with spot_start --- config.h | 7 ------- event.c | 3 +-- xoat.c | 1 - 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/config.h b/config.h index ce30658..7dd230b 100644 --- a/config.h +++ b/config.h @@ -50,13 +50,6 @@ // If spot is not current, window won't steal focus. //#define SPOT_START SPOT1 -// If on multi-head, place windows on monitor N. -// (0-based index, same order as xrandr list) -//#define MONITOR_START 0 - -// If on multi-head, place windows on monitor holding current window. -#define MONITOR_START MONITOR_CURRENT - // Available actions... // action_move .num = SPOT1/2/3 // action_focus .num = SPOT1/2/3 diff --git a/event.c b/event.c index 71c3d2d..7e27861 100644 --- a/event.c +++ b/event.c @@ -73,8 +73,7 @@ void map_request(XEvent *e) client *c = window_build_client(e->xmaprequest.window); if (c && c->manage) { - c->monitor = MONITOR_START == MONITOR_CURRENT ? current_mon: MONITOR_START; - c->monitor = MIN(nmonitors-1, MAX(0, c->monitor)); + c->monitor = current_mon; monitor *m = &monitors[c->monitor]; int i, spot = SPOT_START == SPOT_CURRENT ? current_spot: SPOT_START; diff --git a/xoat.c b/xoat.c index 3db47a5..dfa09ae 100644 --- a/xoat.c +++ b/xoat.c @@ -57,7 +57,6 @@ Display *display; #define STACK 64 #define MONITORS 3 #define ATOMLIST 10 -enum { MONITOR_CURRENT=-1 }; enum { SPOT1=1, SPOT2, SPOT3, SPOT_CURRENT, SPOT_SMART, SPOT1_LEFT, SPOT1_RIGHT }; enum { LEFT=1, RIGHT, UP, DOWN }; From 3ff60a649a586d74ec7403aca9805408d349be47 Mon Sep 17 00:00:00 2001 From: seanpringle Date: Sun, 16 Dec 2012 14:08:06 +1000 Subject: [PATCH 6/6] support toggling _NET_WM_STATE_MAXIMIZE_VERT in spot2 and _NET_WM_STATE_MAXIMIZE_HORZ in spot3. --- action.c | 14 ++++++++++++++ atom.c | 2 ++ client.c | 40 ++++++++++++++++++++++++++++++++++++++++ config.h | 6 +++++- xoat.c | 5 +++-- 5 files changed, 64 insertions(+), 3 deletions(-) diff --git a/action.c b/action.c index 42c96df..2281629 100644 --- a/action.c +++ b/action.c @@ -112,3 +112,17 @@ void action_fullscreen(void *data, int num, client *cli) client_update_border(cli); client_raise_family(cli); } + +void action_maximize_vert(void *data, int num, client *cli) +{ + if (!cli) return; + cli->maxv = client_toggle_state(cli, atoms[_NET_WM_STATE_MAXIMIZE_VERT]); + client_place_spot(cli, cli->spot, cli->monitor, 1); +} + +void action_maximize_horz(void *data, int num, client *cli) +{ + if (!cli) return; + cli->maxh = client_toggle_state(cli, atoms[_NET_WM_STATE_MAXIMIZE_HORZ]); + client_place_spot(cli, cli->spot, cli->monitor, 1); +} \ No newline at end of file diff --git a/atom.c b/atom.c index ce1b3ea..300c1a5 100644 --- a/atom.c +++ b/atom.c @@ -49,6 +49,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. X(_NET_WM_WINDOW_TYPE_DIALOG),\ X(_NET_WM_STATE),\ X(_NET_WM_STATE_FULLSCREEN),\ + X(_NET_WM_STATE_MAXIMIZE_VERT),\ + X(_NET_WM_STATE_MAXIMIZE_HORZ),\ X(_NET_WM_STATE_DEMANDS_ATTENTION),\ X(WM_NAME),\ X(WM_DELETE_WINDOW),\ diff --git a/client.c b/client.c index 6aec31e..87e1414 100644 --- a/client.c +++ b/client.c @@ -70,6 +70,7 @@ client* window_build_client(Window win) && c->type != atoms[_NET_WM_WINDOW_TYPE_SPLASH] ? 1:0; + // detect our own title bars for_monitors(i, m) for_spots(j) if (m->bars[j] && m->bars[j]->window == c->window) { c->ours = 1; c->manage = 0; break; } @@ -92,8 +93,23 @@ client* window_build_client(Window win) { 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->maxv = client_has_state(c, atoms[_NET_WM_STATE_MAXIMIZE_VERT]); + c->maxh = client_has_state(c, atoms[_NET_WM_STATE_MAXIMIZE_HORZ]); + + // _NET_WM_STATE_MAXIMIZE_VERT may apply to spot2 windows. Detect... + if (c->maxv && c->type != atoms[_NET_WM_WINDOW_TYPE_DIALOG] + && INTERSECT(m->spots[SPOT2].x, m->spots[SPOT2].y, m->spots[SPOT2].w, m->spots[SPOT2].h, + c->attr.x + c->attr.width/10, c->attr.y + c->attr.height/10, c->attr.width - c->attr.width/10, c->attr.height - c->attr.height/10)) + c->spot = SPOT2; + + // _NET_WM_STATE_MAXIMIZE_HORZ may apply to spot3 windows. Detect... + if (c->maxh && c->type != atoms[_NET_WM_WINDOW_TYPE_DIALOG] + && INTERSECT(m->spots[SPOT3].x, m->spots[SPOT3].y, m->spots[SPOT3].w, m->spots[SPOT3].h, + c->attr.x + c->attr.width/10, c->attr.y + c->attr.height/10, c->attr.width - c->attr.width/10, c->attr.height - c->attr.height/10)) + c->spot = SPOT3; if ((hints = XGetWMHints(display, c->window))) { @@ -179,6 +195,19 @@ void client_place_spot(client *c, int spot, int mon, int force) XMoveResizeWindow(display, c->window, m->x, m->y, m->w, m->h); return; } + else + // _NET_WM_STATE_MAXIMIZE_VERT may apply to a window in spot2 + if (c->maxv && spot == SPOT2) + { + h = m->h - y; + } + else + // _NET_WM_STATE_MAXIMIZE_HORZ may apply to a window in spot3 + if (c->maxh && spot == SPOT3) + { + w = m->w; + } + w -= BORDER*2; h -= BORDER*2; int sw = w, sh = h; long sr; XSizeHints size; @@ -242,8 +271,19 @@ void client_raise_family(client *c) c = family.clients[family.depth++] = o; client_stack_family(c, &raise); + + if (!c->full) + { + // raise spot's title bar in case some other fullscreen or max v/h window has obscured + monitor *m = &monitors[c->monitor]; + raise.windows[raise.depth] = m->bars[c->spot]->window; + raise.clients[raise.depth] = NULL; + raise.depth++; + } + XRaiseWindow(display, raise.windows[0]); XRestackWindows(display, raise.windows, raise.depth); + STACK_FREE(&family); } diff --git a/config.h b/config.h index 7dd230b..db16440 100644 --- a/config.h +++ b/config.h @@ -7,7 +7,7 @@ #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 @@ -62,6 +62,8 @@ // action_move_monitor // action_focus_monitor // action_fullscreen +// action_maximize_vert +// action_maximize_horz // If you use "AnyModifier" place those keys at the end of the array. binding keys[] = { @@ -100,6 +102,8 @@ binding keys[] = { // Toggle current window full screen. { .mod = Mod4Mask, .key = XK_f, .act = action_fullscreen }, + { .mod = Mod4Mask, .key = XK_v, .act = action_maximize_vert }, + { .mod = Mod4Mask, .key = XK_h, .act = action_maximize_horz }, // Switch focus between monitors. { .mod = Mod4Mask, .key = XK_Next, .act = action_focus_monitor, .num = +1 }, diff --git a/xoat.c b/xoat.c index dfa09ae..0a0f77f 100644 --- a/xoat.c +++ b/xoat.c @@ -75,7 +75,7 @@ typedef struct { XWindowAttributes attr; Window transient, leader; Atom type, states[ATOMLIST+1]; - short monitor, visible, manage, input, urgent, full, ours; + short monitor, visible, manage, input, urgent, full, ours, maxv, maxh; unsigned long spot; char *class; } client; @@ -108,7 +108,8 @@ void action_find_or_start(void*, int, client*); void action_move_monitor(void*, int, client*); void action_focus_monitor(void*, int, client*); void action_fullscreen(void*, int, client*); -void action_above(void*, int, client*); +void action_maximize_vert(void*, int, client*); +void action_maximize_horz(void*, int, client*); #include "config.h"