/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
- actions.h for the Openbox window manager
+ actions.c for the Openbox window manager
Copyright (c) 2007 Dana Jansens
This program is free software; you can redistribute it and/or modify
#include "event.h"
#include "config.h"
#include "client.h"
+#include "focus.h"
#include "openbox.h"
#include "debug.h"
} setup;
ObActionsDataFreeFunc free;
ObActionsRunFunc run;
+ ObActionsShutdownFunc shutdown;
+ gboolean modifies_focused_window;
};
struct _ObActionsAct {
/* free all the registered actions */
while (registered) {
- actions_definition_unref(registered->data);
+ ObActionsDefinition *d = registered->data;
+ if (d->shutdown) d->shutdown();
+ actions_definition_unref(d);
registered = g_slist_delete_link(registered, registered);
}
}
return NULL;
}
- def = g_new(ObActionsDefinition, 1);
+ def = g_slice_new0(ObActionsDefinition);
def->ref = 1;
def->name = g_strdup(name);
def->free = free;
def->run = run;
+ def->shutdown = NULL;
+ def->modifies_focused_window = TRUE;
registered = g_slist_prepend(registered, def);
return def;
return def != NULL;
}
+gboolean actions_set_shutdown(const gchar *name,
+ ObActionsShutdownFunc shutdown)
+{
+ GSList *it;
+ ObActionsDefinition *def;
+
+ for (it = registered; it; it = g_slist_next(it)) {
+ def = it->data;
+ if (!g_ascii_strcasecmp(name, def->name)) {
+ def->shutdown = shutdown;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+gboolean actions_set_modifies_focused_window(const gchar *name,
+ gboolean modifies)
+{
+ GSList *it;
+ ObActionsDefinition *def;
+
+ for (it = registered; it; it = g_slist_next(it)) {
+ def = it->data;
+ if (!g_ascii_strcasecmp(name, def->name)) {
+ def->modifies_focused_window = modifies;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
static void actions_definition_ref(ObActionsDefinition *def)
{
++def->ref;
{
if (def && --def->ref == 0) {
g_free(def->name);
- g_free(def);
+ g_slice_free(ObActionsDefinition, def);
}
}
/* if we found the action */
if (def) {
- act = g_new(ObActionsAct, 1);
+ act = g_slice_new(ObActionsAct);
act->ref = 1;
act->def = def;
actions_definition_ref(act->def);
gchar *name;
ObActionsAct *act = NULL;
- if (obt_parse_attr_string(node, "name", &name)) {
+ if (obt_xml_attr_string(node, "name", &name)) {
if ((act = actions_build_act_from_string(name))) {
/* there is more stuff to parse here */
if (act->def->canbeinteractive) {
act->def->free(act->options);
/* unref the definition */
actions_definition_unref(act->def);
- g_free(act);
+ g_slice_free(ObActionsAct, act);
}
}
struct _ObClient *client)
{
GSList *it;
+ gboolean update_user_time;
/* Don't allow saving the initial state when running things from the
menu */
if (x < 0 && y < 0)
screen_pointer_pos(&x, &y);
+ update_user_time = FALSE;
for (it = acts; it; it = g_slist_next(it)) {
ObActionsData data;
ObActionsAct *act = it->data;
if (!act->def->run(&data, act->options)) {
if (actions_act_is_interactive(act))
actions_interactive_end_act();
+ if (client && client == focus_client &&
+ act->def->modifies_focused_window)
+ {
+ update_user_time = TRUE;
+ }
} else {
/* make sure its interactive if it returned TRUE */
g_assert(act->i_input);
}
}
}
+ if (update_user_time)
+ event_update_user_time();
}
gboolean actions_interactive_act_running(void)
static void actions_interactive_end_act(void)
{
if (interactive_act) {
+ ObActionsAct *ia = interactive_act;
+
+ /* set this to NULL first so the i_post() function can't cause this to
+ get called again (if it decides it wants to cancel any ongoing
+ interactive action). */
+ interactive_act = NULL;
+
ungrab_keyboard();
- if (interactive_act->i_post)
- interactive_act->i_post(interactive_act->options);
+ if (ia->i_post)
+ ia->i_post(ia->options);
- actions_act_unref(interactive_act);
- interactive_act = NULL;
+ actions_act_unref(ia);
}
}
gboolean used = FALSE;
if (interactive_act) {
if (!interactive_act->i_input(interactive_initial_state, e,
+ grab_input_context(),
interactive_act->options, &used))
{
used = TRUE; /* if it cancelled the action then it has to of
ob_debug_type(OB_DEBUG_FOCUS,
"Generating fake leave because we did a "
"mouse-event action");
- event_enter_client(data->client);
+ event_leave_client(data->client);
}
}
}