X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Factions.c;h=a236b581d60359328f645f4fe1a3765be4f258a4;hb=4307366b713aaf1a5787dbb3244a5717db1330e8;hp=a4308e62e2730f3b5081c7ed6e0e3902a00574c6;hpb=d642be361fde438e2b29b7374b4d6465f47ad9e9;p=chaz%2Fopenbox diff --git a/openbox/actions.c b/openbox/actions.c index a4308e62..a236b581 100644 --- a/openbox/actions.c +++ b/openbox/actions.c @@ -20,6 +20,10 @@ #include "gettext.h" #include "grab.h" #include "screen.h" +#include "event.h" +#include "config.h" +#include "client.h" +#include "debug.h" #include "actions/all.h" @@ -27,6 +31,7 @@ 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* actions_build_act_from_string(const gchar *name); static ObActionsAct *interactive_act = NULL; static guint interactive_initial_state = 0; @@ -119,7 +124,7 @@ static void actions_definition_unref(ObActionsDefinition *def) } } -ObActionsAct* actions_parse_string(const gchar *name) +static ObActionsAct* actions_build_act_from_string(const gchar *name) { GSList *it; ObActionsDefinition *def = NULL; @@ -147,6 +152,17 @@ ObActionsAct* actions_parse_string(const gchar *name) return act; } +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, NULL, NULL); + + return act; +} + ObActionsAct* actions_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node) @@ -155,7 +171,7 @@ ObActionsAct* actions_parse(ObParseInst *i, ObActionsAct *act = NULL; if (parse_attr_string("name", node, &name)) { - if ((act = actions_parse_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(i, doc, node->xmlChildrenNode); @@ -232,17 +248,23 @@ void actions_run_acts(GSList *acts, actions_setup_data(&data, uact, state, x, y, button, con, client); - if (actions_act_is_interactive(act) && - (!interactive_act || interactive_act->def != act->def)) - { - ok = actions_interactive_begin_act(act, state); + /* if they have the same run function, then we'll assume they are + cooperating and not cancel eachother out */ + if (!interactive_act || interactive_act->def->run != act->def->run) { + if (actions_act_is_interactive(act)) { + /* cancel the old one */ + if (interactive_act) + actions_interactive_cancel_act(); + ok = actions_interactive_begin_act(act, state); + } } /* fire the action's run function with this data */ if (ok) { - if (!act->def->run(&data, act->options)) - actions_interactive_end_act(); - else { + if (!act->def->run(&data, act->options)) { + if (actions_act_is_interactive(act)) + actions_interactive_end_act(); + } else { /* make sure its interactive if it returned TRUE */ g_assert(act->def->i_cancel && act->def->i_input); @@ -253,12 +275,12 @@ void actions_run_acts(GSList *acts, } } -gboolean actions_interactive_act_running() +gboolean actions_interactive_act_running(void) { return interactive_act != NULL; } -void actions_interactive_cancel_act() +void actions_interactive_cancel_act(void) { if (interactive_act) { interactive_act->def->i_cancel(interactive_act->options); @@ -268,22 +290,23 @@ void actions_interactive_cancel_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; + + /* if using focus_delay, stop the timer now so that focus doesn't go + moving on us, which would kill the action */ + event_halt_focus_delay(); + return TRUE; } else return FALSE; } -static void actions_interactive_end_act() +static void actions_interactive_end_act(void) { if (interactive_act) { ungrab_keyboard(); @@ -307,3 +330,31 @@ gboolean actions_interactive_input_event(XEvent *e) } return used; } + +void actions_client_move(ObActionsData *data, gboolean start) +{ + static gulong ignore_start = 0; + if (start) + ignore_start = event_start_ignore_all_enters(); + else if (config_focus_follow && + data->context != OB_FRAME_CONTEXT_CLIENT) + { + if (data->uact == OB_USER_ACTION_MOUSE_PRESS) { + struct _ObClient *c; + + /* usually this is sorta redundant, but with a press action + 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 + */ + if ((c = client_under_pointer()) && c != data->client) { + ob_debug_type(OB_DEBUG_FOCUS, + "Generating fake enter because we did a " + "mouse-event action"); + event_enter_client(c); + } + } + else if (!data->button && !config_focus_under_mouse) + event_end_ignore_all_enters(ignore_start); + } +}