add the adddesktop and removedesktop actions
authorDana Jansens <danakj@orodu.net>
Sat, 23 Jun 2007 14:42:06 +0000 (14:42 +0000)
committerDana Jansens <danakj@orodu.net>
Sat, 23 Jun 2007 14:42:06 +0000 (14:42 +0000)
Makefile.am
openbox/action.c
openbox/actions/addremovedesktop.c [new file with mode: 0644]
openbox/actions/all.c
openbox/actions/all.h

index 896597f..c65101e 100644 (file)
@@ -156,6 +156,7 @@ openbox_openbox_SOURCES = \
        gettext.h \
        openbox/actions/all.c \
        openbox/actions/all.h \
+       openbox/actions/addremovedesktop.c \
        openbox/actions/breakchroot.c \
        openbox/actions/close.c \
        openbox/actions/cyclewindows.c \
index 8e717e6..8b2cfe8 100644 (file)
@@ -302,16 +302,6 @@ void setup_action_bottom_layer(ObAction **a, ObUserAction uact)
     (*a)->data.layer.layer = -1;
 }
 
-void setup_action_addremove_desktop_current(ObAction **a, ObUserAction uact)
-{
-    (*a)->data.addremovedesktop.current = TRUE;
-}
-
-void setup_action_addremove_desktop_last(ObAction **a, ObUserAction uact)
-{
-    (*a)->data.addremovedesktop.current = FALSE;
-}
-
 void setup_client_action(ObAction **a, ObUserAction uact)
 {
     (*a)->data.any.client_action = OB_CLIENT_ACTION_ALWAYS;
@@ -450,90 +440,12 @@ ActionString actionstrings[] =
         setup_action_growtoedge_east
     },
     {
-        "adddesktoplast",
-        action_add_desktop,
-        setup_action_addremove_desktop_last
-    },
-    {
-        "removedesktoplast",
-        action_remove_desktop,
-        setup_action_addremove_desktop_last
-    },
-    {
-        "adddesktopcurrent",
-        action_add_desktop,
-        setup_action_addremove_desktop_current
-    },
-    {
-        "removedesktopcurrent",
-        action_remove_desktop,
-        setup_action_addremove_desktop_current
-    },
-    {
         NULL,
         NULL,
         NULL
     }
 };
 
-/* 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! >:) */
-#define INTERACTIVE_LIMIT(a, uact) \
-    if (uact != OB_USER_ACTION_KEYBOARD_KEY) \
-        a->data.any.interactive = FALSE;
-
-ObAction *action_from_string(const gchar *name, ObUserAction uact)
-{
-    ObAction *a = NULL;
-    gboolean exist = FALSE;
-    gint i;
-
-    for (i = 0; actionstrings[i].name; i++)
-        if (!g_ascii_strcasecmp(name, actionstrings[i].name)) {
-            exist = TRUE;
-            a = action_new(actionstrings[i].func);
-            if (actionstrings[i].setup)
-                actionstrings[i].setup(&a, uact);
-            if (a)
-                INTERACTIVE_LIMIT(a, uact);
-            break;
-        }
-    if (!exist)
-        g_message(_("Invalid action '%s' requested. No such action exists."),
-                  name);
-    if (!a)
-        g_message(_("Invalid use of action '%s'. Action will be ignored."),
-                  name);
-    return a;
-}
-
-ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                       ObUserAction uact)
-{
-    gchar *actname;
-    ObAction *act = NULL;
-    xmlNodePtr n;
-
-    if (parse_attr_string("name", node, &actname)) {
-        if ((act = action_from_string(actname, uact))) {
-            } else if (act->func == action_desktop) {
-            } else if (act->func == action_send_to_desktop_dir) {
-                if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
-                    act->data.sendtodir.wrap = parse_bool(doc, n);
-                if ((n = parse_find_node("follow", node->xmlChildrenNode)))
-                    act->data.sendtodir.follow = parse_bool(doc, n);
-                if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
-                    act->data.sendtodir.inter.any.interactive =
-                        parse_bool(doc, n);
-            INTERACTIVE_LIMIT(act, uact);
-        }
-        g_free(actname);
-    }
-    return act;
-}
-
-
 void action_unshaderaise(union ActionData *data)
 {
     if (data->client.any.c->shaded)
@@ -550,45 +462,6 @@ void action_shadelower(union ActionData *data)
         action_shade(data);
 }
 
