1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 moveresize.c for the Openbox window manager
4 Copyright (c) 2006 Mikael Magnusson
5 Copyright (c) 2003-2007 Dana Jansens
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.
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.
17 See the COPYING file for a copy of the GNU General Public License.
21 #include "framerender.h"
31 #include "moveresize.h"
35 #include "extensions.h"
36 #include "render/render.h"
37 #include "render/theme.h"
42 /* how far windows move and resize with the keyboard arrows */
45 gboolean moveresize_in_progress
= FALSE
;
46 ObClient
*moveresize_client
= NULL
;
48 XSyncAlarm moveresize_alarm
= None
;
51 static gboolean moving
= FALSE
; /* TRUE - moving, FALSE - resizing */
53 static gint start_x
, start_y
, start_cx
, start_cy
, start_cw
, start_ch
;
54 static gint cur_x
, cur_y
, cur_w
, cur_h
;
56 static guint32 corner
;
57 static ObCorner lockcorner
;
58 static ObDirection edge_warp_dir
= -1;
59 static ObDirection key_resize_edge
= -1;
61 static gboolean waiting_for_sync
;
64 static ObPopup
*popup
= NULL
;
66 static void do_edge_warp(gint x
, gint y
);
67 static void cancel_edge_warp();
69 static gboolean
sync_timeout_func(gpointer data
);
72 static void client_dest(ObClient
*client
, gpointer data
)
74 if (moveresize_client
== client
)
78 void moveresize_startup(gboolean reconfig
)
80 popup
= popup_new(FALSE
);
81 popup_set_text_align(popup
, RR_JUSTIFY_CENTER
);
84 client_add_destroy_notify(client_dest
, NULL
);
87 void moveresize_shutdown(gboolean reconfig
)
90 if (moveresize_in_progress
)
91 moveresize_end(FALSE
);
92 client_remove_destroy_notify(client_dest
);
99 static void popup_coords(ObClient
*c
, const gchar
*format
, gint a
, gint b
)
103 text
= g_strdup_printf(format
, a
, b
);
104 if (config_resize_popup_pos
== 1) /* == "Top" */
105 popup_position(popup
, SouthGravity
,
107 + c
->frame
->area
.width
/2,
108 c
->frame
->area
.y
- ob_rr_theme
->fbwidth
);
109 else /* == "Center" */
110 popup_position(popup
, CenterGravity
,
111 c
->frame
->area
.x
+ c
->frame
->size
.left
+
113 c
->frame
->area
.y
+ c
->frame
->size
.top
+
115 popup_show(popup
, text
);
119 void moveresize_start(ObClient
*c
, gint x
, gint y
, guint b
, guint32 cnr
)
122 gboolean mv
= (cnr
== prop_atoms
.net_wm_moveresize_move
||
123 cnr
== prop_atoms
.net_wm_moveresize_move_keyboard
);
125 if (moveresize_in_progress
|| !c
->frame
->visible
||
127 (c
->functions
& OB_CLIENT_FUNC_MOVE
) :
128 (c
->functions
& OB_CLIENT_FUNC_RESIZE
)))
131 if (cnr
== prop_atoms
.net_wm_moveresize_size_topleft
)
132 cur
= OB_CURSOR_NORTHWEST
;
133 else if (cnr
== prop_atoms
.net_wm_moveresize_size_top
)
134 cur
= OB_CURSOR_NORTH
;
135 else if (cnr
== prop_atoms
.net_wm_moveresize_size_topright
)
136 cur
= OB_CURSOR_NORTHEAST
;
137 else if (cnr
== prop_atoms
.net_wm_moveresize_size_right
)
138 cur
= OB_CURSOR_EAST
;
139 else if (cnr
== prop_atoms
.net_wm_moveresize_size_bottomright
)
140 cur
= OB_CURSOR_SOUTHEAST
;
141 else if (cnr
== prop_atoms
.net_wm_moveresize_size_bottom
)
142 cur
= OB_CURSOR_SOUTH
;
143 else if (cnr
== prop_atoms
.net_wm_moveresize_size_bottomleft
)
144 cur
= OB_CURSOR_SOUTHWEST
;
145 else if (cnr
== prop_atoms
.net_wm_moveresize_size_left
)
146 cur
= OB_CURSOR_WEST
;
147 else if (cnr
== prop_atoms
.net_wm_moveresize_size_keyboard
)
148 cur
= OB_CURSOR_SOUTHEAST
;
149 else if (cnr
== prop_atoms
.net_wm_moveresize_move
)
150 cur
= OB_CURSOR_MOVE
;
151 else if (cnr
== prop_atoms
.net_wm_moveresize_move_keyboard
)
152 cur
= OB_CURSOR_MOVE
;
154 g_assert_not_reached();
156 /* keep the pointer bounded to the screen for move/resize */
157 if (!grab_pointer(FALSE
, TRUE
, cur
))
159 if (!grab_keyboard()) {
164 frame_end_iconify_animation(c
->frame
);
167 moveresize_client
= c
;
168 start_cx
= c
->area
.x
;
169 start_cy
= c
->area
.y
;
170 /* these adjustments for the size_inc make resizing a terminal more
171 friendly. you essentially start the resize in the middle of the
172 increment instead of at 0, so you have to move half an increment
173 either way instead of a full increment one and 1 px the other. */
174 start_cw
= c
->area
.width
+ c
->size_inc
.width
/ 2;
175 start_ch
= c
->area
.height
+ c
->size_inc
.height
/ 2;
180 key_resize_edge
= -1;
183 have to change start_cx and start_cy if going to do this..
184 if (corner == prop_atoms.net_wm_moveresize_move_keyboard ||
185 corner == prop_atoms.net_wm_moveresize_size_keyboard)
186 XWarpPointer(ob_display, None, c->window, 0, 0, 0, 0,
187 c->area.width / 2, c->area.height / 2);
195 moveresize_in_progress
= TRUE
;
198 if (config_resize_redraw
&& !moving
&& extensions_sync
&&
199 moveresize_client
->sync_request
&& moveresize_client
->sync_counter
)
201 /* Initialize values for the resize syncing, and create an alarm for
202 the client's xsync counter */
205 XSyncAlarmAttributes aa
;
207 /* set the counter to an initial value */
208 XSyncIntToValue(&val
, 0);
209 XSyncSetCounter(ob_display
, moveresize_client
->sync_counter
, val
);
211 /* this will be incremented when we tell the client what we're
213 moveresize_client
->sync_counter_value
= 0;
215 /* the next sequence we're waiting for with the alarm */
216 XSyncIntToValue(&val
, 1);
218 /* set an alarm on the counter */
219 aa
.trigger
.counter
= moveresize_client
->sync_counter
;
220 aa
.trigger
.wait_value
= val
;
221 aa
.trigger
.value_type
= XSyncAbsolute
;
222 aa
.trigger
.test_type
= XSyncPositiveTransition
;
224 XSyncIntToValue(&aa
.delta
, 1);
225 moveresize_alarm
= XSyncCreateAlarm(ob_display
,
234 waiting_for_sync
= FALSE
;
239 void moveresize_end(gboolean cancel
)
247 client_move(moveresize_client
,
248 (cancel
? start_cx
: cur_x
),
249 (cancel
? start_cy
: cur_y
));
252 /* turn off the alarm */
253 if (moveresize_alarm
!= None
) {
254 XSyncDestroyAlarm(ob_display
, moveresize_alarm
);
255 moveresize_alarm
= None
;
258 ob_main_loop_timeout_remove(ob_main_loop
, sync_timeout_func
);
261 client_configure(moveresize_client
,
262 (cancel
? start_cx
: cur_x
),
263 (cancel
? start_cy
: cur_y
),
264 (cancel
? start_cw
: cur_w
),
265 (cancel
? start_ch
: cur_h
),
269 /* dont edge warp after its ended */
272 moveresize_in_progress
= FALSE
;
273 moveresize_client
= NULL
;
276 static void do_move(gboolean keyboard
, gint keydist
)
280 if (keyboard
) resist
= keydist
- 1; /* resist for one key press */
281 else resist
= config_resist_win
;
282 resist_move_windows(moveresize_client
, resist
, &cur_x
, &cur_y
);
283 if (!keyboard
) resist
= config_resist_edge
;
284 resist_move_monitors(moveresize_client
, resist
, &cur_x
, &cur_y
);
286 client_configure(moveresize_client
, cur_x
, cur_y
, cur_w
, cur_h
,
288 if (config_resize_popup_show
== 2) /* == "Always" */
289 popup_coords(moveresize_client
, "%d x %d",
290 moveresize_client
->frame
->area
.x
,
291 moveresize_client
->frame
->area
.y
);
295 static void do_resize()
297 gint x
, y
, w
, h
, lw
, lh
;
299 /* see if it is actually going to resize */
304 client_try_configure(moveresize_client
, &x
, &y
, &w
, &h
,
306 if (w
== moveresize_client
->area
.width
&&
307 h
== moveresize_client
->area
.height
)
313 if (config_resize_redraw
&& extensions_sync
&&
314 moveresize_client
->sync_request
&& moveresize_client
->sync_counter
)
319 /* are we already waiting for the sync counter to catch up? */
320 if (waiting_for_sync
)
323 /* increment the value we're waiting for */
324 ++moveresize_client
->sync_counter_value
;
325 XSyncIntToValue(&val
, moveresize_client
->sync_counter_value
);
327 /* tell the client what we're waiting for */
328 ce
.xclient
.type
= ClientMessage
;
329 ce
.xclient
.message_type
= prop_atoms
.wm_protocols
;
330 ce
.xclient
.display
= ob_display
;
331 ce
.xclient
.window
= moveresize_client
->window
;
332 ce
.xclient
.format
= 32;
333 ce
.xclient
.data
.l
[0] = prop_atoms
.net_wm_sync_request
;
334 ce
.xclient
.data
.l
[1] = event_curtime
;
335 ce
.xclient
.data
.l
[2] = XSyncValueLow32(val
);
336 ce
.xclient
.data
.l
[3] = XSyncValueHigh32(val
);
337 ce
.xclient
.data
.l
[4] = 0l;
338 XSendEvent(ob_display
, moveresize_client
->window
, FALSE
,
341 waiting_for_sync
= TRUE
;
343 ob_main_loop_timeout_remove(ob_main_loop
, sync_timeout_func
);
344 ob_main_loop_timeout_add(ob_main_loop
, G_USEC_PER_SEC
* 2,
350 client_configure(moveresize_client
, cur_x
, cur_y
, cur_w
, cur_h
,
353 /* this would be better with a fixed width font ... XXX can do it better
354 if there are 2 text boxes */
355 if (config_resize_popup_show
== 2 || /* == "Always" */
356 (config_resize_popup_show
== 1 && /* == "Nonpixel" */
357 moveresize_client
->size_inc
.width
> 1 &&
358 moveresize_client
->size_inc
.height
> 1))
359 popup_coords(moveresize_client
, "%d x %d",
360 moveresize_client
->logical_size
.width
,
361 moveresize_client
->logical_size
.height
);
365 static gboolean
sync_timeout_func(gpointer data
)
367 waiting_for_sync
= FALSE
; /* we timed out waiting for our sync... */
368 do_resize(); /* ...so let any pending resizes through */
370 return FALSE
; /* don't repeat */
374 static void calc_resize(gboolean keyboard
, gint keydist
, gint
*dw
, gint
*dh
,
377 gint resist
, x
, y
, lw
, lh
, ow
, oh
, nw
, nh
;
381 /* resist_size_* needs the frame size */
383 moveresize_client
->frame
->size
.left
+
384 moveresize_client
->frame
->size
.right
;
386 moveresize_client
->frame
->size
.top
+
387 moveresize_client
->frame
->size
.bottom
;
389 if (keyboard
) resist
= keydist
- 1; /* resist for one key press */
390 else resist
= config_resist_win
;
391 resist_size_windows(moveresize_client
, resist
, &nw
, &nh
, cor
);
392 if (!keyboard
) resist
= config_resist_edge
;
393 resist_size_monitors(moveresize_client
, resist
, &nw
, &nh
, cor
);
395 nw
-= moveresize_client
->frame
->size
.left
+
396 moveresize_client
->frame
->size
.right
;
397 nh
-= moveresize_client
->frame
->size
.top
+
398 moveresize_client
->frame
->size
.bottom
;
400 /* see its actual size */
403 client_try_configure(moveresize_client
, &x
, &y
, &nw
, &nh
, &lw
, &lh
, TRUE
);
410 static gboolean
edge_warp_delay_func(gpointer data
)
414 d
= screen_find_desktop(screen_desktop
, edge_warp_dir
, TRUE
, FALSE
);
415 if (d
!= screen_desktop
) screen_set_desktop(d
, TRUE
);
419 return FALSE
; /* don't repeat */
422 static void do_edge_warp(gint x
, gint y
)
427 if (!config_mouse_screenedgetime
) return;
431 for (i
= 0; i
< screen_num_monitors
; ++i
) {
432 Rect
*a
= screen_physical_area_monitor(i
);
433 if (x
== RECT_LEFT(*a
)) dir
= OB_DIRECTION_WEST
;
434 if (x
== RECT_RIGHT(*a
)) dir
= OB_DIRECTION_EAST
;
435 if (y
== RECT_TOP(*a
)) dir
= OB_DIRECTION_NORTH
;
436 if (y
== RECT_BOTTOM(*a
)) dir
= OB_DIRECTION_SOUTH
;
438 /* try check for xinerama boundaries */
439 if ((x
+ 1 == RECT_LEFT(*a
) || x
- 1 == RECT_RIGHT(*a
)) &&
440 (dir
== OB_DIRECTION_WEST
|| dir
== OB_DIRECTION_EAST
))
444 if ((y
+ 1 == RECT_TOP(*a
) || y
- 1 == RECT_BOTTOM(*a
)) &&
445 (dir
== OB_DIRECTION_NORTH
|| dir
== OB_DIRECTION_SOUTH
))
452 if (dir
!= edge_warp_dir
) {
453 if (dir
== (ObDirection
)-1)
456 ob_main_loop_timeout_add(ob_main_loop
,
457 config_mouse_screenedgetime
* 1000,
458 edge_warp_delay_func
,
464 static void cancel_edge_warp()
466 ob_main_loop_timeout_remove(ob_main_loop
, edge_warp_delay_func
);
469 static void move_with_keys(gint keycode
, gint state
)
471 gint dx
= 0, dy
= 0, ox
= cur_x
, oy
= cur_y
;
472 gint opx
, px
, opy
, py
;
475 /* shift means jump to edge */
476 if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_SHIFT
)) {
480 if (keycode
== ob_keycode(OB_KEY_RIGHT
))
481 dir
= OB_DIRECTION_EAST
;
482 else if (keycode
== ob_keycode(OB_KEY_LEFT
))
483 dir
= OB_DIRECTION_WEST
;
484 else if (keycode
== ob_keycode(OB_KEY_DOWN
))
485 dir
= OB_DIRECTION_SOUTH
;
486 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
487 dir
= OB_DIRECTION_NORTH
;
489 client_find_move_directional(moveresize_client
, dir
, &x
, &y
);
490 dx
= x
- moveresize_client
->area
.x
;
491 dy
= y
- moveresize_client
->area
.y
;
493 /* control means fine grained */
494 if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL
))
499 if (keycode
== ob_keycode(OB_KEY_RIGHT
))
501 else if (keycode
== ob_keycode(OB_KEY_LEFT
))
503 else if (keycode
== ob_keycode(OB_KEY_DOWN
))
505 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
509 screen_pointer_pos(&opx
, &opy
);
510 XWarpPointer(ob_display
, None
, None
, 0, 0, 0, 0, dx
, dy
);
511 /* steal the motion events this causes */
512 XSync(ob_display
, FALSE
);
515 while (XCheckTypedEvent(ob_display
, MotionNotify
, &ce
));
517 screen_pointer_pos(&px
, &py
);
523 /* because the cursor moves even though the window does
524 not nessesarily (resistance), this adjusts where the curor
525 thinks it started so that it keeps up with where the window
527 start_x
+= (px
- opx
) - (cur_x
- ox
);
528 start_y
+= (py
- opy
) - (cur_y
- oy
);
531 static void resize_with_keys(gint keycode
, gint state
)
533 gint dw
= 0, dh
= 0, pdx
= 0, pdy
= 0, opx
, opy
, px
, py
;
538 /* pick the edge if it needs to move */
539 if (keycode
== ob_keycode(OB_KEY_RIGHT
)) {
540 dir
= OB_DIRECTION_EAST
;
541 if (key_resize_edge
!= OB_DIRECTION_WEST
&&
542 key_resize_edge
!= OB_DIRECTION_EAST
)
544 key_resize_edge
= OB_DIRECTION_EAST
;
548 if (keycode
== ob_keycode(OB_KEY_LEFT
)) {
549 dir
= OB_DIRECTION_WEST
;
550 if (key_resize_edge
!= OB_DIRECTION_WEST
&&
551 key_resize_edge
!= OB_DIRECTION_EAST
)
553 key_resize_edge
= OB_DIRECTION_WEST
;
557 if (keycode
== ob_keycode(OB_KEY_UP
)) {
558 dir
= OB_DIRECTION_NORTH
;
559 if (key_resize_edge
!= OB_DIRECTION_NORTH
&&
560 key_resize_edge
!= OB_DIRECTION_SOUTH
)
562 key_resize_edge
= OB_DIRECTION_NORTH
;
566 if (keycode
== ob_keycode(OB_KEY_DOWN
)) {
567 dir
= OB_DIRECTION_SOUTH
;
568 if (key_resize_edge
!= OB_DIRECTION_NORTH
&&
569 key_resize_edge
!= OB_DIRECTION_SOUTH
)
571 key_resize_edge
= OB_DIRECTION_SOUTH
;
576 /* shift means jump to edge */
577 if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_SHIFT
)) {
580 if (keycode
== ob_keycode(OB_KEY_RIGHT
))
581 dir
= OB_DIRECTION_EAST
;
582 else if (keycode
== ob_keycode(OB_KEY_LEFT
))
583 dir
= OB_DIRECTION_WEST
;
584 else if (keycode
== ob_keycode(OB_KEY_DOWN
))
585 dir
= OB_DIRECTION_SOUTH
;
586 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
587 dir
= OB_DIRECTION_NORTH
;
589 client_find_resize_directional(moveresize_client
, key_resize_edge
,
590 key_resize_edge
== dir
,
592 dw
= w
- moveresize_client
->area
.width
;
593 dh
= h
- moveresize_client
->area
.height
;
597 /* control means fine grained */
598 if (moveresize_client
->size_inc
.width
> 1)
599 distw
= moveresize_client
->size_inc
.width
;
600 else if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL
))
604 if (moveresize_client
->size_inc
.height
> 1)
605 disth
= moveresize_client
->size_inc
.height
;
606 else if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL
))
611 if (key_resize_edge
== OB_DIRECTION_WEST
) {
612 if (dir
== OB_DIRECTION_WEST
)
615 dw
= -(dist
= distw
);
617 else if (key_resize_edge
== OB_DIRECTION_EAST
) {
618 if (dir
== OB_DIRECTION_EAST
)
621 dw
= -(dist
= distw
);
623 else if (key_resize_edge
== OB_DIRECTION_NORTH
) {
624 if (dir
== OB_DIRECTION_NORTH
)
627 dh
= -(dist
= disth
);
629 else /*if (key_resize_edge == OB_DIRECTION_SOUTH)*/ {
630 if (dir
== OB_DIRECTION_SOUTH
)
633 dh
= -(dist
= disth
);
637 /* which corner is locked, for resistance */
638 if (key_resize_edge
== OB_DIRECTION_WEST
)
639 cor
= OB_CORNER_TOPRIGHT
;
640 else if (key_resize_edge
== OB_DIRECTION_EAST
)
641 cor
= OB_CORNER_TOPLEFT
;
642 else if (key_resize_edge
== OB_DIRECTION_NORTH
)
643 cor
= OB_CORNER_BOTTOMLEFT
;
644 else if (key_resize_edge
== OB_DIRECTION_SOUTH
)
645 cor
= OB_CORNER_TOPLEFT
;
647 calc_resize(TRUE
, dist
, &dw
, &dh
, cor
);
648 if (key_resize_edge
== OB_DIRECTION_WEST
)
650 else if (key_resize_edge
== OB_DIRECTION_NORTH
)
655 /* how to move the pointer to keep up with the change */
656 if (key_resize_edge
== OB_DIRECTION_WEST
)
658 else if (key_resize_edge
== OB_DIRECTION_EAST
)
660 else if (key_resize_edge
== OB_DIRECTION_NORTH
)
662 else if (key_resize_edge
== OB_DIRECTION_SOUTH
)
665 screen_pointer_pos(&opx
, &opy
);
666 XWarpPointer(ob_display
, None
, None
, 0, 0, 0, 0, pdx
, pdy
);
667 /* steal the motion events this causes */
668 XSync(ob_display
, FALSE
);
671 while (XCheckTypedEvent(ob_display
, MotionNotify
, &ce
));
673 screen_pointer_pos(&px
, &py
);
677 /* because the cursor moves even though the window does
678 not nessesarily (resistance), this adjusts where the cursor
679 thinks it started so that it keeps up with where the window
681 start_x
+= (px
- opx
) - dw
;
682 start_y
+= (py
- opy
) - dh
;
686 gboolean
moveresize_event(XEvent
*e
)
688 gboolean used
= FALSE
;
690 if (!moveresize_in_progress
) return FALSE
;
692 if (e
->type
== ButtonPress
) {
694 start_x
= e
->xbutton
.x_root
;
695 start_y
= e
->xbutton
.y_root
;
696 button
= e
->xbutton
.button
; /* this will end it now */
698 used
= e
->xbutton
.button
== button
;
699 } else if (e
->type
== ButtonRelease
) {
700 if (!button
|| e
->xbutton
.button
== button
) {
701 moveresize_end(FALSE
);
704 } else if (e
->type
== MotionNotify
) {
706 cur_x
= start_cx
+ e
->xmotion
.x_root
- start_x
;
707 cur_y
= start_cy
+ e
->xmotion
.y_root
- start_y
;
709 do_edge_warp(e
->xmotion
.x_root
, e
->xmotion
.y_root
);
713 if (corner
== prop_atoms
.net_wm_moveresize_size_topleft
) {
714 dw
= -(e
->xmotion
.x_root
- start_x
);
715 dh
= -(e
->xmotion
.y_root
- start_y
);
716 lockcorner
= OB_CORNER_BOTTOMRIGHT
;
717 } else if (corner
== prop_atoms
.net_wm_moveresize_size_top
) {
719 dh
= -(e
->xmotion
.y_root
- start_y
);
720 lockcorner
= OB_CORNER_BOTTOMRIGHT
;
721 } else if (corner
== prop_atoms
.net_wm_moveresize_size_topright
) {
722 dw
= (e
->xmotion
.x_root
- start_x
);
723 dh
= -(e
->xmotion
.y_root
- start_y
);
724 lockcorner
= OB_CORNER_BOTTOMLEFT
;
725 } else if (corner
== prop_atoms
.net_wm_moveresize_size_right
) {
726 dw
= (e
->xmotion
.x_root
- start_x
);
728 lockcorner
= OB_CORNER_BOTTOMLEFT
;
730 prop_atoms
.net_wm_moveresize_size_bottomright
) {
731 dw
= (e
->xmotion
.x_root
- start_x
);
732 dh
= (e
->xmotion
.y_root
- start_y
);
733 lockcorner
= OB_CORNER_TOPLEFT
;
734 } else if (corner
== prop_atoms
.net_wm_moveresize_size_bottom
) {
736 dh
= (e
->xmotion
.y_root
- start_y
);
737 lockcorner
= OB_CORNER_TOPLEFT
;
739 prop_atoms
.net_wm_moveresize_size_bottomleft
) {
740 dw
= -(e
->xmotion
.x_root
- start_x
);
741 dh
= (e
->xmotion
.y_root
- start_y
);
742 lockcorner
= OB_CORNER_TOPRIGHT
;
743 } else if (corner
== prop_atoms
.net_wm_moveresize_size_left
) {
744 dw
= -(e
->xmotion
.x_root
- start_x
);
746 lockcorner
= OB_CORNER_TOPRIGHT
;
747 } else if (corner
== prop_atoms
.net_wm_moveresize_size_keyboard
) {
748 dw
= (e
->xmotion
.x_root
- start_x
);
749 dh
= (e
->xmotion
.y_root
- start_y
);
750 lockcorner
= OB_CORNER_TOPLEFT
;
752 g_assert_not_reached();
754 dw
-= cur_w
- start_cw
;
755 dh
-= cur_h
- start_ch
;
757 calc_resize(FALSE
, 0, &dw
, &dh
, lockcorner
);
761 if (corner
== prop_atoms
.net_wm_moveresize_size_topleft
||
762 corner
== prop_atoms
.net_wm_moveresize_size_left
||
763 corner
== prop_atoms
.net_wm_moveresize_size_bottomleft
)
767 if (corner
== prop_atoms
.net_wm_moveresize_size_topleft
||
768 corner
== prop_atoms
.net_wm_moveresize_size_top
||
769 corner
== prop_atoms
.net_wm_moveresize_size_topright
)
777 } else if (e
->type
== KeyPress
) {
778 if (e
->xkey
.keycode
== ob_keycode(OB_KEY_ESCAPE
)) {
779 moveresize_end(TRUE
);
781 } else if (e
->xkey
.keycode
== ob_keycode(OB_KEY_RETURN
)) {
782 moveresize_end(FALSE
);
784 } else if (e
->xkey
.keycode
== ob_keycode(OB_KEY_RIGHT
) ||
785 e
->xkey
.keycode
== ob_keycode(OB_KEY_LEFT
) ||
786 e
->xkey
.keycode
== ob_keycode(OB_KEY_DOWN
) ||
787 e
->xkey
.keycode
== ob_keycode(OB_KEY_UP
))
789 if (corner
== prop_atoms
.net_wm_moveresize_size_keyboard
) {
790 resize_with_keys(e
->xkey
.keycode
, e
->xkey
.state
);
792 } else if (corner
== prop_atoms
.net_wm_moveresize_move_keyboard
) {
793 move_with_keys(e
->xkey
.keycode
, e
->xkey
.state
);
799 else if (e
->type
== extensions_sync_event_basep
+ XSyncAlarmNotify
)
801 waiting_for_sync
= FALSE
; /* we got our sync... */
802 do_resize(); /* ...so try resize if there is more change pending */