summaryrefslogtreecommitdiff
path: root/src/util.c
diff options
context:
space:
mode:
authorGlynn Foster <glynn.foster@sun.com>2004-04-26 04:41:25 +0000
committerGlynn Foster <gman@src.gnome.org>2004-04-26 04:41:25 +0000
commit62785ed80fb0b86847b4eaa3f4cf596f4c109324 (patch)
treee697fadd385dd8a1c122337777daa346a377ed0d /src/util.c
parent1b01fb4b27c8b2e2c02ff517f1ee3ba7fadf2859 (diff)
Add from the 2 Sebastian's, and make email addresses more spam proof.
2004-04-26 Glynn Foster <glynn.foster@sun.com> * THANKS, src/about.c: Add from the 2 Sebastian's, and make email addresses more spam proof. * src/calendar.c, src/entry.c, src/fileselection.c, src/msg.c, * src/progress.c, src/text.c, src/tree.c, src/util.c, * src/util.h: Patch from Sebastian Kapfer to make all zenity dialogs transients of the parent xterm. Fixes #136226. * src/zenity.glade: Patch from Sebastian Heinlein to improve things HIG wise. Fixes #140745.
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);
+}
+