-void action_send_to_desktop_dir(union ActionData *data)
-{
-    ObClient *c = data->sendtodir.inter.any.c;
-    guint d;
-
-    if (!client_normal(c)) return;
-
-    d = screen_cycle_desktop(data->sendtodir.dir, data->sendtodir.wrap,
-                             data->sendtodir.linear,
-                             data->sendtodir.inter.any.interactive,
-                             data->sendtodir.inter.final,
-                             data->sendtodir.inter.cancel);
-    /* only move the desktop when the action is complete. if we switch
-       desktops during the interactive action, focus will move but with
-       NotifyWhileGrabbed and applications don't like that. */
-    if (!data->sendtodir.inter.any.interactive ||
-        (data->sendtodir.inter.final && !data->sendtodir.inter.cancel))
-    {
-        client_set_desktop(c, d, data->sendtodir.follow, FALSE);
-        if (data->sendtodir.follow && d != screen_desktop)
-            screen_set_desktop(d, TRUE);
-    }
-}
-
-void action_directional_focus(union ActionData *data)
-{
-    /* if using focus_delay, stop the timer now so that focus doesn't go moving
-       on us */
-    event_halt_focus_delay();
-
-    focus_directional_cycle(data->interdiraction.direction,
-                            data->interdiraction.dock_windows,
-                            data->interdiraction.desktop_windows,
-                            data->any.interactive,
-                            data->interdiraction.dialog,
-                            data->interdiraction.inter.final,
-                            data->interdiraction.inter.cancel);
-}
-
 void action_movetoedge(union ActionData *data)
 {
     gint x, y;
@@ -718,75 +591,6 @@ void action_toggle_dockautohide(union ActionData *data)
     dock_configure();
 }
 
-void action_add_desktop(union ActionData *data)
-{
-    client_action_start(data);
-    screen_set_num_desktops(screen_num_desktops+1);
-
-    /* move all the clients over */
-    if (data->addremovedesktop.current) {
-        GList *it;
-
-        for (it = client_list; it; it = g_list_next(it)) {
-            ObClient *c = it->data;
-            if (c->desktop != DESKTOP_ALL && c->desktop >= screen_desktop)
-                client_set_desktop(c, c->desktop+1, FALSE, TRUE);
-        }
-    }
-
-    client_action_end(data, config_focus_under_mouse);
-}
-
 void action_remove_desktop(union ActionData *data)
 {
-    guint rmdesktop, movedesktop;
-    GList *it, *stacking_copy;
-
-    if (screen_num_desktops < 2) return;
-
-    client_action_start(data);
-
-    /* what desktop are we removing and moving to? */
-    if (data->addremovedesktop.current)
-        rmdesktop = screen_desktop;
-    else
-        rmdesktop = screen_num_desktops - 1;
-    if (rmdesktop < screen_num_desktops - 1)
-        movedesktop = rmdesktop + 1;
-    else
-        movedesktop = rmdesktop;
-
-    /* make a copy of the list cuz we're changing it */
-    stacking_copy = g_list_copy(stacking_list);
-    for (it = g_list_last(stacking_copy); it; it = g_list_previous(it)) {
-        if (WINDOW_IS_CLIENT(it->data)) {
-            ObClient *c = it->data;
-            guint d = c->desktop;
-            if (d != DESKTOP_ALL && d >= movedesktop) {
-                client_set_desktop(c, c->desktop - 1, TRUE, TRUE);
-                ob_debug("moving window %s\n", c->title);
-            }
-            /* raise all the windows that are on the current desktop which
-               is being merged */
-            if ((screen_desktop == rmdesktop - 1 ||
-                 screen_desktop == rmdesktop) &&
-                (d == DESKTOP_ALL || d == screen_desktop))
-            {
-                stacking_raise(CLIENT_AS_WINDOW(c));
-                ob_debug("raising window %s\n", c->title);
-            }
-        }
-    }
-
-    /* act like we're changing desktops */
-    if (screen_desktop < screen_num_desktops - 1) {
-        gint d = screen_desktop;
-        screen_desktop = screen_last_desktop;
-        screen_set_desktop(d, TRUE);
-        ob_debug("fake desktop change\n");
-    }
-
-    screen_set_num_desktops(screen_num_desktops-1);
-
-    client_action_end(data, config_focus_under_mouse);
 }
