refactoring

This commit is contained in:
seanpringle
2012-09-11 15:05:47 +10:00
parent 91cac07077
commit 9507a258c9
3 changed files with 72 additions and 93 deletions

View File

@@ -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);

133
xoat.c
View File

@@ -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,18 +302,13 @@ 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; spot = t->spot;
mon = t->monitor; mon = t->monitor;
break; break;
} }
} }
}
c->spot = spot; c->monitor = mon; c->spot = spot; c->monitor = mon;
monitor *m = &monitors[c->monitor]; monitor *m = &monitors[c->monitor];
@@ -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,10 +518,8 @@ 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,17 +569,14 @@ 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.clients[snapshot.depth] = window_build_client(c->window);
snapshot.windows[snapshot.depth++] = c->window; snapshot.windows[snapshot.depth++] = c->window;
} }
}
} }
void action_rollback(void *data, int num, client *cli) void action_rollback(void *data, int num, client *cli)
@@ -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
View File

@@ -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;