mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
cursor: Use enum for server set cursor names
This mainly prevents having to use strcmp() on every mouse move.
This commit is contained in:
parent
f491942858
commit
e30fce6c34
5 changed files with 110 additions and 76 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
155
src/cursor.c
155
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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue