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
{ .mod = Mod4Mask, .key = XK_x, .act = ACTION_COMMAND, .data = "dmenu_run" },
// Raise tag groups
{ .mod = Mod4Mask, .key = XK_1, .act = ACTION_RAISE_TAG, .num = TAG1 },
{ .mod = Mod4Mask, .key = XK_2, .act = ACTION_RAISE_TAG, .num = TAG2 },
{ .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 },
// 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).
{ .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 window_listen(Window win);
void client_update_border(client *c);
void client_flush_tags(client *c);
void action_move(void *data, int num, client *cli);
void action_focus(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_move_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_above(void *data, int num, client *cli);
void action_tag(void *data, int num, client *cli);
void action_untag(void *data, int num, client *cli);
void action_snapshot(void *data, int num, client *cli);
void action_rollback(void *data, int num, client *cli);
void create_notify(XEvent *e);
void configure_request(XEvent *ev);
void configure_notify(XEvent *e);

45
xoat.1
View File

@@ -102,48 +102,15 @@ Launch urxvt
.RS
.RE
.TP
.B Mod4-1
Raise windows in tag 1.
.B Mod4-s
Snapshot current window positions and stacking order.
.RS
.RE
.TP
.B Shift-Mod4-1
Place current window in tag 1.
.RS
.RE
.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.
.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

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);
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);
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);
}
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 -------
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++);
}
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)
{
if (!cli) return;
@@ -597,18 +565,44 @@ void action_above(void *data, int num, client *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;
cli->tags |= (unsigned int)num;
client_flush_tags(cli);
int i; client *c; stack wins;
stack_free(&snapshot);
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;
cli->tags &= ~((unsigned int)num);
client_flush_tags(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->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
@@ -625,9 +619,8 @@ action actions[ACTIONS] = {
[ACTION_FOCUS_MONITOR] = action_focus_monitor,
[ACTION_FULLSCREEN_TOGGLE] = action_fullscreen,
[ACTION_ABOVE_TOGGLE] = action_above,
[ACTION_TAG] = action_tag,
[ACTION_UNTAG] = action_untag,
[ACTION_RAISE_TAG] = action_raise_tag,
[ACTION_SNAPSHOT] = action_snapshot,
[ACTION_ROLLBACK] = action_rollback,
};
// ------- event handlers --------
@@ -690,7 +683,6 @@ void map_request(XEvent *e)
client_place_spot(c, spot, 0);
client_update_border(c);
client_flush_tags(c);
}
if (c) XMapWindow(display, c->window);
client_free(c);
@@ -936,6 +928,7 @@ int main(int argc, char *argv[])
XGrabButton(display, Button3, AnyModifier, root, True, ButtonPressMask, GrabModeSync, GrabModeSync, None, None);
// setup existing managable windows
memset(&snapshot, 0, sizeof(stack));
query_visible_windows(&wins);
for (i = 0; i < wins.depth; i++)
{
@@ -943,7 +936,6 @@ int main(int argc, char *argv[])
window_listen(c->window);
client_update_border(c);
client_flush_tags(c);
client_place_spot(c, c->spot, 0);
// only activate first one

13
xoat.h
View File

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

29
xoat.md
View File

@@ -71,32 +71,11 @@ Shift-Mod4-x
F1
: Launch urxvt
Mod4-1
: Raise windows in tag 1.
Mod4-s
: Snapshot current window positions and stacking order.
Shift-Mod4-1
: Place current window in tag 1.
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.
Mod4-r
: Rollback to snapshot. Windows closed since the snapshot will not be reopened. Newer windows not in the snapshot will be lowered.
# OPTIONS