]> git.mdlowis.com Git - proto/labwc.git/commitdiff
cursor: Fix "jumping opposite edges" issue when resizing
authorJohn Lindgren <john@jlindgren.net>
Sun, 3 Apr 2022 01:34:51 +0000 (21:34 -0400)
committerJohan Malm <jgm323@gmail.com>
Mon, 4 Apr 2022 16:28:52 +0000 (17:28 +0100)
Commit 08c537e ("xwayland: Honor size increments from
WM_SIZE_HINTS") adjusted only the window width/height according
to the size hints.  If resizing from the top or left edge of the
window, we also need to adjust the window position to keep the
bottom or right edge from jumping around.

include/labwc.h
src/cursor.c
src/view.c
src/xdg.c
src/xwayland.c

index 44b4d34e67cb853b14a2222f5bf290fbe31a17a5..74c2167e58e579db0466f526a079f955f28d95fe 100644 (file)
@@ -408,7 +408,7 @@ void view_update_title(struct view *view);
 void view_update_app_id(struct view *view);
 
 void view_impl_map(struct view *view);
-void view_min_size(struct view *view, int *w, int *h);
+void view_adjust_size(struct view *view, int *w, int *h);
 
 void foreign_toplevel_handle_create(struct view *view);
 
index 41e091a809987fd20e6d57839d8b3b0c0c797513..87fc28eb035c05bd8137af926a9306e366814192 100644 (file)
@@ -149,32 +149,28 @@ process_cursor_resize(struct server *server, uint32_t time)
                .x = view->x, .y = view->y, .width = view->w, .height = view->h
        };
 
-       int min_width, min_height;
-       view_min_size(view, &min_width, &min_height);
-
-       if (server->resize_edges & WLR_EDGE_TOP) {
-               if (server->grab_box.height - dy < min_height) {
-                       dy = server->grab_box.height - min_height;
-               }
-               new_view_geo.y = server->grab_box.y + dy;
+       if (server->resize_edges & WLR_EDGE_TOP)
                new_view_geo.height = server->grab_box.height - dy;
-       } else if (server->resize_edges & WLR_EDGE_BOTTOM) {
-               if (server->grab_box.height + dy < min_height) {
-                       dy = min_height - server->grab_box.height;
-               }
+       else if (server->resize_edges & WLR_EDGE_BOTTOM)
                new_view_geo.height = server->grab_box.height + dy;
-       }
-       if (server->resize_edges & WLR_EDGE_LEFT) {
-               if (server->grab_box.width - dx < min_width) {
-                       dx = server->grab_box.width - min_width;
-               }
-               new_view_geo.x = server->grab_box.x + dx;
+
+       if (server->resize_edges & WLR_EDGE_LEFT)
                new_view_geo.width = server->grab_box.width - dx;
-       } else if (server->resize_edges & WLR_EDGE_RIGHT) {
-               if (server->grab_box.width + dx < min_width) {
-                       dx = min_width - server->grab_box.width;
-               }
+       else if (server->resize_edges & WLR_EDGE_RIGHT)
                new_view_geo.width = server->grab_box.width + dx;
+
+       view_adjust_size(view, &new_view_geo.width, &new_view_geo.height);
+
+       if (server->resize_edges & WLR_EDGE_TOP) {
+               /* anchor bottom edge */
+               new_view_geo.y = server->grab_box.y +
+                       server->grab_box.height - new_view_geo.height;
+       }
+
+       if (server->resize_edges & WLR_EDGE_LEFT) {
+               /* anchor right edge */
+               new_view_geo.x = server->grab_box.x +
+                       server->grab_box.width - new_view_geo.width;
        }
 
        resistance_resize_apply(view, &new_view_geo);
index 91c9aadc33e05b87888a3e214c5cd3c61885ca47..cfe9549b108e71f0fb476371c3802df0bcfd4e6d 100644 (file)
@@ -4,6 +4,8 @@
 #include "labwc.h"
 #include "ssd.h"
 
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
 void
 view_set_activated(struct view *view, bool activated)
 {
@@ -52,32 +54,44 @@ view_move_resize(struct view *view, struct wlr_box geo)
 #define MIN_VIEW_WIDTH (100)
 #define MIN_VIEW_HEIGHT (60)
 
+#if HAVE_XWAYLAND
+static int
+round_to_increment(int val, int base, int inc)
+{
+       if (base < 0 || inc <= 0)
+               return val;
+       return base + (val - base + inc / 2) / inc * inc;
+}
+#endif
+
 void
-view_min_size(struct view *view, int *w, int *h)
+view_adjust_size(struct view *view, int *w, int *h)
 {
        int min_width = MIN_VIEW_WIDTH;
        int min_height = MIN_VIEW_HEIGHT;
 #if HAVE_XWAYLAND
-       if (view->type != LAB_XWAYLAND_VIEW) {
-               goto out;
-       }
-       if (!view->xwayland_surface->size_hints) {
-               goto out;
-       }
-       if (view->xwayland_surface->size_hints->min_width > 0
-                       || view->xwayland_surface->size_hints->min_height > 0) {
-               min_width = view->xwayland_surface->size_hints->min_width;
-               min_height = view->xwayland_surface->size_hints->min_height;
+       if (view->type == LAB_XWAYLAND_VIEW) {
+               struct wlr_xwayland_surface_size_hints *hints =
+                       view->xwayland_surface->size_hints;
+               /*
+                * Honor size increments from WM_SIZE_HINTS. Typically, X11
+                * terminal emulators will use WM_SIZE_HINTS to make sure that
+                * the terminal is resized to a width/height evenly divisible by
+                * the cell (character) size.
+                */
+               if (hints) {
+                       *w = round_to_increment(*w, hints->base_width,
+                               hints->width_inc);
+                       *h = round_to_increment(*h, hints->base_height,
+                               hints->height_inc);
+
+                       min_width = MAX(1, hints->min_width);
+                       min_height = MAX(1, hints->min_height);
+               }
        }
-out:
 #endif
-
-       if (w) {
-               *w = min_width;
-       }
-       if (h) {
-               *h = min_height;
-       }
+       *w = MAX(*w, min_width);
+       *h = MAX(*h, min_height);
 }
 
 void
index 2e01a3c95e88f18bf677df916a87126949690a0b..0294bcad042c85cb0c8eb3078632cf42e593b3b4 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -170,19 +170,17 @@ handle_set_app_id(struct wl_listener *listener, void *data)
        view_update_app_id(view);
 }
 
-#define MAX(a, b)  (((a) > (b)) ? (a) : (b))
 static void
 xdg_toplevel_view_configure(struct view *view, struct wlr_box geo)
 {
-       int min_width, min_height;
-       view_min_size(view, &min_width, &min_height);
+       view_adjust_size(view, &geo.width, &geo.height);
 
        view->pending_move_resize.update_x = geo.x != view->x;
        view->pending_move_resize.update_y = geo.y != view->y;
        view->pending_move_resize.x = geo.x;
        view->pending_move_resize.y = geo.y;
-       view->pending_move_resize.width = MAX(geo.width, min_width);
-       view->pending_move_resize.height = MAX(geo.height, min_height);
+       view->pending_move_resize.width = geo.width;
+       view->pending_move_resize.height = geo.height;
 
        uint32_t serial = wlr_xdg_toplevel_set_size(view->xdg_surface->toplevel,
                (uint32_t)geo.width, (uint32_t)geo.height);
@@ -196,7 +194,6 @@ xdg_toplevel_view_configure(struct view *view, struct wlr_box geo)
                ssd_update_geometry(view);
        }
 }
-#undef MAX
 
 static void
 xdg_toplevel_view_move(struct view *view, double x, double y)
index 242553b5a102aff3a14f87e4d4bcef1368fb1b7e..c35f3c2137cbab93075bdbeb68b627c0ed7fd32b 100644 (file)
@@ -119,21 +119,19 @@ handle_destroy(struct wl_listener *listener, void *data)
        free(view);
 }
 
