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
19 changes: 19 additions & 0 deletions protocol/pantheon-desktop-shell-v1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@
<arg name="output" type="new_id" interface="io_elementary_pantheon_extended_behavior_v1"/>
<arg name="surface" type="object" interface="wl_surface"/>
</request>

<request name="get_greeter">
<description summary="create a greeter surface from a surface">
Create a greeter surface from an existing surface.
</description>
<arg name="output" type="new_id" interface="io_elementary_pantheon_greeter_v1"/>
<arg name="surface" type="object" interface="wl_surface"/>
</request>
</interface>

<interface name="io_elementary_pantheon_panel_v1" version="1">
Expand Down Expand Up @@ -169,4 +177,15 @@
<arg name="monitor_index" type="int" summary="the index of the monitor this surface should label"/>
</request>
</interface>

<interface name="io_elementary_pantheon_greeter_v1" version="1">
<request name="destroy" type="destructor"/>

<request name="make_greeter">
<description summary="make greeter">
Request to make the surface a Greeter window, which will be displayed bellow other windows
when running in greeter compositor mode.
</description>
</request>
</interface>
</protocol>
16 changes: 14 additions & 2 deletions protocol/pantheon-desktop-shell.vapi
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 elementary, Inc. <https://elementary.io>
* Copyright 2023-2026 elementary, Inc. <https://elementary.io>
* Copyright 2023 Corentin Noël <tintou@noel.tf>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
Expand All @@ -12,7 +12,7 @@ namespace Pantheon.Desktop {
public Pantheon.Desktop.GetPanel get_panel;
public Pantheon.Desktop.GetWidget get_widget;
public Pantheon.Desktop.GetExtendedBehavior get_extended_behavior;

public Pantheon.Desktop.GetGreeter get_greeter;
}

[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "enum io_elementary_pantheon_panel_v1_anchor", cprefix="IO_ELEMENTARY_PANTHEON_PANEL_V1_ANCHOR_", has_type_id = false)]
Expand Down Expand Up @@ -65,13 +65,23 @@ namespace Pantheon.Desktop {
public MakeMonitorLabel make_monitor_label;
}

[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "struct io_elementary_pantheon_greeter_v1_interface")]
public struct GreeterInterface {
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "io_elementary_pantheon_greeter_v1_interface")]
public static Wl.Interface iface;
public Destroy destroy;
public MakeGreeter make_greeter;
}

