all repos — openbox @ 1a348576400b26dad3a58a81415c4c833fb4915c

openbox fork - make it a bit more like ryudo

Make the relative desktop switching actions interactive

The desktop popup can now be shown "permanently" in which case it stays until
you tell it to hide.
Dana Jansens danakj@orodu.net
commit

1a348576400b26dad3a58a81415c4c833fb4915c

parent

1b392b5fbe85c55cda2b0fc9d1e10cbe56216185

M openbox/actions.copenbox/actions.c

@@ -304,9 +304,12 @@ /* cancel the old one */

if (interactive_act) actions_interactive_cancel_act(); if (act->i_pre) - act->i_pre(act->options); + if (!act->i_pre(state, act->options)) + act->i_input = NULL; /* remove the interactivity */ + } + /* check again cuz it might have been cancelled */ + if (actions_act_is_interactive(act)) ok = actions_interactive_begin_act(act, state); - } } /* fire the action's run function with this data */
M openbox/actions.hopenbox/actions.h

@@ -37,7 +37,9 @@ gpointer options);

typedef gpointer (*ObActionsDataSetupFunc)(xmlNodePtr node); /* functions for interactive actions */ -typedef void (*ObActionsIPreFunc)(gpointer options); +/* return TRUE if the action is going to be interactive, or false to change + your mind and make it not */ +typedef gboolean (*ObActionsIPreFunc)(guint initial_state, gpointer options); typedef void (*ObActionsIPostFunc)(gpointer options); typedef gboolean (*ObActionsIInputFunc)(guint initial_state, XEvent *e,
M openbox/actions/cyclewindows.copenbox/actions/cyclewindows.c

@@ -27,17 +27,17 @@ static gpointer setup_func(xmlNodePtr node,

ObActionsIPreFunc *pre, ObActionsIInputFunc *in, ObActionsICancelFunc *c, - ObActionsIPreFunc *post); + ObActionsIPostFunc *post); static gpointer setup_forward_func(xmlNodePtr node, ObActionsIPreFunc *pre, ObActionsIInputFunc *in, ObActionsICancelFunc *c, - ObActionsIPreFunc *post); + ObActionsIPostFunc *post); static gpointer setup_backward_func(xmlNodePtr node, ObActionsIPreFunc *pre, ObActionsIInputFunc *in, ObActionsICancelFunc *c, - ObActionsIPreFunc *post); + ObActionsIPostFunc *post); static void free_func(gpointer options); static gboolean run_func(ObActionsData *data, gpointer options); static gboolean i_input_func(guint initial_state,

@@ -58,7 +58,7 @@ static gpointer setup_func(xmlNodePtr node,

ObActionsIPreFunc *pre, ObActionsIInputFunc *input, ObActionsICancelFunc *cancel, - ObActionsIPreFunc *post) + ObActionsIPostFunc *post) { xmlNodePtr n; Options *o;

@@ -115,7 +115,7 @@ static gpointer setup_forward_func(xmlNodePtr node,

ObActionsIPreFunc *pre, ObActionsIInputFunc *input, ObActionsICancelFunc *cancel, - ObActionsIPreFunc *post) + ObActionsIPostFunc *post) { Options *o = setup_func(node, pre, input, cancel, post); o->forward = TRUE;

@@ -126,7 +126,7 @@ static gpointer setup_backward_func(xmlNodePtr node,

ObActionsIPreFunc *pre, ObActionsIInputFunc *input, ObActionsICancelFunc *cancel, - ObActionsIPreFunc *post) + ObActionsIPostFunc *post) { Options *o = setup_func(node, pre, input, cancel, post); o->forward = FALSE;
M openbox/actions/desktop.copenbox/actions/desktop.c

@@ -1,6 +1,7 @@

#include "openbox/actions.h" #include "openbox/screen.h" #include "openbox/client.h" +#include "openbox/openbox.h" #include <glib.h> typedef enum {

@@ -24,59 +25,130 @@ } rel;

} u; gboolean send; gboolean follow; + gboolean interactive; } Options; -static gpointer setup_go_func(xmlNodePtr node); -static gpointer setup_send_func(xmlNodePtr node); +static gpointer setup_go_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); +static gpointer setup_send_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); static gboolean run_func(ObActionsData *data, gpointer options); + +static gboolean i_pre_func(guint state, gpointer options); +static gboolean i_input_func(guint initial_state, + XEvent *e, + gpointer options, + gboolean *used); +static void i_post_func(gpointer options); + /* 3.4-compatibility */ static gpointer setup_go_last_func(xmlNodePtr node); static gpointer setup_send_last_func(xmlNodePtr node); static gpointer setup_go_abs_func(xmlNodePtr node); static gpointer setup_send_abs_func(xmlNodePtr node); -static gpointer setup_go_next_func(xmlNodePtr node); -static gpointer setup_send_next_func(xmlNodePtr node); -static gpointer setup_go_prev_func(xmlNodePtr node); -static gpointer setup_send_prev_func(xmlNodePtr node); -static gpointer setup_go_left_func(xmlNodePtr node); -static gpointer setup_send_left_func(xmlNodePtr node); -static gpointer setup_go_right_func(xmlNodePtr node); -static gpointer setup_send_right_func(xmlNodePtr node); -static gpointer setup_go_up_func(xmlNodePtr node); -static gpointer setup_send_up_func(xmlNodePtr node); -static gpointer setup_go_down_func(xmlNodePtr node); -static gpointer setup_send_down_func(xmlNodePtr node); - +static gpointer setup_go_next_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); +static gpointer setup_send_next_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); +static gpointer setup_go_prev_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); +static gpointer setup_send_prev_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); +static gpointer setup_go_left_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); +static gpointer setup_send_left_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); +static gpointer setup_go_right_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); +static gpointer setup_send_right_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); +static gpointer setup_go_up_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); +static gpointer setup_send_up_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); +static gpointer setup_go_down_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); +static gpointer setup_send_down_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post); + void action_desktop_startup(void) { - actions_register("GoToDesktop", setup_go_func, g_free, run_func); - actions_register("SendToDesktop", setup_send_func, g_free, run_func); + actions_register_i("GoToDesktop", setup_go_func, g_free, run_func); + actions_register_i("SendToDesktop", setup_send_func, g_free, run_func); /* 3.4-compatibility */ actions_register("DesktopLast", setup_go_last_func, g_free, run_func); actions_register("SendToDesktopLast", setup_send_last_func, g_free, run_func); actions_register("Desktop", setup_go_abs_func, g_free, run_func); actions_register("SendToDesktop", setup_send_abs_func, g_free, run_func); - actions_register("DesktopNext", setup_go_next_func, g_free, run_func); - actions_register("SendToDesktopNext", setup_send_next_func, - g_free, run_func); - actions_register("DesktopPrevious", setup_go_prev_func, g_free, run_func); - actions_register("SendToDesktopPrevious", setup_send_prev_func, - g_free, run_func); - actions_register("DesktopLeft", setup_go_left_func, g_free, run_func); - actions_register("SendToDesktopLeft", setup_send_left_func, - g_free, run_func); - actions_register("DesktopRight", setup_go_right_func, g_free, run_func); - actions_register("SendToDesktopRight", setup_send_right_func, - g_free, run_func); - actions_register("DesktopUp", setup_go_up_func, g_free, run_func); - actions_register("SendToDesktopUp", setup_send_up_func, g_free, run_func); - actions_register("DesktopDown", setup_go_down_func, g_free, run_func); - actions_register("SendToDesktopDown", setup_send_down_func, - g_free, run_func); + actions_register_i("DesktopNext", setup_go_next_func, g_free, run_func); + actions_register_i("SendToDesktopNext", setup_send_next_func, + g_free, run_func); + actions_register_i("DesktopPrevious", setup_go_prev_func, + g_free, run_func); + actions_register_i("SendToDesktopPrevious", setup_send_prev_func, + g_free, run_func); + actions_register_i("DesktopLeft", setup_go_left_func, g_free, run_func); + actions_register_i("SendToDesktopLeft", setup_send_left_func, + g_free, run_func); + actions_register_i("DesktopRight", setup_go_right_func, g_free, run_func); + actions_register_i("SendToDesktopRight", setup_send_right_func, + g_free, run_func); + actions_register_i("DesktopUp", setup_go_up_func, g_free, run_func); + actions_register_i("SendToDesktopUp", setup_send_up_func, + g_free, run_func); + actions_register_i("DesktopDown", setup_go_down_func, g_free, run_func); + actions_register_i("SendToDesktopDown", setup_send_down_func, + g_free, run_func); } -static gpointer setup_go_func(xmlNodePtr node) +static gpointer setup_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { xmlNodePtr n; Options *o;

@@ -135,18 +207,49 @@

return o; } -static gpointer setup_send_func(xmlNodePtr node) + +static gpointer setup_go_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) +{ + Options *o; + + o = setup_func(node, pre, input, cancel, post); + if (o->type == RELATIVE) { + o->interactive = TRUE; + *pre = i_pre_func; + *input = i_input_func; + *post = i_post_func; + } + + return o; +} + +static gpointer setup_send_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { xmlNodePtr n; Options *o; - o = setup_go_func(node); + o = setup_func(node, pre, input, cancel, post); o->send = TRUE; o->follow = TRUE; if ((n = obt_parse_find_node(node, "follow"))) o->follow = obt_parse_node_bool(n); + if (o->type == RELATIVE && o->follow) { + o->interactive = TRUE; + *pre = i_pre_func; + *input = i_input_func; + *post = i_post_func; + } + return o; }

