Skip to content

Commit

Permalink
Portal: support parenting window on wayland (#1768)
Browse files Browse the repository at this point in the history
  • Loading branch information
Marukesu authored Jul 20, 2021
1 parent 5dc6e82 commit 085c43f
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 7 deletions.
58 changes: 51 additions & 7 deletions filechooser-portal/ExternalWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,28 @@ public interface ExternalWindow : GLib.Object {

public static ExternalWindow? from_handle (string handle) {
const string X11_PREFIX = "x11:";
const string WAYLAND_PREFIX = "wayland:";
ExternalWindow? external_window = null;

if (handle.has_prefix (X11_PREFIX)) {
try {
var external_window_x11 = new ExternalWindowX11 (handle.substring (X11_PREFIX.length));
return external_window_x11;
external_window = new ExternalWindowX11 (handle.substring (X11_PREFIX.length));
} catch (Error e) {
warning ("Error getting external X11 window: %s", e.message);
return null;
}
} else if (handle.has_prefix (WAYLAND_PREFIX)) {
try {
external_window = new ExternalWindowWayland (handle.substring (WAYLAND_PREFIX.length));
} catch (Error e) {
warning ("Error getting external Wayland window: %s", e.message);
return null;
}
} else {
warning ("Unhandled parent window type %s", handle);
}

// TODO: Handle Wayland

warning ("Unhandled parent window type %s", handle);

return null;
return external_window;
}
}

Expand Down Expand Up @@ -84,3 +91,40 @@ public class ExternalWindowX11 : ExternalWindow, GLib.Object {
child_window.set_transient_for (foreign_gdk_window);
}
}

public class ExternalWindowWayland : ExternalWindow, GLib.Object {
private static Gdk.Display? wayland_display = null;

private string handle;

public ExternalWindowWayland (string handle) throws GLib.IOError {
var display = get_wayland_display ();
if (display == null) {
throw new IOError.FAILED ("No Wayland display connection, ignoring Wayland parent");
}

this.handle = handle;
}

private static Gdk.Display? get_wayland_display () {
if (wayland_display != null) {
return wayland_display;
}

Gdk.set_allowed_backends ("wayland");
wayland_display = Gdk.Display.open (null);
Gdk.set_allowed_backends (null);

if (wayland_display == null) {
warning ("Failed to open Wayland display");
}

return wayland_display;
}

public void set_parent_of (Gdk.Window child_window) {
if (!((Gdk.Wayland.Window) child_window).set_transient_for_exported (handle)) {
warning ("Failed to set portal window transient for external parent");
}
}
}
1 change: 1 addition & 0 deletions filechooser-portal/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ executable(
dependencies : [
pantheon_files_widgets_dep,
dependency('gdk-x11-3.0'),
dependency('gdk-wayland-3.0'),
project_config_dep
],
install: true,
Expand Down
14 changes: 14 additions & 0 deletions vapi/gdk-wayland-3.0.vapi
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[CCode (cheader_filename = "gdk/gdkwayland.h")]
namespace Gdk.Wayland {
[CCode (type_id = "GDK_TYPE_WAYLAND_WINDOW", type_check_function = "GDK_IS_WAYLAND_WINDOW")]
public class Window : Gdk.Window {
protected Window ();

public bool export_handle (owned WindowExported callback);
public bool set_transient_for_exported (string parent_handle_str);
public void unexport_handle ();
}

[CCode (instance_pos = 2.9)]
public delegate void WindowExported (Gdk.Window window, string handle);
}

0 comments on commit 085c43f

Please sign in to comment.