From bb874ae0fd370a49e33c5f1eda673f9eac2255af Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Sun, 4 Aug 2024 19:28:24 +0200 Subject: [PATCH 1/3] DesktopIntegration/focus_window: Shake window if already focused --- src/DesktopIntegration.vala | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/DesktopIntegration.vala b/src/DesktopIntegration.vala index 3fe823299..75b343e8e 100644 --- a/src/DesktopIntegration.vala +++ b/src/DesktopIntegration.vala @@ -107,12 +107,39 @@ public class Gala.DesktopIntegration : GLib.Object { foreach (unowned var app in apps) { foreach (weak Meta.Window window in app.get_windows ()) { if (window.get_id () == uid) { - window.get_workspace ().activate_with_focus (window, wm.get_display ().get_current_time ()); + if (window.has_focus ()) { + wm.get_display ().get_sound_player ().play_from_theme ("bell", _("Window has already focus"), null); + shake_window (window); + } else { + window.get_workspace ().activate_with_focus (window, wm.get_display ().get_current_time ()); + } } } } } + private void shake_window (Meta.Window window) { + if (window.get_maximized () == BOTH) { + return; + } + + var rect = window.get_frame_rect (); + + int n = 0; + Timeout.add (10, () => { + int diff = 15; + if (n % 2 == 0) { + diff = -15; + } + + window.move_frame (false, rect.x + diff, rect.y); + + n++; + + return n <= 10; + }); + } + public void show_windows_for (string app_id) throws IOError, DBusError { if (wm.window_overview == null) { throw new IOError.FAILED ("Window overview not provided by window manager"); From 6bc8df2a3c64a398432cae0348521b8640571198 Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Sun, 4 Aug 2024 19:36:37 +0200 Subject: [PATCH 2/3] Allow only one notify at a time and reset position --- src/DesktopIntegration.vala | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/DesktopIntegration.vala b/src/DesktopIntegration.vala index 75b343e8e..0c0c5bec8 100644 --- a/src/DesktopIntegration.vala +++ b/src/DesktopIntegration.vala @@ -108,8 +108,7 @@ public class Gala.DesktopIntegration : GLib.Object { foreach (weak Meta.Window window in app.get_windows ()) { if (window.get_id () == uid) { if (window.has_focus ()) { - wm.get_display ().get_sound_player ().play_from_theme ("bell", _("Window has already focus"), null); - shake_window (window); + notify_already_focused (window); } else { window.get_workspace ().activate_with_focus (window, wm.get_display ().get_current_time ()); } @@ -118,8 +117,18 @@ public class Gala.DesktopIntegration : GLib.Object { } } - private void shake_window (Meta.Window window) { + private bool notifying = false; + private void notify_already_focused (Meta.Window window) { + if (notifying) { + return; + } + + notifying = true; + + wm.get_display ().get_sound_player ().play_from_theme ("bell", _("Window has already focus"), null); + if (window.get_maximized () == BOTH) { + notifying = false; return; } @@ -136,7 +145,14 @@ public class Gala.DesktopIntegration : GLib.Object { n++; - return n <= 10; + var should_continue = n <= 10; + + if (!should_continue) { + notifying = false; + window.move_frame (false, rect.x, rect.y); + } + + return should_continue; }); } From a3a8c5e0619f7d85e0e6bcd3bf980a950f586e45 Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Thu, 8 Aug 2024 12:49:23 +0200 Subject: [PATCH 3/3] Use clutter transition for animation --- src/DesktopIntegration.vala | 38 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/DesktopIntegration.vala b/src/DesktopIntegration.vala index 0c0c5bec8..c59ceb994 100644 --- a/src/DesktopIntegration.vala +++ b/src/DesktopIntegration.vala @@ -132,28 +132,26 @@ public class Gala.DesktopIntegration : GLib.Object { return; } - var rect = window.get_frame_rect (); - - int n = 0; - Timeout.add (10, () => { - int diff = 15; - if (n % 2 == 0) { - diff = -15; - } - - window.move_frame (false, rect.x + diff, rect.y); - - n++; - - var should_continue = n <= 10; + var transition = new Clutter.KeyframeTransition ("translation-x") { + repeat_count = 5, + duration = 100, + remove_on_complete = true + }; + transition.set_from_value (0); + transition.set_to_value (0); + transition.set_key_frames ( { 0.5, -0.5 } ); + + var offset = InternalUtils.scale_to_int (15, wm.get_display ().get_monitor_scale (window.get_monitor ())); + transition.set_values ( { -offset, offset }); + + transition.stopped.connect (() => { + notifying = false; + wm.get_display ().enable_unredirect (); + }); - if (!should_continue) { - notifying = false; - window.move_frame (false, rect.x, rect.y); - } + wm.get_display ().disable_unredirect (); - return should_continue; - }); + ((Meta.WindowActor) window.get_compositor_private ()).add_transition ("notify-already-focused", transition); } public void show_windows_for (string app_id) throws IOError, DBusError {