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.
23 #include "engine_interface.h"
27 #include "moveresize.h"
31 #include "render/render.h"
32 #include "render/theme.h"
33 #include "obt/display.h"
35 #include "obt/keyboard.h"
40 /* how far windows move and resize with the keyboard arrows */
43 //gboolean moveresize_in_progress = FALSE;
44 ObClient *moveresize_client = NULL;
46 XSyncAlarm moveresize_alarm = None;
49 static gboolean moving = FALSE; /* TRUE - moving, FALSE - resizing */
51 static gint start_x, start_y, start_cx, start_cy, start_cw, start_ch;
52 static gint cur_x, cur_y, cur_w, cur_h;
54 static guint32 corner;
55 static ObDirection edge_warp_dir = -1;
56 static gboolean edge_warp_odd = FALSE;
57 static ObDirection key_resize_edge = -1;
59 static gboolean waiting_for_sync;
62 static ObPopup *popup = NULL;
64 static void do_edge_warp(gint x, gint y);
65 static void cancel_edge_warp();
67 static gboolean sync_timeout_func(gpointer data);
70 static void client_dest(ObClient *client, gpointer data)
72 if (moveresize_client == client)
76 void moveresize_startup(gboolean reconfig)
79 popup_set_text_align(popup, RR_JUSTIFY_CENTER);
82 client_add_destroy_notify(client_dest, NULL);
85 void moveresize_shutdown(gboolean reconfig)
88 if (render_plugin->moveresize_in_progress)
89 moveresize_end(FALSE);
90 client_remove_destroy_notify(client_dest);
97 static void popup_coords(ObClient *c, const gchar *format, gint a, gint b)
101 Strut size = render_plugin->frame_get_size(c->frame);
102 Rect area = render_plugin->frame_get_window_area(c->frame);
103 text = g_strdup_printf(format, a, b);
104 if (config_resize_popup_pos == OB_RESIZE_POS_TOP)
105 popup_position(popup, SouthGravity,
108 area.y - ob_rr_theme->fbwidth);
109 else if (config_resize_popup_pos == OB_RESIZE_POS_CENTER)
110 popup_position(popup, CenterGravity,
116 Rect *area = screen_physical_area_active();
119 x = config_resize_popup_fixed.x.pos;
120 if (config_resize_popup_fixed.x.center)
121 x = area->x + area->width/2;
122 else if (config_resize_popup_fixed.x.opposite)
123 x = RECT_RIGHT(*area) - x;
127 y = config_resize_popup_fixed.y.pos;
128 if (config_resize_popup_fixed.y.center)
129 y = area->y + area->height/2;
130 else if (config_resize_popup_fixed.y.opposite)
131 y = RECT_RIGHT(*area) - y;
135 if (config_resize_popup_fixed.x.center) {
136 if (config_resize_popup_fixed.y.center)
137 gravity = CenterGravity;
138 else if (config_resize_popup_fixed.y.opposite)
139 gravity = SouthGravity;
141 gravity = NorthGravity;
143 else if (config_resize_popup_fixed.x.opposite) {
144 if (config_resize_popup_fixed.y.center)
145 gravity = EastGravity;
146 else if (config_resize_popup_fixed.y.opposite)
147 gravity = SouthEastGravity;
149 gravity = NorthEastGravity;
152 if (config_resize_popup_fixed.y.center)
153 gravity = WestGravity;
154 else if (config_resize_popup_fixed.y.opposite)
155 gravity = SouthWestGravity;
157 gravity = NorthWestGravity;
160 popup_position(popup, gravity, x, y);
164 popup_show(popup, text);
168 void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr)
171 gboolean mv = (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE) ||
172 cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE_KEYBOARD));
176 if (render_plugin->moveresize_in_progress || !render_plugin->frame_is_visible(c->frame) ||
178 (c->functions & OB_CLIENT_FUNC_MOVE) :
179 (c->functions & OB_CLIENT_FUNC_RESIZE)))
182 if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPLEFT)) {
183 cur = OB_CURSOR_NORTHWEST;
186 else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOP)) {
187 cur = OB_CURSOR_NORTH;
190 else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPRIGHT)) {
191 cur = OB_CURSOR_NORTHEAST;
194 else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_RIGHT))
195 cur = OB_CURSOR_EAST;
196 else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT))
197 cur = OB_CURSOR_SOUTHEAST;
198 else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOM))
199 cur = OB_CURSOR_SOUTH;
200 else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT)) {
201 cur = OB_CURSOR_SOUTHWEST;
204 else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_LEFT)) {
205 cur = OB_CURSOR_WEST;
208 else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_KEYBOARD))
209 cur = OB_CURSOR_SOUTHEAST;
210 else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE))
211 cur = OB_CURSOR_MOVE;
212 else if (cnr == OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE_KEYBOARD))
213 cur = OB_CURSOR_MOVE;
215 g_assert_not_reached();
217 /* keep the pointer bounded to the screen for move/resize */
218 if (!grab_pointer(FALSE, TRUE, cur))
220 if (!grab_keyboard()) {
225 render_plugin->frame_end_iconify_animation(c->frame);
228 moveresize_client = c;
229 start_cx = c->area.x;
230 start_cy = c->area.y;
231 start_cw = c->area.width;
232 start_ch = c->area.height;
233 /* these adjustments for the size_inc make resizing a terminal more
234 friendly. you essentially start the resize in the middle of the
235 increment instead of at 0, so you have to move half an increment
236 either way instead of a full increment one and 1 px the other. */
237 start_x = x - (mv ? 0 : left * c->size_inc.width / 2);
238 start_y = y - (mv ? 0 : up * c->size_inc.height / 2);
241 key_resize_edge = -1;
244 have to change start_cx and start_cy if going to do this..
245 if (corner == prop_atoms.net_wm_moveresize_move_keyboard ||
246 corner == prop_atoms.net_wm_moveresize_size_keyboard)
247 XWarpPointer(ob_display, None, c->window, 0, 0, 0, 0,
248 c->area.width / 2, c->area.height / 2);
256 render_plugin->moveresize_in_progress = TRUE;
259 if (config_resize_redraw && !moving && obt_display_extension_sync &&
260 moveresize_client->sync_request && moveresize_client->sync_counter &&
261 !moveresize_client->not_responding)
263 /* Initialize values for the resize syncing, and create an alarm for
264 the client's xsync counter */
267 XSyncAlarmAttributes aa;
269 /* set the counter to an initial value */
270 XSyncIntToValue(&val, 0);
271 XSyncSetCounter(obt_display, moveresize_client->sync_counter, val);
273 /* this will be incremented when we tell the client what we're
275 moveresize_client->sync_counter_value = 0;
277 /* the next sequence we're waiting for with the alarm */
278 XSyncIntToValue(&val, 1);
280 /* set an alarm on the counter */
281 aa.trigger.counter = moveresize_client->sync_counter;
282 aa.trigger.wait_value = val;
283 aa.trigger.value_type = XSyncAbsolute;
284 aa.trigger.test_type = XSyncPositiveTransition;
286 XSyncIntToValue(&aa.delta, 1);
287 moveresize_alarm = XSyncCreateAlarm(obt_display,
296 waiting_for_sync = FALSE;
301 void moveresize_end(gboolean cancel)
309 client_move(moveresize_client,
310 (cancel ? start_cx : cur_x),
311 (cancel ? start_cy : cur_y));
314 /* turn off the alarm */
315 if (moveresize_alarm != None) {
316 XSyncDestroyAlarm(obt_display, moveresize_alarm);
317 moveresize_alarm = None;
320 obt_main_loop_timeout_remove(ob_main_loop, sync_timeout_func);
323 client_configure(moveresize_client,
324 (cancel ? start_cx : cur_x),
325 (cancel ? start_cy : cur_y),
326 (cancel ? start_cw : cur_w),
327 (cancel ? start_ch : cur_h),
331 /* dont edge warp after its ended */
334 render_plugin->moveresize_in_progress = FALSE;
335 moveresize_client = NULL;
338 static void do_move(gboolean keyboard, gint keydist)
342 if (keyboard) resist = keydist - 1; /* resist for one key press */
343 else resist = config_resist_win;
344 resist_move_windows(moveresize_client, resist, &cur_x, &cur_y);
345 if (!keyboard) resist = config_resist_edge;
346 resist_move_monitors(moveresize_client, resist, &cur_x, &cur_y);
348 client_configure(moveresize_client, cur_x, cur_y, cur_w, cur_h,
350 if (config_resize_popup_show == 2) /* == "Always" */
351 popup_coords(moveresize_client, "%d x %d",
352 render_plugin->frame_get_window_area(moveresize_client->frame).x,
353 render_plugin->frame_get_window_area(moveresize_client->frame).y);
357 static void do_resize(void)
359 gint x, y, w, h, lw, lh;
361 /* see if it is actually going to resize */
366 client_try_configure(moveresize_client, &x, &y, &w, &h,
368 if (w == moveresize_client->area.width &&
369 h == moveresize_client->area.height)
375 if (config_resize_redraw && obt_display_extension_sync &&
376 moveresize_client->sync_request && moveresize_client->sync_counter &&
377 !moveresize_client->not_responding)
382 /* are we already waiting for the sync counter to catch up? */
383 if (waiting_for_sync)
386 /* increment the value we're waiting for */
387 ++moveresize_client->sync_counter_value;
388 XSyncIntToValue(&val, moveresize_client->sync_counter_value);
390 /* tell the client what we're waiting for */
391 ce.xclient.type = ClientMessage;
392 ce.xclient.message_type = OBT_PROP_ATOM(WM_PROTOCOLS);
393 ce.xclient.display = obt_display;
394 ce.xclient.window = moveresize_client->w_client;
395 ce.xclient.format = 32;
396 ce.xclient.data.l[0] = OBT_PROP_ATOM(NET_WM_SYNC_REQUEST);
397 ce.xclient.data.l[1] = event_curtime;
398 ce.xclient.data.l[2] = XSyncValueLow32(val);
399 ce.xclient.data.l[3] = XSyncValueHigh32(val);
400 ce.xclient.data.l[4] = 0l;
401 XSendEvent(obt_display, moveresize_client->w_client, FALSE,
404 waiting_for_sync = TRUE;
406 obt_main_loop_timeout_remove(ob_main_loop, sync_timeout_func);
407 obt_main_loop_timeout_add(ob_main_loop, G_USEC_PER_SEC * 2,
413 client_configure(moveresize_client, cur_x, cur_y, cur_w, cur_h,
416 /* this would be better with a fixed width font ... XXX can do it better
417 if there are 2 text boxes */
418 if (config_resize_popup_show == 2 || /* == "Always" */
419 (config_resize_popup_show == 1 && /* == "Nonpixel" */
420 moveresize_client->size_inc.width > 1 &&
421 moveresize_client->size_inc.height > 1))
422 popup_coords(moveresize_client, "%d x %d",
423 moveresize_client->logical_size.width,
424 moveresize_client->logical_size.height);
428 static gboolean sync_timeout_func(gpointer data)
430 waiting_for_sync = FALSE; /* we timed out waiting for our sync... */
431 do_resize(); /* ...so let any pending resizes through */
433 return FALSE; /* don't repeat */
437 static void calc_resize(gboolean keyboard, gint keydist, gint *dw, gint *dh,
440 gint resist, x = 0, y = 0, lw, lh, ow, oh, nw, nh;
449 (moveresize_client->max_ratio || moveresize_client->min_ratio))
452 case OB_DIRECTION_NORTH:
453 case OB_DIRECTION_SOUTH:
454 /* resize the width based on the height */
455 if (moveresize_client->min_ratio) {
456 if (nh * moveresize_client->min_ratio > nw)
457 nw = (gint)(nh * moveresize_client->min_ratio);
459 if (moveresize_client->max_ratio) {
460 if (nh * moveresize_client->max_ratio < nw)
461 nw = (gint)(nh * moveresize_client->max_ratio);
465 /* resize the height based on the width */
466 if (moveresize_client->min_ratio) {
467 if (nh * moveresize_client->min_ratio > nw)
468 nh = (gint)(nw / moveresize_client->min_ratio);
470 if (moveresize_client->max_ratio) {
471 if (nh * moveresize_client->max_ratio < nw)
472 nh = (gint)(nw / moveresize_client->max_ratio);
477 /* see its actual size (apply aspect ratios) */
478 client_try_configure(moveresize_client, &x, &y, &nw, &nh, &lw, &lh,
485 Strut size = render_plugin->frame_get_size(moveresize_client->frame);
486 /* resist_size_* needs the frame size */
492 if (keyboard) resist = keydist - 1; /* resist for one key press */
493 else resist = config_resist_win;
494 resist_size_windows(moveresize_client, resist, &nw, &nh, dir);
495 if (!keyboard) resist = config_resist_edge;
496 resist_size_monitors(moveresize_client, resist, &nw, &nh, dir);
506 /* take aspect ratios into account for resistance */
508 (moveresize_client->max_ratio || moveresize_client->min_ratio))
510 if (*dh != trydh) { /* got resisted */
511 /* resize the width based on the height */
512 if (moveresize_client->min_ratio) {
513 if (nh * moveresize_client->min_ratio > nw)
514 nw = (gint)(nh * moveresize_client->min_ratio);
516 if (moveresize_client->max_ratio) {
517 if (nh * moveresize_client->max_ratio < nw)
518 nw = (gint)(nh * moveresize_client->max_ratio);
521 if (*dw != trydw) { /* got resisted */
522 /* resize the height based on the width */
523 if (moveresize_client->min_ratio) {
524 if (nh * moveresize_client->min_ratio > nw)
525 nh = (gint)(nw / moveresize_client->min_ratio);
527 if (moveresize_client->max_ratio) {
528 if (nh * moveresize_client->max_ratio < nw)
529 nh = (gint)(nw / moveresize_client->max_ratio);
534 /* make sure it's all valid */
535 client_try_configure(moveresize_client, &x, &y, &nw, &nh, &lw, &lh, TRUE);
541 static gboolean edge_warp_delay_func(gpointer data)
545 /* only fire every second time. so it's fast the first time, but slower
548 d = screen_find_desktop(screen_desktop, edge_warp_dir, TRUE, FALSE);
549 if (d != screen_desktop) screen_set_desktop(d, TRUE);
551 edge_warp_odd = !edge_warp_odd;
553 return TRUE; /* do repeat ! */
556 static void do_edge_warp(gint x, gint y)
561 if (!config_mouse_screenedgetime) return;
565 for (i = 0; i < screen_num_monitors; ++i) {
566 Rect *a = screen_physical_area_monitor(i);
567 if (x == RECT_LEFT(*a)) dir = OB_DIRECTION_WEST;
568 if (x == RECT_RIGHT(*a)) dir = OB_DIRECTION_EAST;
569 if (y == RECT_TOP(*a)) dir = OB_DIRECTION_NORTH;
570 if (y == RECT_BOTTOM(*a)) dir = OB_DIRECTION_SOUTH;
572 /* try check for xinerama boundaries */
573 if ((x + 1 == RECT_LEFT(*a) || x - 1 == RECT_RIGHT(*a)) &&
574 (dir == OB_DIRECTION_WEST || dir == OB_DIRECTION_EAST))
578 if ((y + 1 == RECT_TOP(*a) || y - 1 == RECT_BOTTOM(*a)) &&
579 (dir == OB_DIRECTION_NORTH || dir == OB_DIRECTION_SOUTH))
586 if (dir != edge_warp_dir) {
588 if (dir != (ObDirection)-1) {
589 edge_warp_odd = TRUE; /* switch on the first timeout */
590 obt_main_loop_timeout_add(ob_main_loop,
591 config_mouse_screenedgetime * 1000,
592 edge_warp_delay_func,
599 static void cancel_edge_warp(void)
601 obt_main_loop_timeout_remove(ob_main_loop, edge_warp_delay_func);
604 static void move_with_keys(gint keycode, gint state)
606 gint dx = 0, dy = 0, ox = cur_x, oy = cur_y;
607 gint opx, px, opy, py;
610 /* shift means jump to edge */
611 if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT)) {
615 if (keycode == ob_keycode(OB_KEY_RIGHT))
616 dir = OB_DIRECTION_EAST;
617 else if (keycode == ob_keycode(OB_KEY_LEFT))
618 dir = OB_DIRECTION_WEST;
619 else if (keycode == ob_keycode(OB_KEY_DOWN))
620 dir = OB_DIRECTION_SOUTH;
621 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
622 dir = OB_DIRECTION_NORTH;
624 client_find_move_directional(moveresize_client, dir, &x, &y);
625 dx = x - moveresize_client->area.x;
626 dy = y - moveresize_client->area.y;
628 /* control means fine grained */
630 obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_CONTROL))
637 if (keycode == ob_keycode(OB_KEY_RIGHT))
639 else if (keycode == ob_keycode(OB_KEY_LEFT))
641 else if (keycode == ob_keycode(OB_KEY_DOWN))
643 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
647 screen_pointer_pos(&opx, &opy);
648 XWarpPointer(obt_display, None, None, 0, 0, 0, 0, dx, dy);
649 /* steal the motion events this causes */
650 XSync(obt_display, FALSE);
653 while (XCheckTypedEvent(obt_display, MotionNotify, &ce));
655 screen_pointer_pos(&px, &py);
661 /* because the cursor moves even though the window does
662 not nessesarily (resistance), this adjusts where the curor
663 thinks it started so that it keeps up with where the window
665 start_x += (px - opx) - (cur_x - ox);
666 start_y += (py - opy) - (cur_y - oy);
669 static void resize_with_keys(gint keycode, gint state)
671 gint dw = 0, dh = 0, pdx = 0, pdy = 0, opx, opy, px, py;
672 gint dist = 0, resist = 0;
675 /* pick the edge if it needs to move */
676 if (keycode == ob_keycode(OB_KEY_RIGHT)) {
677 dir = OB_DIRECTION_EAST;
678 if (key_resize_edge != OB_DIRECTION_WEST &&
679 key_resize_edge != OB_DIRECTION_EAST)
681 key_resize_edge = OB_DIRECTION_EAST;
685 if (keycode == ob_keycode(OB_KEY_LEFT)) {
686 dir = OB_DIRECTION_WEST;
687 if (key_resize_edge != OB_DIRECTION_WEST &&
688 key_resize_edge != OB_DIRECTION_EAST)
690 key_resize_edge = OB_DIRECTION_WEST;
694 if (keycode == ob_keycode(OB_KEY_UP)) {
695 dir = OB_DIRECTION_NORTH;
696 if (key_resize_edge != OB_DIRECTION_NORTH &&
697 key_resize_edge != OB_DIRECTION_SOUTH)
699 key_resize_edge = OB_DIRECTION_NORTH;
703 if (keycode == ob_keycode(OB_KEY_DOWN)) {
704 dir = OB_DIRECTION_SOUTH;
705 if (key_resize_edge != OB_DIRECTION_NORTH &&
706 key_resize_edge != OB_DIRECTION_SOUTH)
708 key_resize_edge = OB_DIRECTION_SOUTH;
713 /* shift means jump to edge */
714 if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT)) {
717 if (keycode == ob_keycode(OB_KEY_RIGHT))
718 dir = OB_DIRECTION_EAST;
719 else if (keycode == ob_keycode(OB_KEY_LEFT))
720 dir = OB_DIRECTION_WEST;
721 else if (keycode == ob_keycode(OB_KEY_DOWN))
722 dir = OB_DIRECTION_SOUTH;
723 else /* if (keycode == ob_keycode(OB_KEY_UP)) */
724 dir = OB_DIRECTION_NORTH;
726 client_find_resize_directional(moveresize_client, key_resize_edge,
727 key_resize_edge == dir,
729 dw = w - moveresize_client->area.width;
730 dh = h - moveresize_client->area.height;
734 /* control means fine grained */
735 if (moveresize_client->size_inc.width > 1) {
736 distw = moveresize_client->size_inc.width;
740 obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_CONTROL))
749 if (moveresize_client->size_inc.height > 1) {
750 disth = moveresize_client->size_inc.height;
754 obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_CONTROL))
764 if (key_resize_edge == OB_DIRECTION_WEST) {
765 if (dir == OB_DIRECTION_WEST)
768 dw = -(dist = distw);
770 else if (key_resize_edge == OB_DIRECTION_EAST) {
771 if (dir == OB_DIRECTION_EAST)
774 dw = -(dist = distw);
776 else if (key_resize_edge == OB_DIRECTION_NORTH) {
777 if (dir == OB_DIRECTION_NORTH)
780 dh = -(dist = disth);
782 else /*if (key_resize_edge == OB_DIRECTION_SOUTH)*/ {
783 if (dir == OB_DIRECTION_SOUTH)
786 dh = -(dist = disth);
790 calc_resize(TRUE, resist, &dw, &dh, dir);
791 if (key_resize_edge == OB_DIRECTION_WEST)
793 else if (key_resize_edge == OB_DIRECTION_NORTH)
798 /* how to move the pointer to keep up with the change */
799 if (key_resize_edge == OB_DIRECTION_WEST)
801 else if (key_resize_edge == OB_DIRECTION_EAST)
803 else if (key_resize_edge == OB_DIRECTION_NORTH)
805 else if (key_resize_edge == OB_DIRECTION_SOUTH)
808 screen_pointer_pos(&opx, &opy);
809 XWarpPointer(obt_display, None, None, 0, 0, 0, 0, pdx, pdy);
810 /* steal the motion events this causes */
811 XSync(obt_display, FALSE);
814 while (XCheckTypedEvent(obt_display, MotionNotify, &ce));
816 screen_pointer_pos(&px, &py);
820 /* because the cursor moves even though the window does
821 not nessesarily (resistance), this adjusts where the cursor
822 thinks it started so that it keeps up with where the window
824 start_x += (px - opx) - dw;
825 start_y += (py - opy) - dh;
829 gboolean moveresize_event(XEvent *e)
831 gboolean used = FALSE;
833 if (!render_plugin->moveresize_in_progress) return FALSE;
835 if (e->type == ButtonPress) {
837 start_x = e->xbutton.x_root;
838 start_y = e->xbutton.y_root;
839 button = e->xbutton.button; /* this will end it now */
841 used = e->xbutton.button == button;
842 } else if (e->type == ButtonRelease) {
843 if (!button || e->xbutton.button == button) {
844 moveresize_end(FALSE);
847 } else if (e->type == MotionNotify) {
849 cur_x = start_cx + e->xmotion.x_root - start_x;
850 cur_y = start_cy + e->xmotion.y_root - start_y;
852 do_edge_warp(e->xmotion.x_root, e->xmotion.y_root);
857 if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPLEFT)) {
858 dw = -(e->xmotion.x_root - start_x);
859 dh = -(e->xmotion.y_root - start_y);
860 dir = OB_DIRECTION_NORTHWEST;
861 } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOP)) {
863 dh = -(e->xmotion.y_root - start_y);
864 dir = OB_DIRECTION_NORTH;
866 OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPRIGHT)) {
867 dw = (e->xmotion.x_root - start_x);
868 dh = -(e->xmotion.y_root - start_y);
869 dir = OB_DIRECTION_NORTHEAST;
870 } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_RIGHT)) {
871 dw = (e->xmotion.x_root - start_x);
873 dir = OB_DIRECTION_EAST;
875 OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT)) {
876 dw = (e->xmotion.x_root - start_x);
877 dh = (e->xmotion.y_root - start_y);
878 dir = OB_DIRECTION_SOUTHEAST;
879 } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOM))
882 dh = (e->xmotion.y_root - start_y);
883 dir = OB_DIRECTION_SOUTH;
885 OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT)) {
886 dw = -(e->xmotion.x_root - start_x);
887 dh = (e->xmotion.y_root - start_y);
888 dir = OB_DIRECTION_SOUTHWEST;
889 } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_LEFT)) {
890 dw = -(e->xmotion.x_root - start_x);
892 dir = OB_DIRECTION_WEST;
894 OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_KEYBOARD)) {
895 dw = (e->xmotion.x_root - start_x);
896 dh = (e->xmotion.y_root - start_y);
897 dir = OB_DIRECTION_SOUTHEAST;
899 g_assert_not_reached();
901 dw -= cur_w - start_cw;
902 dh -= cur_h - start_ch;
904 calc_resize(FALSE, 0, &dw, &dh, dir);
908 if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPLEFT) ||
909 corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_LEFT) ||
910 corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT))
914 if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPLEFT) ||
915 corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOP) ||
916 corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPRIGHT))
924 } else if (e->type == KeyPress) {
925 if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) {
926 moveresize_end(TRUE);
928 } else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN)) {
929 moveresize_end(FALSE);
931 } else if (e->xkey.keycode == ob_keycode(OB_KEY_RIGHT) ||
932 e->xkey.keycode == ob_keycode(OB_KEY_LEFT) ||
933 e->xkey.keycode == ob_keycode(OB_KEY_DOWN) ||
934 e->xkey.keycode == ob_keycode(OB_KEY_UP))
936 if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_KEYBOARD)) {
937 resize_with_keys(e->xkey.keycode, e->xkey.state);
940 OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE_KEYBOARD))
942 move_with_keys(e->xkey.keycode, e->xkey.state);
948 else if (e->type == obt_display_extension_sync_basep + XSyncAlarmNotify)
950 waiting_for_sync = FALSE; /* we got our sync... */
951 do_resize(); /* ...so try resize if there is more change pending */