@@ -188,7 +291,54 @@ }

actions_client_move(data, FALSE); } - return FALSE; + + return o->interactive; +} + +static gboolean i_input_func(guint initial_state, + XEvent *e, + gpointer options, + gboolean *used) +{ + if (e->type == KeyPress) { + /* Escape cancels no matter what */ + if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) { + return FALSE; + } + + /* There were no modifiers and they pressed enter */ + else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) && + !initial_state) + { + return FALSE; + } + } + /* They released the modifiers */ + else if (e->type == KeyRelease && initial_state && + (e->xkey.state & initial_state) == 0) + { + return FALSE; + } + + return TRUE; +} + +static gboolean i_pre_func(guint initial_state, gpointer options) +{ + if (!initial_state) { + Options *o = options; + o->interactive = FALSE; + return FALSE; + } + else { + screen_show_desktop_popup(screen_desktop, TRUE); + return TRUE; + } +} + +static void i_post_func(gpointer options) +{ + screen_hide_desktop_popup(); } /* 3.4-compatilibity */

@@ -241,7 +391,11 @@ o->u.abs.desktop = screen_desktop;

return o; } -static void setup_rel(Options *o, xmlNodePtr node, gboolean lin, ObDirection dir) +static void setup_rel(Options *o, xmlNodePtr node, gboolean lin, + ObDirection dir, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsIPostFunc *post) { xmlNodePtr n;

@@ -252,88 +406,149 @@ o->u.rel.wrap = TRUE;

if ((n = obt_parse_find_node(node, "wrap"))) o->u.rel.wrap = obt_parse_node_bool(n); + + if (input) { + o->interactive = TRUE; + *pre = i_pre_func; + *input = i_input_func; + *post = i_post_func; + } } -static gpointer setup_go_next_func(xmlNodePtr node) +static gpointer setup_go_next_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { Options *o = g_new0(Options, 1); - setup_rel(o, node, TRUE, OB_DIRECTION_EAST); + setup_rel(o, node, TRUE, OB_DIRECTION_EAST, pre, input, post); return o; } -static gpointer setup_send_next_func(xmlNodePtr node) +static gpointer setup_send_next_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { Options *o = setup_follow(node); - setup_rel(o, node, TRUE, OB_DIRECTION_EAST); + setup_rel(o, node, TRUE, OB_DIRECTION_EAST, + pre, (o->follow ? input : NULL), post); return o; } -static gpointer setup_go_prev_func(xmlNodePtr node) +static gpointer setup_go_prev_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { Options *o = g_new0(Options, 1); - setup_rel(o, node, TRUE, OB_DIRECTION_WEST); + setup_rel(o, node, TRUE, OB_DIRECTION_WEST, pre, input, post); return o; } -static gpointer setup_send_prev_func(xmlNodePtr node) +static gpointer setup_send_prev_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { Options *o = setup_follow(node); - setup_rel(o, node, TRUE, OB_DIRECTION_WEST); + setup_rel(o, node, TRUE, OB_DIRECTION_WEST, + pre, (o->follow ? input : NULL), post); return o; } -static gpointer setup_go_left_func(xmlNodePtr node) +static gpointer setup_go_left_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { Options *o = g_new0(Options, 1); - setup_rel(o, node, FALSE, OB_DIRECTION_WEST); + setup_rel(o, node, FALSE, OB_DIRECTION_WEST, pre, input, post); return o; } -static gpointer setup_send_left_func(xmlNodePtr node) +static gpointer setup_send_left_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { Options *o = setup_follow(node); - setup_rel(o, node, FALSE, OB_DIRECTION_WEST); + setup_rel(o, node, FALSE, OB_DIRECTION_WEST, + pre, (o->follow ? input : NULL), post); return o; } -static gpointer setup_go_right_func(xmlNodePtr node) +static gpointer setup_go_right_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { Options *o = g_new0(Options, 1); - setup_rel(o, node, FALSE, OB_DIRECTION_EAST); + setup_rel(o, node, FALSE, OB_DIRECTION_EAST, pre, input, post); return o; } -static gpointer setup_send_right_func(xmlNodePtr node) +static gpointer setup_send_right_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { Options *o = setup_follow(node); - setup_rel(o, node, FALSE, OB_DIRECTION_EAST); + setup_rel(o, node, FALSE, OB_DIRECTION_EAST, + pre, (o->follow ? input : NULL), post); return o; } -static gpointer setup_go_up_func(xmlNodePtr node) +static gpointer setup_go_up_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { Options *o = g_new0(Options, 1); - setup_rel(o, node, FALSE, OB_DIRECTION_NORTH); + setup_rel(o, node, FALSE, OB_DIRECTION_NORTH, pre, input, post); return o; } -static gpointer setup_send_up_func(xmlNodePtr node) +static gpointer setup_send_up_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { Options *o = setup_follow(node); - setup_rel(o, node, FALSE, OB_DIRECTION_NORTH); + setup_rel(o, node, FALSE, OB_DIRECTION_NORTH, + pre, (o->follow ? input : NULL), post); return o; } -static gpointer setup_go_down_func(xmlNodePtr node) +static gpointer setup_go_down_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { Options *o = g_new0(Options, 1); - setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH); + setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH, pre, input, post); return o; } -static gpointer setup_send_down_func(xmlNodePtr node) +static gpointer setup_send_down_func(xmlNodePtr node, + ObActionsIPreFunc *pre, + ObActionsIInputFunc *input, + ObActionsICancelFunc *cancel, + ObActionsIPostFunc *post) { Options *o = setup_follow(node); - setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH); + setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH, + pre, (o->follow ? input : NULL), post); return o; }
M openbox/screen.copenbox/screen.c

