From e30fce6c3464edec14a495325a85d511182c9702 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Fri, 16 Sep 2022 02:23:44 +0200 Subject: [PATCH] cursor: Use enum for server set cursor names This mainly prevents having to use strcmp() on every mouse move. --- include/cursor.h | 16 ++++- include/labwc.h | 8 +-- src/cursor.c | 157 +++++++++++++++++++++++++++------------------- src/interactive.c | 4 +- src/ssd/ssd.c | 3 +- 5 files changed, 111 insertions(+), 77 deletions(-) diff --git a/include/cursor.h b/include/cursor.h index 62fd42ac..757a14db 100644 --- a/include/cursor.h +++ b/include/cursor.h @@ -66,9 +66,9 @@ struct cursor_context get_cursor_context(struct server *server); /** * cursor_set - set cursor icon * @seat - current seat - * @cursor_name - name of cursor, for example "left_ptr" or "grab" + * @cursor - name of cursor, for example LAB_CURSOR_DEFAULT or LAB_CURSOR_GRAB */ -void cursor_set(struct seat *seat, const char *cursor_name); +void cursor_set(struct seat *seat, enum lab_cursors cursor); /** * cursor_get_resize_edges - calculate resize edge based on cursor position @@ -84,6 +84,18 @@ void cursor_set(struct seat *seat, const char *cursor_name); uint32_t cursor_get_resize_edges(struct wlr_cursor *cursor, struct cursor_context *ctx); +/** + * cursor_get_from_edge - translate wlroots edge enum to lab_cursor enum + * @resize_edges - WLR_EDGE_ combination like WLR_EDGE_TOP | WLR_EDGE_RIGHT + * + * Returns LAB_CURSOR_DEFAULT on WLR_EDGE_NONE + * Returns the appropriate lab_cursors enum if @resize_edges + * is one of the 4 corners or one of the 4 edges. + * + * Asserts on invalid edge combinations like WLR_EDGE_LEFT | WLR_EDGE_RIGHT + */ +enum lab_cursors cursor_get_from_edge(uint32_t resize_edges); + /** * cursor_update_focus - update cursor focus, may update the cursor icon * @server - server diff --git a/include/labwc.h b/include/labwc.h index 4a73d8aa..2e1d8010 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -59,7 +59,6 @@ #define XCURSOR_DEFAULT "left_ptr" #define XCURSOR_SIZE 24 -#define XCURSOR_MOVE "grabbing" enum input_mode { LAB_INPUT_STATE_PASSTHROUGH = 0, @@ -80,13 +79,12 @@ struct seat { struct server *server; struct wlr_keyboard_group *keyboard_group; - bool cursor_requires_fallback; /* - * Name of most recent server-side cursor image. Set by + * Enum of most recent server-side cursor image. Set by * cursor_set(). Cleared when a client surface is entered - * (in that case the client is expected to set a cursor image). + * (in that case the client is expected to set its own cursor image). */ - char *cursor_set_by_server; + enum lab_cursors server_cursor; struct wlr_cursor *cursor; struct wlr_xcursor_manager *xcursor_manager; diff --git a/src/cursor.c b/src/cursor.c index 60997a20..9753654a 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -12,28 +12,84 @@ #include "ssd.h" #include "config/mousebind.h" #include "common/scene-helpers.h" -#include "common/zfree.h" - -static const struct cursor_alias { - const char *name, *alias; -} cursor_aliases[] = { - { "default", "left_ptr" }, - { "text", "xterm" }, - { "grab", "grabbing" }, - { "pointer", "hand1" }, - { "wait", "watch" }, - { "all-scroll", "grabbing" }, - /* Resize edges */ - { "nw-resize", "top_left_corner" }, - { "n-resize", "top_side" }, - { "ne-resize", "top_right_corner" }, - { "e-resize", "right_side" }, - { "se-resize", "bottom_right_corner" }, - { "s-resize", "bottom_side" }, - { "sw-resize", "bottom_left_corner" }, - { "w-resize", "left_side" }, + +static const char **cursor_names = NULL; + +/* Usual cursor names */ +static const char *cursors_xdg[] = { + NULL, + "default", + "grab", + "nw-resize", + "n-resize", + "ne-resize", + "e-resize", + "se-resize", + "s-resize", + "sw-resize", + "w-resize" +}; + +/* XCursor fallbacks */ +static const char *cursors_x11[] = { + NULL, + "left_ptr", + "grabbing", + "top_left_corner", + "top_side", + "top_right_corner", + "right_side", + "bottom_right_corner", + "bottom_side", + "bottom_left_corner", + "left_side" }; +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) +static_assert( + ARRAY_SIZE(cursors_xdg) == LAB_CURSOR_COUNT, + "XDG cursor names are out ot sync"); +static_assert( + ARRAY_SIZE(cursors_x11) == LAB_CURSOR_COUNT, + "X11 cursor names are out ot sync"); +#undef ARRAY_SIZE + +enum lab_cursors +cursor_get_from_edge(uint32_t resize_edges) +{ + switch (resize_edges) { + case WLR_EDGE_NONE: + return LAB_CURSOR_DEFAULT; + case WLR_EDGE_TOP | WLR_EDGE_LEFT: + return LAB_CURSOR_RESIZE_NW; + case WLR_EDGE_TOP: + return LAB_CURSOR_RESIZE_N; + case WLR_EDGE_TOP | WLR_EDGE_RIGHT: + return LAB_CURSOR_RESIZE_NE; + case WLR_EDGE_RIGHT: + return LAB_CURSOR_RESIZE_E; + case WLR_EDGE_BOTTOM | WLR_EDGE_RIGHT: + return LAB_CURSOR_RESIZE_SE; + case WLR_EDGE_BOTTOM: + return LAB_CURSOR_RESIZE_S; + case WLR_EDGE_BOTTOM | WLR_EDGE_LEFT: + return LAB_CURSOR_RESIZE_SW; + case WLR_EDGE_LEFT: + return LAB_CURSOR_RESIZE_W; + default: + wlr_log(WLR_ERROR, + "Failed to resolve wlroots edge %u to cursor name", resize_edges); + assert(false); + } +} + +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) { @@ -185,52 +241,19 @@ process_cursor_resize(struct server *server, uint32_t time) view_move_resize(view, new_view_geo); } -static const char * -cursor_name_fallback(struct wlr_xcursor_manager *manager, const char *name) -{ - if (wlr_xcursor_manager_get_xcursor(manager, name, 1)) { - return name; - } - for (size_t i = 0; i < sizeof(cursor_aliases) / sizeof(cursor_aliases[0]); i++) { - if (!strcmp(cursor_aliases[i].name, name)) { - return cursor_aliases[i].alias; - } - } - return name; -} - void -cursor_set(struct seat *seat, const char *cursor_name) +cursor_set(struct seat *seat, enum lab_cursors cursor) { - /* - * Required until wlroots MR !3651 is merged. - * Once that happened, the whole commit can be reverted. - */ - if (seat->cursor_requires_fallback) { - cursor_name = cursor_name_fallback(seat->xcursor_manager, cursor_name); - } + assert(cursor > LAB_CURSOR_CLIENT && cursor < LAB_CURSOR_COUNT); /* Prevent setting the same cursor image twice */ - if (seat->cursor_set_by_server && !strcmp(cursor_name, - seat->cursor_set_by_server)) { + if (seat->server_cursor == cursor) { return; } wlr_xcursor_manager_set_cursor_image( - seat->xcursor_manager, cursor_name, seat->cursor); - zfree(seat->cursor_set_by_server); - seat->cursor_set_by_server = strdup(cursor_name); -} - -static void -set_server_cursor(struct seat *seat, enum ssd_part_type view_area) -{ - uint32_t resize_edges = ssd_resize_edges(view_area); - if (resize_edges) { - cursor_set(seat, wlr_xcursor_get_resize_name(resize_edges)); - } else { - cursor_set(seat, XCURSOR_DEFAULT); - } + seat->xcursor_manager, cursor_names[cursor], seat->cursor); + seat->server_cursor = cursor; } bool @@ -346,7 +369,7 @@ cursor_update_common(struct server *server, struct cursor_context *ctx, * in response to the enter event. */ if (ctx->surface != wlr_seat->pointer_state.focused_surface - || seat->cursor_set_by_server) { + || seat->server_cursor != LAB_CURSOR_CLIENT) { /* * Enter the surface if necessary. Usually we * prevent re-entering an already focused @@ -361,7 +384,7 @@ cursor_update_common(struct server *server, struct cursor_context *ctx, wlr_seat_pointer_notify_clear_focus(wlr_seat); wlr_seat_pointer_notify_enter(wlr_seat, ctx->surface, ctx->sx, ctx->sy); - zfree(seat->cursor_set_by_server); + seat->server_cursor = LAB_CURSOR_CLIENT; } if (cursor_has_moved) { wlr_seat_pointer_notify_motion(wlr_seat, time_msec, @@ -374,7 +397,7 @@ cursor_update_common(struct server *server, struct cursor_context *ctx, * set the cursor image ourselves. */ wlr_seat_pointer_notify_clear_focus(wlr_seat); - set_server_cursor(seat, ctx->type); + cursor_set(seat, cursor_get_from_ssd(ctx->type)); } } @@ -411,7 +434,7 @@ process_cursor_motion(struct server *server, uint32_t time) if (ctx.type == LAB_SSD_MENU) { menu_process_cursor_motion(ctx.node); - set_server_cursor(seat, ctx.type); + cursor_set(&server->seat, LAB_CURSOR_DEFAULT); return; } @@ -983,11 +1006,13 @@ cursor_init(struct seat *seat) seat->xcursor_manager = wlr_xcursor_manager_create(xcursor_theme, size); wlr_xcursor_manager_load(seat->xcursor_manager, 1); - /* Check if we need to run every cursor_set() through translation */ - if (strcmp("grab", cursor_name_fallback(seat->xcursor_manager, "grab"))) { - seat->cursor_requires_fallback = true; + if (wlr_xcursor_manager_get_xcursor(seat->xcursor_manager, + cursors_xdg[LAB_CURSOR_DEFAULT], 1)) { + cursor_names = cursors_xdg; + } else { wlr_log(WLR_INFO, - "Cursor theme is missing cursor names, using fallbacks"); + "Cursor theme is missing cursor names, using fallback"); + cursor_names = cursors_x11; } seat->cursor_motion.notify = cursor_motion; diff --git a/src/interactive.c b/src/interactive.c index 02ee9ee6..de47d09d 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -84,10 +84,10 @@ interactive_begin(struct view *view, enum input_mode mode, uint32_t edges) switch (mode) { case LAB_INPUT_STATE_MOVE: - cursor_set(&server->seat, "grab"); + cursor_set(&server->seat, LAB_CURSOR_GRAB); break; case LAB_INPUT_STATE_RESIZE: - cursor_set(&server->seat, wlr_xcursor_get_resize_name(edges)); + cursor_set(&server->seat, cursor_get_from_edge(edges)); break; default: break; diff --git a/src/ssd/ssd.c b/src/ssd/ssd.c index 14e7f462..6cb8ae13 100644 --- a/src/ssd/ssd.c +++ b/src/ssd/ssd.c @@ -141,9 +141,8 @@ ssd_resize_edges(enum ssd_part_type type) case LAB_SSD_PART_CORNER_BOTTOM_LEFT: return WLR_EDGE_BOTTOM | WLR_EDGE_LEFT; default: - break; + return WLR_EDGE_NONE; } - return 0; } void -- 2.52.0