Fix negative ResizeRelative values with terminal windows (Fix bug 5228)
[dana/openbox.git] / openbox / actions / maximize.c
1 #include "openbox/actions.h"
2 #include "openbox/client.h"
3
4 /* These match the values for client_maximize */
5 typedef enum {
6     BOTH = 0,
7     HORZ = 1,
8     VERT = 2
9 } MaxDirection;
10
11 typedef struct {
12     MaxDirection dir;
13 } Options;
14
15 static gpointer setup_func(xmlNodePtr node);
16 static void free_func(gpointer o);
17 static gboolean run_func_on(ObActionsData *data, gpointer options);
18 static gboolean run_func_off(ObActionsData *data, gpointer options);
19 static gboolean run_func_toggle(ObActionsData *data, gpointer options);
20 /* 3.4-compatibility */
21 static gpointer setup_both_func(xmlNodePtr node);
22 static gpointer setup_horz_func(xmlNodePtr node);
23 static gpointer setup_vert_func(xmlNodePtr node);
24
25 void action_maximize_startup(void)
26 {
27     actions_register("Maximize", setup_func, free_func, run_func_on);
28     actions_register("Unmaximize", setup_func, free_func, run_func_off);
29     actions_register("ToggleMaximize", setup_func, free_func, run_func_toggle);
30     /* 3.4-compatibility */
31     actions_register("MaximizeFull", setup_both_func, free_func,
32                      run_func_on);
33     actions_register("UnmaximizeFull", setup_both_func, free_func,
34                      run_func_off);
35     actions_register("ToggleMaximizeFull", setup_both_func, free_func,
36                      run_func_toggle);
37     actions_register("MaximizeHorz", setup_horz_func, free_func,
38                      run_func_on);
39     actions_register("UnmaximizeHorz", setup_horz_func, free_func,
40                      run_func_off);
41     actions_register("ToggleMaximizeHorz", setup_horz_func, free_func,
42                      run_func_toggle);
43     actions_register("MaximizeVert", setup_vert_func, free_func,
44                      run_func_on);
45     actions_register("UnmaximizeVert", setup_vert_func, free_func,
46                      run_func_off);
47     actions_register("ToggleMaximizeVert", setup_vert_func, free_func,
48                      run_func_toggle);
49 }
50
51 static gpointer setup_func(xmlNodePtr node)
52 {
53     xmlNodePtr n;
54     Options *o;
55
56     o = g_slice_new0(Options);
57     o->dir = BOTH;
58
59     if ((n = obt_xml_find_node(node, "direction"))) {
60         gchar *s = obt_xml_node_string(n);
61         if (!g_ascii_strcasecmp(s, "vertical") ||
62             !g_ascii_strcasecmp(s, "vert"))
63             o->dir = VERT;
64         else if (!g_ascii_strcasecmp(s, "horizontal") ||
65                  !g_ascii_strcasecmp(s, "horz"))
66             o->dir = HORZ;
67         g_free(s);
68     }
69
70     return o;
71 }
72
73 static void free_func(gpointer o)
74 {
75     g_slice_free(Options, o);
76 }
77
78 /* Always return FALSE because its not interactive */
79 static gboolean run_func_on(ObActionsData *data, gpointer options)
80 {
81     Options *o = options;
82     if (data->client) {
83         actions_client_move(data, TRUE);
84         client_maximize(data->client, TRUE, o->dir);
85         actions_client_move(data, FALSE);
86     }
87     return FALSE;
88 }
89
90 /* Always return FALSE because its not interactive */
91 static gboolean run_func_off(ObActionsData *data, gpointer options)
92 {
93     Options *o = options;
94     if (data->client) {
95         actions_client_move(data, TRUE);
96         client_maximize(data->client, FALSE, o->dir);
97         actions_client_move(data, FALSE);
98     }
99     return FALSE;
100 }
101
102 /* Always return FALSE because its not interactive */
103 static gboolean run_func_toggle(ObActionsData *data, gpointer options)
104 {
105     Options *o = options;
106     if (data->client) {
107         gboolean toggle;
108         actions_client_move(data, TRUE);
109         toggle = ((o->dir == HORZ && !data->client->max_horz) ||
110                   (o->dir == VERT && !data->client->max_vert) ||
111                   (o->dir == BOTH &&
112                    !(data->client->max_horz && data->client->max_vert)));
113         client_maximize(data->client, toggle, o->dir);
114         actions_client_move(data, FALSE);
115     }
116     return FALSE;
117 }
118
119 /* 3.4-compatibility */
120 static gpointer setup_both_func(xmlNodePtr node)
121 {
122     Options *o = g_slice_new0(Options);
123     o->dir = BOTH;
124     return o;
125 }
126
127 static gpointer setup_horz_func(xmlNodePtr node)
128 {
129     Options *o = g_slice_new0(Options);
130     o->dir = HORZ;
131     return o;
132 }
133
134 static gpointer setup_vert_func(xmlNodePtr node)
135 {
136     Options *o = g_slice_new0(Options);
137     o->dir = VERT;
138     return o;
139 }
140