diff --git a/docs/changelog.rst b/docs/changelog.rst index 409df450b..c497ae40f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -74,6 +74,11 @@ consumption to do the same tasks. Detailed list of changes ------------------------------------- +0.36.1 [future] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Allow specifying that the :opt:`cursor shape for unfocused windows ` should remain unchanged (:pull:`7728`) + 0.36.0 [2024-08-17] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/cursor.c b/kitty/cursor.c index b80265e0f..fb5e7d506 100644 --- a/kitty/cursor.c +++ b/kitty/cursor.c @@ -27,7 +27,7 @@ static int __eq__(Cursor *a, Cursor *b) { return EQ(bold) && EQ(italic) && EQ(strikethrough) && EQ(dim) && EQ(reverse) && EQ(decoration) && EQ(fg) && EQ(bg) && EQ(decoration_fg) && EQ(x) && EQ(y) && EQ(shape) && EQ(non_blinking); } -static const char* cursor_names[NUM_OF_CURSOR_SHAPES] = { "NO_SHAPE", "BLOCK", "BEAM", "UNDERLINE" }; +static const char* cursor_names[NUM_OF_CURSOR_SHAPES] = { "NO_SHAPE", "BLOCK", "BEAM", "UNDERLINE", "HOLLOW" }; #define BOOL(x) ((x) ? Py_True : Py_False) static PyObject * diff --git a/kitty/data-types.c b/kitty/data-types.c index 7f4b3e2e8..776ad2638 100644 --- a/kitty/data-types.c +++ b/kitty/data-types.c @@ -728,6 +728,7 @@ PyInit_fast_data_types(void) { PyModule_AddIntMacro(m, CURSOR_BLOCK); PyModule_AddIntMacro(m, CURSOR_BEAM); PyModule_AddIntMacro(m, CURSOR_UNDERLINE); + PyModule_AddIntMacro(m, CURSOR_HOLLOW); PyModule_AddIntMacro(m, NO_CURSOR_SHAPE); PyModule_AddIntMacro(m, DECAWM); PyModule_AddIntMacro(m, DECCOLM); diff --git a/kitty/data-types.h b/kitty/data-types.h index 2b860f85f..a2db1f318 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -68,7 +68,7 @@ typedef uint16_t glyph_index; typedef uint32_t pixel; typedef unsigned int index_type; typedef uint16_t sprite_index; -typedef enum CursorShapes { NO_CURSOR_SHAPE, CURSOR_BLOCK, CURSOR_BEAM, CURSOR_UNDERLINE, NUM_OF_CURSOR_SHAPES } CursorShape; +typedef enum CursorShapes { NO_CURSOR_SHAPE, CURSOR_BLOCK, CURSOR_BEAM, CURSOR_UNDERLINE, CURSOR_HOLLOW, NUM_OF_CURSOR_SHAPES } CursorShape; typedef enum { DISABLE_LIGATURES_NEVER, DISABLE_LIGATURES_CURSOR, DISABLE_LIGATURES_ALWAYS } DisableLigature; #define ERROR_PREFIX "[PARSE ERROR]" diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index c2f191730..861eb6454 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -256,6 +256,7 @@ GLFW_RELEASE: int GLFW_REPEAT: int CURSOR_BEAM: int CURSOR_BLOCK: int +CURSOR_HOLLOW: int NO_CURSOR_SHAPE: int CURSOR_UNDERLINE: int DECAWM: int diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 07f9009e8..a6a4d13e3 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -315,7 +315,7 @@ opt('cursor_shape_unfocused', 'hollow', option_type='to_cursor_unfocused_shape', ctype='int', long_text=''' Defines the text cursor shape when the OS window is not focused. The unfocused cursor shape can be one of :code:`block`, :code:`beam`, :code:`underline`, -:code:`hollow`. +:code:`hollow` and :code:`unchanged` (leave the cursor shape as it is). ''') opt('cursor_beam_thickness', '1.5', diff --git a/kitty/options/types.py b/kitty/options/types.py index 3fa0c38f8..067cc578e 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -507,7 +507,7 @@ class Options: cursor_beam_thickness: float = 1.5 cursor_blink_interval: typing.Tuple[float, kitty.options.utils.EasingFunction, kitty.options.utils.EasingFunction] = (-1.0, kitty.options.utils.EasingFunction(), kitty.options.utils.EasingFunction()) cursor_shape: int = 1 - cursor_shape_unfocused: int = 0 + cursor_shape_unfocused: int = 4 cursor_stop_blinking_after: float = 15.0 cursor_text_color: typing.Optional[kitty.fast_data_types.Color] = Color(17, 17, 17) cursor_underline_thickness: float = 2.0 diff --git a/kitty/options/utils.py b/kitty/options/utils.py index 876bf6381..49c8517bb 100644 --- a/kitty/options/utils.py +++ b/kitty/options/utils.py @@ -46,7 +46,7 @@ unit_float, ) from kitty.constants import is_macos -from kitty.fast_data_types import CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE, NO_CURSOR_SHAPE, Color, Shlex, SingleKey +from kitty.fast_data_types import CURSOR_BEAM, CURSOR_BLOCK, CURSOR_HOLLOW, CURSOR_UNDERLINE, NO_CURSOR_SHAPE, Color, Shlex, SingleKey from kitty.fonts import FontModification, FontSpec, ModificationType, ModificationUnit, ModificationValue from kitty.key_names import character_key_name_aliases, functional_key_name_aliases, get_key_name_lookup from kitty.rgb import color_as_int @@ -530,7 +530,8 @@ def cursor_text_color(x: str) -> Optional[Color]: 'block': CURSOR_BLOCK, 'beam': CURSOR_BEAM, 'underline': CURSOR_UNDERLINE, - 'hollow': NO_CURSOR_SHAPE + 'hollow': CURSOR_HOLLOW, + 'unchanged': NO_CURSOR_SHAPE, } diff --git a/kitty/screen.c b/kitty/screen.c index a4ae03bcc..28f425f89 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -2442,8 +2442,7 @@ screen_request_capabilities(Screen *self, char c, const char *query) { if (strcmp(" q", query) == 0) { // cursor shape DECSCUSR switch(self->cursor->shape) { - case NO_CURSOR_SHAPE: - case NUM_OF_CURSOR_SHAPES: + case NO_CURSOR_SHAPE: case CURSOR_HOLLOW: case NUM_OF_CURSOR_SHAPES: shape = 1; break; case CURSOR_BLOCK: shape = self->cursor->non_blinking ? 2 : 0; break; diff --git a/kitty/shaders.c b/kitty/shaders.c index 1cad02886..fa60a04f7 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -327,27 +327,17 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c if (cursor->opacity > 0) { rd->cursor_x = cursor->x, rd->cursor_y = cursor->y; rd->cursor_opacity = cursor->opacity; - if (cursor->is_focused) { - switch(cursor->shape) { - default: - rd->cursor_fg_sprite_idx = BLOCK_IDX; break; - case CURSOR_BEAM: - rd->cursor_fg_sprite_idx = BEAM_IDX; break; - case CURSOR_UNDERLINE: - rd->cursor_fg_sprite_idx = UNDERLINE_IDX; break; - } - } else { - switch(OPT(cursor_shape_unfocused)) { - default: - rd->cursor_fg_sprite_idx = UNFOCUSED_IDX; break; - case CURSOR_BEAM: - rd->cursor_fg_sprite_idx = BEAM_IDX; break; - case CURSOR_UNDERLINE: - rd->cursor_fg_sprite_idx = UNDERLINE_IDX; break; - case CURSOR_BLOCK: - rd->cursor_fg_sprite_idx = BLOCK_IDX; break; - } - } + CursorShape cs = (cursor->is_focused || OPT(cursor_shape_unfocused) == NO_CURSOR_SHAPE) ? cursor->shape : OPT(cursor_shape_unfocused); + switch(cs) { + case CURSOR_BEAM: + rd->cursor_fg_sprite_idx = BEAM_IDX; break; + case CURSOR_UNDERLINE: + rd->cursor_fg_sprite_idx = UNDERLINE_IDX; break; + case CURSOR_BLOCK: case NUM_OF_CURSOR_SHAPES: + rd->cursor_fg_sprite_idx = BLOCK_IDX; break; + case CURSOR_HOLLOW: case NO_CURSOR_SHAPE: + rd->cursor_fg_sprite_idx = UNFOCUSED_IDX; break; + }; color_type cell_fg = rd->default_fg, cell_bg = rd->default_bg; index_type cell_color_x = cursor->x; bool reversed = false;