]> Dogcows Code - chaz/openbox/blobdiff - openbox/moveresize.c
rewrote the movetoedge code so it works with both types of edges (to edge and from...
[chaz/openbox] / openbox / moveresize.c
index 837f3e92feec451dd59993944d42fa9f785fc36e..19bed579d234d2a9124c86a0ef1ac67d5860e977 100644 (file)
@@ -25,6 +25,8 @@
 #include "frame.h"
 #include "openbox.h"
 #include "resist.h"
+#include "mainloop.h"
+#include "modkeys.h"
 #include "popup.h"
 #include "moveresize.h"
 #include "config.h"
@@ -38,7 +40,7 @@
 #include <glib.h>
 
 /* how far windows move and resize with the keyboard arrows */
-#define KEY_DIST 4
+#define KEY_DIST 8
 
 gboolean moveresize_in_progress = FALSE;
 ObClient *moveresize_client = NULL;
@@ -53,12 +55,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)
@@ -68,6 +74,7 @@ static void client_dest(ObClient *client, gpointer data)
 void moveresize_startup(gboolean reconfig)
 {
     popup = popup_new(FALSE);
+    popup_set_text_align(popup, RR_JUSTIFY_CENTER);
 
     if (!reconfig)
         client_add_destroy_notify(client_dest, NULL);
@@ -104,7 +111,7 @@ static void get_resize_position(gint *x, gint *y, gboolean cancel)
     /* 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);
     }
@@ -126,7 +133,7 @@ static void get_resize_position(gint *x, gint *y, gboolean cancel)
         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)
@@ -152,12 +159,11 @@ 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;
@@ -197,6 +203,7 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr)
 
     frame_end_iconify_animation(c->frame);
 
+    moving = mv;
     moveresize_client = c;
     start_cx = c->area.x;
     start_cy = c->area.y;
@@ -297,9 +304,13 @@ void moveresize_end(gboolean cancel)
         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;
 }
@@ -316,7 +327,8 @@ static void do_move(gboolean keyboard)
 
     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,
@@ -325,31 +337,32 @@ static void do_move(gboolean keyboard)
 
 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);
@@ -372,11 +385,8 @@ static void do_resize()
     }
 #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 */
@@ -411,11 +421,70 @@ 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;
+    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) {
@@ -434,6 +503,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);
@@ -528,15 +598,41 @@ gboolean moveresize_event(XEvent *e)
             } else if (corner == prop_atoms.net_wm_moveresize_move_keyboard) {
                 gint dx = 0, dy = 0, ox = cur_x, oy = cur_y;
                 gint opx, px, opy, py;
-
-                if (e->xkey.keycode == ob_keycode(OB_KEY_RIGHT))
-                    dx = KEY_DIST;
-                else if (e->xkey.keycode == ob_keycode(OB_KEY_LEFT))
-                    dx = -KEY_DIST;
-                else if (e->xkey.keycode == ob_keycode(OB_KEY_DOWN))
-                    dy = KEY_DIST;
-                else /* if (e->xkey.keycode == ob_keycode(OB_KEY_UP)) */
-                    dy = -KEY_DIST;
+                gint dist = KEY_DIST;
+
+                /* shift means jump to edge */
+                if (e->xkey.state & modkeys_key_to_mask(OB_MODKEY_KEY_SHIFT)) {
+                    gint x, y;
+                    ObDirection dir;
+
+                    if (e->xkey.keycode == ob_keycode(OB_KEY_RIGHT))
+                        dir = OB_DIRECTION_EAST;
+                    else if (e->xkey.keycode == ob_keycode(OB_KEY_LEFT))
+                        dir = OB_DIRECTION_WEST;
+                    else if (e->xkey.keycode == ob_keycode(OB_KEY_DOWN))
+                        dir = OB_DIRECTION_SOUTH;
+                    else /* if (e->xkey.keycode == ob_keycode(OB_KEY_UP)) */
+                        dir = OB_DIRECTION_NORTH;
+
+                    client_find_move_directional(moveresize_client, dir,
+                                                 &x, &y);
+                    dx = x - moveresize_client->area.x;
+                    dy = y - moveresize_client->area.y;
+                } else {
+                    /* control means fine grained */
+                    if (e->xkey.state &
+                        modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL))
+                        dist = 1;
+
+                    if (e->xkey.keycode == ob_keycode(OB_KEY_RIGHT))
+                        dx = dist;
+                    else if (e->xkey.keycode == ob_keycode(OB_KEY_LEFT))
+                        dx = -dist;
+                    else if (e->xkey.keycode == ob_keycode(OB_KEY_DOWN))
+                        dy = dist;
+                    else /* if (e->xkey.keycode == ob_keycode(OB_KEY_UP)) */
+                        dy = -dist;
+                }
 
                 cur_x += dx;
                 cur_y += dy;
This page took 0.026902 seconds and 4 git commands to generate.