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_shape
&&
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
, ow
, oh
, nw
, nh
;
379 /* resist_size_* needs the frame size */
381 moveresize_client
->frame
->size
.left
+
382 moveresize_client
->frame
->size
.right
;
384 moveresize_client
->frame
->size
.top
+
385 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
);
399 static gboolean
edge_warp_delay_func(gpointer data
)
403 d
= screen_find_desktop(screen_desktop
, edge_warp_dir
, TRUE
, FALSE
);
404 if (d
!= screen_desktop
) screen_set_desktop(d
, TRUE
);
408 return FALSE
; /* don't repeat */
411 static void do_edge_warp(gint x
, gint y
)
416 if (!config_mouse_screenedgetime
) return;
420 for (i
= 0; i
< screen_num_monitors
; ++i
) {
421 Rect
*a
= screen_physical_area_monitor(i
);
422 if (x
== RECT_LEFT(*a
)) dir
= OB_DIRECTION_WEST
;
423 if (x
== RECT_RIGHT(*a
)) dir
= OB_DIRECTION_EAST
;
424 if (y
== RECT_TOP(*a
)) dir
= OB_DIRECTION_NORTH
;
425 if (y
== RECT_BOTTOM(*a
)) dir
= OB_DIRECTION_SOUTH
;
427 /* try check for xinerama boundaries */
428 if ((x
+ 1 == RECT_LEFT(*a
) || x
- 1 == RECT_RIGHT(*a
)) &&
429 (dir
== OB_DIRECTION_WEST
|| dir
== OB_DIRECTION_EAST
))
433 if ((y
+ 1 == RECT_TOP(*a
) || y
- 1 == RECT_BOTTOM(*a
)) &&
434 (dir
== OB_DIRECTION_NORTH
|| dir
== OB_DIRECTION_SOUTH
))
441 if (dir
!= edge_warp_dir
) {
442 if (dir
== (ObDirection
)-1)
445 ob_main_loop_timeout_add(ob_main_loop
,
446 config_mouse_screenedgetime
* 1000,
447 edge_warp_delay_func
,
453 static void cancel_edge_warp()
455 ob_main_loop_timeout_remove(ob_main_loop
, edge_warp_delay_func
);
458 static void move_with_keys(gint keycode
, gint state
)
460 gint dx
= 0, dy
= 0, ox
= cur_x
, oy
= cur_y
;
461 gint opx
, px
, opy
, py
;
464 /* shift means jump to edge */
465 if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_SHIFT
)) {
469 if (keycode
== ob_keycode(OB_KEY_RIGHT
))
470 dir
= OB_DIRECTION_EAST
;
471 else if (keycode
== ob_keycode(OB_KEY_LEFT
))
472 dir
= OB_DIRECTION_WEST
;
473 else if (keycode
== ob_keycode(OB_KEY_DOWN
))
474 dir
= OB_DIRECTION_SOUTH
;
475 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
476 dir
= OB_DIRECTION_NORTH
;
478 client_find_move_directional(moveresize_client
, dir
, &x
, &y
);
479 dx
= x
- moveresize_client
->area
.x
;
480 dy
= y
- moveresize_client
->area
.y
;
482 /* control means fine grained */
483 if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL
))
488 if (keycode
== ob_keycode(OB_KEY_RIGHT
))
490 else if (keycode
== ob_keycode(OB_KEY_LEFT
))
492 else if (keycode
== ob_keycode(OB_KEY_DOWN
))
494 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
498 screen_pointer_pos(&opx
, &opy
);
499 XWarpPointer(ob_display
, None
, None
, 0, 0, 0, 0, dx
, dy
);
500 /* steal the motion events this causes */
501 XSync(ob_display
, FALSE
);
504 while (XCheckTypedEvent(ob_display
, MotionNotify
, &ce
));
506 screen_pointer_pos(&px
, &py
);
512 /* because the cursor moves even though the window does
513 not nessesarily (resistance), this adjusts where the curor
514 thinks it started so that it keeps up with where the window
516 start_x
+= (px
- opx
) - (cur_x
- ox
);
517 start_y
+= (py
- opy
) - (cur_y
- oy
);
520 static void resize_with_keys(gint keycode
, gint state
)
522 gint dw
= 0, dh
= 0, pdx
= 0, pdy
= 0, opx
, opy
, px
, py
;
527 /* pick the edge if it needs to move */
528 if (keycode
== ob_keycode(OB_KEY_RIGHT
)) {
529 dir
= OB_DIRECTION_EAST
;
530 if (key_resize_edge
!= OB_DIRECTION_WEST
&&
531 key_resize_edge
!= OB_DIRECTION_EAST
)
533 key_resize_edge
= OB_DIRECTION_EAST
;
537 if (keycode
== ob_keycode(OB_KEY_LEFT
)) {
538 dir
= OB_DIRECTION_WEST
;
539 if (key_resize_edge
!= OB_DIRECTION_WEST
&&
540 key_resize_edge
!= OB_DIRECTION_EAST
)
542 key_resize_edge
= OB_DIRECTION_WEST
;
546 if (keycode
== ob_keycode(OB_KEY_UP
)) {
547 dir
= OB_DIRECTION_NORTH
;
548 if (key_resize_edge
!= OB_DIRECTION_NORTH
&&
549 key_resize_edge
!= OB_DIRECTION_SOUTH
)
551 key_resize_edge
= OB_DIRECTION_NORTH
;
555 if (keycode
== ob_keycode(OB_KEY_DOWN
)) {
556 dir
= OB_DIRECTION_SOUTH
;
557 if (key_resize_edge
!= OB_DIRECTION_NORTH
&&
558 key_resize_edge
!= OB_DIRECTION_SOUTH
)
560 key_resize_edge
= OB_DIRECTION_SOUTH
;
565 /* shift means jump to edge */
566 if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_SHIFT
)) {
569 if (keycode
== ob_keycode(OB_KEY_RIGHT
))
570 dir
= OB_DIRECTION_EAST
;
571 else if (keycode
== ob_keycode(OB_KEY_LEFT
))
572 dir
= OB_DIRECTION_WEST
;
573 else if (keycode
== ob_keycode(OB_KEY_DOWN
))
574 dir
= OB_DIRECTION_SOUTH
;
575 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
576 dir
= OB_DIRECTION_NORTH
;
578 client_find_resize_directional(moveresize_client
, key_resize_edge
,
579 key_resize_edge
== dir
,
581 dw
= w
- moveresize_client
->area
.width
;
582 dh
= h
- moveresize_client
->area
.height
;
586 /* control means fine grained */
587 if (moveresize_client
->size_inc
.width
> 1)
588 distw
= moveresize_client
->size_inc
.width
;
589 else if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL
))
593 if (moveresize_client
->size_inc
.height
> 1)
594 disth
= moveresize_client
->size_inc
.height
;
595 else if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL
))
600 if (key_resize_edge
== OB_DIRECTION_WEST
) {
601 if (dir
== OB_DIRECTION_WEST
)
604 dw
= -(dist
= distw
);
606 else if (key_resize_edge
== OB_DIRECTION_EAST
) {
607 if (dir
== OB_DIRECTION_EAST
)
610 dw
= -(dist
= distw
);
612 else if (key_resize_edge
== OB_DIRECTION_NORTH
) {
613 if (dir
== OB_DIRECTION_NORTH
)
616 dh
= -(dist
= disth
);
618 else /*if (key_resize_edge == OB_DIRECTION_SOUTH)*/ {
619 if (dir
== OB_DIRECTION_SOUTH
)
622 dh
= -(dist
= disth
);
626 /* which corner is locked, for resistance */
627 if (key_resize_edge
== OB_DIRECTION_WEST
)
628 cor
= OB_CORNER_TOPRIGHT
;
629 else if (key_resize_edge
== OB_DIRECTION_EAST
)
630 cor
= OB_CORNER_TOPLEFT
;
631 else if (key_resize_edge
== OB_DIRECTION_NORTH
)
632 cor
= OB_CORNER_BOTTOMLEFT
;
633 else if (key_resize_edge
== OB_DIRECTION_SOUTH
)
634 cor
= OB_CORNER_TOPLEFT
;
636 calc_resize(TRUE
, dist
, &dw
, &dh
, cor
);
637 if (key_resize_edge
== OB_DIRECTION_WEST
)
639 else if (key_resize_edge
== OB_DIRECTION_NORTH
)
644 /* how to move the pointer to keep up with the change */
645 if (key_resize_edge
== OB_DIRECTION_WEST
)
647 else if (key_resize_edge
== OB_DIRECTION_EAST
)
649 else if (key_resize_edge
== OB_DIRECTION_NORTH
)
651 else if (key_resize_edge
== OB_DIRECTION_SOUTH
)
654 screen_pointer_pos(&opx
, &opy
);
655 XWarpPointer(ob_display
, None
, None
, 0, 0, 0, 0, pdx
, pdy
);
656 /* steal the motion events this causes */
657 XSync(ob_display
, FALSE
);
660 while (XCheckTypedEvent(ob_display
, MotionNotify
, &ce
));
662 screen_pointer_pos(&px
, &py
);
666 /* because the cursor moves even though the window does
667 not nessesarily (resistance), this adjusts where the cursor
668 thinks it started so that it keeps up with where the window
670 start_x
+= (px
- opx
) - dw
;
671 start_y
+= (py
- opy
) - dh
;
675 gboolean
moveresize_event(XEvent
*e
)
677 gboolean used
= FALSE
;
679 if (!moveresize_in_progress
) return FALSE
;
681 if (e
->type
== ButtonPress
) {
683 start_x
= e
->xbutton
.x_root
;
684 start_y
= e
->xbutton
.y_root
;
685 button
= e
->xbutton
.button
; /* this will end it now */
687 used
= e
->xbutton
.button
== button
;
688 } else if (e
->type
== ButtonRelease
) {
689 if (!button
|| e
->xbutton
.button
== button
) {
690 moveresize_end(FALSE
);
693 } else if (e
->type
== MotionNotify
) {
695 cur_x
= start_cx
+ e
->xmotion
.x_root
- start_x
;
696 cur_y
= start_cy
+ e
->xmotion
.y_root
- start_y
;
698 do_edge_warp(e
->xmotion
.x_root
, e
->xmotion
.y_root
);
702 if (corner
== prop_atoms
.net_wm_moveresize_size_topleft
) {
703 dw
= -(e
->xmotion
.x_root
- start_x
);
704 dh
= -(e
->xmotion
.y_root
- start_y
);
705 lockcorner
= OB_CORNER_BOTTOMRIGHT
;
706 } else if (corner
== prop_atoms
.net_wm_moveresize_size_top
) {
708 dh
= (e
->xmotion
.y_root
- start_y
);
709 lockcorner
= OB_CORNER_BOTTOMRIGHT
;
710 } else if (corner
== prop_atoms
.net_wm_moveresize_size_topright
) {
711 dw
= (e
->xmotion
.x_root
- start_x
);
712 dh
= -(e
->xmotion
.y_root
- start_y
);
713 lockcorner
= OB_CORNER_BOTTOMLEFT
;
714 } else if (corner
== prop_atoms
.net_wm_moveresize_size_right
) {
715 dw
= (e
->xmotion
.x_root
- start_x
);
717 lockcorner
= OB_CORNER_BOTTOMLEFT
;
719 prop_atoms
.net_wm_moveresize_size_bottomright
) {
720 dw
= (e
->xmotion
.x_root
- start_x
);
721 dh
= (e
->xmotion
.y_root
- start_y
);
722 lockcorner
= OB_CORNER_TOPLEFT
;
723 } else if (corner
== prop_atoms
.net_wm_moveresize_size_bottom
) {
725 dh
= (e
->xmotion
.y_root
- start_y
);
726 lockcorner
= OB_CORNER_TOPLEFT
;
728 prop_atoms
.net_wm_moveresize_size_bottomleft
) {
729 dw
= -(e
->xmotion
.x_root
- start_x
);
730 dh
= (e
->xmotion
.y_root
- start_y
);
731 lockcorner
= OB_CORNER_TOPRIGHT
;
732 } else if (corner
== prop_atoms
.net_wm_moveresize_size_left
) {
733 dw
= -(e
->xmotion
.x_root
- start_x
);
735 lockcorner
= OB_CORNER_TOPRIGHT
;
736 } else if (corner
== prop_atoms
.net_wm_moveresize_size_keyboard
) {
737 dw
= (e
->xmotion
.x_root
- start_x
);
738 dh
= (e
->xmotion
.y_root
- start_y
);
739 lockcorner
= OB_CORNER_TOPLEFT
;
741 g_assert_not_reached();
743 dw
-= cur_w
- start_cw
;
744 dh
-= cur_h
- start_ch
;
746 calc_resize(FALSE
, 0, &dw
, &dh
, lockcorner
);
750 if (corner
== prop_atoms
.net_wm_moveresize_size_topleft
||
751 corner
== prop_atoms
.net_wm_moveresize_size_left
||
752 corner
== prop_atoms
.net_wm_moveresize_size_bottomleft
)
756 if (corner
== prop_atoms
.net_wm_moveresize_size_topleft
||
757 corner
== prop_atoms
.net_wm_moveresize_size_top
||
758 corner
== prop_atoms
.net_wm_moveresize_size_topright
)
766 } else if (e
->type
== KeyPress
) {
767 if (e
->xkey
.keycode
== ob_keycode(OB_KEY_ESCAPE
)) {
768 moveresize_end(TRUE
);
770 } else if (e
->xkey
.keycode
== ob_keycode(OB_KEY_RETURN
)) {
771 moveresize_end(FALSE
);
773 } else if (e
->xkey
.keycode
== ob_keycode(OB_KEY_RIGHT
) ||
774 e
->xkey
.keycode
== ob_keycode(OB_KEY_LEFT
) ||
775 e
->xkey
.keycode
== ob_keycode(OB_KEY_DOWN
) ||
776 e
->xkey
.keycode
== ob_keycode(OB_KEY_UP
))
778 if (corner
== prop_atoms
.net_wm_moveresize_size_keyboard
) {
779 resize_with_keys(e
->xkey
.keycode
, e
->xkey
.state
);
781 } else if (corner
== prop_atoms
.net_wm_moveresize_move_keyboard
) {
782 move_with_keys(e
->xkey
.keycode
, e
->xkey
.state
);
788 else if (e
->type
== extensions_sync_event_basep
+ XSyncAlarmNotify
)
790 waiting_for_sync
= FALSE
; /* we got our sync... */
791 do_resize(); /* ...so try resize if there is more change pending */