diff --git a/cursor-shape.c b/cursor-shape.c new file mode 100644 index 00000000..152f176f --- /dev/null +++ b/cursor-shape.c @@ -0,0 +1,29 @@ +#include + +#include "cursor-shape.h" +#include "debug.h" +#include "util.h" + +const char * +cursor_shape_to_string(enum cursor_shape shape) +{ + static const char *const table[] = { + [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", + + }; + + xassert(shape <= ALEN(table)); + return table[shape]; +} diff --git a/cursor-shape.h b/cursor-shape.h new file mode 100644 index 00000000..fb79e45a --- /dev/null +++ b/cursor-shape.h @@ -0,0 +1,21 @@ +#pragma once + +enum cursor_shape { + CURSOR_SHAPE_NONE, + CURSOR_SHAPE_CUSTOM, + + CURSOR_SHAPE_HIDDEN, + 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, + CURSOR_SHAPE_BOTTOM_RIGHT_CORNER, + CURSOR_SHAPE_LEFT_SIDE, + CURSOR_SHAPE_RIGHT_SIDE, + CURSOR_SHAPE_TOP_SIDE, + CURSOR_SHAPE_BOTTOM_SIDE, +}; + +const char *cursor_shape_to_string(enum cursor_shape shape); diff --git a/input.c b/input.c index 7e5d204d..0f638cc1 100644 --- a/input.c +++ b/input.c @@ -1704,20 +1704,20 @@ is_bottom_right(const struct terminal *term, int x, int y) (term->active_surface == TERM_SURF_BORDER_BOTTOM && x > term->width + 1 * csd_border_size * term->scale - 10 * term->scale))); } -const char * +enum cursor_shape xcursor_for_csd_border(struct terminal *term, int x, int y) { - if (is_top_left(term, x, y)) return XCURSOR_TOP_LEFT_CORNER; - else if (is_top_right(term, x, y)) return XCURSOR_TOP_RIGHT_CORNER; - else if (is_bottom_left(term, x, y)) return XCURSOR_BOTTOM_LEFT_CORNER; - else if (is_bottom_right(term, x, y)) return XCURSOR_BOTTOM_RIGHT_CORNER; - else if (term->active_surface == TERM_SURF_BORDER_LEFT) return XCURSOR_LEFT_SIDE; - else if (term->active_surface == TERM_SURF_BORDER_RIGHT) return XCURSOR_RIGHT_SIDE; - else if (term->active_surface == TERM_SURF_BORDER_TOP) return XCURSOR_TOP_SIDE; - else if (term->active_surface == TERM_SURF_BORDER_BOTTOM) return XCURSOR_BOTTOM_SIDE; + if (is_top_left(term, x, y)) return CURSOR_SHAPE_TOP_LEFT_CORNER; + else if (is_top_right(term, x, y)) return CURSOR_SHAPE_TOP_RIGHT_CORNER; + else if (is_bottom_left(term, x, y)) return CURSOR_SHAPE_BOTTOM_LEFT_CORNER; + else if (is_bottom_right(term, x, y)) return CURSOR_SHAPE_BOTTOM_RIGHT_CORNER; + else if (term->active_surface == TERM_SURF_BORDER_LEFT) return CURSOR_SHAPE_LEFT_SIDE; + else if (term->active_surface == TERM_SURF_BORDER_RIGHT) return CURSOR_SHAPE_RIGHT_SIDE; + else if (term->active_surface == TERM_SURF_BORDER_TOP) return CURSOR_SHAPE_TOP_SIDE; + else if (term->active_surface == TERM_SURF_BORDER_BOTTOM) return CURSOR_SHAPE_BOTTOM_SIDE; else { BUG("Unreachable"); - return NULL; + return CURSOR_SHAPE_NONE; } } @@ -1819,7 +1819,7 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, } /* Reset last-set-xcursor, to ensure we update it on a pointer-enter event */ - seat->pointer.xcursor = NULL; + seat->pointer.shape = CURSOR_SHAPE_NONE; /* Reset mouse state */ seat->mouse.x = seat->mouse.y = 0; diff --git a/input.h b/input.h index ea488a86..825dc3be 100644 --- a/input.h +++ b/input.h @@ -3,8 +3,9 @@ #include #include -#include "wayland.h" +#include "cursor-shape.h" #include "misc.h" +#include "wayland.h" /* * Custom defines for mouse wheel left/right buttons. @@ -33,4 +34,4 @@ void get_current_modifiers(const struct seat *seat, xkb_mod_mask_t *consumed, uint32_t key); -const char *xcursor_for_csd_border(struct terminal *term, int x, int y); +enum cursor_shape xcursor_for_csd_border(struct terminal *term, int x, int y); diff --git a/meson.build b/meson.build index 6e219caf..9560504f 100644 --- a/meson.build +++ b/meson.build @@ -261,6 +261,7 @@ executable( 'box-drawing.c', 'box-drawing.h', 'config.c', 'config.h', 'commands.c', 'commands.h', + 'cursor-shape.c', 'cursor-shape.h', 'extract.c', 'extract.h', 'fdm.c', 'fdm.h', 'foot-features.h', diff --git a/render.c b/render.c index 4498290e..fedc3467 100644 --- a/render.c +++ b/render.c @@ -4254,9 +4254,9 @@ render_xcursor_update(struct seat *seat) if (!seat->mouse_focus) return; - xassert(seat->pointer.xcursor != NULL); + xassert(seat->pointer.shape != CURSOR_SHAPE_NONE); - if (seat->pointer.xcursor == XCURSOR_HIDDEN) { + if (seat->pointer.shape == CURSOR_SHAPE_HIDDEN) { /* Hide cursor */ wl_surface_attach(seat->pointer.surface.surf, NULL, 0, 0); wl_surface_commit(seat->pointer.surface.surf); @@ -4434,13 +4434,13 @@ render_refresh_urls(struct terminal *term) } bool -render_xcursor_set(struct seat *seat, struct terminal *term, const char *xcursor) +render_xcursor_set(struct seat *seat, struct terminal *term, enum cursor_shape shape) { if (seat->pointer.theme == NULL) return false; if (seat->mouse_focus == NULL) { - seat->pointer.xcursor = NULL; + seat->pointer.shape = CURSOR_SHAPE_NONE; return true; } @@ -4449,18 +4449,24 @@ render_xcursor_set(struct seat *seat, struct terminal *term, const char *xcursor return true; } - if (seat->pointer.xcursor == xcursor) + if (seat->pointer.shape == shape) return true; - if (xcursor != XCURSOR_HIDDEN) { + if (shape != CURSOR_SHAPE_HIDDEN) { + const char *const xcursor = 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, XCURSOR_TEXT_FALLBACK ); + seat->pointer.theme, fallback); + if (seat->pointer.cursor == NULL) { - LOG_ERR("failed to load xcursor pointer '%s', and fallback '%s'", xcursor, XCURSOR_TEXT_FALLBACK); + LOG_ERR("failed to load xcursor pointer " + "'%s', and fallback '%s'", xcursor, fallback); return false; } } @@ -4468,7 +4474,7 @@ render_xcursor_set(struct seat *seat, struct terminal *term, const char *xcursor seat->pointer.cursor = NULL; /* FDM hook takes care of actual rendering */ - seat->pointer.xcursor = xcursor; + seat->pointer.shape = shape; seat->pointer.xcursor_pending = true; return true; } diff --git a/render.h b/render.h index d2c673ee..f038ffb0 100644 --- a/render.h +++ b/render.h @@ -19,7 +19,7 @@ void render_refresh_search(struct terminal *term); void render_refresh_title(struct terminal *term); void render_refresh_urls(struct terminal *term); bool render_xcursor_set( - struct seat *seat, struct terminal *term, const char *xcursor); + struct seat *seat, struct terminal *term, enum cursor_shape shape); bool render_xcursor_is_valid(const struct seat *seat, const char *cursor); struct render_worker_context { diff --git a/terminal.c b/terminal.c index df77d2b9..3591040b 100644 --- a/terminal.c +++ b/terminal.c @@ -47,20 +47,6 @@ #define PTMX_TIMING 0 -const char *const XCURSOR_HIDDEN = "hidden"; -const char *const XCURSOR_LEFT_PTR = "left_ptr"; -const char *const XCURSOR_TEXT = "text"; -const char *const XCURSOR_TEXT_FALLBACK = "xterm"; -//const char *const XCURSOR_HAND2 = "hand2"; -const char *const XCURSOR_TOP_LEFT_CORNER = "top_left_corner"; -const char *const XCURSOR_TOP_RIGHT_CORNER = "top_right_corner"; -const char *const XCURSOR_BOTTOM_LEFT_CORNER = "bottom_left_corner"; -const char *const XCURSOR_BOTTOM_RIGHT_CORNER = "bottom_right_corner"; -const char *const XCURSOR_LEFT_SIDE = "left_side"; -const char *const XCURSOR_RIGHT_SIDE = "right_side"; -const char *const XCURSOR_TOP_SIDE = "top_side"; -const char *const XCURSOR_BOTTOM_SIDE = "bottom_side"; - static void enqueue_data_for_slave(const void *data, size_t len, size_t offset, ptmx_buffer_list_t *buffer_list) @@ -3137,44 +3123,44 @@ term_mouse_motion(struct terminal *term, int button, int row, int col, void term_xcursor_update_for_seat(struct terminal *term, struct seat *seat) { - const char *xcursor = NULL; + enum cursor_shape shape = CURSOR_SHAPE_NONE; switch (term->active_surface) { case TERM_SURF_GRID: { bool have_custom_cursor = render_xcursor_is_valid(seat, term->mouse_user_cursor); - xcursor = seat->pointer.hidden ? XCURSOR_HIDDEN - : have_custom_cursor ? term->mouse_user_cursor - : term->is_searching ? XCURSOR_LEFT_PTR + shape = seat->pointer.hidden ? CURSOR_SHAPE_HIDDEN + : have_custom_cursor ? CURSOR_SHAPE_CUSTOM //term->mouse_user_cursor + : term->is_searching ? CURSOR_SHAPE_LEFT_PTR : (seat->mouse.col >= 0 && seat->mouse.row >= 0 && - term_mouse_grabbed(term, seat)) ? XCURSOR_TEXT - : XCURSOR_LEFT_PTR; + term_mouse_grabbed(term, seat)) ? CURSOR_SHAPE_TEXT + : CURSOR_SHAPE_LEFT_PTR; break; } case TERM_SURF_TITLE: case TERM_SURF_BUTTON_MINIMIZE: case TERM_SURF_BUTTON_MAXIMIZE: case TERM_SURF_BUTTON_CLOSE: - xcursor = XCURSOR_LEFT_PTR; + shape = CURSOR_SHAPE_LEFT_PTR; break; case TERM_SURF_BORDER_LEFT: case TERM_SURF_BORDER_RIGHT: case TERM_SURF_BORDER_TOP: case TERM_SURF_BORDER_BOTTOM: - xcursor = xcursor_for_csd_border(term, seat->mouse.x, seat->mouse.y); + shape = xcursor_for_csd_border(term, seat->mouse.x, seat->mouse.y); break; case TERM_SURF_NONE: return; } - if (xcursor == NULL) + if (shape == CURSOR_SHAPE_NONE) BUG("xcursor not set"); - render_xcursor_set(seat, term, xcursor); + render_xcursor_set(seat, term, shape); } void diff --git a/terminal.h b/terminal.h index 1ccb3219..6dace7ac 100644 --- a/terminal.h +++ b/terminal.h @@ -718,20 +718,6 @@ struct terminal { char *cwd; }; -extern const char *const XCURSOR_HIDDEN; -extern const char *const XCURSOR_LEFT_PTR; -extern const char *const XCURSOR_TEXT; -extern const char *const XCURSOR_TEXT_FALLBACK; -//extern const char *const XCURSOR_HAND2; -extern const char *const XCURSOR_TOP_LEFT_CORNER; -extern const char *const XCURSOR_TOP_RIGHT_CORNER; -extern const char *const XCURSOR_BOTTOM_LEFT_CORNER; -extern const char *const XCURSOR_BOTTOM_RIGHT_CORNER; -extern const char *const XCURSOR_LEFT_SIDE; -extern const char *const XCURSOR_RIGHT_SIDE; -extern const char *const XCURSOR_TOP_SIDE; -extern const char *const XCURSOR_BOTTOM_SIDE; - struct config; struct terminal *term_init( const struct config *conf, struct fdm *fdm, struct reaper *reaper, diff --git a/wayland.h b/wayland.h index e2d22031..af1bcb3f 100644 --- a/wayland.h +++ b/wayland.h @@ -28,6 +28,7 @@ #include #include +#include "cursor-shape.h" #include "fdm.h" /* Forward declarations */ @@ -151,7 +152,7 @@ struct seat { float scale; bool hidden; - const char *xcursor; + enum cursor_shape shape; struct wl_callback *xcursor_callback; bool xcursor_pending; } pointer;