diff --git a/docs/labwc-config.5.scd b/docs/labwc-config.5.scd index 1c160a45..ebe0b746 100644 --- a/docs/labwc-config.5.scd +++ b/docs/labwc-config.5.scd @@ -512,6 +512,12 @@ extending outward from the snapped edge. ** The radius of server side decoration top corners. Default is 8. +** + 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. + ** [yes|no] Even when disabling server side decorations via ToggleDecorations, keep a small border (and resize area) around the window. Default is yes. diff --git a/docs/rc.xml.all b/docs/rc.xml.all index 16f5c212..78891df2 100644 --- a/docs/rc.xml.all +++ b/docs/rc.xml.all @@ -36,6 +36,7 @@ yes 8 + 8 yes no diff --git a/include/config/rcxml.h b/include/config/rcxml.h index 9aa6c9ba..d60689f0 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -88,6 +88,7 @@ struct rcxml { struct wl_list title_buttons_left; struct wl_list title_buttons_right; int corner_radius; + int corner_size; bool show_title; bool title_layout_loaded; bool ssd_keep_border; diff --git a/include/ssd.h b/include/ssd.h index fe56be54..a4876d89 100644 --- a/include/ssd.h +++ b/include/ssd.h @@ -3,6 +3,9 @@ #define LABWC_SSD_H #include +#include + +#include "action.h" #include "common/border.h" #define SSD_EXTENDED_AREA 8 @@ -111,8 +114,9 @@ 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); -uint32_t ssd_resize_edges(enum ssd_part_type type); -bool ssd_part_contains(enum ssd_part_type whole, enum ssd_part_type candidate); +uint32_t ssd_resize_edges(struct cursor_context *ctx, struct wlr_cursor *cursor); +bool ssd_part_contains(enum ssd_part_type candidate, + struct cursor_context *ctx, struct wlr_cursor *cursor); enum ssd_mode ssd_mode_parse(const char *mode); /* TODO: clean up / update */ diff --git a/src/action.c b/src/action.c index 86d72d6c..48f184d0 100644 --- a/src/action.c +++ b/src/action.c @@ -682,8 +682,7 @@ show_menu(struct server *server, struct view *view, struct cursor_context *ctx, x = extent.x; y = view->current.y; /* Push the client menu underneath the button */ - if (is_client_menu && ssd_part_contains( - LAB_SSD_BUTTON, ctx->type)) { + if (is_client_menu && ssd_part_contains(LAB_SSD_BUTTON, ctx, NULL)) { assert(ctx->node); int lx, ly; wlr_scene_node_coords(ctx->node, &lx, &ly); diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 0dfdc604..ea87bd3c 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -1081,6 +1081,8 @@ entry(xmlNode *node, char *nodename, char *content) rc.show_title = parse_bool(content, true); } else if (!strcmp(nodename, "cornerradius.theme")) { rc.corner_radius = atoi(content); + } else if (!strcmp(nodename, "cornersize.theme")) { + rc.corner_size = MAX(0, atoi(content)); } else if (!strcasecmp(nodename, "keepBorder.theme")) { set_bool(content, &rc.ssd_keep_border); } else if (!strcasecmp(nodename, "dropShadows.theme")) { @@ -1429,6 +1431,7 @@ rcxml_init(void) rc.title_layout_loaded = false; rc.ssd_keep_border = true; rc.corner_radius = 8; + rc.corner_size = 8; rc.shadows_enabled = false; rc.gap = 0; diff --git a/src/input/cursor.c b/src/input/cursor.c index fdaaa59c..2de40b66 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -103,13 +103,6 @@ cursor_get_from_edge(uint32_t resize_edges) return LAB_CURSOR_DEFAULT; } -static enum lab_cursors -cursor_get_from_ssd(enum ssd_part_type view_area) -{ - uint32_t resize_edges = ssd_resize_edges(view_area); - return cursor_get_from_edge(resize_edges); -} - static struct wlr_surface * get_toplevel(struct wlr_surface *surface) { @@ -546,7 +539,9 @@ cursor_update_common(struct server *server, struct cursor_context *ctx, */ wlr_seat_pointer_notify_clear_focus(wlr_seat); if (!seat->drag.active) { - enum lab_cursors cursor = cursor_get_from_ssd(ctx->type); + uint32_t resize_edge = + ssd_resize_edges(ctx, server->seat.cursor); + enum lab_cursors cursor = cursor_get_from_edge(resize_edge); if (ctx->view && ctx->view->shaded && cursor > LAB_CURSOR_GRAB) { /* Prevent resize cursor on borders for shaded SSD */ cursor = LAB_CURSOR_DEFAULT; @@ -560,7 +555,7 @@ cursor_update_common(struct server *server, struct cursor_context *ctx, uint32_t cursor_get_resize_edges(struct wlr_cursor *cursor, struct cursor_context *ctx) { - uint32_t resize_edges = ssd_resize_edges(ctx->type); + uint32_t resize_edges = ssd_resize_edges(ctx, cursor); if (ctx->view && !resize_edges) { struct wlr_box box = ctx->view->current; resize_edges |= @@ -898,7 +893,7 @@ handle_release_mousebinding(struct server *server, uint32_t modifiers = keyboard_get_all_modifiers(&server->seat); wl_list_for_each(mousebind, &rc.mousebinds, link) { - if (ssd_part_contains(mousebind->context, ctx->type) + if (ssd_part_contains(mousebind->context, ctx, server->seat.cursor) && mousebind->button == button && modifiers == mousebind->modifiers) { switch (mousebind->mouse_event) { @@ -965,7 +960,7 @@ handle_press_mousebinding(struct server *server, struct cursor_context *ctx, uint32_t modifiers = keyboard_get_all_modifiers(&server->seat); wl_list_for_each(mousebind, &rc.mousebinds, link) { - if (ssd_part_contains(mousebind->context, ctx->type) + if (ssd_part_contains(mousebind->context, ctx, server->seat.cursor) && mousebind->button == button && modifiers == mousebind->modifiers) { switch (mousebind->mouse_event) { @@ -1325,7 +1320,7 @@ handle_cursor_axis(struct server *server, struct cursor_context *ctx, } wl_list_for_each(mousebind, &rc.mousebinds, link) { - if (ssd_part_contains(mousebind->context, ctx->type) + if (ssd_part_contains(mousebind->context, ctx, server->seat.cursor) && mousebind->direction == direction && modifiers == mousebind->modifiers && mousebind->mouse_event == MOUSE_ACTION_SCROLL) { 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..b952244c 100644 --- a/src/ssd/ssd.c +++ b/src/ssd/ssd.c @@ -143,20 +143,30 @@ ssd_at(const struct ssd *ssd, struct wlr_scene *scene, double lx, double ly) } uint32_t -ssd_resize_edges(enum ssd_part_type type) +ssd_resize_edges(struct cursor_context *ctx, struct wlr_cursor *cursor) { - switch (type) { + assert(ctx); + struct view *view = ctx->view; + uint32_t edge = WLR_EDGE_NONE; + + switch (ctx->type) { case LAB_SSD_PART_TOP: - return WLR_EDGE_TOP; + edge = WLR_EDGE_TOP; + break; case LAB_SSD_PART_RIGHT: - return WLR_EDGE_RIGHT; + edge = WLR_EDGE_RIGHT; + break; case LAB_SSD_PART_BOTTOM: - return WLR_EDGE_BOTTOM; + edge = WLR_EDGE_BOTTOM; + break; case LAB_SSD_PART_LEFT: - return WLR_EDGE_LEFT; + edge = WLR_EDGE_LEFT; + break; case LAB_SSD_PART_CORNER_TOP_LEFT: + case LAB_SSD_PART_TITLEBAR_CORNER_LEFT: return WLR_EDGE_TOP | WLR_EDGE_LEFT; case LAB_SSD_PART_CORNER_TOP_RIGHT: + case LAB_SSD_PART_TITLEBAR_CORNER_RIGHT: return WLR_EDGE_RIGHT | WLR_EDGE_TOP; case LAB_SSD_PART_CORNER_BOTTOM_RIGHT: return WLR_EDGE_BOTTOM | WLR_EDGE_RIGHT; @@ -165,6 +175,32 @@ ssd_resize_edges(enum ssd_part_type type) default: return WLR_EDGE_NONE; } + + if (!view || !cursor || !view->ssd) { + return edge; + } + + if (edge == WLR_EDGE_BOTTOM || edge == WLR_EDGE_TOP) { + int width = view->current.width; + int corner_size = MAX(0, MIN(rc.corner_size, width / 2)); + + if (cursor->x < view->current.x + corner_size) { + edge |= WLR_EDGE_LEFT; + } else if (cursor->x > view->current.x + width - corner_size) { + edge |= WLR_EDGE_RIGHT; + } + } else if (edge == WLR_EDGE_LEFT || edge == WLR_EDGE_RIGHT) { + int height = view_effective_height(view, /* use_pending */ false); + int corner_size = MAX(0, MIN(rc.corner_size, height / 2)); + + if (cursor->y < view->current.y + corner_size) { + edge |= WLR_EDGE_TOP; + } else if (cursor->y > view->current.y + height - corner_size) { + edge |= WLR_EDGE_BOTTOM; + } + } + + return edge; } struct ssd * @@ -305,8 +341,11 @@ ssd_destroy(struct ssd *ssd) } bool -ssd_part_contains(enum ssd_part_type whole, enum ssd_part_type candidate) +ssd_part_contains(enum ssd_part_type whole, + struct cursor_context *ctx, struct wlr_cursor *cursor) { + assert(ctx); + enum ssd_part_type candidate = ctx->type; if (whole == candidate || whole == LAB_SSD_ALL) { return true; } @@ -327,22 +366,21 @@ ssd_part_contains(enum ssd_part_type whole, enum ssd_part_type candidate) return candidate >= LAB_SSD_BUTTON_CLOSE && candidate <= LAB_SSD_CLIENT; } - if (whole == LAB_SSD_PART_TOP) { - return candidate == LAB_SSD_PART_CORNER_TOP_LEFT - || candidate == LAB_SSD_PART_CORNER_TOP_RIGHT; - } - if (whole == LAB_SSD_PART_RIGHT) { - return candidate == LAB_SSD_PART_CORNER_TOP_RIGHT - || candidate == LAB_SSD_PART_CORNER_BOTTOM_RIGHT; - } - if (whole == LAB_SSD_PART_BOTTOM) { - return candidate == LAB_SSD_PART_CORNER_BOTTOM_RIGHT - || candidate == LAB_SSD_PART_CORNER_BOTTOM_LEFT; - } - if (whole == LAB_SSD_PART_LEFT) { - return candidate == LAB_SSD_PART_CORNER_TOP_LEFT - || candidate == LAB_SSD_PART_CORNER_BOTTOM_LEFT; + + /* Perform corner tests if necessary */ + switch (whole) { + case LAB_SSD_PART_CORNER_TOP_LEFT: + return ssd_resize_edges(ctx, cursor) == (WLR_EDGE_TOP | WLR_EDGE_LEFT); + case LAB_SSD_PART_CORNER_TOP_RIGHT: + return ssd_resize_edges(ctx, cursor) == (WLR_EDGE_TOP | WLR_EDGE_RIGHT); + case LAB_SSD_PART_CORNER_BOTTOM_LEFT: + return ssd_resize_edges(ctx, cursor) == (WLR_EDGE_BOTTOM | WLR_EDGE_LEFT); + case LAB_SSD_PART_CORNER_BOTTOM_RIGHT: + return ssd_resize_edges(ctx, cursor) == (WLR_EDGE_BOTTOM | WLR_EDGE_RIGHT); + default: + break; } + return false; }