-#define MAX(a, b)  (((a) > (b)) ? (a) : (b))
 static void
 handle_request_configure(struct wl_listener *listener, void *data)
 {
        struct view *view = wl_container_of(listener, view, request_configure);
        struct wlr_xwayland_surface_configure_event *event = data;
 
-       int min_width, min_height;
-       view_min_size(view, &min_width, &min_height);
+       int width = event->width;
+       int height = event->height;
+       view_adjust_size(view, &width, &height);
 
        wlr_xwayland_surface_configure(view->xwayland_surface,
-               event->x, event->y, MAX(event->width, min_width),
-               MAX(event->height, min_height));
+               event->x, event->y, width, height);
 }
-#undef MAX
 
 static void
 handle_request_activate(struct wl_listener *listener, void *data)
@@ -185,33 +183,9 @@ handle_set_class(struct wl_listener *listener, void *data)
        view_update_app_id(view);
 }
 
-static int
-round_to_increment(int val, int base, int inc)
-{
-       if (base < 0 || inc <= 0) {
-               return val;
-       }
-       return base + (val - base + inc / 2) / inc * inc;
-}
-
 static void
 configure(struct view *view, struct wlr_box geo)
 {
-       /*
-        * Honor size increments from WM_SIZE_HINTS. Typically, X11 terminal
-        * emulators will use WM_SIZE_HINTS to make sure that the terminal is
-        * resized to a width/height evenly divisible by the cell (character)
-        * size.
-        */
-       struct wlr_xwayland_surface_size_hints *hints =
-               view->xwayland_surface->size_hints;
-       if (hints) {
-               geo.width = round_to_increment(geo.width,
-                       hints->base_width, hints->width_inc);
-               geo.height = round_to_increment(geo.height,
-                       hints->base_height, hints->height_inc);
-       }
-
        view->pending_move_resize.update_x = geo.x != view->x;
        view->pending_move_resize.update_y = geo.y != view->y;
        view->pending_move_resize.x = geo.x;