Merge branch 'main' into leolost/shell-clients-force-hide

This commit is contained in:
Leonhard 2024-12-10 01:43:15 +01:00 committed by GitHub
commit a97122c830
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 87 additions and 128 deletions

View File

@ -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 <mail@kisaragi-hiu.com>\n"
"Language-Team: Chinese (Traditional) <https://l10n.elementary.io/projects/"
"desktop/gala/zh_Hant/>\n"
"Language-Team: Chinese (Traditional Han script) <https://l10n.elementary.io/"
"projects/desktop/gala/zh_Hant/>\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"

View File

@ -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;
}
}
}

View File

@ -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);

View File

@ -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) {