X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Faction.c;h=daa18ad18cf9ff590023994544d9ca087809414b;hb=a51d2082bd28baa11e28441bc0fb4016150618df;hp=22a5785e8b6f9ece3bbb0adf71cce43725ed5a27;hpb=1213b079bb0d32dcb97c37b2b0f6fcb0c8b6eefc;p=chaz%2Fopenbox diff --git a/openbox/action.c b/openbox/action.c index 22a5785e..daa18ad1 100644 --- a/openbox/action.c +++ b/openbox/action.c @@ -30,6 +30,7 @@ #include "keyboard.h" #include "event.h" #include "config.h" +#include "mainloop.h" #include @@ -65,19 +66,26 @@ typedef struct 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); @@ -87,6 +95,21 @@ void action_free(ObAction *a) 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; @@ -201,6 +224,11 @@ void setup_action_send_to_desktop_down(ObAction **a, ObUserAction uact) (*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; @@ -334,7 +362,8 @@ void setup_action_move(ObAction **a, ObUserAction uact) (*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); } @@ -343,7 +372,8 @@ void setup_action_resize(ObAction **a, ObUserAction uact) (*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); } @@ -354,7 +384,7 @@ void setup_action_showmenu(ObAction **a, ObUserAction uact) 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; } } @@ -589,7 +619,7 @@ ActionString actionstrings[] = { "desktop", action_desktop, - NULL + setup_action_desktop }, { "desktopnext", @@ -767,10 +797,12 @@ ObAction *action_from_string(const gchar *name, ObUserAction uact) 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; @@ -889,11 +921,24 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context, 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; @@ -944,7 +989,8 @@ void action_raiselower(union ActionData *data) 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; @@ -1161,9 +1207,29 @@ void action_send_to_desktop(union ActionData *data) 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) @@ -1214,8 +1280,7 @@ void action_toggle_decorations(union ActionData *data) ObClient *c = data->client.any.c; client_action_start(data); - c->decorate = !c->decorate; - client_setup_decor_and_functions(c); + client_set_undecorated(c, !c->undecorated); client_action_end(data); }