diff --git a/kitty/mouse.c b/kitty/mouse.c index 74d1c837f..407a0b403 100644 --- a/kitty/mouse.c +++ b/kitty/mouse.c @@ -447,6 +447,7 @@ calculate_scrollbar_geometry(Window *w) { WindowGeometry *g = &w->render_data.geometry; unsigned cell_width = w->render_data.screen->cell_size.width; geom.width = OPT(scrollbar_width) * cell_width; + if (w->scrollbar.is_hovering) geom.width = OPT(scrollbar_hover_width) * cell_width; geom.gap = OPT(scrollbar_gap) * cell_width; geom.hitbox_expansion = OPT(scrollbar_hitbox_expansion) * cell_width; diff --git a/kitty/options/definition.py b/kitty/options/definition.py index ee090c2d5..2017b0720 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -471,6 +471,10 @@ opt('scrollbar_width', '0.5', option_type='positive_float', ctype='float', long_ The width of the scroll bar in units of cell width. ''') +opt('scrollbar_hover_width', '1', option_type='positive_float', ctype='float', long_text=''' +The width of the scroll bar when the mouse is hovering over it, in units of cell width. +''') + opt('scrollbar_handle_opacity', '0.5', option_type='positive_float', ctype='float', long_text=''' The opacity of the scrollbar handle, 0 being fully transparent and 1 being full opaque. ''') diff --git a/kitty/options/parse.py b/kitty/options/parse.py index 892c6288a..a74377f9f 100644 --- a/kitty/options/parse.py +++ b/kitty/options/parse.py @@ -1226,6 +1226,9 @@ class Parser: def scrollbar_hitbox_expansion(self, val: str, ans: dict[str, typing.Any]) -> None: ans['scrollbar_hitbox_expansion'] = positive_float(val) + def scrollbar_hover_width(self, val: str, ans: dict[str, typing.Any]) -> None: + ans['scrollbar_hover_width'] = positive_float(val) + def scrollbar_interactive(self, val: str, ans: dict[str, typing.Any]) -> None: ans['scrollbar_interactive'] = to_bool(val) diff --git a/kitty/options/to-c-generated.h b/kitty/options/to-c-generated.h index cff644784..f29d21b92 100644 --- a/kitty/options/to-c-generated.h +++ b/kitty/options/to-c-generated.h @@ -304,6 +304,19 @@ convert_from_opts_scrollbar_width(PyObject *py_opts, Options *opts) { Py_DECREF(ret); } +static void +convert_from_python_scrollbar_hover_width(PyObject *val, Options *opts) { + opts->scrollbar_hover_width = PyFloat_AsFloat(val); +} + +static void +convert_from_opts_scrollbar_hover_width(PyObject *py_opts, Options *opts) { + PyObject *ret = PyObject_GetAttrString(py_opts, "scrollbar_hover_width"); + if (ret == NULL) return; + convert_from_python_scrollbar_hover_width(ret, opts); + Py_DECREF(ret); +} + static void convert_from_python_scrollbar_handle_opacity(PyObject *val, Options *opts) { opts->scrollbar_handle_opacity = PyFloat_AsFloat(val); @@ -1392,6 +1405,8 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) { if (PyErr_Occurred()) return false; convert_from_opts_scrollbar_width(py_opts, opts); if (PyErr_Occurred()) return false; + convert_from_opts_scrollbar_hover_width(py_opts, opts); + if (PyErr_Occurred()) return false; convert_from_opts_scrollbar_handle_opacity(py_opts, opts); if (PyErr_Occurred()) return false; convert_from_opts_scrollbar_radius(py_opts, opts); diff --git a/kitty/options/types.py b/kitty/options/types.py index a32aea2fe..b29c955fd 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -420,6 +420,7 @@ option_names = ( 'scrollbar_handle_color', 'scrollbar_handle_opacity', 'scrollbar_hitbox_expansion', + 'scrollbar_hover_width', 'scrollbar_interactive', 'scrollbar_jump_on_click', 'scrollbar_min_handle_height', @@ -606,6 +607,7 @@ class Options: scrollbar_handle_color: int = 0 scrollbar_handle_opacity: float = 0.5 scrollbar_hitbox_expansion: float = 0.25 + scrollbar_hover_width: float = 1.0 scrollbar_interactive: bool = True scrollbar_jump_on_click: bool = True scrollbar_min_handle_height: float = 1.0 diff --git a/kitty/shaders.c b/kitty/shaders.c index 249933640..6dad08a5f 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -906,6 +906,7 @@ draw_scrollbar(const UIRenderData *ui) { float opacity = OPT(scrollbar_handle_opacity); float track_opacity = window->scrollbar.is_hovering ? OPT(scrollbar_track_hover_opacity) : OPT(scrollbar_track_opacity); GLsizei scrollbar_width_px = (GLsizei)(OPT(scrollbar_width) * ui->cell_width); + if (window->scrollbar.is_hovering) scrollbar_width_px = (GLsizei)(OPT(scrollbar_hover_width) * ui->cell_width); GLsizei scrollbar_gap_px = (GLsizei)(OPT(scrollbar_gap) * ui->cell_width); unsigned scrollbar_radius = (unsigned)(OPT(scrollbar_radius) * ui->cell_width); diff --git a/kitty/state.h b/kitty/state.h index 2ccacf489..a6f0d6f88 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -75,7 +75,7 @@ typedef struct Options { ScrollbarVisibilityPolicy scrollbar; bool scrollbar_interactive, scrollbar_jump_on_click; float scrollbar_width, scrollbar_radius, scrollbar_gap, scrollbar_min_handle_height, scrollbar_hitbox_expansion; - float scrollbar_handle_opacity, scrollbar_track_opacity, scrollbar_track_hover_opacity; + float scrollbar_hover_width, scrollbar_handle_opacity, scrollbar_track_opacity, scrollbar_track_hover_opacity; color_type scrollbar_handle_color, scrollbar_track_color; float text_contrast, text_gamma_adjustment;