diff --git a/src/Background/BackgroundContainer.vala b/src/Background/BackgroundContainer.vala index 2f824b33f..9d2425db9 100644 --- a/src/Background/BackgroundContainer.vala +++ b/src/Background/BackgroundContainer.vala @@ -28,7 +28,12 @@ public class Gala.BackgroundContainer : Meta.BackgroundGroup { } }); - set_black_background (true); +#if HAS_MUTTER47 + background_color = Cogl.Color.from_string ("Black"); +#else + background_color = Clutter.Color.from_string ("Black"); +#endif + update (); } @@ -37,14 +42,6 @@ public class Gala.BackgroundContainer : Meta.BackgroundGroup { monitor_manager.monitors_changed.disconnect (update); } - public void set_black_background (bool black) { -#if HAS_MUTTER47 - set_background_color (black ? Cogl.Color.from_string ("Black") : null); -#else - set_background_color (black ? Clutter.Color.from_string ("Black") : null); -#endif - } - private void update () { var reference_child = (get_child_at_index (0) as BackgroundManager); if (reference_child != null) diff --git a/src/Gestures/ActorTarget.vala b/src/Gestures/ActorTarget.vala index f3a968d47..284b69aba 100644 --- a/src/Gestures/ActorTarget.vala +++ b/src/Gestures/ActorTarget.vala @@ -17,11 +17,17 @@ public class Gala.ActorTarget : Clutter.Actor, GestureTarget { } } + public bool animating { get { return ongoing_animations > 0; } } + private double[] current_progress; + private double[] current_commit; private Gee.List targets; + private int ongoing_animations = 0; + construct { current_progress = new double[GestureAction.N_ACTIONS]; + current_commit = new double[GestureAction.N_ACTIONS]; targets = new Gee.ArrayList (); child_added.connect (on_child_added); @@ -29,7 +35,7 @@ public class Gala.ActorTarget : Clutter.Actor, GestureTarget { private void sync_target (GestureTarget target) { for (int action = 0; action < current_progress.length; action++) { - target.propagate (COMMIT, action, current_progress[action]); + target.propagate (COMMIT, action, current_commit[action]); target.propagate (UPDATE, action, current_progress[action]); } } @@ -51,16 +57,35 @@ public class Gala.ActorTarget : Clutter.Actor, GestureTarget { return current_progress[action]; } + public double get_current_commit (GestureAction action) { + return current_commit[action]; + } + public virtual void start_progress (GestureAction action) {} public virtual void update_progress (GestureAction action, double progress) {} public virtual void commit_progress (GestureAction action, double to) {} public virtual void end_progress (GestureAction action) {} public override void propagate (UpdateType update_type, GestureAction action, double progress) { - current_progress[action] = progress; + if (update_type == COMMIT) { + current_commit[action] = progress; + } else { + current_progress[action] = progress; + } + + foreach (var target in targets) { + target.propagate (update_type, action, progress); + } + + for (var child = get_first_child (); child != null; child = child.get_next_sibling ()) { + if (child is ActorTarget) { + child.propagate (update_type, action, progress); + } + } switch (update_type) { case START: + ongoing_animations++; start_progress (action); break; case UPDATE: @@ -70,19 +95,10 @@ public class Gala.ActorTarget : Clutter.Actor, GestureTarget { commit_progress (action, progress); break; case END: + ongoing_animations--; end_progress (action); break; } - - foreach (var target in targets) { - target.propagate (update_type, action, progress); - } - - for (var child = get_first_child (); child != null; child = child.get_next_sibling ()) { - if (child is ActorTarget) { - child.propagate (update_type, action, progress); - } - } } private void on_child_added (Clutter.Actor child) { diff --git a/src/Gestures/Gesture.vala b/src/Gestures/Gesture.vala index 5eb38cf36..d0d8d7807 100644 --- a/src/Gestures/Gesture.vala +++ b/src/Gestures/Gesture.vala @@ -37,7 +37,6 @@ namespace Gala { public enum GestureAction { NONE, SWITCH_WORKSPACE, - MOVE_TO_WORKSPACE, SWITCH_WINDOWS, MULTITASKING_VIEW, DOCK, diff --git a/src/Gestures/GestureController.vala b/src/Gestures/GestureController.vala index 183aa9618..a3df15841 100644 --- a/src/Gestures/GestureController.vala +++ b/src/Gestures/GestureController.vala @@ -39,10 +39,13 @@ public class Gala.GestureController : Object { get { return _target; } set { _target = value; - target.propagate (UPDATE, action, calculate_bounded_progress ()); + target.propagate (UPDATE, action, progress); } } + private Variant? _action_info; + public Variant? action_info { get { return _action_info; } } + public double distance { get; construct set; } public double overshoot_lower_clamp { get; construct set; default = 0d; } public double overshoot_upper_clamp { get; construct set; default = 1d; } @@ -58,7 +61,7 @@ public class Gala.GestureController : Object { get { return _progress; } set { _progress = value; - target.propagate (UPDATE, action, calculate_bounded_progress ()); + target.propagate (UPDATE, action, value); } } @@ -77,34 +80,19 @@ public class Gala.GestureController : Object { private ScrollBackend? scroll_backend; private GestureBackend? recognizing_backend; + private double gesture_progress; private double previous_percentage; private uint64 previous_time; private double previous_delta; private double velocity; private int direction_multiplier; - private Clutter.Timeline? timeline; + private SpringTimeline? timeline; public GestureController (GestureAction action, GestureTarget target) { Object (action: action, target: target); } - private double calculate_bounded_progress () { - var lower_clamp_int = (int) overshoot_lower_clamp; - var upper_clamp_int = (int) overshoot_upper_clamp; - - double stretched_percentage = 0; - if (_progress < lower_clamp_int) { - stretched_percentage = (_progress - lower_clamp_int) * - (overshoot_lower_clamp - lower_clamp_int); - } else if (_progress > upper_clamp_int) { - stretched_percentage = (_progress - upper_clamp_int) * (overshoot_upper_clamp - upper_clamp_int); - } - - var clamped = _progress.clamp (lower_clamp_int, upper_clamp_int); - - return clamped + stretched_percentage; - } - public void enable_touchpad () { touchpad_backend = ToucheggBackend.get_default (); touchpad_backend.on_gesture_detected.connect (gesture_detected); @@ -127,11 +115,11 @@ public class Gala.GestureController : Object { timeline = null; } - target.propagate (START, action, calculate_bounded_progress ()); + target.propagate (START, action, progress); } private bool gesture_detected (GestureBackend backend, Gesture gesture, uint32 timestamp) { - recognizing = enabled && (GestureSettings.get_action (gesture) == action + recognizing = enabled && (GestureSettings.get_action (gesture, out _action_info) == action || backend == scroll_backend && GestureSettings.get_action (gesture) == NONE); if (recognizing) { @@ -142,9 +130,9 @@ public class Gala.GestureController : Object { } if (snap && !Meta.Prefs.get_gnome_animations ()) { + recognizing = false; prepare (); finish (0, progress + direction_multiplier); - recognizing = false; } recognizing_backend = backend; @@ -160,6 +148,7 @@ public class Gala.GestureController : Object { prepare (); + gesture_progress = progress; previous_percentage = percentage; previous_time = elapsed_time; } @@ -182,7 +171,7 @@ public class Gala.GestureController : Object { } } - progress += calculate_applied_delta (percentage, updated_delta); + update_gesture_progress (percentage, updated_delta); previous_percentage = percentage; previous_time = elapsed_time; @@ -196,7 +185,7 @@ public class Gala.GestureController : Object { recognizing = false; - progress += calculate_applied_delta (percentage, previous_delta); + update_gesture_progress (percentage, previous_delta); var to = progress; @@ -208,8 +197,9 @@ public class Gala.GestureController : Object { to = Math.round (to); } - finish (velocity, to); + finish (velocity * direction_multiplier, to); + gesture_progress = 0; previous_percentage = 0; previous_time = 0; previous_delta = 0; @@ -217,8 +207,22 @@ public class Gala.GestureController : Object { direction_multiplier = 0; } - private inline double calculate_applied_delta (double percentage, double percentage_delta) { - return ((percentage - percentage_delta) - (previous_percentage - previous_delta)) * direction_multiplier; + private void update_gesture_progress (double percentage, double percentage_delta) { + gesture_progress += ((percentage - percentage_delta) - (previous_percentage - previous_delta)) * direction_multiplier; + + var lower_clamp_int = (int) overshoot_lower_clamp; + var upper_clamp_int = (int) overshoot_upper_clamp; + + double stretched_percentage = 0; + if (gesture_progress < lower_clamp_int) { + stretched_percentage = (gesture_progress - lower_clamp_int) * - (overshoot_lower_clamp - lower_clamp_int); + } else if (gesture_progress > upper_clamp_int) { + stretched_percentage = (gesture_progress - upper_clamp_int) * (overshoot_upper_clamp - upper_clamp_int); + } + + var clamped = gesture_progress.clamp (lower_clamp_int, upper_clamp_int); + + progress = clamped + stretched_percentage; } private void finish (double velocity, double to) { @@ -227,26 +231,32 @@ public class Gala.GestureController : Object { target.propagate (COMMIT, action, clamped_to); if (progress == to) { - target.propagate (END, action, calculate_bounded_progress ()); + finished (); return; } if (!Meta.Prefs.get_gnome_animations ()) { progress = clamped_to; - target.propagate (END, action, calculate_bounded_progress ()); + finished (); return; } - var spring = new SpringTimeline (target.actor, progress, clamped_to, velocity, 1, 1, 1000); + var spring = new SpringTimeline (target.actor, progress, clamped_to, velocity, 1, 1, 500); spring.progress.connect ((value) => progress = value); - spring.stopped.connect (() => { - target.propagate (END, action, calculate_bounded_progress ()); - timeline = null; - }); + spring.stopped.connect_after (finished); timeline = spring; } + private void finished (bool is_finished = true) { + target.propagate (END, action, progress); + timeline = null; + + if (is_finished) { + _action_info = null; + } + } + /** * Animates to the given progress value. * If the gesture is currently recognizing, it will do nothing. @@ -254,12 +264,15 @@ public class Gala.GestureController : Object { * If you don't want animation but an immediate jump, you should set {@link progress} directly. */ public void goto (double to) { - if (progress == to || recognizing) { + var clamped_to = to.clamp ((int) overshoot_lower_clamp, (int) overshoot_upper_clamp); + if (progress == to || recognizing || + timeline != null && clamped_to == timeline.value_to // Only allow overshoot if there's no ongoing overshoot animation to prevent stacking + ) { return; } prepare (); - finish (0.005, to); + finish ((to > progress ? 1 : -1) * 1, to); } public void cancel_gesture () { diff --git a/src/Gestures/GestureSettings.vala b/src/Gestures/GestureSettings.vala index 0ef5ff39e..a5e701a81 100644 --- a/src/Gestures/GestureSettings.vala +++ b/src/Gestures/GestureSettings.vala @@ -70,7 +70,8 @@ public class Gala.GestureSettings : Object { return gala_settings.get_string (setting_id); } - public static GestureAction get_action (Gesture gesture) { + public static GestureAction get_action (Gesture gesture, out Variant? action_info = null) { + action_info = null; var fingers = gesture.fingers; switch (gesture.type) { @@ -86,7 +87,8 @@ public class Gala.GestureSettings : Object { if (fingers == 3 && three_finger_swipe_horizontal == "move-to-workspace" || fingers == 4 && four_finger_swipe_horizontal == "move-to-workspace") { - return MOVE_TO_WORKSPACE; + action_info = true; + return SWITCH_WORKSPACE; } diff --git a/src/Widgets/IconGroup.vala b/src/Widgets/MultitaskingView/IconGroup.vala similarity index 100% rename from src/Widgets/IconGroup.vala rename to src/Widgets/MultitaskingView/IconGroup.vala diff --git a/src/Widgets/IconGroupContainer.vala b/src/Widgets/MultitaskingView/IconGroupContainer.vala similarity index 100% rename from src/Widgets/IconGroupContainer.vala rename to src/Widgets/MultitaskingView/IconGroupContainer.vala diff --git a/src/Widgets/MonitorClone.vala b/src/Widgets/MultitaskingView/MonitorClone.vala similarity index 100% rename from src/Widgets/MonitorClone.vala rename to src/Widgets/MultitaskingView/MonitorClone.vala diff --git a/src/Widgets/MultitaskingView.vala b/src/Widgets/MultitaskingView/MultitaskingView.vala similarity index 80% rename from src/Widgets/MultitaskingView.vala rename to src/Widgets/MultitaskingView/MultitaskingView.vala index e9983ac67..5054b0a6a 100644 --- a/src/Widgets/MultitaskingView.vala +++ b/src/Widgets/MultitaskingView/MultitaskingView.vala @@ -67,7 +67,6 @@ namespace Gala { workspaces = new WorkspaceRow (display); workspaces_gesture_controller = new GestureController (SWITCH_WORKSPACE, this) { - enabled = false, overshoot_upper_clamp = 0.1 }; workspaces_gesture_controller.enable_touchpad (); @@ -92,13 +91,23 @@ namespace Gala { primary_monitor_container.add_child (workspaces); add_child (primary_monitor_container); + add_child (StaticWindowContainer.get_instance (display)); + unowned var manager = display.get_workspace_manager (); manager.workspace_added.connect (add_workspace); manager.workspace_removed.connect (remove_workspace); - manager.workspaces_reordered.connect (() => update_positions (false)); - manager.workspace_switched.connect_after ((from, to, direction) => { - update_positions (opened); - }); + manager.workspaces_reordered.connect (() => reposition_icon_groups (false)); + manager.workspace_switched.connect (on_workspace_switched); + + manager.bind_property ( + "n-workspaces", + workspaces_gesture_controller, + "overshoot-lower-clamp", + DEFAULT, + (binding, from_value, ref to_value) => { + to_value.set_double (-from_value.get_int () - 0.1 + 1); + } + ); window_containers_monitors = new List (); update_monitors (); @@ -210,86 +219,90 @@ namespace Gala { break; } - unowned Meta.WorkspaceManager manager = display.get_workspace_manager (); - var active_workspace = manager.get_active_workspace (); - var new_workspace = active_workspace.get_neighbor (direction); - - if (active_workspace != new_workspace) { - new_workspace.activate (scroll_event.get_time ()); - } else { - play_nudge_animation (direction); - } + switch_to_next_workspace (direction); return true; } - public void play_nudge_animation (Meta.MotionDirection direction) { - if (!Meta.Prefs.get_gnome_animations ()) { - return; - } - - var scale = display.get_monitor_scale (display.get_primary_monitor ()); - var nudge_gap = InternalUtils.scale_to_int (WindowManagerGala.NUDGE_GAP, scale); - - float dest = nudge_gap; - if (direction == Meta.MotionDirection.RIGHT) { - dest *= -1; - } + public void move_window (Meta.Window window, Meta.Workspace workspace) { + StaticWindowContainer.get_instance (display).notify_window_moving (window); + workspaces_gesture_controller.goto (-workspace.index ()); + } - double[] keyframes = { 0.5 }; - GLib.Value[] x = { dest }; + public void switch_to_next_workspace (Meta.MotionDirection direction) { + var relative_direction = direction == LEFT ? 1 : -1; + workspaces_gesture_controller.goto (get_current_commit (SWITCH_WORKSPACE) + relative_direction); + } - var nudge = new Clutter.KeyframeTransition ("translation-x") { - duration = AnimationDuration.NUDGE, - remove_on_complete = true, - progress_mode = Clutter.AnimationMode.EASE_IN_QUAD - }; - nudge.set_from_value (0.0f); - nudge.set_to_value (0.0f); - nudge.set_key_frames (keyframes); - nudge.set_values (x); - workspaces.add_transition ("nudge", nudge); + public void kill_switch_workspace () { + // Not really a kill (we let the animation finish) + // but since we only use clones that's ok + workspaces_gesture_controller.cancel_gesture (); } public override void start_progress (GestureAction action) { - if (action != MULTITASKING_VIEW) { - return; - } - if (!opened) { + opened = true; + + wm.background_group.hide (); + wm.window_group.hide (); + wm.top_window_group.hide (); + show (); + grab_key_focus (); + modal_proxy = wm.push_modal (this); modal_proxy.set_keybinding_filter (keybinding_filter); var scale = display.get_monitor_scale (display.get_primary_monitor ()); icon_groups.force_reposition (); icon_groups.y = primary_monitor_container.height - InternalUtils.scale_to_int (WorkspaceClone.BOTTOM_OFFSET - 20, scale); - } else { + reposition_icon_groups (false); + + if (action != MULTITASKING_VIEW) { + icon_groups.hide (); + } + } else if (action == MULTITASKING_VIEW) { DragDropAction.cancel_all_by_id ("multitaskingview-window"); } - wm.kill_switch_workspace (); - wm.background_group.hide (); - wm.window_group.hide (); - wm.top_window_group.hide (); - show (); - grab_key_focus (); + if (action == SWITCH_WORKSPACE) { + WorkspaceManager.get_default ().freeze_remove (); - update_positions (opened); - workspaces_gesture_controller.cancel_gesture (); + if (workspaces_gesture_controller.action_info != null + && (bool) workspaces_gesture_controller.action_info + && display.focus_window != null + ) { + var moving = display.focus_window; + + StaticWindowContainer.get_instance (display).notify_window_moving (moving); - opened = true; + // Prevent moving to the last workspace if second last would be empty + if (moving.get_workspace ().index () == display.get_workspace_manager ().n_workspaces - 2 && + Utils.get_n_windows (moving.get_workspace (), true, moving) == 0 + ) { + workspaces_gesture_controller.overshoot_lower_clamp += 1; + } + } + } } public override void commit_progress (GestureAction action, double to) { switch (action) { case MULTITASKING_VIEW: - opened = to > 0.5; - workspaces_gesture_controller.enabled = opened; + opened = to > 0.5 || workspaces_gesture_controller.recognizing; + workspaces_gesture_controller.cancel_gesture (); break; case SWITCH_WORKSPACE: - unowned var workspace_manager = display.get_workspace_manager (); - workspace_manager.get_workspace_by_index ((int) (-to)).activate (display.get_current_time ()); + opened = get_current_commit (MULTITASKING_VIEW) > 0.5 || multitasking_gesture_controller.recognizing; + unowned var target_workspace = display.get_workspace_manager ().get_workspace_by_index ((int) (-to)); + var moving_window = StaticWindowContainer.get_instance (display).moving_window; + if (moving_window != null) { + moving_window.change_workspace (target_workspace); + target_workspace.activate_with_focus (moving_window, display.get_current_time ()); + } else { + target_workspace.activate (display.get_current_time ()); + } break; default: @@ -298,38 +311,21 @@ namespace Gala { } public override void end_progress (GestureAction action) { - if (action != MULTITASKING_VIEW) { - return; - } - - if (!opened) { + if (!opened && !animating) { wm.background_group.show (); wm.window_group.show (); wm.top_window_group.show (); + icon_groups.show (); hide (); wm.pop_modal (modal_proxy); } - } - /** - * Places the WorkspaceClones, moves the view so that the active one is shown - * and does the same for the IconGroups. - * - * @param animate Whether to animate the movement or have all elements take their - * positions immediately. - */ - private void update_positions (bool animate) { - unowned var manager = display.get_workspace_manager (); - workspaces_gesture_controller.overshoot_lower_clamp = -manager.n_workspaces - 0.1 + 1; - - if (animate) { - workspaces_gesture_controller.goto (-manager.get_active_workspace_index ()); - } else { - workspaces_gesture_controller.progress = -manager.get_active_workspace_index (); + if (action == SWITCH_WORKSPACE) { + WorkspaceManager.get_default ().thaw_remove (); + StaticWindowContainer.get_instance (display).notify_move_ended (); + display.get_workspace_manager ().notify_property ("n-workspaces"); //Recalc overshoot bounds } - - reposition_icon_groups (animate); } private void reposition_icon_groups (bool animate) { @@ -367,7 +363,7 @@ namespace Gala { workspace.window_selected.connect (window_selected); workspace.selected.connect (activate_workspace); - update_positions (false); + reposition_icon_groups (false); } private void remove_workspace (int num) { @@ -401,7 +397,15 @@ namespace Gala { workspace.destroy (); - update_positions (opened); + reposition_icon_groups (opened); + + workspaces_gesture_controller.progress = -manager.get_active_workspace_index (); + } + + private void on_workspace_switched (int from, int to) { + if ((int) (-get_current_commit (SWITCH_WORKSPACE)) != to) { + workspaces_gesture_controller.goto (-to); + } } /** diff --git a/src/Widgets/MultitaskingView/StaticWindowClone.vala b/src/Widgets/MultitaskingView/StaticWindowClone.vala new file mode 100644 index 000000000..56b0c744d --- /dev/null +++ b/src/Widgets/MultitaskingView/StaticWindowClone.vala @@ -0,0 +1,30 @@ +/* + * Copyright 2025 elementary, Inc. (https://elementary.io) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Authored by: Leonhard Kargl + */ + +/** + * A exact clone of a window (same position and size). This is used for static + * windows (e.g. on all workspaces or moving) and fades out while the multitasking view + * is being opened. + */ +public class Gala.StaticWindowClone : ActorTarget { + public Meta.Window window { get; construct; } + + public StaticWindowClone (Meta.Window window) { + Object (window: window); + } + + construct { + var window_actor = (Meta.WindowActor) window.get_compositor_private (); + var clone = new Clutter.Clone (window_actor); + add_child (clone); + + add_target (new PropertyTarget (MULTITASKING_VIEW, this, "opacity", typeof (uint), 255u, 0u)); + + window_actor.bind_property ("x", this, "x", SYNC_CREATE); + window_actor.bind_property ("y", this, "y", SYNC_CREATE); + } +} diff --git a/src/Widgets/MultitaskingView/StaticWindowContainer.vala b/src/Widgets/MultitaskingView/StaticWindowContainer.vala new file mode 100644 index 000000000..42224ad5d --- /dev/null +++ b/src/Widgets/MultitaskingView/StaticWindowContainer.vala @@ -0,0 +1,96 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io) + */ + +/** + * Holds clones of static windows (e.g. on all workspaces or being moved) + * in the multitasking view and fades them out while opening the multitasking view. + * The window container use this to know whether a window became static (they shouldn't show it anymore) + * or isn't static anymore (they have to show it now). + */ +public class Gala.StaticWindowContainer : ActorTarget { + private static GLib.Once instance; + public static StaticWindowContainer get_instance (Meta.Display display) { + return instance.once (() => { return new StaticWindowContainer (display); }); + } + + public signal void window_changed (Meta.Window window, bool is_static); + + public Meta.Display display { get; construct; } + + public Meta.Window? grabbed_window { get; private set; } + public Meta.Window? moving_window { get; private set; } + + private StaticWindowContainer (Meta.Display display) { + Object (display: display); + } + + construct { + display.grab_op_begin.connect (on_grab_op_begin); + display.grab_op_end.connect (on_grab_op_end); + + WindowListener.get_default ().window_on_all_workspaces_changed.connect (on_all_workspaces_changed); + } + + private void on_grab_op_begin (Meta.Window window, Meta.GrabOp op) { + if (op != MOVING) { + return; + } + + grabbed_window = window; + check_window_changed (window); + } + + private void on_grab_op_end (Meta.Window window, Meta.GrabOp op) { + grabbed_window = null; + check_window_changed (window); + } + + private void on_all_workspaces_changed (Meta.Window window) { + // We have to wait for shell clients here + Idle.add (() => { + check_window_changed (window); + return Source.REMOVE; + }); + } + + public void notify_window_moving (Meta.Window window) { + moving_window = window; + check_window_changed (window); + } + + public void notify_move_ended () { + if (moving_window == null) { + return; + } + + var window = moving_window; + moving_window = null; + check_window_changed (window); + } + + private void check_window_changed (Meta.Window window) { + var is_static = is_static (window) && !ShellClientsManager.get_instance ().is_positioned_window (window); + + Clutter.Actor? clone = null; + for (var child = get_first_child (); child != null; child = child.get_next_sibling ()) { + if (((StaticWindowClone) child).window == window) { + clone = child; + break; + } + } + + if (!is_static && clone != null) { + remove_child (clone); + } else if (is_static && !window.on_all_workspaces && clone == null) { + add_child (new StaticWindowClone (window)); + } + + window_changed (window, is_static); + } + + public bool is_static (Meta.Window window) { + return window == grabbed_window || window == moving_window || window.on_all_workspaces; + } +} diff --git a/src/Widgets/Tooltip.vala b/src/Widgets/MultitaskingView/Tooltip.vala similarity index 100% rename from src/Widgets/Tooltip.vala rename to src/Widgets/MultitaskingView/Tooltip.vala diff --git a/src/Widgets/WindowClone.vala b/src/Widgets/MultitaskingView/WindowClone.vala similarity index 97% rename from src/Widgets/WindowClone.vala rename to src/Widgets/MultitaskingView/WindowClone.vala index f49845ec2..f029198f7 100644 --- a/src/Widgets/WindowClone.vala +++ b/src/Widgets/MultitaskingView/WindowClone.vala @@ -106,7 +106,6 @@ public class Gala.WindowClone : ActorTarget { reactive = true; window.unmanaged.connect (unmanaged); - window.notify["on-all-workspaces"].connect (on_all_workspaces_changed); window.notify["fullscreen"].connect (check_shadow_requirements); window.notify["maximized-horizontally"].connect (check_shadow_requirements); window.notify["maximized-vertically"].connect (check_shadow_requirements); @@ -152,7 +151,6 @@ public class Gala.WindowClone : ActorTarget { ~WindowClone () { window.unmanaged.disconnect (unmanaged); - window.notify["on-all-workspaces"].disconnect (on_all_workspaces_changed); window.notify["fullscreen"].disconnect (check_shadow_requirements); window.notify["maximized-horizontally"].disconnect (check_shadow_requirements); window.notify["maximized-vertically"].disconnect (check_shadow_requirements); @@ -228,13 +226,6 @@ public class Gala.WindowClone : ActorTarget { && window.get_workspace () != window.get_display ().get_workspace_manager ().get_active_workspace ()) || window.minimized; } - private void on_all_workspaces_changed () { - // we don't display windows that are on all workspaces - if (window.on_all_workspaces) { - unmanaged (); - } - } - /** * Animate the window to the given slot */ @@ -283,15 +274,11 @@ public class Gala.WindowClone : ActorTarget { } public override void start_progress (GestureAction action) { - if (action == MULTITASKING_VIEW) { - update_hover_widgets (true); - } + update_hover_widgets (true); } public override void end_progress (GestureAction action) { - if (action == MULTITASKING_VIEW) { - update_hover_widgets (true); - } + update_hover_widgets (false); } public override void allocate (Clutter.ActorBox box) { diff --git a/src/Widgets/WindowCloneContainer.vala b/src/Widgets/MultitaskingView/WindowCloneContainer.vala similarity index 92% rename from src/Widgets/WindowCloneContainer.vala rename to src/Widgets/MultitaskingView/WindowCloneContainer.vala index 58d449780..9eed2abe4 100644 --- a/src/Widgets/WindowCloneContainer.vala +++ b/src/Widgets/MultitaskingView/WindowCloneContainer.vala @@ -72,7 +72,7 @@ public class Gala.WindowCloneContainer : ActorTarget { new_window.destroy.connect ((_new_window) => { // make sure to release reference if the window is selected if (_new_window == current_window) { - select_next_window (Meta.MotionDirection.RIGHT); + select_next_window (Meta.MotionDirection.RIGHT, false); } // if window is still selected, reset the selection @@ -215,16 +215,16 @@ public class Gala.WindowCloneContainer : ActorTarget { requested_close (); break; case Clutter.Key.Down: - select_next_window (Meta.MotionDirection.DOWN); + select_next_window (Meta.MotionDirection.DOWN, true); break; case Clutter.Key.Up: - select_next_window (Meta.MotionDirection.UP); + select_next_window (Meta.MotionDirection.UP, true); break; case Clutter.Key.Left: - select_next_window (Meta.MotionDirection.LEFT); + select_next_window (Meta.MotionDirection.LEFT, true); break; case Clutter.Key.Right: - select_next_window (Meta.MotionDirection.RIGHT); + select_next_window (Meta.MotionDirection.RIGHT, true); break; case Clutter.Key.Return: case Clutter.Key.KP_Enter: @@ -243,7 +243,7 @@ public class Gala.WindowCloneContainer : ActorTarget { * * @param direction The MetaMotionDirection in which to search for windows for. */ - public void select_next_window (Meta.MotionDirection direction) { + public void select_next_window (Meta.MotionDirection direction, bool user_action) { if (get_n_children () < 1) { return; } @@ -326,7 +326,7 @@ public class Gala.WindowCloneContainer : ActorTarget { } if (closest == null) { - if (current_window != null) { + if (current_window != null && user_action) { InternalUtils.bell_notify (display); current_window.active = true; } @@ -337,7 +337,10 @@ public class Gala.WindowCloneContainer : ActorTarget { current_window.active = false; } - closest.active = true; + if (user_action) { + closest.active = true; + } + current_window = closest; } @@ -354,11 +357,9 @@ public class Gala.WindowCloneContainer : ActorTarget { } public override void start_progress (GestureAction action) { - if (action != MULTITASKING_VIEW) { - return; - } - if (!opened) { + opened = true; + if (current_window != null) { current_window.active = false; } @@ -370,19 +371,26 @@ public class Gala.WindowCloneContainer : ActorTarget { break; } } - } - - opened = true; - restack_windows (); - reflow (true); + restack_windows (); + reflow (true); + } else if (action == MULTITASKING_VIEW) { // If we are open we only want to restack when we close + restack_windows (); + } } public override void commit_progress (GestureAction action, double to) { - if (action != MULTITASKING_VIEW) { - return; - } + switch (action) { + case MULTITASKING_VIEW: + opened = to > 0.5; + break; - opened = to > 0.5; + case SWITCH_WORKSPACE: + opened = get_current_commit (MULTITASKING_VIEW) > 0.5; + break; + + default: + break; + } } } diff --git a/src/Widgets/WindowIconActor.vala b/src/Widgets/MultitaskingView/WindowIconActor.vala similarity index 100% rename from src/Widgets/WindowIconActor.vala rename to src/Widgets/MultitaskingView/WindowIconActor.vala diff --git a/src/Widgets/WorkspaceClone.vala b/src/Widgets/MultitaskingView/WorkspaceClone.vala similarity index 95% rename from src/Widgets/WorkspaceClone.vala rename to src/Widgets/MultitaskingView/WorkspaceClone.vala index ca900dac7..8f4d2875e 100644 --- a/src/Widgets/WorkspaceClone.vala +++ b/src/Widgets/MultitaskingView/WorkspaceClone.vala @@ -229,8 +229,8 @@ namespace Gala { } } - var listener = WindowListener.get_default (); - listener.window_no_longer_on_all_workspaces.connect (add_window); + var static_windows = StaticWindowContainer.get_instance (display); + static_windows.window_changed.connect (on_window_static_changed); unowned var monitor_manager = display.get_context ().get_backend ().get_monitor_manager (); monitor_manager.monitors_changed.connect (update_targets); @@ -246,9 +246,6 @@ namespace Gala { workspace.window_added.disconnect (add_window); workspace.window_removed.disconnect (remove_window); - var listener = WindowListener.get_default (); - listener.window_no_longer_on_all_workspaces.disconnect (add_window); - background.destroy (); window_container.destroy (); icon_group.destroy (); @@ -266,7 +263,7 @@ namespace Gala { private void add_window (Meta.Window window) { if (window.window_type != Meta.WindowType.NORMAL || window.get_workspace () != workspace - || window.on_all_workspaces + || StaticWindowContainer.get_instance (workspace.get_display ()).is_static (window) || !window.is_on_primary_monitor ()) return; @@ -295,6 +292,14 @@ namespace Gala { remove_window (window); } + private void on_window_static_changed (Meta.Window window, bool is_static) { + if (is_static) { + remove_window (window); + } else { + add_window (window); + } + } + #if HAS_MUTTER45 public void update_size (Mtk.Rectangle monitor_geometry) { #else @@ -318,7 +323,7 @@ namespace Gala { background.set_pivot_point (0.5f, pivot_y); var initial_width = monitor.width; - var target_width = monitor.width * scale + WindowManagerGala.WORKSPACE_GAP * 2; + var target_width = monitor.width * scale + WorkspaceRow.WORKSPACE_GAP * 2; add_target (new PropertyTarget (MULTITASKING_VIEW, this, "width", typeof (float), (float) initial_width, (float) target_width)); add_target (new PropertyTarget (MULTITASKING_VIEW, background, "scale-x", typeof (double), 1d, (double) scale)); diff --git a/src/Widgets/WorkspaceInsertThumb.vala b/src/Widgets/MultitaskingView/WorkspaceInsertThumb.vala similarity index 100% rename from src/Widgets/WorkspaceInsertThumb.vala rename to src/Widgets/MultitaskingView/WorkspaceInsertThumb.vala diff --git a/src/Widgets/WorkspaceRow.vala b/src/Widgets/MultitaskingView/WorkspaceRow.vala similarity index 94% rename from src/Widgets/WorkspaceRow.vala rename to src/Widgets/MultitaskingView/WorkspaceRow.vala index f6f04ae59..1398a2361 100644 --- a/src/Widgets/WorkspaceRow.vala +++ b/src/Widgets/MultitaskingView/WorkspaceRow.vala @@ -6,6 +6,8 @@ */ public class Gala.WorkspaceRow : ActorTarget { + public const int WORKSPACE_GAP = 24; + public Meta.Display display { get; construct; } public WorkspaceRow (Meta.Display display) { @@ -26,7 +28,7 @@ public class Gala.WorkspaceRow : ActorTarget { float preferred_width; child.get_preferred_width (-1, null, out preferred_width); - var child_x = (float) Math.round ((progress + index) * preferred_width); + var child_x = (float) Math.round ((progress + index) * (preferred_width + WORKSPACE_GAP)); child.allocate_preferred_size (child_x, 0); diff --git a/src/WindowGrabTracker.vala b/src/WindowGrabTracker.vala deleted file mode 100644 index 55053d665..000000000 --- a/src/WindowGrabTracker.vala +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-3.0-or-later - * SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io) - */ - -public class Gala.WindowGrabTracker : GLib.Object { - public Meta.Display display { get; construct; } - public Meta.Window? current_window { get; private set; } - - public WindowGrabTracker (Meta.Display display) { - Object (display: display); - } - - construct { - display.grab_op_begin.connect (on_grab_op_begin); - display.grab_op_end.connect (on_grab_op_end); - } - - private void on_grab_op_begin (Meta.Window window, Meta.GrabOp op) { - if (op != MOVING) { - return; - } - - current_window = window; - } - - private void on_grab_op_end (Meta.Window window, Meta.GrabOp op) { - current_window = null; - } -} diff --git a/src/WindowListener.vala b/src/WindowListener.vala index d26cabb7b..8378715e9 100644 --- a/src/WindowListener.vala +++ b/src/WindowListener.vala @@ -53,7 +53,7 @@ public class Gala.WindowListener : Object { return instance; } - public signal void window_no_longer_on_all_workspaces (Meta.Window window); + public signal void window_on_all_workspaces_changed (Meta.Window window); private Gee.HashMap unmaximized_state_geometry; @@ -82,13 +82,6 @@ public class Gala.WindowListener : Object { } } - private void window_on_all_workspaces_changed (Meta.Window window) { - if (window.on_all_workspaces) - return; - - window_no_longer_on_all_workspaces (window); - } - private void window_maximized_changed (Meta.Window window) { WindowGeometry window_geometry = {}; window_geometry.inner = window.get_frame_rect (); diff --git a/src/WindowManager.vala b/src/WindowManager.vala index e1c7cae1b..968f9f527 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -83,12 +83,8 @@ namespace Gala { private Clutter.Actor? tile_preview; - private Meta.Window? moving; //place for the window that is being moved over - private DaemonManager daemon_manager; - private WindowGrabTracker window_grab_tracker; - private NotificationStack notification_stack; private Gee.LinkedList modal_stack = new Gee.LinkedList (); @@ -112,18 +108,6 @@ namespace Gala { private GLib.Settings new_behavior_settings; private GestureTracker gesture_tracker; - private bool animating_switch_workspace = false; - private bool switch_workspace_with_gesture = false; - - /** - * Amount of pixels to move on the nudge animation. - */ - public const int NUDGE_GAP = 32; - - /** - * Gap to show between workspaces while switching between them. - */ - public const int WORKSPACE_GAP = 24; construct { gesture_tracker = new GestureTracker (AnimationDuration.WORKSPACE_SWITCH_MIN, AnimationDuration.WORKSPACE_SWITCH); @@ -144,7 +128,6 @@ namespace Gala { public override void start () { ShellClientsManager.init (this); daemon_manager = new DaemonManager (get_display ()); - window_grab_tracker = new WindowGrabTracker (get_display ()); show_stage (); @@ -590,36 +573,11 @@ namespace Gala { return false; } - var action = GestureSettings.get_action (gesture); - switch_workspace_with_gesture = action == SWITCH_WORKSPACE || action == MOVE_TO_WORKSPACE; - return switch_workspace_with_gesture || (action == SWITCH_WINDOWS && !window_switcher.opened); + return GestureSettings.get_action (gesture) == SWITCH_WINDOWS && !window_switcher.opened; } private double on_gesture_handled (Gesture gesture, uint32 timestamp) { - var direction = gesture_tracker.settings.get_natural_scroll_direction (gesture); - - switch (GestureSettings.get_action (gesture)) { - case MOVE_TO_WORKSPACE: - unowned var display = get_display (); - unowned var manager = display.get_workspace_manager (); - unowned var active_workspace = manager.get_active_workspace (); - unowned var target_workspace = active_workspace.get_neighbor (direction); - - move_window (display.focus_window, target_workspace, timestamp); - break; - - case SWITCH_WORKSPACE: - switch_to_next_workspace (direction, timestamp); - break; - - case SWITCH_WINDOWS: - window_switcher.handle_gesture (gesture.direction); - break; - - default: - break; - } - + window_switcher.handle_gesture (gesture.direction); return 0; } @@ -627,56 +585,7 @@ namespace Gala { * {@inheritDoc} */ public void switch_to_next_workspace (Meta.MotionDirection direction, uint32 timestamp) { - if (animating_switch_workspace) { - return; - } - - unowned var display = get_display (); - unowned var active_workspace = display.get_workspace_manager ().get_active_workspace (); - unowned var neighbor = active_workspace.get_neighbor (direction); - - if (neighbor != active_workspace) { - neighbor.activate (timestamp); - } else { - // if we didn't switch, show a nudge-over animation if one is not already in progress - if (workspace_view.is_opened () && workspace_view is MultitaskingView) { - ((MultitaskingView) workspace_view).play_nudge_animation (direction); - } else { - play_nudge_animation (direction); - } - } - } - - private void play_nudge_animation (Meta.MotionDirection direction) { - if (!Meta.Prefs.get_gnome_animations ()) { - return; - } - - animating_switch_workspace = true; - - unowned var display = get_display (); - unowned var active_index = display.get_workspace_manager ().get_active_workspace_index (); - prepare_workspace_switch (active_index, active_index, direction); - - var monitor_scale = display.get_monitor_scale (display.get_primary_monitor ()); - var monitor_geom = display.get_monitor_geometry (display.get_primary_monitor ()); - - var to_value = monitor_geom.width + WORKSPACE_GAP * monitor_scale; - - if (direction == RIGHT) { - to_value *= -1; - } - - new GesturePropertyTransition (out_group, gesture_tracker, "x", 0f, to_value) { - overshoot_upper_clamp = 0.1 - }.start (switch_workspace_with_gesture); - - new GesturePropertyTransition (wallpaper, gesture_tracker, "x", 0f, to_value) { - overshoot_upper_clamp = 0.1 - }.start (switch_workspace_with_gesture, () => { - switch_workspace_animation_finished (direction, false, true); - animating_switch_workspace = false; - }); + ((MultitaskingView) workspace_view).switch_to_next_workspace (direction); } private void update_input_area () { @@ -809,13 +718,7 @@ namespace Gala { return; } - moving = window; - - if (!window.is_on_all_workspaces ()) { - window.change_workspace (workspace); - } - - workspace.activate_with_focus (window, timestamp); + ((MultitaskingView) workspace_view).move_window (window, workspace); } /** @@ -1855,379 +1758,12 @@ namespace Gala { end_animation (ref maximizing, actor); } - /*workspace switcher*/ - private List? windows; - private List? parents; - private List? tmp_actors; - private Clutter.Actor? out_group; - private Clutter.Actor? in_group; - private Clutter.Actor? wallpaper; - private Clutter.Actor? wallpaper_clone; - - private void prepare_workspace_switch (int from, int to, Meta.MotionDirection direction) { - float screen_width, screen_height; - unowned var display = get_display (); - var primary = display.get_primary_monitor (); - var move_primary_only = Meta.Prefs.get_workspaces_only_on_primary (); - var monitor_geom = display.get_monitor_geometry (primary); - var clone_offset_x = move_primary_only ? monitor_geom.x : 0.0f; - var clone_offset_y = move_primary_only ? monitor_geom.y : 0.0f; - - display.get_size (out screen_width, out screen_height); - - unowned var manager = display.get_workspace_manager (); - unowned var workspace_from = manager.get_workspace_by_index (from); - unowned var workspace_to = from != to ? manager.get_workspace_by_index (to) : null; - - var main_container = new Clutter.Actor (); - var background_actor = new Clutter.Clone (system_background.background_actor); - var static_windows = new Clutter.Actor (); - if (workspace_to != null) { - in_group = new Clutter.Actor (); - } - out_group = new Clutter.Actor (); - windows = new List (); - parents = new List (); - tmp_actors = new List (); - - tmp_actors.prepend (main_container); - tmp_actors.prepend (background_actor); - if (in_group != null) { - tmp_actors.prepend (in_group); - } - tmp_actors.prepend (out_group); - tmp_actors.prepend (static_windows); - - window_group.add_child (main_container); - - // prepare wallpaper - if (move_primary_only) { - unowned var background = background_group.get_child_at_index (primary); - background.hide (); - wallpaper = new Clutter.Clone (background); - } else { - background_group.hide (); - ((BackgroundContainer) background_group).set_black_background (false); - wallpaper = new Clutter.Clone (background_group); - } - wallpaper.add_effect (new Gala.ShadowEffect ("workspace")); - tmp_actors.prepend (wallpaper); - - if (workspace_to != null) { - wallpaper_clone = new Clutter.Clone (wallpaper); - wallpaper_clone.add_effect (new Gala.ShadowEffect ("workspace")); - tmp_actors.prepend (wallpaper_clone); - } - - // pack all containers - main_container.add_child (background_actor); - main_container.add_child (wallpaper); - if (wallpaper_clone != null) { - main_container.add_child (wallpaper_clone); - } - main_container.add_child (out_group); - if (in_group != null) { - main_container.add_child (in_group); - } - main_container.add_child (static_windows); - - unowned var grabbed_window = window_grab_tracker.current_window; - var to_has_fullscreened = false; - var from_has_fullscreened = false; - - // collect all windows and put them in the appropriate containers - var slist = new GLib.SList (); - display.list_all_windows ().@foreach ((win) => { - slist.append (win); - }); - foreach (unowned var window in display.sort_windows_by_stacking (slist)) { - unowned var actor = (Meta.WindowActor) window.get_compositor_private (); - - if (actor.is_destroyed ()) { - continue; - } - - if (!window.showing_on_its_workspace () || - move_primary_only && !window.is_on_primary_monitor () || - actor.get_parent () == shell_group - ) { - continue; - } - - if (window.on_all_workspaces || window == moving || window == grabbed_window) { - // notifications use their own group and are always on top - if (NotificationStack.is_notification (window)) { - continue; - } - - windows.append (actor); - parents.append (actor.get_parent ()); - - InternalUtils.clutter_actor_reparent (actor, static_windows); - actor.set_translation (-clone_offset_x, -clone_offset_y, 0); - - // Don't fade docks and moving/grabbed windows they just stay where they are - if (window.window_type == DOCK || window == moving || window == grabbed_window) { - continue; - } - - // windows that are on all workspaces will be faded out and back in - actor.save_easing_state (); - actor.set_easing_duration (300); - actor.opacity = 0; - actor.restore_easing_state (); - - continue; - } - - if (window.get_workspace () == workspace_from) { - windows.append (actor); - parents.append (actor.get_parent ()); - actor.set_translation (-clone_offset_x, -clone_offset_y, 0); - InternalUtils.clutter_actor_reparent (actor, out_group); - - if (window.fullscreen) - from_has_fullscreened = true; - - } else if (workspace_to != null && window.get_workspace () == workspace_to) { - windows.append (actor); - parents.append (actor.get_parent ()); - actor.set_translation (-clone_offset_x, -clone_offset_y, 0); - InternalUtils.clutter_actor_reparent (actor, in_group); - - if (window.fullscreen) - to_has_fullscreened = true; - - } - } - - main_container.clip_to_allocation = true; - main_container.x = move_primary_only ? monitor_geom.x : 0.0f; - main_container.y = move_primary_only ? monitor_geom.y : 0.0f; - main_container.width = move_primary_only ? monitor_geom.width : screen_width; - main_container.height = move_primary_only ? monitor_geom.height : screen_height; - - var monitor_scale = display.get_monitor_scale (primary); - var x2 = move_primary_only ? monitor_geom.width : screen_width; - if (workspace_to != null) { - x2 += WORKSPACE_GAP * monitor_scale; - } - if (direction == Meta.MotionDirection.RIGHT) { - x2 = -x2; - } - - out_group.x = 0.0f; - wallpaper.x = 0.0f; - wallpaper.y += clone_offset_y; - wallpaper.set_translation (-clone_offset_x, 0.0f, 0.0f); - - if (in_group != null && wallpaper_clone != null) { - in_group.x = -x2; - wallpaper_clone.x = -x2; - wallpaper_clone.y += clone_offset_y; - wallpaper_clone.set_translation (-clone_offset_x, 0.0f, 0.0f); - } - - // The wallpapers need to move upwards inside the container to match their - // original position before/after the transition. - if (move_primary_only) { - wallpaper.y = -monitor_geom.y; - if (wallpaper_clone != null) { - wallpaper_clone.y = -monitor_geom.y; - } - } - - out_group.clip_to_allocation = true; - out_group.width = move_primary_only ? monitor_geom.width : screen_width; - out_group.height = move_primary_only ? monitor_geom.height : screen_height; - - if (in_group != null) { - in_group.clip_to_allocation = out_group.clip_to_allocation; - in_group.width = out_group.width; - in_group.height = out_group.height; - } - } - public override void switch_workspace (int from, int to, Meta.MotionDirection direction) { - if (!Meta.Prefs.get_gnome_animations () - || (direction != Meta.MotionDirection.LEFT && direction != Meta.MotionDirection.RIGHT) - || animating_switch_workspace - || workspace_view.is_opened () - || window_overview.is_opened ()) { - animating_switch_workspace = false; - switch_workspace_completed (); - return; - } - - animating_switch_workspace = true; - - prepare_workspace_switch (from, to, direction); - - var animation_mode = Clutter.AnimationMode.EASE_OUT_CUBIC; - - var x2 = -in_group.x; - GestureTracker.OnUpdate on_animation_update = (percentage) => { - var x_out = GestureTracker.animation_value (0.0f, x2, percentage, true); - var x_in = GestureTracker.animation_value (-x2, 0.0f, percentage, true); - - out_group.x = x_out; - in_group.x = x_in; - - wallpaper.x = x_out; - wallpaper_clone.x = x_in; - }; - - GestureTracker.OnEnd on_animation_end = (percentage, completions, duration) => { - if (switch_workspace_with_gesture && (percentage == 1 || percentage == 0)) { - switch_workspace_animation_finished (direction, completions == 0); - return; - } - - out_group.save_easing_state (); - out_group.set_easing_mode (animation_mode); - out_group.set_easing_duration (duration); - - in_group.save_easing_state (); - in_group.set_easing_mode (animation_mode); - in_group.set_easing_duration (duration); - - wallpaper_clone.save_easing_state (); - wallpaper_clone.set_easing_mode (animation_mode); - wallpaper_clone.set_easing_duration (duration); - - wallpaper.save_easing_state (); - wallpaper.set_easing_mode (animation_mode); - wallpaper.set_easing_duration (duration); - - out_group.x = completions * x2; - out_group.restore_easing_state (); - - in_group.x = completions == 0 ? -x2 : 0.0f; - in_group.restore_easing_state (); - - wallpaper.x = completions == 0 ? 0.0f : x2; - wallpaper.restore_easing_state (); - - wallpaper_clone.x = completions == 0 ? -x2 : 0.0f; - wallpaper_clone.restore_easing_state (); - - var transition = in_group.get_transition ("x"); - if (transition != null) { - transition.completed.connect (() => { - switch_workspace_animation_finished (direction, completions == 0); - }); - } else { - switch_workspace_animation_finished (direction, completions == 0); - } - }; - - if (!switch_workspace_with_gesture) { - on_animation_end (1, 1, AnimationDuration.WORKSPACE_SWITCH_MIN); - } else { - gesture_tracker.connect_handlers (null, (owned) on_animation_update, (owned) on_animation_end); - } - } - - private void switch_workspace_animation_finished (Meta.MotionDirection animation_direction, - bool cancel_action, bool is_nudge_animation = false) { - if (!animating_switch_workspace) { - return; - } - - end_switch_workspace (); - - if (!is_nudge_animation) { - switch_workspace_completed (); - } - - animating_switch_workspace = cancel_action; - - if (cancel_action) { - var cancel_direction = (animation_direction == Meta.MotionDirection.LEFT) - ? Meta.MotionDirection.RIGHT - : Meta.MotionDirection.LEFT; - unowned Meta.Display display = get_display (); - unowned var active_workspace = display.get_workspace_manager ().get_active_workspace (); - unowned var neighbor = active_workspace.get_neighbor (cancel_direction); - - if (moving != null) { - move_window (moving, neighbor, Meta.CURRENT_TIME); - } else { - neighbor.activate (display.get_current_time ()); - } - } else { - moving = null; - } - } - - private void end_switch_workspace () { - if ((windows == null || parents == null) && tmp_actors == null) - return; - - unowned var display = get_display (); - unowned var active_workspace = display.get_workspace_manager ().get_active_workspace (); - - // Show the real wallpaper again - if (Meta.Prefs.get_workspaces_only_on_primary ()) { - unowned var background = background_group.get_child_at_index (display.get_primary_monitor ()); - background.show (); - } else { - ((BackgroundContainer) background_group).set_black_background (true); - background_group.show (); - } - - for (var i = 0; i < windows.length (); i++) { - unowned var actor = windows.nth_data (i); - actor.set_translation (0.0f, 0.0f, 0.0f); - - unowned Meta.WindowActor? window = actor as Meta.WindowActor; - if (window == null) { - InternalUtils.clutter_actor_reparent (actor, parents.nth_data (i)); - continue; - } - - unowned Meta.Window? meta_window = window.get_meta_window (); - if (!window.is_destroyed ()) { - InternalUtils.clutter_actor_reparent (actor, parents.nth_data (i)); - } - - kill_window_effects (window); - - if (meta_window != null - && meta_window.get_workspace () != active_workspace - && !meta_window.is_on_all_workspaces ()) - window.hide (); - - // some static windows may have been faded out - if (actor.opacity < 255U) { - actor.save_easing_state (); - actor.set_easing_duration (300); - actor.opacity = 255U; - actor.restore_easing_state (); - } - } - - if (tmp_actors != null) { - foreach (var actor in tmp_actors) { - actor.destroy (); - } - tmp_actors = null; - } - - windows = null; - parents = null; - - out_group = null; - in_group = null; - wallpaper = null; - wallpaper_clone = null; - - switch_workspace_with_gesture = false; - animating_switch_workspace = false; + switch_workspace_completed (); } public override void kill_switch_workspace () { - end_switch_workspace (); + ((MultitaskingView) workspace_view).kill_switch_workspace (); } public override void locate_pointer () { diff --git a/src/meson.build b/src/meson.build index 89980dc99..0a8b958ad 100644 --- a/src/meson.build +++ b/src/meson.build @@ -15,7 +15,6 @@ gala_bin_sources = files( 'SessionManager.vala', 'SuperScrollAction.vala', 'WindowAttentionTracker.vala', - 'WindowGrabTracker.vala', 'WindowListener.vala', 'WindowManager.vala', 'WindowStateSaver.vala', @@ -58,24 +57,26 @@ gala_bin_sources = files( 'ShellClients/ShellClientsManager.vala', 'ShellClients/ShellWindow.vala', 'Widgets/DwellClickTimer.vala', - 'Widgets/IconGroup.vala', - 'Widgets/IconGroupContainer.vala', - 'Widgets/MonitorClone.vala', - 'Widgets/MultitaskingView.vala', + 'Widgets/MultitaskingView/IconGroup.vala', + 'Widgets/MultitaskingView/IconGroupContainer.vala', + 'Widgets/MultitaskingView/MonitorClone.vala', + 'Widgets/MultitaskingView/MultitaskingView.vala', + 'Widgets/MultitaskingView/StaticWindowClone.vala', + 'Widgets/MultitaskingView/StaticWindowContainer.vala', + 'Widgets/MultitaskingView/Tooltip.vala', + 'Widgets/MultitaskingView/WindowClone.vala', + 'Widgets/MultitaskingView/WindowCloneContainer.vala', + 'Widgets/MultitaskingView/WindowIconActor.vala', + 'Widgets/MultitaskingView/WorkspaceClone.vala', + 'Widgets/MultitaskingView/WorkspaceInsertThumb.vala', + 'Widgets/MultitaskingView/WorkspaceRow.vala', 'Widgets/PixelPicker.vala', 'Widgets/PointerLocator.vala', 'Widgets/ScreenShield.vala', 'Widgets/SelectionArea.vala', - 'Widgets/Tooltip.vala', - 'Widgets/WindowClone.vala', - 'Widgets/WindowCloneContainer.vala', - 'Widgets/WindowIconActor.vala', 'Widgets/WindowOverview.vala', 'Widgets/WindowSwitcher/WindowSwitcher.vala', 'Widgets/WindowSwitcher/WindowSwitcherIcon.vala', - 'Widgets/WorkspaceClone.vala', - 'Widgets/WorkspaceInsertThumb.vala', - 'Widgets/WorkspaceRow.vala', ) gala_bin = executable(