replace tags with snapshot mechanism

This commit is contained in:
seanpringle
2012-09-08 21:51:58 +10:00
parent 29a1c1f490
commit cd3f873bb8
6 changed files with 55 additions and 135 deletions

View File

@@ -92,18 +92,9 @@ binding keys[] = {
// Launcher // Launcher
{ .mod = Mod4Mask, .key = XK_x, .act = ACTION_COMMAND, .data = "dmenu_run" }, { .mod = Mod4Mask, .key = XK_x, .act = ACTION_COMMAND, .data = "dmenu_run" },
// Raise tag groups // Snapshot state
{ .mod = Mod4Mask, .key = XK_1, .act = ACTION_RAISE_TAG, .num = TAG1 }, { .mod = Mod4Mask, .key = XK_s, .act = ACTION_SNAPSHOT },
{ .mod = Mod4Mask, .key = XK_2, .act = ACTION_RAISE_TAG, .num = TAG2 }, { .mod = Mod4Mask, .key = XK_r, .act = ACTION_ROLLBACK },
{ .mod = Mod4Mask, .key = XK_3, .act = ACTION_RAISE_TAG, .num = TAG3 },
// Tag/untag the current window
{ .mod = ShiftMask|Mod4Mask, .key = XK_1, .act = ACTION_TAG, .num = TAG1 },
{ .mod = ShiftMask|Mod4Mask, .key = XK_2, .act = ACTION_TAG, .num = TAG2 },
{ .mod = ShiftMask|Mod4Mask, .key = XK_3, .act = ACTION_TAG, .num = TAG3 },
{ .mod = ShiftMask|ControlMask|Mod4Mask, .key = XK_1, .act = ACTION_UNTAG, .num = TAG1 },
{ .mod = ShiftMask|ControlMask|Mod4Mask, .key = XK_2, .act = ACTION_UNTAG, .num = TAG2 },
{ .mod = ShiftMask|ControlMask|Mod4Mask, .key = XK_3, .act = ACTION_UNTAG, .num = TAG3 },
// Find or start apps by WM_CLASS (lower case match). // Find or start apps by WM_CLASS (lower case match).
{ .mod = AnyModifier, .key = XK_F1, .act = ACTION_FIND_OR_START, .data = "urxvt" }, { .mod = AnyModifier, .key = XK_F1, .act = ACTION_FIND_OR_START, .data = "urxvt" },

View File

@@ -28,7 +28,6 @@ void client_set_focus(client *c);
void client_activate(client *c); void client_activate(client *c);
void window_listen(Window win); void window_listen(Window win);
void client_update_border(client *c); void client_update_border(client *c);
void client_flush_tags(client *c);
void action_move(void *data, int num, client *cli); void action_move(void *data, int num, client *cli);
void action_focus(void *data, int num, client *cli); void action_focus(void *data, int num, client *cli);
void action_close(void *data, int num, client *cli); void action_close(void *data, int num, client *cli);
@@ -38,11 +37,10 @@ void action_command(void *data, int num, client *cli);
void action_find_or_start(void *data, int num, client *cli); void action_find_or_start(void *data, int num, client *cli);
void action_move_monitor(void *data, int num, client *cli); void action_move_monitor(void *data, int num, client *cli);
void action_focus_monitor(void *data, int num, client *cli); void action_focus_monitor(void *data, int num, client *cli);
void action_raise_tag(void *data, int tag, client *cli);
void action_fullscreen(void *data, int num, client *cli); void action_fullscreen(void *data, int num, client *cli);
void action_above(void *data, int num, client *cli); void action_above(void *data, int num, client *cli);
void action_tag(void *data, int num, client *cli); void action_snapshot(void *data, int num, client *cli);
void action_untag(void *data, int num, client *cli); void action_rollback(void *data, int num, client *cli);
void create_notify(XEvent *e); void create_notify(XEvent *e);
void configure_request(XEvent *ev); void configure_request(XEvent *ev);
void configure_notify(XEvent *e); void configure_notify(XEvent *e);

45
xoat.1
View File

@@ -102,48 +102,15 @@ Launch urxvt
.RS .RS
.RE .RE
.TP .TP
.B Mod4-1 .B Mod4-s
Raise windows in tag 1. Snapshot current window positions and stacking order.
.RS .RS
.RE .RE
.TP .TP
.B Shift-Mod4-1 .B Mod4-r
Place current window in tag 1. Rollback to snapshot.
.RS Windows closed since the snapshot will not be reopened.
.RE Newer windows not in the snapshot will be lowered.
.TP
.B Shift-Control-Mod4-1
Remove current window from tag 1.
.RS
.RE
.TP
.B Mod4-2
Raise windows in tag 2.
.RS
.RE
.TP
.B Shift-Mod4-2
Place current window in tag 2.
.RS
.RE
.TP
.B Shift-Control-Mod4-2
Remove current window from tag 2.
.RS
.RE
.TP
.B Mod4-3
Raise windows in tag 3.
.RS
.RE
.TP
.B Shift-Mod4-3
Place current window in tag 3.
.RS
.RE
.TP
.B Shift-Control-Mod4-3
Remove current window from tag 3.
.RS .RS
.RE .RE
.SH OPTIONS .SH OPTIONS

82
xoat.c
View File

@@ -169,10 +169,6 @@ client* window_build_client(Window win)
window_get_atom_prop(c->window, atoms[_NET_WM_STATE], c->states, MAX_NET_WM_STATES); window_get_atom_prop(c->window, atoms[_NET_WM_STATE], c->states, MAX_NET_WM_STATES);
c->urgent = client_has_state(c, atoms[_NET_WM_STATE_DEMANDS_ATTENTION]); c->urgent = client_has_state(c, atoms[_NET_WM_STATE_DEMANDS_ATTENTION]);
unsigned long tags = 0;
if (window_get_cardinal_prop(c->window, atoms[XOAT_TAGS], &tags, 1))
c->tags = tags;
XWMHints *hints = XGetWMHints(display, c->window); XWMHints *hints = XGetWMHints(display, c->window);
if (hints) if (hints)
{ {
@@ -481,15 +477,6 @@ void client_update_border(client *c)
XSetWindowBorderWidth(display, c->window, client_has_state(c, atoms[_NET_WM_STATE_FULLSCREEN]) ? 0: BORDER); XSetWindowBorderWidth(display, c->window, client_has_state(c, atoms[_NET_WM_STATE_FULLSCREEN]) ? 0: BORDER);
} }
void client_flush_tags(client *c)
{
unsigned long tags = c->tags;
window_set_cardinal_prop(c->window, atoms[XOAT_TAGS], &tags, 1);
unsigned long desktop = tags & TAG3 ? 2: (tags & TAG2 ? 1: (tags & TAG1 ? 0: 0xffffffff));
window_set_cardinal_prop(c->window, atoms[_NET_WM_DESKTOP], &desktop, 1);
}
// ------- key actions ------- // ------- key actions -------
void action_move(void *data, int num, client *cli) void action_move(void *data, int num, client *cli)
@@ -551,25 +538,6 @@ void action_focus_monitor(void *data, int num, client *cli)
for (i = SPOT1; i <= SPOT3 && !spot_focus_top_window(i, mon, None); i++); for (i = SPOT1; i <= SPOT3 && !spot_focus_top_window(i, mon, None); i++);
} }
void action_raise_tag(void *data, int tag, client *cli)
{
int i; client *c = NULL, *t = NULL;
stack all; query_visible_windows(&all);
for (i = all.depth-1; i > -1; i--)
{
if ((c = all.clients[i]) && c->manage && c->visible && c->tags & tag)
{
if (c->monitor == current_mon && c->spot == current_spot) t = c;
client_raise_family(c);
}
}
if (t) client_set_focus(t);
unsigned long desktop = tag & TAG2 ? 1: (tag & TAG3 ? 2: 0);
window_set_cardinal_prop(root, atoms[_NET_CURRENT_DESKTOP], &desktop, 1);
}
void action_fullscreen(void *data, int num, client *cli) void action_fullscreen(void *data, int num, client *cli)
{ {
if (!cli) return; if (!cli) return;
@@ -597,18 +565,44 @@ void action_above(void *data, int num, client *cli)
client_raise_family(cli); client_raise_family(cli);
} }
void action_tag(void *data, int num, client *cli) void action_snapshot(void *data, int num, client *cli)
{ {
if (!cli) return; int i; client *c; stack wins;
cli->tags |= (unsigned int)num; stack_free(&snapshot);
client_flush_tags(cli); query_visible_windows(&wins);
for (i = 0; i < wins.depth; i++)
{
if ((c = wins.clients[i]) && c->manage)
{
snapshot.clients[snapshot.depth] = window_build_client(c->window);
snapshot.windows[snapshot.depth++] = c->window;
}
}
} }
void action_untag(void *data, int num, client *cli) void action_rollback(void *data, int num, client *cli)
{ {
if (!cli) return; int i; client *c = NULL, *s, *a = NULL;
cli->tags &= ~((unsigned int)num); for (i = snapshot.depth-1; i > -1; i--)
client_flush_tags(cli); {
if ((s = snapshot.clients[i]) && (c = window_build_client(s->window)) && c->visible && c->manage)
{
c->monitor = s->monitor;
client_place_spot(c, s->spot, 1);
client_raise_family(c);
if (s->spot == current_spot && s->monitor == current_mon)
{
client_free(a);
a = c; c = NULL;
}
}
client_free(c);
}
if (a)
{
client_set_focus(a);
client_free(a);
}
} }
// key actions // key actions
@@ -625,9 +619,8 @@ action actions[ACTIONS] = {
[ACTION_FOCUS_MONITOR] = action_focus_monitor, [ACTION_FOCUS_MONITOR] = action_focus_monitor,
[ACTION_FULLSCREEN_TOGGLE] = action_fullscreen, [ACTION_FULLSCREEN_TOGGLE] = action_fullscreen,
[ACTION_ABOVE_TOGGLE] = action_above, [ACTION_ABOVE_TOGGLE] = action_above,
[ACTION_TAG] = action_tag, [ACTION_SNAPSHOT] = action_snapshot,
[ACTION_UNTAG] = action_untag, [ACTION_ROLLBACK] = action_rollback,
[ACTION_RAISE_TAG] = action_raise_tag,
}; };
// ------- event handlers -------- // ------- event handlers --------
@@ -690,7 +683,6 @@ void map_request(XEvent *e)
client_place_spot(c, spot, 0); client_place_spot(c, spot, 0);
client_update_border(c); client_update_border(c);
client_flush_tags(c);
} }
if (c) XMapWindow(display, c->window); if (c) XMapWindow(display, c->window);
client_free(c); client_free(c);
@@ -936,6 +928,7 @@ int main(int argc, char *argv[])
XGrabButton(display, Button3, AnyModifier, root, True, ButtonPressMask, GrabModeSync, GrabModeSync, None, None); XGrabButton(display, Button3, AnyModifier, root, True, ButtonPressMask, GrabModeSync, GrabModeSync, None, None);
// setup existing managable windows // setup existing managable windows
memset(&snapshot, 0, sizeof(stack));
query_visible_windows(&wins); query_visible_windows(&wins);
for (i = 0; i < wins.depth; i++) for (i = 0; i < wins.depth; i++)
{ {
@@ -943,7 +936,6 @@ int main(int argc, char *argv[])
window_listen(c->window); window_listen(c->window);
client_update_border(c); client_update_border(c);
client_flush_tags(c);
client_place_spot(c, c->spot, 0); client_place_spot(c, c->spot, 0);
// only activate first one // only activate first one

13
xoat.h
View File

@@ -70,10 +70,6 @@ enum {
SPOT1_RIGHT SPOT1_RIGHT
}; };
#define TAG1 1<<0
#define TAG2 1<<1
#define TAG3 1<<2
typedef struct { typedef struct {
short x, y, w, h; short x, y, w, h;
} box; } box;
@@ -96,7 +92,6 @@ typedef struct {
Window transient_for; Window transient_for;
Atom type, states[MAX_NET_WM_STATES+1]; Atom type, states[MAX_NET_WM_STATES+1];
short monitor, spot, visible, manage, input, urgent; short monitor, spot, visible, manage, input, urgent;
unsigned short tags;
char *class; char *class;
} client; } client;
@@ -110,7 +105,7 @@ typedef struct {
short current_spot = 0, current_mon = 0; short current_spot = 0, current_mon = 0;
Window current = None; Window current = None;
stack inplay; stack inplay, snapshot;
static int (*xerror)(Display *, XErrorEvent *); static int (*xerror)(Display *, XErrorEvent *);
@@ -127,7 +122,6 @@ wm_strut struts;
#define GENERAL_ATOMS(X) \ #define GENERAL_ATOMS(X) \
X(XOAT_SPOT),\ X(XOAT_SPOT),\
X(XOAT_TAGS),\
X(XOAT_EXIT),\ X(XOAT_EXIT),\
X(XOAT_RESTART),\ X(XOAT_RESTART),\
X(_MOTIF_WM_HINTS),\ X(_MOTIF_WM_HINTS),\
@@ -179,9 +173,8 @@ enum {
ACTION_FOCUS_MONITOR, ACTION_FOCUS_MONITOR,
ACTION_FULLSCREEN_TOGGLE, ACTION_FULLSCREEN_TOGGLE,
ACTION_ABOVE_TOGGLE, ACTION_ABOVE_TOGGLE,
ACTION_TAG, ACTION_SNAPSHOT,
ACTION_UNTAG, ACTION_ROLLBACK,
ACTION_RAISE_TAG,
ACTIONS ACTIONS
}; };

29
xoat.md
View File

@@ -71,32 +71,11 @@ Shift-Mod4-x
F1 F1
: Launch urxvt : Launch urxvt
Mod4-1 Mod4-s
: Raise windows in tag 1. : Snapshot current window positions and stacking order.
Shift-Mod4-1 Mod4-r
: Place current window in tag 1. : Rollback to snapshot. Windows closed since the snapshot will not be reopened. Newer windows not in the snapshot will be lowered.
Shift-Control-Mod4-1
: Remove current window from tag 1.
Mod4-2
: Raise windows in tag 2.
Shift-Mod4-2
: Place current window in tag 2.
Shift-Control-Mod4-2
: Remove current window from tag 2.
Mod4-3
: Raise windows in tag 3.
Shift-Mod4-3
: Place current window in tag 3.
Shift-Control-Mod4-3
: Remove current window from tag 3.
# OPTIONS # OPTIONS