diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd
index 1c160a45..c274a0d2 100644
--- a/docs/labwc-config.5.scd
+++ b/docs/labwc-config.5.scd
@@ -576,6 +576,12 @@ extending outward from the snapped edge.
outlined rectangle is shown to indicate the geometry of resized window.
Default is yes.
+**
+ The size of corner regions to which the 'TLCorner', 'TRCorner',
+ 'BLCorner' and 'RLCorner' mousebind contexts apply, as well as the size
+ of the border region for which mouse resizing will apply both
+ horizontally and vertically rather than one or the other. Default is 8.
+
## KEYBOARD
** [on|off]
diff --git a/docs/rc.xml.all b/docs/rc.xml.all
index 16f5c212..02a9be9e 100644
--- a/docs/rc.xml.all
+++ b/docs/rc.xml.all
@@ -131,6 +131,7 @@
Never
yes
+ 8
diff --git a/include/config/rcxml.h b/include/config/rcxml.h
index 9aa6c9ba..264326e6 100644
--- a/include/config/rcxml.h
+++ b/include/config/rcxml.h
@@ -151,6 +151,7 @@ struct rcxml {
enum resize_indicator_mode resize_indicator;
bool resize_draw_contents;
+ int resize_corner_range;
struct {
int popuptime;
diff --git a/include/ssd.h b/include/ssd.h
index fe56be54..3c023121 100644
--- a/include/ssd.h
+++ b/include/ssd.h
@@ -5,6 +5,8 @@
#include
#include "common/border.h"
+struct wlr_cursor;
+
#define SSD_EXTENDED_AREA 8
/*
@@ -107,10 +109,8 @@ enum ssd_part_type ssd_button_get_type(const struct ssd_button *button);
struct view *ssd_button_get_view(const struct ssd_button *button);
/* Public SSD helpers */
-enum ssd_part_type ssd_at(const struct ssd *ssd,
- struct wlr_scene *scene, double lx, double ly);
enum ssd_part_type ssd_get_part_type(const struct ssd *ssd,
- struct wlr_scene_node *node);
+ struct wlr_scene_node *node, struct wlr_cursor *cursor);
uint32_t ssd_resize_edges(enum ssd_part_type type);
bool ssd_part_contains(enum ssd_part_type whole, enum ssd_part_type candidate);
enum ssd_mode ssd_mode_parse(const char *mode);
diff --git a/src/config/rcxml.c b/src/config/rcxml.c
index 0dfdc604..2193336c 100644
--- a/src/config/rcxml.c
+++ b/src/config/rcxml.c
@@ -1220,6 +1220,8 @@ entry(xmlNode *node, char *nodename, char *content)
}
} else if (!strcasecmp(nodename, "drawContents.resize")) {
set_bool(content, &rc.resize_draw_contents);
+ } else if (!strcasecmp(nodename, "cornerRange.resize")) {
+ rc.resize_corner_range = MAX(0, atoi(content));
} else if (!strcasecmp(nodename, "mouseEmulation.tablet")) {
set_bool(content, &rc.tablet.force_mouse_emulation);
} else if (!strcasecmp(nodename, "mapToOutput.tablet")) {
@@ -1492,6 +1494,7 @@ rcxml_init(void)
rc.resize_indicator = LAB_RESIZE_INDICATOR_NEVER;
rc.resize_draw_contents = true;
+ rc.resize_corner_range = 8;
rc.workspace_config.popuptime = INT_MIN;
rc.workspace_config.min_nr_workspaces = 1;
diff --git a/src/desktop.c b/src/desktop.c
index 5a78bffa..e3380705 100644
--- a/src/desktop.c
+++ b/src/desktop.c
@@ -278,7 +278,8 @@ get_cursor_context(struct server *server)
case LAB_NODE_DESC_VIEW:
case LAB_NODE_DESC_XDG_POPUP:
ret.view = desc->data;
- ret.type = ssd_get_part_type(ret.view->ssd, ret.node);
+ ret.type = ssd_get_part_type(
+ ret.view->ssd, ret.node, cursor);
if (ret.type == LAB_SSD_CLIENT) {
ret.surface = lab_wlr_surface_from_node(ret.node);
}
diff --git a/src/ssd/ssd-extents.c b/src/ssd/ssd-extents.c
index 1a0ed351..e88b58ea 100644
--- a/src/ssd/ssd-extents.c
+++ b/src/ssd/ssd-extents.c
@@ -37,17 +37,10 @@ ssd_extents_create(struct ssd *ssd)
-(theme->border_width + extended_area),
-(ssd->titlebar.height + theme->border_width + extended_area));
- /* Top */
- add_extent(part_list, LAB_SSD_PART_CORNER_TOP_LEFT, parent);
add_extent(part_list, LAB_SSD_PART_TOP, parent);
- add_extent(part_list, LAB_SSD_PART_CORNER_TOP_RIGHT, parent);
- /* Sides */
add_extent(part_list, LAB_SSD_PART_LEFT, parent);
add_extent(part_list, LAB_SSD_PART_RIGHT, parent);
- /* Bottom */
- add_extent(part_list, LAB_SSD_PART_CORNER_BOTTOM_LEFT, parent);
add_extent(part_list, LAB_SSD_PART_BOTTOM, parent);
- add_extent(part_list, LAB_SSD_PART_CORNER_BOTTOM_RIGHT, parent);
/* Initial manual update to keep X11 applications happy */
ssd_extents_update(ssd);
@@ -76,11 +69,6 @@ ssd_extents_update(struct ssd *ssd)
int full_height = height + theme->border_width * 2 + ssd->titlebar.height;
int full_width = width + 2 * theme->border_width;
int extended_area = SSD_EXTENDED_AREA;
- int corner_width = ssd_get_corner_width();
- int corner_size = extended_area + theme->border_width +
- MIN(corner_width, width) / 2;
- int side_width = full_width + extended_area * 2 - corner_size * 2;
- int side_height = full_height + extended_area * 2 - corner_size * 2;
struct wlr_box part_box;
struct wlr_box result_box;
@@ -120,54 +108,30 @@ ssd_extents_update(struct ssd *ssd)
wl_list_for_each(part, &ssd->extents.parts, link) {
rect = wlr_scene_rect_from_node(part->node);
switch (part->type) {
- case LAB_SSD_PART_CORNER_TOP_LEFT:
+ case LAB_SSD_PART_TOP:
target.x = 0;
target.y = 0;
- target.width = corner_size;
- target.height = corner_size;
- break;
- case LAB_SSD_PART_TOP:
- target.x = corner_size;
- target.y = 0;
- target.width = side_width;
+ target.width = full_width + extended_area * 2;
target.height = extended_area;
break;
- case LAB_SSD_PART_CORNER_TOP_RIGHT:
- target.x = corner_size + side_width;
- target.y = 0;
- target.width = corner_size;
- target.height = corner_size;
- break;
case LAB_SSD_PART_LEFT:
target.x = 0;
- target.y = corner_size;
+ target.y = extended_area;
target.width = extended_area;
- target.height = side_height;
+ target.height = full_height;
break;
case LAB_SSD_PART_RIGHT:
target.x = extended_area + full_width;
- target.y = corner_size;
+ target.y = extended_area;
target.width = extended_area;
- target.height = side_height;
- break;
- case LAB_SSD_PART_CORNER_BOTTOM_LEFT:
- target.x = 0;
- target.y = corner_size + side_height;
- target.width = corner_size;
- target.height = corner_size;
+ target.height = full_height;
break;
case LAB_SSD_PART_BOTTOM:
- target.x = corner_size;
+ target.x = 0;
target.y = extended_area + full_height;
- target.width = side_width;
+ target.width = full_width + extended_area * 2;
target.height = extended_area;
break;
- case LAB_SSD_PART_CORNER_BOTTOM_RIGHT:
- target.x = corner_size + side_width;
- target.y = corner_size + side_height;
- target.width = corner_size;
- target.height = corner_size;
- break;
default:
/* not reached */
assert(false);
diff --git a/src/ssd/ssd.c b/src/ssd/ssd.c
index 49f088b7..ae2c06de 100644
--- a/src/ssd/ssd.c
+++ b/src/ssd/ssd.c
@@ -74,8 +74,63 @@ ssd_max_extents(struct view *view)
};
}
+/*
+ * Returns a part type representing mouse contexts like 'Left' and 'TLCorner'
+ * based on the view geometry and cursor position
+ */
+static enum ssd_part_type
+get_resizing_type(const struct ssd *ssd, struct wlr_cursor *cursor)
+{
+ assert(ssd);
+ assert(cursor);
+ struct view *view = ssd->view;
+
+ if (!view || !view->ssd_enabled || view->fullscreen) {
+ return LAB_SSD_NONE;
+ }
+
+ struct wlr_box view_box = view->current;
+ view_box.height = view_effective_height(view, /* use_pending */ false);
+ if (view->ssd_enabled && !view->fullscreen && !view->ssd_titlebar_hidden) {
+ int titlebar_height = view->server->theme->titlebar_height;
+ view_box.y -= titlebar_height;
+ view_box.height += titlebar_height;
+ }
+ if (wlr_box_contains_point(&view_box, cursor->x, cursor->y)) {
+ return LAB_SSD_NONE;
+ }
+
+ int corner_height = MAX(0, MIN(rc.resize_corner_range, view_box.height / 2));
+ int corner_width = MAX(0, MIN(rc.resize_corner_range, view_box.width / 2));
+ bool left = cursor->x < view_box.x + corner_width;
+ bool right = cursor->x > view_box.x + view_box.width - corner_width;
+ bool top = cursor->y < view_box.y + corner_height;
+ bool bottom = cursor->y > view_box.y + view_box.height - corner_height;
+
+ if (top && left) {
+ return LAB_SSD_PART_CORNER_TOP_LEFT;
+ } else if (top && right) {
+ return LAB_SSD_PART_CORNER_TOP_RIGHT;
+ } else if (bottom && left) {
+ return LAB_SSD_PART_CORNER_BOTTOM_LEFT;
+ } else if (bottom && right) {
+ return LAB_SSD_PART_CORNER_BOTTOM_RIGHT;
+ } else if (top) {
+ return LAB_SSD_PART_TOP;
+ } else if (bottom) {
+ return LAB_SSD_PART_BOTTOM;
+ } else if (left) {
+ return LAB_SSD_PART_LEFT;
+ } else if (right) {
+ return LAB_SSD_PART_RIGHT;
+ }
+
+ return LAB_SSD_NONE;
+}
+
enum ssd_part_type
-ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node)
+ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node,
+ struct wlr_cursor *cursor)
{
if (!node) {
return LAB_SSD_NONE;
@@ -86,6 +141,15 @@ ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node)
return LAB_SSD_NONE;
}
+ /*
+ * Detect some mouse context (e.g. 'Left', 'TLCorner') from cursor
+ * position, not from node->type
+ */
+ enum ssd_part_type resizing_type = get_resizing_type(ssd, cursor);
+ if (resizing_type != LAB_SSD_NONE) {
+ return resizing_type;
+ }
+
const struct wl_list *part_list = NULL;
struct wlr_scene_tree *grandparent =
node->parent ? node->parent->node.parent : NULL;
@@ -132,16 +196,6 @@ ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node)
return LAB_SSD_NONE;
}
-enum ssd_part_type
-ssd_at(const struct ssd *ssd, struct wlr_scene *scene, double lx, double ly)
-{
- assert(scene);
- double sx, sy;
- struct wlr_scene_node *node = wlr_scene_node_at(
- &scene->tree.node, lx, ly, &sx, &sy);
- return ssd_get_part_type(ssd, node);
-}
-
uint32_t
ssd_resize_edges(enum ssd_part_type type)
{