From 399322052b81a0443ceea40f6bd586003d0c3d88 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 26 Jul 2021 20:06:52 +0100 Subject: [PATCH] ssd: add ssd_interactive_box() ...which is used by desktop_view_at() and ssd_at() to determine which decoration part is under the cursor. ssd_interactive_box() allows deocoration parts to extend outside the visible regions, and therefore supports a wider 'resize-edges' area than the border itself. --- include/ssd.h | 1 + src/cursor.c | 43 ++--------------- src/ssd.c | 124 ++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 110 insertions(+), 58 deletions(-) diff --git a/include/ssd.h b/include/ssd.h index 54d7f105..0274fd1f 100644 --- a/include/ssd.h +++ b/include/ssd.h @@ -48,6 +48,7 @@ struct border ssd_thickness(struct view *view); struct wlr_box ssd_max_extents(struct view *view); struct wlr_box ssd_box(struct view *view, enum ssd_part_type type); enum ssd_part_type ssd_at(struct view *view, double lx, double ly); +uint32_t ssd_resize_edges(enum ssd_part_type type); void ssd_create(struct view *view); void ssd_destroy(struct view *view); void ssd_update_geometry(struct view *view); diff --git a/src/cursor.c b/src/cursor.c index 43a10dfb..3d1fc647 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -4,39 +4,6 @@ #include "menu/menu.h" #include "ssd.h" -#define RESIZE_BORDER_WIDTH 2 - -/* - * TODO: refactor code to get rid of get_resize_edges() - * Use a wl_list of SSD instead and build RESIZE_BORDER_WIDTH into that. - * Had to set RESIZE_BORDER_WIDTH to 2 for the time being to get - * cursor_name to behave properly when entering surface - */ -static uint32_t -get_resize_edges(struct view *view, double x, double y) -{ - uint32_t edges = 0; - int top, right, bottom, left; - - top = view->y - view->margin.top; - left = view->x - view->margin.left; - bottom = top + view->h + view->margin.top + view->margin.bottom; - right = left + view->w + view->margin.left + view->margin.right; - - if (top <= y && y < top + RESIZE_BORDER_WIDTH) { - edges |= WLR_EDGE_TOP; - } else if (bottom - RESIZE_BORDER_WIDTH <= y && y < bottom) { - edges |= WLR_EDGE_BOTTOM; - } - if (left <= x && x < left + RESIZE_BORDER_WIDTH) { - edges |= WLR_EDGE_LEFT; - } else if (right - RESIZE_BORDER_WIDTH <= x && x < right) { - edges |= WLR_EDGE_RIGHT; - } - - return edges; -} - static void request_cursor_notify(struct wl_listener *listener, void *data) { @@ -149,12 +116,11 @@ process_cursor_motion(struct server *server, uint32_t time) if (!view) { cursor_name = XCURSOR_DEFAULT; } else { - uint32_t resize_edges = get_resize_edges( - view, server->seat.cursor->x, server->seat.cursor->y); + uint32_t resize_edges = ssd_resize_edges(view_area); switch (resize_edges) { case 0: - if (rc.focus_follow_mouse){ - if (rc.raise_on_focus){ + if (rc.focus_follow_mouse) { + if (rc.raise_on_focus) { desktop_focus_view(&server->seat, view); } else { desktop_set_focus_view_only(&server->seat, view); @@ -361,8 +327,7 @@ cursor_button(struct wl_listener *listener, void *data) desktop_focus_view(&server->seat, view); damage_all_outputs(server); - resize_edges = get_resize_edges(view, server->seat.cursor->x, - server->seat.cursor->y); + resize_edges = ssd_resize_edges(view_area); if (resize_edges != 0) { interactive_begin(view, LAB_INPUT_STATE_RESIZE, resize_edges); return; diff --git a/src/ssd.c b/src/ssd.c index b0e7648c..d922b6bf 100644 --- a/src/ssd.c +++ b/src/ssd.c @@ -10,6 +10,8 @@ #include "theme.h" #include "ssd.h" +#define INVISIBLE_MARGIN (16) + struct border ssd_thickness(struct view *view) { @@ -36,13 +38,12 @@ ssd_max_extents(struct view *view) return box; } -struct wlr_box -ssd_box(struct view *view, enum ssd_part_type type) +static struct wlr_box +ssd_interactive_box(struct view *view, enum ssd_part_type type) { struct theme *theme = view->server->theme; struct wlr_box box = { 0 }; int corner_square = theme->title_height + theme->border_width; - assert(view); switch (type) { case LAB_SSD_BUTTON_CLOSE: box.x = view->x + view->w - theme->title_height; @@ -63,46 +64,103 @@ ssd_box(struct view *view, enum ssd_part_type type) box.height = theme->title_height; break; case LAB_SSD_PART_TITLE: - box.x = view->x + theme->title_height; + box.x = view->x; box.y = view->y - theme->title_height; - box.width = view->w - 2 * theme->title_height; + box.width = view->w; box.height = theme->title_height; break; case LAB_SSD_PART_TOP: box.x = view->x + theme->title_height; - box.y = view->y - corner_square; + box.y = view->y - corner_square - INVISIBLE_MARGIN; box.width = view->w - 2 * theme->title_height; - box.height = theme->border_width; + box.height = theme->border_width + INVISIBLE_MARGIN; break; case LAB_SSD_PART_RIGHT: box.x = view->x + view->w; box.y = view->y; - box.width = theme->border_width; + box.width = theme->border_width + INVISIBLE_MARGIN; box.height = view->h; break; case LAB_SSD_PART_BOTTOM: box.x = view->x - theme->border_width; box.y = view->y + view->h; box.width = view->w + 2 * theme->border_width; - box.height = +theme->border_width; + box.height = +theme->border_width + INVISIBLE_MARGIN; break; case LAB_SSD_PART_LEFT: - box.x = view->x - theme->border_width; + box.x = view->x - theme->border_width - INVISIBLE_MARGIN; box.y = view->y; - box.width = theme->border_width; + box.width = theme->border_width + INVISIBLE_MARGIN; box.height = view->h; break; case LAB_SSD_PART_CORNER_TOP_LEFT: - box.x = view->x - theme->border_width; - box.y = view->y - corner_square; - box.width = corner_square; - box.height = corner_square; + box.x = view->x - theme->border_width - INVISIBLE_MARGIN; + box.y = view->y - corner_square - INVISIBLE_MARGIN; + box.width = corner_square + INVISIBLE_MARGIN; + box.height = corner_square + INVISIBLE_MARGIN; break; case LAB_SSD_PART_CORNER_TOP_RIGHT: box.x = view->x + view->w - theme->title_height; - box.y = view->y - corner_square; - box.width = corner_square; - box.height = corner_square; + box.y = view->y - corner_square - INVISIBLE_MARGIN; + box.width = corner_square + INVISIBLE_MARGIN; + box.height = corner_square + INVISIBLE_MARGIN; + break; + default: + break; + } + return box; +} + +struct wlr_box +ssd_box(struct view *view, enum ssd_part_type type) +{ + struct theme *theme = view->server->theme; + struct wlr_box box = { 0 }; + switch (type) { + case LAB_SSD_BUTTON_CLOSE: + box = ssd_interactive_box(view, type); + break; + case LAB_SSD_BUTTON_MAXIMIZE: + box = ssd_interactive_box(view, type); + break; + case LAB_SSD_BUTTON_ICONIFY: + box = ssd_interactive_box(view, type); + break; + case LAB_SSD_PART_TITLE: + box = ssd_interactive_box(view, type); + box.x += theme->title_height; + box.width -= 2 * theme->title_height; + break; + case LAB_SSD_PART_TOP: + box = ssd_interactive_box(view, type); + box.y += INVISIBLE_MARGIN; + box.height -= INVISIBLE_MARGIN; + break; + case LAB_SSD_PART_RIGHT: + box = ssd_interactive_box(view, type); + box.width -= INVISIBLE_MARGIN; + break; + case LAB_SSD_PART_BOTTOM: + box = ssd_interactive_box(view, type); + box.height -= INVISIBLE_MARGIN; + break; + case LAB_SSD_PART_LEFT: + box = ssd_interactive_box(view, type); + box.x += INVISIBLE_MARGIN; + box.width -= INVISIBLE_MARGIN; + break; + case LAB_SSD_PART_CORNER_TOP_LEFT: + box = ssd_interactive_box(view, type); + box.x += INVISIBLE_MARGIN; + box.y += INVISIBLE_MARGIN; + box.width -= INVISIBLE_MARGIN; + box.height -= INVISIBLE_MARGIN; + break; + case LAB_SSD_PART_CORNER_TOP_RIGHT: + box = ssd_interactive_box(view, type); + box.y += INVISIBLE_MARGIN; + box.width -= INVISIBLE_MARGIN; + box.height -= INVISIBLE_MARGIN; break; default: break; @@ -115,7 +173,7 @@ ssd_at(struct view *view, double lx, double ly) { enum ssd_part_type type; for (type = 0; type < LAB_SSD_END_MARKER; ++type) { - struct wlr_box box = ssd_box(view, type); + struct wlr_box box = ssd_interactive_box(view, type); if (wlr_box_contains_point(&box, lx, ly)) { return type; } @@ -123,6 +181,34 @@ ssd_at(struct view *view, double lx, double ly) return LAB_SSD_NONE; } +uint32_t +ssd_resize_edges(enum ssd_part_type type) +{ + uint32_t edges = 0; + + if (type == LAB_SSD_PART_TOP) { + edges |= WLR_EDGE_TOP; + } + if (type == LAB_SSD_PART_RIGHT) { + edges |= WLR_EDGE_RIGHT; + } + if (type == LAB_SSD_PART_BOTTOM) { + edges |= WLR_EDGE_BOTTOM; + } + if (type == LAB_SSD_PART_LEFT) { + edges |= WLR_EDGE_LEFT; + } + if (type == LAB_SSD_PART_CORNER_TOP_RIGHT) { + edges = WLR_EDGE_RIGHT | WLR_EDGE_TOP; + } + if (type == LAB_SSD_PART_CORNER_TOP_LEFT) { + edges |= WLR_EDGE_TOP; + edges |= WLR_EDGE_LEFT; + } + return edges; +} + + static struct ssd_part * add_part(struct view *view, enum ssd_part_type type) {