From 71defb68b93aae249ddfb257d43920e785677cd3 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Mon, 24 Mar 2003 17:13:28 +0000 Subject: Rename, rewrite, make them actually work. * e-dialog-utils.c (e_dialog_set_transient_for, e_dialog_set_transient_for_xid): Rename, rewrite, make them actually work. svn path=/trunk/; revision=20482 --- e-util/ChangeLog | 6 ++ e-util/e-dialog-utils.c | 215 +++++++++++++++++++----------------------------- e-util/e-dialog-utils.h | 22 ++--- 3 files changed, 98 insertions(+), 145 deletions(-) diff --git a/e-util/ChangeLog b/e-util/ChangeLog index 151fd0c33e..446a27e687 100644 --- a/e-util/ChangeLog +++ b/e-util/ChangeLog @@ -1,3 +1,9 @@ +2003-03-24 Dan Winship + + * e-dialog-utils.c (e_dialog_set_transient_for, + e_dialog_set_transient_for_xid): Rename, rewrite, make them + actually work. + 2003-03-25 Not Zed * Makefile.am: Added e-meta.[ch] to libeutil diff --git a/e-util/e-dialog-utils.c b/e-util/e-dialog-utils.c index 2a4a3bb07d..5637c260ea 100644 --- a/e-util/e-dialog-utils.c +++ b/e-util/e-dialog-utils.c @@ -25,158 +25,136 @@ #include "e-dialog-utils.h" #include -#include -#include #include +#include -#include -#include #include +#include +#include #include #include #include #include -#include -#include - - -#define TRANSIENT_DATA_ID "e-dialog:transient" - -static void -transient_realize_callback (GtkWidget *widget) -{ - GdkWindow *window; - - window = g_object_get_data ((GObject *) widget, TRANSIENT_DATA_ID); - g_assert (window != NULL); - - gdk_window_set_transient_for (GTK_WIDGET (widget)->window, window); -} - -static void -transient_unrealize_callback (GtkWidget *widget) -{ - GdkWindow *window; - - window = g_object_get_data ((GObject *) widget, TRANSIENT_DATA_ID); - g_assert (window != NULL); - - gdk_property_delete (window, gdk_atom_intern ("WM_TRANSIENT_FOR", FALSE)); -} - -static void -transient_destroy_callback (GtkWidget *widget, GObject *deadbeef) -{ - GdkWindow *window; - - window = g_object_get_data ((GObject *) widget, "transient"); - if (window != NULL) - gdk_window_unref (window); -} - -static void -set_transient_for_gdk (GtkWindow *window, - GdkWindow *parent) +/* Tests whether or not an X Window is being managed by the + * window manager. + */ +static gboolean +window_is_wm_toplevel (Display *display, Window window) { - g_return_if_fail (window != NULL); - g_return_if_fail (g_object_get_data ((GObject *) window, TRANSIENT_DATA_ID) == NULL); - - /* if the parent window doesn't exist anymore, - * something is probably about to go very wrong, - * but at least let's not segfault here. */ - - if (parent == NULL) { - g_warning ("set_transient_for_gdk: uhoh, parent of window %p is NULL", window); - return; + static Atom WM_STATE = None; + unsigned long nitems, after; + unsigned char *data = NULL; + Atom type = None; + int format; + + if (!WM_STATE) + WM_STATE = XInternAtom (display, "WM_STATE", False); + + if (XGetWindowProperty (display, window, WM_STATE, 0, 0, False, + AnyPropertyType, &type, &format, + &nitems, &after, &data) == Success) { + if (data) + XFree((char*)data); + if (type) + return TRUE; } - - gdk_window_ref (parent); /* FIXME? */ - - g_object_set_data ((GObject *) window, TRANSIENT_DATA_ID, parent); - - if (GTK_WIDGET_REALIZED (window)) - gdk_window_set_transient_for (GTK_WIDGET (window)->window, parent); - - g_signal_connect (window, "realize", G_CALLBACK (transient_realize_callback), NULL); - g_signal_connect (window, "unrealize", G_CALLBACK (transient_unrealize_callback), NULL); - - g_object_weak_ref ((GObject *) window, (GWeakNotify) transient_destroy_callback, window); + return FALSE; } - /** - * e_set_dialog_parent: - * @dialog: - * @parent_widget: + * e_dialog_set_transient_for: + * @dialog: a dialog window + * @parent_widget: the parent for @dialog * - * This sets the parent for @dialog to be @parent_widget. Unlike - * gtk_window_set_parent(), this doesn't need @parent_widget to be the actual - * toplevel, and also works if @parent_widget is been embedded as a Bonobo - * control by an out-of-process container. + * This sets the parent for @dialog to be @parent_widget. Unlike + * gtk_window_set_transient_for(), this doesn't need @parent_widget to + * be the actual toplevel, and also works if @parent_widget is + * embedded as a Bonobo control by an out-of-process container. + * @parent_widget must already be realized before calling this + * function, but @dialog does not need to be. **/ void -e_set_dialog_parent (GtkWindow *dialog, - GtkWidget *parent_widget) +e_dialog_set_transient_for (GtkWindow *dialog, + GtkWidget *parent_widget) { GtkWidget *toplevel; + Window parent, root_ret, *children; + unsigned int numchildren; + Display *display; + Status status; - g_return_if_fail (dialog != NULL); g_return_if_fail (GTK_IS_WINDOW (dialog)); - g_return_if_fail (parent_widget != NULL); g_return_if_fail (GTK_IS_WIDGET (parent_widget)); toplevel = gtk_widget_get_toplevel (parent_widget); if (toplevel == NULL) return; - if (! BONOBO_IS_CONTROL (toplevel)) { - if (GTK_IS_WINDOW (toplevel)) - gtk_window_set_transient_for (dialog, GTK_WINDOW (toplevel)); + if (!GTK_IS_PLUG (toplevel)) { + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (toplevel)); return; } -#if 0 - Bonobo_PropertyBag property_bag; - GdkWindow *gdk_window; - CORBA_char *id; - guint32 xid; - - property_bag = bonobo_control_get_ambient_properties (BONOBO_CONTROL (toplevel), NULL); - if (property_bag == CORBA_OBJECT_NIL) - return; + /* Find the top-level windowmanager-managed X Window */ + display = GDK_WINDOW_XDISPLAY (parent_widget->window); + parent = GDK_WINDOW_XID (parent_widget->window); - id = bonobo_property_bag_client_get_value_string (property_bag, E_BONOBO_WIDGET_TOPLEVEL_PROPERTY_ID, NULL); - if (id == NULL) - return; + while (parent && !window_is_wm_toplevel (display, parent)) { + status = XQueryTree (display, parent, &root_ret, + &parent, &children, &numchildren); + if (status != 0) + XFree (children); + } - xid = strtol (id, NULL, 10); + e_dialog_set_transient_for_xid (dialog, parent); +} - gdk_window = gdk_window_foreign_new (xid); - set_transient_for_gdk (dialog, gdk_window); -#endif +static void +dialog_realized (GtkWindow *dialog, gpointer xid) +{ + e_dialog_set_transient_for_xid (dialog, (GdkNativeWindow)xid); } /** - * e_set_dialog_parent_from_xid: - * @dialog: - * @xid: + * e_dialog_set_transient_for_xid: + * @dialog: a dialog window + * @xid: the X Window parent * - * Like %e_set_dialog_parent_from_xid, but use an XID to specify the parent - * window. + * Like e_dialog_set_transient_for(), but use an XID to specify the + * parent window. **/ void -e_set_dialog_parent_from_xid (GtkWindow *dialog, - Window xid) +e_dialog_set_transient_for_xid (GtkWidget *dialog, + GdkNativeWindow xid) { - g_return_if_fail (dialog != NULL); + GdkDisplay *display; + GdkWindow *parent; + g_return_if_fail (GTK_IS_WINDOW (dialog)); - set_transient_for_gdk (dialog, gdk_window_foreign_new (xid)); + if (!GTK_WIDGET_REALIZED (dialog)) { + g_signal_connect (dialog, "realize", + G_CALLBACK (dialog_realized), + (gpointer) xid); + return; + } + + display = gdk_drawable_get_display (GDK_DRAWABLE (dialog->window)); + parent = gdk_window_lookup_for_display (display, xid); + if (!parent) { + parent = gdk_window_foreign_new_for_display (display, xid); + g_return_if_fail (parent != NULL); + } + + gdk_window_set_transient_for (dialog->window, parent); } + + static void e_gnome_dialog_parent_destroyed (GnomeDialog *dialog, GObject *deadbeef) { @@ -190,29 +168,6 @@ e_gnome_dialog_set_parent (GnomeDialog *dialog, GtkWindow *parent) g_object_weak_ref ((GObject *) parent, (GWeakNotify) e_gnome_dialog_parent_destroyed, dialog); } -GtkWidget * -e_gnome_warning_dialog_parented (const char *warning, GtkWindow *parent) -{ - GtkWidget *dialog; - - dialog = gnome_warning_dialog_parented (warning, parent); - g_object_weak_ref ((GObject *) parent, (GWeakNotify) e_gnome_dialog_parent_destroyed, dialog); - - return dialog; -} - -GtkWidget * -e_gnome_ok_cancel_dialog_parented (const char *message, GnomeReplyCallback callback, - gpointer data, GtkWindow *parent) -{ - GtkWidget *dialog; - - dialog = gnome_ok_cancel_dialog_parented (message, callback, data, parent); - g_object_weak_ref ((GObject *) parent, (GWeakNotify) e_gnome_dialog_parent_destroyed, dialog); - - return dialog; -} - static void save_ok (GtkWidget *widget, gpointer data) { diff --git a/e-util/e-dialog-utils.h b/e-util/e-dialog-utils.h index fbb32d8804..dfacfd4149 100644 --- a/e-util/e-dialog-utils.h +++ b/e-util/e-dialog-utils.h @@ -28,27 +28,19 @@ #include #include -#include /* Window */ - -void e_set_dialog_parent (GtkWindow *dialog, - GtkWidget *parent_widget); -void e_set_dialog_parent_from_xid (GtkWindow *dialog, - Window xid); +void e_dialog_set_transient_for (GtkWindow *dialog, + GtkWidget *parent_widget); +void e_dialog_set_transient_for_xid (GtkWindow *dialog, + GdkNativeWindow xid); /* FIXME These functions should go away completely at some point. */ #ifndef GNOME_DISABLE_DEPRECATED -void e_gnome_dialog_set_parent (GnomeDialog *dialog, - GtkWindow *parent); -GtkWidget *e_gnome_warning_dialog_parented (const char *warning, - GtkWindow *parent); -GtkWidget *e_gnome_ok_cancel_dialog_parented (const char *message, - GnomeReplyCallback callback, - gpointer data, - GtkWindow *parent); +void e_gnome_dialog_set_parent (GnomeDialog *dialog, + GtkWindow *parent); #endif -char *e_file_dialog_save (const char *title); +char *e_file_dialog_save (const char *title); #endif -- cgit v1.2.3