]> Dogcows Code - chaz/openbox/blobdiff - openbox/moveresize.c
Change resizing terminals to work for top and left edges too, the code is a little...
[chaz/openbox] / openbox / moveresize.c
index da4d92f97c0aafa6abfafb20b37cf81c0bc66712..55a42c7fc6915d6fd8c09ef0f83bc670c2d4ae68 100644 (file)
@@ -54,7 +54,6 @@ static gint start_x, start_y, start_cx, start_cy, start_cw, start_ch;
 static gint cur_x, cur_y, cur_w, cur_h;
 static guint button;
 static guint32 corner;
-static ObCorner lockcorner;
 static ObDirection edge_warp_dir = -1;
 static ObDirection key_resize_edge = -1;
 #ifdef SYNC
@@ -65,11 +64,14 @@ static ObPopup *popup = NULL;
 
 static void do_edge_warp(gint x, gint y);
 static void cancel_edge_warp();
+#ifdef SYNC
+static gboolean sync_timeout_func(gpointer data);
+#endif
 
 static void client_dest(ObClient *client, gpointer data)
 {
     if (moveresize_client == client)
-        moveresize_end(TRUE);    
+        moveresize_end(TRUE);
 }
 
 void moveresize_startup(gboolean reconfig)
@@ -118,6 +120,8 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr)
     ObCursor cur;
     gboolean mv = (cnr == prop_atoms.net_wm_moveresize_move ||
                    cnr == prop_atoms.net_wm_moveresize_move_keyboard);
+    gint up = 1;
+    gint left = 1;
 
     if (moveresize_in_progress || !c->frame->visible ||
         !(mv ?
@@ -125,23 +129,28 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr)
           (c->functions & OB_CLIENT_FUNC_RESIZE)))
         return;
 
-    if (cnr == prop_atoms.net_wm_moveresize_size_topleft)
+    if (cnr == prop_atoms.net_wm_moveresize_size_topleft) {
         cur = OB_CURSOR_NORTHWEST;
-    else if (cnr == prop_atoms.net_wm_moveresize_size_top)
+        up = left = -1;
+    } else if (cnr == prop_atoms.net_wm_moveresize_size_top) {
         cur = OB_CURSOR_NORTH;
-    else if (cnr == prop_atoms.net_wm_moveresize_size_topright)
+        up = -1;
+    } else if (cnr == prop_atoms.net_wm_moveresize_size_topright) {
         cur = OB_CURSOR_NORTHEAST;
-    else if (cnr == prop_atoms.net_wm_moveresize_size_right)
+        up = -1;
+    } 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)
+    else if (cnr == prop_atoms.net_wm_moveresize_size_bottomleft) {
         cur = OB_CURSOR_SOUTHWEST;
-    else if (cnr == prop_atoms.net_wm_moveresize_size_left)
+        left = -1;
+    } else if (cnr == prop_atoms.net_wm_moveresize_size_left) {
         cur = OB_CURSOR_WEST;
-    else if (cnr == prop_atoms.net_wm_moveresize_size_keyboard)
+        left = -1;
+    } 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;
@@ -164,14 +173,14 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr)
     moveresize_client = c;
     start_cx = c->area.x;
     start_cy = c->area.y;
+    start_cw = c->area.width;
+    start_ch = c->area.height;
     /* these adjustments for the size_inc make resizing a terminal more
        friendly. you essentially start the resize in the middle of the
        increment instead of at 0, so you have to move half an increment
        either way instead of a full increment one and 1 px the other. */
-    start_cw = c->area.width + c->size_inc.width / 2;
-    start_ch = c->area.height + c->size_inc.height / 2;
-    start_x = x;
-    start_y = y;
+    start_x = x - (mv ? 0 : left * c->size_inc.width / 2);
+    start_y = y - (mv ? 0 : up * c->size_inc.height / 2);
     corner = cnr;
     button = b;
     key_resize_edge = -1;
@@ -192,7 +201,7 @@ void moveresize_start(ObClient *c, gint x, gint y, guint b, guint32 cnr)
     moveresize_in_progress = TRUE;
 
 #ifdef SYNC
