1 #include "openbox/actions.h"
2 #include "openbox/prop.h"
3 #include "openbox/moveresize.h"
4 #include "openbox/client.h"
5 #include "openbox/frame.h"
11 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
12 static void free_func(gpointer options);
13 static gboolean run_func(ObActionsData *data, gpointer options);
15 static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch,
18 void action_resize_startup()
20 actions_register("Resize",
27 static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
32 o = g_new0(Options, 1);
34 if ((n = parse_find_node("edge", node))) {
35 gchar *s = parse_string(doc, n);
36 if (!g_ascii_strcasecmp(s, "top"))
37 o->corner = prop_atoms.net_wm_moveresize_size_top;
38 else if (!g_ascii_strcasecmp(s, "bottom"))
39 o->corner = prop_atoms.net_wm_moveresize_size_bottom;
40 else if (!g_ascii_strcasecmp(s, "left"))
41 o->corner = prop_atoms.net_wm_moveresize_size_left;
42 else if (!g_ascii_strcasecmp(s, "right"))
43 o->corner = prop_atoms.net_wm_moveresize_size_right;
44 else if (!g_ascii_strcasecmp(s, "topleft"))
45 o->corner = prop_atoms.net_wm_moveresize_size_topleft;
46 else if (!g_ascii_strcasecmp(s, "topright"))
47 o->corner = prop_atoms.net_wm_moveresize_size_topright;
48 else if (!g_ascii_strcasecmp(s, "bottomleft"))
49 o->corner = prop_atoms.net_wm_moveresize_size_bottomleft;
50 else if (!g_ascii_strcasecmp(s, "bottomright"))
51 o->corner = prop_atoms.net_wm_moveresize_size_bottomright;
57 static void free_func(gpointer options)
64 /* Always return FALSE because its not interactive */
65 static gboolean run_func(ObActionsData *data, gpointer options)
70 ObClient *c = data->client;
74 corner = prop_atoms.net_wm_moveresize_size_keyboard;
76 corner = o->corner; /* it was specified in the binding */
78 corner = pick_corner(data->x, data->y,
79 c->frame->area.x, c->frame->area.y,
80 /* use the client size because the frame
81 can be differently sized (shaded
82 windows) and we want this based on the
84 c->area.width + c->frame->size.left +
86 c->area.height + c->frame->size.top +
87 c->frame->size.bottom, c->shaded);
89 moveresize_start(c, data->x, data->y, data->button, corner);
95 static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch,
98 /* let's make x and y client relative instead of screen relative */
100 y = ch - (y - cy); /* y is inverted, 0 is at the bottom of the window */
103 #define A -4*X + 7*ch/3
104 #define B 4*X -15*ch/9
105 #define C -X/4 + 2*ch/3
106 #define D X/4 + 5*ch/12
108 #define F -X/4 + 7*ch/12
109 #define G 4*X - 4*ch/3
110 #define H -4*X + 8*ch/3
111 #define a (y > 5*ch/9)
112 #define b (x < 4*cw/9)
113 #define c (x > 5*cw/9)
114 #define d (y < 4*ch/9)
117 Each of these defines (except X which is just there for fun), represents
118 the equation of a line. The lines they represent are shown in the diagram
119 below. Checking y against these lines, we are able to choose a region
120 of the window as shown.
122 +---------------------A-------|-------|-------B---------------------+
129 | northwest | A north B | northeast |
132 C---------------------+----A--+-------+--B----+---------------------D
133 |CCCCCCC | A B | DDDDDDD|
134 | CCCCCCCC | A | | B | DDDDDDDD |
135 | CCCCCCC A B DDDDDDD |
136 - - - - - - - - - - - +CCCCCCC+aaaaaaa+DDDDDDD+ - - - - - - - - - - - -
138 | west | b move c | east | ad
140 - - - - - - - - - - - +EEEEEEE+ddddddd+FFFFFFF+- - - - - - - - - - - -
141 | EEEEEEE G H FFFFFFF |
142 | EEEEEEEE | G | | H | FFFFFFFF |
143 |EEEEEEE | G H | FFFFFFF|
144 E---------------------+----G--+-------+--H----+---------------------F
147 | southwest | G south H | southeast |
154 +---------------------G-------|-------|-------H---------------------+
158 /* for shaded windows, you can only resize west/east and move */
160 return prop_atoms.net_wm_moveresize_size_left;
162 return prop_atoms.net_wm_moveresize_size_right;
163 return prop_atoms.net_wm_moveresize_move;
167 return prop_atoms.net_wm_moveresize_size_topleft;
168 else if (y >= A && y >= B && a)
169 return prop_atoms.net_wm_moveresize_size_top;
170 else if (y < B && y >= D)
171 return prop_atoms.net_wm_moveresize_size_topright;
172 else if (y < C && y >= E && b)
173 return prop_atoms.net_wm_moveresize_size_left;
174 else if (y < D && y >= F && c)
175 return prop_atoms.net_wm_moveresize_size_right;
176 else if (y < E && y >= G)
177 return prop_atoms.net_wm_moveresize_size_bottomleft;
178 else if (y < G && y < H && d)
179 return prop_atoms.net_wm_moveresize_size_bottom;
180 else if (y >= H && y < F)
181 return prop_atoms.net_wm_moveresize_size_bottomright;
183 return prop_atoms.net_wm_moveresize_move;