replace tags with snapshot mechanism
This commit is contained in:
15
config.h
15
config.h
@@ -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" },
|
||||
|
||||
6
proto.h
6
proto.h
@@ -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
45
xoat.1
@@ -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
82
xoat.c
@@ -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
13
xoat.h
@@ -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
29
xoat.md
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user