#include "keyboard.h"
#include "event.h"
#include "config.h"
+#include "mainloop.h"
#include <glib.h>
void (*setup)(ObAction **, ObUserAction uact);
} ActionString;
-static ObAction *action_new(void (*func)(union ActionData *data),
- ObUserAction uact)
+static ObAction *action_new(void (*func)(union ActionData *data))
{
ObAction *a = g_new0(ObAction, 1);
+ a->ref = 1;
a->func = func;
return a;
}
-void action_free(ObAction *a)
+void action_ref(ObAction *a)
+{
+ ++a->ref;
+}
+
+void action_unref(ObAction *a)
{
if (a == NULL) return;
+ if (--a->ref > 0) return;
+
/* deal with pointers */
if (a->func == action_execute || a->func == action_restart)
g_free(a->data.execute.path);
g_free(a);
}
+ObAction* action_copy(const ObAction *src)
+{
+ ObAction *a = action_new(src->func);
+
+ a->data = src->data;
+
+ /* deal with pointers */
+ if (a->func == action_execute || a->func == action_restart)
+ a->data.execute.path = g_strdup(a->data.execute.path);
+ else if (a->func == action_showmenu)
+ a->data.showmenu.name = g_strdup(a->data.showmenu.name);
+
+ return a;
+}
+
void setup_action_directional_focus_north(ObAction **a, ObUserAction uact)
{
(*a)->data.interdiraction.inter.any.interactive = TRUE;
(*a)->data.sendtodir.follow = TRUE;
}
+void setup_action_desktop(ObAction **a, ObUserAction uact)
+{
+ (*a)->data.desktop.inter.any.interactive = TRUE;
+}
+
void setup_action_desktop_prev(ObAction **a, ObUserAction uact)
{
(*a)->data.desktopdir.inter.any.interactive = TRUE;
(*a)->data.moveresize.any.client_action = OB_CLIENT_ACTION_ALWAYS;
(*a)->data.moveresize.move = TRUE;
(*a)->data.moveresize.keyboard =
- (uact == OB_USER_ACTION_KEYBOARD_KEY ||
+ (uact == OB_USER_ACTION_NONE ||
+ uact == OB_USER_ACTION_KEYBOARD_KEY ||
uact == OB_USER_ACTION_MENU_SELECTION);
}
(*a)->data.moveresize.any.client_action = OB_CLIENT_ACTION_ALWAYS;
(*a)->data.moveresize.move = FALSE;
(*a)->data.moveresize.keyboard =
- (uact == OB_USER_ACTION_KEYBOARD_KEY ||
+ (uact == OB_USER_ACTION_NONE ||
+ uact == OB_USER_ACTION_KEYBOARD_KEY ||
uact == OB_USER_ACTION_MENU_SELECTION);
}
assumptions that there is only one menu (and submenus) open at
a time! */
if (uact == OB_USER_ACTION_MENU_SELECTION) {
- action_free(*a);
+ action_unref(*a);
a = NULL;
}
}
{
"desktop",
action_desktop,
- NULL
+ setup_action_desktop
},
{
"desktopnext",
for (i = 0; actionstrings[i].name; i++)
if (!g_ascii_strcasecmp(name, actionstrings[i].name)) {
exist = TRUE;
- a = action_new(actionstrings[i].func, uact);
+ a = action_new(actionstrings[i].func);
if (actionstrings[i].setup)
actionstrings[i].setup(&a, uact);
- /* only key bindings can be interactive. thus saith the xor. */
+ /* only key bindings can be interactive. thus saith the xor.
+ because of how the mouse is grabbed, mouse events dont even get
+ read during interactive events, so no dice! >:) */
if (uact != OB_USER_ACTION_KEYBOARD_KEY)
a->data.any.interactive = FALSE;
break;
keyboard_interactive_grab(state, a->data.any.c, a);
}
- a->func(&a->data);
+ ob_main_loop_queue_action(ob_main_loop, a);
}
}
}
+void action_run_string(const gchar *name, struct _ObClient *c)
+{
+ ObAction *a;
+ GSList *l;
+
+ a = action_from_string(name, OB_USER_ACTION_NONE);
+ g_assert(a);
+
+ l = g_slist_append(NULL, a);
+
+ action_run(l, c, 0);
+}
+
void action_execute(union ActionData *data)
{
GError *e = NULL;
if (cit == c) break;
if (client_normal(cit) == client_normal(c) &&
cit->layer == c->layer &&
- cit->frame->visible)
+ cit->frame->visible &&
+ !client_search_transient(c, cit))
{
if (RECT_INTERSECTS_RECT(cit->frame->area, c->frame->area)) {
raise = TRUE;
void action_desktop(union ActionData *data)
{
- if (data->desktop.desk < screen_num_desktops ||
- data->desktop.desk == DESKTOP_ALL)
- screen_set_desktop(data->desktop.desk);
+ static guint first = (unsigned) -1;
+
+ if (data->inter.any.interactive && first == (unsigned) -1)
+ first = screen_desktop;
+
+ if (!data->inter.any.interactive ||
+ (!data->inter.cancel && !data->inter.final))
+ {
+ if (data->desktop.desk < screen_num_desktops ||
+ data->desktop.desk == DESKTOP_ALL)
+ {
+ screen_set_desktop(data->desktop.desk);
+ if (data->inter.any.interactive)
+ screen_desktop_popup(data->desktop.desk, TRUE);
+ }
+ } else if (data->inter.cancel) {
+ screen_set_desktop(first);
+ }
+
+ if (data->inter.any.interactive && data->inter.final) {
+ screen_desktop_popup(0, FALSE);
+ first = (unsigned) -1;
+ }
}
void action_desktop_dir(union ActionData *data)