From 9d83c0054e849ff7a8a68a12f8fa8d90ccac1270 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:54:28 +0200 Subject: [PATCH 01/22] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 701f054cf..14a3a3a81 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ You can set the `documentation` option to `true` to build the documentation. In To install, run `ninja install`, then based on your session type do the following: - **Wayland**: Log out and log back in (or reboot) to start the newly installed Gala. (`gala --replace` is not supported for an already running Wayland session.) -- **X11**: run `gala --replace` to replace the running Gala. +- **X11**: Support for X11 was dropped in OS9 ### Running the tests From 9e80eab40d291bd3b9422b4e827fffd9fc9820a7 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 18:04:24 +0200 Subject: [PATCH 02/22] Main: Guard against launching as X WM --- src/Main.vala | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Main.vala b/src/Main.vala index 420e33b7b..56b9b3c3d 100644 --- a/src/Main.vala +++ b/src/Main.vala @@ -76,6 +76,14 @@ namespace Gala { try { ctx.start (); + +#if !HAS_MUTTER50 + if (ctx.get_compositor_type () != WAYLAND) { + critical ("Gala only supports Wayland"); + return Posix.EXIT_FAILURE; + } +#endif + #if HAS_MUTTER50 if (true) { #else From 5e22dc7fa6e9f4dc88af88d1e169ed08138ad7bf Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 18:04:52 +0200 Subject: [PATCH 03/22] Main: Always init pantheon shell --- src/Main.vala | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Main.vala b/src/Main.vala index 56b9b3c3d..3b307ec0f 100644 --- a/src/Main.vala +++ b/src/Main.vala @@ -84,13 +84,7 @@ namespace Gala { } #endif -#if HAS_MUTTER50 - if (true) { -#else - if (ctx.get_compositor_type () == Meta.CompositorType.WAYLAND) { -#endif - Gala.init_pantheon_shell (ctx); - } + Gala.init_pantheon_shell (ctx); } catch (Error e) { stderr.printf ("Failed to start: %s\n", e.message); return Posix.EXIT_FAILURE; From 31530fc166b47ea2555bebb78158a0413c0f2e68 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:11:25 +0200 Subject: [PATCH 04/22] ManagedClient: Drop X11 support --- src/ShellClients/ManagedClient.vala | 81 +++++++---------------------- 1 file changed, 20 insertions(+), 61 deletions(-) diff --git a/src/ShellClients/ManagedClient.vala b/src/ShellClients/ManagedClient.vala index 712935e6a..ff9df3e08 100644 --- a/src/ShellClients/ManagedClient.vala +++ b/src/ShellClients/ManagedClient.vala @@ -8,7 +8,6 @@ /** * 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); @@ -31,42 +30,34 @@ public class Gala.ManagedClient : Object { construct { instances.add (this); - 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); - - // We have to manage is alive manually since windows created by WaylandClients have our pid - // and we don't want to end our own process - window.notify["is-alive"].connect (() => { - if (!window.is_alive && subprocess != null) { - subprocess.force_exit (); - warning ("WaylandClient window became unresponsive, killing the client."); - } - }); - } - }); - } else { - start_x.begin (); - } + start_wayland.begin (); + + display.window_created.connect ((window) => { + if (wayland_client != null && wayland_client.owns_window (window)) { + window_created (window); + + // We have to manage is alive manually since windows created by WaylandClients have our pid + // and we don't want to end our own process + window.notify["is-alive"].connect (() => { + if (!window.is_alive && subprocess != null) { + subprocess.force_exit (); + warning ("WaylandClient window became unresponsive, killing the client."); + } + }); + } + }); } public static void make_dock (Meta.Window window) { #if HAS_MUTTER49 window.set_type (Meta.WindowType.DOCK); #else - if (Meta.Util.is_wayland_compositor ()) { - make_dock_wayland (window); - } else { - make_dock_x11 (window); - } + make_dock_wayland (window); #endif } #if !HAS_MUTTER49 - private static void make_dock_wayland (Meta.Window window) requires (Meta.Util.is_wayland_compositor ()) { + private static void make_dock_wayland (Meta.Window window) { foreach (var client in instances) { if (client.wayland_client.owns_window (window)) { client.wayland_client.make_dock (window); @@ -74,35 +65,18 @@ public class Gala.ManagedClient : Object { } } } - - private static void make_dock_x11 (Meta.Window window) requires (!Meta.Util.is_wayland_compositor ()) { - unowned var x11_display = window.display.get_x11_display (); - - var x_window = x11_display.lookup_xwindow (window); - // gtk3's gdk_x11_window_set_type_hint() is used as a reference - unowned var xdisplay = x11_display.get_xdisplay (); - var atom = xdisplay.intern_atom ("_NET_WM_WINDOW_TYPE", false); - var dock_atom = xdisplay.intern_atom ("_NET_WM_WINDOW_TYPE_DOCK", false); - - // 32 is format - xdisplay.change_property (x_window, atom, X.XA_ATOM, 32, X.PropMode.Replace, (uchar[]) dock_atom, 1); - } #endif public static void make_desktop (Meta.Window window) { #if HAS_MUTTER49 window.set_type (Meta.WindowType.DESKTOP); #else - if (Meta.Util.is_wayland_compositor ()) { - make_desktop_wayland (window); - } else { - critical ("Making desktop window on X11 is not supported."); - } + make_desktop_wayland (window); #endif } #if !HAS_MUTTER49 - private static void make_desktop_wayland (Meta.Window window) requires (Meta.Util.is_wayland_compositor ()) { + private static void make_desktop_wayland (Meta.Window window) { foreach (var client in instances) { if (client.wayland_client.owns_window (window)) { client.wayland_client.make_desktop (window); @@ -135,19 +109,4 @@ public class Gala.ManagedClient : Object { return; } } - - private async void start_x () { - try { - 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); - } - } } From 123ad643bd1df4bf84d4a4907a59a2635dc92bfe Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:37:28 +0200 Subject: [PATCH 05/22] DaemonManager: Drop gtk3 daemon args --- src/Misc/DaemonManager.vala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Misc/DaemonManager.vala b/src/Misc/DaemonManager.vala index ff22aec81..62e67ee6c 100644 --- a/src/Misc/DaemonManager.vala +++ b/src/Misc/DaemonManager.vala @@ -28,8 +28,7 @@ public class Gala.DaemonManager : GLib.Object { construct { Bus.watch_name (BusType.SESSION, DAEMON_DBUS_NAME, BusNameWatcherFlags.NONE, daemon_appeared, lost_daemon); - string[] args = { Meta.Util.is_wayland_compositor () ? "gala-daemon" : "gala-daemon-gtk3" }; - client = new ManagedClient (display, args); + client = new ManagedClient (display, { "gala-daemon" }); client.window_created.connect ((window) => { ManagedClient.make_dock (window); From 501f4d1da706156be07dac446cb32b81e7ead006 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:49:20 +0200 Subject: [PATCH 06/22] ShellClientsManager: Drop parse mutter hints --- src/ShellClients/ShellClientsManager.vala | 111 ---------------------- 1 file changed, 111 deletions(-) diff --git a/src/ShellClients/ShellClientsManager.vala b/src/ShellClients/ShellClientsManager.vala index bab8534ae..b5bc6e826 100644 --- a/src/ShellClients/ShellClientsManager.vala +++ b/src/ShellClients/ShellClientsManager.vala @@ -43,13 +43,6 @@ public class Gala.ShellClientsManager : Object, GestureTarget { start_clients.begin (); - if (!Meta.Util.is_wayland_compositor ()) { - wm.get_display ().window_created.connect ((window) => { - window.notify["mutter-hints"].connect ((obj, pspec) => parse_mutter_hints ((Meta.Window) obj)); - parse_mutter_hints (window); - }); - } - Timeout.add_seconds_once (5, on_failsafe_timeout); } @@ -309,110 +302,6 @@ public class Gala.ShellClientsManager : Object, GestureTarget { return positioned_windows[window].dim; } - //X11 only - private void parse_mutter_hints (Meta.Window window) requires (!Meta.Util.is_wayland_compositor ()) { - if (window.mutter_hints == null) { - return; - } - - var mutter_hints = window.mutter_hints.split (":"); - foreach (var mutter_hint in mutter_hints) { - var split = mutter_hint.split ("="); - - if (split.length != 2) { - continue; - } - - var key = split[0]; - var val = split[1]; - - switch (key) { - case "anchor": - int meta_side_parsed; // Will be used as Meta.Side which is a 4 value bitfield so check bounds for that - if (int.try_parse (val, out meta_side_parsed) && 0 <= meta_side_parsed && meta_side_parsed <= 15) { - //FIXME: Next major release change dock and wingpanel calls to get rid of this - Pantheon.Desktop.Anchor parsed = TOP; - switch ((Meta.Side) meta_side_parsed) { - case BOTTOM: - parsed = BOTTOM; - break; - - case LEFT: - parsed = LEFT; - break; - - case RIGHT: - parsed = RIGHT; - break; - - default: - break; - } - - set_anchor (window, parsed); - // We need to set a second time because the intention is to call this before the window is shown which it is on wayland - // but on X the window was already shown when we get here so we have to call again to instantly apply it. - set_anchor (window, parsed); - } else { - warning ("Failed to parse %s as anchor", val); - } - break; - - case "hide-mode": - int parsed; // Will be used as Pantheon.Desktop.HideMode which is a 5 value enum so check bounds for that - if (int.try_parse (val, out parsed) && 0 <= parsed && parsed <= 4) { - set_hide_mode (window, parsed); - } else { - warning ("Failed to parse %s as hide mode", val); - } - break; - - case "size": - var split_val = val.split (","); - if (split_val.length != 2) { - break; - } - int parsed_width, parsed_height = 0; //set to 0 because vala doesn't realize height will be set too - if (int.try_parse (split_val[0], out parsed_width) && int.try_parse (split_val[1], out parsed_height)) { - set_size (window, parsed_width, parsed_height); - } else { - warning ("Failed to parse %s as width and height", val); - } - break; - - case "visible-in-multitasking-view": - request_visible_in_multitasking_view (window); - break; - - case "centered": - make_centered (window); - break; - - case "restore-previous-region": - set_restore_previous_x11_region (window); - break; - - case "monitor-label": - int parsed; - if (int.try_parse (val, out parsed)) { - make_monitor_label (window, parsed); - } else { - warning ("Failed to parse %s as monitor label", val); - } - break; - - default: - break; - } - } - } - - private void set_restore_previous_x11_region (Meta.Window window) - requires (!Meta.Util.is_wayland_compositor ()) - requires (window in panel_windows) { - panel_windows[window].restore_previous_x11_region = true; - } - public Mtk.Rectangle? get_shell_client_rect () { foreach (var client in panel_windows.get_values ()) { if (client.visible_in_multitasking_view) { From 7a2fdc19e141d1a363944e8c2b49ad619ea1524e Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:39:28 +0200 Subject: [PATCH 07/22] WindowManager: Drop input area management --- src/InternalUtils.vala | 81 ------------------------------------------ src/WindowManager.vala | 37 ------------------- 2 files changed, 118 deletions(-) diff --git a/src/InternalUtils.vala b/src/InternalUtils.vala index 25f30d0c1..e2f28ac45 100644 --- a/src/InternalUtils.vala +++ b/src/InternalUtils.vala @@ -6,88 +6,7 @@ */ namespace Gala { - public enum InputArea { - NONE, - FULLSCREEN, - MULTITASKING_VIEW, - DEFAULT - } - public class InternalUtils { - /** - * set the area where clutter can receive events - **/ - public static void set_input_area (Meta.Display display, InputArea area) { -#if !HAS_MUTTER50 - if (Meta.Util.is_wayland_compositor ()) { - return; - } - - X.Xrectangle[] rects = {}; - - switch (area) { - case InputArea.FULLSCREEN: - int width, height; - display.get_size (out width, out height); - - X.Xrectangle rect = {0, 0, (ushort)width, (ushort)height}; - rects = {rect}; - break; - - case InputArea.MULTITASKING_VIEW: - var shell_client_rect = ShellClientsManager.get_instance ().get_shell_client_rect (); - - int width, height; - display.get_size (out width, out height); - - if (shell_client_rect != null) { - X.Xrectangle left_rect = {0, 0, (ushort) shell_client_rect.x, (ushort) height}; - X.Xrectangle right_rect = { - (short) (shell_client_rect.x + shell_client_rect.width), 0, - (ushort) (width - shell_client_rect.x - shell_client_rect.width), (ushort) height - }; - X.Xrectangle top_rect = { - (short) shell_client_rect.x, 0, - (ushort) shell_client_rect.width, (ushort) shell_client_rect.y - }; - X.Xrectangle bottom_rect = { - (short) shell_client_rect.x, - (short) (shell_client_rect.y + shell_client_rect.height), - (ushort) shell_client_rect.width, - (ushort) (height - shell_client_rect.y - shell_client_rect.height) - }; - rects = {left_rect, right_rect, top_rect, bottom_rect}; - } else { - X.Xrectangle rect = {0, 0, (ushort)width, (ushort)height}; - rects = {rect}; - } - - break; - - case InputArea.DEFAULT: - // add plugin's requested areas - foreach (var rect in PluginManager.get_default ().get_regions ()) { - rects += rect; - } - - break; - - case InputArea.NONE: - default: - rects = {}; - break; - } - - unowned Meta.X11Display x11display = display.get_x11_display (); -#if HAS_MUTTER47 - x11display.set_stage_input_region (rects); -#else - var xregion = X.Fixes.create_region (x11display.get_xdisplay (), rects); - x11display.set_stage_input_region (xregion); -#endif -#endif - } - /** * Inserts a workspace at the given index. To ensure the workspace is not immediately * removed again when in dynamic workspaces, the window is first placed on it. diff --git a/src/WindowManager.vala b/src/WindowManager.vala index 5543b36ae..16b3fdcbe 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -206,7 +206,6 @@ namespace Gala { // plugin manager unowned var plugin_manager = PluginManager.get_default (); plugin_manager.initialize (this); - plugin_manager.regions_changed.connect (update_input_area); /* Then once we have the layout structures that we expose to widgets and initialized the plugins, init the rest of the UI */ @@ -215,10 +214,6 @@ namespace Gala { lock_screen_manager = new LockScreenManager (layout_manager.lock_screen); screensaver = new ScreenSaverManager (layout_manager.session_locker); - // Due to a bug which enables access to the stage when using multiple monitors - // in the screensaver, we have to listen for changes and make sure the input area - // is set to NONE when we are in locked mode - screensaver.active_changed.connect (update_input_area); /*keybindings*/ var keybinding_settings = new GLib.Settings ("io.elementary.desktop.wm.keybindings"); @@ -266,13 +261,10 @@ namespace Gala { } hot_corner_manager = new HotCornerManager (this, behavior_settings); - hot_corner_manager.on_configured.connect (update_input_area); hot_corner_manager.configure (); zoom = new Zoom (this); - update_input_area (); - var scroll_action = new SuperScrollAction (display); scroll_action.triggered.connect (handle_super_scroll); stage.add_action_full ("wm-super-scroll-action", CAPTURE, scroll_action); @@ -438,31 +430,6 @@ namespace Gala { layout_manager.multitasking_view.switch_to_next_workspace (direction); } - private void update_input_area () { - unowned Meta.Display display = get_display (); - - if (screensaver != null) { - try { - if (screensaver.get_active ()) { - InternalUtils.set_input_area (display, InputArea.NONE); - return; - } - } catch (Error e) { - // the screensaver object apparently won't be null even though - // it is unavailable. This error will be thrown however, so we - // can just ignore it, because if it is thrown, the screensaver - // is unavailable. - } - } - - if (is_modal ()) { - var area = layout_manager.multitasking_view.opened ? InputArea.MULTITASKING_VIEW : InputArea.FULLSCREEN; - InternalUtils.set_input_area (display, area); - } else { - InternalUtils.set_input_area (display, InputArea.DEFAULT); - } - } - /** * {@inheritDoc} */ @@ -510,8 +477,6 @@ namespace Gala { return proxy; } - update_input_area (); - #if HAS_MUTTER48 get_display ().get_compositor ().disable_unredirect (); #else @@ -539,8 +504,6 @@ namespace Gala { return; } - update_input_area (); - unowned var display = get_display (); #if HAS_MUTTER48 display.get_compositor ().enable_unredirect (); From 34545e6cc650552f6dfc9d7d9229e5f80665e731 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:40:58 +0200 Subject: [PATCH 08/22] HotCornerManager: Drop unused on_configured signal and cleanup --- src/HotCorners/HotCornerManager.vala | 8 +++----- src/WindowManager.vala | 1 - 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/HotCorners/HotCornerManager.vala b/src/HotCorners/HotCornerManager.vala index d59c35574..91a838f18 100644 --- a/src/HotCorners/HotCornerManager.vala +++ b/src/HotCorners/HotCornerManager.vala @@ -17,8 +17,6 @@ */ public class Gala.HotCornerManager : Object { - public signal void on_configured (); - public WindowManager wm { get; construct; } public GLib.Settings behavior_settings { get; construct; } @@ -31,9 +29,11 @@ public class Gala.HotCornerManager : Object { behavior_settings.changed.connect (configure); unowned var monitor_manager = wm.get_display ().get_context ().get_backend ().get_monitor_manager (); monitor_manager.monitors_changed.connect (configure); + + configure (); } - public void configure () { + private void configure () { unowned Meta.Display display = wm.get_display (); if (display.get_n_monitors () == 0) { @@ -49,8 +49,6 @@ public class Gala.HotCornerManager : Object { add_hotcorner (geometry.x + geometry.width, geometry.y, scale, HotCorner.POSITION_TOP_RIGHT); add_hotcorner (geometry.x, geometry.y + geometry.height, scale, HotCorner.POSITION_BOTTOM_LEFT); add_hotcorner (geometry.x + geometry.width, geometry.y + geometry.height, scale, HotCorner.POSITION_BOTTOM_RIGHT); - - this.on_configured (); } private void remove_all_hot_corners () { diff --git a/src/WindowManager.vala b/src/WindowManager.vala index 16b3fdcbe..376059299 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -261,7 +261,6 @@ namespace Gala { } hot_corner_manager = new HotCornerManager (this, behavior_settings); - hot_corner_manager.configure (); zoom = new Zoom (this); From 36445fbb9469b72312a25bef0cd76dd310ff04dc Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:43:06 +0200 Subject: [PATCH 09/22] PluginManager: Drop input region handling --- src/Misc/PluginManager.vala | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/src/Misc/PluginManager.vala b/src/Misc/PluginManager.vala index aa2ef8334..862b398db 100644 --- a/src/Misc/PluginManager.vala +++ b/src/Misc/PluginManager.vala @@ -12,15 +12,8 @@ public class Gala.PluginManager : Object { public delegate PluginInfo RegisterPluginFunction (); - public signal void regions_changed (); - public bool initialized { get; private set; default = false; } - private X.Xrectangle[] _regions = {}; - public unowned X.Xrectangle[] get_regions () { - return _regions; - } - public string? window_switcher_provider { get; private set; default = null; } private HashTable plugins; @@ -112,13 +105,11 @@ public class Gala.PluginManager : Object { if (initialized) { initialize_plugin (info.module_name, plugin); - recalculate_regions (); } } private void initialize_plugin (string plugin_name, Plugin plugin) { plugin.initialize (wm); - plugin.region_changed.connect (recalculate_regions); } private bool check_provides (string name, PluginFunction provides) { @@ -143,7 +134,6 @@ public class Gala.PluginManager : Object { wm = _wm; plugins.@foreach (initialize_plugin); - recalculate_regions (); initialized = true; } @@ -159,28 +149,4 @@ public class Gala.PluginManager : Object { public Plugin? get_plugin (string id) { return plugins.lookup (id); } - - /** - * Iterate over all plugins and grab their regions, update the regions - * array accordingly and emit the regions_changed signal. - */ - private void recalculate_regions () { - X.Xrectangle[] regions = {}; - - plugins.@foreach ((name, plugin) => { - foreach (var region in plugin.get_region ()) { - X.Xrectangle rect = { - (short) region.x, - (short) region.y, - (ushort) region.width, - (ushort) region.height - }; - - regions += rect; - } - }); - - this._regions = regions; - regions_changed (); - } } From 8e66882be640f6b199299ff551bcbc3869f9c0c6 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:51:15 +0200 Subject: [PATCH 10/22] ShellWindow: Drop special handling for X11 clients regarding input regions --- lib/Utils.vala | 40 ------------------------------- src/ShellClients/ShellWindow.vala | 10 -------- 2 files changed, 50 deletions(-) diff --git a/lib/Utils.vala b/lib/Utils.vala index 20e04e927..ef30924b7 100644 --- a/lib/Utils.vala +++ b/lib/Utils.vala @@ -269,46 +269,6 @@ namespace Gala { ); } - private static HashTable regions = new HashTable (null, null); - - public static void x11_set_window_pass_through (Meta.Window window) { - unowned var x11_display = window.display.get_x11_display (); - - var x_window = x11_display.lookup_xwindow (window); - unowned var xdisplay = x11_display.get_xdisplay (); - - int count, ordering; - regions[window] = X.Shape.get_rectangles (xdisplay, x_window, 2, out count, out ordering)[0]; - - X.Xrectangle rect = {}; - var region = X.Fixes.create_region (xdisplay, {rect}); - - X.Fixes.set_window_shape_region (xdisplay, x_window, 2, 0, 0, region); - - X.Fixes.destroy_region (xdisplay, region); - } - - public static void x11_unset_window_pass_through (Meta.Window window, bool restore_previous_region) { - unowned var x11_display = window.display.get_x11_display (); - - var x_window = x11_display.lookup_xwindow (window); - unowned var xdisplay = x11_display.get_xdisplay (); - - if (restore_previous_region) { - var region = regions[window]; - if (region == null) { - debug ("Cannot unset pass through: window not found."); - return; - } - - X.Shape.combine_rectangles (xdisplay, x_window, 2, 0, 0, { region }, 0, 3); - } else { - X.Fixes.set_window_shape_region (xdisplay, x_window, 2, 0, 0, (X.XserverRegion) 0); - } - - regions.remove (window); - } - /** * Utility that returns the given duration or 0 if animations are disabled. */ diff --git a/src/ShellClients/ShellWindow.vala b/src/ShellClients/ShellWindow.vala index d8bbd548c..b73389c48 100644 --- a/src/ShellClients/ShellWindow.vala +++ b/src/ShellClients/ShellWindow.vala @@ -6,8 +6,6 @@ */ public abstract class Gala.ShellWindow : PositionedWindow, GestureTarget { - public bool restore_previous_x11_region { private get; set; default = false; } - /** * A gesture target that will receive a CUSTOM update every time a gesture * is propagated, with the progress gotten via {@link get_hidden_progress()} @@ -75,14 +73,6 @@ public abstract class Gala.ShellWindow : PositionedWindow, GestureTarget { #endif } - if (!Meta.Util.is_wayland_compositor ()) { - if (window_actor.visible) { - Utils.x11_unset_window_pass_through (window, restore_previous_x11_region); - } else { - Utils.x11_set_window_pass_through (window); - } - } - unowned var manager = ShellClientsManager.get_instance (); window.foreach_transient ((transient) => { if (manager.is_itself_shell_window (transient)) { From 4de276b4efad3098a069a360ebecff40f2c1dcf5 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:13:30 +0200 Subject: [PATCH 11/22] WindowManager: Drop X11 workaround for DND windows --- src/WindowManager.vala | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/WindowManager.vala b/src/WindowManager.vala index 376059299..c6f5a5fb7 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -824,11 +824,6 @@ namespace Gala { ) { layout_manager.change_window_group (actor, MENU); } - - // Workaround for X11 bug: https://github.com/elementary/dock/issues/479 - if (!Meta.Util.is_wayland_compositor () && window.window_type == DND) { - InternalUtils.clutter_actor_reparent (actor, get_display ().get_compositor ().get_feedback_group ()); - } } /* From e2953bd870e6a65f7af509c2f6d2bbfa887d6394 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:14:13 +0200 Subject: [PATCH 12/22] WindowManager: Always start x11 services --- src/WindowManager.vala | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/WindowManager.vala b/src/WindowManager.vala index c6f5a5fb7..3a876bf2a 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -142,12 +142,10 @@ namespace Gala { display.notify["focus-window"].connect (on_focus_window_changed); #if WITH_SYSTEMD - if (Meta.Util.is_wayland_compositor ()) { - display.init_xserver.connect ((task) => { - start_x11_services.begin (task); - return true; - }); - } + display.init_xserver.connect ((task) => { + start_x11_services.begin (task); + return true; + }); #endif } From 4900688d8d4f3d658d873a6cf330d8f9a8f5ed1b Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:45:01 +0200 Subject: [PATCH 13/22] ToucheggBackend: Drop wayland compositor check --- lib/Gestures/Backends/ToucheggBackend.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Gestures/Backends/ToucheggBackend.vala b/lib/Gestures/Backends/ToucheggBackend.vala index 137563024..72456f084 100644 --- a/lib/Gestures/Backends/ToucheggBackend.vala +++ b/lib/Gestures/Backends/ToucheggBackend.vala @@ -181,9 +181,9 @@ private class Gala.ToucheggBackend : Object, GestureBackend { out performed_on_device_type, out elapsed_time); #if HAS_MUTTER49 - if (Meta.Util.is_wayland_compositor () && performed_on_device_type != DeviceType.TOUCHSCREEN) { + if (performed_on_device_type != DeviceType.TOUCHSCREEN) { #else - if (Meta.Util.is_wayland_compositor () && performed_on_device_type != DeviceType.TOUCHSCREEN && type != PINCH) { + if (performed_on_device_type != DeviceType.TOUCHSCREEN && type != PINCH) { #endif return; } From 652eca3ac1be9de920049d8482ad553263ccd697 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:46:21 +0200 Subject: [PATCH 14/22] DragDropAction: drop X11 support --- lib/DragDropAction.vala | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/lib/DragDropAction.vala b/lib/DragDropAction.vala index 8b04692ad..d39bb6400 100644 --- a/lib/DragDropAction.vala +++ b/lib/DragDropAction.vala @@ -193,10 +193,6 @@ namespace Gala { switch (event.get_type ()) { case Clutter.EventType.BUTTON_PRESS: case Clutter.EventType.TOUCH_BEGIN: - if (!is_valid_touch_event (event)) { - return Clutter.EVENT_PROPAGATE; - } - if (grabbed_actor != null) { return Clutter.EVENT_PROPAGATE; } @@ -215,10 +211,6 @@ namespace Gala { case Clutter.EventType.MOTION: case Clutter.EventType.TOUCH_UPDATE: - if (!is_valid_touch_event (event)) { - return Clutter.EVENT_PROPAGATE; - } - if (!clicked) { return Clutter.EVENT_PROPAGATE; } @@ -334,10 +326,6 @@ namespace Gala { case Clutter.EventType.BUTTON_RELEASE: case Clutter.EventType.TOUCH_END: - if (!is_valid_touch_event (event)) { - return Clutter.EVENT_PROPAGATE; - } - if (hovered != null) { finish (); hovered = null; @@ -349,10 +337,6 @@ namespace Gala { case Clutter.EventType.MOTION: case Clutter.EventType.TOUCH_UPDATE: - if (!is_valid_touch_event (event)) { - return Clutter.EVENT_PROPAGATE; - } - float x, y; event.get_coords (out x, out y); @@ -482,17 +466,5 @@ namespace Gala { dragging = false; handle = null; } - - private bool is_valid_touch_event (Clutter.Event event) { - var type = event.get_type (); - - return ( - Meta.Util.is_wayland_compositor () || - type != Clutter.EventType.TOUCH_BEGIN && - type != Clutter.EventType.TOUCH_CANCEL && - type != Clutter.EventType.TOUCH_END && - type != Clutter.EventType.TOUCH_UPDATE - ); - } } } From a2109f5985ad946f1a28e72d584a31c569bb1926 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:48:12 +0200 Subject: [PATCH 15/22] Drop special handling for X11 in fullscreen --- src/InternalUtils.vala | 6 ------ src/ShellClients/HideTracker.vala | 3 +-- src/WindowManager.vala | 7 ------- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/InternalUtils.vala b/src/InternalUtils.vala index e2f28ac45..48ee7687e 100644 --- a/src/InternalUtils.vala +++ b/src/InternalUtils.vala @@ -106,12 +106,6 @@ namespace Gala { #endif } - public static bool get_x11_in_fullscreen (Meta.Display display) { - var primary_monitor = display.get_primary_monitor (); - var is_in_fullscreen = display.get_monitor_in_fullscreen (primary_monitor); - return !Meta.Util.is_wayland_compositor () && is_in_fullscreen; - } - /** * Returns the most recently used "normal" window (as gotten via {@link get_window_is_normal}) in the given workspace. * If there is a not normal but more recent window (e.g. a menu/tooltip) any_window will be set to that window otherwise diff --git a/src/ShellClients/HideTracker.vala b/src/ShellClients/HideTracker.vala index e7fc441cf..527f7f0fd 100644 --- a/src/ShellClients/HideTracker.vala +++ b/src/ShellClients/HideTracker.vala @@ -193,8 +193,7 @@ public class Gala.HideTracker : Object { } private void on_barrier_triggered () { - // Showing panels in fullscreen is broken in X11 - if (InternalUtils.get_x11_in_fullscreen (display) || panel == null) { + if (panel == null) { return; } diff --git a/src/WindowManager.vala b/src/WindowManager.vala index 3a876bf2a..6ca085ce3 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -229,13 +229,6 @@ namespace Gala { display.add_keybinding ("expose-all-windows", keybinding_settings, IGNORE_AUTOREPEAT, layout_manager.window_overview.toggle); display.overlay_key.connect (() => { - // Showing panels in fullscreen is broken in X11 - if (InternalUtils.get_x11_in_fullscreen (display) && - behavior_settings.get_string ("overlay-action") == OPEN_APPLICATIONS_MENU - ) { - return; - } - launch_action (ActionKeys.OVERLAY_ACTION); }); From 95fcf8dd00933199b56ab2ad3098f853e5ff7934 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:52:05 +0200 Subject: [PATCH 16/22] ShellClientsManager: Drop reading launch-on-x --- src/ShellClients/ShellClientsManager.vala | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/ShellClients/ShellClientsManager.vala b/src/ShellClients/ShellClientsManager.vala index b5bc6e826..96ea9ae8e 100644 --- a/src/ShellClients/ShellClientsManager.vala +++ b/src/ShellClients/ShellClientsManager.vala @@ -87,16 +87,6 @@ public class Gala.ShellClientsManager : Object, GestureTarget { } foreach (var group in key_file.get_groups ()) { - if (!Meta.Util.is_wayland_compositor ()) { - try { - if (!key_file.get_boolean (group, "launch-on-x")) { - continue; - } - } catch (Error e) { - warning ("Failed to check whether client should be launched on x, assuming yes: %s", e.message); - } - } - try { var type = key_file.get_string (group, "session-type"); if (type != SessionSettings.get_shell_clients_type ()) { From f0a480a720a9cb6c59570e8bbcad67ad5b36c5de Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:58:42 +0200 Subject: [PATCH 17/22] shell clients config: Drop launch on x key --- data/io.elementary.desktop.wm.shell | 2 -- 1 file changed, 2 deletions(-) diff --git a/data/io.elementary.desktop.wm.shell b/data/io.elementary.desktop.wm.shell index c550db7bf..f0573cba2 100644 --- a/data/io.elementary.desktop.wm.shell +++ b/data/io.elementary.desktop.wm.shell @@ -1,11 +1,9 @@ [io.elementary.wingpanel] -launch-on-x=true args=io.elementary.wingpanel wait-for-n-panels=1 session-type=desktop [io.elementary.dock] -launch-on-x=true args=io.elementary.dock wait-for-n-panels=1 session-type=desktop From 413ee43a64f5f09cd1104dd0d87294bde2c9ed3e Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:53:26 +0200 Subject: [PATCH 18/22] BlurManager: Drop parsing mutter hints --- src/Misc/BlurManager.vala | 51 --------------------------------------- 1 file changed, 51 deletions(-) diff --git a/src/Misc/BlurManager.vala b/src/Misc/BlurManager.vala index 594b75496..f55e6af81 100644 --- a/src/Misc/BlurManager.vala +++ b/src/Misc/BlurManager.vala @@ -38,13 +38,6 @@ public class Gala.BlurManager : Object { Object (wm: wm); } - construct { - wm.get_display ().window_created.connect ((window) => { - window.notify["mutter-hints"].connect ((obj, pspec) => parse_mutter_hints ((Meta.Window) obj)); - parse_mutter_hints (window); - }); - } - /** * Blurs the given region of the given window. */ @@ -112,48 +105,4 @@ public class Gala.BlurManager : Object { add_blur (window, blur_data.left, blur_data.right, blur_data.top, blur_data.bottom, blur_data.clip_radius); } - - //X11 only - private void parse_mutter_hints (Meta.Window window) { - if (window.mutter_hints == null) { - return; - } - - var mutter_hints = window.mutter_hints.split (":"); - foreach (var mutter_hint in mutter_hints) { - var split = mutter_hint.split ("="); - - if (split.length != 2) { - continue; - } - - var key = split[0]; - var val = split[1]; - - switch (key) { - case "blur": - var split_val = val.split (","); - if (split_val.length != 5) { - break; - } - - uint parsed_left = 0, parsed_right = 0, parsed_top = 0, parsed_bottom = 0, parsed_clip_radius = 0; - if ( - uint.try_parse (split_val[0], out parsed_left) && - uint.try_parse (split_val[1], out parsed_right) && - uint.try_parse (split_val[2], out parsed_top) && - uint.try_parse (split_val[3], out parsed_bottom) && - uint.try_parse (split_val[4], out parsed_clip_radius) - ) { - add_blur (window, parsed_left, parsed_right, parsed_top, parsed_bottom, parsed_clip_radius); - } else { - warning ("Failed to parse %s as width and height", val); - } - - break; - default: - break; - } - } - } } From d18cb8d2c65064083208b5199bda181c9efb7ba8 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 17:57:53 +0200 Subject: [PATCH 19/22] Drop X11 systemd target --- data/gala.target | 1 - data/gala@x11.service.in | 40 ---------------------------------------- data/meson.build | 8 -------- 3 files changed, 49 deletions(-) delete mode 100644 data/gala@x11.service.in diff --git a/data/gala.target b/data/gala.target index 059d6ead8..1bb98892a 100644 --- a/data/gala.target +++ b/data/gala.target @@ -7,4 +7,3 @@ PartOf=gnome-session-initialized.target Before=gnome-session-initialized.target Wants=io.elementary.gala@wayland.service -Wants=io.elementary.gala@x11.service diff --git a/data/gala@x11.service.in b/data/gala@x11.service.in deleted file mode 100644 index 88b798ee0..000000000 --- a/data/gala@x11.service.in +++ /dev/null @@ -1,40 +0,0 @@ -[Unit] -Description=Gala on X11 -# On X11, try to show the GNOME Session Failed screen -OnFailure=gnome-session-failed.target -OnFailureJobMode=replace -CollectMode=inactive-or-failed -RefuseManualStart=on -RefuseManualStop=on - -After=gnome-session-manager.target - -Requisite=gnome-session-initialized.target -PartOf=gnome-session-initialized.target -Before=gnome-session-initialized.target - -#NOTE: ConditionEnvironment works with systemd >= 246 -ConditionEnvironment=XDG_SESSION_TYPE=%I - -# Limit startup frequency more than the default -StartLimitIntervalSec=15s -StartLimitBurst=3 - -[Service] -Slice=session.slice -Type=notify -ExecStart=@bindir@/gala - -# On X11 we do not need to unset any variables - -# On X11 we want to restart on-success (Alt+F2 + r) and on-failure. -Restart=always -# Do not wait before restarting the shell -RestartSec=0ms -# Kill any stubborn child processes after this long -TimeoutStopSec=5 - -# Lower down gnome-shell's OOM score to avoid being killed by OOM-killer too early -OOMScoreAdjust=-1000 - - diff --git a/data/meson.build b/data/meson.build index 46bbdf801..a2149ca2c 100644 --- a/data/meson.build +++ b/data/meson.build @@ -55,14 +55,6 @@ if get_option('systemd') unit_conf = configuration_data() unit_conf.set('bindir', bindir) - configure_file( - input: 'gala@x11.service.in', - output: 'io.elementary.gala@x11.service', - install: true, - install_dir: systemd_userunitdir, - configuration: unit_conf - ) - configure_file( input: 'gala@wayland.service.in', output: 'io.elementary.gala@wayland.service', From 153d0b0e4555f3aa42d79849de458d2b04cddc9b Mon Sep 17 00:00:00 2001 From: Leonhard Date: Fri, 14 Aug 2026 18:12:21 +0200 Subject: [PATCH 20/22] Drop GTK3 daemon --- daemon-gtk3/BackgroundMenu.vala | 57 ------------------ daemon-gtk3/DBus.vala | 101 -------------------------------- daemon-gtk3/Main.vala | 49 ---------------- daemon-gtk3/MonitorLabel.vala | 62 -------------------- daemon-gtk3/Window.vala | 51 ---------------- daemon-gtk3/meson.build | 19 ------ meson.build | 1 - po/POTFILES | 6 -- 8 files changed, 346 deletions(-) delete mode 100644 daemon-gtk3/BackgroundMenu.vala delete mode 100644 daemon-gtk3/DBus.vala delete mode 100644 daemon-gtk3/Main.vala delete mode 100644 daemon-gtk3/MonitorLabel.vala delete mode 100644 daemon-gtk3/Window.vala delete mode 100644 daemon-gtk3/meson.build diff --git a/daemon-gtk3/BackgroundMenu.vala b/daemon-gtk3/BackgroundMenu.vala deleted file mode 100644 index 9e9c26453..000000000 --- a/daemon-gtk3/BackgroundMenu.vala +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2024 elementary, Inc. (https://elementary.io) - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -public class Gala.Daemon.BackgroundMenu : Gtk.Menu { - private const string ACTION_GROUP_PREFIX = "background-menu"; - private const string ACTION_PREFIX = ACTION_GROUP_PREFIX + "."; - - construct { - var change_wallpaper = new Gtk.MenuItem.with_label (_("Change Wallpaper…")) { - action_name = ACTION_PREFIX + "launch-uri", - action_target = new Variant.string ("settings://desktop/appearance/wallpaper") - }; - - var display_settings = new Gtk.MenuItem.with_label (_("Display Settings…")) { - action_name = ACTION_PREFIX + "launch-uri", - action_target = new Variant.string ("settings://display") - }; - - - var system_settings = new Gtk.MenuItem.with_label (_("System Settings…")) { - action_name = ACTION_PREFIX + "launch-uri", - action_target = new Variant.string ("settings://") - }; - - append (change_wallpaper); - append (display_settings); - append (new Gtk.SeparatorMenuItem ()); - append (system_settings); - show_all (); - - var launch_action = new SimpleAction ("launch-uri", VariantType.STRING); - launch_action.activate.connect (action_launch); - - var action_group = new SimpleActionGroup (); - action_group.add_action (launch_action); - - insert_action_group (ACTION_GROUP_PREFIX, action_group); - } - - private void action_launch (SimpleAction action, Variant? variant) { - try { - AppInfo.launch_default_for_uri (variant.get_string (), null); - } catch (Error e) { - var message_dialog = new Granite.MessageDialog.with_image_from_icon_name ( - _("Failed to open System Settings"), - _("A handler for the “settings://” URI scheme must be installed."), - "dialog-error", - Gtk.ButtonsType.CLOSE - ); - message_dialog.show_error_details (e.message); - message_dialog.present (); - message_dialog.response.connect (message_dialog.destroy); - } - } -} diff --git a/daemon-gtk3/DBus.vala b/daemon-gtk3/DBus.vala deleted file mode 100644 index f8df4dd6c..000000000 --- a/daemon-gtk3/DBus.vala +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2024 elementary, Inc. (https://elementary.io) - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -public struct Gala.Daemon.MonitorLabelInfo { - public int monitor; - public string label; - public string background_color; - public string text_color; - public int x; - public int y; -} - -[DBus (name = "org.pantheon.gala.daemon")] -public class Gala.Daemon.DBus : GLib.Object { - private Gtk.Menu? window_menu; - private BackgroundMenu? background_menu; - - private List monitor_labels = new List (); - - construct { - load_window_menu.begin (); - } - - private async void load_window_menu () { - DBusConnection connection; - try { - connection = yield Bus.get (SESSION, null); - } catch (Error e) { - warning ("Failed to get DBus connection: %s", e.message); - return; - } - - var menu_model = DBusMenuModel.get (connection, "io.elementary.gala.WindowMenu", "/io/elementary/gala/WindowMenu"); - var action_group = DBusActionGroup.get (connection, "io.elementary.gala.WindowMenu", "/io/elementary/gala/WindowMenu"); - - window_menu = new Gtk.Menu.from_model (menu_model); - window_menu.insert_action_group ("window-menu", action_group); - } - - public void show_window_menu (int display_width, int display_height, int x, int y) throws DBusError, IOError { - show_menu (window_menu, display_width, display_height, x, y, true); - } - - public void show_desktop_menu (int display_width, int display_height, int x, int y) throws DBusError, IOError { - if (background_menu == null) { - background_menu = new BackgroundMenu (); - } - - show_menu (background_menu, display_width, display_height, x, y, false); - } - - private void show_menu (Gtk.Menu menu, int display_width, int display_height, int x, int y, bool ignore_first_release) { - var window = new Window (display_width, display_height); - window.present (); - - menu.attach_to_widget (window.content, null); - - Gdk.Rectangle rect = { - x / window.scale_factor, - y / window.scale_factor, - 0, - 0 - }; - - menu.show_all (); - menu.popup_at_rect (window.get_window (), rect, NORTH, NORTH_WEST); - - menu.deactivate.connect (window.close); - - if (ignore_first_release) { - bool first = true; - menu.button_release_event.connect (() => { - if (first) { - first = false; - return Gdk.EVENT_STOP; - } - - return Gdk.EVENT_PROPAGATE; - }); - } - } - - public void show_monitor_labels (MonitorLabelInfo[] label_infos) throws GLib.DBusError, GLib.IOError { - hide_monitor_labels (); - - monitor_labels = new List (); - foreach (var info in label_infos) { - var label = new MonitorLabel (info); - monitor_labels.append (label); - label.present (); - } - } - - public void hide_monitor_labels () throws GLib.DBusError, GLib.IOError { - foreach (var monitor_label in monitor_labels) { - monitor_label.close (); - } - } -} diff --git a/daemon-gtk3/Main.vala b/daemon-gtk3/Main.vala deleted file mode 100644 index d2ffaaacc..000000000 --- a/daemon-gtk3/Main.vala +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2024 elementary, Inc. (https://elementary.io) - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -public class Gala.Daemon.Application : Gtk.Application { - public Application () { - Object (application_id: "org.pantheon.gala.daemon"); - } - - public override void startup () { - base.startup (); - - var granite_settings = Granite.Settings.get_default (); - var gtk_settings = Gtk.Settings.get_default (); - - gtk_settings.gtk_application_prefer_dark_theme = granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK; - - granite_settings.notify["prefers-color-scheme"].connect (() => { - gtk_settings.gtk_application_prefer_dark_theme = granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK; - }); - - var app_provider = new Gtk.CssProvider (); - app_provider.load_from_resource ("io/elementary/desktop/gala-daemon/gala-daemon.css"); - Gtk.StyleContext.add_provider_for_screen (Gdk.Screen.get_default (), app_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); - } - - public override void activate () { - hold (); - } - - public override bool dbus_register (DBusConnection connection, string object_path) throws Error { - base.dbus_register (connection, object_path); - - connection.register_object (object_path, new DBus ()); - - return true; - } -} - -public static int main (string[] args) { - GLib.Intl.setlocale (LocaleCategory.ALL, ""); - GLib.Intl.bindtextdomain (Config.GETTEXT_PACKAGE, Config.LOCALEDIR); - GLib.Intl.bind_textdomain_codeset (Config.GETTEXT_PACKAGE, "UTF-8"); - GLib.Intl.textdomain (Config.GETTEXT_PACKAGE); - - var app = new Gala.Daemon.Application (); - return app.run (); -} diff --git a/daemon-gtk3/MonitorLabel.vala b/daemon-gtk3/MonitorLabel.vala deleted file mode 100644 index 0ece57239..000000000 --- a/daemon-gtk3/MonitorLabel.vala +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2024 elementary, Inc. (https://elementary.io) - * SPDX-License-Identifier: LGPL-3.0-or-later - */ - - public class Gala.Daemon.MonitorLabel : Hdy.Window { - private const int SPACING = 12; - private const string COLORED_STYLE_CSS = """ - .%s { - background-color: alpha(%s, 0.8); - color: %s; - } - """; - - public MonitorLabelInfo info { get; construct; } - - public MonitorLabel (MonitorLabelInfo info) { - Object (info: info); - } - - construct { - child = new Gtk.Label (info.label); - - title = "LABEL-%i".printf (info.monitor); - - input_shape_combine_region (null); - accept_focus = false; - decorated = false; - resizable = false; - deletable = false; - can_focus = false; - skip_taskbar_hint = true; - skip_pager_hint = true; - type_hint = Gdk.WindowTypeHint.TOOLTIP; - set_keep_above (true); - - stick (); - - var scale_factor = get_style_context ().get_scale (); - move ( - (int) (info.x / scale_factor) + SPACING, - (int) (info.y / scale_factor) + SPACING - ); - - var provider = new Gtk.CssProvider (); - try { - provider.load_from_data (COLORED_STYLE_CSS.printf (title, info.background_color, info.text_color)); - get_style_context ().add_class (title); - get_style_context ().add_class ("monitor-label"); - - Gtk.StyleContext.add_provider_for_screen ( - Gdk.Screen.get_default (), - provider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION - ); - } catch (Error e) { - warning ("Failed to load CSS: %s", e.message); - } - - show_all (); - } -} diff --git a/daemon-gtk3/Window.vala b/daemon-gtk3/Window.vala deleted file mode 100644 index 5b42c4ecd..000000000 --- a/daemon-gtk3/Window.vala +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2024 elementary, Inc. (https://elementary.io) - * SPDX-License-Identifier: GPL-3.0-or-later - * - * Authored by: Leonhard Kargl - */ - -public class Gala.Daemon.Window : Gtk.Window { - public int width { get; construct; } - public int height { get; construct; } - public Gtk.Box content { get; construct; } - - public Window (int width, int height) { - Object (width: width, height: height); - } - - class construct { - set_css_name ("daemon-window"); - } - - construct { - decorated = false; - resizable = false; - deletable = false; - can_focus = false; - input_shape_combine_region (null); - accept_focus = false; - skip_taskbar_hint = true; - skip_pager_hint = true; - type_hint = Gdk.WindowTypeHint.DOCK; - set_keep_above (true); - - title = "MODAL"; - child = content = new Gtk.Box (HORIZONTAL, 0) { - hexpand = true, - vexpand = true, - width_request = width, - height_request = height - }; - - set_visual (get_screen ().get_rgba_visual ()); - - show_all (); - move (0, 0); - - button_press_event.connect (() => { - close (); - return Gdk.EVENT_STOP; - }); - } -} diff --git a/daemon-gtk3/meson.build b/daemon-gtk3/meson.build deleted file mode 100644 index cd249db08..000000000 --- a/daemon-gtk3/meson.build +++ /dev/null @@ -1,19 +0,0 @@ -gala_daemon_sources = files( - 'Main.vala', - 'DBus.vala', - 'MonitorLabel.vala', - 'Window.vala', - 'BackgroundMenu.vala', -) - -granite6_dep = dependency('granite') -hdy_dep = dependency('libhandy-1') - -executable( - 'gala-daemon-gtk3', - gala_daemon_sources, - config_header, - gala_resources, - dependencies: [granite6_dep, hdy_dep], - install: true, -) diff --git a/meson.build b/meson.build index 7c2cb2c5a..a87081c18 100644 --- a/meson.build +++ b/meson.build @@ -172,7 +172,6 @@ subdir('protocol') subdir('lib') subdir('src') subdir('daemon') -subdir('daemon-gtk3') subdir('plugins/pip') subdir('plugins/template') if get_option('documentation') diff --git a/po/POTFILES b/po/POTFILES index 870388dc4..352f116b7 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -10,12 +10,6 @@ daemon/Main.vala daemon/MonitorLabel.vala daemon/Window.vala -daemon-gtk3/BackgroundMenu.vala -daemon-gtk3/DBus.vala -daemon-gtk3/Main.vala -daemon-gtk3/MonitorLabel.vala -daemon-gtk3/Window.vala - data/gala-multitaskingview.desktop.in data/gala-other.desktop.in data/gala.metainfo.xml.in From 722c04ee1183167f08f4ca297ce31ac673bf34c3 Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Wed, 16 Sep 2026 22:11:35 +0200 Subject: [PATCH 21/22] NotificationStack: Dont use window type for is_notification --- src/Misc/NotificationStack.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Misc/NotificationStack.vala b/src/Misc/NotificationStack.vala index 20e3ba1a1..9e8c06bfa 100644 --- a/src/Misc/NotificationStack.vala +++ b/src/Misc/NotificationStack.vala @@ -202,6 +202,6 @@ public class Gala.NotificationStack : Object { } public static bool is_notification (Meta.Window window) { - return window.window_type == NOTIFICATION || window.get_data (NOTIFICATION_DATA_KEY); + return window.get_data (NOTIFICATION_DATA_KEY); } } From 387ed14542e4e8e9df845ecebb19d20375cd48d5 Mon Sep 17 00:00:00 2001 From: Leonhard Kargl Date: Wed, 16 Sep 2026 22:11:38 +0200 Subject: [PATCH 22/22] Revert "Fix crash when destroying notifications" This reverts commit 9179cd7c20a593ec7eec09ec0c314421832e00d0. This is no longer needed on wayland and with the preceding commit. --- src/Misc/NotificationStack.vala | 4 ++-- src/WindowManager.vala | 10 +--------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/Misc/NotificationStack.vala b/src/Misc/NotificationStack.vala index 9e8c06bfa..fc27b6766 100644 --- a/src/Misc/NotificationStack.vala +++ b/src/Misc/NotificationStack.vala @@ -163,7 +163,7 @@ public class Gala.NotificationStack : Object { } } - public async bool destroy_notification (Meta.WindowActor notification) { + public async void destroy_notification (Meta.WindowActor notification) { notifications.remove (notification); update_positions (); @@ -171,7 +171,7 @@ public class Gala.NotificationStack : Object { builder.add_property ("opacity", 0u); builder.add_property ("x", notification.x + stack_width); - return yield builder.run (); + yield builder.run (); } /** diff --git a/src/WindowManager.vala b/src/WindowManager.vala index 6ca085ce3..582791007 100644 --- a/src/WindowManager.vala +++ b/src/WindowManager.vala @@ -1103,15 +1103,7 @@ namespace Gala { default: if (NotificationStack.is_notification (window)) { - if (!(yield notification_stack.destroy_notification (actor)) && window.window_type == NOTIFICATION) { - /* This is a workaround for X11. On X11 notifications actually get the window type - notification which is according to mutter not allowed to have any destroy animations. - Therefore if the destroy animation didn't finish this means it was interrupted probably - because mutter destroyed the actor already so don't call destroy_completed - because that would lead to a use after free. */ - destroying.remove (actor); - return; - } + yield notification_stack.destroy_notification (actor); } break; }