rewrote the movetoedge code so it works with both types of edges (to edge and from...
[dana/openbox.git] / openbox / actions / growtoedge.c
1 #include "openbox/actions.h"
2 #include "openbox/misc.h"
3 #include "openbox/client.h"
4 #include "openbox/frame.h"
5 #include "openbox/screen.h"
6 #include <glib.h>
7
8 typedef struct {
9     ObDirection dir;
10 } Options;
11
12 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
13 static void     free_func(gpointer options);
14 static gboolean run_func(ObActionsData *data, gpointer options);
15
16 void action_growtoedge_startup()
17 {
18     actions_register("GrowToEdge",
19                      setup_func,
20                      free_func,
21                      run_func,
22                      NULL, NULL);
23 }
24
25 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
26 {
27     xmlNodePtr n;
28     Options *o;
29
30     o = g_new0(Options, 1);
31     o->dir = OB_DIRECTION_NORTH;
32
33     if ((n = parse_find_node("direction", node))) {
34         gchar *s = parse_string(doc, n);
35         if (!g_ascii_strcasecmp(s, "north") ||
36             !g_ascii_strcasecmp(s, "up"))
37             o->dir = OB_DIRECTION_NORTH;
38         else if (!g_ascii_strcasecmp(s, "south") ||
39                  !g_ascii_strcasecmp(s, "down"))
40             o->dir = OB_DIRECTION_SOUTH;
41         else if (!g_ascii_strcasecmp(s, "west") ||
42                  !g_ascii_strcasecmp(s, "left"))
43             o->dir = OB_DIRECTION_WEST;
44         else if (!g_ascii_strcasecmp(s, "east") ||
45                  !g_ascii_strcasecmp(s, "right"))
46             o->dir = OB_DIRECTION_EAST;
47         g_free(s);
48     }
49
50     return o;
51 }
52
53 static void free_func(gpointer options)
54 {
55     Options *o = options;
56
57     g_free(o);
58 }
59
60 /* Always return FALSE because its not interactive */
61 static gboolean run_func(ObActionsData *data, gpointer options)
62 {
63     Options *o = options;
64
65     if (data->client) {
66         gint x, y, width, height, dest;
67         ObClient *c = data->client;
68         Rect *a;
69
70         a = screen_area(c->desktop, SCREEN_AREA_ALL_MONITORS, &c->frame->area);
71         x = c->frame->area.x;
72         y = c->frame->area.y;
73         /* get the unshaded frame's dimensions..if it is shaded */
74         width = c->area.width + c->frame->size.left + c->frame->size.right;
75         height = c->area.height + c->frame->size.top + c->frame->size.bottom;
76
77 #if 0
78         dest = client_directional_edge_search(c, o->dir);
79
80         switch(o->dir) {
81         case OB_DIRECTION_NORTH:
82             if (c->shaded) break; /* don't allow vertical resize if shaded */
83
84             if (a->y == y)
85                 height = height / 2;
86             else {
87                 height = c->frame->area.y + height - dest;
88                 y = dest;
89             }
90             break;
91         case OB_DIRECTION_WEST:
92             if (a->x == x)
93                 width = width / 2;
94             else {
95                 width = c->frame->area.x + width - dest;
96                 x = dest;
97             }
98             break;
99         case OB_DIRECTION_SOUTH:
100             if (c->shaded) break; /* don't allow vertical resize if shaded */
101
102             if (a->y + a->height == y + c->frame->area.height) {
103                 height = c->frame->area.height / 2;
104                 y = a->y + a->height - height;
105             } else
106                 height = dest - c->frame->area.y;
107             y += (height - c->frame->area.height) % c->size_inc.height;
108             height -= (height - c->frame->area.height) % c->size_inc.height;
109             break;
110         case OB_DIRECTION_EAST:
111             if (a->x + a->width == x + c->frame->area.width) {
112                 width = c->frame->area.width / 2;
113                 x = a->x + a->width - width;
114             } else
115                 width = dest - c->frame->area.x;
116             x += (width - c->frame->area.width) % c->size_inc.width;
117             width -= (width - c->frame->area.width) % c->size_inc.width;
118             break;
119         default:
120             g_assert_not_reached();
121         }
122
123         width -= c->frame->size.left + c->frame->size.right;
124         height -= c->frame->size.top + c->frame->size.bottom;
125         frame_frame_gravity(c->frame, &x, &y);
126
127         actions_client_move(data, FALSE);
128         client_move_resize(c, x, y, width, height);
129         actions_client_move(data, TRUE);
130
131 #endif
132         g_free(a);
133     }
134
135     return FALSE;
136 }