mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-15 22:05:24 -05:00
terminal: use the 'text' xcursor pointer whenever selection is possible
This commit is contained in:
parent
729ba8b8ac
commit
0dd37f0a36
6 changed files with 72 additions and 36 deletions
4
csi.c
4
csi.c
|
|
@ -875,14 +875,17 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
|
||||
case 1000:
|
||||
term->mouse_tracking = MOUSE_CLICK;
|
||||
term_xcursor_update(term);
|
||||
break;
|
||||
|
||||
case 1002:
|
||||
term->mouse_tracking = MOUSE_DRAG;
|
||||
term_xcursor_update(term);
|
||||
break;
|
||||
|
||||
case 1003:
|
||||
term->mouse_tracking = MOUSE_MOTION;
|
||||
term_xcursor_update(term);
|
||||
break;
|
||||
|
||||
case 1004:
|
||||
|
|
@ -1000,6 +1003,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
case 1002: /* MOUSE_BUTTON_EVENT */
|
||||
case 1003: /* MOUSE_ANY_EVENT */
|
||||
term->mouse_tracking = MOUSE_NONE;
|
||||
term_xcursor_update(term);
|
||||
break;
|
||||
|
||||
case 1005: /* MOUSE_UTF8 */
|
||||
|
|
|
|||
8
input.c
8
input.c
|
|
@ -88,6 +88,7 @@ keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
|||
wayl->focused = wayl_terminal_from_surface(wayl, surface);
|
||||
assert(wayl->focused != NULL);
|
||||
term_focus_in(wayl->focused);
|
||||
term_xcursor_update(wayl->focused);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -379,6 +380,8 @@ keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
|||
xkb_state_update_mask(
|
||||
wayl->kbd.xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group);
|
||||
|
||||
bool old_shift = wayl->kbd.shift;
|
||||
|
||||
/* Update state of modifiers we're interrested in for e.g mouse events */
|
||||
wayl->kbd.shift = xkb_state_mod_index_is_active(
|
||||
wayl->kbd.xkb_state, wayl->kbd.mod_shift, XKB_STATE_MODS_DEPRESSED);
|
||||
|
|
@ -388,6 +391,9 @@ keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
|||
wayl->kbd.xkb_state, wayl->kbd.mod_ctrl, XKB_STATE_MODS_DEPRESSED);
|
||||
wayl->kbd.meta = xkb_state_mod_index_is_active(
|
||||
wayl->kbd.xkb_state, wayl->kbd.mod_meta, XKB_STATE_MODS_DEPRESSED);
|
||||
|
||||
if (wayl->moused && old_shift != wayl->kbd.shift)
|
||||
term_xcursor_update(wayl->moused);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -431,7 +437,7 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer,
|
|||
wayl->mouse.col = x / term->cell_width;
|
||||
wayl->mouse.row = y / term->cell_height;
|
||||
|
||||
wayl_update_cursor_surface(wayl, term);
|
||||
term_xcursor_update(term);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
14
terminal.c
14
terminal.c
|
|
@ -483,6 +483,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
|||
.text = conf->cursor.color.text,
|
||||
.cursor = conf->cursor.color.cursor,
|
||||
},
|
||||
.xcursor = "text",
|
||||
.selection = {
|
||||
.start = {-1, -1},
|
||||
.end = {-1, -1},
|
||||
|
|
@ -1429,6 +1430,19 @@ term_mouse_motion(struct terminal *term, int button, int row, int col,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
term_xcursor_update(struct terminal *term)
|
||||
{
|
||||
const bool is_focused = term->wl->focused == term;
|
||||
const char *new_cursor =
|
||||
is_focused && selection_enabled(term) ? "text" : "left_ptr";
|
||||
|
||||
LOG_DBG("setting xcursor to '%s' for term=%p", new_cursor, term);
|
||||
|
||||
term->xcursor = new_cursor;
|
||||
wayl_cursor_set(term->wl, term);
|
||||
}
|
||||
|
||||
void
|
||||
term_set_window_title(struct terminal *term, const char *title)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -240,6 +240,7 @@ struct terminal {
|
|||
uint32_t text;
|
||||
uint32_t cursor;
|
||||
} cursor_color;
|
||||
const char *xcursor;
|
||||
|
||||
struct {
|
||||
struct coord start;
|
||||
|
|
@ -365,6 +366,7 @@ void term_mouse_up(struct terminal *term, int button, int row, int col,
|
|||
bool shift, bool alt, bool ctrl);
|
||||
void term_mouse_motion(struct terminal *term, int button, int row, int col,
|
||||
bool shift, bool alt, bool ctrl);
|
||||
void term_xcursor_update(struct terminal *term);
|
||||
|
||||
void term_set_window_title(struct terminal *term, const char *title);
|
||||
void term_flash(struct terminal *term, unsigned duration_ms);
|
||||
|
|
|
|||
77
wayland.c
77
wayland.c
|
|
@ -28,6 +28,9 @@
|
|||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
static bool wayl_reload_cursor_theme(
|
||||
struct wayland *wayl, const struct terminal *term);
|
||||
|
||||
static void
|
||||
shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
|
||||
{
|
||||
|
|
@ -792,7 +795,45 @@ wayl_win_destroy(struct wl_window *win)
|
|||
}
|
||||
|
||||
bool
|
||||
wayl_reload_cursor_theme(struct wayland *wayl, struct terminal *term)
|
||||
wayl_cursor_set(struct wayland *wayl, const struct terminal *term)
|
||||
{
|
||||
if (wayl->pointer.theme == NULL)
|
||||
return false;
|
||||
|
||||
if (wayl->moused != term) {
|
||||
/* This terminal doesn't have mouse focus */
|
||||
return true;
|
||||
}
|
||||
|
||||
wayl->pointer.cursor = wl_cursor_theme_get_cursor(wayl->pointer.theme, term->xcursor);
|
||||
if (wayl->pointer.cursor == NULL) {
|
||||
LOG_ERR("%s: failed to load xcursor pointer '%s'",
|
||||
wayl->pointer.theme_name, term->xcursor);
|
||||
return false;
|
||||
}
|
||||
|
||||
const int scale = term->scale;
|
||||
struct wl_cursor_image *image = wayl->pointer.cursor->images[0];
|
||||
|
||||
wl_surface_attach(
|
||||
wayl->pointer.surface, wl_cursor_image_get_buffer(image), 0, 0);
|
||||
|
||||
wl_pointer_set_cursor(
|
||||
wayl->pointer.pointer, wayl->pointer.serial,
|
||||
wayl->pointer.surface,
|
||||
image->hotspot_x / scale, image->hotspot_y / scale);
|
||||
|
||||
wl_surface_damage_buffer(
|
||||
wayl->pointer.surface, 0, 0, INT32_MAX, INT32_MAX);
|
||||
|
||||
wl_surface_set_buffer_scale(wayl->pointer.surface, scale);
|
||||
wl_surface_commit(wayl->pointer.surface);
|
||||
wl_display_roundtrip(wayl->display);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
wayl_reload_cursor_theme(struct wayland *wayl, const struct terminal *term)
|
||||
{
|
||||
if (wayl->pointer.size == 0)
|
||||
return true;
|
||||
|
|
@ -808,45 +849,15 @@ wayl_reload_cursor_theme(struct wayland *wayl, struct terminal *term)
|
|||
|
||||
wayl->pointer.theme = wl_cursor_theme_load(
|
||||
wayl->pointer.theme_name, wayl->pointer.size * term->scale, wayl->shm);
|
||||
|
||||
if (wayl->pointer.theme == NULL) {
|
||||
LOG_ERR("failed to load cursor theme");
|
||||
return false;
|
||||
}
|
||||
|
||||
wayl->pointer.cursor = wl_cursor_theme_get_cursor(
|
||||
wayl->pointer.theme, "left_ptr");
|
||||
assert(wayl->pointer.cursor != NULL);
|
||||
wayl_update_cursor_surface(wayl, term);
|
||||
|
||||
return true;
|
||||
return wayl_cursor_set(wayl, term);
|
||||
}
|
||||
|
||||
void
|
||||
wayl_update_cursor_surface(struct wayland *wayl, struct terminal *term)
|
||||
{
|
||||
if (wayl->pointer.cursor == NULL)
|
||||
return;
|
||||
|
||||
const int scale = term->scale;
|
||||
wl_surface_set_buffer_scale(wayl->pointer.surface, scale);
|
||||
|
||||
struct wl_cursor_image *image = wayl->pointer.cursor->images[0];
|
||||
|
||||
wl_surface_attach(
|
||||
wayl->pointer.surface, wl_cursor_image_get_buffer(image), 0, 0);
|
||||
|
||||
wl_pointer_set_cursor(
|
||||
wayl->pointer.pointer, wayl->pointer.serial,
|
||||
wayl->pointer.surface,
|
||||
image->hotspot_x / scale, image->hotspot_y / scale);
|
||||
|
||||
wl_surface_damage_buffer(
|
||||
wayl->pointer.surface, 0, 0, INT32_MAX, INT32_MAX);
|
||||
|
||||
wl_surface_commit(wayl->pointer.surface);
|
||||
}
|
||||
|
||||
|
||||
struct terminal *
|
||||
wayl_terminal_from_surface(struct wayland *wayl, struct wl_surface *surface)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -166,8 +166,7 @@ struct terminal *wayl_terminal_from_xdg_toplevel(
|
|||
struct wayland *wayl, struct xdg_toplevel *toplevel);
|
||||
|
||||
/* TODO: pass something other than 'term'? Need scale... */
|
||||
bool wayl_reload_cursor_theme(struct wayland *wayl, struct terminal *term);
|
||||
void wayl_update_cursor_surface(struct wayland *wayl, struct terminal *term);
|
||||
bool wayl_cursor_set(struct wayland *wayl, const struct terminal *term);
|
||||
|
||||
struct wl_window *wayl_win_init(struct wayland *wayl);
|
||||
void wayl_win_destroy(struct wl_window *win);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue