[gcr/wip/nielsdg/lose-x11-dependency: 33/35] prompt: Support transient_for in Wayland



commit 84e13aa25e524af6fa5213682f3110c638fb5d83
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Tue Dec 3 08:51:28 2019 +0100

    prompt: Support transient_for in Wayland
    
    GDK provides an interface to the _xdg-foreign_ protocol extension, which
    exactly allows to export a handle that another window can use to set
    itself transient to.
    
    Also bump the minmal GTK version to 3.22, since that is the version that
    adds the necessary methods to do this in GDK.

 configure.ac           |  2 +-
 gcr/gcr-prompt.c       |  4 +++
 ui/frob-prompt.c       |  2 ++
 ui/gcr-prompt-dialog.c | 81 +++++++++++++++++++++++++++++++++++++++-----------
 4 files changed, 70 insertions(+), 19 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index e63d48c..1cc337e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,7 +17,7 @@ GLIB_MAX=GLIB_VERSION_2_38
 
 GCRYPT_VERSION=1.4.5
 
-GTK_REQ=3.12
+GTK_REQ=3.22
 
 dnl ****************************************************************************
 dnl Library package and libtool versioning
diff --git a/gcr/gcr-prompt.c b/gcr/gcr-prompt.c
index 6a34cba..997c819 100644
--- a/gcr/gcr-prompt.c
+++ b/gcr/gcr-prompt.c
@@ -210,6 +210,10 @@ gcr_prompt_default_init (GcrPromptIface *iface)
                 * The caller window indicates to the prompt which window is prompting the
                 * user. The prompt may choose to ignore this information or use it in whatever
                 * way it sees fit.
+                *
+                * In X11, this will be a stringified version of the XWindow handle; in
+                * Wayland this is the result of an export using the XDG foreign
+                * protocol.
                 */
                g_object_interface_install_property (iface,
                                g_param_spec_string ("caller-window", "Caller window", "Window ID of 
application window requesting prompt",
diff --git a/ui/frob-prompt.c b/ui/frob-prompt.c
index 53955be..f5a8403 100644
--- a/ui/frob-prompt.c
+++ b/ui/frob-prompt.c
@@ -25,7 +25,9 @@
 #include "gcr/gcr-base.h"
 
 #include <gtk/gtk.h>
+#ifdef GDK_WINDOWING_X11
 #include <gdk/gdkx.h>
+#endif
 
 #include <err.h>
 
diff --git a/ui/gcr-prompt-dialog.c b/ui/gcr-prompt-dialog.c
index 054dd1f..c5066a9 100644
--- a/ui/gcr-prompt-dialog.c
+++ b/ui/gcr-prompt-dialog.c
@@ -30,6 +30,9 @@
 #ifdef GDK_WINDOWING_X11
 #include <gdk/gdkx.h>
 #endif
+#ifdef GDK_WINDOWING_WAYLAND
+#include <gdk/gdkwayland.h>
+#endif
 #include <glib/gi18n.h>
 
 /**
@@ -126,29 +129,22 @@ G_DEFINE_TYPE_WITH_CODE (GcrPromptDialog, gcr_prompt_dialog, GTK_TYPE_DIALOG,
                          G_IMPLEMENT_INTERFACE (GCR_TYPE_PROMPT, gcr_prompt_dialog_prompt_iface);
 );
 
-static void
-update_transient_for (GcrPromptDialog *self)
+#ifdef GDK_WINDOWING_X11
+static gboolean
+update_transient_for_x11 (GcrPromptDialog *self, GdkWindow *window)
 {
-       GdkDisplay *display;
-       GdkWindow *transient_for = NULL;
-       GdkWindow *window;
        gint64 handle;
        gchar *end;
+       GdkDisplay *display;
+       GdkWindow *transient_for;
 
-       if (self->pv->caller_window == NULL || g_str_equal (self->pv->caller_window, "")) {
-               gtk_window_set_modal (GTK_WINDOW (self), FALSE);
-               return;
-       }
-
-       window = gtk_widget_get_window (GTK_WIDGET (self));
-       if (window == NULL)
-               return;
+       if (!GDK_IS_X11_WINDOW (window))
+               return FALSE;
 
-#ifdef GDK_WINDOWING_X11
        handle = g_ascii_strtoll (self->pv->caller_window, &end, 10);
        if (!end || *end != '\0') {
                g_warning ("couldn't parse caller-window property: %s", self->pv->caller_window);
-               return;
+               return FALSE;
        }
 
        display = gtk_widget_get_display (GTK_WIDGET (self));
@@ -156,12 +152,61 @@ update_transient_for (GcrPromptDialog *self)
        if (transient_for == NULL) {
                g_warning ("caller-window property doesn't represent a window on current display: %s",
                           self->pv->caller_window);
-       } else {
-               gdk_window_set_transient_for (window, transient_for);
-               g_object_unref (transient_for);
+               return FALSE;
        }
+
+       gdk_window_set_transient_for (window, transient_for);
+       g_object_unref (transient_for);
+       return TRUE;
+}
 #endif
 
+#ifdef GDK_WINDOWING_WAYLAND
+static gboolean
+update_transient_for_wl (GcrPromptDialog *self, GdkWindow *window)
+{
+       if (!GDK_IS_WAYLAND_WINDOW (window))
+               return FALSE;
+
+       if (gdk_wayland_window_set_transient_for_exported (window, self->pv->caller_window)) {
+               g_debug ("Succesfully set transient for WL window %s", self->pv->caller_window);
+               return TRUE;
+       }
+
+       g_warning ("caller-window property doesn't represent a window on current display: %s",
+                  self->pv->caller_window);
+       return FALSE;
+}
+#endif
+
+static void
+update_transient_for (GcrPromptDialog *self)
+{
+       GdkWindow *window;
+       gboolean success = FALSE;
+
+       if (self->pv->caller_window == NULL || g_str_equal (self->pv->caller_window, "")) {
+               gtk_window_set_modal (GTK_WINDOW (self), FALSE);
+               return;
+       }
+
+       window = gtk_widget_get_window (GTK_WIDGET (self));
+       if (window == NULL)
+               return;
+
+#ifdef GDK_WINDOWING_X11
+       if (!success)
+               success |= update_transient_for_x11 (self, window);
+#endif
+#ifdef GDK_WINDOWING_WAYLAND
+       if (!success)
+               success |= update_transient_for_wl (self, window);
+#endif
+
+       if (!success) {
+               g_warning ("Couldn't set transient to caller window");
+       }
+
        gtk_window_set_modal (GTK_WINDOW (self), TRUE);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]