X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Factions.c;h=fda119c825008aa533c357b310fabc69b767a75c;hb=1b392b5fbe85c55cda2b0fc9d1e10cbe56216185;hp=6068f19c31d576856ae736bb92dd4d93db60c35d;hpb=0dc7eca4cdfff6425e19a0bace0f9ae8834d04e8;p=chaz%2Fopenbox diff --git a/openbox/actions.c b/openbox/actions.c index 6068f19c..fda119c8 100644 --- a/openbox/actions.c +++ b/openbox/actions.c @@ -36,30 +36,34 @@ static ObActionsAct* actions_build_act_from_string(const gchar *name); static ObActionsAct *interactive_act = NULL; static guint interactive_initial_state = 0; -static gboolean replay_pointer = FALSE; struct _ObActionsDefinition { guint ref; gchar *name; - ObActionsDataSetupFunc setup; + gboolean canbeinteractive; + union { + ObActionsIDataSetupFunc i; + ObActionsDataSetupFunc n; + } setup; ObActionsDataFreeFunc free; ObActionsRunFunc run; - ObActionsInteractiveInputFunc i_input; - ObActionsInteractiveCancelFunc i_cancel; }; struct _ObActionsAct { guint ref; ObActionsDefinition *def; + ObActionsIPreFunc i_pre; + ObActionsIInputFunc i_input; + ObActionsICancelFunc i_cancel; + ObActionsIPostFunc i_post; gpointer options; }; static GSList *registered = NULL; - void actions_startup(gboolean reconfig) { if (reconfig) return; @@ -80,37 +84,55 @@ void actions_shutdown(gboolean reconfig) } } -gboolean actions_register(const gchar *name, - ObActionsDataSetupFunc setup, - ObActionsDataFreeFunc free, - ObActionsRunFunc run, - ObActionsInteractiveInputFunc i_input, - ObActionsInteractiveCancelFunc i_cancel) +ObActionsDefinition* do_register(const gchar *name, + ObActionsDataFreeFunc free, + ObActionsRunFunc run) { GSList *it; ObActionsDefinition *def; g_assert(run != NULL); - g_assert((i_input == NULL) == (i_cancel == NULL)); for (it = registered; it; it = g_slist_next(it)) { def = it->data; if (!g_ascii_strcasecmp(name, def->name)) /* already registered */ - return FALSE; + return NULL; } def = g_new(ObActionsDefinition, 1); def->ref = 1; def->name = g_strdup(name); - def->setup = setup; def->free = free; def->run = run; - def->i_input = i_input; - def->i_cancel = i_cancel; registered = g_slist_prepend(registered, def); + return def; +} - return TRUE; +gboolean actions_register_i(const gchar *name, + ObActionsIDataSetupFunc setup, + ObActionsDataFreeFunc free, + ObActionsRunFunc run) +{ + ObActionsDefinition *def = do_register(name, free, run); + if (def) { + def->canbeinteractive = TRUE; + def->setup.i = setup; + } + return def != NULL; +} + +gboolean actions_register(const gchar *name, + ObActionsDataSetupFunc setup, + ObActionsDataFreeFunc free, + ObActionsRunFunc run) +{ + ObActionsDefinition *def = do_register(name, free, run); + if (def) { + def->canbeinteractive = FALSE; + def->setup.n = setup; + } + return def != NULL; } static void actions_definition_ref(ObActionsDefinition *def) @@ -146,9 +168,13 @@ static ObActionsAct* actions_build_act_from_string(const gchar *name) act->ref = 1; act->def = def; actions_definition_ref(act->def); + act->i_pre = NULL; + act->i_input = NULL; + act->i_cancel = NULL; + act->i_post = NULL; act->options = NULL; } else - g_message(_("Invalid action '%s' requested. No such action exists."), + g_message(_("Invalid action \"%s\" requested. No such action exists."), name); return act; @@ -158,9 +184,21 @@ ObActionsAct* actions_parse_string(const gchar *name) { ObActionsAct *act = NULL; - if ((act = actions_build_act_from_string(name))) - if (act->def->setup) - act->options = act->def->setup(NULL); + if ((act = actions_build_act_from_string(name))) { + if (act->def->canbeinteractive) { + if (act->def->setup.i) + act->options = act->def->setup.i(NULL, + &act->i_pre, + &act->i_input, + &act->i_cancel, + &act->i_post); + } + else { + if (act->def->setup.n) + act->options = act->def->setup.n(NULL); + } + } + return act; } @@ -171,11 +209,21 @@ ObActionsAct* actions_parse(xmlNodePtr node) ObActionsAct *act = NULL; if (obt_parse_attr_string(node, "name", &name)) { - if ((act = actions_build_act_from_string(name))) + if ((act = actions_build_act_from_string(name))) { /* there is more stuff to parse here */ - if (act->def->setup) - act->options = act->def->setup(node->children); - + if (act->def->canbeinteractive) { + if (act->def->setup.i) + act->options = act->def->setup.i(node->children, + &act->i_pre, + &act->i_input, + &act->i_cancel, + &act->i_post); + } + else { + if (act->def->setup.n) + act->options = act->def->setup.n(node->children); + } + } g_free(name); } @@ -184,7 +232,7 @@ ObActionsAct* actions_parse(xmlNodePtr node) gboolean actions_act_is_interactive(ObActionsAct *act) { - return act->def->i_cancel != NULL; + return act->i_input != NULL; } void actions_act_ref(ObActionsAct *act) @@ -222,16 +270,6 @@ static void actions_setup_data(ObActionsData *data, data->client = client; } -void actions_set_need_pointer_replay_before_move(gboolean replay) -{ - replay_pointer = replay; -} - -gboolean actions_get_need_pointer_replay_before_move() -{ - return replay_pointer; -} - void actions_run_acts(GSList *acts, ObUserAction uact, guint state, @@ -265,6 +303,8 @@ void actions_run_acts(GSList *acts, /* cancel the old one */ if (interactive_act) actions_interactive_cancel_act(); + if (act->i_pre) + act->i_pre(act->options); ok = actions_interactive_begin_act(act, state); } } @@ -276,7 +316,7 @@ void actions_run_acts(GSList *acts, actions_interactive_end_act(); } else { /* make sure its interactive if it returned TRUE */ - g_assert(act->def->i_cancel && act->def->i_input); + g_assert(act->i_input); /* no actions are run after the interactive one */ break; @@ -293,7 +333,8 @@ gboolean actions_interactive_act_running(void) void actions_interactive_cancel_act(void) { if (interactive_act) { - interactive_act->def->i_cancel(interactive_act->options); + if (interactive_act->i_cancel) + interactive_act->i_cancel(interactive_act->options); actions_interactive_end_act(); } } @@ -321,6 +362,9 @@ static void actions_interactive_end_act(void) if (interactive_act) { ungrab_keyboard(); + if (interactive_act->i_post) + interactive_act->i_post(interactive_act->options); + actions_act_unref(interactive_act); interactive_act = NULL; } @@ -330,8 +374,8 @@ 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)) + if (!interactive_act->i_input(interactive_initial_state, e, + interactive_act->options, &used)) { used = TRUE; /* if it cancelled the action then it has to of been used */ @@ -344,14 +388,8 @@ gboolean actions_interactive_input_event(XEvent *e) void actions_client_move(ObActionsData *data, gboolean start) { static gulong ignore_start = 0; - if (start) { + if (start) ignore_start = event_start_ignore_all_enters(); - if (replay_pointer) { - /* replay the pointer event before any windows move */ - XAllowEvents(obt_display, ReplayPointer, event_curtime); - replay_pointer = FALSE; - } - } else if (config_focus_follow && data->context != OB_FRAME_CONTEXT_CLIENT) { @@ -362,8 +400,14 @@ void actions_client_move(ObActionsData *data, gboolean start) that moves windows our from under the cursor, the enter event will come as a GrabNotify which is ignored, so this makes a fake enter event + + don't do this if there is a grab on the pointer. enter events + are ignored during a grab, so don't force fake ones when they + should be ignored */ - if ((c = client_under_pointer()) && c != data->client) { + if ((c = client_under_pointer()) && c != data->client && + !grab_on_pointer()) + { ob_debug_type(OB_DEBUG_FOCUS, "Generating fake enter because we did a " "mouse-event action");