mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
cursor-shape: improve xcursor fallback support, and prefer CSS names
Before this patch, we used legacy X11 xcursor names, and didn't really have any fallback handling in place (we only tried to fallback to "xterm", regardless of which cursor shape we were trying to load). This patch changes two things: 1. Improved fallback support. cursor_shape_to_string() now returns a list of strings. This allows us to have per-shape fallbacks, and any number of fallbacks. 2. We prefer CSS xcursor names over legacy X11 names.
This commit is contained in:
parent
6fd533ce13
commit
d3b348a5b1
4 changed files with 53 additions and 46 deletions
|
|
@ -90,6 +90,7 @@
|
|||
bindings `ctrl-+` and `ctrl+-`).
|
||||
* Use XRGB pixel format (instead of ARGB) when there is no
|
||||
transparency.
|
||||
* Prefer CSS xcursor names, and fallback to legacy X11 names.
|
||||
|
||||
[1526]: https://codeberg.org/dnkl/foot/issues/1526
|
||||
[1528]: https://codeberg.org/dnkl/foot/issues/1528
|
||||
|
|
|
|||
|
|
@ -9,28 +9,26 @@
|
|||
#include "debug.h"
|
||||
#include "util.h"
|
||||
|
||||
const char *
|
||||
const char *const *
|
||||
cursor_shape_to_string(enum cursor_shape shape)
|
||||
{
|
||||
static const char *const table[CURSOR_SHAPE_COUNT] = {
|
||||
[CURSOR_SHAPE_NONE] = NULL,
|
||||
[CURSOR_SHAPE_HIDDEN] = "hidden",
|
||||
[CURSOR_SHAPE_LEFT_PTR] = "left_ptr",
|
||||
[CURSOR_SHAPE_TEXT] = "text",
|
||||
[CURSOR_SHAPE_TEXT_FALLBACK] = "xterm",
|
||||
[CURSOR_SHAPE_TOP_LEFT_CORNER] = "top_left_corner",
|
||||
[CURSOR_SHAPE_TOP_RIGHT_CORNER] = "top_right_corner",
|
||||
[CURSOR_SHAPE_BOTTOM_LEFT_CORNER] = "bottom_left_corner",
|
||||
[CURSOR_SHAPE_BOTTOM_RIGHT_CORNER] = "bottom_right_corner",
|
||||
[CURSOR_SHAPE_LEFT_SIDE] = "left_side",
|
||||
[CURSOR_SHAPE_RIGHT_SIDE] = "right_side",
|
||||
[CURSOR_SHAPE_TOP_SIDE] = "top_side",
|
||||
[CURSOR_SHAPE_BOTTOM_SIDE] = "bottom_side",
|
||||
static const char *const table[][CURSOR_SHAPE_COUNT]= {
|
||||
[CURSOR_SHAPE_NONE] = {NULL},
|
||||
[CURSOR_SHAPE_HIDDEN] = {"hidden", NULL},
|
||||
[CURSOR_SHAPE_LEFT_PTR] = {"default", "left_ptr", NULL},
|
||||
[CURSOR_SHAPE_TEXT] = {"text", "xterm", NULL},
|
||||
[CURSOR_SHAPE_TOP_LEFT_CORNER] = {"nw-resize", "top_left_corner", NULL},
|
||||
[CURSOR_SHAPE_TOP_RIGHT_CORNER] = {"ne-resize", "top_right_corner", NULL},
|
||||
[CURSOR_SHAPE_BOTTOM_LEFT_CORNER] = {"sw-resize", "bottom_left_corner", NULL},
|
||||
[CURSOR_SHAPE_BOTTOM_RIGHT_CORNER] = {"se-resize", "bottom_right_corner", NULL},
|
||||
[CURSOR_SHAPE_LEFT_SIDE] = {"w-resize", "left_side", NULL},
|
||||
[CURSOR_SHAPE_RIGHT_SIDE] = {"e-resize", "right_side", NULL},
|
||||
[CURSOR_SHAPE_TOP_SIDE] = {"n-resize", "top_side", NULL},
|
||||
[CURSOR_SHAPE_BOTTOM_SIDE] = {"s-resize", "bottom_side", NULL},
|
||||
|
||||
};
|
||||
|
||||
xassert(shape <= ALEN(table));
|
||||
xassert(table[shape] != NULL);
|
||||
return table[shape];
|
||||
}
|
||||
|
||||
|
|
@ -40,7 +38,6 @@ cursor_shape_to_server_shape(enum cursor_shape shape)
|
|||
static const enum wp_cursor_shape_device_v1_shape table[CURSOR_SHAPE_COUNT] = {
|
||||
[CURSOR_SHAPE_LEFT_PTR] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT,
|
||||
[CURSOR_SHAPE_TEXT] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_TEXT,
|
||||
[CURSOR_SHAPE_TEXT_FALLBACK] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_TEXT,
|
||||
[CURSOR_SHAPE_TOP_LEFT_CORNER] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NW_RESIZE,
|
||||
[CURSOR_SHAPE_TOP_RIGHT_CORNER] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NE_RESIZE,
|
||||
[CURSOR_SHAPE_BOTTOM_LEFT_CORNER] = WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_SW_RESIZE,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ enum cursor_shape {
|
|||
|
||||
CURSOR_SHAPE_LEFT_PTR,
|
||||
CURSOR_SHAPE_TEXT,
|
||||
CURSOR_SHAPE_TEXT_FALLBACK,
|
||||
CURSOR_SHAPE_TOP_LEFT_CORNER,
|
||||
CURSOR_SHAPE_TOP_RIGHT_CORNER,
|
||||
CURSOR_SHAPE_BOTTOM_LEFT_CORNER,
|
||||
|
|
@ -22,7 +21,7 @@ enum cursor_shape {
|
|||
CURSOR_SHAPE_COUNT,
|
||||
};
|
||||
|
||||
const char *cursor_shape_to_string(enum cursor_shape shape);
|
||||
const char *const *cursor_shape_to_string(enum cursor_shape shape);
|
||||
|
||||
enum wp_cursor_shape_device_v1_shape cursor_shape_to_server_shape(
|
||||
enum cursor_shape shape);
|
||||
|
|
|
|||
64
render.c
64
render.c
|
|
@ -4625,38 +4625,48 @@ render_xcursor_set(struct seat *seat, struct terminal *term,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* TODO: skip this when using server-side cursors */
|
||||
if (shape != CURSOR_SHAPE_HIDDEN) {
|
||||
const char *const xcursor = shape == CURSOR_SHAPE_CUSTOM
|
||||
? term->mouse_user_cursor
|
||||
: cursor_shape_to_string(shape);
|
||||
const char *const fallback =
|
||||
cursor_shape_to_string(CURSOR_SHAPE_TEXT_FALLBACK);
|
||||
|
||||
seat->pointer.cursor = wl_cursor_theme_get_cursor(
|
||||
seat->pointer.theme, xcursor);
|
||||
|
||||
if (seat->pointer.cursor == NULL) {
|
||||
seat->pointer.cursor = wl_cursor_theme_get_cursor(
|
||||
seat->pointer.theme, fallback);
|
||||
|
||||
if (seat->pointer.cursor == NULL) {
|
||||
LOG_ERR("failed to load xcursor pointer "
|
||||
"'%s', and fallback '%s'", xcursor, fallback);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (shape == CURSOR_SHAPE_CUSTOM) {
|
||||
free(seat->pointer.last_custom_xcursor);
|
||||
seat->pointer.last_custom_xcursor = xstrdup(term->mouse_user_cursor);
|
||||
}
|
||||
} else {
|
||||
if (shape == CURSOR_SHAPE_HIDDEN) {
|
||||
seat->pointer.cursor = NULL;
|
||||
free(seat->pointer.last_custom_xcursor);
|
||||
seat->pointer.last_custom_xcursor = NULL;
|
||||
}
|
||||
|
||||
else if (seat->pointer.shape_device == NULL) {
|
||||
const char *const custom_xcursors[] = {term->mouse_user_cursor, NULL};
|
||||
const char *const *xcursors = shape == CURSOR_SHAPE_CUSTOM
|
||||
? custom_xcursors
|
||||
: cursor_shape_to_string(shape);
|
||||
|
||||
xassert(xcursors[0] != NULL);
|
||||
|
||||
seat->pointer.cursor = NULL;
|
||||
|
||||
for (size_t i = 0; xcursors[i] != NULL; i++) {
|
||||
seat->pointer.cursor =
|
||||
wl_cursor_theme_get_cursor(seat->pointer.theme, xcursors[i]);
|
||||
|
||||
if (seat->pointer.cursor != NULL) {
|
||||
LOG_DBG("loaded xcursor %s", xcursors[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (seat->pointer.cursor == NULL) {
|
||||
LOG_ERR(
|
||||
"failed to load xcursor pointer '%s', and all of its fallbacks",
|
||||
xcursors[0]);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
/* Server-side cursors - no need to load anything */
|
||||
}
|
||||
|
||||
if (shape == CURSOR_SHAPE_CUSTOM) {
|
||||
free(seat->pointer.last_custom_xcursor);
|
||||
seat->pointer.last_custom_xcursor =
|
||||
xstrdup(term->mouse_user_cursor);
|
||||
}
|
||||
|
||||
/* FDM hook takes care of actual rendering */
|
||||
seat->pointer.shape = shape;
|
||||
seat->pointer.xcursor_pending = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue