From 3bebf8429d908e896b3db940b41abf7a09d9ee85 Mon Sep 17 00:00:00 2001 From: Dan Bolser Date: Fri, 28 Aug 2026 13:09:18 +0100 Subject: [PATCH] Add a preference to zoom only the focused terminal The zoom in/out shortcuts changed the configured font size and applied it to every terminal, so terminals could not be sized individually. Add a "Zoom in/out affects only the focused terminal" preference: when enabled, each terminal keeps its own zoom level, as a scale on top of the configured font size. It is off by default, keeping the current behaviour. Addresses the first point of #1568. Terminal already had increase_font_size() and decrease_font_size() for this, but nothing called them. When zooming every terminal, start from the size the focused terminal shows, so terminals that were zoomed individually snap to it rather than keeping their offset, and drop their own zoom levels. Zooming every terminal also applied the change twice, as a font size and as a Vte font scale, making a step larger than intended and zoom out a different size than zoom in; and it could reach a font size of zero. Apply the font size alone, and stop at 1. sem-ver: feature Co-Authored-By: Claude Opus 5 (1M context) --- guake/data/org.guake.gschema.xml | 5 +++ guake/data/prefs.glade | 17 +++++++ guake/guake_app.py | 45 ++++++++++++++----- guake/prefs.py | 8 ++++ guake/terminal.py | 8 +++- .../per_terminal_zoom-102c01144c94d613.yaml | 17 +++++++ 6 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 releasenotes/notes/per_terminal_zoom-102c01144c94d613.yaml diff --git a/guake/data/org.guake.gschema.xml b/guake/data/org.guake.gschema.xml index cad5252fa..57669dff1 100644 --- a/guake/data/org.guake.gschema.xml +++ b/guake/data/org.guake.gschema.xml @@ -136,6 +136,11 @@ Hide tab bar if there is only one tab When true, the tab bar will hide when there is only one tab + + false + Zoom only the focused terminal + When true, the zoom in/out shortcuts change the font size of the focused terminal only, and each terminal keeps its own zoom level. When false, they change the configured font size, zooming every terminal at once. + false Enable Quick Open feature. diff --git a/guake/data/prefs.glade b/guake/data/prefs.glade index 1e31db6a2..b91426023 100644 --- a/guake/data/prefs.glade +++ b/guake/data/prefs.glade @@ -2261,6 +2261,23 @@ 3 + + + Zoom in/out affects only the focused terminal + True + True + False + Each terminal keeps its own zoom level. When disabled, zooming changes the configured font size and every terminal at once. + start + True + True + + + + 0 + 5 + + True diff --git a/guake/guake_app.py b/guake/guake_app.py index f81e7bcb1..84d3d084e 100644 --- a/guake/guake_app.py +++ b/guake/guake_app.py @@ -950,22 +950,47 @@ def accel_reset_terminal(self, *args): HidePrevention(self.window).allow() return True + def zoom(self, step): + """Zoom in or out by one step. + + A zoom level is a scale a terminal applies on top of the configured font size. + With per-terminal zoom, only the focused terminal is zoomed and each terminal + keeps its own level. Otherwise every terminal ends up the same size as the + focused one: their individual levels are dropped, and the configured font size + is changed instead, so the zoom is remembered across restarts. + """ + notebook = self.get_notebook() + terminal = notebook.get_current_terminal() + + if self.settings.general.get_boolean("per-terminal-zoom"): + if terminal: + terminal.font_scale += step + return + + if self.settings.general.get_boolean("use-default-font"): + # The font size follows the desktop setting, so there is no configured size + # to change here: zoom every terminal to the same level instead. + scale = (terminal.font_scale if terminal else 0) + step + for term in notebook.iter_terminals(): + term.font_scale = scale + return + + font, _, size = self.settings.styleFont.get_string("style").rpartition(" ") + # Start from the size the focused terminal shows, so a terminal zoomed on its + # own is the one the others snap to. + size = round(int(size) * terminal.font_scale_factor) if terminal else int(size) + self.settings.styleFont.set_string("style", f"{font} {max(1, size + step)}") + for term in notebook.iter_terminals(): + term.font_scale = 0 + def accel_zoom_in(self, *args): """Callback to zoom in.""" - font = " ".join(self.settings.styleFont.get_string("style").split(" ")[:-1]) - new_size = int(self.settings.styleFont.get_string("style").split(" ")[-1]) + 1 - self.settings.styleFont.set_string("style", f"{font} {new_size}") - for term in self.get_notebook().iter_terminals(): - term.set_font_scale(new_size / (new_size - 1)) + self.zoom(1) return True def accel_zoom_out(self, *args): """Callback to zoom out.""" - font = " ".join(self.settings.styleFont.get_string("style").split(" ")[:-1]) - new_size = int(self.settings.styleFont.get_string("style").split(" ")[-1]) - 1 - self.settings.styleFont.set_string("style", f"{font} {new_size}") - for term in self.get_notebook().iter_terminals(): - term.set_font_scale((new_size - 1) / new_size) + self.zoom(-1) return True def accel_increase_height(self, *args): diff --git a/guake/prefs.py b/guake/prefs.py index 42c240625..ae5a1ed0c 100644 --- a/guake/prefs.py +++ b/guake/prefs.py @@ -534,6 +534,10 @@ def on_bold_is_bright_toggled(self, chk): """Changes the value of bold_is_bright in dconf""" self.settings.styleFont.set_boolean("bold-is-bright", chk.get_active()) + def on_per_terminal_zoom_toggled(self, chk): + """Changes the activity of per_terminal_zoom in dconf""" + self.settings.general.set_boolean("per-terminal-zoom", chk.get_active()) + def on_cell_height_scale_value_changed(self, scale): value = scale.get_value() self.settings.styleFont.set_double("cell-height-scale", value) @@ -1290,6 +1294,10 @@ def load_configs(self): value = self.settings.styleFont.get_boolean("bold-is-bright") self.get_widget("bold_is_bright").set_active(value) + # zoom only the focused terminal + value = self.settings.general.get_boolean("per-terminal-zoom") + self.get_widget("per_terminal_zoom").set_active(value) + # cell height scale value = self.settings.styleFont.get_double("cell-height-scale") self.get_widget("cell_height_scale_adjustment").set_value(value) diff --git a/guake/terminal.py b/guake/terminal.py index c34544689..f9ea9acbc 100644 --- a/guake/terminal.py +++ b/guake/terminal.py @@ -513,8 +513,7 @@ def set_font_scale_index(self, scale_index): self.font_scale_index = clamp(scale_index, -6, 12) font = Pango.FontDescription(self.font.to_string()) - scale_factor = 2 ** (self.font_scale_index / 6) - new_size = int(scale_factor * font.get_size()) + new_size = int(self.font_scale_factor * font.get_size()) if font.get_size_is_absolute(): font.set_absolute_size(new_size) @@ -525,6 +524,11 @@ def set_font_scale_index(self, scale_index): font_scale = property(fset=set_font_scale_index, fget=lambda self: self.font_scale_index) + @property + def font_scale_factor(self): + """Factor the zoom level applies to the configured font size.""" + return 2 ** (self.font_scale_index / 6) + def increase_font_size(self): self.font_scale += 1 diff --git a/releasenotes/notes/per_terminal_zoom-102c01144c94d613.yaml b/releasenotes/notes/per_terminal_zoom-102c01144c94d613.yaml new file mode 100644 index 000000000..9465c2fde --- /dev/null +++ b/releasenotes/notes/per_terminal_zoom-102c01144c94d613.yaml @@ -0,0 +1,17 @@ +release_summary: > + Zoom in and out can now apply to the focused terminal only, letting each terminal + keep its own zoom level. + +features: + - | + - New "Zoom in/out affects only the focused terminal" preference, in Appearance. + When enabled, each terminal keeps its own zoom level, applied on top of the + configured font size. When disabled (the default, as before), zooming changes + the configured font size and every terminal with it. + +fixes: + - | + - Zooming every terminal no longer applies the new font size twice, once as a + font size and once as a terminal font scale, which made a zoom step larger + than intended and zoom out a different size than zoom in. + - Zooming out repeatedly no longer reaches a font size of zero.