From 77d4ee70253f298405541132713288b09bfcd4d1 Mon Sep 17 00:00:00 2001 From: seanpringle Date: Thu, 6 Sep 2012 15:57:53 +1000 Subject: [PATCH] pass focused client to action callbacks --- proto.h | 30 +++++----- xoat.c | 179 +++++++++++++++++++++++++------------------------------- xoat.h | 2 +- 3 files changed, 96 insertions(+), 115 deletions(-) diff --git a/proto.h b/proto.h index b9c8e63..224aad0 100644 --- a/proto.h +++ b/proto.h @@ -1,5 +1,6 @@ void catch_exit(int sig); int execsh(char *cmd); +void exec_cmd(char *cmd); int oops(Display *d, XErrorEvent *ee); 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); @@ -11,6 +12,7 @@ void window_set_window_prop(Window w, Atom prop, Window *values, int count); void ewmh_client_list(); client* window_build_client(Window win); void client_free(client *c); +void stack_free(stack *s); int client_has_state(client *c, Atom state); int client_toggle_state(client *c, Atom state); void query_visible_windows(stack *s); @@ -28,20 +30,20 @@ void client_set_focus(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); -void action_focus(void *data, int num); -void action_close(void *data, int num); -void action_cycle(void *data, int num); -void action_other(void *data, int num); -void action_command(void *data, int num); -void action_find_or_start(void *data, int num); -void action_move_monitor(void *data, int num); -void action_focus_monitor(void *data, int num); -void action_raise_tag(void *data, int tag); -void action_fullscreen(void *data, int num); -void action_above(void *data, int num); -void action_tag(void *data, int num); -void action_untag(void *data, int num); +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); +void action_cycle(void *data, int num, client *cli); +void action_other(void *data, int num, client *cli); +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 create_notify(XCreateWindowEvent *e); void configure_request(XConfigureRequestEvent *e); void map_request(XMapEvent *e); diff --git a/xoat.c b/xoat.c index 544796c..86a34b1 100644 --- a/xoat.c +++ b/xoat.c @@ -39,19 +39,17 @@ int execsh(char *cmd) return execlp("/bin/sh", "sh", "-c", cmd, NULL); } -pid_t exec_cmd(char *cmd) +void exec_cmd(char *cmd) { - if (!cmd || !cmd[0]) return -1; + if (!cmd || !cmd[0]) return; warnx("exec_cmd %s", cmd); + signal(SIGCHLD, catch_exit); - pid_t pid = fork(); - if (!pid) - { - setsid(); - execsh(cmd); - exit(EXIT_FAILURE); - } - return pid; + if (fork()) return; + + setsid(); + execsh(cmd); + exit(EXIT_FAILURE); } // X error handler @@ -215,6 +213,12 @@ void client_free(client *c) free(c); } +void stack_free(stack *s) +{ + while (s->depth) + client_free(s->clients[--s->depth]); +} + int client_has_state(client *c, Atom state) { int i; @@ -312,13 +316,11 @@ void client_position_xywh(client *c, int x, int y, int w, int h) } w -= BORDER*2; h -= BORDER*2; - int basew = 0, baseh = 0, sw = w, sh = h; + int sw = w, sh = h; + + int basew = c->size.flags & PBaseSize ? c->size.base_width : 0; + int baseh = c->size.flags & PBaseSize ? c->size.base_height: 0; - if (c->size.flags & PBaseSize) - { - basew = c->size.base_width; - baseh = c->size.base_height; - } if (c->size.flags & PMinSize) { w = MAX(w, c->size.min_width); @@ -481,21 +483,19 @@ void client_raise_family(client *c) client_stack_family(c, &all, &raise); XRaiseWindow(display, raise.windows[0]); XRestackWindows(display, raise.windows, raise.depth); - - while (family.depth) - client_free(family.clients[--family.depth]); + stack_free(&family); } void client_set_focus(client *c) { if (!c || !c->visible) return; - client *o; - Window old = current; - current = c->window; + Window old = current; + current = c->window; current_spot = c->spot; current_mon = c->monitor; + client *o; if (old && (o = window_build_client(old))) { client_update_border(o); @@ -532,50 +532,41 @@ void client_flush_tags(client *c) // ------- key actions ------- -void action_move(void *data, int num) +void action_move(void *data, int num, client *cli) { - client *c = window_build_client(current); - if (c) - { - client_raise_family(c); - client_place_spot(c, num, 1); - client_free(c); - } + if (!cli) return; + + client_raise_family(cli); + client_place_spot(cli, num, 1); } -void action_focus(void *data, int num) +void action_focus(void *data, int num, client *cli) { spot_focus_top_window(num, current_mon, None); } -void action_close(void *data, int num) +void action_close(void *data, int num, client *cli) { - client *c = window_build_client(current); - if (c) client_close(c); - client_free(c); + if (cli) client_close(cli); } -void action_cycle(void *data, int num) +void action_cycle(void *data, int num, client *cli) { - client *c = window_build_client(current); - if (c) client_spot_cycle(c); - client_free(c); + if (cli) client_spot_cycle(cli); } -void action_other(void *data, int num) +void action_other(void *data, int num, client *cli) { - client *c = window_build_client(current); - if (c) spot_focus_top_window(c->spot, c->monitor, c->window); - client_free(c); + if (cli) spot_focus_top_window(cli->spot, cli->monitor, cli->window); } -void action_command(void *data, int num) +void action_command(void *data, int num, client *cli) { exec_cmd(data); } // real simple switcher/launcher -void action_find_or_start(void *data, int num) +void action_find_or_start(void *data, int num, client *cli) { int i; client *c; char *class = data; stack all; query_visible_windows(&all); @@ -592,25 +583,23 @@ void action_find_or_start(void *data, int num) exec_cmd(class); } -void action_move_monitor(void *data, int num) +void action_move_monitor(void *data, int num, client *cli) { - client *c = window_build_client(current); - if (!c) return; + if (!cli) return; - client_raise_family(c); - c->monitor = MAX(0, MIN(current_mon+num, nmonitors-1)); - client_place_spot(c, c->spot, 1); - client_free(c); + client_raise_family(cli); + cli->monitor = MAX(0, MIN(current_mon+num, nmonitors-1)); + client_place_spot(cli, cli->spot, 1); } -void action_focus_monitor(void *data, int num) +void action_focus_monitor(void *data, int num, client *cli) { int i, mon = MAX(0, MIN(current_mon+num, nmonitors-1)); if (spot_focus_top_window(current_spot, mon, None)) return; for (i = SPOT1; i <= SPOT3 && !spot_focus_top_window(i, mon, None); i++); } -void action_raise_tag(void *data, int tag) +void action_raise_tag(void *data, int tag, client *cli) { int i; client *c = NULL, *t = NULL; stack all; query_visible_windows(&all); @@ -629,57 +618,49 @@ void action_raise_tag(void *data, int tag) window_set_cardinal_prop(root, atoms[_NET_CURRENT_DESKTOP], &desktop, 1); } -void action_fullscreen(void *data, int num) +void action_fullscreen(void *data, int num, client *cli) { - client *c = window_build_client(current); - if (!c) return; + if (!cli) return; - unsigned long spot = c->spot; - client_raise_family(c); + unsigned long spot = cli->spot; + client_raise_family(cli); - if (client_toggle_state(c, atoms[_NET_WM_STATE_FULLSCREEN])) + if (client_toggle_state(cli, atoms[_NET_WM_STATE_FULLSCREEN])) { - window_set_cardinal_prop(c->window, atoms[XOAT_SPOT], &spot, 1); - c->spot = SPOT1; + window_set_cardinal_prop(cli->window, atoms[XOAT_SPOT], &spot, 1); + cli->spot = SPOT1; } else - if (window_get_cardinal_prop(c->window, atoms[XOAT_SPOT], &spot, 1)) - c->spot = spot; + if (window_get_cardinal_prop(cli->window, atoms[XOAT_SPOT], &spot, 1)) + cli->spot = spot; - client_update_border(c); - client_place_spot(c, c->spot, 1); - client_free(c); + client_update_border(cli); + client_place_spot(cli, cli->spot, 1); } -void action_above(void *data, int num) +void action_above(void *data, int num, client *cli) { - client *c = window_build_client(current); - if (!c) return; + if (!cli) return; - client_toggle_state(c, atoms[_NET_WM_STATE_ABOVE]); - client_update_border(c); - client_raise_family(c); - client_free(c); + client_toggle_state(cli, atoms[_NET_WM_STATE_ABOVE]); + client_update_border(cli); + client_raise_family(cli); } -void action_tag(void *data, int num) +void action_tag(void *data, int num, client *cli) { - client *c = window_build_client(current); - if (!c) return; + if (!cli) return; - c->tags |= (unsigned int)num; - client_flush_tags(c); - client_free(c); + cli->tags |= (unsigned int)num; + client_flush_tags(cli); } -void action_untag(void *data, int num) +void action_untag(void *data, int num, client *cli) { - client *c = window_build_client(current); - if (!c) return; + if (!cli) return; - c->tags &= ~((unsigned int)num); - client_flush_tags(c); - client_free(c); + cli->tags &= ~((unsigned int)num); + client_flush_tags(cli); } // key actions @@ -822,7 +803,11 @@ void key_press(XKeyEvent *e) } } if (actions[act]) - actions[act](data, num); + { + client *cli = window_build_client(current); + actions[act](data, num, cli); + client_free(cli); + } } void button_press(XButtonEvent *e) @@ -920,7 +905,6 @@ int main(int argc, char *argv[]) // detect panel struts query_visible_windows(&wins); - inplay.depth = 0; for (i = 0; i < wins.depth; i++) { if (!(c = wins.clients[i])) continue; @@ -935,8 +919,9 @@ int main(int argc, char *argv[]) struts.bottom = MAX(struts.bottom, strut.bottom); warnx("struts %ld %ld %ld %ld 0x%08lx %s", strut.left, strut.left, strut.left, strut.left, (long)c->window, c->class); } - client_free(c); } + stack_free(&inplay); + // support multi-head. if (XineramaIsActive(display)) { @@ -1001,12 +986,9 @@ int main(int argc, char *argv[]) if (keys[i].mod == AnyModifier) continue; - XGrabKey(display, XKeysymToKeycode(display, keys[i].key), keys[i].mod|LockMask, root, - True, GrabModeAsync, GrabModeAsync); - XGrabKey(display, XKeysymToKeycode(display, keys[i].key), keys[i].mod|NumlockMask, root, - True, GrabModeAsync, GrabModeAsync); - XGrabKey(display, XKeysymToKeycode(display, keys[i].key), keys[i].mod|LockMask|NumlockMask, root, - True, GrabModeAsync, GrabModeAsync); + XGrabKey(display, XKeysymToKeycode(display, keys[i].key), keys[i].mod|LockMask, root, True, GrabModeAsync, GrabModeAsync); + XGrabKey(display, XKeysymToKeycode(display, keys[i].key), keys[i].mod|NumlockMask, root, True, GrabModeAsync, GrabModeAsync); + XGrabKey(display, XKeysymToKeycode(display, keys[i].key), keys[i].mod|LockMask|NumlockMask, root, True, GrabModeAsync, GrabModeAsync); } // we grab buttons to do click-to-focus. all clicks get passed through to apps. @@ -1015,7 +997,6 @@ int main(int argc, char *argv[]) // setup existing managable windows query_visible_windows(&wins); - inplay.depth = 0; for (i = 0; i < wins.depth; i++) { if (!(c = wins.clients[i]) || !c->manage) continue; @@ -1033,14 +1014,12 @@ int main(int argc, char *argv[]) client_set_focus(c); } } - client_free(c); } + // main event loop for (;;) { - while (inplay.depth) - client_free(inplay.clients[--inplay.depth]); - + stack_free(&inplay); XEvent ev; XNextEvent(display, &ev); switch (ev.type) diff --git a/xoat.h b/xoat.h index db6799e..808684d 100644 --- a/xoat.h +++ b/xoat.h @@ -166,7 +166,7 @@ enum { ACTIONS }; -typedef void (*action)(void*, int); +typedef void (*action)(void*, int, client*); typedef struct { unsigned int mod;