X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Factions.c;h=67dc3d31ee38c79b26ea780d4e972d341619999b;hb=85c7635b9b163face21b460de7fd3877baea321b;hp=00563a700055aa7b2ebeb7064da415895dc4a30f;hpb=780d1b0961e2eed5fea4645b4398fafb4adad73a;p=chaz%2Fopenbox diff --git a/openbox/actions.c b/openbox/actions.c index 00563a70..67dc3d31 100644 --- a/openbox/actions.c +++ b/openbox/actions.c @@ -20,6 +20,12 @@ #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" static void actions_definition_ref(ObActionsDefinition *def); static void actions_definition_unref(ObActionsDefinition *def); @@ -33,7 +39,6 @@ struct _ObActionsDefinition { guint ref; gchar *name; - ObActionsType type; ObActionsDataSetupFunc setup; ObActionsDataFreeFunc free; @@ -55,6 +60,8 @@ static GSList *registered = NULL; void actions_startup(gboolean reconfig) { if (reconfig) return; + + action_all_startup(); } void actions_shutdown(gboolean reconfig) @@ -71,7 +78,6 @@ void actions_shutdown(gboolean reconfig) } gboolean actions_register(const gchar *name, - ObActionsType type, ObActionsDataSetupFunc setup, ObActionsDataFreeFunc free, ObActionsRunFunc run, @@ -81,23 +87,26 @@ gboolean actions_register(const gchar *name, 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; } - g_assert((i_input == NULL) == (i_cancel == NULL)); - def = g_new(ObActionsDefinition, 1); def->ref = 1; def->name = g_strdup(name); - def->type = type; 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 TRUE; } @@ -117,7 +126,7 @@ static void actions_definition_unref(ObActionsDefinition *def) ObActionsAct* actions_parse_string(const gchar *name) { GSList *it; - ObActionsDefinition *def; + ObActionsDefinition *def = NULL; ObActionsAct *act = NULL; /* find the requested action */ @@ -152,7 +161,8 @@ ObActionsAct* actions_parse(ObParseInst *i, if (parse_attr_string("name", node, &name)) { if ((act = actions_parse_string(name))) /* there is more stuff to parse here */ - act->options = act->def->setup(i, doc, node->children); + if (act->def->setup) + act->options = act->def->setup(i, doc, node->xmlChildrenNode); g_free(name); } @@ -174,7 +184,8 @@ void actions_act_unref(ObActionsAct *act) { if (act && --act->ref == 0) { /* free the action specific options */ - act->def->free(act->options); + if (act->def->free) + act->def->free(act->options); /* unref the definition */ actions_definition_unref(act->def); g_free(act); @@ -183,24 +194,28 @@ void actions_act_unref(ObActionsAct *act) static void actions_setup_data(ObActionsData *data, ObUserAction uact, - Time time, guint state, gint x, - gint y) + gint y, + gint button, + ObFrameContext con, + struct _ObClient *client) { - data->any.uact = uact; - data->any.time = time; - data->any.state = state; - data->any.x = x; - data->any.y = y; + data->uact = uact; + data->state = state; + data->x = x; + data->y = y; + data->button = button; + data->context = con; + data->client = client; } void actions_run_acts(GSList *acts, ObUserAction uact, - Time time, guint state, gint x, gint y, + gint button, ObFrameContext con, struct _ObClient *client) { @@ -219,18 +234,7 @@ void actions_run_acts(GSList *acts, ObActionsAct *act = it->data; gboolean ok = TRUE; - data.type = act->def->type; - actions_setup_data(&data, uact, time, state, x, y); - switch (data.type) { - case OB_ACTION_TYPE_GLOBAL: - break; - case OB_ACTION_TYPE_CLIENT: - data.client.context = con; - data.client.c = client; - break; - default: - g_assert_not_reached(); - } + actions_setup_data(&data, uact, state, x, y, button, con, client); if (actions_act_is_interactive(act) && (!interactive_act || interactive_act->def != act->def)) @@ -242,8 +246,13 @@ void actions_run_acts(GSList *acts, if (ok) { if (!act->def->run(&data, act->options)) actions_interactive_end_act(); - else - break; /* no actions are run after the interactive one */ + else { + /* make sure its interactive if it returned TRUE */ + g_assert(act->def->i_cancel && act->def->i_input); + + /* no actions are run after the interactive one */ + break; + } } } } @@ -302,3 +311,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->button && data->client && !config_focus_under_mouse) + event_end_ignore_all_enters(ignore_start); + else { + 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); + } + } + } +}