From 97792a403a52c12c2601a7b2caebdea197f0b5f0 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sat, 23 Jun 2007 19:52:09 +0000 Subject: [PATCH] warp desktops when you hit the edge of the screen while moving a window --- data/rc.xml | 4 +++ data/rc.xsd | 1 + openbox/config.c | 4 +++ openbox/config.h | 3 ++ openbox/moveresize.c | 68 +++++++++++++++++++++++++++++++++++++++ openbox/screen.c | 89 ++++++++++++++++++++++++++-------------------------- openbox/screen.h | 3 ++ 7 files changed, 128 insertions(+), 44 deletions(-) diff --git a/data/rc.xml b/data/rc.xml index 1a4230c..6bbc34a 100644 --- a/data/rc.xml +++ b/data/rc.xml @@ -232,6 +232,10 @@ 200 + 400 + diff --git a/data/rc.xsd b/data/rc.xsd index 3e6b312..89bed98 100644 --- a/data/rc.xsd +++ b/data/rc.xsd @@ -142,6 +142,7 @@ + diff --git a/openbox/config.c b/openbox/config.c index 51e169e..96f3ba8 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -79,6 +79,7 @@ guint config_keyboard_reset_state; gint config_mouse_threshold; gint config_mouse_dclicktime; +gint config_mouse_screenedgetime; guint config_menu_hide_delay; gboolean config_menu_middle; @@ -422,6 +423,8 @@ static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, config_mouse_threshold = parse_int(doc, n); if ((n = parse_find_node("doubleClickTime", node))) config_mouse_dclicktime = parse_int(doc, n); + if ((n = parse_find_node("screenEdgeWarpTime", node))) + config_mouse_screenedgetime = parse_int(doc, n); n = parse_find_node("context", node); while (n) { @@ -887,6 +890,7 @@ void config_startup(ObParseInst *i) config_mouse_threshold = 8; config_mouse_dclicktime = 200; + config_mouse_screenedgetime = 400; bind_default_mouse(); diff --git a/openbox/config.h b/openbox/config.h index e8c70eb..8a365f8 100644 --- a/openbox/config.h +++ b/openbox/config.h @@ -153,6 +153,9 @@ extern gint config_mouse_threshold; /*! Number of milliseconds within which 2 clicks must occur to be a double-click */ extern gint config_mouse_dclicktime; +/*! Number of milliseconds that the mouse has to be on the screen edge before + a screen edge event is triggered */ +extern gint config_mouse_screenedgetime; /*! Number of pixels to resist while crossing another window's edge */ extern gint config_resist_win; diff --git a/openbox/moveresize.c b/openbox/moveresize.c index 01cbb79..05c5f59 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -25,6 +25,7 @@ #include "frame.h" #include "openbox.h" #include "resist.h" +#include "mainloop.h" #include "popup.h" #include "moveresize.h" #include "config.h" @@ -53,12 +54,16 @@ static gint cur_x, cur_y; 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) @@ -302,6 +307,9 @@ void moveresize_end(gboolean cancel) TRUE, TRUE, FALSE); } + /* dont edge warp after its ended */ + cancel_edge_warp(); + moveresize_in_progress = FALSE; moveresize_client = NULL; } @@ -412,6 +420,65 @@ static void calc_resize(gboolean keyboard) 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; @@ -435,6 +502,7 @@ gboolean moveresize_event(XEvent *e) 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); diff --git a/openbox/screen.c b/openbox/screen.c index 926b21e..1a01bfb 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -49,7 +49,7 @@ #define ROOT_EVENTMASK (StructureNotifyMask | PropertyChangeMask | \ EnterWindowMask | LeaveWindowMask | \ SubstructureRedirectMask | FocusChangeMask | \ - ButtonPressMask | ButtonReleaseMask | ButtonMotionMask) + ButtonPressMask | ButtonReleaseMask) static gboolean screen_validate_layout(ObDesktopLayout *l); static gboolean replace_wm(); @@ -830,22 +830,14 @@ void screen_desktop_popup(guint d, gboolean show) } } -guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, - gboolean dialog, gboolean done, gboolean cancel) +guint screen_find_desktop(guint from, ObDirection dir, + gboolean wrap, gboolean linear) { guint r, c; - static guint d = (guint)-1; - guint ret, oldd; + guint d; - if (d == (guint)-1) - d = screen_desktop; - - if ((cancel || done) && dialog) - goto show_cycle_dialog; - - oldd = d; + d = from; get_row_col(d, &r, &c); - if (linear) { switch (dir) { case OB_DIRECTION_EAST: @@ -853,16 +845,20 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, ++d; else if (wrap) d = 0; + else + return from; break; case OB_DIRECTION_WEST: if (d > 0) --d; else if (wrap) d = screen_num_desktops - 1; + else + return from; break; default: - assert(0); - return screen_desktop; + g_assert_not_reached(); + return from; } } else { switch (dir) { @@ -872,16 +868,14 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, if (wrap) c = 0; else - goto show_cycle_dialog; + return from; } d = translate_row_col(r, c); if (d >= screen_num_desktops) { - if (wrap) { + if (wrap) ++c; - } else { - d = oldd; - goto show_cycle_dialog; - } + else + return from; } break; case OB_DIRECTION_WEST: @@ -890,16 +884,14 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, if (wrap) c = screen_desktop_layout.columns - 1; else - goto show_cycle_dialog; + return from; } d = translate_row_col(r, c); if (d >= screen_num_desktops) { - if (wrap) { + if (wrap) --c; - } else { - d = oldd; - goto show_cycle_dialog; - } + else + return from; } break; case OB_DIRECTION_SOUTH: @@ -908,16 +900,14 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, if (wrap) r = 0; else - goto show_cycle_dialog; + return from; } d = translate_row_col(r, c); if (d >= screen_num_desktops) { - if (wrap) { + if (wrap) ++r; - } else { - d = oldd; - goto show_cycle_dialog; - } + else + return from; } break; case OB_DIRECTION_NORTH: @@ -926,30 +916,41 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, if (wrap) r = screen_desktop_layout.rows - 1; else - goto show_cycle_dialog; + return from; } d = translate_row_col(r, c); if (d >= screen_num_desktops) { - if (wrap) { + if (wrap) --r; - } else { - d = oldd; - goto show_cycle_dialog; - } + else + return from; } break; default: - assert(0); - return d = screen_desktop; + g_assert_not_reached(); + return from; } d = translate_row_col(r, c); } + return d; +} + +guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, + gboolean dialog, gboolean done, gboolean cancel) +{ + static guint d = (guint)-1; + guint ret; + + if (d == (guint)-1) + d = screen_desktop; -show_cycle_dialog: - if (dialog && !cancel && !done) { + if ((!cancel && !done) || !dialog) + d = screen_find_desktop(d, dir, wrap, linear); + + if (dialog && !cancel && !done) screen_desktop_popup(d, TRUE); - } else + else screen_desktop_popup(0, FALSE); ret = d; diff --git a/openbox/screen.h b/openbox/screen.h index 041d9cc..c2c57f0 100644 --- a/openbox/screen.h +++ b/openbox/screen.h @@ -76,6 +76,9 @@ void screen_remove_desktop(gboolean current); guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, gboolean dialog, gboolean done, gboolean cancel); +guint screen_find_desktop(guint from, ObDirection dir, + gboolean wrap, gboolean linear); + /*! Show/hide the desktop popup (pager) for the given desktop */ void screen_desktop_popup(guint d, gboolean show); -- 1.9.1