<!-- 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">
<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">
gint config_mouse_threshold;
gint config_mouse_dclicktime;
+gint config_mouse_screenedgetime;
guint config_menu_hide_delay;
gboolean config_menu_middle;
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) {
config_mouse_threshold = 8;
config_mouse_dclicktime = 200;
+ config_mouse_screenedgetime = 400;
bind_default_mouse();
/*! 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;
#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)
TRUE, TRUE, FALSE);
}
+ /* dont edge warp after its ended */
+ cancel_edge_warp();
+
moveresize_in_progress = FALSE;
moveresize_client = NULL;
}
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;
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);
#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();
}
}
-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:
++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) {
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:
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:
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:
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;
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);