summaryrefslogtreecommitdiff
path: root/src/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/src/util.c b/src/util.c
index c521f17..3364e30 100644
--- a/src/util.c
+++ b/src/util.c
@@ -31,10 +31,15 @@
#include <locale.h>
#include <errno.h>
#include <string.h>
+#include <stdlib.h>
#include "config.h"
#include "util.h"
#include "zenity.h"
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#endif
+
#define ZENITY_OK_DEFAULT 0
#define ZENITY_CANCEL_DEFAULT 1
#define ZENITY_ESC_DEFAULT 1
@@ -259,3 +264,91 @@ zenity_util_return_exit_code ( ZenityExitCode value )
retval = atoi (env_var);
return retval;
}
+
+
+#ifdef GDK_WINDOWING_X11
+
+static Window
+transient_get_xterm ()
+{
+ const char *wid_str = g_getenv ("WINDOWID");
+ if (wid_str) {
+ char *wid_str_end;
+ Window wid = strtoul (wid_str, &wid_str_end, 10);
+ if (*wid_str != '\0' && *wid_str_end == '\0' && wid != 0)
+ return wid;
+ }
+ return None;
+}
+
+static void
+transient_x_free (void *ptr)
+{
+ if (ptr)
+ XFree (ptr);
+}
+
+static gboolean
+transient_is_toplevel (Window wid)
+{
+ XTextProperty prop;
+ Display *dpy = GDK_DISPLAY ();
+ if (!XGetWMName (dpy, wid, &prop))
+ return FALSE;
+ transient_x_free (prop.value);
+ return !!prop.value;
+}
+
+/*
+ * GNOME Terminal doesn't give us its toplevel window, but the WM needs a
+ * toplevel XID for proper stacking. Other terminals work fine without this
+ * magic. We can't use GDK here since "xterm" is a foreign window.
+ */
+
+static Window
+transient_get_xterm_toplevel ()
+{
+ Window xterm = transient_get_xterm ();
+ Display *dpy = GDK_DISPLAY ();
+ while (xterm != None && !transient_is_toplevel (xterm))
+ {
+ Window root, parent, *children;
+ int nchildren;
+ XQueryTree (dpy, xterm,
+ &root, &parent,
+ &children, &nchildren);
+ transient_x_free (children);
+ if (parent == root)
+ xterm = None;
+ else
+ xterm = parent;
+ }
+ return xterm;
+}
+
+static void
+zenity_util_make_transient (GdkWindow *window)
+{
+ Window xterm = transient_get_xterm_toplevel ();
+ if (xterm != None) {
+ GdkWindow *gdkxterm = gdk_window_foreign_new (xterm);
+ if (gdkxterm) {
+ gdk_window_set_transient_for (window, gdkxterm);
+ g_object_unref (G_OBJECT (gdkxterm));
+ }
+ }
+}
+
+#endif /* GDK_WINDOWING_X11 */
+
+void
+zenity_util_show_dialog (GtkWidget *dialog)
+{
+ gtk_widget_realize (dialog);
+#ifdef GDK_WINDOWING_X11
+ g_assert (dialog->window);
+ zenity_util_make_transient (dialog->window);
+#endif
+ gtk_widget_show (dialog);
+}
+