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