-    if (config_resize_redraw && !moving && extensions_shape &&
+    if (config_resize_redraw && !moving && extensions_sync &&
         moveresize_client->sync_request && moveresize_client->sync_counter)
     {
         /* Initialize values for the resize syncing, and create an alarm for
@@ -251,6 +260,8 @@ void moveresize_end(gboolean cancel)
             XSyncDestroyAlarm(ob_display, moveresize_alarm);
             moveresize_alarm = None;
         }
+
+        ob_main_loop_timeout_remove(ob_main_loop, sync_timeout_func);
 #endif
 
         client_configure(moveresize_client,
@@ -286,6 +297,7 @@ static void do_move(gboolean keyboard, gint keydist)
                      moveresize_client->frame->area.y);
 }
 
+
 static void do_resize()
 {
     gint x, y, w, h, lw, lh;
@@ -333,6 +345,11 @@ static void do_resize()
                    NoEventMask, &ce);
 
         waiting_for_sync = TRUE;
+
+        ob_main_loop_timeout_remove(ob_main_loop, sync_timeout_func);
+        ob_main_loop_timeout_add(ob_main_loop, G_USEC_PER_SEC * 2,
+                                 sync_timeout_func,
+                                 NULL, NULL, NULL);
     }
 #endif
 
@@ -350,26 +367,113 @@ static void do_resize()
                      moveresize_client->logical_size.height);
 }
 
+#ifdef SYNC
+static gboolean sync_timeout_func(gpointer data)
+{
+    waiting_for_sync = FALSE; /* we timed out waiting for our sync... */
+    do_resize(); /* ...so let any pending resizes through */
+
+    return FALSE; /* don't repeat */
+}
+#endif
+
 static void calc_resize(gboolean keyboard, gint keydist, gint *dw, gint *dh,
-                        ObCorner cor)
+                        ObDirection dir)
 {
-    gint resist, ow, oh, nw, nh;
+    gint resist, x = 0, y = 0, lw, lh, ow, oh, nw, nh;
+    gint trydw, trydh;
+
+    ow = cur_w;
+    oh = cur_h;
+    nw = ow + *dw;
+    nh = oh + *dh;
+
+    if (!keyboard &&
+        (moveresize_client->max_ratio || moveresize_client->min_ratio))
+    {
+        switch (dir) {
+        case OB_DIRECTION_NORTH:
+        case OB_DIRECTION_SOUTH:
+            /* resize the width based on the height */
+            if (moveresize_client->min_ratio) {
+                if (nh * moveresize_client->min_ratio > nw)
+                    nw = (gint)(nh * moveresize_client->min_ratio);
+            }
+            if (moveresize_client->max_ratio) {
+                if (nh * moveresize_client->max_ratio < nw)
+                    nw = (gint)(nh * moveresize_client->max_ratio);
+            }
+            break;
+        default:
+            /* resize the height based on the width */
+            if (moveresize_client->min_ratio) {
+                if (nh * moveresize_client->min_ratio > nw)
+                    nh = (gint)(nw / moveresize_client->min_ratio);
+            }
+            if (moveresize_client->max_ratio) {
+                if (nh * moveresize_client->max_ratio < nw)
+                    nh = (gint)(nw / moveresize_client->max_ratio);
+            }
+            break;
+        }
+
+        /* see its actual size (apply aspect ratios) */
+        client_try_configure(moveresize_client, &x, &y, &nw, &nh, &lw, &lh,
+                             TRUE);
+        trydw = nw - ow;
+        trydh = nh - oh;
+    }
 
     /* resist_size_* needs the frame size */
-    ow = cur_w +
-        moveresize_client->frame->size.left +
+    nw += moveresize_client->frame->size.left +
         moveresize_client->frame->size.right;
-    oh = cur_h +
-        moveresize_client->frame->size.top +
+    nh += moveresize_client->frame->size.top +
         moveresize_client->frame->size.bottom;
-    nw = ow + *dw;
-    nh = oh + *dh;
 
     if (keyboard) resist = keydist - 1; /* resist for one key press */
     else resist = config_resist_win;
-    resist_size_windows(moveresize_client, resist, &nw, &nh, cor);
+    resist_size_windows(moveresize_client, resist, &nw, &nh, dir);
     if (!keyboard) resist = config_resist_edge;
-    resist_size_monitors(moveresize_client, resist, &nw, &nh, cor);
+    resist_size_monitors(moveresize_client, resist, &nw, &nh, dir);
+
+    nw -= moveresize_client->frame->size.left +
+        moveresize_client->frame->size.right;
+    nh -= moveresize_client->frame->size.top +
+        moveresize_client->frame->size.bottom;
+
+    *dw = nw - ow;
+    *dh = nh - oh;
+
+    /* take aspect ratios into account for resistance */
+    if (!keyboard &&
+        (moveresize_client->max_ratio || moveresize_client->min_ratio))
+    {
+        if (*dh != trydh) { /* got resisted */
+            /* resize the width based on the height */
+            if (moveresize_client->min_ratio) {
+                if (nh * moveresize_client->min_ratio > nw)
+                    nw = (gint)(nh * moveresize_client->min_ratio);
+            }
+            if (moveresize_client->max_ratio) {
+                if (nh * moveresize_client->max_ratio < nw)
+                    nw = (gint)(nh * moveresize_client->max_ratio);
+            }
+        }
+        if (*dw != trydw) { /* got resisted */
+            /* resize the height based on the width */
+            if (moveresize_client->min_ratio) {
+                if (nh * moveresize_client->min_ratio > nw)
+                    nh = (gint)(nw / moveresize_client->min_ratio);
+            }
+            if (moveresize_client->max_ratio) {
+                if (nh * moveresize_client->max_ratio < nw)
+                    nh = (gint)(nw / moveresize_client->max_ratio);
+            }
+        }
+    }
+
+    /* make sure it's all valid */
+    client_try_configure(moveresize_client, &x, &y, &nw, &nh, &lw, &lh, TRUE);
 
     *dw = nw - ow;
     *dh = nh - oh;
@@ -499,9 +603,8 @@ static void move_with_keys(gint keycode, gint state)
 static void resize_with_keys(gint keycode, gint state)
 {
     gint dw = 0, dh = 0, pdx = 0, pdy = 0, opx, opy, px, py;
-    gint dist = 0;
+    gint dist = 0, resist = 0;
     ObDirection dir;
-    ObCorner cor;
 
     /* pick the edge if it needs to move */
     if (keycode == ob_keycode(OB_KEY_RIGHT)) {
@@ -563,18 +666,30 @@ static void resize_with_keys(gint keycode, gint state)
         gint distw, disth;
 
         /* control means fine grained */
-        if (moveresize_client->size_inc.width > 1)
+        if (moveresize_client->size_inc.width > 1) {
             distw = moveresize_client->size_inc.width;
-        else if (state & modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL))
+            resist = 1;
+        }
+        else if (state & modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL)) {
             distw = 1;
-        else
+            resist = 1;
+        }
+        else {
             distw = KEY_DIST;
-        if (moveresize_client->size_inc.height > 1)
+            resist = KEY_DIST;
+        }
+        if (moveresize_client->size_inc.height > 1) {
             disth = moveresize_client->size_inc.height;
-        else if (state & modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL))
+            resist = 1;
+        }
+        else if (state & modkeys_key_to_mask(OB_MODKEY_KEY_CONTROL)) {
             disth = 1;
-        else
+            resist = 1;
+        }
+        else {
             disth = KEY_DIST;
+            resist = KEY_DIST;
+        }
 
         if (key_resize_edge == OB_DIRECTION_WEST) {
             if (dir == OB_DIRECTION_WEST)
@@ -602,17 +717,7 @@ static void resize_with_keys(gint keycode, gint state)
         }
     }
 
