cursor: Use enum for server set cursor names

This mainly prevents having to use strcmp() on every mouse move.
This commit is contained in:
Consolatis 2022-09-16 02:23:44 +02:00 committed by Johan Malm
parent f491942858
commit e30fce6c34
5 changed files with 110 additions and 76 deletions

View file

@ -66,9 +66,9 @@ struct cursor_context get_cursor_context(struct server *server);
/** /**
* cursor_set - set cursor icon * cursor_set - set cursor icon
* @seat - current seat * @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 * 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, uint32_t cursor_get_resize_edges(struct wlr_cursor *cursor,
struct cursor_context *ctx); 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 * cursor_update_focus - update cursor focus, may update the cursor icon
* @server - server * @server - server

View file

@ -59,7 +59,6 @@
#define XCURSOR_DEFAULT "left_ptr" #define XCURSOR_DEFAULT "left_ptr"
#define XCURSOR_SIZE 24 #define XCURSOR_SIZE 24
#define XCURSOR_MOVE "grabbing"
enum input_mode { enum input_mode {
LAB_INPUT_STATE_PASSTHROUGH = 0, LAB_INPUT_STATE_PASSTHROUGH = 0,
@ -80,13 +79,12 @@ struct seat {
struct server *server; struct server *server;
struct wlr_keyboard_group *keyboard_group; 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 * 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_cursor *cursor;
struct wlr_xcursor_manager *xcursor_manager; struct wlr_xcursor_manager *xcursor_manager;

View file

@ -12,28 +12,84 @@
#include "ssd.h" #include "ssd.h"
#include "config/mousebind.h" #include "config/mousebind.h"
#include "common/scene-helpers.h" #include "common/scene-helpers.h"
#include "common/zfree.h"
static const struct cursor_alias { static const char **cursor_names = NULL;
const char *name, *alias;
} cursor_aliases[] = { /* Usual cursor names */
{ "default", "left_ptr" }, static const char *cursors_xdg[] = {
{ "text", "xterm" }, NULL,
{ "grab", "grabbing" }, "default",
{ "pointer", "hand1" }, "grab",
{ "wait", "watch" }, "nw-resize",
{ "all-scroll", "grabbing" }, "n-resize",
/* Resize edges */ "ne-resize",
{ "nw-resize", "top_left_corner" }, "e-resize",
{ "n-resize", "top_side" }, "se-resize",
{ "ne-resize", "top_right_corner" }, "s-resize",
{ "e-resize", "right_side" }, "sw-resize",
{ "se-resize", "bottom_right_corner" }, "w-resize"
{ "s-resize", "bottom_side" },
{ "sw-resize", "bottom_left_corner" },
{ "w-resize", "left_side" },
}; };
/* 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 * static struct wlr_surface *
get_toplevel(struct wlr_surface *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); 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 void
cursor_set(struct seat *seat, const char *cursor_name) cursor_set(struct seat *seat, enum lab_cursors cursor)
{ {
/* assert(cursor > LAB_CURSOR_CLIENT && cursor < LAB_CURSOR_COUNT);
* 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);
}
/* Prevent setting the same cursor image twice */ /* Prevent setting the same cursor image twice */
if (seat->cursor_set_by_server && !strcmp(cursor_name, if (seat->server_cursor == cursor) {
seat->cursor_set_by_server)) {
return; return;
} }
wlr_xcursor_manager_set_cursor_image( wlr_xcursor_manager_set_cursor_image(
seat->xcursor_manager, cursor_name, seat->cursor); seat->xcursor_manager, cursor_names[cursor], seat->cursor);
zfree(seat->cursor_set_by_server); seat->server_cursor = cursor;
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);
}
} }
bool bool
@ -346,7 +369,7 @@ cursor_update_common(struct server *server, struct cursor_context *ctx,
* in response to the enter event. * in response to the enter event.
*/ */
if (ctx->surface != wlr_seat->pointer_state.focused_surface 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 * Enter the surface if necessary. Usually we
* prevent re-entering an already focused * 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_clear_focus(wlr_seat);
wlr_seat_pointer_notify_enter(wlr_seat, ctx->surface, wlr_seat_pointer_notify_enter(wlr_seat, ctx->surface,
ctx->sx, ctx->sy); ctx->sx, ctx->sy);
zfree(seat->cursor_set_by_server); seat->server_cursor = LAB_CURSOR_CLIENT;
} }
if (cursor_has_moved) { if (cursor_has_moved) {
wlr_seat_pointer_notify_motion(wlr_seat, time_msec, 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. * set the cursor image ourselves.
*/ */
wlr_seat_pointer_notify_clear_focus(wlr_seat); 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) { if (ctx.type == LAB_SSD_MENU) {
menu_process_cursor_motion(ctx.node); menu_process_cursor_motion(ctx.node);
set_server_cursor(seat, ctx.type); cursor_set(&server->seat, LAB_CURSOR_DEFAULT);
return; return;
} }
@ -983,11 +1006,13 @@ cursor_init(struct seat *seat)
seat->xcursor_manager = wlr_xcursor_manager_create(xcursor_theme, size); seat->xcursor_manager = wlr_xcursor_manager_create(xcursor_theme, size);
wlr_xcursor_manager_load(seat->xcursor_manager, 1); wlr_xcursor_manager_load(seat->xcursor_manager, 1);
/* Check if we need to run every cursor_set() through translation */ if (wlr_xcursor_manager_get_xcursor(seat->xcursor_manager,
if (strcmp("grab", cursor_name_fallback(seat->xcursor_manager, "grab"))) { cursors_xdg[LAB_CURSOR_DEFAULT], 1)) {
seat->cursor_requires_fallback = true; cursor_names = cursors_xdg;
} else {
wlr_log(WLR_INFO, 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; seat->cursor_motion.notify = cursor_motion;

View file

@ -84,10 +84,10 @@ interactive_begin(struct view *view, enum input_mode mode, uint32_t edges)
switch (mode) { switch (mode) {
case LAB_INPUT_STATE_MOVE: case LAB_INPUT_STATE_MOVE:
cursor_set(&server->seat, "grab"); cursor_set(&server->seat, LAB_CURSOR_GRAB);
break; break;
case LAB_INPUT_STATE_RESIZE: 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; break;
default: default:
break; break;

View file

@ -141,9 +141,8 @@ ssd_resize_edges(enum ssd_part_type type)
case LAB_SSD_PART_CORNER_BOTTOM_LEFT: case LAB_SSD_PART_CORNER_BOTTOM_LEFT:
return WLR_EDGE_BOTTOM | WLR_EDGE_LEFT; return WLR_EDGE_BOTTOM | WLR_EDGE_LEFT;
default: default:
break; return WLR_EDGE_NONE;
} }
return 0;
} }
void void