mirror of
https://github.com/labwc/labwc.git
synced 2025-11-04 13:30:07 -05:00
cursor: Fix "jumping opposite edges" issue when resizing
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.
This commit is contained in:
parent
47912aebb6
commit
8e1f115486
5 changed files with 59 additions and 78 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
40
src/cursor.c
40
src/cursor.c
|
|
@ -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)
|
||||
new_view_geo.height = server->grab_box.height - dy;
|
||||
else if (server->resize_edges & WLR_EDGE_BOTTOM)
|
||||
new_view_geo.height = server->grab_box.height + dy;
|
||||
|
||||
if (server->resize_edges & WLR_EDGE_LEFT)
|
||||
new_view_geo.width = server->grab_box.width - dx;
|
||||
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) {
|
||||
if (server->grab_box.height - dy < min_height) {
|
||||
dy = server->grab_box.height - min_height;
|
||||
}
|
||||
new_view_geo.y = server->grab_box.y + dy;
|
||||
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;
|
||||
}
|
||||
new_view_geo.height = server->grab_box.height + dy;
|
||||
/* 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) {
|
||||
if (server->grab_box.width - dx < min_width) {
|
||||
dx = server->grab_box.width - min_width;
|
||||
}
|
||||
new_view_geo.x = server->grab_box.x + dx;
|
||||
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;
|
||||
}
|
||||
new_view_geo.width = server->grab_box.width + dx;
|
||||
/* 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);
|
||||
|
|
|
|||
52
src/view.c
52
src/view.c
|
|
@ -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;
|
||||
}
|
||||
out:
|
||||
#endif
|
||||
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);
|
||||
|
||||
if (w) {
|
||||
*w = min_width;
|
||||
}
|
||||
if (h) {
|
||||
*h = min_height;
|
||||
min_width = MAX(1, hints->min_width);
|
||||
min_height = MAX(1, hints->min_height);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
*w = MAX(*w, min_width);
|
||||
*h = MAX(*h, min_height);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue