From f36b4bef232150cf189f2886f2dc68835de89973 Mon Sep 17 00:00:00 2001 From: Kisaragi Hiu Date: Mon, 9 Dec 2024 08:03:59 +0000 Subject: [PATCH 1/2] Translated using Weblate (Chinese (Traditional Han script)) Currently translated at 100.0% (57 of 57 strings) Translation: Desktop/Gala Translate-URL: https://l10n.elementary.io/projects/desktop/gala/zh_Hant/ --- po/zh_TW.po | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/po/zh_TW.po b/po/zh_TW.po index 3af05276..9477bb3f 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -8,16 +8,16 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://github.com/elementary/gala/issues\n" "POT-Creation-Date: 2024-11-23 16:06+0000\n" -"PO-Revision-Date: 2024-11-06 11:20+0000\n" +"PO-Revision-Date: 2024-12-09 11:10+0000\n" "Last-Translator: Kisaragi Hiu \n" -"Language-Team: Chinese (Traditional) \n" +"Language-Team: Chinese (Traditional Han script) \n" "Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.6.2\n" +"X-Generator: Weblate 5.8.4\n" "X-Launchpad-Export-Date: 2017-02-21 05:48+0000\n" #: daemon/DBus.vala:82 daemon-gtk3/BackgroundMenu.vala:11 @@ -34,7 +34,7 @@ msgstr "系統設定值…" #: daemon/DBus.vala:207 daemon-gtk3/BackgroundMenu.vala:47 msgid "Failed to open System Settings" -msgstr "開啟系統設定失敗了" +msgstr "無法開啟《系統設定值》" #: daemon/DBus.vala:208 daemon-gtk3/BackgroundMenu.vala:48 msgid "A handler for the “settings://” URI scheme must be installed." @@ -123,7 +123,7 @@ msgstr "更新翻譯" #: data/gala.metainfo.xml.in:35 msgid "Improved shadows performance" -msgstr "" +msgstr "改善陰影效能" #: data/gala.metainfo.xml.in:78 msgid "Fix a potential crash when moving windows between workspaces" From 903bc3fd776b4f20d9e6377db034356c54f1a9a6 Mon Sep 17 00:00:00 2001 From: Leonhard <106322251+leolost2605@users.noreply.github.com> Date: Tue, 10 Dec 2024 01:38:58 +0100 Subject: [PATCH 2/2] WindowClone: Layout in allocate virtual (#2082) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Leo Co-authored-by: Danielle Foré Co-authored-by: Stanisław <6031763+stsdc@users.noreply.github.com> --- src/InternalUtils.vala | 8 ++ src/Widgets/Tooltip.vala | 23 ----- src/Widgets/WindowClone.vala | 172 +++++++++++++++-------------------- 3 files changed, 81 insertions(+), 122 deletions(-) diff --git a/src/InternalUtils.vala b/src/InternalUtils.vala index 18d06a8e..cd5cc571 100644 --- a/src/InternalUtils.vala +++ b/src/InternalUtils.vala @@ -340,5 +340,13 @@ namespace Gala { return { 0, 0, (int) screen_width, (int) screen_height }; } } + + public static Clutter.ActorBox actor_box_from_rect (float x, float y, float width, float height) { + var actor_box = Clutter.ActorBox (); + actor_box.init_rect (x, y, width, height); + Clutter.ActorBox.clamp_to_pixel (ref actor_box); + + return actor_box; + } } } diff --git a/src/Widgets/Tooltip.vala b/src/Widgets/Tooltip.vala index 331949b9..6a552a84 100644 --- a/src/Widgets/Tooltip.vala +++ b/src/Widgets/Tooltip.vala @@ -13,15 +13,7 @@ public class Gala.Tooltip : CanvasActor { */ private Clutter.Text text_actor; - /** - * Maximum width of the Tooltip. - * @see set_max_width - */ - public float max_width; - construct { - max_width = 200; - #if HAS_MUTTER47 Cogl.Color text_color = { #else @@ -51,21 +43,6 @@ public class Gala.Tooltip : CanvasActor { text_actor.text = new_text; } - public void set_max_width (float new_max_width) { - max_width = new_max_width; - - queue_relayout (); - } - - protected override void allocate (Clutter.ActorBox box) { - if (box.get_width () > max_width) { - box.set_origin (box.get_x () + ((box.get_width () - max_width) / 2), box.get_y ()); - box.set_size (max_width, box.get_height ()); - } - - base.allocate (box); - } - protected override void draw (Cairo.Context ctx, int width, int height) { ctx.save (); ctx.set_operator (Cairo.Operator.CLEAR); diff --git a/src/Widgets/WindowClone.vala b/src/Widgets/WindowClone.vala index 4aa1c5cb..db747dc1 100644 --- a/src/Widgets/WindowClone.vala +++ b/src/Widgets/WindowClone.vala @@ -9,7 +9,6 @@ * a close button and a shadow. Used together with the WindowCloneContainer. */ public class Gala.WindowClone : Clutter.Actor { - private const int CLOSE_WINDOW_ICON_SIZE = 36; private const int WINDOW_ICON_SIZE = 64; private const int ACTIVE_SHAPE_SIZE = 12; private const int FADE_ANIMATION_DURATION = 200; @@ -144,6 +143,11 @@ public class Gala.WindowClone : Clutter.Actor { reallocate (); load_clone (); + + window.notify["title"].connect (() => window_title.set_text (window.get_title () ?? "")); + window_title.set_text (window.get_title () ?? ""); + + notify["has-pointer"].connect (() => update_hover_widgets ()); } ~WindowClone () { @@ -186,10 +190,10 @@ public class Gala.WindowClone : Clutter.Actor { private void load_clone (bool was_waiting = false) { var actor = (Meta.WindowActor) window.get_compositor_private (); if (actor == null) { - ulong shown_handler = 0; - shown_handler = window.shown.connect (() => { - load_clone (true); - window.disconnect (shown_handler); + Idle.add (() => { + if (window.get_compositor_private () != null) + load_clone (true); + return Source.REMOVE; }); return; @@ -200,6 +204,7 @@ public class Gala.WindowClone : Clutter.Actor { } clone = new Clutter.Clone (actor); + clone.set_content_scaling_filters (TRILINEAR, TRILINEAR); add_child (clone); set_child_below_sibling (active_shape, clone); @@ -283,8 +288,7 @@ public class Gala.WindowClone : Clutter.Actor { var target_y = outer_rect.y - offset_y; active = false; - in_slot_animation = true; - place_widgets (outer_rect.width, outer_rect.height, initial_scale); + update_hover_widgets (true); new GesturePropertyTransition (this, gesture_tracker, "x", null, (float) target_x).start (with_gesture); new GesturePropertyTransition (this, gesture_tracker, "y", null, (float) target_y).start (with_gesture); @@ -292,8 +296,7 @@ public class Gala.WindowClone : Clutter.Actor { new GesturePropertyTransition (this, gesture_tracker, "height", null, (float) outer_rect.height).start (with_gesture); new GesturePropertyTransition (this, gesture_tracker, "shadow-opacity", (uint8) 255, (uint8) 0).start (with_gesture); new GesturePropertyTransition (window_icon, gesture_tracker, "opacity", 255u, 0u).start (with_gesture, () => { - in_slot_animation = false; - place_widgets (outer_rect.width, outer_rect.height, target_scale); + update_hover_widgets (false); }); GestureTracker.OnUpdate on_animation_update = (percentage) => { @@ -302,7 +305,6 @@ public class Gala.WindowClone : Clutter.Actor { var scale = GestureTracker.animation_value (initial_scale, target_scale, percentage); set_window_icon_position (width, height, scale, false); - place_widgets ((int)width, (int)height, scale); }; GestureTracker.OnEnd on_animation_end = (percentage, cancel_action) => { @@ -335,8 +337,6 @@ public class Gala.WindowClone : Clutter.Actor { public void take_slot (Meta.Rectangle rect, bool from_window_position, bool with_gesture = false, bool is_cancel_animation = false) { #endif slot = rect; - in_slot_animation = true; - active = false; var outer_rect = window.get_frame_rect (); @@ -349,8 +349,8 @@ public class Gala.WindowClone : Clutter.Actor { float intial_y = from_window_position ? outer_rect.y - monitor_geom.y : y; var scale = display.get_monitor_scale (display.get_monitor_index_for_rect (rect)); - place_widgets (rect.width, rect.height, scale); + update_hover_widgets (true); set_window_icon_position (initial_width, initial_height, scale); new GesturePropertyTransition (this, gesture_tracker, "x", intial_x, (float) rect.x).start (with_gesture); @@ -359,8 +359,7 @@ public class Gala.WindowClone : Clutter.Actor { new GesturePropertyTransition (this, gesture_tracker, "height", (float) initial_height, (float) rect.height).start (with_gesture); new GesturePropertyTransition (this, gesture_tracker, "shadow-opacity", (uint8) 0, (uint8) 255).start (with_gesture); new GesturePropertyTransition (window_icon, gesture_tracker, "opacity", 0u, 255u).start (with_gesture, () => { - in_slot_animation = false; - place_widgets (rect.width, rect.height, scale); + update_hover_widgets (false); }); GestureTracker.OnUpdate on_animation_update = (percentage) => { @@ -393,33 +392,62 @@ public class Gala.WindowClone : Clutter.Actor { } } - /** - * Except for the texture clone and the highlight all children are placed - * according to their given allocations. The first two are placed in a way - * that compensates for invisible borders of the texture. - */ public override void allocate (Clutter.ActorBox box) { base.allocate (box); - var input_rect = window.get_buffer_rect (); - var outer_rect = window.get_frame_rect (); - var scale_factor = width / outer_rect.width; - - Clutter.ActorBox shape_alloc = { - -ACTIVE_SHAPE_SIZE, - -ACTIVE_SHAPE_SIZE, - outer_rect.width * scale_factor + ACTIVE_SHAPE_SIZE, - outer_rect.height * scale_factor + ACTIVE_SHAPE_SIZE - }; - active_shape.allocate (shape_alloc); - if (clone == null || (drag_action != null && drag_action.dragging)) { return; } - clone.set_scale (scale_factor, scale_factor); - clone.set_position ((input_rect.x - outer_rect.x) * scale_factor, - (input_rect.y - outer_rect.y) * scale_factor); + var input_rect = window.get_buffer_rect (); + var outer_rect = window.get_frame_rect (); + var clone_scale_factor = width / outer_rect.width; + + clone.set_scale (clone_scale_factor, clone_scale_factor); + + float clone_width, clone_height; + clone.get_preferred_size (null, null, out clone_width, out clone_height); + + // Compensate for invisible borders of the texture + float clone_x = (input_rect.x - outer_rect.x) * clone_scale_factor; + float clone_y = (input_rect.y - outer_rect.y) * clone_scale_factor; + + var clone_alloc = InternalUtils.actor_box_from_rect (clone_x, clone_y, clone_width, clone_height); + clone.allocate (clone_alloc); + + Clutter.ActorBox shape_alloc = { + -ACTIVE_SHAPE_SIZE, + -ACTIVE_SHAPE_SIZE, + box.get_width () + ACTIVE_SHAPE_SIZE, + box.get_height () + ACTIVE_SHAPE_SIZE + }; + Clutter.ActorBox.clamp_to_pixel (ref shape_alloc); + active_shape.allocate (shape_alloc); + + float close_button_width, close_button_height; + close_button.get_preferred_size (null, null, out close_button_width, out close_button_height); + + var close_button_x = is_close_button_on_left () ? + -close_button_width * 0.5f : box.get_width () - close_button_width * 0.5f; + + var close_button_alloc = InternalUtils.actor_box_from_rect (close_button_x, -close_button_height * 0.33f, close_button_width, close_button_height); + close_button.allocate (close_button_alloc); + + var rect = get_transformed_extents (); + var monitor_index = display.get_monitor_index_for_rect (Mtk.Rectangle.from_graphene_rect (rect, ROUND)); + var monitor_scale = display.get_monitor_scale (monitor_index); + + float window_title_max_width = box.get_width () - InternalUtils.scale_to_int (TITLE_MAX_WIDTH_MARGIN, monitor_scale); + float window_title_height, window_title_nat_width; + window_title.get_preferred_size (null, null, out window_title_nat_width, out window_title_height); + + var window_title_width = window_title_nat_width.clamp (0, window_title_max_width); + + float window_title_x = (box.get_width () - window_title_width) / 2; + float window_title_y = box.get_height () - InternalUtils.scale_to_int (WINDOW_ICON_SIZE, monitor_scale) * 0.75f - (window_title_height / 2) - InternalUtils.scale_to_int (18, monitor_scale); + + var window_title_alloc = InternalUtils.actor_box_from_rect (window_title_x, window_title_y, window_title_width, window_title_height); + window_title.allocate (window_title_alloc); } #if HAS_MUTTER45 @@ -430,74 +458,26 @@ public class Gala.WindowClone : Clutter.Actor { return Clutter.EVENT_STOP; } -#if HAS_MUTTER45 - public override bool enter_event (Clutter.Event event) { -#else - public override bool enter_event (Clutter.CrossingEvent event) { -#endif - if (drag_action != null && drag_action.dragging) { - return Clutter.EVENT_PROPAGATE; + private void update_hover_widgets (bool? animating = null) { + if (animating != null) { + in_slot_animation = animating; } var duration = AnimationsSettings.get_animation_duration (FADE_ANIMATION_DURATION); - close_button.save_easing_state (); - close_button.set_easing_mode (Clutter.AnimationMode.LINEAR); - close_button.set_easing_duration (duration); - close_button.opacity = in_slot_animation ? 0 : 255; - close_button.restore_easing_state (); - - window_title.save_easing_state (); - window_title.set_easing_mode (Clutter.AnimationMode.LINEAR); - window_title.set_easing_duration (duration); - window_title.opacity = in_slot_animation ? 0 : 255; - window_title.restore_easing_state (); - - return Clutter.EVENT_PROPAGATE; - } - -#if HAS_MUTTER45 - public override bool leave_event (Clutter.Event event) { -#else - public override bool leave_event (Clutter.CrossingEvent event) { -#endif - var duration = AnimationsSettings.get_animation_duration (FADE_ANIMATION_DURATION); + var show = has_pointer && !in_slot_animation; close_button.save_easing_state (); close_button.set_easing_mode (Clutter.AnimationMode.LINEAR); close_button.set_easing_duration (duration); - close_button.opacity = 0; - close_button.restore_easing_state (); - - window_title.save_easing_state (); - window_title.set_easing_mode (Clutter.AnimationMode.LINEAR); - window_title.set_easing_duration (duration); - window_title.opacity = 0; - window_title.restore_easing_state (); - - return Clutter.EVENT_PROPAGATE; - } - - /** - * Place the widgets, that is the close button and the WindowIcon of the window, - * at their positions inside the actor for a given width and height. - */ - public void place_widgets (int dest_width, int dest_height, float scale_factor) { - var close_button_size = InternalUtils.scale_to_int (CLOSE_WINDOW_ICON_SIZE, scale_factor); - close_button.set_size (close_button_size, close_button_size); - - close_button.y = -close_button.height * 0.33f; - close_button.x = is_close_button_on_left () ? - -close_button.width * 0.5f : - dest_width - close_button.width * 0.5f; - - bool show = has_pointer && !in_slot_animation; close_button.opacity = show ? 255 : 0; - window_title.opacity = close_button.opacity; + close_button.restore_easing_state (); - window_title.set_text (window.get_title () ?? ""); - window_title.set_max_width (dest_width - InternalUtils.scale_to_int (TITLE_MAX_WIDTH_MARGIN, scale_factor)); - set_window_title_position (dest_width, dest_height, scale_factor); + window_title.save_easing_state (); + window_title.set_easing_mode (Clutter.AnimationMode.LINEAR); + window_title.set_easing_duration (duration); + window_title.opacity = show ? 255 : 0; + window_title.restore_easing_state (); } private void toggle_shadow (bool show) { @@ -800,12 +780,6 @@ public class Gala.WindowClone : Clutter.Actor { window_icon.set_position (x, y); } - private void set_window_title_position (float window_width, float window_height, float scale_factor) { - var x = (int)Math.round ((window_width - window_title.width) / 2); - var y = (int)Math.round (window_height - InternalUtils.scale_to_int (WINDOW_ICON_SIZE, scale_factor) * 0.75f - (window_title.height / 2) - InternalUtils.scale_to_int (18, scale_factor)); - window_title.set_position (x, y); - } - private static bool is_close_button_on_left () { var layout = Meta.Prefs.get_button_layout (); foreach (var button_function in layout.left_buttons) {