@@ -77,6 +77,7 @@ static GSList *struts_right = NULL;

static GSList *struts_bottom = NULL; static ObPagerPopup *desktop_popup; +static gboolean desktop_popup_perm; /*! The number of microseconds that you need to be on a desktop before it will replace the remembered "last desktop" */

@@ -347,6 +348,7 @@ guint32 d;

gboolean namesexist = FALSE; desktop_popup = pager_popup_new(); + desktop_popup_perm = FALSE; pager_popup_height(desktop_popup, POPUP_HEIGHT); if (reconfig) {

@@ -677,7 +679,7 @@

ob_debug("Moving to desktop %d", num+1); if (ob_state() == OB_STATE_RUNNING) - screen_show_desktop_popup(screen_desktop); + screen_show_desktop_popup(screen_desktop, FALSE); /* ignore enter events caused by the move */ ignore_start = event_start_ignore_all_enters();

@@ -701,8 +703,7 @@ /* hide windows from bottom to top */

for (it = g_list_last(stacking_list); it; it = g_list_previous(it)) { if (WINDOW_IS_CLIENT(it->data)) { ObClient *c = it->data; - client_hide(c); - if (c == focus_client) { + if (client_hide(c) && c == focus_client) { /* c was focused and we didn't do fallback clearly so make sure openbox doesnt still consider the window focused. this happens when using NextWindow with allDesktops, since

@@ -922,7 +923,7 @@ pager_popup_hide(desktop_popup);

return FALSE; /* don't repeat */ } -void screen_show_desktop_popup(guint d) +void screen_show_desktop_popup(guint d, gboolean perm) { Rect *a;

@@ -942,9 +943,13 @@ MAX(a->width/3, POPUP_WIDTH));

pager_popup_show(desktop_popup, screen_desktop_names[d], d); obt_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func); - obt_main_loop_timeout_add(ob_main_loop, config_desktop_popup_time * 1000, - hide_desktop_popup_func, desktop_popup, - g_direct_equal, NULL); + if (!perm && !desktop_popup_perm) + /* only hide if its not already being show permanently */ + obt_main_loop_timeout_add(ob_main_loop, + config_desktop_popup_time * 1000, + hide_desktop_popup_func, desktop_popup, + g_direct_equal, NULL); + g_free(a); }

@@ -953,6 +958,7 @@ {

obt_main_loop_timeout_remove_data(ob_main_loop, hide_desktop_popup_func, desktop_popup, FALSE); pager_popup_hide(desktop_popup); + desktop_popup_perm = FALSE; } guint screen_find_desktop(guint from, ObDirection dir,
M openbox/screen.hopenbox/screen.h

@@ -75,8 +75,12 @@

guint screen_find_desktop(guint from, ObDirection dir, gboolean wrap, gboolean linear); -/*! Show the desktop popup/notification */ -void screen_show_desktop_popup(guint d); +/*! Show the desktop popup/notification + @permanent If TRUE, the popup will stay on the screen until you call + screen_hide_desktop_popup(). Otherwise it will hide after a + delay. + */ +void screen_show_desktop_popup(guint d, gboolean permanent); /*! Hide it */ void screen_hide_desktop_popup(void);