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 ObDirection edge_warp_dir
= -1;
58 static ObDirection key_resize_edge
= -1;
60 static gboolean waiting_for_sync
;
63 static ObPopup
*popup
= NULL
;
65 static void do_edge_warp(gint x
, gint y
);
66 static void cancel_edge_warp();
68 static gboolean
sync_timeout_func(gpointer data
);
71 static void client_dest(ObClient
*client
, gpointer data
)
73 if (moveresize_client
== client
)
77 void moveresize_startup(gboolean reconfig
)
79 popup
= popup_new(FALSE
);
80 popup_set_text_align(popup
, RR_JUSTIFY_CENTER
);
83 client_add_destroy_notify(client_dest
, NULL
);
86 void moveresize_shutdown(gboolean reconfig
)
89 if (moveresize_in_progress
)
90 moveresize_end(FALSE
);
91 client_remove_destroy_notify(client_dest
);
98 static void popup_coords(ObClient
*c
, const gchar
*format
, gint a
, gint b
)
102 text
= g_strdup_printf(format
, a
, b
);
103 if (config_resize_popup_pos
== 1) /* == "Top" */
104 popup_position(popup
, SouthGravity
,
106 + c
->frame
->area
.width
/2,
107 c
->frame
->area
.y
- ob_rr_theme
->fbwidth
);
108 else /* == "Center" */
109 popup_position(popup
, CenterGravity
,
110 c
->frame
->area
.x
+ c
->frame
->size
.left
+
112 c
->frame
->area
.y
+ c
->frame
->size
.top
+
114 popup_show(popup
, text
);
118 void moveresize_start(ObClient
*c
, gint x
, gint y
, guint b
, guint32 cnr
)
121 gboolean mv
= (cnr
== prop_atoms
.net_wm_moveresize_move
||
122 cnr
== prop_atoms
.net_wm_moveresize_move_keyboard
);
126 if (moveresize_in_progress
|| !c
->frame
->visible
||
128 (c
->functions
& OB_CLIENT_FUNC_MOVE
) :
129 (c
->functions
& OB_CLIENT_FUNC_RESIZE
)))
132 if (cnr
== prop_atoms
.net_wm_moveresize_size_topleft
) {
133 cur
= OB_CURSOR_NORTHWEST
;
135 } else if (cnr
== prop_atoms
.net_wm_moveresize_size_top
) {
136 cur
= OB_CURSOR_NORTH
;
138 } else if (cnr
== prop_atoms
.net_wm_moveresize_size_topright
) {
139 cur
= OB_CURSOR_NORTHEAST
;
141 } else if (cnr
== prop_atoms
.net_wm_moveresize_size_right
)
142 cur
= OB_CURSOR_EAST
;
143 else if (cnr
== prop_atoms
.net_wm_moveresize_size_bottomright
)
144 cur
= OB_CURSOR_SOUTHEAST
;
145 else if (cnr
== prop_atoms
.net_wm_moveresize_size_bottom
)
146 cur
= OB_CURSOR_SOUTH
;
147 else if (cnr
== prop_atoms
.net_wm_moveresize_size_bottomleft
) {
148 cur
= OB_CURSOR_SOUTHWEST
;
150 } else if (cnr
== prop_atoms
.net_wm_moveresize_size_left
) {
151 cur
= OB_CURSOR_WEST
;
153 } else if (cnr
== prop_atoms
.net_wm_moveresize_size_keyboard
)
154 cur
= OB_CURSOR_SOUTHEAST
;
155 else if (cnr
== prop_atoms
.net_wm_moveresize_move
)
156 cur
= OB_CURSOR_MOVE
;
157 else if (cnr
== prop_atoms
.net_wm_moveresize_move_keyboard
)
158 cur
= OB_CURSOR_MOVE
;
160 g_assert_not_reached();
162 /* keep the pointer bounded to the screen for move/resize */
163 if (!grab_pointer(FALSE
, TRUE
, cur
))
165 if (!grab_keyboard()) {
170 frame_end_iconify_animation(c
->frame
);
173 moveresize_client
= c
;
174 start_cx
= c
->area
.x
;
175 start_cy
= c
->area
.y
;
176 start_cw
= c
->area
.width
;
177 start_ch
= c
->area
.height
;
178 /* these adjustments for the size_inc make resizing a terminal more
179 friendly. you essentially start the resize in the middle of the
180 increment instead of at 0, so you have to move half an increment
181 either way instead of a full increment one and 1 px the other. */
182 start_x
= x
- (mv
? 0 : left
* c
->size_inc
.width
/ 2);
183 start_y
= y
- (mv
? 0 : up
* c
->size_inc
.height
/ 2);
186 key_resize_edge
= -1;
189 have to change start_cx and start_cy if going to do this..
190 if (corner == prop_atoms.net_wm_moveresize_move_keyboard ||
191 corner == prop_atoms.net_wm_moveresize_size_keyboard)
192 XWarpPointer(ob_display, None, c->window, 0, 0, 0, 0,
193 c->area.width / 2, c->area.height / 2);
201 moveresize_in_progress
= TRUE
;
204 if (config_resize_redraw
&& !moving
&& extensions_sync
&&
205 moveresize_client
->sync_request
&& moveresize_client
->sync_counter
)
207 /* Initialize values for the resize syncing, and create an alarm for
208 the client's xsync counter */
211 XSyncAlarmAttributes aa
;
213 /* set the counter to an initial value */
214 XSyncIntToValue(&val
, 0);
215 XSyncSetCounter(ob_display
, moveresize_client
->sync_counter
, val
);
217 /* this will be incremented when we tell the client what we're
219 moveresize_client
->sync_counter_value
= 0;
221 /* the next sequence we're waiting for with the alarm */
222 XSyncIntToValue(&val
, 1);
224 /* set an alarm on the counter */
225 aa
.trigger
.counter
= moveresize_client
->sync_counter
;
226 aa
.trigger
.wait_value
= val
;
227 aa
.trigger
.value_type
= XSyncAbsolute
;
228 aa
.trigger
.test_type
= XSyncPositiveTransition
;
230 XSyncIntToValue(&aa
.delta
, 1);
231 moveresize_alarm
= XSyncCreateAlarm(ob_display
,
240 waiting_for_sync
= FALSE
;
245 void moveresize_end(gboolean cancel
)
253 client_move(moveresize_client
,
254 (cancel
? start_cx
: cur_x
),
255 (cancel
? start_cy
: cur_y
));
258 /* turn off the alarm */
259 if (moveresize_alarm
!= None
) {
260 XSyncDestroyAlarm(ob_display
, moveresize_alarm
);
261 moveresize_alarm
= None
;
264 ob_main_loop_timeout_remove(ob_main_loop
, sync_timeout_func
);
267 client_configure(moveresize_client
,
268 (cancel
? start_cx
: cur_x
),
269 (cancel
? start_cy
: cur_y
),
270 (cancel
? start_cw
: cur_w
),
271 (cancel
? start_ch
: cur_h
),
275 /* dont edge warp after its ended */
278 moveresize_in_progress
= FALSE
;
279 moveresize_client
= NULL
;
282 static void do_move(gboolean keyboard
, gint keydist
)
286 if (keyboard
) resist
= keydist
- 1; /* resist for one key press */
287 else resist
= config_resist_win
;
288 resist_move_windows(moveresize_client
, resist
, &cur_x
, &cur_y
);
289 if (!keyboard
) resist
= config_resist_edge
;
290 resist_move_monitors(moveresize_client
, resist
, &cur_x
, &cur_y
);
292 client_configure(moveresize_client
, cur_x
, cur_y
, cur_w
, cur_h
,
294 if (config_resize_popup_show
== 2) /* == "Always" */
295 popup_coords(moveresize_client
, "%d x %d",
296 moveresize_client
->frame
->area
.x
,
297 moveresize_client
->frame
->area
.y
);
301 static void do_resize()
303 gint x
, y
, w
, h
, lw
, lh
;
305 /* see if it is actually going to resize */
310 client_try_configure(moveresize_client
, &x
, &y
, &w
, &h
,
312 if (w
== moveresize_client
->area
.width
&&
313 h
== moveresize_client
->area
.height
)
319 if (config_resize_redraw
&& extensions_sync
&&
320 moveresize_client
->sync_request
&& moveresize_client
->sync_counter
)
325 /* are we already waiting for the sync counter to catch up? */
326 if (waiting_for_sync
)
329 /* increment the value we're waiting for */
330 ++moveresize_client
->sync_counter_value
;
331 XSyncIntToValue(&val
, moveresize_client
->sync_counter_value
);
333 /* tell the client what we're waiting for */
334 ce
.xclient
.type
= ClientMessage
;
335 ce
.xclient
.message_type
= prop_atoms
.wm_protocols
;
336 ce
.xclient
.display
= ob_display
;
337 ce
.xclient
.window
= moveresize_client
->window
;
338 ce
.xclient
.format
= 32;
339 ce
.xclient
.data
.l
[0] = prop_atoms
.net_wm_sync_request
;
340 ce
.xclient
.data
.l
[1] = event_curtime
;
341 ce
.xclient
.data
.l
[2] = XSyncValueLow32(val
);
342 ce
.xclient
.data
.l
[3] = XSyncValueHigh32(val
);
343 ce
.xclient
.data
.l
[4] = 0l;
344 XSendEvent(ob_display
, moveresize_client
->window
, FALSE
,
347 waiting_for_sync
= TRUE
;
349 ob_main_loop_timeout_remove(ob_main_loop
, sync_timeout_func
);
350 ob_main_loop_timeout_add(ob_main_loop
, G_USEC_PER_SEC
* 2,
356 client_configure(moveresize_client
, cur_x
, cur_y
, cur_w
, cur_h
,
359 /* this would be better with a fixed width font ... XXX can do it better
360 if there are 2 text boxes */
361 if (config_resize_popup_show
== 2 || /* == "Always" */
362 (config_resize_popup_show
== 1 && /* == "Nonpixel" */
363 moveresize_client
->size_inc
.width
> 1 &&
364 moveresize_client
->size_inc
.height
> 1))
365 popup_coords(moveresize_client
, "%d x %d",
366 moveresize_client
->logical_size
.width
,
367 moveresize_client
->logical_size
.height
);
371 static gboolean
sync_timeout_func(gpointer data
)
373 waiting_for_sync
= FALSE
; /* we timed out waiting for our sync... */
374 do_resize(); /* ...so let any pending resizes through */
376 return FALSE
; /* don't repeat */
380 static void calc_resize(gboolean keyboard
, gint keydist
, gint
*dw
, gint
*dh
,
383 gint resist
, x
= 0, y
= 0, lw
, lh
, ow
, oh
, nw
, nh
;
392 (moveresize_client
->max_ratio
|| moveresize_client
->min_ratio
))
395 case OB_DIRECTION_NORTH
:
396 case OB_DIRECTION_SOUTH
:
397 /* resize the width based on the height */
398 if (moveresize_client
->min_ratio
) {
399 if (nh
* moveresize_client
->min_ratio
> nw
)
400 nw
= (gint
)(nh
* moveresize_client
->min_ratio
);
402 if (moveresize_client
->max_ratio
) {
403 if (nh
* moveresize_client
->max_ratio
< nw
)
404 nw
= (gint
)(nh
* moveresize_client
->max_ratio
);
408 /* resize the height based on the width */
409 if (moveresize_client
->min_ratio
) {
410 if (nh
* moveresize_client
->min_ratio
> nw
)
411 nh
= (gint
)(nw
/ moveresize_client
->min_ratio
);
413 if (moveresize_client
->max_ratio
) {
414 if (nh
* moveresize_client
->max_ratio
< nw
)
415 nh
= (gint
)(nw
/ moveresize_client
->max_ratio
);
420 /* see its actual size (apply aspect ratios) */
421 client_try_configure(moveresize_client
, &x
, &y
, &nw
, &nh
, &lw
, &lh
,
427 /* resist_size_* needs the frame size */
428 nw
+= moveresize_client
->frame
->size
.left
+
429 moveresize_client
->frame
->size
.right
;
430 nh
+= moveresize_client
->frame
->size
.top
+
431 moveresize_client
->frame
->size
.bottom
;
433 if (keyboard
) resist
= keydist
- 1; /* resist for one key press */
434 else resist
= config_resist_win
;
435 resist_size_windows(moveresize_client
, resist
, &nw
, &nh
, dir
);
436 if (!keyboard
) resist
= config_resist_edge
;
437 resist_size_monitors(moveresize_client
, resist
, &nw
, &nh
, dir
);
439 nw
-= moveresize_client
->frame
->size
.left
+
440 moveresize_client
->frame
->size
.right
;
441 nh
-= moveresize_client
->frame
->size
.top
+
442 moveresize_client
->frame
->size
.bottom
;
447 /* take aspect ratios into account for resistance */
449 (moveresize_client
->max_ratio
|| moveresize_client
->min_ratio
))
451 if (*dh
!= trydh
) { /* got resisted */
452 /* resize the width based on the height */
453 if (moveresize_client
->min_ratio
) {
454 if (nh
* moveresize_client
->min_ratio
> nw
)
455 nw
= (gint
)(nh
* moveresize_client
->min_ratio
);
457 if (moveresize_client
->max_ratio
) {
458 if (nh
* moveresize_client
->max_ratio
< nw
)
459 nw
= (gint
)(nh
* moveresize_client
->max_ratio
);
462 if (*dw
!= trydw
) { /* got resisted */
463 /* resize the height based on the width */
464 if (moveresize_client
->min_ratio
) {
465 if (nh
* moveresize_client
->min_ratio
> nw
)
466 nh
= (gint
)(nw
/ moveresize_client
->min_ratio
);
468 if (moveresize_client
->max_ratio
) {
469 if (nh
* moveresize_client
->max_ratio
< nw
)
470 nh
= (gint
)(nw
/ moveresize_client
->max_ratio
);
475 /* make sure it's all valid */
476 client_try_configure(moveresize_client
, &x
, &y
, &nw
, &nh
, &lw
, &lh
, TRUE
);
482 static gboolean
edge_warp_delay_func(gpointer data
)
486 d
= screen_find_desktop(screen_desktop
, edge_warp_dir
, TRUE
, FALSE
);
487 if (d
!= screen_desktop
) screen_set_desktop(d
, TRUE
);
491 return FALSE
; /* don't repeat */
494 static void do_edge_warp(gint x
, gint y
)
499 if (!config_mouse_screenedgetime
) return;
503 for (i
= 0; i
< screen_num_monitors
; ++i
) {
504 Rect
*a
= screen_physical_area_monitor(i
);
505 if (x
== RECT_LEFT(*a
)) dir
= OB_DIRECTION_WEST
;
506 if (x
== RECT_RIGHT(*a
)) dir
= OB_DIRECTION_EAST
;
507 if (y
== RECT_TOP(*a
)) dir
= OB_DIRECTION_NORTH
;
508 if (y
== RECT_BOTTOM(*a
)) dir
= OB_DIRECTION_SOUTH
;
510 /* try check for xinerama boundaries */
511 if ((x
+ 1 == RECT_LEFT(*a
) || x
- 1 == RECT_RIGHT(*a
)) &&
512 (dir
== OB_DIRECTION_WEST
|| dir
== OB_DIRECTION_EAST
))
516 if ((y
+ 1 == RECT_TOP(*a
) || y
- 1 == RECT_BOTTOM(*a
)) &&
517 (dir
== OB_DIRECTION_NORTH
|| dir
== OB_DIRECTION_SOUTH
))
524 if (dir
!= edge_warp_dir
) {
525 if (dir
== (ObDirection
)-1)
528 ob_main_loop_timeout_add(ob_main_loop
,
529 config_mouse_screenedgetime
* 1000,
530 edge_warp_delay_func
,
536 static void cancel_edge_warp()
538 ob_main_loop_timeout_remove(ob_main_loop
, edge_warp_delay_func
);
541 static void move_with_keys(gint keycode
, gint state
)
543 gint dx
= 0, dy
= 0, ox
= cur_x
, oy
= cur_y
;
544 gint opx
, px
, opy
, py
;
547 /* shift means jump to edge */
548 if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_SHIFT
)) {
552 if (keycode
== ob_keycode(OB_KEY_RIGHT
))
553 dir
= OB_DIRECTION_EAST
;
554 else if (keycode
== ob_keycode(OB_KEY_LEFT
))
555 dir
= OB_DIRECTION_WEST
;
556 else if (keycode
== ob_keycode(OB_KEY_DOWN
))
557 dir
= OB_DIRECTION_SOUTH
;
558 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
559 dir
= OB_DIRECTION_NORTH
;
561 client_find_move_directional(moveresize_client
, dir
, &x
, &y
);
562 dx
= x
- moveresize_client
->area
.x
;
563 dy
= y
- moveresize_client
->area
.y
;
565 /* control means fine grained */
566 if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL
))
571 if (keycode
== ob_keycode(OB_KEY_RIGHT
))
573 else if (keycode
== ob_keycode(OB_KEY_LEFT
))
575 else if (keycode
== ob_keycode(OB_KEY_DOWN
))
577 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
581 screen_pointer_pos(&opx
, &opy
);
582 XWarpPointer(ob_display
, None
, None
, 0, 0, 0, 0, dx
, dy
);
583 /* steal the motion events this causes */
584 XSync(ob_display
, FALSE
);
587 while (XCheckTypedEvent(ob_display
, MotionNotify
, &ce
));
589 screen_pointer_pos(&px
, &py
);
595 /* because the cursor moves even though the window does
596 not nessesarily (resistance), this adjusts where the curor
597 thinks it started so that it keeps up with where the window
599 start_x
+= (px
- opx
) - (cur_x
- ox
);
600 start_y
+= (py
- opy
) - (cur_y
- oy
);
603 static void resize_with_keys(gint keycode
, gint state
)
605 gint dw
= 0, dh
= 0, pdx
= 0, pdy
= 0, opx
, opy
, px
, py
;
606 gint dist
= 0, resist
= 0;
609 /* pick the edge if it needs to move */
610 if (keycode
== ob_keycode(OB_KEY_RIGHT
)) {
611 dir
= OB_DIRECTION_EAST
;
612 if (key_resize_edge
!= OB_DIRECTION_WEST
&&
613 key_resize_edge
!= OB_DIRECTION_EAST
)
615 key_resize_edge
= OB_DIRECTION_EAST
;
619 if (keycode
== ob_keycode(OB_KEY_LEFT
)) {
620 dir
= OB_DIRECTION_WEST
;
621 if (key_resize_edge
!= OB_DIRECTION_WEST
&&
622 key_resize_edge
!= OB_DIRECTION_EAST
)
624 key_resize_edge
= OB_DIRECTION_WEST
;
628 if (keycode
== ob_keycode(OB_KEY_UP
)) {
629 dir
= OB_DIRECTION_NORTH
;
630 if (key_resize_edge
!= OB_DIRECTION_NORTH
&&
631 key_resize_edge
!= OB_DIRECTION_SOUTH
)
633 key_resize_edge
= OB_DIRECTION_NORTH
;
637 if (keycode
== ob_keycode(OB_KEY_DOWN
)) {
638 dir
= OB_DIRECTION_SOUTH
;
639 if (key_resize_edge
!= OB_DIRECTION_NORTH
&&
640 key_resize_edge
!= OB_DIRECTION_SOUTH
)
642 key_resize_edge
= OB_DIRECTION_SOUTH
;
647 /* shift means jump to edge */
648 if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_SHIFT
)) {
651 if (keycode
== ob_keycode(OB_KEY_RIGHT
))
652 dir
= OB_DIRECTION_EAST
;
653 else if (keycode
== ob_keycode(OB_KEY_LEFT
))
654 dir
= OB_DIRECTION_WEST
;
655 else if (keycode
== ob_keycode(OB_KEY_DOWN
))
656 dir
= OB_DIRECTION_SOUTH
;
657 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
658 dir
= OB_DIRECTION_NORTH
;
660 client_find_resize_directional(moveresize_client
, key_resize_edge
,
661 key_resize_edge
== dir
,
663 dw
= w
- moveresize_client
->area
.width
;
664 dh
= h
- moveresize_client
->area
.height
;
668 /* control means fine grained */
669 if (moveresize_client
->size_inc
.width
> 1) {
670 distw
= moveresize_client
->size_inc
.width
;
673 else if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL
)) {
681 if (moveresize_client
->size_inc
.height
> 1) {
682 disth
= moveresize_client
->size_inc
.height
;
685 else if (state
& modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL
)) {
694 if (key_resize_edge
== OB_DIRECTION_WEST
) {
695 if (dir
== OB_DIRECTION_WEST
)
698 dw
= -(dist
= distw
);
700 else if (key_resize_edge
== OB_DIRECTION_EAST
) {
701 if (dir
== OB_DIRECTION_EAST
)
704 dw
= -(dist
= distw
);
706 else if (key_resize_edge
== OB_DIRECTION_NORTH
) {
707 if (dir
== OB_DIRECTION_NORTH
)
710 dh
= -(dist
= disth
);
712 else /*if (key_resize_edge == OB_DIRECTION_SOUTH)*/ {
713 if (dir
== OB_DIRECTION_SOUTH
)
716 dh
= -(dist
= disth
);
720 calc_resize(TRUE
, resist
, &dw
, &dh
, dir
);
721 if (key_resize_edge
== OB_DIRECTION_WEST
)
723 else if (key_resize_edge
== OB_DIRECTION_NORTH
)
728 /* how to move the pointer to keep up with the change */
729 if (key_resize_edge
== OB_DIRECTION_WEST
)
731 else if (key_resize_edge
== OB_DIRECTION_EAST
)
733 else if (key_resize_edge
== OB_DIRECTION_NORTH
)
735 else if (key_resize_edge
== OB_DIRECTION_SOUTH
)
738 screen_pointer_pos(&opx
, &opy
);
739 XWarpPointer(ob_display
, None
, None
, 0, 0, 0, 0, pdx
, pdy
);
740 /* steal the motion events this causes */
741 XSync(ob_display
, FALSE
);
744 while (XCheckTypedEvent(ob_display
, MotionNotify
, &ce
));
746 screen_pointer_pos(&px
, &py
);
750 /* because the cursor moves even though the window does
751 not nessesarily (resistance), this adjusts where the cursor
752 thinks it started so that it keeps up with where the window
754 start_x
+= (px
- opx
) - dw
;
755 start_y
+= (py
- opy
) - dh
;
759 gboolean
moveresize_event(XEvent
*e
)
761 gboolean used
= FALSE
;
763 if (!moveresize_in_progress
) return FALSE
;
765 if (e
->type
== ButtonPress
) {
767 start_x
= e
->xbutton
.x_root
;
768 start_y
= e
->xbutton
.y_root
;
769 button
= e
->xbutton
.button
; /* this will end it now */
771 used
= e
->xbutton
.button
== button
;
772 } else if (e
->type
== ButtonRelease
) {
773 if (!button
|| e
->xbutton
.button
== button
) {
774 moveresize_end(FALSE
);
777 } else if (e
->type
== MotionNotify
) {
779 cur_x
= start_cx
+ e
->xmotion
.x_root
- start_x
;
780 cur_y
= start_cy
+ e
->xmotion
.y_root
- start_y
;
782 do_edge_warp(e
->xmotion
.x_root
, e
->xmotion
.y_root
);
787 if (corner
== prop_atoms
.net_wm_moveresize_size_topleft
) {
788 dw
= -(e
->xmotion
.x_root
- start_x
);
789 dh
= -(e
->xmotion
.y_root
- start_y
);
790 dir
= OB_DIRECTION_NORTHWEST
;
791 } else if (corner
== prop_atoms
.net_wm_moveresize_size_top
) {
793 dh
= -(e
->xmotion
.y_root
- start_y
);
794 dir
= OB_DIRECTION_NORTH
;
795 } else if (corner
== prop_atoms
.net_wm_moveresize_size_topright
) {
796 dw
= (e
->xmotion
.x_root
- start_x
);
797 dh
= -(e
->xmotion
.y_root
- start_y
);
798 dir
= OB_DIRECTION_NORTHEAST
;
799 } else if (corner
== prop_atoms
.net_wm_moveresize_size_right
) {
800 dw
= (e
->xmotion
.x_root
- start_x
);
802 dir
= OB_DIRECTION_EAST
;
804 prop_atoms
.net_wm_moveresize_size_bottomright
) {
805 dw
= (e
->xmotion
.x_root
- start_x
);
806 dh
= (e
->xmotion
.y_root
- start_y
);
807 dir
= OB_DIRECTION_SOUTHEAST
;
808 } else if (corner
== prop_atoms
.net_wm_moveresize_size_bottom
) {
810 dh
= (e
->xmotion
.y_root
- start_y
);
811 dir
= OB_DIRECTION_SOUTH
;
813 prop_atoms
.net_wm_moveresize_size_bottomleft
) {
814 dw
= -(e
->xmotion
.x_root
- start_x
);
815 dh
= (e
->xmotion
.y_root
- start_y
);
816 dir
= OB_DIRECTION_SOUTHWEST
;
817 } else if (corner
== prop_atoms
.net_wm_moveresize_size_left
) {
818 dw
= -(e
->xmotion
.x_root
- start_x
);
820 dir
= OB_DIRECTION_WEST
;
821 } else if (corner
== prop_atoms
.net_wm_moveresize_size_keyboard
) {
822 dw
= (e
->xmotion
.x_root
- start_x
);
823 dh
= (e
->xmotion
.y_root
- start_y
);
824 dir
= OB_DIRECTION_SOUTHEAST
;
826 g_assert_not_reached();
828 dw
-= cur_w
- start_cw
;
829 dh
-= cur_h
- start_ch
;
831 calc_resize(FALSE
, 0, &dw
, &dh
, dir
);
835 if (corner
== prop_atoms
.net_wm_moveresize_size_topleft
||
836 corner
== prop_atoms
.net_wm_moveresize_size_left
||
837 corner
== prop_atoms
.net_wm_moveresize_size_bottomleft
)
841 if (corner
== prop_atoms
.net_wm_moveresize_size_topleft
||
842 corner
== prop_atoms
.net_wm_moveresize_size_top
||
843 corner
== prop_atoms
.net_wm_moveresize_size_topright
)
851 } else if (e
->type
== KeyPress
) {
852 if (e
->xkey
.keycode
== ob_keycode(OB_KEY_ESCAPE
)) {
853 moveresize_end(TRUE
);
855 } else if (e
->xkey
.keycode
== ob_keycode(OB_KEY_RETURN
)) {
856 moveresize_end(FALSE
);
858 } else if (e
->xkey
.keycode
== ob_keycode(OB_KEY_RIGHT
) ||
859 e
->xkey
.keycode
== ob_keycode(OB_KEY_LEFT
) ||
860 e
->xkey
.keycode
== ob_keycode(OB_KEY_DOWN
) ||
861 e
->xkey
.keycode
== ob_keycode(OB_KEY_UP
))
863 if (corner
== prop_atoms
.net_wm_moveresize_size_keyboard
) {
864 resize_with_keys(e
->xkey
.keycode
, e
->xkey
.state
);
866 } else if (corner
== prop_atoms
.net_wm_moveresize_move_keyboard
) {
867 move_with_keys(e
->xkey
.keycode
, e
->xkey
.state
);
873 else if (e
->type
== extensions_sync_event_basep
+ XSyncAlarmNotify
)
875 waiting_for_sync
= FALSE
; /* we got our sync... */
876 do_resize(); /* ...so try resize if there is more change pending */