From fb90fa22a301a5e8de36adeb5aed6d4c57973628 Mon Sep 17 00:00:00 2001 From: lenemter Date: Sat, 4 Apr 2026 23:20:47 +0300 Subject: [PATCH 1/5] Tooltip and Text improvements --- lib/Drawing/Color.vala | 6 +-- lib/Widgets/Text.vala | 52 +++++++++++++++++++---- src/Widgets/MultitaskingView/Tooltip.vala | 4 +- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/lib/Drawing/Color.vala b/lib/Drawing/Color.vala index 1733c6d13..3203127a6 100644 --- a/lib/Drawing/Color.vala +++ b/lib/Drawing/Color.vala @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 elementary, Inc. (https://elementary.io) + * Copyright 2019-2026 elementary, Inc. (https://elementary.io) * Copyright 2011–2013 Robert Dyer * SPDX-License-Identifier: LGPL-3.0-or-later */ @@ -16,7 +16,7 @@ namespace Gala.Drawing { public const Clutter.Color DARK_BORDER = { 0, 0, 0, 191}; public const Clutter.Color LIGHT_HIGHLIGHT = { 255, 255, 255, 255}; public const Clutter.Color DARK_HIGHLIGHT = { 255, 255, 255, 13}; - public const Clutter.Color TOOLTIP_BACKGROUND = { 0, 0, 0, 255}; + public const Clutter.Color TOOLTIP_BACKGROUND = { 26, 26, 26, 230}; public const Clutter.Color TOOLTIP_TEXT_COLOR = { 255, 255, 255, 255}; #else public const Cogl.Color LIGHT_BACKGROUND = { 250, 250, 250, 255}; @@ -25,7 +25,7 @@ namespace Gala.Drawing { public const Cogl.Color DARK_BORDER = { 0, 0, 0, 191}; public const Cogl.Color LIGHT_HIGHLIGHT = { 255, 255, 255, 255}; public const Cogl.Color DARK_HIGHLIGHT = { 255, 255, 255, 13}; - public const Cogl.Color TOOLTIP_BACKGROUND = { 0, 0, 0, 255}; + public const Cogl.Color TOOLTIP_BACKGROUND = { 26, 26, 26, 230 }; public const Cogl.Color TOOLTIP_TEXT_COLOR = { 255, 255, 255, 255}; #endif diff --git a/lib/Widgets/Text.vala b/lib/Widgets/Text.vala index 7a5bd37de..0e74bd73e 100644 --- a/lib/Widgets/Text.vala +++ b/lib/Widgets/Text.vala @@ -1,13 +1,13 @@ /* * SPDX-License-Identifier: LGPL-3.0-or-later - * SPDX-FileCopyrightText: 2025 elementary, Inc. (https://elementary.io) + * SPDX-FileCopyrightText: 2025-2026 elementary, Inc. (https://elementary.io) */ /* * Clutter.Text that automatically changes font-name to the system one */ public class Gala.Text : Clutter.Actor { - private static GLib.Settings gnome_interface_settings; + private static GLib.Settings gnome_interface_settings = new GLib.Settings ("org.gnome.desktop.interface"); #if HAS_MUTTER47 public Cogl.Color color { get { return text_actor.color; } set { text_actor.color = value; } } @@ -15,16 +15,31 @@ public class Gala.Text : Clutter.Actor { public Clutter.Color color { get { return text_actor.color; } set { text_actor.color = value; } } #endif public Pango.EllipsizeMode ellipsize { get { return text_actor.ellipsize; } set { text_actor.ellipsize = value; } } - public Pango.Alignment line_alignment { - get { return text_actor.line_alignment; } set { text_actor.line_alignment = value; } - } + public Pango.Alignment line_alignment { get { return text_actor.line_alignment; } set { text_actor.line_alignment = value; }} public string text { get { return text_actor.text; } set { text_actor.text = value; } } - private Clutter.Text text_actor; - - static construct { - gnome_interface_settings = new GLib.Settings ("org.gnome.desktop.interface"); + public bool use_shadow { + get { + return shadow_actor.get_parent () != null; + } + set { + if (value) { + insert_child_below (shadow_actor, null); + } else { + remove_child (shadow_actor); + } + } } +#if HAS_MUTTER47 + public Cogl.Color shadow_color { get { return shadow_actor.color; } set { shadow_actor.color = value; } } +#else + public Clutter.Color shadow_color { get { return shadow_actor.color; } set { shadow_actor.color = value; } } +#endif + // public float shadow_offset_x { get { return shadow_actor.margin_left; } set { shadow_actor.margin_left = value; }} + // public float shadow_offset_y { get { return shadow_actor.margin_top; } set { shadow_actor.margin_top = value; }} + + private Clutter.Text text_actor; + private Clutter.Text shadow_actor; class construct { set_layout_manager_type (typeof (Clutter.BinLayout)); @@ -34,6 +49,17 @@ public class Gala.Text : Clutter.Actor { text_actor = new Clutter.Text (); add_child (text_actor); + shadow_actor = new Clutter.Text (); + // We add 2 blur effects because the shadow size needs to be 2px, and Clutter.BlurEffect is quite cheap. + // TODO: replace with a Gala.BoxBlurEffect in the future + shadow_actor.add_effect (new Clutter.BlurEffect ()); + shadow_actor.add_effect (new Clutter.BlurEffect ()); + + text_actor.bind_property ("ellipsize", shadow_actor, "ellipsize"); + text_actor.bind_property ("line-alignment", shadow_actor, "line-alignment"); + text_actor.bind_property ("text", shadow_actor, "text"); + text_actor.bind_property ("font-name", shadow_actor, "font-name"); + set_system_font_name (); gnome_interface_settings.changed["font-name"].connect (set_system_font_name); } @@ -50,4 +76,12 @@ public class Gala.Text : Clutter.Actor { text_actor.font_name = string.joinv (" ", name); } + + public override void get_preferred_height (float for_width, out float min_height_p, out float natural_height_p) { + /* + *shadow_actor.margin_top increases total height by 2px, when it shouldn't affect height at all. + * To workaround this we override the height calculation. + */ + min_height_p = natural_height_p = text_actor.height; + } } diff --git a/src/Widgets/MultitaskingView/Tooltip.vala b/src/Widgets/MultitaskingView/Tooltip.vala index 2dec8ed57..acaa0c7dc 100644 --- a/src/Widgets/MultitaskingView/Tooltip.vala +++ b/src/Widgets/MultitaskingView/Tooltip.vala @@ -22,7 +22,9 @@ public class Gala.Tooltip : Clutter.Actor { construct { text_actor = new Gala.Text () { ellipsize = Pango.EllipsizeMode.MIDDLE, - color = Drawing.Color.TOOLTIP_TEXT_COLOR + color = Drawing.Color.TOOLTIP_TEXT_COLOR, + use_shadow = true, + shadow_color = { 0, 0, 0, 153 } }; bind_property ("monitor-scale", text_actor, "margin-left", SYNC_CREATE, transform_monitor_scale_to_margin); bind_property ("monitor-scale", text_actor, "margin-top", SYNC_CREATE, transform_monitor_scale_to_margin); From a824a4fa4daa93579084a011076909141f047518 Mon Sep 17 00:00:00 2001 From: lenemter Date: Sun, 5 Apr 2026 18:42:31 +0200 Subject: [PATCH 2/5] Introduce Gala.BoxBlurEffect --- data/gala.gresource.xml | 1 + data/shaders/box-blur.frag | 23 ++++++++++++ lib/Effects/BoxBlurEffect.vala | 68 ++++++++++++++++++++++++++++++++++ lib/meson.build | 1 + 4 files changed, 93 insertions(+) create mode 100644 data/shaders/box-blur.frag create mode 100644 lib/Effects/BoxBlurEffect.vala diff --git a/data/gala.gresource.xml b/data/gala.gresource.xml index 7713468a1..424b4f10c 100644 --- a/data/gala.gresource.xml +++ b/data/gala.gresource.xml @@ -21,6 +21,7 @@ resize.svg + shaders/box-blur.frag shaders/colorblindness-correction.frag shaders/monochrome.frag shaders/rounded-corners.frag diff --git a/data/shaders/box-blur.frag b/data/shaders/box-blur.frag new file mode 100644 index 000000000..ac3d86433 --- /dev/null +++ b/data/shaders/box-blur.frag @@ -0,0 +1,23 @@ +/* + * Copyright 2026 elementary, Inc. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +uniform sampler2D tex; +uniform int RADIUS; +uniform vec2 PIXEL_STEP; +uniform vec2 DIRECTION; + +void main() { + vec4 sum = vec4(0, 0, 0, 0); + int count = 0; + + for (int i = -RADIUS; i <= RADIUS; i++) { + vec2 offset = DIRECTION * PIXEL_STEP * i; + + sum += texture2D(tex, cogl_tex_coord0_in.xy + offset); + count += 1; + } + + cogl_color_out = sum / count; +} diff --git a/lib/Effects/BoxBlurEffect.vala b/lib/Effects/BoxBlurEffect.vala new file mode 100644 index 000000000..46dba211e --- /dev/null +++ b/lib/Effects/BoxBlurEffect.vala @@ -0,0 +1,68 @@ +/* + * Copyright 2026 elementary, Inc. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +public class Gala.BoxBlurEffect : Clutter.ShaderEffect { + private enum PassDirection { + HORIZONTAL = 1, + VERTICAL = 2; + } + + private const float[] HORIZONTAL_PASS_DATA = { 1.0f, 0.0f }; + private const float[] VERTICAL_PASS_DATA = { 0.0f, 1.0f }; + + public int radius { set { set_uniform_value ("RADIUS", value); } } + + private BoxBlurEffect (int radius, PassDirection direction) { + Object ( +#if HAS_MUTTER48 + shader_type: Cogl.ShaderType.FRAGMENT +#else + shader_type: Clutter.ShaderType.FRAGMENT_SHADER +#endif + ); + + try { + var bytes = GLib.resources_lookup_data ("/io/elementary/desktop/gala/shaders/box-blur.frag", NONE); + set_shader_source ((string) bytes.get_data ()); + } catch (Error e) { + critical ("Unable to load box-blur.frag: %s", e.message); + } + + this.radius = radius; + + var direction_value = GLib.Value (typeof (Clutter.ShaderFloat)); + var direction_data = direction == HORIZONTAL ? HORIZONTAL_PASS_DATA : VERTICAL_PASS_DATA; + Clutter.Value.set_shader_float (direction_value, direction_data); + + set_uniform_value ("DIRECTION", direction_value); + } + + public static void apply_to_actor (Clutter.Actor actor, int radius) { + actor.add_effect (new BoxBlurEffect (radius, HORIZONTAL)); + actor.add_effect (new BoxBlurEffect (radius, VERTICAL)); + } + + public override void set_actor (Clutter.Actor? new_actor) { + if (actor != null) { + actor.notify["width"].disconnect (update_pixel_step); + actor.notify["height"].disconnect (update_pixel_step); + } + + base.set_actor (new_actor); + + if (actor != null) { + actor.notify["width"].connect (update_pixel_step); + actor.notify["height"].connect (update_pixel_step); + update_pixel_step (); + } + } + + private void update_pixel_step () { + var pixel_step_value = GLib.Value (typeof (Clutter.ShaderFloat)); + Clutter.Value.set_shader_float (pixel_step_value, { 1 / actor.width, 1 / actor.height }); + + set_uniform_value ("PIXEL_STEP", pixel_step_value); + } +} diff --git a/lib/meson.build b/lib/meson.build index dfa1ff668..df1ac6e85 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -19,6 +19,7 @@ gala_lib_sources = files( 'Drawing/StyleManager.vala', 'Drawing/Utilities.vala', 'Effects/BackgroundBlurEffect.vala', + 'Effects/BoxBlurEffect.vala', 'Effects/RoundedCornersEffect.vala', 'Effects/ShadowEffect.vala', 'Gestures/Backends/GestureBackend.vala', From 3b82bd51fb218fc552c19901c60c558636091462 Mon Sep 17 00:00:00 2001 From: lenemter Date: Sun, 5 Apr 2026 23:37:16 +0300 Subject: [PATCH 3/5] Improve everything --- data/shaders/box-blur.frag | 5 ++ lib/Drawing/Color.vala | 32 +++++---- lib/Effects/BoxBlurEffect.vala | 68 ------------------ lib/Effects/BoxBlurManager.vala | 88 +++++++++++++++++++++++ lib/Widgets/Text.vala | 21 +++--- lib/meson.build | 2 +- src/Widgets/MultitaskingView/Tooltip.vala | 6 +- 7 files changed, 126 insertions(+), 96 deletions(-) delete mode 100644 lib/Effects/BoxBlurEffect.vala create mode 100644 lib/Effects/BoxBlurManager.vala diff --git a/data/shaders/box-blur.frag b/data/shaders/box-blur.frag index ac3d86433..474759d13 100644 --- a/data/shaders/box-blur.frag +++ b/data/shaders/box-blur.frag @@ -9,6 +9,11 @@ uniform vec2 PIXEL_STEP; uniform vec2 DIRECTION; void main() { + if (RADIUS == 0) { + cogl_color_out = texture2D(tex, cogl_tex_coord0_in.xy); + return; + } + vec4 sum = vec4(0, 0, 0, 0); int count = 0; diff --git a/lib/Drawing/Color.vala b/lib/Drawing/Color.vala index 3203127a6..5deb9adac 100644 --- a/lib/Drawing/Color.vala +++ b/lib/Drawing/Color.vala @@ -10,23 +10,25 @@ namespace Gala.Drawing { */ public class Color : GLib.Object { #if !HAS_MUTTER47 - public const Clutter.Color LIGHT_BACKGROUND = { 250, 250, 250, 255}; - public const Clutter.Color DARK_BACKGROUND = { 51, 51, 51, 255}; - public const Clutter.Color LIGHT_BORDER = { 0, 0, 0, 51}; - public const Clutter.Color DARK_BORDER = { 0, 0, 0, 191}; - public const Clutter.Color LIGHT_HIGHLIGHT = { 255, 255, 255, 255}; - public const Clutter.Color DARK_HIGHLIGHT = { 255, 255, 255, 13}; - public const Clutter.Color TOOLTIP_BACKGROUND = { 26, 26, 26, 230}; - public const Clutter.Color TOOLTIP_TEXT_COLOR = { 255, 255, 255, 255}; + public const Clutter.Color LIGHT_BACKGROUND = { 250, 250, 250, 255 }; + public const Clutter.Color DARK_BACKGROUND = { 51, 51, 51, 255 }; + public const Clutter.Color LIGHT_BORDER = { 0, 0, 0, 51 }; + public const Clutter.Color DARK_BORDER = { 0, 0, 0, 191 }; + public const Clutter.Color LIGHT_HIGHLIGHT = { 255, 255, 255, 255 }; + public const Clutter.Color DARK_HIGHLIGHT = { 255, 255, 255, 13 }; + public const Clutter.Color TOOLTIP_BACKGROUND = { 26, 26, 26, 230 }; + public const Clutter.Color TOOLTIP_TEXT_COLOR = { 255, 255, 255, 255 }; + public const Clutter.Color TOOLTIP_TEXT_SHADOW_COLOR = { 0, 0, 0, 153 }; #else - public const Cogl.Color LIGHT_BACKGROUND = { 250, 250, 250, 255}; - public const Cogl.Color DARK_BACKGROUND = { 51, 51, 51, 255}; - public const Cogl.Color LIGHT_BORDER = { 0, 0, 0, 51}; - public const Cogl.Color DARK_BORDER = { 0, 0, 0, 191}; - public const Cogl.Color LIGHT_HIGHLIGHT = { 255, 255, 255, 255}; - public const Cogl.Color DARK_HIGHLIGHT = { 255, 255, 255, 13}; + public const Cogl.Color LIGHT_BACKGROUND = { 250, 250, 250, 255 }; + public const Cogl.Color DARK_BACKGROUND = { 51, 51, 51, 255 }; + public const Cogl.Color LIGHT_BORDER = { 0, 0, 0, 51 }; + public const Cogl.Color DARK_BORDER = { 0, 0, 0, 191 }; + public const Cogl.Color LIGHT_HIGHLIGHT = { 255, 255, 255, 255 }; + public const Cogl.Color DARK_HIGHLIGHT = { 255, 255, 255, 13 }; public const Cogl.Color TOOLTIP_BACKGROUND = { 26, 26, 26, 230 }; - public const Cogl.Color TOOLTIP_TEXT_COLOR = { 255, 255, 255, 255}; + public const Cogl.Color TOOLTIP_TEXT_COLOR = { 255, 255, 255, 255 }; + public const Cogl.Color TOOLTIP_TEXT_SHADOW_COLOR = { 0, 0, 0, 153 }; #endif /** diff --git a/lib/Effects/BoxBlurEffect.vala b/lib/Effects/BoxBlurEffect.vala deleted file mode 100644 index 46dba211e..000000000 --- a/lib/Effects/BoxBlurEffect.vala +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2026 elementary, Inc. - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -public class Gala.BoxBlurEffect : Clutter.ShaderEffect { - private enum PassDirection { - HORIZONTAL = 1, - VERTICAL = 2; - } - - private const float[] HORIZONTAL_PASS_DATA = { 1.0f, 0.0f }; - private const float[] VERTICAL_PASS_DATA = { 0.0f, 1.0f }; - - public int radius { set { set_uniform_value ("RADIUS", value); } } - - private BoxBlurEffect (int radius, PassDirection direction) { - Object ( -#if HAS_MUTTER48 - shader_type: Cogl.ShaderType.FRAGMENT -#else - shader_type: Clutter.ShaderType.FRAGMENT_SHADER -#endif - ); - - try { - var bytes = GLib.resources_lookup_data ("/io/elementary/desktop/gala/shaders/box-blur.frag", NONE); - set_shader_source ((string) bytes.get_data ()); - } catch (Error e) { - critical ("Unable to load box-blur.frag: %s", e.message); - } - - this.radius = radius; - - var direction_value = GLib.Value (typeof (Clutter.ShaderFloat)); - var direction_data = direction == HORIZONTAL ? HORIZONTAL_PASS_DATA : VERTICAL_PASS_DATA; - Clutter.Value.set_shader_float (direction_value, direction_data); - - set_uniform_value ("DIRECTION", direction_value); - } - - public static void apply_to_actor (Clutter.Actor actor, int radius) { - actor.add_effect (new BoxBlurEffect (radius, HORIZONTAL)); - actor.add_effect (new BoxBlurEffect (radius, VERTICAL)); - } - - public override void set_actor (Clutter.Actor? new_actor) { - if (actor != null) { - actor.notify["width"].disconnect (update_pixel_step); - actor.notify["height"].disconnect (update_pixel_step); - } - - base.set_actor (new_actor); - - if (actor != null) { - actor.notify["width"].connect (update_pixel_step); - actor.notify["height"].connect (update_pixel_step); - update_pixel_step (); - } - } - - private void update_pixel_step () { - var pixel_step_value = GLib.Value (typeof (Clutter.ShaderFloat)); - Clutter.Value.set_shader_float (pixel_step_value, { 1 / actor.width, 1 / actor.height }); - - set_uniform_value ("PIXEL_STEP", pixel_step_value); - } -} diff --git a/lib/Effects/BoxBlurManager.vala b/lib/Effects/BoxBlurManager.vala new file mode 100644 index 000000000..a8e1e65ec --- /dev/null +++ b/lib/Effects/BoxBlurManager.vala @@ -0,0 +1,88 @@ +/* + * Copyright 2026 elementary, Inc. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +public class Gala.BoxBlurManager : Object { + private int _radius = 0; + public int radius { + get { + return _radius; + } + set { + _radius = value; + horizontal_effect.radius = value; + vertical_effect.radius = value; + } + } + + private BoxBlurEffect horizontal_effect; + private BoxBlurEffect vertical_effect; + + public BoxBlurManager (Clutter.Actor actor) { + horizontal_effect = new BoxBlurEffect (HORIZONTAL); + vertical_effect = new BoxBlurEffect (VERTICAL); + + actor.add_effect (horizontal_effect); + actor.add_effect (vertical_effect); + } + + private class BoxBlurEffect : Clutter.ShaderEffect { + public enum PassDirection { + HORIZONTAL, + VERTICAL; + } + + private const float[] HORIZONTAL_PASS_DATA = { 1.0f, 0.0f }; + private const float[] VERTICAL_PASS_DATA = { 0.0f, 1.0f }; + + public int radius { set { set_uniform_value ("RADIUS", value); } } + + public BoxBlurEffect (PassDirection direction) { + Object ( + #if HAS_MUTTER48 + shader_type: Cogl.ShaderType.FRAGMENT + #else + shader_type: Clutter.ShaderType.FRAGMENT_SHADER + #endif + ); + + try { + var bytes = GLib.resources_lookup_data ("/io/elementary/desktop/gala/shaders/box-blur.frag", NONE); + set_shader_source ((string) bytes.get_data ()); + } catch (Error e) { + critical ("Unable to load box-blur.frag: %s", e.message); + } + + radius = 0; + + var direction_value = GLib.Value (typeof (Clutter.ShaderFloat)); + var direction_data = direction == HORIZONTAL ? HORIZONTAL_PASS_DATA : VERTICAL_PASS_DATA; + Clutter.Value.set_shader_float (direction_value, direction_data); + + set_uniform_value ("DIRECTION", direction_value); + } + + public override void set_actor (Clutter.Actor? new_actor) { + if (actor != null) { + actor.notify["width"].disconnect (update_pixel_step); + actor.notify["height"].disconnect (update_pixel_step); + } + + base.set_actor (new_actor); + + if (actor != null) { + actor.notify["width"].connect (update_pixel_step); + actor.notify["height"].connect (update_pixel_step); + update_pixel_step (); + } + } + + private void update_pixel_step () { + var pixel_step_value = GLib.Value (typeof (Clutter.ShaderFloat)); + Clutter.Value.set_shader_float (pixel_step_value, { 1 / actor.width, 1 / actor.height }); + + set_uniform_value ("PIXEL_STEP", pixel_step_value); + } + } +} diff --git a/lib/Widgets/Text.vala b/lib/Widgets/Text.vala index 0e74bd73e..668d97406 100644 --- a/lib/Widgets/Text.vala +++ b/lib/Widgets/Text.vala @@ -4,7 +4,7 @@ */ /* - * Clutter.Text that automatically changes font-name to the system one + * Clutter.Text that automatically changes font-name to the system one and supports text shadow */ public class Gala.Text : Clutter.Actor { private static GLib.Settings gnome_interface_settings = new GLib.Settings ("org.gnome.desktop.interface"); @@ -35,11 +35,13 @@ public class Gala.Text : Clutter.Actor { #else public Clutter.Color shadow_color { get { return shadow_actor.color; } set { shadow_actor.color = value; } } #endif - // public float shadow_offset_x { get { return shadow_actor.margin_left; } set { shadow_actor.margin_left = value; }} - // public float shadow_offset_y { get { return shadow_actor.margin_top; } set { shadow_actor.margin_top = value; }} + public float shadow_offset_x { get { return shadow_actor.translation_x; } set { shadow_actor.translation_x = value; } } + public float shadow_offset_y { get { return shadow_actor.translation_y; } set { shadow_actor.translation_y = value; } } + public int shadow_blur_radius { get { return box_blur_manager.radius; } set { box_blur_manager.radius = value; } } private Clutter.Text text_actor; private Clutter.Text shadow_actor; + private BoxBlurManager box_blur_manager; class construct { set_layout_manager_type (typeof (Clutter.BinLayout)); @@ -50,10 +52,7 @@ public class Gala.Text : Clutter.Actor { add_child (text_actor); shadow_actor = new Clutter.Text (); - // We add 2 blur effects because the shadow size needs to be 2px, and Clutter.BlurEffect is quite cheap. - // TODO: replace with a Gala.BoxBlurEffect in the future - shadow_actor.add_effect (new Clutter.BlurEffect ()); - shadow_actor.add_effect (new Clutter.BlurEffect ()); + box_blur_manager = new BoxBlurManager (shadow_actor); text_actor.bind_property ("ellipsize", shadow_actor, "ellipsize"); text_actor.bind_property ("line-alignment", shadow_actor, "line-alignment"); @@ -78,10 +77,10 @@ public class Gala.Text : Clutter.Actor { } public override void get_preferred_height (float for_width, out float min_height_p, out float natural_height_p) { - /* - *shadow_actor.margin_top increases total height by 2px, when it shouldn't affect height at all. - * To workaround this we override the height calculation. - */ min_height_p = natural_height_p = text_actor.height; } + + public override void get_preferred_width (float for_height, out float min_width_p, out float natural_width_p) { + min_width_p = natural_width_p = text_actor.width; + } } diff --git a/lib/meson.build b/lib/meson.build index df1ac6e85..b15220b5a 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -19,7 +19,7 @@ gala_lib_sources = files( 'Drawing/StyleManager.vala', 'Drawing/Utilities.vala', 'Effects/BackgroundBlurEffect.vala', - 'Effects/BoxBlurEffect.vala', + 'Effects/BoxBlurManager.vala', 'Effects/RoundedCornersEffect.vala', 'Effects/ShadowEffect.vala', 'Gestures/Backends/GestureBackend.vala', diff --git a/src/Widgets/MultitaskingView/Tooltip.vala b/src/Widgets/MultitaskingView/Tooltip.vala index acaa0c7dc..fffc7613a 100644 --- a/src/Widgets/MultitaskingView/Tooltip.vala +++ b/src/Widgets/MultitaskingView/Tooltip.vala @@ -10,6 +10,8 @@ public class Gala.Tooltip : Clutter.Actor { private const int TEXT_MARGIN = 6; private const int CORNER_RADIUS = 3; + private const int TEXT_SHADOW_Y_OFFSET = 1; + private const int TEXT_SHADOW_BLUR_RADIUS = 2; public float monitor_scale { get; construct set; } @@ -24,7 +26,9 @@ public class Gala.Tooltip : Clutter.Actor { ellipsize = Pango.EllipsizeMode.MIDDLE, color = Drawing.Color.TOOLTIP_TEXT_COLOR, use_shadow = true, - shadow_color = { 0, 0, 0, 153 } + shadow_color = Drawing.Color.TOOLTIP_TEXT_SHADOW_COLOR, + shadow_offset_y = TEXT_SHADOW_Y_OFFSET, + shadow_blur_radius = TEXT_SHADOW_BLUR_RADIUS }; bind_property ("monitor-scale", text_actor, "margin-left", SYNC_CREATE, transform_monitor_scale_to_margin); bind_property ("monitor-scale", text_actor, "margin-top", SYNC_CREATE, transform_monitor_scale_to_margin); From decdbf2841dc30b1297a7fff18e070494d8489d5 Mon Sep 17 00:00:00 2001 From: lenemter Date: Sun, 5 Apr 2026 23:50:05 +0300 Subject: [PATCH 4/5] Improve API --- lib/Drawing/Color.vala | 36 +++++++++++------------ lib/Widgets/Text.vala | 30 +++++++------------ src/Widgets/MultitaskingView/Tooltip.vala | 1 - 3 files changed, 29 insertions(+), 38 deletions(-) diff --git a/lib/Drawing/Color.vala b/lib/Drawing/Color.vala index 5deb9adac..a38f80548 100644 --- a/lib/Drawing/Color.vala +++ b/lib/Drawing/Color.vala @@ -10,25 +10,25 @@ namespace Gala.Drawing { */ public class Color : GLib.Object { #if !HAS_MUTTER47 - public const Clutter.Color LIGHT_BACKGROUND = { 250, 250, 250, 255 }; - public const Clutter.Color DARK_BACKGROUND = { 51, 51, 51, 255 }; - public const Clutter.Color LIGHT_BORDER = { 0, 0, 0, 51 }; - public const Clutter.Color DARK_BORDER = { 0, 0, 0, 191 }; - public const Clutter.Color LIGHT_HIGHLIGHT = { 255, 255, 255, 255 }; - public const Clutter.Color DARK_HIGHLIGHT = { 255, 255, 255, 13 }; - public const Clutter.Color TOOLTIP_BACKGROUND = { 26, 26, 26, 230 }; - public const Clutter.Color TOOLTIP_TEXT_COLOR = { 255, 255, 255, 255 }; - public const Clutter.Color TOOLTIP_TEXT_SHADOW_COLOR = { 0, 0, 0, 153 }; + public const Clutter.Color LIGHT_BACKGROUND = { 250, 250, 250, 255}; + public const Clutter.Color DARK_BACKGROUND = { 51, 51, 51, 255}; + public const Clutter.Color LIGHT_BORDER = { 0, 0, 0, 51}; + public const Clutter.Color DARK_BORDER = { 0, 0, 0, 191}; + public const Clutter.Color LIGHT_HIGHLIGHT = { 255, 255, 255, 255}; + public const Clutter.Color DARK_HIGHLIGHT = { 255, 255, 255, 13}; + public const Clutter.Color TOOLTIP_BACKGROUND = { 26, 26, 26, 230}; + public const Clutter.Color TOOLTIP_TEXT_COLOR = { 255, 255, 255, 255}; + public const Clutter.Color TOOLTIP_TEXT_SHADOW_COLOR = { 255, 0, 0, 153}; #else - public const Cogl.Color LIGHT_BACKGROUND = { 250, 250, 250, 255 }; - public const Cogl.Color DARK_BACKGROUND = { 51, 51, 51, 255 }; - public const Cogl.Color LIGHT_BORDER = { 0, 0, 0, 51 }; - public const Cogl.Color DARK_BORDER = { 0, 0, 0, 191 }; - public const Cogl.Color LIGHT_HIGHLIGHT = { 255, 255, 255, 255 }; - public const Cogl.Color DARK_HIGHLIGHT = { 255, 255, 255, 13 }; - public const Cogl.Color TOOLTIP_BACKGROUND = { 26, 26, 26, 230 }; - public const Cogl.Color TOOLTIP_TEXT_COLOR = { 255, 255, 255, 255 }; - public const Cogl.Color TOOLTIP_TEXT_SHADOW_COLOR = { 0, 0, 0, 153 }; + public const Cogl.Color LIGHT_BACKGROUND = { 250, 250, 250, 255}; + public const Cogl.Color DARK_BACKGROUND = { 51, 51, 51, 255}; + public const Cogl.Color LIGHT_BORDER = { 0, 0, 0, 51}; + public const Cogl.Color DARK_BORDER = { 0, 0, 0, 191}; + public const Cogl.Color LIGHT_HIGHLIGHT = { 255, 255, 255, 255}; + public const Cogl.Color DARK_HIGHLIGHT = { 255, 255, 255, 13}; + public const Cogl.Color TOOLTIP_BACKGROUND = { 26, 26, 26, 230}; + public const Cogl.Color TOOLTIP_TEXT_COLOR = { 255, 255, 255, 255}; + public const Cogl.Color TOOLTIP_TEXT_SHADOW_COLOR = { 0, 0, 0, 153}; #endif /** diff --git a/lib/Widgets/Text.vala b/lib/Widgets/Text.vala index 668d97406..492fdc19e 100644 --- a/lib/Widgets/Text.vala +++ b/lib/Widgets/Text.vala @@ -18,23 +18,23 @@ public class Gala.Text : Clutter.Actor { public Pango.Alignment line_alignment { get { return text_actor.line_alignment; } set { text_actor.line_alignment = value; }} public string text { get { return text_actor.text; } set { text_actor.text = value; } } - public bool use_shadow { - get { - return shadow_actor.get_parent () != null; - } +#if HAS_MUTTER47 + public Cogl.Color shadow_color { +#else + public Clutter.Color shadow_color { +#endif + get { return shadow_actor.color; } set { - if (value) { + shadow_actor.color = value; + + if (shadow_actor.color.alpha != 0 && shadow_actor.get_parent () == null) { insert_child_below (shadow_actor, null); - } else { + } else if (shadow_actor.color.alpha == 0 && shadow_actor.get_parent () == this) { remove_child (shadow_actor); } } } -#if HAS_MUTTER47 - public Cogl.Color shadow_color { get { return shadow_actor.color; } set { shadow_actor.color = value; } } -#else - public Clutter.Color shadow_color { get { return shadow_actor.color; } set { shadow_actor.color = value; } } -#endif + public float shadow_offset_x { get { return shadow_actor.translation_x; } set { shadow_actor.translation_x = value; } } public float shadow_offset_y { get { return shadow_actor.translation_y; } set { shadow_actor.translation_y = value; } } public int shadow_blur_radius { get { return box_blur_manager.radius; } set { box_blur_manager.radius = value; } } @@ -75,12 +75,4 @@ public class Gala.Text : Clutter.Actor { text_actor.font_name = string.joinv (" ", name); } - - public override void get_preferred_height (float for_width, out float min_height_p, out float natural_height_p) { - min_height_p = natural_height_p = text_actor.height; - } - - public override void get_preferred_width (float for_height, out float min_width_p, out float natural_width_p) { - min_width_p = natural_width_p = text_actor.width; - } } diff --git a/src/Widgets/MultitaskingView/Tooltip.vala b/src/Widgets/MultitaskingView/Tooltip.vala index fffc7613a..bd13fcd94 100644 --- a/src/Widgets/MultitaskingView/Tooltip.vala +++ b/src/Widgets/MultitaskingView/Tooltip.vala @@ -25,7 +25,6 @@ public class Gala.Tooltip : Clutter.Actor { text_actor = new Gala.Text () { ellipsize = Pango.EllipsizeMode.MIDDLE, color = Drawing.Color.TOOLTIP_TEXT_COLOR, - use_shadow = true, shadow_color = Drawing.Color.TOOLTIP_TEXT_SHADOW_COLOR, shadow_offset_y = TEXT_SHADOW_Y_OFFSET, shadow_blur_radius = TEXT_SHADOW_BLUR_RADIUS From 63043da19cb7c0517612a0ba11feafbaf0700ed7 Mon Sep 17 00:00:00 2001 From: lenemter Date: Sun, 5 Apr 2026 23:50:49 +0300 Subject: [PATCH 5/5] Fix oopsie --- lib/Drawing/Color.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Drawing/Color.vala b/lib/Drawing/Color.vala index a38f80548..ad8b2ba70 100644 --- a/lib/Drawing/Color.vala +++ b/lib/Drawing/Color.vala @@ -18,7 +18,7 @@ namespace Gala.Drawing { public const Clutter.Color DARK_HIGHLIGHT = { 255, 255, 255, 13}; public const Clutter.Color TOOLTIP_BACKGROUND = { 26, 26, 26, 230}; public const Clutter.Color TOOLTIP_TEXT_COLOR = { 255, 255, 255, 255}; - public const Clutter.Color TOOLTIP_TEXT_SHADOW_COLOR = { 255, 0, 0, 153}; + public const Clutter.Color TOOLTIP_TEXT_SHADOW_COLOR = { 0, 0, 0, 153}; #else public const Cogl.Color LIGHT_BACKGROUND = { 250, 250, 250, 255}; public const Cogl.Color DARK_BACKGROUND = { 51, 51, 51, 255};