]> Dogcows Code - chaz/openbox/blob - openbox/moveresize.c
move keyboard moving into its own function
[chaz/openbox] / openbox / moveresize.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3 moveresize.c for the Openbox window manager
4 Copyright (c) 2006 Mikael Magnusson
5 Copyright (c) 2003-2007 Dana Jansens
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 See the COPYING file for a copy of the GNU General Public License.
18 */
19
20 #include "grab.h"
21 #include "framerender.h"
22 #include "screen.h"
23 #include "prop.h"
24 #include "client.h"
25 #include "frame.h"
26 #include "openbox.h"
27 #include "resist.h"
28 #include "mainloop.h"
29 #include "modkeys.h"
30 #include "popup.h"
31 #include "moveresize.h"
32 #include "config.h"
33 #include "event.h"
34 #include "debug.h"
35 #include "extensions.h"
36 #include "render/render.h"
37 #include "render/theme.h"
38
39 #include <X11/Xlib.h>
40 #include <glib.h>
41
42 /* how far windows move and resize with the keyboard arrows */
43 #define KEY_DIST 8
44
45 gboolean moveresize_in_progress = FALSE;
46 ObClient *moveresize_client = NULL;
47 #ifdef SYNC
48 XSyncAlarm moveresize_alarm = None;
49 #endif
50
51 static gboolean moving = FALSE; /* TRUE - moving, FALSE - resizing */
52
53 static gint start_x, start_y, start_cx, start_cy, start_cw, start_ch;
54 static gint cur_x, cur_y;
55 static guint button;
56 static guint32 corner;
57 static ObCorner lockcorner;
58 static ObDirection edge_warp_dir = -1;
59 #ifdef SYNC
60 static gboolean waiting_for_sync;
61 #endif
62
63 static ObPopup *popup = NULL;
64
65 static void do_edge_warp(gint x, gint y);
66 static void cancel_edge_warp();
67
68 static void client_dest(ObClient *client, gpointer data)
69 {
70 if (moveresize_client == client)
71 moveresize_end(TRUE);
72 }
73
74 void moveresize_startup(gboolean reconfig)
75 {
76 popup = popup_new(FALSE);
77 popup_set_text_align(popup, RR_JUSTIFY_CENTER);
78
79 if (!reconfig)
80 client_add_destroy_notify(client_dest, NULL);
81 }
82
83 void moveresize_shutdown(gboolean reconfig)
84 {
85 if (!reconfig) {
86 if (moveresize_in_progress)
87 moveresize_end(FALSE);
88 client_remove_destroy_notify(client_dest);
89 }
90
91 popup_free(popup);
92 popup = NULL;
93 }
94
95 static void get_resize_position(gint *x, gint *y, gboolean cancel)
96 {
97 gint dw, dh;
98 gint w, h, lw, lh;
99
100 *x = moveresize_client->frame->area.x;
101 *y = moveresize_client->frame->area.y;
102
103 if (cancel) {
104 w = start_cw;
105 h = start_ch;
106 } else {
107 w = cur_x;
108 h = cur_y;
109 }
110
111 /* see how much it is actually going to resize */
112 {
113 gint cx = *x, cy = *y;
114 frame_frame_gravity(moveresize_client->frame, &cx, &cy);
115 client_try_configure(moveresize_client, &cx, &cy, &w, &h,
116 &lw, &lh, TRUE);
117 }
118 dw = w - moveresize_client->area.width;
119 dh = h - moveresize_client->area.height;
120
121 switch (lockcorner) {
122 case OB_CORNER_TOPLEFT:
123 break;
124 case OB_CORNER_TOPRIGHT:
125 *x -= dw;
126 break;
127 case OB_CORNER_BOTTOMLEFT:
128 *y -= dh;
129 break;
130 case OB_CORNER_BOTTOMRIGHT:
131 *x -= dw;
132 *y -= dh;
133 break;
134 }
135
136 frame_frame_gravity(moveresize_client->frame, x, y);
137 }
138
139 static void popup_coords(ObClient *c, const gchar *format, gint a, gint b)
140 {
141 gchar *text;
142
143 text = g_strdup_printf(format, a, b);
144 if (config_resize_popup_pos == 1) /* == "Top" */
145 popup_position(popup, SouthGravity,
146 c->frame->area.x
147 + c->frame->area.width/2,
148 c->frame->area.y - ob_rr_theme->fbwidth);
149 else /* == "Center" */
150 popup_position(popup, CenterGravity,
151 c->frame->area.x + c->frame->size.left +
152 c->area.width / 2,
153 c->frame->area.y + c->frame->size.top +
154 c->area.height / 2);
155 popup_show(popup, text);
156 g_free(text);
157 }
158
159 void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr)
160 {
161 ObCursor cur;
162 gboolean mv = (cnr == prop_atoms.net_wm_moveresize_move ||
163 cnr == prop_atoms.net_wm_moveresize_move_keyboard);
164
165 if (moveresize_in_progress || !c->frame->visible ||
166 !(mv ?
167 (c->functions & OB_CLIENT_FUNC_MOVE) :
168 (c->functions & OB_CLIENT_FUNC_RESIZE)))
169 return;
170
171 if (cnr == prop_atoms.net_wm_moveresize_size_topleft)
172 cur = OB_CURSOR_NORTHWEST;
173 else if (cnr == prop_atoms.net_wm_moveresize_size_top)
174 cur = OB_CURSOR_NORTH;
175 else if (cnr == prop_atoms.net_wm_moveresize_size_topright)
176 cur = OB_CURSOR_NORTHEAST;
177 else if (cnr == prop_atoms.net_wm_moveresize_size_right)
178 cur = OB_CURSOR_EAST;
179 else if (cnr == prop_atoms.net_wm_moveresize_size_bottomright)
180 cur = OB_CURSOR_SOUTHEAST;
181 else if (cnr == prop_atoms.net_wm_moveresize_size_bottom)
182 cur = OB_CURSOR_SOUTH;
183 else if (cnr == prop_atoms.net_wm_moveresize_size_bottomleft)
184 cur = OB_CURSOR_SOUTHWEST;
185 else if (cnr == prop_atoms.net_wm_moveresize_size_left)
186 cur = OB_CURSOR_WEST;
187 else if (cnr == prop_atoms.net_wm_moveresize_size_keyboard)
188 cur = OB_CURSOR_SOUTHEAST;
189 else if (cnr == prop_atoms.net_wm_moveresize_move)
190 cur = OB_CURSOR_MOVE;
191 else if (cnr == prop_atoms.net_wm_moveresize_move_keyboard)
192 cur = OB_CURSOR_MOVE;
193 else
194 g_assert_not_reached();
195
196 /* keep the pointer bounded to the screen for move/resize */
197 if (!grab_pointer(FALSE, TRUE, cur))
198 return;
199 if (!grab_keyboard()) {
200 ungrab_pointer();
201 return;
202 }
203
204 frame_end_iconify_animation(c->frame);
205
206 moving = mv;
207 moveresize_client = c;
208 start_cx = c->area.x;
209 start_cy = c->area.y;
210 /* these adjustments for the size_inc make resizing a terminal more
211 friendly. you essentially start the resize in the middle of the
212 increment instead of at 0, so you have to move half an increment
213 either way instead of a full increment one and 1 px the other. and this
214 is one large mother fucking comment. */
215 start_cw = c->area.width + c->size_inc.width / 2;
216 start_ch = c->area.height + c->size_inc.height / 2;
217 start_x = x;
218 start_y = y;
219 corner = cnr;
220 button = b;
221
222 /*
223 have to change start_cx and start_cy if going to do this..
224 if (corner == prop_atoms.net_wm_moveresize_move_keyboard ||
225 corner == prop_atoms.net_wm_moveresize_size_keyboard)
226 XWarpPointer(ob_display, None, c->window, 0, 0, 0, 0,
227 c->area.width / 2, c->area.height / 2);
228 */
229
230 if (moving) {
231 cur_x = start_cx;
232 cur_y = start_cy;
233 } else {
234 cur_x = start_cw;
235 cur_y = start_ch;
236 }
237
238 moveresize_in_progress = TRUE;
239
240 #ifdef SYNC
241 if (config_resize_redraw && !moving && extensions_shape &&
242 moveresize_client->sync_request && moveresize_client->sync_counter)
243 {
244 /* Initialize values for the resize syncing, and create an alarm for
245 the client's xsync counter */
246
247 XSyncValue val;
248 XSyncAlarmAttributes aa;
249
250 /* set the counter to an initial value */
251 XSyncIntToValue(&val, 0);
252 XSyncSetCounter(ob_display, moveresize_client->sync_counter, val);
253
254 /* this will be incremented when we tell the client what we're
255 looking for */
256 moveresize_client->sync_counter_value = 0;
257
258 /* the next sequence we're waiting for with the alarm */
259 XSyncIntToValue(&val, 1);
260
261 /* set an alarm on the counter */
262 aa.trigger.counter = moveresize_client->sync_counter;
263 aa.trigger.wait_value = val;
264 aa.trigger.value_type = XSyncAbsolute;
265 aa.trigger.test_type = XSyncPositiveTransition;
266 aa.events = True;
267 XSyncIntToValue(&aa.delta, 1);
268 moveresize_alarm = XSyncCreateAlarm(ob_display,
269 XSyncCACounter |
270 XSyncCAValue |
271 XSyncCAValueType |
272 XSyncCATestType |
273 XSyncCADelta |
274 XSyncCAEvents,
275 &aa);
276
277 waiting_for_sync = FALSE;
278 }
279 #endif
280 }
281
282 void moveresize_end(gboolean cancel)
283 {
284 gint x, y;
285
286 ungrab_keyboard();
287 ungrab_pointer();
288
289 popup_hide(popup);
290
291 if (moving) {
292 client_move(moveresize_client,
293 (cancel ? start_cx : cur_x),
294 (cancel ? start_cy : cur_y));
295 } else {
296 #ifdef SYNC
297 /* turn off the alarm */
298 if (moveresize_alarm != None) {
299 XSyncDestroyAlarm(ob_display, moveresize_alarm);
300 moveresize_alarm = None;
301 }
302 #endif
303
304 get_resize_position(&x, &y, cancel);
305 client_configure(moveresize_client, x, y,
306 (cancel ? start_cw : cur_x),
307 (cancel ? start_ch : cur_y),
308 TRUE, TRUE, FALSE);
309 }
310
311 /* dont edge warp after its ended */
312 cancel_edge_warp();
313
314 moveresize_in_progress = FALSE;
315 moveresize_client = NULL;
316 }
317
318 static void do_move(gboolean keyboard, gint keydist)
319 {
320 gint resist;
321
322 if (keyboard) resist = keydist - 1; /* resist for one key press */
323 else resist = config_resist_win;
324 resist_move_windows(moveresize_client, resist, &cur_x, &cur_y);
325 if (!keyboard) resist = config_resist_edge;
326 resist_move_monitors(moveresize_client, resist, &cur_x, &cur_y);
327
328 client_configure(moveresize_client, cur_x, cur_y,
329 moveresize_client->area.width,
330 moveresize_client->area.height,
331 TRUE, FALSE, FALSE);
332 if (config_resize_popup_show == 2) /* == "Always" */
333 popup_coords(moveresize_client, "%d x %d",
334 moveresize_client->frame->area.x,
335 moveresize_client->frame->area.y);
336 }
337
338 static void do_resize()
339 {
340 gint x, y, w, h, lw, lh;
341
342 /* see if it is actually going to resize */
343 x = 0;
344 y = 0;
345 w = cur_x;
346 h = cur_y;
347 client_try_configure(moveresize_client, &x, &y, &w, &h,
348 &lw, &lh, TRUE);
349 if (w == moveresize_client->area.width &&
350 h == moveresize_client->area.height)
351 {
352 return;
353 }
354
355 #ifdef SYNC
356 if (config_resize_redraw && extensions_sync &&
357 moveresize_client->sync_request && moveresize_client->sync_counter)
358 {
359 XEvent ce;
360 XSyncValue val;
361
362 /* are we already waiting for the sync counter to catch up? */
363 if (waiting_for_sync)
364 return;
365
366 /* increment the value we're waiting for */
367 ++moveresize_client->sync_counter_value;
368 XSyncIntToValue(&val, moveresize_client->sync_counter_value);
369
370 /* tell the client what we're waiting for */
371 ce.xclient.type = ClientMessage;
372 ce.xclient.message_type = prop_atoms.wm_protocols;
373 ce.xclient.display = ob_display;
374 ce.xclient.window = moveresize_client->window;
375 ce.xclient.format = 32;
376 ce.xclient.data.l[0] = prop_atoms.net_wm_sync_request;
377 ce.xclient.data.l[1] = event_curtime;
378 ce.xclient.data.l[2] = XSyncValueLow32(val);
379 ce.xclient.data.l[3] = XSyncValueHigh32(val);
380 ce.xclient.data.l[4] = 0l;
381 XSendEvent(ob_display, moveresize_client->window, FALSE,
382 NoEventMask, &ce);
383
384 waiting_for_sync = TRUE;
385 }
386 #endif
387
388 get_resize_position(&x, &y, FALSE);
389 client_configure(moveresize_client, x, y, cur_x, cur_y, TRUE, FALSE, FALSE);
390
391 /* this would be better with a fixed width font ... XXX can do it better
392 if there are 2 text boxes */
393 if (config_resize_popup_show == 2 || /* == "Always" */
394 (config_resize_popup_show == 1 && /* == "Nonpixel" */
395 moveresize_client->size_inc.width > 1 &&
396 moveresize_client->size_inc.height > 1))
397 popup_coords(moveresize_client, "%d x %d",
398 moveresize_client->logical_size.width,
399 moveresize_client->logical_size.height);
400 }
401
402 static void calc_resize(gboolean keyboard)
403 {
404 gint resist;
405
406 /* resist_size_* needs the frame size */
407 cur_x += moveresize_client->frame->size.left +
408 moveresize_client->frame->size.right;
409 cur_y += moveresize_client->frame->size.top +
410 moveresize_client->frame->size.bottom;
411
412 if (keyboard) resist = KEY_DIST - 1; /* resist for one key press */
413 else resist = config_resist_win;
414 resist_size_windows(moveresize_client, resist, &cur_x, &cur_y, lockcorner);
415 if (!keyboard) resist = config_resist_edge;
416 resist_size_monitors(moveresize_client, resist, &cur_x, &cur_y,lockcorner);
417
418 cur_x -= moveresize_client->frame->size.left +
419 moveresize_client->frame->size.right;
420 cur_y -= moveresize_client->frame->size.top +
421 moveresize_client->frame->size.bottom;
422 }
423
424 static gboolean edge_warp_delay_func(gpointer data)
425 {
426 guint d;
427
428 d = screen_find_desktop(screen_desktop, edge_warp_dir, TRUE, FALSE);
429 if (d != screen_desktop) screen_set_desktop(d, TRUE);
430
431 edge_warp_dir = -1;
432
433 return FALSE; /* don't repeat */
434 }
435
436 static void do_edge_warp(gint x, gint y)
437 {
438 guint i;
439 ObDirection dir;
440
441 if (!config_mouse_screenedgetime) return;
442
443 dir = -1;
444
445 for (i = 0; i < screen_num_monitors; ++i) {
446 Rect *a = screen_physical_area_monitor(i);
447 if (x == RECT_LEFT(*a)) dir = OB_DIRECTION_WEST;
448 if (x == RECT_RIGHT(*a)) dir = OB_DIRECTION_EAST;
449 if (y == RECT_TOP(*a)) dir = OB_DIRECTION_NORTH;
450 if (y == RECT_BOTTOM(*a)) dir = OB_DIRECTION_SOUTH;
451
452 /* try check for xinerama boundaries */
453 if ((x + 1 == RECT_LEFT(*a) || x - 1 == RECT_RIGHT(*a)) &&
454 (dir == OB_DIRECTION_WEST || dir == OB_DIRECTION_EAST))
455 {
456 dir = -1;
457 }
458 if ((y + 1 == RECT_TOP(*a) || y - 1 == RECT_BOTTOM(*a)) &&
459 (dir == OB_DIRECTION_NORTH || dir == OB_DIRECTION_SOUTH))
460 {
461 dir = -1;
462 }
463 g_free(a);
464 }
465
466 if (dir != edge_warp_dir) {
467 if (dir == (ObDirection)-1)
468 cancel_edge_warp();
469 else
470 ob_main_loop_timeout_add(ob_main_loop,
471 config_mouse_screenedgetime * 1000,
472 edge_warp_delay_func,
473 NULL, NULL, NULL);
474 edge_warp_dir = dir;
475 }
476 }
477
478 static void cancel_edge_warp()
479 {
480 ob_main_loop_timeout_remove(ob_main_loop, edge_warp_delay_func);
481 }
482
483 static void move_with_keys(gint keycode, gint state)
484 {
485 gint dx = 0, dy = 0, ox = cur_x, oy = cur_y;
486 gint opx, px, opy, py;
487 gint dist = 0;
488
489 /* shift means jump to edge */
490 if (state & modkeys_key_to_mask(OB_MODKEY_KEY_SHIFT)) {
491 gint x, y;
492 ObDirection dir;
493
494 if (keycode == ob_keycode(OB_KEY_RIGHT))
495 dir = OB_DIRECTION_EAST;
496 else if (keycode == ob_keycode(OB_KEY_LEFT))
497 dir = OB_DIRECTION_WEST;
498 else if (keycode == ob_keycode(OB_KEY_DOWN))
499 dir = OB_DIRECTION_SOUTH;
500 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
501 dir = OB_DIRECTION_NORTH;
502
503 client_find_move_directional(moveresize_client, dir, &x, &y);
504 dx = x - moveresize_client->area.x;
505 dy = y - moveresize_client->area.y;
506 } else {
507 /* control means fine grained */
508 if (state & modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL))
509 dist = 1;
510 else
511 dist = KEY_DIST;
512
513 if (keycode == ob_keycode(OB_KEY_RIGHT))
514 dx = dist;
515 else if (keycode == ob_keycode(OB_KEY_LEFT))
516 dx = -dist;
517 else if (keycode == ob_keycode(OB_KEY_DOWN))
518 dy = dist;
519 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
520 dy = -dist;
521 }
522
523 screen_pointer_pos(&opx, &opy);
524 XWarpPointer(ob_display, None, None, 0, 0, 0, 0, dx, dy);
525 /* steal the motion events this causes */
526 XSync(ob_display, FALSE);
527 {
528 XEvent ce;
529 while (XCheckTypedEvent(ob_display, MotionNotify, &ce));
530 }
531 screen_pointer_pos(&px, &py);
532
533 cur_x += dx;
534 cur_y += dy;
535 do_move(TRUE, dist);
536
537 /* because the cursor moves even though the window does
538 not nessesarily (resistance), this adjusts where the curor
539 thinks it started so that it keeps up with where the window
540 actually is */
541 start_x += (px - opx) - (cur_x - ox);
542 start_y += (py - opy) - (cur_y - oy);
543 }
544
545 gboolean moveresize_event(XEvent *e)
546 {
547 gboolean used = FALSE;
548
549 if (!moveresize_in_progress) return FALSE;
550
551 if (e->type == ButtonPress) {
552 if (!button) {
553 start_x = e->xbutton.x_root;
554 start_y = e->xbutton.y_root;
555 button = e->xbutton.button; /* this will end it now */
556 }
557 used = e->xbutton.button == button;
558 } else if (e->type == ButtonRelease) {
559 if (!button || e->xbutton.button == button) {
560 moveresize_end(FALSE);
561 used = TRUE;
562 }
563 } else if (e->type == MotionNotify) {
564 if (moving) {
565 cur_x = start_cx + e->xmotion.x_root - start_x;
566 cur_y = start_cy + e->xmotion.y_root - start_y;
567 do_move(FALSE, 0);
568 do_edge_warp(e->xmotion.x_root, e->xmotion.y_root);
569 } else {
570 if (corner == prop_atoms.net_wm_moveresize_size_topleft) {
571 cur_x = start_cw - (e->xmotion.x_root - start_x);
572 cur_y = start_ch - (e->xmotion.y_root - start_y);
573 lockcorner = OB_CORNER_BOTTOMRIGHT;
574 } else if (corner == prop_atoms.net_wm_moveresize_size_top) {
575 cur_x = start_cw;
576 cur_y = start_ch - (e->xmotion.y_root - start_y);
577 lockcorner = OB_CORNER_BOTTOMRIGHT;
578 } else if (corner == prop_atoms.net_wm_moveresize_size_topright) {
579 cur_x = start_cw + (e->xmotion.x_root - start_x);
580 cur_y = start_ch - (e->xmotion.y_root - start_y);
581 lockcorner = OB_CORNER_BOTTOMLEFT;
582 } else if (corner == prop_atoms.net_wm_moveresize_size_right) {
583 cur_x = start_cw + (e->xmotion.x_root - start_x);
584 cur_y = start_ch;
585 lockcorner = OB_CORNER_BOTTOMLEFT;
586 } else if (corner ==
587 prop_atoms.net_wm_moveresize_size_bottomright) {
588 cur_x = start_cw + (e->xmotion.x_root - start_x);
589 cur_y = start_ch + (e->xmotion.y_root - start_y);
590 lockcorner = OB_CORNER_TOPLEFT;
591 } else if (corner == prop_atoms.net_wm_moveresize_size_bottom) {
592 cur_x = start_cw;
593 cur_y = start_ch + (e->xmotion.y_root - start_y);
594 lockcorner = OB_CORNER_TOPLEFT;
595 } else if (corner ==
596 prop_atoms.net_wm_moveresize_size_bottomleft) {
597 cur_x = start_cw - (e->xmotion.x_root - start_x);
598 cur_y = start_ch + (e->xmotion.y_root - start_y);
599 lockcorner = OB_CORNER_TOPRIGHT;
600 } else if (corner == prop_atoms.net_wm_moveresize_size_left) {
601 cur_x = start_cw - (e->xmotion.x_root - start_x);
602 cur_y = start_ch;
603 lockcorner = OB_CORNER_TOPRIGHT;
604 } else if (corner == prop_atoms.net_wm_moveresize_size_keyboard) {
605 cur_x = start_cw + (e->xmotion.x_root - start_x);
606 cur_y = start_ch + (e->xmotion.y_root - start_y);
607 lockcorner = OB_CORNER_TOPLEFT;
608 } else
609 g_assert_not_reached();
610
611 calc_resize(FALSE);
612 do_resize();
613 }
614 used = TRUE;
615 } else if (e->type == KeyPress) {
616 if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) {
617 moveresize_end(TRUE);
618 used = TRUE;
619 } else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN)) {
620 moveresize_end(FALSE);
621 used = TRUE;
622 } else if (e->xkey.keycode == ob_keycode(OB_KEY_RIGHT) ||
623 e->xkey.keycode == ob_keycode(OB_KEY_LEFT) ||
624 e->xkey.keycode == ob_keycode(OB_KEY_DOWN) ||
625 e->xkey.keycode == ob_keycode(OB_KEY_UP))
626 {
627 if (corner == prop_atoms.net_wm_moveresize_size_keyboard) {
628 gint dx = 0, dy = 0, ox = cur_x, oy = cur_y;
629
630 if (e->xkey.keycode == ob_keycode(OB_KEY_RIGHT))
631 dx = MAX(KEY_DIST, moveresize_client->size_inc.width);
632 else if (e->xkey.keycode == ob_keycode(OB_KEY_LEFT))
633 dx = -MAX(KEY_DIST, moveresize_client->size_inc.width);
634 else if (e->xkey.keycode == ob_keycode(OB_KEY_DOWN))
635 dy = MAX(KEY_DIST, moveresize_client->size_inc.height);
636 else /* if (e->xkey.keycode == ob_keycode(OB_KEY_UP)) */
637 dy = -MAX(KEY_DIST, moveresize_client->size_inc.height);
638
639 cur_x += dx;
640 cur_y += dy;
641 XWarpPointer(ob_display, None, None, 0, 0, 0, 0, dx, dy);
642 /* steal the motion events this causes */
643 XSync(ob_display, FALSE);
644 {
645 XEvent ce;
646 while (XCheckTypedEvent(ob_display, MotionNotify, &ce));
647 }
648
649 calc_resize(TRUE);
650 do_resize();
651
652 /* because the cursor moves even though the window does
653 not nessesarily (resistance), this adjusts where the curor
654 thinks it started so that it keeps up with where the window
655 actually is */
656 start_x += dx - (cur_x - ox);
657 start_y += dy - (cur_y - oy);
658
659 used = TRUE;
660 } else if (corner == prop_atoms.net_wm_moveresize_move_keyboard) {
661 move_with_keys(e->xkey.keycode, e->xkey.state);
662 used = TRUE;
663 }
664 }
665 }
666 #ifdef SYNC
667 else if (e->type == extensions_sync_event_basep + XSyncAlarmNotify)
668 {
669 waiting_for_sync = FALSE; /* we got our sync... */
670 do_resize(); /* ...so try resize if there is more change pending */
671 used = TRUE;
672 }
673 #endif
674 return used;
675 }
This page took 0.065521 seconds and 5 git commands to generate.