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) {