]> icculus.org git repositories - dana/openbox.git/blob - openbox/actions/movetofromedge.c
debug print
[dana/openbox.git] / openbox / actions / movetofromedge.c
1 #include "openbox/actions.h"
2 #include "openbox/misc.h"
3 #include "openbox/client.h"
4 #include "openbox/frame.h"
5 #include <glib.h>
6
7 typedef struct {
8     ObDirection dir;
9     gboolean hang;
10 } Options;
11
12 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
13 static gpointer setup_to_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
14 static gpointer setup_from_func(ObParseInst *i,xmlDocPtr doc, xmlNodePtr node);
15 static void     free_func(gpointer options);
16 static gboolean run_func(ObActionsData *data, gpointer options);
17
18 void action_movetofromedge_startup()
19 {
20     actions_register("MoveToEdge",
21                      setup_to_func,
22                      free_func,
23                      run_func,
24                      NULL, NULL);
25     actions_register("MoveFromEdge",
26                      setup_from_func,
27                      free_func,
28                      run_func,
29                      NULL, NULL);
30 }
31
32 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
33 {
34     xmlNodePtr n;
35     Options *o;
36
37     o = g_new0(Options, 1);
38     o->dir = OB_DIRECTION_NORTH;
39
40     if ((n = parse_find_node("direction", node))) {
41         gchar *s = parse_string(doc, n);
42         if (!g_ascii_strcasecmp(s, "north") ||
43             !g_ascii_strcasecmp(s, "up"))
44             o->dir = OB_DIRECTION_NORTH;
45         else if (!g_ascii_strcasecmp(s, "south") ||
46                  !g_ascii_strcasecmp(s, "down"))
47             o->dir = OB_DIRECTION_SOUTH;
48         else if (!g_ascii_strcasecmp(s, "west") ||
49                  !g_ascii_strcasecmp(s, "left"))
50             o->dir = OB_DIRECTION_WEST;
51         else if (!g_ascii_strcasecmp(s, "east") ||
52                  !g_ascii_strcasecmp(s, "right"))
53             o->dir = OB_DIRECTION_EAST;
54         g_free(s);
55     }
56
57     return o;
58 }
59
60 static gpointer setup_to_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
61 {
62     Options *o = setup_func(i, doc, node);
63     o->hang = FALSE;
64     return o;
65 }
66
67 static gpointer setup_from_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
68 {
69     Options *o = setup_func(i, doc, node);
70     o->hang = TRUE;
71     return o;
72 }
73
74 static void free_func(gpointer options)
75 {
76     Options *o = options;
77
78     g_free(o);
79 }
80
81 /* Always return FALSE because its not interactive */
82 static gboolean run_func(ObActionsData *data, gpointer options)
83 {
84     Options *o = options;
85
86     if (data->client) {
87         gint x, y;
88         ObClient *c = data->client;
89
90         x = c->frame->area.x;
91         y = c->frame->area.y;
92     
93         switch(o->dir) {
94         case OB_DIRECTION_NORTH:
95             y = client_directional_edge_search(c, OB_DIRECTION_NORTH,
96                                                o->hang)
97                 - (o->hang ? c->frame->area.height : 0);
98             break;
99         case OB_DIRECTION_WEST:
100             x = client_directional_edge_search(c, OB_DIRECTION_WEST,
101                                                o->hang)
102                 - (o->hang ? c->frame->area.width : 0);
103             break;
104         case OB_DIRECTION_SOUTH:
105             y = client_directional_edge_search(c, OB_DIRECTION_SOUTH,
106                                                o->hang)
107                 - (o->hang ? 0 : c->frame->area.height);
108             break;
109         case OB_DIRECTION_EAST:
110             x = client_directional_edge_search(c, OB_DIRECTION_EAST,
111                                                o->hang)
112                 - (o->hang ? 0 : c->frame->area.width);
113             break;
114         default:
115             g_assert_not_reached();
116         }
117         frame_frame_gravity(c->frame, &x, &y);
118
119         actions_client_move(data, FALSE);
120         client_move(c, x, y);
121         actions_client_move(data, TRUE);
122     }
123
124     return FALSE;
125 }