]> Dogcows Code - chaz/openbox/blobdiff - openbox/actions/movetofromedge.c
add moveto/fromedge actions
[chaz/openbox] / openbox / actions / movetofromedge.c
diff --git a/openbox/actions/movetofromedge.c b/openbox/actions/movetofromedge.c
new file mode 100644 (file)
index 0000000..72a89c1
--- /dev/null
@@ -0,0 +1,125 @@
+#include "openbox/actions.h"
+#include "openbox/misc.h"
+#include "openbox/client.h"
+#include "openbox/frame.h"
+#include <glib.h>
+
+typedef struct {
+    ObDirection dir;
+    gboolean hang;
+} Options;
+
+static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_to_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
+static gpointer setup_from_func(ObParseInst *i,xmlDocPtr doc, xmlNodePtr node);
+static void     free_func(gpointer options);
+static gboolean run_func(ObActionsData *data, gpointer options);
+
+void action_movetofromedge_startup()
+{
+    actions_register("MoveToEdge",
+                     setup_to_func,
+                     free_func,
+                     run_func,
+                     NULL, NULL);
+    actions_register("MoveFromEdge",
+                     setup_from_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);
+    o->dir = OB_DIRECTION_NORTH;
+
+    if ((n = parse_find_node("direction", node))) {
+        gchar *s = parse_string(doc, n);
+        if (!g_ascii_strcasecmp(s, "north") ||
+            !g_ascii_strcasecmp(s, "up"))
+            o->dir = OB_DIRECTION_NORTH;
+        else if (!g_ascii_strcasecmp(s, "south") ||
+                 !g_ascii_strcasecmp(s, "down"))
+            o->dir = OB_DIRECTION_SOUTH;
+        else if (!g_ascii_strcasecmp(s, "west") ||
+                 !g_ascii_strcasecmp(s, "left"))
+            o->dir = OB_DIRECTION_WEST;
+        else if (!g_ascii_strcasecmp(s, "east") ||
+                 !g_ascii_strcasecmp(s, "right"))
+            o->dir = OB_DIRECTION_EAST;
+        g_free(s);
+    }
+
+    return o;
+}
+
+static gpointer setup_to_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->hang = FALSE;
+    return o;
+}
+
+static gpointer setup_from_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
+{
+    Options *o = setup_func(i, doc, node);
+    o->hang = TRUE;
+    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;
+
+    if (data->client) {
+        gint x, y;
+        ObClient *c = data->client;
+
+        x = c->frame->area.x;
+        y = c->frame->area.y;
+    
+        switch(o->dir) {
+        case OB_DIRECTION_NORTH:
+            y = client_directional_edge_search(c, OB_DIRECTION_NORTH,
+                                               o->hang)
+                - (o->hang ? c->frame->area.height : 0);
+            break;
+        case OB_DIRECTION_WEST:
+            x = client_directional_edge_search(c, OB_DIRECTION_WEST,
+                                               o->hang)
+                - (o->hang ? c->frame->area.width : 0);
+            break;
+        case OB_DIRECTION_SOUTH:
+            y = client_directional_edge_search(c, OB_DIRECTION_SOUTH,
+                                               o->hang)
+                - (o->hang ? 0 : c->frame->area.height);
+            break;
+        case OB_DIRECTION_EAST:
+            x = client_directional_edge_search(c, OB_DIRECTION_EAST,
+                                               o->hang)
+                - (o->hang ? 0 : c->frame->area.width);
+            break;
+        default:
+            g_assert_not_reached();
+        }
+        frame_frame_gravity(c->frame, &x, &y);
+
+        actions_client_move(data, FALSE);
+        client_move(c, x, y);
+        actions_client_move(data, TRUE);
+    }
+
+    return FALSE;
+}
This page took 0.021938 seconds and 4 git commands to generate.