refactoring
This commit is contained in:
4
proto.h
4
proto.h
@@ -2,6 +2,7 @@ void catch_exit(int sig);
|
|||||||
int execsh(char *cmd);
|
int execsh(char *cmd);
|
||||||
void exec_cmd(char *cmd);
|
void exec_cmd(char *cmd);
|
||||||
int oops(Display *d, XErrorEvent *ee);
|
int oops(Display *d, XErrorEvent *ee);
|
||||||
|
void query_windows();
|
||||||
unsigned int color_name_to_pixel(const char *name);
|
unsigned int color_name_to_pixel(const char *name);
|
||||||
int window_get_prop(Window w, Atom prop, Atom *type, int *items, void *buffer, int bytes);
|
int window_get_prop(Window w, Atom prop, Atom *type, int *items, void *buffer, int bytes);
|
||||||
int window_get_atom_prop(Window w, Atom atom, Atom *list, int count);
|
int window_get_atom_prop(Window w, Atom atom, Atom *list, int count);
|
||||||
@@ -16,14 +17,13 @@ void client_free(client *c);
|
|||||||
void stack_free(stack *s);
|
void stack_free(stack *s);
|
||||||
int client_has_state(client *c, Atom state);
|
int client_has_state(client *c, Atom state);
|
||||||
int client_toggle_state(client *c, Atom state);
|
int client_toggle_state(client *c, Atom state);
|
||||||
void query_visible_windows(stack *s);
|
|
||||||
int window_send_clientmessage(Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask);
|
int window_send_clientmessage(Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask);
|
||||||
int client_send_wm_protocol(client *c, Atom protocol);
|
int client_send_wm_protocol(client *c, Atom protocol);
|
||||||
void client_close(client *c);
|
void client_close(client *c);
|
||||||
void client_place_spot(client *c, int spot, int mon, int force);
|
void client_place_spot(client *c, int spot, int mon, int force);
|
||||||
void client_spot_cycle(client *c);
|
void client_spot_cycle(client *c);
|
||||||
Window spot_focus_top_window(int spot, int mon, Window except);
|
Window spot_focus_top_window(int spot, int mon, Window except);
|
||||||
void client_stack_family(client *c, stack *all, stack *raise);
|
void client_stack_family(client *c, stack *raise);
|
||||||
void client_raise_family(client *c);
|
void client_raise_family(client *c);
|
||||||
void client_set_focus(client *c);
|
void client_set_focus(client *c);
|
||||||
void client_activate(client *c);
|
void client_activate(client *c);
|
||||||
|
|||||||
145
xoat.c
145
xoat.c
@@ -63,6 +63,26 @@ int oops(Display *d, XErrorEvent *ee)
|
|||||||
return xerror(display, ee);
|
return xerror(display, ee);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build windows cache
|
||||||
|
void query_windows()
|
||||||
|
{
|
||||||
|
if (windows.depth) return;
|
||||||
|
unsigned int nwins; int i; Window w1, w2, *wins; client *c;
|
||||||
|
if (XQueryTree(display, root, &w1, &w2, &wins, &nwins) && wins)
|
||||||
|
{
|
||||||
|
for (i = nwins-1; i > -1; i--)
|
||||||
|
{
|
||||||
|
if ((c = window_build_client(wins[i])) && c->visible && windows.depth < STACK)
|
||||||
|
{
|
||||||
|
windows.clients[windows.depth] = c;
|
||||||
|
windows.windows[windows.depth++] = wins[i];
|
||||||
|
}
|
||||||
|
else client_free(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wins) XFree(wins);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int color_name_to_pixel(const char *name)
|
unsigned int color_name_to_pixel(const char *name)
|
||||||
{
|
{
|
||||||
XColor color; Colormap map = DefaultColormap(display, DefaultScreen(display));
|
XColor color; Colormap map = DefaultColormap(display, DefaultScreen(display));
|
||||||
@@ -123,13 +143,11 @@ void window_set_window_prop(Window w, Atom prop, Window *values, int count)
|
|||||||
|
|
||||||
void ewmh_client_list()
|
void ewmh_client_list()
|
||||||
{
|
{
|
||||||
int i; client *c; stack all, wins;
|
int i; client *c; stack wins;
|
||||||
memset(&wins, 0, sizeof(stack));
|
memset(&wins, 0, sizeof(stack));
|
||||||
query_visible_windows(&all);
|
|
||||||
|
|
||||||
for (i = all.depth-1; i > -1; i--)
|
for_windows_rev(i, c) if (c->manage)
|
||||||
{
|
{
|
||||||
if (!((c = all.clients[i]) && c->manage)) continue;
|
|
||||||
wins.clients[wins.depth] = c;
|
wins.clients[wins.depth] = c;
|
||||||
wins.windows[wins.depth++] = c->window;
|
wins.windows[wins.depth++] = c->window;
|
||||||
}
|
}
|
||||||
@@ -234,31 +252,6 @@ int client_toggle_state(client *c, Atom state)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_visible_windows(stack *s)
|
|
||||||
{
|
|
||||||
if (inplay.depth) // cached?
|
|
||||||
{
|
|
||||||
memmove(s, &inplay, sizeof(stack));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memset(s, 0, sizeof(stack));
|
|
||||||
unsigned int nwins; int i; Window w1, w2, *wins; client *c;
|
|
||||||
if (XQueryTree(display, root, &w1, &w2, &wins, &nwins) && wins)
|
|
||||||
{
|
|
||||||
for (i = nwins-1; i > -1; i--)
|
|
||||||
{
|
|
||||||
if ((c = window_build_client(wins[i])) && c->visible && s->depth < STACK)
|
|
||||||
{
|
|
||||||
s->clients[s->depth] = c;
|
|
||||||
s->windows[s->depth++] = wins[i];
|
|
||||||
}
|
|
||||||
else client_free(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (wins) XFree(wins);
|
|
||||||
memmove(&inplay, s, sizeof(stack));
|
|
||||||
}
|
|
||||||
|
|
||||||
int window_send_clientmessage(Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask)
|
int window_send_clientmessage(Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask)
|
||||||
{
|
{
|
||||||
XEvent e; memset(&e, 0, sizeof(XEvent));
|
XEvent e; memset(&e, 0, sizeof(XEvent));
|
||||||
@@ -296,7 +289,7 @@ void client_close(client *c)
|
|||||||
void client_place_spot(client *c, int spot, int mon, int force)
|
void client_place_spot(client *c, int spot, int mon, int force)
|
||||||
{
|
{
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
client *t;
|
int i; client *t;
|
||||||
|
|
||||||
// try to center over our transient parent
|
// try to center over our transient parent
|
||||||
if (!force && c->transient && (t = window_build_client(c->transient)))
|
if (!force && c->transient && (t = window_build_client(c->transient)))
|
||||||
@@ -309,16 +302,11 @@ void client_place_spot(client *c, int spot, int mon, int force)
|
|||||||
// try to center over top-most window in our group
|
// try to center over top-most window in our group
|
||||||
if (!force && c->leader && c->type == atoms[_NET_WM_WINDOW_TYPE_DIALOG])
|
if (!force && c->leader && c->type == atoms[_NET_WM_WINDOW_TYPE_DIALOG])
|
||||||
{
|
{
|
||||||
int i; stack wins;
|
for_windows(i, t) if (t->manage && t->window != c->window && t->leader == c->leader)
|
||||||
query_visible_windows(&wins);
|
|
||||||
for (i = 0; i < wins.depth; i++)
|
|
||||||
{
|
{
|
||||||
if ((t = wins.clients[i]) && t->manage && t->window != c->window && t->leader == c->leader)
|
spot = t->spot;
|
||||||
{
|
mon = t->monitor;
|
||||||
spot = t->spot;
|
break;
|
||||||
mon = t->monitor;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c->spot = spot; c->monitor = mon;
|
c->spot = spot; c->monitor = mon;
|
||||||
@@ -389,11 +377,8 @@ void client_spot_cycle(client *c)
|
|||||||
if (!c) return;
|
if (!c) return;
|
||||||
|
|
||||||
spot_focus_top_window(c->spot, c->monitor, c->window);
|
spot_focus_top_window(c->spot, c->monitor, c->window);
|
||||||
|
|
||||||
stack lower; memset(&lower, 0, sizeof(stack));
|
stack lower; memset(&lower, 0, sizeof(stack));
|
||||||
stack all; query_visible_windows(&all);
|
client_stack_family(c, &lower);
|
||||||
|
|
||||||
client_stack_family(c, &all, &lower);
|
|
||||||
XLowerWindow(display, lower.windows[0]);
|
XLowerWindow(display, lower.windows[0]);
|
||||||
XRestackWindows(display, lower.windows, lower.depth);
|
XRestackWindows(display, lower.windows, lower.depth);
|
||||||
}
|
}
|
||||||
@@ -401,10 +386,9 @@ void client_spot_cycle(client *c)
|
|||||||
Window spot_focus_top_window(int spot, int mon, Window except)
|
Window spot_focus_top_window(int spot, int mon, Window except)
|
||||||
{
|
{
|
||||||
int i; client *c;
|
int i; client *c;
|
||||||
stack wins; query_visible_windows(&wins);
|
for_windows(i, c)
|
||||||
for (i = 0; i < wins.depth; i++)
|
|
||||||
{
|
{
|
||||||
if ((c = wins.clients[i]) && c->window != except && c->manage && c->spot == spot && c->monitor == mon)
|
if (c->window != except && c->manage && c->spot == spot && c->monitor == mon)
|
||||||
{
|
{
|
||||||
client_raise_family(c);
|
client_raise_family(c);
|
||||||
client_set_focus(c);
|
client_set_focus(c);
|
||||||
@@ -414,15 +398,15 @@ Window spot_focus_top_window(int spot, int mon, Window except)
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_stack_family(client *c, stack *all, stack *raise)
|
void client_stack_family(client *c, stack *raise)
|
||||||
{
|
{
|
||||||
int i; client *o, *self = NULL;
|
int i; client *o, *self = NULL;
|
||||||
for (i = 0; i < all->depth; i++)
|
for_windows(i, o)
|
||||||
{
|
{
|
||||||
if ((o = all->clients[i]) && o->manage && o->visible && o->transient == c->window)
|
if (o->manage && o->visible && o->transient == c->window)
|
||||||
client_stack_family(o, all, raise);
|
client_stack_family(o, raise);
|
||||||
else
|
else
|
||||||
if (o && o->visible && o->window == c->window)
|
if (o->visible && o->window == c->window)
|
||||||
self = o;
|
self = o;
|
||||||
}
|
}
|
||||||
if (self)
|
if (self)
|
||||||
@@ -436,28 +420,22 @@ void client_raise_family(client *c)
|
|||||||
{
|
{
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
|
|
||||||
int i; client *o; stack raise, all, family;
|
int i; client *o; stack raise, family;
|
||||||
memset(&raise, 0, sizeof(stack));
|
memset(&raise, 0, sizeof(stack));
|
||||||
memset(&family, 0, sizeof(stack));
|
memset(&family, 0, sizeof(stack));
|
||||||
query_visible_windows(&all);
|
|
||||||
|
|
||||||
for (i = 0; i < all.depth; i++)
|
for_windows(i, o) if (o->type == atoms[_NET_WM_WINDOW_TYPE_DOCK])
|
||||||
if ((o = all.clients[i]) && o->type == atoms[_NET_WM_WINDOW_TYPE_DOCK])
|
client_stack_family(o, &raise);
|
||||||
client_stack_family(o, &all, &raise);
|
|
||||||
|
|
||||||
// above only counts for fullscreen windows
|
// above only counts for fullscreen windows
|
||||||
if (client_has_state(c, atoms[_NET_WM_STATE_FULLSCREEN]))
|
if (client_has_state(c, atoms[_NET_WM_STATE_FULLSCREEN]))
|
||||||
for (i = 0; i < all.depth; i++)
|
for_windows(i, o) if (client_has_state(o, atoms[_NET_WM_STATE_ABOVE]))
|
||||||
if ((o = all.clients[i]) && client_has_state(o, atoms[_NET_WM_STATE_ABOVE]))
|
client_stack_family(o, &raise);
|
||||||
client_stack_family(o, &all, &raise);
|
|
||||||
|
|
||||||
while (c->transient)
|
while (c->transient && (o = window_build_client(c->transient)))
|
||||||
{
|
c = family.clients[family.depth++] = o;
|
||||||
client *t = window_build_client(c->transient);
|
|
||||||
if (t) c = family.clients[family.depth++] = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
client_stack_family(c, &all, &raise);
|
client_stack_family(c, &raise);
|
||||||
XRaiseWindow(display, raise.windows[0]);
|
XRaiseWindow(display, raise.windows[0]);
|
||||||
XRestackWindows(display, raise.windows, raise.depth);
|
XRestackWindows(display, raise.windows, raise.depth);
|
||||||
stack_free(&family);
|
stack_free(&family);
|
||||||
@@ -540,11 +518,9 @@ 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)
|
||||||
{
|
{
|
||||||
int i; client *c; char *class = data;
|
int i; client *c; char *class = data;
|
||||||
stack all; query_visible_windows(&all);
|
|
||||||
|
|
||||||
for (i = 0; i < all.depth; i++)
|
for_windows(i, c) if (c->manage && !strcasecmp(c->class, class))
|
||||||
if ((c = all.clients[i]) && c->manage && !strcasecmp(c->class, class))
|
{ client_activate(c); return; }
|
||||||
{ client_activate(c); return; }
|
|
||||||
|
|
||||||
exec_cmd(class);
|
exec_cmd(class);
|
||||||
}
|
}
|
||||||
@@ -593,16 +569,13 @@ void action_above(void *data, int num, client *cli)
|
|||||||
|
|
||||||
void action_snapshot(void *data, int num, client *cli)
|
void action_snapshot(void *data, int num, client *cli)
|
||||||
{
|
{
|
||||||
int i; client *c; stack wins;
|
int i; client *c;
|
||||||
stack_free(&snapshot);
|
stack_free(&snapshot);
|
||||||
query_visible_windows(&wins);
|
|
||||||
for (i = 0; i < wins.depth; i++)
|
for_windows(i, c) if (c->manage)
|
||||||
{
|
{
|
||||||
if ((c = wins.clients[i]) && c->manage)
|
snapshot.clients[snapshot.depth] = window_build_client(c->window);
|
||||||
{
|
snapshot.windows[snapshot.depth++] = c->window;
|
||||||
snapshot.clients[snapshot.depth] = window_build_client(c->window);
|
|
||||||
snapshot.windows[snapshot.depth++] = c->window;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,7 +793,7 @@ handler handlers[LASTEvent] = {
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i, j; client *c; XEvent ev; stack wins;
|
int i, j; client *c; XEvent ev;
|
||||||
|
|
||||||
if (!(display = XOpenDisplay(0))) return 1;
|
if (!(display = XOpenDisplay(0))) return 1;
|
||||||
|
|
||||||
@@ -843,16 +816,12 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// default non-multi-head setup
|
// default non-multi-head setup
|
||||||
memset(monitors, 0, sizeof(monitors));
|
|
||||||
monitors[0].w = WidthOfScreen(DefaultScreenOfDisplay(display));
|
monitors[0].w = WidthOfScreen(DefaultScreenOfDisplay(display));
|
||||||
monitors[0].h = HeightOfScreen(DefaultScreenOfDisplay(display));
|
monitors[0].h = HeightOfScreen(DefaultScreenOfDisplay(display));
|
||||||
|
|
||||||
// detect panel struts
|
// detect panel struts
|
||||||
query_visible_windows(&wins);
|
for_windows(i, c)
|
||||||
for (i = 0; i < wins.depth; i++)
|
|
||||||
{
|
{
|
||||||
if (!(c = wins.clients[i])) continue;
|
|
||||||
|
|
||||||
wm_strut strut; memset(&strut, 0, sizeof(wm_strut));
|
wm_strut strut; memset(&strut, 0, sizeof(wm_strut));
|
||||||
if (window_get_cardinal_prop(c->window, atoms[_NET_WM_STRUT_PARTIAL], (unsigned long*)&strut, 12)
|
if (window_get_cardinal_prop(c->window, atoms[_NET_WM_STRUT_PARTIAL], (unsigned long*)&strut, 12)
|
||||||
|| window_get_cardinal_prop(c->window, atoms[_NET_WM_STRUT], (unsigned long*)&strut, 4))
|
|| window_get_cardinal_prop(c->window, atoms[_NET_WM_STRUT], (unsigned long*)&strut, 4))
|
||||||
@@ -863,7 +832,6 @@ int main(int argc, char *argv[])
|
|||||||
struts.bottom = MIN(MAX_STRUT, MAX(struts.bottom, strut.bottom));
|
struts.bottom = MIN(MAX_STRUT, MAX(struts.bottom, strut.bottom));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stack_free(&inplay);
|
|
||||||
|
|
||||||
// support multi-head.
|
// support multi-head.
|
||||||
XineramaScreenInfo *info;
|
XineramaScreenInfo *info;
|
||||||
@@ -948,12 +916,9 @@ 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));
|
stack_free(&windows);
|
||||||
query_visible_windows(&wins);
|
for_windows(i, c) if (c->manage)
|
||||||
for (i = 0; i < wins.depth; i++)
|
|
||||||
{
|
{
|
||||||
if (!(c = wins.clients[i]) || !c->manage) continue;
|
|
||||||
|
|
||||||
window_listen(c->window);
|
window_listen(c->window);
|
||||||
client_update_border(c);
|
client_update_border(c);
|
||||||
client_place_spot(c, c->spot, c->monitor, 0);
|
client_place_spot(c, c->spot, c->monitor, 0);
|
||||||
@@ -965,7 +930,7 @@ int main(int argc, char *argv[])
|
|||||||
// main event loop
|
// main event loop
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
stack_free(&inplay);
|
stack_free(&windows);
|
||||||
XNextEvent(display, &ev);
|
XNextEvent(display, &ev);
|
||||||
if (handlers[ev.type])
|
if (handlers[ev.type])
|
||||||
handlers[ev.type](&ev);
|
handlers[ev.type](&ev);
|
||||||
|
|||||||
16
xoat.h
16
xoat.h
@@ -110,7 +110,15 @@ typedef struct {
|
|||||||
|
|
||||||
short current_spot = 0, current_mon = 0;
|
short current_spot = 0, current_mon = 0;
|
||||||
Window current = None;
|
Window current = None;
|
||||||
stack inplay, snapshot;
|
stack windows, snapshot;
|
||||||
|
|
||||||
|
#define for_windows(i,c)\
|
||||||
|
for ((i) = 0, query_windows(); (i) < windows.depth; (i)++)\
|
||||||
|
if (((c) = windows.clients[(i)]))
|
||||||
|
|
||||||
|
#define for_windows_rev(i,c)\
|
||||||
|
for ((i) = windows.depth-1, query_windows(); (i) > -1; (i)--)\
|
||||||
|
if (((c) = windows.clients[(i)]))
|
||||||
|
|
||||||
static int (*xerror)(Display *, XErrorEvent *);
|
static int (*xerror)(Display *, XErrorEvent *);
|
||||||
|
|
||||||
@@ -190,3 +198,9 @@ typedef struct {
|
|||||||
void *data;
|
void *data;
|
||||||
int num;
|
int num;
|
||||||
} binding;
|
} binding;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user