From 56fc4eddbdfb911bdc5816765ab14bd00f0b45b0 Mon Sep 17 00:00:00 2001 From: aki Date: Wed, 12 Jun 2024 21:29:04 +0900 Subject: [PATCH 1/3] add option to scale window_logo via window_logo_scale --- kitty/options/definition.py | 7 +++++++ kitty/options/parse.py | 5 ++++- kitty/options/to-c-generated.h | 15 +++++++++++++++ kitty/options/types.py | 4 +++- kitty/shaders.c | 20 ++++++++++++++++++++ kitty/state.h | 1 + 6 files changed, 50 insertions(+), 2 deletions(-) diff --git a/kitty/options/definition.py b/kitty/options/definition.py index aebc28e1a..7486f6d47 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -1160,6 +1160,13 @@ ''' ) +opt('window_logo_scale', '0', + option_type='int', ctype='int', + long_text=''' +The percentage [1-100] of the window which the logo should scale to. +0 to disable. +''' + ) opt('resize_debounce_time', '0.1 0.5', option_type='resize_debounce_time', ctype='!resize_debounce_time', diff --git a/kitty/options/parse.py b/kitty/options/parse.py index cfeb2e3b3..11fab67bf 100644 --- a/kitty/options/parse.py +++ b/kitty/options/parse.py @@ -1388,7 +1388,10 @@ def window_logo_position(self, val: str, ans: typing.Dict[str, typing.Any]) -> N raise ValueError(f"The value {val} is not a valid choice for window_logo_position") ans["window_logo_position"] = val - choices_for_window_logo_position = frozenset(('top-left', 'top', 'top-right', 'left', 'center', 'right', 'bottom-left', 'bottom', 'bottom-right')) + choices_for_window_logo_position = choices_for_placement_strategy + + def window_logo_scale(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: + ans['window_logo_scale'] = int(val) def window_margin_width(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['window_margin_width'] = edge_width(val) diff --git a/kitty/options/to-c-generated.h b/kitty/options/to-c-generated.h index eba012444..437e2830a 100644 --- a/kitty/options/to-c-generated.h +++ b/kitty/options/to-c-generated.h @@ -616,6 +616,19 @@ convert_from_opts_window_logo_alpha(PyObject *py_opts, Options *opts) { Py_DECREF(ret); } +static void +convert_from_python_window_logo_scale(PyObject *val, Options *opts) { + opts->window_logo_scale = PyLong_AsLong(val); +} + +static void +convert_from_opts_window_logo_scale(PyObject *py_opts, Options *opts) { + PyObject *ret = PyObject_GetAttrString(py_opts, "window_logo_scale"); + if (ret == NULL) return; + convert_from_python_window_logo_scale(ret, opts); + Py_DECREF(ret); +} + static void convert_from_python_resize_debounce_time(PyObject *val, Options *opts) { resize_debounce_time(val, opts); @@ -1232,6 +1245,8 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) { if (PyErr_Occurred()) return false; convert_from_opts_window_logo_alpha(py_opts, opts); if (PyErr_Occurred()) return false; + convert_from_opts_window_logo_scale(py_opts, opts); + if (PyErr_Occurred()) return false; convert_from_opts_resize_debounce_time(py_opts, opts); if (PyErr_Occurred()) return false; convert_from_opts_resize_in_steps(py_opts, opts); diff --git a/kitty/options/types.py b/kitty/options/types.py index 8ee04f12b..ef766f274 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -34,7 +34,7 @@ choices_for_terminfo_type = typing.Literal['path', 'direct', 'none'] choices_for_undercurl_style = typing.Literal['thin-sparse', 'thin-dense', 'thick-sparse', 'thick-dense'] choices_for_underline_hyperlinks = typing.Literal['hover', 'always', 'never'] -choices_for_window_logo_position = typing.Literal['top-left', 'top', 'top-right', 'left', 'center', 'right', 'bottom-left', 'bottom', 'bottom-right'] +choices_for_window_logo_position = choices_for_placement_strategy option_names = ( # {{{ 'action_alias', @@ -459,6 +459,7 @@ 'window_logo_alpha', 'window_logo_path', 'window_logo_position', + 'window_logo_scale', 'window_margin_width', 'window_padding_width', 'window_resize_step_cells', @@ -619,6 +620,7 @@ class Options: window_logo_alpha: float = 0.5 window_logo_path: typing.Optional[str] = None window_logo_position: choices_for_window_logo_position = 'bottom-right' + window_logo_scale: int = 0 window_margin_width: FloatEdges = FloatEdges(left=0, top=0, right=0, bottom=0) window_padding_width: FloatEdges = FloatEdges(left=0, top=0, right=0, bottom=0) window_resize_step_cells: int = 2 diff --git a/kitty/shaders.c b/kitty/shaders.c index bcda16822..052a5c118 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -732,6 +732,26 @@ draw_window_logo(ssize_t vao_idx, OSWindow *os_window, const WindowLogoRenderDat BLEND_PREMULT; GLfloat logo_width_gl = gl_size(wl->instance->width, os_window->viewport_width); GLfloat logo_height_gl = gl_size(wl->instance->height, os_window->viewport_height); + + if (OPT(window_logo_scale) != 0) { + unsigned int scaled_wl_width; + unsigned int scaled_wl_height; + + if (os_window->viewport_height < os_window->viewport_width) { + scaled_wl_height = os_window->viewport_height * OPT(window_logo_scale) / 100; + scaled_wl_width = wl->instance->width * scaled_wl_height / wl->instance->height; + } else { + scaled_wl_width = os_window->viewport_width * OPT(window_logo_scale) / 100; + scaled_wl_height = wl->instance->height * scaled_wl_width / wl->instance->width; + } + + logo_height_gl = gl_size(scaled_wl_height, os_window->viewport_height); + logo_width_gl = gl_size(scaled_wl_width, os_window->viewport_width); + } else { + logo_height_gl = 0; + logo_width_gl = 0; + } + GLfloat logo_left_gl = clamp_position_to_nearest_pixel( crd->gl.xstart + crd->gl.width * wl->position.canvas_x - logo_width_gl * wl->position.image_x, os_window->viewport_width); GLfloat logo_top_gl = clamp_position_to_nearest_pixel( diff --git a/kitty/state.h b/kitty/state.h index fb86b2128..084164d27 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -65,6 +65,7 @@ typedef struct { ImageAnchorPosition window_logo_position; bool background_image_linear; float background_tint, background_tint_gaps, window_logo_alpha; + unsigned int window_logo_scale; bool dynamic_background_opacity; float inactive_text_alpha; From a8b28ca32bbc980f7388ea5368a947a8222c78b0 Mon Sep 17 00:00:00 2001 From: aki Date: Wed, 12 Jun 2024 22:13:00 +0900 Subject: [PATCH 2/3] remove test block --- kitty/shaders.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/kitty/shaders.c b/kitty/shaders.c index 052a5c118..0de117ec5 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -747,9 +747,6 @@ draw_window_logo(ssize_t vao_idx, OSWindow *os_window, const WindowLogoRenderDat logo_height_gl = gl_size(scaled_wl_height, os_window->viewport_height); logo_width_gl = gl_size(scaled_wl_width, os_window->viewport_width); - } else { - logo_height_gl = 0; - logo_width_gl = 0; } GLfloat logo_left_gl = clamp_position_to_nearest_pixel( From 4d8b34cab8382d380f25f22a604b4adcd79cd41a Mon Sep 17 00:00:00 2001 From: aki Date: Thu, 13 Jun 2024 23:33:28 +0900 Subject: [PATCH 3/3] change window_logo_scale to float, add granular xy scaling options to window_logo_scale --- kitty/options/definition.py | 9 +++++---- kitty/options/parse.py | 5 +++-- kitty/options/to-c-generated.h | 2 +- kitty/options/to-c.h | 6 ++++++ kitty/options/types.py | 2 +- kitty/options/utils.py | 7 +++++++ kitty/shaders.c | 36 +++++++++++++++++++++++++--------- kitty/state.h | 2 +- 8 files changed, 51 insertions(+), 18 deletions(-) diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 7486f6d47..1d9068011 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -1160,11 +1160,12 @@ ''' ) -opt('window_logo_scale', '0', - option_type='int', ctype='int', +opt('window_logo_scale', '0.0 -1.0', + option_type='window_logo_scale', ctype='!window_logo_scale', long_text=''' -The percentage [1-100] of the window which the logo should scale to. -0 to disable. +The percentage [1-100] of the window which the logo should scale to. +Optionally setting 2 seperate values allows individual Width/Height scaling. +Value of 0 in a given dimension disables scaling in that direction, single 0 to disable scaling. ''' ) diff --git a/kitty/options/parse.py b/kitty/options/parse.py index 11fab67bf..32c75dab2 100644 --- a/kitty/options/parse.py +++ b/kitty/options/parse.py @@ -18,7 +18,8 @@ shell_integration, store_multiple, symbol_map, tab_activity_symbol, tab_bar_edge, tab_bar_margin_height, tab_bar_min_tabs, tab_fade, tab_font_style, tab_separator, tab_title_template, titlebar_color, to_cursor_shape, to_font_size, to_layout_names, to_modifiers, - url_prefixes, url_style, visual_window_select_characters, window_border_width, window_size + url_prefixes, url_style, visual_window_select_characters, window_border_width, window_logo_scale, + window_size ) @@ -1391,7 +1392,7 @@ def window_logo_position(self, val: str, ans: typing.Dict[str, typing.Any]) -> N choices_for_window_logo_position = choices_for_placement_strategy def window_logo_scale(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: - ans['window_logo_scale'] = int(val) + ans['window_logo_scale'] = window_logo_scale(val) def window_margin_width(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['window_margin_width'] = edge_width(val) diff --git a/kitty/options/to-c-generated.h b/kitty/options/to-c-generated.h index 437e2830a..1b51973fd 100644 --- a/kitty/options/to-c-generated.h +++ b/kitty/options/to-c-generated.h @@ -618,7 +618,7 @@ convert_from_opts_window_logo_alpha(PyObject *py_opts, Options *opts) { static void convert_from_python_window_logo_scale(PyObject *val, Options *opts) { - opts->window_logo_scale = PyLong_AsLong(val); + window_logo_scale(val, opts); } static void diff --git a/kitty/options/to-c.h b/kitty/options/to-c.h index 76608e200..00434564f 100644 --- a/kitty/options/to-c.h +++ b/kitty/options/to-c.h @@ -338,6 +338,12 @@ tab_bar_margin_height(PyObject *val, Options *opts) { opts->tab_bar_margin_height.inner = PyFloat_AsDouble(PyTuple_GET_ITEM(val, 1)); } +static void +window_logo_scale(PyObject *src, Options *opts) { + opts->window_logo_scale.width = PyFloat_AsFloat(PyTuple_GET_ITEM(src, 0)); + opts->window_logo_scale.height = PyFloat_AsFloat(PyTuple_GET_ITEM(src, 1)); +} + static void resize_debounce_time(PyObject *src, Options *opts) { opts->resize_debounce_time.on_end = s_double_to_monotonic_t(PyFloat_AsDouble(PyTuple_GET_ITEM(src, 0))); diff --git a/kitty/options/types.py b/kitty/options/types.py index ef766f274..6f4bac55e 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -620,7 +620,7 @@ class Options: window_logo_alpha: float = 0.5 window_logo_path: typing.Optional[str] = None window_logo_position: choices_for_window_logo_position = 'bottom-right' - window_logo_scale: int = 0 + window_logo_scale: typing.Tuple[float, float] = (0, -1.0) window_margin_width: FloatEdges = FloatEdges(left=0, top=0, right=0, bottom=0) window_padding_width: FloatEdges = FloatEdges(left=0, top=0, right=0, bottom=0) window_resize_step_cells: int = 2 diff --git a/kitty/options/utils.py b/kitty/options/utils.py index 6ac4aec20..4ed496605 100644 --- a/kitty/options/utils.py +++ b/kitty/options/utils.py @@ -646,6 +646,13 @@ def resize_draw_strategy(x: str) -> int: return cmap.get(x.lower(), 0) +def window_logo_scale(x: str) -> Tuple[float, float]: + parts = x.split(maxsplit=1) + if len(parts) == 1: + return positive_float(parts[0]), -1.0 + return positive_float(parts[0]), positive_float(parts[1]) + + def resize_debounce_time(x: str) -> Tuple[float, float]: parts = x.split(maxsplit=1) if len(parts) == 1: diff --git a/kitty/shaders.c b/kitty/shaders.c index 0de117ec5..f1ff64840 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -733,16 +733,34 @@ draw_window_logo(ssize_t vao_idx, OSWindow *os_window, const WindowLogoRenderDat GLfloat logo_width_gl = gl_size(wl->instance->width, os_window->viewport_width); GLfloat logo_height_gl = gl_size(wl->instance->height, os_window->viewport_height); - if (OPT(window_logo_scale) != 0) { - unsigned int scaled_wl_width; - unsigned int scaled_wl_height; + if (OPT(window_logo_scale.width) > 0 || OPT(window_logo_scale.height) > 0) { + unsigned int scaled_wl_width = os_window->viewport_width; + unsigned int scaled_wl_height = os_window->viewport_height; - if (os_window->viewport_height < os_window->viewport_width) { - scaled_wl_height = os_window->viewport_height * OPT(window_logo_scale) / 100; - scaled_wl_width = wl->instance->width * scaled_wl_height / wl->instance->height; - } else { - scaled_wl_width = os_window->viewport_width * OPT(window_logo_scale) / 100; - scaled_wl_height = wl->instance->height * scaled_wl_width / wl->instance->width; + // [sx] Scales logo to sx % of the viewports shortest dimension, preserving aspect ratio + if (OPT(window_logo_scale.height) < 0) { + if (os_window->viewport_height < os_window->viewport_width) { + scaled_wl_height = (int)(os_window->viewport_height * OPT(window_logo_scale.width) / 100); + scaled_wl_width = wl->instance->width * scaled_wl_height / wl->instance->height; + } else { + scaled_wl_width = (int)(os_window->viewport_width * OPT(window_logo_scale.width) / 100); + scaled_wl_height = wl->instance->height * scaled_wl_width / wl->instance->width; + } + } + // [0 sy] Scales logo's y dimension to sy % of viewporty keeping original x dimension + else if (OPT(window_logo_scale.width) == 0.0) { + scaled_wl_height = (int)(scaled_wl_height * OPT(window_logo_scale.height) / 100); + scaled_wl_width = wl->instance->width; + } + // [sx 0] Scales logo's x dimension to sx % of viewportx keeping original y dimension + else if (OPT(window_logo_scale.height) == 0.0) { + scaled_wl_width = (int)(scaled_wl_width * OPT(window_logo_scale.width) / 100); + scaled_wl_height = wl->instance->height; + } + // [sx sy] Scales logo's x and y dimension to sx and sy % of viewportx and viewporty respectively + else { + scaled_wl_height = (int)(scaled_wl_height * OPT(window_logo_scale.height) / 100); + scaled_wl_width = (int)(scaled_wl_width * OPT(window_logo_scale.width) / 100); } logo_height_gl = gl_size(scaled_wl_height, os_window->viewport_height); diff --git a/kitty/state.h b/kitty/state.h index 084164d27..64641c14f 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -65,7 +65,7 @@ typedef struct { ImageAnchorPosition window_logo_position; bool background_image_linear; float background_tint, background_tint_gaps, window_logo_alpha; - unsigned int window_logo_scale; + struct { float width, height; } window_logo_scale; bool dynamic_background_opacity; float inactive_text_alpha;