all repos — openbox @ ae624a1487fd7db9291c4de1a3b2c34fcab89ef9

openbox fork - make it a bit more like ryudo

add code for interactive actions
Dana Jansens danakj@orodu.net
commit

ae624a1487fd7db9291c4de1a3b2c34fcab89ef9

parent

8becd1f93f9a8a448ca61372e50bd8bf79e7ab9d

4 files changed, 91 insertions(+), 15 deletions(-)

jump to
M openbox/actions.copenbox/actions.c

@@ -18,9 +18,15 @@ */

#include "actions.h" #include "gettext.h" +#include "grab.h" -static void actions_definition_ref(ObActionsDefinition *def); -static void actions_definition_unref(ObActionsDefinition *def); +static void actions_definition_ref(ObActionsDefinition *def); +static void actions_definition_unref(ObActionsDefinition *def); +static gboolean actions_interactive_begin_act(ObActionsAct *act, guint state); +static void actions_interactive_end_act(); + +static ObActionsAct *interactive_act = NULL; +static guint interactive_initial_state = 0; struct _ObActionsDefinition { guint ref;

@@ -202,6 +208,7 @@

for (it = acts; it; it = g_slist_next(it)) { ObActionsData data; ObActionsAct *act = it->data; + gboolean ok = TRUE; data.type = act->def->type; actions_setup_data(&data, uact, time, state, x, y);

@@ -216,7 +223,73 @@ default:

g_assert_not_reached(); } + if (actions_act_is_interactive(act) && + (!interactive_act || interactive_act->def != act->def)) + { + ok = actions_interactive_begin_act(act, state); + } + /* fire the action's run function with this data */ - act->def->run(&data, act->options); + if (ok) { + if (!act->def->run(&data, act->options)) + actions_interactive_end_act(); + else + break; /* no actions are run after the interactive one */ + } + } +} + +gboolean actions_interactive_act_running() +{ + return interactive_act != NULL; +} + +void actions_interactive_cancel_act() +{ + if (interactive_act) { + interactive_act->def->i_cancel(interactive_act->options); + actions_interactive_end_act(); + } +} + +static gboolean actions_interactive_begin_act(ObActionsAct *act, guint state) +{ + /* cancel the old one */ + if (interactive_act) + actions_interactive_cancel_act(); + + if (grab_keyboard()) { + interactive_act = act; + actions_act_ref(interactive_act); + + interactive_initial_state = state; + return TRUE; } + else + return FALSE; +} + +static void actions_interactive_end_act() +{ + if (interactive_act) { + ungrab_keyboard(); + + actions_act_unref(interactive_act); + interactive_act = NULL; + } +} + +gboolean actions_interactive_input_event(XEvent *e) +{ + gboolean used = FALSE; + if (interactive_act) { + if (!interactive_act->def->i_input(interactive_initial_state, e, + interactive_act->options, &used)) + { + used = TRUE; /* if it cancelled the action then it has to of + been used */ + actions_interactive_end_act(); + } + } + return used; }
M openbox/actions.hopenbox/actions.h

@@ -37,7 +37,8 @@ typedef gboolean (*ObActionsRunFunc)(ObActionsData *data,

gpointer options); typedef gboolean (*ObActionsInteractiveInputFunc)(guint initial_state, XEvent *e, - gpointer options); + gpointer options, + gboolean *used); typedef void (*ObActionsInteractiveCancelFunc)(gpointer options); typedef enum {

@@ -112,3 +113,8 @@ gint x,

gint y, ObFrameContext con, struct _ObClient *client); + +gboolean actions_interactive_act_running(); +void actions_interactive_cancel_act(); + +gboolean actions_interactive_input_event(XEvent *e);
M openbox/event.copenbox/event.c

@@ -808,8 +808,7 @@ the mouse is grabbed (possibly) and if we get these events we don't

want to deal with them */ if (!(e->xbutton.button == 4 || e->xbutton.button == 5) && - !keyboard_interactively_grabbed() && - !menu_frame_visible) + !grab_on_keyboard()) { /* use where the press occured */ con = frame_context(client, e->xbutton.window, px, py);

@@ -956,7 +955,7 @@ "%sNotify mode %d detail %d on %lx\n",

(e->type == EnterNotify ? "Enter" : "Leave"), e->xcrossing.mode, e->xcrossing.detail, (client?client->window:0)); - if (keyboard_interactively_grabbed()) + if (grab_on_keyboard()) break; if (config_focus_follow && config_focus_delay && /* leave inferior events can happen when the mouse goes onto

@@ -999,7 +998,7 @@ client->frame->close_hover = TRUE;

frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_FRAME: - if (keyboard_interactively_grabbed()) + if (grab_on_keyboard()) break; if (e->xcrossing.mode == NotifyGrab || e->xcrossing.mode == NotifyUngrab ||

@@ -1792,9 +1791,7 @@ }

/* if the keyboard interactive action uses the event then dont use it for bindings. likewise is moveresize uses the event. */ - if (!keyboard_process_interactive_grab(e, &client) && - !(moveresize_in_progress && moveresize_event(e))) - { + if (!actions_interactive_input_event(e) && !moveresize_event(e)) { if (moveresize_in_progress) /* make further actions work on the client being moved/resized */

@@ -1899,9 +1896,9 @@ }

void event_cancel_all_key_grabs() { - if (keyboard_interactively_grabbed()) { - keyboard_interactive_cancel(); - ob_debug("KILLED interactive event\n"); + if (actions_interactive_act_running()) { + actions_interactive_cancel_act(); + ob_debug("KILLED interactive action\n"); } else if (menu_frame_visible) { menu_frame_hide_all();
M openbox/moveresize.copenbox/moveresize.c

@@ -416,7 +416,7 @@ gboolean moveresize_event(XEvent *e)

{ gboolean used = FALSE; - g_assert(moveresize_in_progress); + if (!moveresize_in_progress) return FALSE; if (e->type == ButtonPress) { if (!button) {