]> Dogcows Code - chaz/openbox/blob - openbox/moveresize.c
add comment about the new code in moveresize for size increment windows
[chaz/openbox] / openbox / moveresize.c
1 #include "grab.h"
2 #include "framerender.h"
3 #include "screen.h"
4 #include "prop.h"
5 #include "client.h"
6 #include "frame.h"
7 #include "openbox.h"
8 #include "resist.h"
9 #include "popup.h"
10 #include "moveresize.h"
11 #include "config.h"
12 #include "render/render.h"
13 #include "render/theme.h"
14
15 #include <X11/Xlib.h>
16 #include <glib.h>
17
18 gboolean moveresize_in_progress = FALSE;
19 ObClient *moveresize_client = NULL;
20
21 static gboolean moving = FALSE; /* TRUE - moving, FALSE - resizing */
22
23 static int start_x, start_y, start_cx, start_cy, start_cw, start_ch;
24 static int cur_x, cur_y;
25 static guint button;
26 static guint32 corner;
27 static ObCorner lockcorner;
28
29 static Popup *popup = NULL;
30
31 #define POPUP_X (10)
32 #define POPUP_Y (10)
33
34 static void client_dest(ObClient *c)
35 {
36 if (moveresize_client == c)
37 moveresize_end(TRUE);
38 }
39
40 void moveresize_startup()
41 {
42 XSetWindowAttributes attrib;
43
44 popup = popup_new(FALSE);
45 popup_size_to_string(popup, "W: 0000 W: 0000");
46
47 attrib.save_under = True;
48
49 client_add_destructor(client_dest);
50 }
51
52 void moveresize_shutdown()
53 {
54 client_remove_destructor(client_dest);
55
56 popup_free(popup);
57 popup = NULL;
58 }
59
60 static void popup_coords(char *format, int a, int b)
61 {
62 char *text;
63 Rect *area;
64
65 text = g_strdup_printf(format, a, b);
66 area = screen_physical_area_monitor(0);
67 popup_position(popup, NorthWestGravity,
68 POPUP_X + area->x, POPUP_Y + area->y);
69 popup_show(popup, text, NULL);
70 g_free(text);
71 }
72
73 void moveresize_start(ObClient *c, int x, int y, guint b, guint32 cnr)
74 {
75 ObCursor cur;
76
77 g_assert(!moveresize_in_progress);
78
79 moveresize_client = c;
80 start_cx = c->frame->area.x;
81 start_cy = c->frame->area.y;
82 /* these adjustments for the size_inc make resizing a terminal more
83 friendly. you essentially start the resize in the middle of the
84 increment instead of at 0, so you have to move half an increment
85 either way instead of a full increment one and 1 px the other. and this
86 is one large mother fucking comment. */
87 start_cw = c->area.width + (c->size_inc.width + 1) / 2;
88 start_ch = c->area.height + (c->size_inc.height + 1) / 2;
89 start_x = x;
90 start_y = y;
91 corner = cnr;
92 button = b;
93
94 /*
95 have to change start_cx and start_cy if going to do this..
96 if (corner == prop_atoms.net_wm_moveresize_move_keyboard ||
97 corner == prop_atoms.net_wm_moveresize_size_keyboard)
98 XWarpPointer(ob_display, None, c->window, 0, 0, 0, 0,
99 c->area.width / 2, c->area.height / 2);
100 */
101
102 if (corner == prop_atoms.net_wm_moveresize_move ||
103 corner == prop_atoms.net_wm_moveresize_move_keyboard) {
104 cur_x = start_cx;
105 cur_y = start_cy;
106 moving = TRUE;
107 } else {
108 cur_x = start_cw;
109 cur_y = start_ch;
110 moving = FALSE;
111 }
112
113 moveresize_in_progress = TRUE;
114
115 if (corner == prop_atoms.net_wm_moveresize_size_topleft)
116 cur = OB_CURSOR_NORTHWEST;
117 else if (corner == prop_atoms.net_wm_moveresize_size_top)
118 cur = OB_CURSOR_NORTH;
119 else if (corner == prop_atoms.net_wm_moveresize_size_topright)
120 cur = OB_CURSOR_NORTHEAST;
121 else if (corner == prop_atoms.net_wm_moveresize_size_right)
122 cur = OB_CURSOR_EAST;
123 else if (corner == prop_atoms.net_wm_moveresize_size_bottomright)
124 cur = OB_CURSOR_SOUTHEAST;
125 else if (corner == prop_atoms.net_wm_moveresize_size_bottom)
126 cur = OB_CURSOR_SOUTH;
127 else if (corner == prop_atoms.net_wm_moveresize_size_bottomleft)
128 cur = OB_CURSOR_SOUTHWEST;
129 else if (corner == prop_atoms.net_wm_moveresize_size_left)
130 cur = OB_CURSOR_WEST;
131 else if (corner == prop_atoms.net_wm_moveresize_size_keyboard)
132 cur = OB_CURSOR_SOUTHEAST;
133 else if (corner == prop_atoms.net_wm_moveresize_move)
134 cur = OB_CURSOR_MOVE;
135 else if (corner == prop_atoms.net_wm_moveresize_move_keyboard)
136 cur = OB_CURSOR_MOVE;
137 else
138 g_assert_not_reached();
139
140 grab_pointer(TRUE, cur);
141 grab_keyboard(TRUE);
142 }
143
144 void moveresize_end(gboolean cancel)
145 {
146 grab_keyboard(FALSE);
147 grab_pointer(FALSE, None);
148
149 popup_hide(popup);
150
151 if (moving) {
152 client_move(moveresize_client,
153 (cancel ? start_cx : cur_x),
154 (cancel ? start_cy : cur_y));
155 } else {
156 client_configure(moveresize_client, lockcorner,
157 moveresize_client->area.x,
158 moveresize_client->area.y,
159 (cancel ? start_cw : cur_x),
160 (cancel ? start_ch : cur_y), TRUE, TRUE);
161 }
162
163 moveresize_in_progress = FALSE;
164 moveresize_client = NULL;
165 }
166
167 static void do_move(gboolean resist)
168 {
169 Rect *a;
170
171 if (resist)
172 resist_move_windows(moveresize_client, &cur_x, &cur_y);
173 resist_move_monitors(moveresize_client, &cur_x, &cur_y);
174
175 /* get where the client should be */
176 frame_frame_gravity(moveresize_client->frame, &cur_x, &cur_y);
177 client_configure(moveresize_client, OB_CORNER_TOPLEFT, cur_x, cur_y,
178 start_cw, start_ch, TRUE, FALSE);
179
180 /* this would be better with a fixed width font ... XXX can do it better
181 if there are 2 text boxes */
182 a = screen_area(screen_desktop);
183 popup_coords("X: %4d Y: %4d",
184 moveresize_client->frame->area.x - a->x,
185 moveresize_client->frame->area.y - a->y);
186 }
187
188 static void do_resize(gboolean resist)
189 {
190 /* resist_size_* needs the frame size */
191 cur_x += moveresize_client->frame->size.left +
192 moveresize_client->frame->size.right;
193 cur_y += moveresize_client->frame->size.top +
194 moveresize_client->frame->size.bottom;
195
196 if (resist)
197 resist_size_windows(moveresize_client, &cur_x, &cur_y, lockcorner);
198 resist_size_monitors(moveresize_client, &cur_x, &cur_y, lockcorner);
199
200 cur_x -= moveresize_client->frame->size.left +
201 moveresize_client->frame->size.right;
202 cur_y -= moveresize_client->frame->size.top +
203 moveresize_client->frame->size.bottom;
204
205 client_configure(moveresize_client, lockcorner,
206 moveresize_client->area.x, moveresize_client->area.y,
207 cur_x, cur_y, TRUE, FALSE);
208
209 /* this would be better with a fixed width font ... XXX can do it better
210 if there are 2 text boxes */
211 popup_coords("W: %4d H: %4d", moveresize_client->logical_size.width,
212 moveresize_client->logical_size.height);
213 }
214
215 void moveresize_event(XEvent *e)
216 {
217 g_assert(moveresize_in_progress);
218
219 if (e->type == ButtonPress) {
220 if (!button) {
221 start_x = e->xbutton.x_root;
222 start_y = e->xbutton.y_root;
223 button = e->xbutton.button; /* this will end it now */
224 }
225 } else if (e->type == ButtonRelease) {
226 if (!button || e->xbutton.button == button) {
227 moveresize_end(FALSE);
228 }
229 } else if (e->type == MotionNotify) {
230 if (moving) {
231 cur_x = start_cx + e->xmotion.x_root - start_x;
232 cur_y = start_cy + e->xmotion.y_root - start_y;
233 do_move(TRUE);
234 } else {
235 if (corner == prop_atoms.net_wm_moveresize_size_topleft) {
236 cur_x = start_cw - (e->xmotion.x_root - start_x);
237 cur_y = start_ch - (e->xmotion.y_root - start_y);
238 lockcorner = OB_CORNER_BOTTOMRIGHT;
239 } else if (corner == prop_atoms.net_wm_moveresize_size_top) {
240 cur_x = start_cw;
241 cur_y = start_ch - (e->xmotion.y_root - start_y);
242 lockcorner = OB_CORNER_BOTTOMRIGHT;
243 } else if (corner == prop_atoms.net_wm_moveresize_size_topright) {
244 cur_x = start_cw + (e->xmotion.x_root - start_x);
245 cur_y = start_ch - (e->xmotion.y_root - start_y);
246 lockcorner = OB_CORNER_BOTTOMLEFT;
247 } else if (corner == prop_atoms.net_wm_moveresize_size_right) {
248 cur_x = start_cw + (e->xmotion.x_root - start_x);
249 cur_y = start_ch;
250 lockcorner = OB_CORNER_BOTTOMLEFT;
251 } else if (corner ==
252 prop_atoms.net_wm_moveresize_size_bottomright) {
253 cur_x = start_cw + (e->xmotion.x_root - start_x);
254 cur_y = start_ch + (e->xmotion.y_root - start_y);
255 lockcorner = OB_CORNER_TOPLEFT;
256 } else if (corner == prop_atoms.net_wm_moveresize_size_bottom) {
257 cur_x = start_cw;
258 cur_y = start_ch + (e->xmotion.y_root - start_y);
259 lockcorner = OB_CORNER_TOPLEFT;
260 } else if (corner ==
261 prop_atoms.net_wm_moveresize_size_bottomleft) {
262 cur_x = start_cw - (e->xmotion.x_root - start_x);
263 cur_y = start_ch + (e->xmotion.y_root - start_y);
264 lockcorner = OB_CORNER_TOPRIGHT;
265 } else if (corner == prop_atoms.net_wm_moveresize_size_left) {
266 cur_x = start_cw - (e->xmotion.x_root - start_x);
267 cur_y = start_ch;
268 lockcorner = OB_CORNER_TOPRIGHT;
269 } else if (corner == prop_atoms.net_wm_moveresize_size_keyboard) {
270 cur_x = start_cw + (e->xmotion.x_root - start_x);
271 cur_y = start_ch + (e->xmotion.y_root - start_y);
272 lockcorner = OB_CORNER_TOPLEFT;
273 } else
274 g_assert_not_reached();
275
276 do_resize(TRUE);
277 }
278 } else if (e->type == KeyPress) {
279 if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE))
280 moveresize_end(TRUE);
281 else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN))
282 moveresize_end(FALSE);
283 else {
284 if (corner == prop_atoms.net_wm_moveresize_size_keyboard) {
285 int dx = 0, dy = 0;
286
287 if (e->xkey.keycode == ob_keycode(OB_KEY_RIGHT))
288 dx = MAX(4, moveresize_client->size_inc.width);
289 else if (e->xkey.keycode == ob_keycode(OB_KEY_LEFT))
290 dx = -MAX(4, moveresize_client->size_inc.width);
291 else if (e->xkey.keycode == ob_keycode(OB_KEY_DOWN))
292 dy = MAX(4, moveresize_client->size_inc.height);
293 else if (e->xkey.keycode == ob_keycode(OB_KEY_UP))
294 dy = -MAX(4, moveresize_client->size_inc.height);
295 else
296 return;
297
298 cur_x += dx;
299 cur_y += dy;
300 XWarpPointer(ob_display, None, None, 0, 0, 0, 0, dx, dy);
301
302 do_resize(FALSE);
303 } else if (corner == prop_atoms.net_wm_moveresize_move_keyboard) {
304 int dx = 0, dy = 0;
305
306 if (e->xkey.keycode == ob_keycode(OB_KEY_RIGHT))
307 dx = 4;
308 else if (e->xkey.keycode == ob_keycode(OB_KEY_LEFT))
309 dx = -4;
310 else if (e->xkey.keycode == ob_keycode(OB_KEY_DOWN))
311 dy = 4;
312 else if (e->xkey.keycode == ob_keycode(OB_KEY_UP))
313 dy = -4;
314 else
315 return;
316
317 cur_x += dx;
318 cur_y += dy;
319 XWarpPointer(ob_display, None, None, 0, 0, 0, 0, dx, dy);
320
321 do_move(FALSE);
322 }
323 }
324 }
325 }
This page took 0.052957 seconds and 5 git commands to generate.