[CCode (has_target = false, has_typedef = false)]
public delegate void GetPanel (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface);
[CCode (has_target = false, has_typedef = false)]
public delegate void GetWidget (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface);
[CCode (has_target = false, has_typedef = false)]
public delegate void GetExtendedBehavior (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface);
[CCode (has_target = false, has_typedef = false)]
public delegate void GetGreeter (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface);
[CCode (has_target = false, has_typedef = false)]
public delegate void SetAnchor (Wl.Client client, Wl.Resource resource, [CCode (type = "uint32_t")] Anchor anchor);
[CCode (has_target = false, has_typedef = false)]
public delegate void Focus (Wl.Client client, Wl.Resource resource);
Expand All @@ -94,5 +104,7 @@ namespace Pantheon.Desktop {
[CCode (has_target = false, has_typedef = false)]
public delegate void MakeMonitorLabel (Wl.Client client, Wl.Resource resource, int monitor_index);
[CCode (has_target = false, has_typedef = false)]
public delegate void MakeGreeter (Wl.Client client, Wl.Resource resource);
[CCode (has_target = false, has_typedef = false)]
public delegate void Destroy (Wl.Client client, Wl.Resource resource);
}
77 changes: 77 additions & 0 deletions src/PantheonShell.vala
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace Gala {
private static Pantheon.Desktop.PanelInterface wayland_pantheon_panel_interface;
private static Pantheon.Desktop.WidgetInterface wayland_pantheon_widget_interface;
private static Pantheon.Desktop.ExtendedBehaviorInterface wayland_pantheon_extended_behavior_interface;
private static Pantheon.Desktop.GreeterInterface wayland_pantheon_greeter_interface;
private static Wl.Global shell_global;

public void init_pantheon_shell (Meta.Context context) {
Expand All @@ -31,6 +32,7 @@ namespace Gala {
get_panel,
get_widget,
get_extended_behavior,
get_greeter,
};

wayland_pantheon_panel_interface = {
Expand All @@ -57,9 +59,15 @@ namespace Gala {
make_monitor_label,
};

wayland_pantheon_greeter_interface = {
destroy_greeter_surface,
make_greeter,
};

PanelSurface.quark = GLib.Quark.from_string ("-gala-wayland-panel-surface-data");
WidgetSurface.quark = GLib.Quark.from_string ("-gala-wayland-widget-surface-data");
ExtendedBehaviorSurface.quark = GLib.Quark.from_string ("-gala-wayland-extended-behavior-surface-data");
GreeterSurface.quark = GLib.Quark.from_string ("-gala-wayland-greeter-surface-data");

shell_global = Wl.Global.create (wl_disp, ref Pantheon.Desktop.ShellInterface.iface, 1, (client, version, id) => {
unowned var resource = client.create_resource (ref Pantheon.Desktop.ShellInterface.iface, (int) version, id);
Expand Down Expand Up @@ -124,6 +132,25 @@ namespace Gala {
}
}

public class GreeterSurface : GLib.Object {
public static GLib.Quark quark = 0;
public unowned GLib.Object? wayland_surface;

public GreeterSurface (GLib.Object wayland_surface) {
this.wayland_surface = wayland_surface;
}

~GreeterSurface () {
if (wayland_surface != null) {
wayland_surface.steal_qdata<unowned GLib.Object> (quark);
}
}

public void on_wayland_surface_disposed () {
wayland_surface = null;
}
}

static void unref_obj_on_destroy (Wl.Resource resource) {
resource.get_user_data<GLib.Object> ().unref ();
}
Expand Down Expand Up @@ -215,6 +242,35 @@ namespace Gala {
);
}

internal static void get_greeter (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface_resource) {
unowned GLib.Object? wayland_surface = surface_resource.get_user_data<GLib.Object> ();
GreeterSurface? greeter_surface = wayland_surface.get_qdata (GreeterSurface.quark);
if (greeter_surface != null) {
surface_resource.post_error (
Wl.DisplayError.INVALID_OBJECT,
"io_elementary_pantheon_shell_v1_interface::get_greeter already requested"
);
return;
}

greeter_surface = new GreeterSurface (wayland_surface);
unowned var greeter_resource = client.create_resource (
ref Pantheon.Desktop.GreeterInterface.iface,
resource.get_version (),
output
);
greeter_resource.set_implementation (
&wayland_pantheon_greeter_interface,
greeter_surface.ref (),
unref_obj_on_destroy
);
wayland_surface.set_qdata_full (
GreeterSurface.quark,
greeter_surface,
(GLib.DestroyNotify) GreeterSurface.on_wayland_surface_disposed
);
}

internal static void set_anchor (Wl.Client client, Wl.Resource resource, [CCode (type = "uint32_t")] Pantheon.Desktop.Anchor anchor) {
unowned PanelSurface? panel_surface = resource.get_user_data<PanelSurface> ();
if (panel_surface.wayland_surface == null) {
Expand Down Expand Up @@ -408,6 +464,23 @@ namespace Gala {
ShellClientsManager.get_instance ().make_monitor_label (window, monitor_index);
}

internal static void make_greeter (Wl.Client client, Wl.Resource resource) {
unowned GreeterSurface? greeter_surface = resource.get_user_data<GreeterSurface> ();
if (greeter_surface.wayland_surface == null) {
warning ("Window tried to make greeter but wayland surface is null.");
return;
}

Meta.Window? window;
greeter_surface.wayland_surface.get ("window", out window, null);
if (window == null) {
warning ("Window tried to make greeter but wayland surface had no associated window.");
return;
}

ShellClientsManager.get_instance ().make_greeter (window);
}

internal static void destroy_panel_surface (Wl.Client client, Wl.Resource resource) {
resource.destroy ();
}
Expand All @@ -419,4 +492,8 @@ namespace Gala {
internal static void destroy_extended_behavior_surface (Wl.Client client, Wl.Resource resource) {
resource.destroy ();
}

internal static void destroy_greeter_surface (Wl.Client client, Wl.Resource resource) {
resource.destroy ();
}
}
33 changes: 32 additions & 1 deletion src/ShellClients/ShellClientsManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public class Gala.ShellClientsManager : Object, GestureTarget {
}
}

public void make_dock (Meta.Window window) {
private void make_dock (Meta.Window window) {
#if HAS_MUTTER49
window.set_type (Meta.WindowType.DOCK);
#else
Expand Down Expand Up @@ -182,6 +182,31 @@ public class Gala.ShellClientsManager : Object, GestureTarget {
}
#endif

private 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.");
}
#endif
}

#if !HAS_MUTTER49
private void make_desktop_wayland (Meta.Window window) requires (Meta.Util.is_wayland_compositor ()) {
foreach (var client in protocol_clients) {
if (client.wayland_client.owns_window (window)) {
#if HAS_MUTTER46
client.wayland_client.make_desktop (window);
#endif
break;
}
}
}
#endif

public void set_anchor (Meta.Window window, Pantheon.Desktop.Anchor anchor) {
if (window in panel_windows) {
panel_windows[window].anchor = anchor;
Expand Down Expand Up @@ -290,6 +315,12 @@ public class Gala.ShellClientsManager : Object, GestureTarget {
window.unmanaged.connect_after (() => ibus_candidate_window = null);
}

public void make_greeter (Meta.Window window) {
make_desktop (window);

wm.override_window_group (window, LOCK_SCREEN);
}

public void propagate (UpdateType update_type, GestureAction action, double progress) {
foreach (var window in positioned_windows.get_values ()) {
window.propagate (update_type, action, progress);
Expand Down