]> Dogcows Code - chaz/openbox/blobdiff - openbox/action.c
give actions a ref count
[chaz/openbox] / openbox / action.c
index 22a5785e8b6f9ece3bbb0adf71cce43725ed5a27..52a602ccf7071ba53818f0737a8307c4a5083d0c 100644 (file)
@@ -65,19 +65,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);
@@ -201,6 +208,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;
@@ -354,7 +366,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 +601,7 @@ ActionString actionstrings[] =
     {
         "desktop",
         action_desktop,
-        NULL
+        setup_action_desktop
     },
     {
         "desktopnext",
@@ -767,10 +779,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;
@@ -944,7 +958,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 +1176,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 +1249,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);
 }
 
This page took 0.025463 seconds and 4 git commands to generate.