#include "frame.h"
#include "openbox.h"
#include "resist.h"
+#include "mainloop.h"
#include "popup.h"
#include "moveresize.h"
#include "config.h"
static guint button;
static guint32 corner;
static ObCorner lockcorner;
+static ObDirection edge_warp_dir = -1;
#ifdef SYNC
static gboolean waiting_for_sync;
#endif
static ObPopup *popup = NULL;
+static void do_edge_warp(gint x, gint y);
+static void cancel_edge_warp();
+
static void client_dest(ObClient *client, gpointer data)
{
if (moveresize_client == client)
void moveresize_startup(gboolean reconfig)
{
popup = popup_new(FALSE);
+ popup_set_text_align(popup, RR_JUSTIFY_CENTER);
if (!reconfig)
- client_add_destructor(client_dest, NULL);
+ client_add_destroy_notify(client_dest, NULL);
}
void moveresize_shutdown(gboolean reconfig)
if (!reconfig) {
if (moveresize_in_progress)
moveresize_end(FALSE);
- client_remove_destructor(client_dest);
+ client_remove_destroy_notify(client_dest);
}
popup_free(popup);
/* see how much it is actually going to resize */
{
gint cx = *x, cy = *y;
- frame_frame_gravity(moveresize_client->frame, &cx, &cy, w, h);
+ frame_frame_gravity(moveresize_client->frame, &cx, &cy);
client_try_configure(moveresize_client, &cx, &cy, &w, &h,
&lw, &lh, TRUE);
}
break;
}
- frame_frame_gravity(moveresize_client->frame, x, y, w, h);
+ frame_frame_gravity(moveresize_client->frame, x, y);
}
static void popup_coords(ObClient *c, const gchar *format, gint a, gint b)
void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr)
{
ObCursor cur;
-
- moving = (cnr == prop_atoms.net_wm_moveresize_move ||
- cnr == prop_atoms.net_wm_moveresize_move_keyboard);
+ gboolean mv = (cnr == prop_atoms.net_wm_moveresize_move ||
+ cnr == prop_atoms.net_wm_moveresize_move_keyboard);
if (moveresize_in_progress || !c->frame->visible ||
- !(moving ?
+ !(mv ?
(c->functions & OB_CLIENT_FUNC_MOVE) :
(c->functions & OB_CLIENT_FUNC_RESIZE)))
return;
+ if (cnr == prop_atoms.net_wm_moveresize_size_topleft)
+ cur = OB_CURSOR_NORTHWEST;
+ else if (cnr == prop_atoms.net_wm_moveresize_size_top)
+ cur = OB_CURSOR_NORTH;
+ else if (cnr == prop_atoms.net_wm_moveresize_size_topright)
+ cur = OB_CURSOR_NORTHEAST;
+ else if (cnr == prop_atoms.net_wm_moveresize_size_right)
+ cur = OB_CURSOR_EAST;
+ else if (cnr == prop_atoms.net_wm_moveresize_size_bottomright)
+ cur = OB_CURSOR_SOUTHEAST;
+ else if (cnr == prop_atoms.net_wm_moveresize_size_bottom)
+ cur = OB_CURSOR_SOUTH;
+ else if (cnr == prop_atoms.net_wm_moveresize_size_bottomleft)
+ cur = OB_CURSOR_SOUTHWEST;
+ else if (cnr == prop_atoms.net_wm_moveresize_size_left)
+ cur = OB_CURSOR_WEST;
+ else if (cnr == prop_atoms.net_wm_moveresize_size_keyboard)
+ cur = OB_CURSOR_SOUTHEAST;
+ else if (cnr == prop_atoms.net_wm_moveresize_move)
+ cur = OB_CURSOR_MOVE;
+ else if (cnr == prop_atoms.net_wm_moveresize_move_keyboard)
+ cur = OB_CURSOR_MOVE;
+ else
+ g_assert_not_reached();
+
+ /* keep the pointer bounded to the screen for move/resize */
+ if (!grab_pointer(FALSE, TRUE, cur))
+ return;
+ if (!grab_keyboard()) {
+ ungrab_pointer();
+ return;
+ }
+
frame_end_iconify_animation(c->frame);
+ moving = mv;
moveresize_client = c;
start_cx = c->area.x;
start_cy = c->area.y;
moveresize_in_progress = TRUE;
- if (corner == prop_atoms.net_wm_moveresize_size_topleft)
- cur = OB_CURSOR_NORTHWEST;
- else if (corner == prop_atoms.net_wm_moveresize_size_top)
- cur = OB_CURSOR_NORTH;
- else if (corner == prop_atoms.net_wm_moveresize_size_topright)
- cur = OB_CURSOR_NORTHEAST;
- else if (corner == prop_atoms.net_wm_moveresize_size_right)
- cur = OB_CURSOR_EAST;
- else if (corner == prop_atoms.net_wm_moveresize_size_bottomright)
- cur = OB_CURSOR_SOUTHEAST;
- else if (corner == prop_atoms.net_wm_moveresize_size_bottom)
- cur = OB_CURSOR_SOUTH;
- else if (corner == prop_atoms.net_wm_moveresize_size_bottomleft)
- cur = OB_CURSOR_SOUTHWEST;
- else if (corner == prop_atoms.net_wm_moveresize_size_left)
- cur = OB_CURSOR_WEST;
- else if (corner == prop_atoms.net_wm_moveresize_size_keyboard)
- cur = OB_CURSOR_SOUTHEAST;
- else if (corner == prop_atoms.net_wm_moveresize_move)
- cur = OB_CURSOR_MOVE;
- else if (corner == prop_atoms.net_wm_moveresize_move_keyboard)
- cur = OB_CURSOR_MOVE;
- else
- g_assert_not_reached();
-
#ifdef SYNC
if (config_resize_redraw && !moving && extensions_shape &&
moveresize_client->sync_request && moveresize_client->sync_counter)
waiting_for_sync = FALSE;
}
#endif
-
- grab_pointer(TRUE, FALSE, cur);
- grab_keyboard(TRUE);
}
void moveresize_end(gboolean cancel)
{
gint x, y;
- grab_keyboard(FALSE);
- grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
+ ungrab_keyboard();
+ ungrab_pointer();
popup_hide(popup);
get_resize_position(&x, &y, cancel);
client_configure(moveresize_client, x, y,
(cancel ? start_cw : cur_x),
- (cancel ? start_ch : cur_y), TRUE, TRUE);
+ (cancel ? start_ch : cur_y),
+ TRUE, TRUE, FALSE);
}
+ /* dont edge warp after its ended */
+ cancel_edge_warp();
+
moveresize_in_progress = FALSE;
moveresize_client = NULL;
}
client_configure(moveresize_client, cur_x, cur_y,
moveresize_client->area.width,
- moveresize_client->area.height, TRUE, FALSE);
+ moveresize_client->area.height,
+ TRUE, FALSE, FALSE);
if (config_resize_popup_show == 2) /* == "Always" */
popup_coords(moveresize_client, "%d x %d",
moveresize_client->frame->area.x,
static void do_resize()
{
+ gint x, y, w, h, lw, lh;
+
+ /* see if it is actually going to resize */
+ x = 0;
+ y = 0;
+ w = cur_x;
+ h = cur_y;
+ client_try_configure(moveresize_client, &x, &y, &w, &h,
+ &lw, &lh, TRUE);
+ if (w == moveresize_client->area.width &&
+ h == moveresize_client->area.height)
+ {
+ return;
+ }
+
#ifdef SYNC
if (config_resize_redraw && extensions_sync &&
moveresize_client->sync_request && moveresize_client->sync_counter)
{
XEvent ce;
XSyncValue val;
- gint x, y, w, h, lw, lh;
/* are we already waiting for the sync counter to catch up? */
if (waiting_for_sync)
return;
- /* see if it is actually going to resize */
- x = 0;
- y = 0;
- w = cur_x;
- h = cur_y;
- client_try_configure(moveresize_client, &x, &y, &w, &h,
- &lw, &lh, TRUE);
- if (w == moveresize_client->area.width &&
- h == moveresize_client->area.height)
- {
- return;
- }
-
/* increment the value we're waiting for */
++moveresize_client->sync_counter_value;
XSyncIntToValue(&val, moveresize_client->sync_counter_value);
}
#endif
- {
- gint x, y;
- get_resize_position(&x, &y, FALSE);
- client_configure(moveresize_client, x, y, cur_x, cur_y, TRUE, FALSE);
- }
+ get_resize_position(&x, &y, FALSE);
+ client_configure(moveresize_client, x, y, cur_x, cur_y, TRUE, FALSE, FALSE);
/* this would be better with a fixed width font ... XXX can do it better
if there are 2 text boxes */
moveresize_client->frame->size.bottom;
}
+static gboolean edge_warp_delay_func(gpointer data)
+{
+ guint d;
+
+ d = screen_find_desktop(screen_desktop, edge_warp_dir, TRUE, FALSE);
+ if (d != screen_desktop) screen_set_desktop(d, TRUE);
+
+ edge_warp_dir = -1;
+
+ return FALSE; /* don't repeat */
+}
+
+static void do_edge_warp(gint x, gint y)
+{
+ guint i, d;
+ ObDirection dir;
+
+ if (!config_mouse_screenedgetime) return;
+
+ dir = -1;
+
+ for (i = 0; i < screen_num_monitors; ++i) {
+ Rect *a = screen_physical_area_monitor(i);
+ if (x == RECT_LEFT(*a)) dir = OB_DIRECTION_WEST;
+ if (x == RECT_RIGHT(*a)) dir = OB_DIRECTION_EAST;
+ if (y == RECT_TOP(*a)) dir = OB_DIRECTION_NORTH;
+ if (y == RECT_BOTTOM(*a)) dir = OB_DIRECTION_SOUTH;
+
+ /* try check for xinerama boundaries */
+ if ((x + 1 == RECT_LEFT(*a) || x - 1 == RECT_RIGHT(*a)) &&
+ (dir == OB_DIRECTION_WEST || dir == OB_DIRECTION_EAST))
+ {
+ dir = -1;
+ }
+ if ((y + 1 == RECT_TOP(*a) || y - 1 == RECT_BOTTOM(*a)) &&
+ (dir == OB_DIRECTION_NORTH || dir == OB_DIRECTION_SOUTH))
+ {
+ dir = -1;
+ }
+ g_free(a);
+ }
+
+ if (dir != edge_warp_dir) {
+ if (dir == (ObDirection)-1)
+ cancel_edge_warp();
+ else
+ ob_main_loop_timeout_add(ob_main_loop,
+ config_mouse_screenedgetime * 1000,
+ edge_warp_delay_func,
+ NULL, NULL, NULL);
+ edge_warp_dir = dir;
+ }
+}
+
+static void cancel_edge_warp()
+{
+ ob_main_loop_timeout_remove(ob_main_loop, edge_warp_delay_func);
+}
+
gboolean moveresize_event(XEvent *e)
{
gboolean used = FALSE;
- g_assert(moveresize_in_progress);
+ if (!moveresize_in_progress) return FALSE;
if (e->type == ButtonPress) {
if (!button) {
cur_x = start_cx + e->xmotion.x_root - start_x;
cur_y = start_cy + e->xmotion.y_root - start_y;
do_move(FALSE);
+ do_edge_warp(e->xmotion.x_root, e->xmotion.y_root);
} else {
if (corner == prop_atoms.net_wm_moveresize_size_topleft) {
cur_x = start_cw - (e->xmotion.x_root - start_x);