diff --git a/CHANGELOG.md b/CHANGELOG.md index 36bf8f88..1d756d63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ * **pipe-selected** key binding. Works like **pipe-visible** and **pipe-scrollback**, but only pipes the currently selected text, if any (https://codeberg.org/dnkl/foot/issues/51). +* **cursor.hide-when-typing** option to `footrc. ### Deprecated diff --git a/config.c b/config.c index a069877a..fb939f50 100644 --- a/config.c +++ b/config.c @@ -517,6 +517,9 @@ parse_section_cursor(const char *key, const char *value, struct config *conf, else if (strcmp(key, "blink") == 0) conf->cursor.blink = str_to_bool(value); + else if (strcmp(key, "hide-when-typing") == 0) + conf->cursor.hide_when_typing = str_to_bool(value); + else if (strcmp(key, "color") == 0) { char *value_copy = strdup(value); const char *text = strtok(value_copy, " "); @@ -1251,6 +1254,7 @@ config_load(struct config *conf, const char *conf_path, bool errors_are_fatal) .cursor = { .style = CURSOR_BLOCK, .blink = false, + .hide_when_typing = false, .color = { .text = 0, .cursor = 0, diff --git a/config.h b/config.h index e47a0549..baee177d 100644 --- a/config.h +++ b/config.h @@ -74,6 +74,7 @@ struct config { struct { enum cursor_style style; bool blink; + bool hide_when_typing; struct { uint32_t text; uint32_t cursor; diff --git a/doc/footrc.5.scd b/doc/footrc.5.scd index c112a257..8fbe7bd6 100644 --- a/doc/footrc.5.scd +++ b/doc/footrc.5.scd @@ -106,6 +106,9 @@ applications can change these at runtime. Boolean. Enables blinking cursor. Note that this can be overridden by applications. Default: _no_. +*hide-when-typing* + Boolean. When enabled, the mouse cursor is hidden while typing. + *color* Two RRGGBB values specifying the foreground (text) and background (cursor) colors for the cursor. Default: inversed foreground and diff --git a/extract.c b/extract.c index b626d3e6..45dbee3f 100644 --- a/extract.c +++ b/extract.c @@ -43,6 +43,7 @@ ensure_size(struct extraction_context *ctx, size_t additional_chars) assert(ctx->size >= ctx->idx + additional_chars); return true; } + bool extract_finish(struct extraction_context *ctx, char **text, size_t *len) { diff --git a/footrc b/footrc index 87fb6fe6..5bc6f24a 100644 --- a/footrc +++ b/footrc @@ -18,6 +18,7 @@ # style=block # color=111111 dcdccc # blink=no +# hide-when-typing=no [colors] # alpha=1.0 diff --git a/input.c b/input.c index c3231a09..0d501dcb 100644 --- a/input.c +++ b/input.c @@ -544,9 +544,11 @@ keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, seat->kbd.meta = false; xkb_compose_state_reset(seat->kbd.xkb_compose_state); - if (old_focused != NULL) + if (old_focused != NULL) { + seat->pointer.hidden = false; + term_xcursor_update_for_seat(old_focused, seat); term_kbd_focus_out(old_focused); - else { + } else { /* * Sway bug - under certain conditions we get a * keyboard_leave() (and keyboard_key()) without first having @@ -694,6 +696,11 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, return; } + if (state == XKB_KEY_DOWN && term->conf->cursor.hide_when_typing) { + seat->pointer.hidden = true; + term_xcursor_update_for_seat(term, seat); + } + key += 8; bool should_repeat = xkb_keymap_key_repeats(seat->kbd.xkb_keymap, key); xkb_keysym_t sym = xkb_state_key_get_one_sym(seat->kbd.xkb_state, key); @@ -922,7 +929,7 @@ keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, seat->kbd.xkb_state, seat->kbd.mod_meta, XKB_STATE_MODS_DEPRESSED); if (seat->kbd_focus && seat->kbd_focus->active_surface == TERM_SURF_GRID) - term_xcursor_update(seat->kbd_focus); + term_xcursor_update_for_seat(seat->kbd_focus, seat); } static void @@ -1017,6 +1024,7 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, struct terminal *term = win->term; seat->pointer.serial = serial; + seat->pointer.hidden = false; LOG_DBG("pointer-enter: pointer=%p, serial=%u, surface = %p, new-moused = %p", wl_pointer, serial, surface, term); @@ -1037,7 +1045,7 @@ wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, seat->mouse.col = col >= 0 && col < term->cols ? col : -1; seat->mouse.row = row >= 0 && row < term->rows ? row : -1; - term_xcursor_update(term); + term_xcursor_update_for_seat(term, seat); break; } @@ -1078,6 +1086,8 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, "%s: pointer-leave: pointer=%p, serial=%u, surface = %p, old-moused = %p", seat->name, wl_pointer, serial, surface, old_moused); + seat->pointer.hidden = false; + if (seat->pointer.xcursor_callback != NULL) { /* A cursor frame callback may never be called if the pointer leaves our surface */ wl_callback_destroy(seat->pointer.xcursor_callback); @@ -1105,7 +1115,7 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, enum term_surface active_surface = old_moused->active_surface; old_moused->active_surface = TERM_SURF_NONE; - term_xcursor_update(old_moused); + term_xcursor_update_for_seat(old_moused, seat); switch (active_surface) { case TERM_SURF_BUTTON_MINIMIZE: @@ -1149,6 +1159,7 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, int x = wl_fixed_to_int(surface_x) * term->scale; int y = wl_fixed_to_int(surface_y) * term->scale; + seat->pointer.hidden = false; seat->mouse.x = x; seat->mouse.y = y; @@ -1180,7 +1191,7 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, break; case TERM_SURF_GRID: { - term_xcursor_update(term); + term_xcursor_update_for_seat(term, seat); int col = (x - term->margins.left) / term->cell_width; int row = (y - term->margins.top) / term->cell_height; @@ -1247,6 +1258,8 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, struct wayland *wayl = seat->wayl; struct terminal *term = seat->mouse_focus; + seat->pointer.hidden = false; + assert(term != NULL); /* Update double/triple click state */ diff --git a/render.c b/render.c index 081b7641..e0e9f3a5 100644 --- a/render.c +++ b/render.c @@ -2105,6 +2105,15 @@ render_xcursor_update(struct seat *seat) if (!seat->mouse_focus) return; + assert(seat->pointer.xcursor != NULL); + + if (seat->pointer.xcursor == XCURSOR_HIDDEN) { + /* Hide cursor */ + wl_surface_attach(seat->pointer.surface, NULL, 0, 0); + wl_surface_commit(seat->pointer.surface); + return; + } + seat->pointer.cursor = wl_cursor_theme_get_cursor( seat->pointer.theme, seat->pointer.xcursor); diff --git a/terminal.c b/terminal.c index 85dde554..ae4f3ee5 100644 --- a/terminal.c +++ b/terminal.c @@ -36,6 +36,7 @@ #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_HAND2 = "hand2"; @@ -2206,19 +2207,23 @@ 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 + = seat->pointer.hidden ? XCURSOR_HIDDEN + : term->is_searching ? XCURSOR_LEFT_PTR + : selection_enabled(term, seat) ? XCURSOR_TEXT + : XCURSOR_LEFT_PTR; + + render_xcursor_set(seat, term, xcursor); +} + void term_xcursor_update(struct terminal *term) { - tll_foreach(term->wl->seats, it) { - struct seat *seat = &it->item; - - const char *xcursor - = term->is_searching ? XCURSOR_LEFT_PTR : /* TODO: something different? */ - selection_enabled(term, seat) ? XCURSOR_TEXT : - XCURSOR_LEFT_PTR; - - render_xcursor_set(seat, term, xcursor); - } + tll_foreach(term->wl->seats, it) + term_xcursor_update_for_seat(term, &it->item); } void diff --git a/terminal.h b/terminal.h index 31316e37..8d3283ce 100644 --- a/terminal.h +++ b/terminal.h @@ -439,6 +439,7 @@ 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_HAND2; @@ -531,6 +532,7 @@ void term_mouse_motion( bool shift, bool alt, bool ctrl); bool term_mouse_grabbed(const struct terminal *term, struct seat *seat); void term_xcursor_update(struct terminal *term); +void term_xcursor_update_for_seat(struct terminal *term, struct seat *seat); void term_set_window_title(struct terminal *term, const char *title); void term_flash(struct terminal *term, unsigned duration_ms); diff --git a/wayland.h b/wayland.h index 3dbd034c..777c1517 100644 --- a/wayland.h +++ b/wayland.h @@ -152,6 +152,7 @@ struct seat { struct wl_cursor_theme *theme; struct wl_cursor *cursor; int scale; + bool hidden; const char *xcursor; struct wl_callback *xcursor_callback;