warp desktops when you hit the edge of the screen while moving a window
This commit is contained in:
parent
d933f5c11f
commit
97792a403a
7 changed files with 128 additions and 44 deletions
|
@ -232,6 +232,10 @@
|
|||
<!-- number of pixels the mouse must move before a drag begins -->
|
||||
<doubleClickTime>200</doubleClickTime>
|
||||
<!-- in milliseconds (1000 = 1 second) -->
|
||||
<screenEdgeWarpTime>400</screenEdgeWarpTime>
|
||||
<!-- time before changing desktops when the pointer touches the edge of the
|
||||
screen while moving a window, in milliseconds (1000 = 1 second),
|
||||
0 disables warping -->
|
||||
|
||||
<context name="Frame">
|
||||
<mousebind button="A-Left" action="Press">
|
||||
|
|
|
@ -142,6 +142,7 @@
|
|||
<xsd:complexType name="mouse">
|
||||
<xsd:element minOccurs="0" name="dragThreshold" type="xsd:integer"/>
|
||||
<xsd:element minOccurs="0" name="doubleClickTime" type="xsd:integer"/>
|
||||
<xsd:element minOccurs="0" name="screenEdgeWarpTime" type="xsd:integer"/>
|
||||
<xsd:element maxOccurs="unbounded" name="context" type="ob:context"/>
|
||||
</xsd:complexType>
|
||||
<xsd:complexType name="menu">
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
show_cycle_dialog:
|
||||
if (dialog && !cancel && !done) {
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue