Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions po/POTFILES
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
src/Application.vala
src/App.vala
src/AppWindow.vala
src/Application.vala
src/AppSystem.vala
src/DesktopIntegration.vala
src/Launcher.vala
src/ItemManager.vala
src/Launcher.vala
src/MainWindow.vala
src/PoofPopover.vala
src/Window.vala
src/WindowSystem.vala
src/DBus/ItemInterface.vala
src/DBus/Unity.vala
src/DBus/SwitcherooControl.vala
34 changes: 11 additions & 23 deletions src/App.vala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* SPDX-License-Identifier: GPL-3.0
* SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io)
* SPDX-FileCopyrightText: 2024-2025 elementary, Inc. (https://elementary.io)
*/

public class Dock.App : Object {
Expand Down Expand Up @@ -48,7 +48,7 @@ public class Dock.App : Object {
public SimpleActionGroup action_group { get; construct; }
public Menu menu_model { get; construct; }

public Gee.List<AppWindow> windows { get; private owned set; } //Ordered by stacking order with topmost at 0
public Gee.List<Window> windows { get; private owned set; } // Ordered by stacking order with topmost at 0

private static Dock.SwitcherooControl switcheroo_control;

Expand All @@ -63,7 +63,7 @@ public class Dock.App : Object {
}

construct {
windows = new Gee.LinkedList<AppWindow> ();
windows = new Gee.LinkedList<Window> ();

action_group = new SimpleActionGroup ();

Expand Down Expand Up @@ -138,9 +138,9 @@ public class Dock.App : Object {
} else if (windows.size == 0) {
app_info.launch (null, context);
} else if (windows.size == 1) {
AppSystem.get_default ().desktop_integration.focus_window.begin (windows.first ().uid);
} else if (AppSystem.get_default ().desktop_integration != null) {
AppSystem.get_default ().desktop_integration.show_windows_for.begin (app_info.get_id ());
WindowSystem.get_default ().desktop_integration.focus_window.begin (windows.first ().uid);
} else if (WindowSystem.get_default ().desktop_integration != null) {
WindowSystem.get_default ().desktop_integration.show_windows_for.begin (app_info.get_id ());
}
} catch (Error e) {
critical (e.message);
Expand Down Expand Up @@ -184,9 +184,9 @@ public class Dock.App : Object {
}
}

public void update_windows (Gee.List<AppWindow>? new_windows) {
public void update_windows (Gee.List<Window>? new_windows) {
if (new_windows == null) {
windows = new Gee.LinkedList<AppWindow> ();
windows = new Gee.LinkedList<Window> ();
} else {
windows = new_windows;
}
Expand All @@ -201,18 +201,6 @@ public class Dock.App : Object {
check_remove ();
}

public AppWindow? find_window (uint64 window_uid) {
var found_win = windows.first_match ((win) => {
return win.uid == window_uid;
});

if (found_win != null) {
return found_win;
} else {
return null;
}
}

public void perform_unity_update (VariantIter prop_iter) {
string prop_key;
Variant prop_value;
Expand Down Expand Up @@ -241,7 +229,7 @@ public class Dock.App : Object {
progress = 0;
}

private AppWindow[] current_windows;
private Window[] current_windows;
private uint current_index;
private uint timer_id = 0;
private bool should_wait = false;
Expand All @@ -264,7 +252,7 @@ public class Dock.App : Object {
return;
}

AppSystem.get_default ().desktop_integration.focus_window.begin (current_windows[current_index].uid);
WindowSystem.get_default ().desktop_integration.focus_window.begin (current_windows[current_index].uid);

// Throttle the scroll for performance and better visibility of the windows
Timeout.add (250, () => {
Expand All @@ -282,7 +270,7 @@ public class Dock.App : Object {
yield AppSystem.get_default ().sync_windows (); // Get the current stacking order
current_index = windows.size > 1 && windows.first ().has_focus ? 1 : 0;
current_windows = {};
foreach (AppWindow window in windows) {
foreach (var window in windows) {
current_windows += window;
}
}
Expand Down
53 changes: 13 additions & 40 deletions src/AppSystem.vala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* SPDX-License-Identifier: GPL-3.0
* SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io)
* SPDX-FileCopyrightText: 2024-2025 elementary, Inc. (https://elementary.io)
*/

public class Dock.AppSystem : Object, UnityClient {
Expand All @@ -17,8 +17,6 @@ public class Dock.AppSystem : Object, UnityClient {

public signal void app_added (App app);

public DesktopIntegration? desktop_integration { get; private set; }

private GLib.HashTable<unowned string, App> id_to_app;

private AppSystem () { }
Expand All @@ -37,19 +35,8 @@ public class Dock.AppSystem : Object, UnityClient {
add_app (app_info, true);
}

try {
desktop_integration = yield GLib.Bus.get_proxy<Dock.DesktopIntegration> (
SESSION,
"org.pantheon.gala",
"/org/pantheon/gala/DesktopInterface"
);

yield sync_windows ();

desktop_integration.windows_changed.connect (sync_windows);
} catch (Error e) {
critical ("Failed to get desktop integration: %s", e.message);
}
yield sync_windows ();
WindowSystem.get_default ().notify["windows"].connect (sync_windows);
}

private App add_app (DesktopAppInfo app_info, bool pinned) {
Expand All @@ -60,47 +47,33 @@ public class Dock.AppSystem : Object, UnityClient {
return app;
}

public async void sync_windows () requires (desktop_integration != null) {
DesktopIntegration.Window[] windows;
try {
windows = yield desktop_integration.get_windows ();
} catch (Error e) {
critical (e.message);
return;
}
public async void sync_windows () {
var windows = WindowSystem.get_default ().windows;

var app_window_list = new Gee.HashMap<App, Gee.List<AppWindow>> ();
foreach (unowned var window in windows) {
unowned var app_id = window.properties["app-id"].get_string ();
App? app = id_to_app[app_id];
var app_window_list = new Gee.HashMap<App, Gee.List<Window>> ();
foreach (var window in windows) {
App? app = id_to_app[window.app_id];
if (app == null) {
var app_info = new GLib.DesktopAppInfo (app_id);
var app_info = new GLib.DesktopAppInfo (window.app_id);
if (app_info == null) {
continue;
}

app = add_app (app_info, false);
}

AppWindow? app_window = app.find_window (window.uid);
if (app_window == null) {
app_window = new AppWindow (window.uid);
}

app_window.update_properties (window.properties);

var window_list = app_window_list.get (app);
if (window_list == null) {
var new_window_list = new Gee.LinkedList<AppWindow> ();
new_window_list.add (app_window);
var new_window_list = new Gee.LinkedList<Window> ();
new_window_list.add (window);
app_window_list.set (app, new_window_list);
} else {
window_list.add (app_window);
window_list.add (window);
}
}

foreach (var app in id_to_app.get_values ()) {
Gee.List<AppWindow>? window_list = null;
Gee.List<Window>? window_list = null;
app_window_list.unset (app, out window_list);
app.update_windows (window_list);
}
Expand Down
11 changes: 8 additions & 3 deletions src/AppWindow.vala → src/Window.vala
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
/*
* Copyright 2022 elementary, Inc. <https://elementary.io>
* Copyright 2022, 2025 elementary, Inc. <https://elementary.io>
* Copyright 2022 Corentin Noël <[email protected]>
* SPDX-License-Identifier: GPL-3.0-or-later
*/

public class Dock.AppWindow : GLib.Object {
public class Dock.Window : GLib.Object {
public uint64 uid { get; construct set; }

public string app_id { get; private set; default = ""; }
public bool has_focus { get; private set; default = false; }
public bool on_active_workspace { get; private set; default = false; }

public AppWindow (uint64 uid) {
public Window (uint64 uid) {
Object (uid: uid);
}

public void update_properties (GLib.HashTable<string, Variant> properties) {
if ("app-id" in properties) {
app_id = properties["app-id"].get_string ();
}

if ("has-focus" in properties) {
has_focus = (bool) properties["has-focus"];
}
Expand Down
67 changes: 67 additions & 0 deletions src/WindowSystem.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* SPDX-License-Identifier: GPL-3.0
* SPDX-FileCopyrightText: 2025 elementary, Inc. (https://elementary.io)
*/

public class Dock.WindowSystem : Object {
private static GLib.Once<WindowSystem> instance;
public static unowned WindowSystem get_default () {
return instance.once (() => { return new WindowSystem (); });
}

public DesktopIntegration? desktop_integration { get; private set; }
public Gee.List<Window> windows { get; private owned set; }

private WindowSystem () {}

construct {
windows = new Gee.LinkedList<Window> ();
load.begin ();
}

private async void load () {
try {
desktop_integration = yield GLib.Bus.get_proxy<Dock.DesktopIntegration> (
SESSION,
"org.pantheon.gala",
"/org/pantheon/gala/DesktopInterface"
);

yield sync_windows ();

desktop_integration.windows_changed.connect (sync_windows);
} catch (Error e) {
critical ("Failed to get desktop integration: %s", e.message);
}
}

private Window? find_window (uint64 uid) {
return windows.first_match ((win) => {
return win.uid == uid;
});
}

private async void sync_windows () requires (desktop_integration != null) {
DesktopIntegration.Window[] di_windows;
try {
di_windows = yield desktop_integration.get_windows ();
} catch (Error e) {
critical (e.message);
return;
}

var new_windows = new Gee.LinkedList<Window> ();
foreach (unowned var di_window in di_windows) {
var window = find_window (di_window.uid);
if (window == null) {
window = new Window (di_window.uid);
}

window.update_properties (di_window.properties);

new_windows.add (window);
}

windows = new_windows;
}
}
3 changes: 2 additions & 1 deletion src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ sources = [
'App.vala',
'AppSystem.vala',
'Application.vala',
'AppWindow.vala',
'DesktopIntegration.vala',
'ItemManager.vala',
'Launcher.vala',
'MainWindow.vala',
'PoofPopover.vala',
'Window.vala',
'WindowSystem.vala',
'DBus' / 'ItemInterface.vala',
'DBus' / 'ShellKeyGrabber.vala',
'DBus' / 'SwitcherooControl.vala',
Expand Down