]> icculus.org git repositories - mikachu/openbox.git/blob - openbox/actions/growtoedge.c
changes for the 3.4 branch from master (svn trunk)
[mikachu/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 gpointer setup_north_func(ObParseInst *i,
14                                  xmlDocPtr doc, xmlNodePtr node);
15 static gpointer setup_south_func(ObParseInst *i,
16                                  xmlDocPtr doc, xmlNodePtr node);
17 static gpointer setup_east_func(ObParseInst *i,
18                                 xmlDocPtr doc, xmlNodePtr node);
19 static gpointer setup_west_func(ObParseInst *i,
20                                 xmlDocPtr doc, xmlNodePtr node);
21 static void     free_func(gpointer options);
22 static gboolean run_func(ObActionsData *data, gpointer options);
23
24 void action_growtoedge_startup()
25 {
26     actions_register("GrowToEdge",
27                      setup_func,
28                      free_func,
29                      run_func,
30                      NULL, NULL);
31     actions_register("GrowToEdgeNorth",
32                      setup_north_func,
33                      free_func,
34                      run_func,
35                      NULL, NULL);
36     actions_register("GrowToEdgeSouth",
37                      setup_south_func,
38                      free_func,
39                      run_func,
40                      NULL, NULL);
41     actions_register("GrowToEdgeEast",
42                      setup_east_func,
43                      free_func,
44                      run_func,
45                      NULL, NULL);
46     actions_register("GrowToEdgeWest",
47                      setup_west_func,
48                      free_func,
49                      run_func,
50                      NULL, NULL);
51 }
52
53 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
54 {
55     xmlNodePtr n;
56     Options *o;
57
58     o = g_new0(Options, 1);
59     o->dir = OB_DIRECTION_NORTH;
60
61     if ((n = parse_find_node("direction", node))) {
62         gchar *s = parse_string(doc, n);
63         if (!g_ascii_strcasecmp(s, "north") ||
64             !g_ascii_strcasecmp(s, "up"))
65             o->dir = OB_DIRECTION_NORTH;
66         else if (!g_ascii_strcasecmp(s, "south") ||
67                  !g_ascii_strcasecmp(s, "down"))
68             o->dir = OB_DIRECTION_SOUTH;
69         else if (!g_ascii_strcasecmp(s, "west") ||
70                  !g_ascii_strcasecmp(s, "left"))
71             o->dir = OB_DIRECTION_WEST;
72         else if (!g_ascii_strcasecmp(s, "east") ||
73                  !g_ascii_strcasecmp(s, "right"))
74             o->dir = OB_DIRECTION_EAST;
75         g_free(s);
76     }
77
78     return o;
79 }
80
81 static gpointer setup_north_func(ObParseInst *i,
82                                  xmlDocPtr doc, xmlNodePtr node)
83 {
84     Options *o = g_new0(Options, 1);
85     o->dir = OB_DIRECTION_NORTH;
86     return o;
87 }
88
89 static gpointer setup_south_func(ObParseInst *i,
90                                  xmlDocPtr doc, xmlNodePtr node)
91 {
92     Options *o = g_new0(Options, 1);
93     o->dir = OB_DIRECTION_SOUTH;
94     return o;
95 }
96
97 static gpointer setup_east_func(ObParseInst *i,
98                                 xmlDocPtr doc, xmlNodePtr node)
99 {
100     Options *o = g_new0(Options, 1);
101     o->dir = OB_DIRECTION_EAST;
102     return o;
103 }
104
105 static gpointer setup_west_func(ObParseInst *i,
106                                 xmlDocPtr doc, xmlNodePtr node)
107 {
108     Options *o = g_new0(Options, 1);
109     o->dir = OB_DIRECTION_WEST;
110     return o;
111 }
112
113 static void free_func(gpointer options)
114 {
115     Options *o = options;
116
117     g_free(o);
118 }
119
120 /* Always return FALSE because its not interactive */
121 static gboolean run_func(ObActionsData *data, gpointer options)
122 {
123     Options *o = options;
124
125     if (data->client) {
126         gint x, y, w, h;
127
128         /* don't allow vertical resize if shaded */
129         if (o->dir != OB_DIRECTION_NORTH || o->dir != OB_DIRECTION_SOUTH ||
130             !data->client->shaded)
131         {
132             client_find_resize_directional(data->client, o->dir, TRUE,
133                                            &x, &y, &w, &h);
134             if (x != data->client->area.x || y != data->client->area.y ||
135                 w != data->client->area.width ||
136                 h != data->client->area.height)
137             {
138                 actions_client_move(data, TRUE);
139                 client_move_resize(data->client, x, y, w, h);
140                 actions_client_move(data, FALSE);
141             }
142         }
143     }
144
145     return FALSE;
146 }