-    /* which corner is locked, for resistance */
-    if (key_resize_edge == OB_DIRECTION_WEST)
-        cor = OB_CORNER_TOPRIGHT;
-    else if (key_resize_edge == OB_DIRECTION_EAST)
-        cor = OB_CORNER_TOPLEFT;
-    else if (key_resize_edge == OB_DIRECTION_NORTH)
-        cor = OB_CORNER_BOTTOMLEFT;
-    else if (key_resize_edge == OB_DIRECTION_SOUTH)
-        cor = OB_CORNER_TOPLEFT;
-
-    calc_resize(TRUE, dist, &dw, &dh, cor);
+    calc_resize(TRUE, resist, &dw, &dh, dir);
     if (key_resize_edge == OB_DIRECTION_WEST)
         cur_x -= dw;
     else if (key_resize_edge == OB_DIRECTION_NORTH)
@@ -629,7 +734,7 @@ static void resize_with_keys(gint keycode, gint state)
         pdy = -dh;
     else if (key_resize_edge == OB_DIRECTION_SOUTH)
         pdy = dh;
-    
+
     screen_pointer_pos(&opx, &opy);
     XWarpPointer(ob_display, None, None, 0, 0, 0, 0, pdx, pdy);
     /* steal the motion events this causes */
@@ -677,52 +782,53 @@ gboolean moveresize_event(XEvent *e)
             do_edge_warp(e->xmotion.x_root, e->xmotion.y_root);
         } else {
             gint dw, dh;
+            ObDirection dir;
 
             if (corner == prop_atoms.net_wm_moveresize_size_topleft) {
                 dw = -(e->xmotion.x_root - start_x);
                 dh = -(e->xmotion.y_root - start_y);
-                lockcorner = OB_CORNER_BOTTOMRIGHT;
+                dir = OB_DIRECTION_NORTHWEST;
             } else if (corner == prop_atoms.net_wm_moveresize_size_top) {
                 dw = 0;
-                dh = (e->xmotion.y_root - start_y);
-                lockcorner = OB_CORNER_BOTTOMRIGHT;
+                dh = -(e->xmotion.y_root - start_y);
+                dir = OB_DIRECTION_NORTH;
             } else if (corner == prop_atoms.net_wm_moveresize_size_topright) {
                 dw = (e->xmotion.x_root - start_x);
                 dh = -(e->xmotion.y_root - start_y);
-                lockcorner = OB_CORNER_BOTTOMLEFT;
-            } else if (corner == prop_atoms.net_wm_moveresize_size_right) { 
+                dir = OB_DIRECTION_NORTHEAST;
+            } else if (corner == prop_atoms.net_wm_moveresize_size_right) {
                 dw = (e->xmotion.x_root - start_x);
                 dh = 0;
-                lockcorner = OB_CORNER_BOTTOMLEFT;
+                dir = OB_DIRECTION_EAST;
             } else if (corner ==
                        prop_atoms.net_wm_moveresize_size_bottomright) {
                 dw = (e->xmotion.x_root - start_x);
                 dh = (e->xmotion.y_root - start_y);
-                lockcorner = OB_CORNER_TOPLEFT;
+                dir = OB_DIRECTION_SOUTHEAST;
             } else if (corner == prop_atoms.net_wm_moveresize_size_bottom) {
                 dw = 0;
                 dh = (e->xmotion.y_root - start_y);
-                lockcorner = OB_CORNER_TOPLEFT;
+                dir = OB_DIRECTION_SOUTH;
             } else if (corner ==
                        prop_atoms.net_wm_moveresize_size_bottomleft) {
                 dw = -(e->xmotion.x_root - start_x);
                 dh = (e->xmotion.y_root - start_y);
-                lockcorner = OB_CORNER_TOPRIGHT;
+                dir = OB_DIRECTION_SOUTHWEST;
             } else if (corner == prop_atoms.net_wm_moveresize_size_left) {
                 dw = -(e->xmotion.x_root - start_x);
                 dh = 0;
-                lockcorner = OB_CORNER_TOPRIGHT;
+                dir = OB_DIRECTION_WEST;
             } else if (corner == prop_atoms.net_wm_moveresize_size_keyboard) {
                 dw = (e->xmotion.x_root - start_x);
                 dh = (e->xmotion.y_root - start_y);
-                lockcorner = OB_CORNER_TOPLEFT;
+                dir = OB_DIRECTION_SOUTHEAST;
             } else
                 g_assert_not_reached();
 
             dw -= cur_w - start_cw;
             dh -= cur_h - start_ch;
 
-            calc_resize(FALSE, 0, &dw, &dh, lockcorner);
+            calc_resize(FALSE, 0, &dw, &dh, dir);
             cur_w += dw;
             cur_h += dh;
 
This page took 0.031012 seconds and 4 git commands to generate.