Skip to content
Merged
6 changes: 3 additions & 3 deletions src/DBus.vala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class Gala.DBus {
private static WindowManagerGala wm;

[DBus (visible = false)]
public static void init (WindowManagerGala _wm) {
public static void init (WindowManagerGala _wm, DBusAccelerator dbus_accelerator, ScreenshotManager screenshot_manager) {
wm = _wm;

Bus.own_name (BusType.SESSION, "org.pantheon.gala", BusNameOwnerFlags.NONE,
Expand All @@ -33,8 +33,8 @@ public class Gala.DBus {
Bus.own_name (BusType.SESSION, "org.gnome.Shell", BusNameOwnerFlags.NONE,
(connection) => {
try {
connection.register_object ("/org/gnome/Shell", DBusAccelerator.init (wm.get_display ()));
connection.register_object ("/org/gnome/Shell/Screenshot", ScreenshotManager.init (wm));
connection.register_object ("/org/gnome/Shell", dbus_accelerator);
connection.register_object ("/org/gnome/Shell/Screenshot", screenshot_manager);
} catch (Error e) { warning (e.message); }
},
() => {},
Expand Down
29 changes: 17 additions & 12 deletions src/DBusAccelerator.vala
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,17 @@ namespace Gala {

[DBus (name="org.gnome.Shell")]
public class DBusAccelerator {
private static DBusAccelerator? instance;

[DBus (visible = false)]
public static unowned DBusAccelerator init (Meta.Display display) {
if (instance == null) {
instance = new DBusAccelerator (display);
}

return instance;
}
private const string NOTIFICATION_COMPONENT_NAME = "DBusAccelerator";

public signal void accelerator_activated (uint action, GLib.HashTable<string, Variant> parameters);

private Meta.Display display;
private NotificationsManager notifications_manager;
private GLib.HashTable<unowned string, GrabbedAccelerator> grabbed_accelerators;

private DBusAccelerator (Meta.Display _display) {
public DBusAccelerator (Meta.Display _display, NotificationsManager _notifications_manager) {
display = _display;
notifications_manager = _notifications_manager;
grabbed_accelerators = new HashTable<unowned string, GrabbedAccelerator> (str_hash, str_equal);
display.accelerator_activated.connect (on_accelerator_activated);
}
Expand Down Expand Up @@ -176,7 +169,19 @@ namespace Gala {
level = (int)(double_level * 100);
}

MediaFeedback.send (icon, level);
var hints = new GLib.HashTable<string, Variant> (null, null);
hints.set ("x-canonical-private-synchronous", new Variant.string ("gala-feedback"));
hints.set ("value", new Variant.int32 (level));

notifications_manager.send (
new NotificationsManager.NotificationData (
NOTIFICATION_COMPONENT_NAME,
label,
"",
icon,
hints
)
);
}
}
}
107 changes: 0 additions & 107 deletions src/MediaFeedback.vala

This file was deleted.

121 changes: 121 additions & 0 deletions src/NotificationsManager.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2016 Rico Tzschichholz
* 2025 elementary, Inc. (https://elementary.io)
*/

/**
* Gala.NotificationsManager can be used to send notifications to org.freedesktop.Notifications
*/
public class Gala.NotificationsManager : GLib.Object {
[DBus (name = "org.freedesktop.Notifications")]
private interface DBusNotifications : GLib.Object {
public abstract uint32 notify (string app_name, uint32 replaces_id, string app_icon, string summary,
string body, string[] actions, HashTable<string, Variant> hints, int32 expire_timeout) throws DBusError, IOError;
}

private const int EXPIRE_TIMEOUT = 2000;

/**
* Data structure to hold notification data. Component name is used to correctly replace notifications.
*/
[Compact]
public class NotificationData {
public string component_name;
public string summary;
public string body;
public string icon;
public GLib.HashTable<string, Variant> hints;

public NotificationData (
string _component_name,
string _summary,
string _body,
string _icon,
GLib.HashTable<string, Variant> _hints
) {
component_name = _component_name;
summary = _summary;
body = _body;
icon = _icon;
hints = _hints;
}
}

private ThreadPool<NotificationData>? pool = null;
private DBusNotifications? notifications = null;
private GLib.HashTable<string, uint32> replaces_id_table = new GLib.HashTable<string, uint32> (str_hash, str_equal);

construct {
try {
pool = new ThreadPool<NotificationData>.with_owned_data (send_feedback, 1, false);
} catch (ThreadError e) {
warning (e.message);
pool = null;
}

try {
Bus.watch_name (BusType.SESSION, "org.freedesktop.Notifications", BusNameWatcherFlags.NONE, on_watch, on_unwatch);
} catch (IOError e) {
warning (e.message);
}
}

private void on_watch (DBusConnection conn) {
conn.get_proxy.begin<DBusNotifications> (
"org.freedesktop.Notifications", "/org/freedesktop/Notifications", DBusProxyFlags.NONE, null,
(obj, res) => {
try {
notifications = ((DBusConnection) obj).get_proxy.end<DBusNotifications> (res);
} catch (Error e) {
warning (e.message);
notifications = null;
}
}
);
}

private void on_unwatch (DBusConnection conn) {
notifications = null;
}

public void send (owned NotificationData notification_data) {
if (pool == null) {
return;
}

try {
pool.add ((owned) notification_data);
} catch (ThreadError e) {
warning ("NotificationsManager: could't add notificationData: %s", e.message);
}
}

private void send_feedback (owned NotificationData notification_data) {
if (notifications == null) {
return;
}

uint32? replaces_id = replaces_id_table.get (notification_data.component_name);
if (replaces_id == null) {
replaces_id = 0;
}

try {
var notification_id = notifications.notify (
"gala-feedback",
replaces_id,
notification_data.icon,
notification_data.summary,
notification_data.body,
{},
notification_data.hints,
EXPIRE_TIMEOUT
);

replaces_id_table.insert (notification_data.component_name, notification_id);
} catch (Error e) {
critical (e.message);
}
}
}
19 changes: 5 additions & 14 deletions src/ScreenshotManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,6 @@ namespace Gala {

[DBus (name="org.gnome.Shell.Screenshot")]
public class ScreenshotManager : Object {
private static ScreenshotManager? instance;

[DBus (visible = false)]
public static unowned ScreenshotManager init (WindowManager wm) {
if (instance == null)
instance = new ScreenshotManager (wm);

return instance;
}

private WindowManager wm;
private Settings desktop_settings;

Expand All @@ -39,12 +29,13 @@ namespace Gala {
private string prev_font_mono;
private uint conceal_timeout;

construct {
desktop_settings = new Settings ("org.gnome.desktop.interface");
[DBus (visible = false)]
public ScreenshotManager (WindowManager _wm) {
wm = _wm;
}

private ScreenshotManager (WindowManager _wm) {
wm = _wm;
construct {
desktop_settings = new Settings ("org.gnome.desktop.interface");
}

public void flash_area (int x, int y, int width, int height) throws DBusError, IOError {
Expand Down
17 changes: 10 additions & 7 deletions src/WindowManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ namespace Gala {

public WindowTracker? window_tracker { get; private set; }

private NotificationsManager notifications_manager;

private DBusAccelerator dbus_accelerator;

private ScreenshotManager screenshot_manager;

/**
* Allow to zoom in/out the entire desktop.
*/
Expand Down Expand Up @@ -187,9 +193,10 @@ namespace Gala {
private void show_stage () {
unowned Meta.Display display = get_display ();

DBus.init (this);
DBusAccelerator.init (display);
MediaFeedback.init ();
notifications_manager = new NotificationsManager ();
screenshot_manager = new ScreenshotManager (this);
dbus_accelerator = new DBusAccelerator (display, notifications_manager);
DBus.init (this, dbus_accelerator, screenshot_manager);

WindowListener.init (display);
KeyboardManager.init (display);
Expand Down Expand Up @@ -2317,7 +2324,6 @@ namespace Gala {
string filename = clipboard ? "" : generate_screenshot_filename ();
bool success = false;
string filename_used = "";
unowned var screenshot_manager = ScreenshotManager.init (this);
yield screenshot_manager.screenshot_window (true, false, true, filename, out success, out filename_used);
} catch (Error e) {
// Ignore this error
Expand All @@ -2330,8 +2336,6 @@ namespace Gala {
bool success = false;
string filename_used = "";

unowned var screenshot_manager = ScreenshotManager.init (this);

int x, y, w, h;
yield screenshot_manager.select_area (out x, out y, out w, out h);
yield screenshot_manager.screenshot_area (x, y, w, h, true, filename, out success, out filename_used);
Expand All @@ -2345,7 +2349,6 @@ namespace Gala {
string filename = clipboard ? "" : generate_screenshot_filename ();
bool success = false;
string filename_used = "";
unowned var screenshot_manager = ScreenshotManager.init (this);
yield screenshot_manager.screenshot (false, true, filename, out success, out filename_used);
} catch (Error e) {
// Ignore this error
Expand Down
2 changes: 1 addition & 1 deletion src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ gala_bin_sources = files(
'InternalUtils.vala',
'KeyboardManager.vala',
'Main.vala',
'MediaFeedback.vala',
'NotificationsManager.vala',
'NotificationStack.vala',
'PantheonShell.vala',
'PluginManager.vala',
Expand Down
Loading