mirror of
https://github.com/elementary/gala.git
synced 2024-11-26 00:04:27 +03:00
wayland: Launch notifications server as a wayland client (#1882)
This commit is contained in:
parent
4c6f503b31
commit
0e88796b96
@ -34,4 +34,10 @@ namespace Gala {
|
||||
// Duration of the nudge animation when trying to switch to at the end of the workspace list
|
||||
NUDGE = 360,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used as a key for Object.set_data<bool> on Meta.Windows that should be
|
||||
* treated as notifications. Has to be set before the window is mapped.
|
||||
*/
|
||||
public const string NOTIFICATION_DATA_KEY = "elementary-notification";
|
||||
}
|
||||
|
76
src/ShellClients/ManagedClient.vala
Normal file
76
src/ShellClients/ManagedClient.vala
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2024 elementary, Inc. (https://elementary.io)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Authored by: Leonhard Kargl <leo.kargl@proton.me>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Utility class that takes care of launching and restarting a subprocess.
|
||||
* On wayland this uses a WaylandClient and emits window_created if a window for the client was created.
|
||||
* On X this just launches a normal subprocess and never emits window_created.
|
||||
*/
|
||||
public class Gala.ManagedClient : Object {
|
||||
public signal void window_created (Meta.Window window);
|
||||
|
||||
public Meta.Display display { get; construct; }
|
||||
public string[] args { get; construct; }
|
||||
|
||||
public Meta.WaylandClient? wayland_client { get; private set; }
|
||||
|
||||
public ManagedClient (Meta.Display display, string[] args) {
|
||||
Object (display: display, args: args);
|
||||
}
|
||||
|
||||
construct {
|
||||
if (Meta.Util.is_wayland_compositor ()) {
|
||||
start_wayland.begin ();
|
||||
|
||||
display.window_created.connect ((window) => {
|
||||
if (wayland_client != null && wayland_client.owns_window (window)) {
|
||||
window_created (window);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
start_x.begin ();
|
||||
}
|
||||
}
|
||||
|
||||
private async void start_wayland () {
|
||||
var subprocess_launcher = new GLib.SubprocessLauncher (STDERR_PIPE | STDOUT_PIPE);
|
||||
try {
|
||||
#if HAS_MUTTER44
|
||||
wayland_client = new Meta.WaylandClient (display.get_context (), subprocess_launcher);
|
||||
#else
|
||||
wayland_client = new Meta.WaylandClient (subprocess_launcher);
|
||||
#endif
|
||||
var subprocess = wayland_client.spawnv (display, args);
|
||||
|
||||
yield subprocess.wait_async ();
|
||||
|
||||
//Restart the daemon if it crashes
|
||||
Timeout.add_seconds (1, () => {
|
||||
start_wayland.begin ();
|
||||
return Source.REMOVE;
|
||||
});
|
||||
} catch (Error e) {
|
||||
warning ("Failed to create dock client: %s", e.message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private async void start_x () {
|
||||
try {
|
||||
var subprocess = new Subprocess.newv (args, NONE);
|
||||
yield subprocess.wait_async ();
|
||||
|
||||
//Restart the daemon if it crashes
|
||||
Timeout.add_seconds (1, () => {
|
||||
start_x.begin ();
|
||||
return Source.REMOVE;
|
||||
});
|
||||
} catch (Error e) {
|
||||
warning ("Failed to create daemon subprocess with x: %s", e.message);
|
||||
}
|
||||
}
|
||||
}
|
28
src/ShellClients/NotificationsClient.vala
Normal file
28
src/ShellClients/NotificationsClient.vala
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2024 elementary, Inc. (https://elementary.io)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Authored by: Leonhard Kargl <leo.kargl@proton.me>
|
||||
*/
|
||||
|
||||
public class Gala.NotificationsClient : Object {
|
||||
public Meta.Display display { get; construct; }
|
||||
|
||||
private ManagedClient client;
|
||||
|
||||
public NotificationsClient (Meta.Display display) {
|
||||
Object (display: display);
|
||||
}
|
||||
|
||||
construct {
|
||||
client = new ManagedClient (display, { "io.elementary.notifications" });
|
||||
|
||||
client.window_created.connect ((window) => {
|
||||
window.set_data (NOTIFICATION_DATA_KEY, true);
|
||||
window.make_above ();
|
||||
#if HAS_MUTTER_46
|
||||
client.wayland_client.make_dock (window);
|
||||
#endif
|
||||
});
|
||||
}
|
||||
}
|
20
src/ShellClients/ShellClientsManager.vala
Normal file
20
src/ShellClients/ShellClientsManager.vala
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2024 elementary, Inc. (https://elementary.io)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Authored by: Leonhard Kargl <leo.kargl@proton.me>
|
||||
*/
|
||||
|
||||
public class Gala.ShellClientsManager : Object {
|
||||
public Meta.Display display { get; construct; }
|
||||
|
||||
private NotificationsClient notifications_client;
|
||||
|
||||
public ShellClientsManager (Meta.Display display) {
|
||||
Object (display: display);
|
||||
}
|
||||
|
||||
construct {
|
||||
notifications_client = new NotificationsClient (display);
|
||||
}
|
||||
}
|
@ -83,6 +83,8 @@ namespace Gala {
|
||||
|
||||
private DaemonManager daemon_manager;
|
||||
|
||||
private ShellClientsManager shell_clients_manager;
|
||||
|
||||
private WindowGrabTracker window_grab_tracker;
|
||||
|
||||
private NotificationStack notification_stack;
|
||||
@ -143,6 +145,7 @@ namespace Gala {
|
||||
}
|
||||
|
||||
public override void start () {
|
||||
shell_clients_manager = new ShellClientsManager (get_display ());
|
||||
daemon_manager = new DaemonManager (get_display ());
|
||||
window_grab_tracker = new WindowGrabTracker (get_display ());
|
||||
|
||||
@ -1446,10 +1449,20 @@ namespace Gala {
|
||||
move_window_to_next_ws (window);
|
||||
}
|
||||
|
||||
actor.remove_all_transitions ();
|
||||
actor.show ();
|
||||
|
||||
// Notifications are a special case and have to be always be handled
|
||||
// regardless of the animation setting
|
||||
if (!enable_animations && window.window_type != Meta.WindowType.NOTIFICATION) {
|
||||
actor.show ();
|
||||
// (also regardless of the animation setting)
|
||||
if (window.get_data (NOTIFICATION_DATA_KEY) || window.window_type == NOTIFICATION) {
|
||||
clutter_actor_reparent (actor, notification_group);
|
||||
notification_stack.show_notification (actor, enable_animations);
|
||||
|
||||
map_completed (actor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!enable_animations) {
|
||||
map_completed (actor);
|
||||
|
||||
if (InternalUtils.get_window_is_normal (window) && window.get_layer () == Meta.StackLayer.BOTTOM) {
|
||||
@ -1459,9 +1472,6 @@ namespace Gala {
|
||||
return;
|
||||
}
|
||||
|
||||
actor.remove_all_transitions ();
|
||||
actor.show ();
|
||||
|
||||
switch (window.window_type) {
|
||||
case Meta.WindowType.NORMAL:
|
||||
var duration = AnimationDuration.HIDE;
|
||||
@ -1558,12 +1568,6 @@ namespace Gala {
|
||||
|
||||
dim_parent_window (window);
|
||||
|
||||
break;
|
||||
case Meta.WindowType.NOTIFICATION:
|
||||
clutter_actor_reparent (actor, notification_group);
|
||||
notification_stack.show_notification (actor, enable_animations);
|
||||
map_completed (actor);
|
||||
|
||||
break;
|
||||
default:
|
||||
map_completed (actor);
|
||||
@ -1576,7 +1580,30 @@ namespace Gala {
|
||||
|
||||
ws_assoc.remove (window);
|
||||
|
||||
if (!enable_animations && window.window_type != Meta.WindowType.NOTIFICATION) {
|
||||
actor.remove_all_transitions ();
|
||||
|
||||
if (window.get_data (NOTIFICATION_DATA_KEY) || window.window_type == NOTIFICATION) {
|
||||
if (enable_animations) {
|
||||
destroying.add (actor);
|
||||
}
|
||||
|
||||
notification_stack.destroy_notification (actor, enable_animations);
|
||||
|
||||
if (enable_animations) {
|
||||
ulong destroy_handler_id = 0UL;
|
||||
destroy_handler_id = actor.transitions_completed.connect (() => {
|
||||
actor.disconnect (destroy_handler_id);
|
||||
destroying.remove (actor);
|
||||
destroy_completed (actor);
|
||||
});
|
||||
} else {
|
||||
destroy_completed (actor);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!enable_animations) {
|
||||
destroy_completed (actor);
|
||||
|
||||
if (window.window_type == Meta.WindowType.NORMAL) {
|
||||
@ -1586,8 +1613,6 @@ namespace Gala {
|
||||
return;
|
||||
}
|
||||
|
||||
actor.remove_all_transitions ();
|
||||
|
||||
switch (window.window_type) {
|
||||
case Meta.WindowType.NORMAL:
|
||||
var duration = AnimationDuration.CLOSE;
|
||||
@ -1659,25 +1684,6 @@ namespace Gala {
|
||||
destroying.remove (actor);
|
||||
destroy_completed (actor);
|
||||
});
|
||||
break;
|
||||
case Meta.WindowType.NOTIFICATION:
|
||||
if (enable_animations) {
|
||||
destroying.add (actor);
|
||||
}
|
||||
|
||||
notification_stack.destroy_notification (actor, enable_animations);
|
||||
|
||||
if (enable_animations) {
|
||||
ulong destroy_handler_id = 0UL;
|
||||
destroy_handler_id = actor.transitions_completed.connect (() => {
|
||||
actor.disconnect (destroy_handler_id);
|
||||
destroying.remove (actor);
|
||||
destroy_completed (actor);
|
||||
});
|
||||
} else {
|
||||
destroy_completed (actor);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
destroy_completed (actor);
|
||||
|
@ -39,6 +39,9 @@ gala_bin_sources = files(
|
||||
'HotCorners/Barrier.vala',
|
||||
'HotCorners/HotCorner.vala',
|
||||
'HotCorners/HotCornerManager.vala',
|
||||
'ShellClients/ManagedClient.vala',
|
||||
'ShellClients/NotificationsClient.vala',
|
||||
'ShellClients/ShellClientsManager.vala',
|
||||
'Widgets/DwellClickTimer.vala',
|
||||
'Widgets/IconGroup.vala',
|
||||
'Widgets/IconGroupContainer.vala',
|
||||
|
Loading…
Reference in New Issue
Block a user