diff --git a/openbox/actions/addremovedesktop.c b/openbox/actions/addremovedesktop.c
new file mode 100644 (file)
index 0000000..85aeb3f
--- /dev/null
@@ -0,0 +1,145 @@
+#include "openbox/actions.h"
+#include "openbox/screen.h"
+#include "openbox/client.h"
+#include "openbox/debug.h"
+#include <glib.h>
+
+typedef struct {
+    gboolean current;
+    gboolean add;
+} Options;
+
+static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_add_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_remove_func(ObParseInst *i,
+                                  xmlDocPtr doc, xmlNodePtr node);
+static void     free_func(gpointer options);
+static gboolean run_func(ObActionsData *data, gpointer options);
+
+void action_addremovedesktop_startup()
+{
+    actions_register("AddDesktop",
+                     setup_add_func,
+                     free_func,
+                     run_func,
+                     NULL, NULL);
+    actions_register("RemoveDesktop",
+                     setup_remove_func,
+                     free_func,
+                     run_func,
+                     NULL, NULL);
+}
+
+static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
+{
+    xmlNodePtr n;
+    Options *o;
+
+    o = g_new0(Options, 1);
+
+    if ((n = parse_find_node("where", node))) {
+        gchar *s = parse_string(doc, n);
+        if (!g_ascii_strcasecmp(s, "last"))
+            o->current = FALSE;
+        else if (!g_ascii_strcasecmp(s, "current"))
+            o->current = TRUE;
+        g_free(s);
+    }
+
+    return o;
+}
+
+static gpointer setup_add_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->add = TRUE;
+    return o;
+}
+
+static gpointer setup_remove_func(ObParseInst *i,
+                                  xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->add = FALSE;
+    return o;
+}
+
+static void free_func(gpointer options)
+{
+    Options *o = options;
+
+    g_free(o);
+}
+
+/* Always return FALSE because its not interactive */
+static gboolean run_func(ObActionsData *data, gpointer options)
+{
+    Options *o = options;
+
+    actions_client_move(data, FALSE);
+
+    if (o->add) {
+        screen_set_num_desktops(screen_num_desktops+1);
+
+        /* move all the clients over */
+        if (o->current) {
+            GList *it;
+
+            for (it = client_list; it; it = g_list_next(it)) {
+                ObClient *c = it->data;
+                if (c->desktop != DESKTOP_ALL && c->desktop >= screen_desktop)
+                    client_set_desktop(c, c->desktop+1, FALSE, TRUE);
+            }
+        }
+    }
+    else if (screen_num_desktops > 1) {
+        guint rmdesktop, movedesktop;
+        GList *it, *stacking_copy;
+
+        /* what desktop are we removing and moving to? */
+        if (o->current)
+            rmdesktop = screen_desktop;
+        else
+            rmdesktop = screen_num_desktops - 1;
+        if (rmdesktop < screen_num_desktops - 1)
+            movedesktop = rmdesktop + 1;
+        else
+            movedesktop = rmdesktop;
+
+        /* make a copy of the list cuz we're changing it */
+        stacking_copy = g_list_copy(stacking_list);
+        for (it = g_list_last(stacking_copy); it; it = g_list_previous(it)) {
+            if (WINDOW_IS_CLIENT(it->data)) {
+                ObClient *c = it->data;
+                guint d = c->desktop;
+                if (d != DESKTOP_ALL && d >= movedesktop) {
+                    client_set_desktop(c, c->desktop - 1, TRUE, TRUE);
+                    ob_debug("moving window %s\n", c->title);
+                }
+                /* raise all the windows that are on the current desktop which
+                   is being merged */
+                if ((screen_desktop == rmdesktop - 1 ||
+                     screen_desktop == rmdesktop) &&
+                    (d == DESKTOP_ALL || d == screen_desktop))
+                {
+                    stacking_raise(CLIENT_AS_WINDOW(c));
+                    ob_debug("raising window %s\n", c->title);
+                }
+            }
+        }
+
+        /* act like we're changing desktops */
+        if (screen_desktop < screen_num_desktops - 1) {
+            gint d = screen_desktop;
+            screen_desktop = screen_last_desktop;
+            screen_set_desktop(d, TRUE);
+            ob_debug("fake desktop change\n");
+        }
+
+        screen_set_num_desktops(screen_num_desktops-1);
+    }
+
+    actions_client_move(data, TRUE);
+
+    return FALSE;
+}
index 5610a48..4e35181 100644 (file)
@@ -35,4 +35,5 @@ void action_all_startup()
     action_desktop_startup();
     action_directionaldesktop_startup();
     action_resizerelative_startup();
+    action_addremovedesktop_startup();
 }
index 9a940d4..2919463 100644 (file)
@@ -36,5 +36,6 @@ void action_decorations_startup();
 void action_desktop_startup();
 void action_directionaldesktop_startup();
 void action_resizerelative_startup();
+void action_addremovedesktop_startup();
 
 #endif