Re: Support for WM spec



On 27 Feb 2001, Havoc Pennington wrote:

>
> Alexander Larsson <alla lysator liu se> writes:
> > +  xev.xclient.window = gdk_root_window;
> > +  xev.xclient.display = gdk_display;
> > +  xev.xclient.window = gdk_root_window;
>
> Should be the window to be modal, not the root window, I think.
>
> I have this same code in a couple places - maybe it should be broken
> out into a function.
>
> > +#ifdef NO_GDK_WMSPEC_SUPPORTED_YET
> > +  if (!_gdk_wmspec_supported (gdk_atom_intern ("_NET_WM_ICON", FALSE)))
> > +    return FALSE;
> > +#endif
>
> Possibly should set the icon anyway, in case a supported WM appears
> later, as Tim pointed out for the stuff I was doing.

Ok, here is a new version, fixing some bugs and cleaning up some stuff.

Can I apply this?

/ Alex

Index: gdk/gdkwindow.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/gdkwindow.h,v
retrieving revision 1.16
diff -u -p -r1.16 gdkwindow.h
--- gdk/gdkwindow.h	2001/02/27 20:39:49	1.16
+++ gdk/gdkwindow.h	2001/02/28 14:48:49
@@ -84,6 +84,28 @@ typedef enum
   GDK_HINT_WIN_GRAVITY = 1 << 6
 } GdkWindowHints;

+
+/* Window type hints.
+ * These are hints for the window manager that indicate
+ * what type of function the window has. The window manager
+ * can use this when determining decoration and behaviour
+ * of the window. The hint must be set before mapping the
+ * window.
+ *
+ *   Normal: Normal toplevel window
+ *   Dialog: Dialog window
+ *   Menu: Window used to implement a menu.
+ *   Toolbar: Window used to implement toolbars.
+ */
+typedef enum
+{
+  GDK_WINDOW_TYPE_HINT_NORMAL,
+  GDK_WINDOW_TYPE_HINT_DIALOG,
+  GDK_WINDOW_TYPE_HINT_MENU,
+  GDK_WINDOW_TYPE_HINT_TOOLBAR
+} GdkWindowTypeHint;
+
+
 /* The next two enumeration values current match the
  * Motif constants. If this is changed, the implementation
  * of gdk_window_set_decorations/gdk_window_set_functions
@@ -204,6 +226,7 @@ struct _GdkWindowObject

   guint guffaw_gravity : 1;
   guint input_only : 1;
+  guint modal_hint : 1;

   guint destroyed : 2;
 };
@@ -327,6 +350,10 @@ void	      gdk_window_set_hints	 (GdkWin
 					  gint		   max_width,
 					  gint		   max_height,
 					  gint		   flags);
+void          gdk_window_set_type_hint   (GdkWindow       *window,
+					  GdkWindowTypeHint hint);
+void          gdk_window_set_modal_hint  (GdkWindow       *window,
+					  gboolean         modal);
 void          gdk_window_set_geometry_hints (GdkWindow        *window,
 					     GdkGeometry      *geometry,
 					     GdkWindowHints    flags);
@@ -384,6 +411,8 @@ GdkEventMask  gdk_window_get_events	 (Gd
 void	      gdk_window_set_events	 (GdkWindow	  *window,
 					  GdkEventMask	   event_mask);

+gboolean      gdk_window_set_icon_list   (GdkWindow       *window,
+					  GList           *pixbufs);
 void	      gdk_window_set_icon	 (GdkWindow	  *window,
 					  GdkWindow	  *icon_window,
 					  GdkPixmap	  *pixmap,
Index: gdk/x11/gdkwindow-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.c,v
retrieving revision 1.106
diff -u -p -r1.106 gdkwindow-x11.c
--- gdk/x11/gdkwindow-x11.c	2001/02/27 20:40:00	1.106
+++ gdk/x11/gdkwindow-x11.c	2001/02/28 14:48:50
@@ -761,6 +761,12 @@ set_initial_hints (GdkWindow *window)
       ++i;
     }

+  if (private->modal_hint)
+    {
+      atoms[i] = gdk_atom_intern ("_NET_WM_STATE_MODAL", FALSE);
+      ++i;
+    }
+
   if (i > 0)
     {
       XChangeProperty (GDK_WINDOW_XDISPLAY (window),
@@ -1141,6 +1147,121 @@ gdk_window_set_hints (GdkWindow *window,
 		     &size_hints);
 }

+/**
+ * gdk_window_set_type_hint:
+ * @window: A #GdkWindow
+ * @hint: A hint of the function this window will have
+ *
+ * The application can use this call to hint to the window
+ * manager about the functionallity of a window. The window manager
+ * can use this information to decide the decoration and behaviour
+ * of the window.
+ *
+ * The hint must be set before the window is mapped.
+ **/
+void
+gdk_window_set_type_hint (GdkWindow        *window,
+			  GdkWindowTypeHint hint)
+{
+  GdkAtom atom;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  switch (hint)
+    {
+    case GDK_WINDOW_TYPE_HINT_DIALOG:
+      atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_DIALOG", FALSE);
+      break;
+    case GDK_WINDOW_TYPE_HINT_MENU:
+      atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_MENU", FALSE);
+      break;
+    case GDK_WINDOW_TYPE_HINT_TOOLBAR:
+      atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_TOOLBAR", FALSE);
+      break;
+    default:
+      g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
+      /* Fall thru */
+    case GDK_WINDOW_TYPE_HINT_NORMAL:
+      atom = gdk_atom_intern ("_NET_WM_WINDOW_TYPE_NORMAL", FALSE);
+      break;
+    }
+
+  XChangeProperty (GDK_WINDOW_XDISPLAY (window),
+		   GDK_WINDOW_XID (window),
+		   gdk_atom_intern ("_NET_WM_WINDOW_TYPE", FALSE),
+		   XA_ATOM, 32, PropModeReplace,
+		   (guchar *)&atom, 1);
+}
+
+
+static void
+gdk_wmspec_change_state (gboolean add,
+			 GdkWindow *window,
+			 GdkAtom state1,
+			 GdkAtom state2)
+{
+  XEvent xev;
+  Atom op;
+
+  if (add)
+    op = gdk_atom_intern ("_NET_WM_STATE_ADD", FALSE);
+  else
+    op = gdk_atom_intern ("_NET_WM_STATE_REMOVE", FALSE);
+
+  xev.xclient.type = ClientMessage;
+  xev.xclient.serial = 0;
+  xev.xclient.send_event = True;
+  xev.xclient.display = gdk_display;
+  xev.xclient.window = GDK_WINDOW_XID (window);
+  xev.xclient.message_type = gdk_atom_intern ("_NET_WM_STATE", FALSE);
+  xev.xclient.format = 32;
+  xev.xclient.data.l[0] = op;
+  xev.xclient.data.l[1] = state1;
+  xev.xclient.data.l[2] = state2;
+
+  XSendEvent (gdk_display, gdk_root_window, False,
+	      SubstructureRedirectMask | SubstructureNotifyMask,
+	      &xev);
+}
+/**
+ * gdk_window_set_modal_hint:
+ * @window: A #GdkWindow
+ * @modal: TRUE if the window is modal, FALSE otherwise.
+ *
+ * The application can use this hint to tell the window manager
+ * that a certain window has modal behaviour. The window manager
+ * can use this information to handle modal windows in a special
+ * way.
+ *
+ * The #gdk_window_set_transient_for() function must be used to
+ * tell the window manager which window the window is modal to.
+ **/
+void
+gdk_window_set_modal_hint (GdkWindow *window,
+			   gboolean   modal)
+{
+  GdkWindowObject *private;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return;
+
+  private = (GdkWindowObject*) window;
+
+  private->modal_hint = modal;
+
+  if (GDK_WINDOW_IS_MAPPED (window))
+    gdk_wmspec_change_state (modal, window,
+			     gdk_atom_intern ("_NET_WM_STATE_MODAL", FALSE),
+			     0);
+}
+
 void
 gdk_window_set_geometry_hints (GdkWindow      *window,
 			       GdkGeometry    *geometry,
@@ -1310,7 +1431,15 @@ gdk_window_set_title (GdkWindow   *windo

   set_text_property (window, gdk_atom_intern ("WM_NAME", FALSE), title);
   if (!gdk_window_icon_name_set (window))
-    set_text_property (window, gdk_atom_intern ("WM_ICON_NAME", FALSE), title);
+    {
+      XChangeProperty (GDK_WINDOW_XDISPLAY (window),
+		       GDK_WINDOW_XID (window),
+		       gdk_atom_intern ("_NET_WM_ICON_NAME", FALSE),
+		       gdk_atom_intern ("UTF8_STRING", FALSE), 8,
+		       PropModeReplace, title,
+		       strlen (title));
+      set_text_property (window, gdk_atom_intern ("WM_ICON_NAME", FALSE), title);
+    }
 }

 void
@@ -1892,6 +2021,122 @@ gdk_window_set_override_redirect (GdkWin
     }
 }

+
+/**
+ * gdk_window_set_icon_list:
+ * @window: The #GdkWindow toplevel window to set the icon of.
+ * @pixbufs: A list of pixbufs, of different sizes.
+ * @Returns: TRUE if the icons where set, false otherwise
+ *
+ * Sets a list of icons for the window. These are used to represent
+ * the window when it has been iconized. It is usually shown in
+ * an icon box or some sort of task bar. Which icon size is shown
+ * depends on the window manager (and it can be scaled), but
+ * setting several size icons can give better image quality since
+ * the icons might not need to be scaled.
+ *
+ * On a successfull call the ownership of the pixbufs and the list
+ * is transfered to Gdk function.
+ *
+ * On the X11 backend this call might fail if the window manager
+ * doesn't support the Extended Window Manager Hints. Then this
+ * function returns FALSE, and the application should fall back
+ * to #gdk_window_set_icon().
+ **/
+gboolean
+gdk_window_set_icon_list (GdkWindow *window,
+			  GList     *pixbufs)
+{
+  guint *data;
+  guchar *pixels;
+  guint *p;
+  gint size;
+  GList *l;
+  GdkPixbuf *pixbuf;
+  gint width, height, stride;
+  gint x, y;
+  gint n_channels;
+
+  g_return_val_if_fail (window != NULL, FALSE);
+  g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
+
+  if (GDK_WINDOW_DESTROYED (window))
+    return FALSE;
+
+  if (!gdk_wmspec_supported (gdk_atom_intern ("_NET_WM_ICON", FALSE)))
+    return FALSE;
+
+  l = pixbufs;
+  size = 0;
+
+  while (l)
+    {
+      pixbuf = l->data;
+      g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE);
+
+      width = gdk_pixbuf_get_width (pixbuf);
+      height = gdk_pixbuf_get_height (pixbuf);
+
+      size += 2 + width * height;
+
+      l = g_list_next (l);
+    }
+
+  data = g_malloc (size*4);
+
+  l = pixbufs;
+  p = data;
+  while (l)
+    {
+      pixbuf = l->data;
+
+      width = gdk_pixbuf_get_width (pixbuf);
+      height = gdk_pixbuf_get_height (pixbuf);
+      stride = gdk_pixbuf_get_rowstride (pixbuf);
+      n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+
+      *p++ = width;
+      *p++ = height;
+
+      pixels = gdk_pixbuf_get_pixels (pixbuf);
+
+      for (y = 0; y < height; y++)
+	{
+	  for (x = 0; x < width; x++)
+	    {
+	      guchar r, g, b, a;
+
+	      r = pixels[y*stride + x*n_channels + 0];
+	      g = pixels[y*stride + x*n_channels + 1];
+	      b = pixels[y*stride + x*n_channels + 2];
+	      if (n_channels >= 4)
+		a = pixels[y*stride + x*n_channels + 3];
+	      else
+		a = 255;
+
+	      *p++ = a << 24 | r << 16 | g << 8 | b ;
+	    }
+	}
+
+      /* The X11 backend need not store the pixbufs,
+       * other backends might. */
+      g_object_unref (pixbuf);
+
+      l = g_list_next (l);
+    }
+
+  XChangeProperty (GDK_WINDOW_XDISPLAY (window),
+		   GDK_WINDOW_XID (window),
+		   gdk_atom_intern ("_NET_WM_ICON", FALSE),
+		   XA_CARDINAL, 32,
+		   PropModeReplace,
+		   (guchar*) data, size);
+
+  g_list_free (pixbufs);
+
+  return TRUE;
+}
+
 void
 gdk_window_set_icon (GdkWindow *window,
 		     GdkWindow *icon_window,
@@ -1954,6 +2199,12 @@ gdk_window_set_icon_name (GdkWindow   *w
   g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
 		      GUINT_TO_POINTER (TRUE));

+  XChangeProperty (GDK_WINDOW_XDISPLAY (window),
+		   GDK_WINDOW_XID (window),
+		   gdk_atom_intern ("_NET_WM_ICON_NAME", FALSE),
+		   gdk_atom_intern ("UTF8_STRING", FALSE), 8,
+		   PropModeReplace, name,
+		   strlen (name));
   set_text_property (window, gdk_atom_intern ("WM_ICON_NAME", FALSE), name);
 }

@@ -2033,22 +2284,10 @@ gdk_window_stick (GdkWindow *window)
       XEvent xev;

       /* Request stick during viewport scroll */
-      xev.xclient.type = ClientMessage;
-      xev.xclient.serial = 0;
-      xev.xclient.send_event = True;
-      xev.xclient.window = GDK_WINDOW_XWINDOW (window);
-      xev.xclient.display = gdk_display;
-      xev.xclient.message_type = gdk_atom_intern ("_NET_WM_STATE", FALSE);
-      xev.xclient.format = 32;
+      gdk_wmspec_change_state (TRUE, window,
+			       gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
+			       0);

-      xev.xclient.data.l[0] = gdk_atom_intern ("_NET_WM_STATE_ADD", FALSE);
-      xev.xclient.data.l[1] = gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE);
-      xev.xclient.data.l[2] = 0;
-
-      XSendEvent (gdk_display, gdk_root_window, False,
-                  SubstructureRedirectMask | SubstructureNotifyMask,
-                  &xev);
-
       /* Request desktop 0xFFFFFFFF */
       xev.xclient.type = ClientMessage;
       xev.xclient.serial = 0;
@@ -2091,22 +2330,10 @@ gdk_window_unstick (GdkWindow *window)
       gulong *current_desktop;

       /* Request unstick from viewport */
-      xev.xclient.type = ClientMessage;
-      xev.xclient.serial = 0;
-      xev.xclient.send_event = True;
-      xev.xclient.window = GDK_WINDOW_XWINDOW (window);
-      xev.xclient.display = gdk_display;
-      xev.xclient.message_type = gdk_atom_intern ("_NET_WM_STATE", FALSE);
-      xev.xclient.format = 32;
+      gdk_wmspec_change_state (FALSE, window,
+			       gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
+			       0);

-      xev.xclient.data.l[0] = gdk_atom_intern ("_NET_WM_STATE_REMOVE", FALSE);
-      xev.xclient.data.l[1] = gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE);
-      xev.xclient.data.l[2] = 0;
-
-      XSendEvent (gdk_display, gdk_root_window, False,
-                  SubstructureRedirectMask | SubstructureNotifyMask,
-                  &xev);
-
       /* Get current desktop, then set it; this is a race, but not
        * one that matters much in practice.
        */
@@ -2154,31 +2381,13 @@ gdk_window_maximize (GdkWindow *window)
     return;

   if (GDK_WINDOW_IS_MAPPED (window))
-    {
-      XEvent xev;
-
-      xev.xclient.type = ClientMessage;
-      xev.xclient.serial = 0;
-      xev.xclient.send_event = True;
-      xev.xclient.window = GDK_WINDOW_XWINDOW (window);
-      xev.xclient.display = gdk_display;
-      xev.xclient.message_type = gdk_atom_intern ("_NET_WM_STATE", FALSE);
-      xev.xclient.format = 32;
-
-      xev.xclient.data.l[0] = gdk_atom_intern ("_NET_WM_STATE_ADD", FALSE);
-      xev.xclient.data.l[1] = gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE);
-      xev.xclient.data.l[2] = gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE);
-
-      XSendEvent (gdk_display, gdk_root_window, False,
-                  SubstructureRedirectMask | SubstructureNotifyMask,
-                  &xev);
-    }
+    gdk_wmspec_change_state (TRUE, window,
+			     gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
+			     gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
   else
-    {
-      gdk_synthesize_window_state (window,
-                                   0,
-                                   GDK_WINDOW_STATE_MAXIMIZED);
-    }
+    gdk_synthesize_window_state (window,
+				 0,
+				 GDK_WINDOW_STATE_MAXIMIZED);
 }

 void
@@ -2190,31 +2399,13 @@ gdk_window_unmaximize (GdkWindow *window
     return;

   if (GDK_WINDOW_IS_MAPPED (window))
-    {
-      XEvent xev;
-
-      xev.xclient.type = ClientMessage;
-      xev.xclient.serial = 0;
-      xev.xclient.send_event = True;
-      xev.xclient.window = GDK_WINDOW_XWINDOW (window);
-      xev.xclient.display = gdk_display;
-      xev.xclient.message_type = gdk_atom_intern ("_NET_WM_STATE", FALSE);
-      xev.xclient.format = 32;
-
-      xev.xclient.data.l[0] = gdk_atom_intern ("_NET_WM_STATE_REMOVE", FALSE);
-      xev.xclient.data.l[1] = gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE);
-      xev.xclient.data.l[2] = gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE);
-
-      XSendEvent (gdk_display, gdk_root_window, False,
-                  SubstructureRedirectMask | SubstructureNotifyMask,
-                  &xev);
-    }
+    gdk_wmspec_change_state (FALSE, window,
+			     gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
+			     gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
   else
-    {
-      gdk_synthesize_window_state (window,
-                                   GDK_WINDOW_STATE_MAXIMIZED,
-                                   0);
-    }
+    gdk_synthesize_window_state (window,
+				 GDK_WINDOW_STATE_MAXIMIZED,
+				 0);
 }

 void
Index: gtk/gtkdialog.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkdialog.c,v
retrieving revision 1.16
diff -u -p -r1.16 gtkdialog.c
--- gtk/gtkdialog.c	2001/01/09 17:45:33	1.16
+++ gtk/gtkdialog.c	2001/02/28 14:48:50
@@ -139,6 +139,9 @@ gtk_dialog_init (GtkDialog *dialog)
   separator = gtk_hseparator_new ();
   gtk_box_pack_end (GTK_BOX (dialog->vbox), separator, FALSE, TRUE, 0);
   gtk_widget_show (separator);
+
+  gtk_window_set_type_hint (GTK_WINDOW (dialog),
+			    GDK_WINDOW_TYPE_HINT_DIALOG);
 }

 static gint
@@ -202,7 +205,7 @@ gtk_dialog_new_empty (const gchar     *t

   if (flags & GTK_DIALOG_MODAL)
     gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
-
+
   if (flags & GTK_DIALOG_DESTROY_WITH_PARENT)
     gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);

Index: gtk/gtkhandlebox.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkhandlebox.c,v
retrieving revision 1.73
diff -u -p -r1.73 gtkhandlebox.c
--- gtk/gtkhandlebox.c	2001/02/02 17:53:29	1.73
+++ gtk/gtkhandlebox.c	2001/02/28 14:48:51
@@ -409,6 +409,7 @@ gtk_handle_box_realize (GtkWidget *widge
   hb->float_window = gdk_window_new (NULL, &attributes, attributes_mask);
   gdk_window_set_user_data (hb->float_window, widget);
   gdk_window_set_decorations (hb->float_window, 0);
+  gdk_window_set_type_hint (hb->float_window, GDK_WINDOW_TYPE_HINT_TOOLBAR);

   widget->style = gtk_style_attach (widget->style, widget->window);
   gtk_style_set_background (widget->style, widget->window, GTK_WIDGET_STATE (hb));
Index: gtk/gtkmenu.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenu.c,v
retrieving revision 1.55
diff -u -p -r1.55 gtkmenu.c
--- gtk/gtkmenu.c	2001/02/25 17:25:09	1.55
+++ gtk/gtkmenu.c	2001/02/28 14:48:52
@@ -846,6 +846,8 @@ gtk_menu_set_tearoff_state (GtkMenu  *me
 						     "type", GTK_WINDOW_TOPLEVEL,
 						     "signal::destroy", gtk_widget_destroyed, &menu->tearoff_window,
 						     NULL);
+	      gtk_window_set_type_hint (GTK_WINDOW (menu->tearoff_window),
+					GDK_WINDOW_TYPE_HINT_MENU);
 	      gtk_widget_set_app_paintable (menu->tearoff_window, TRUE);
 	      gtk_signal_connect (GTK_OBJECT (menu->tearoff_window),
 				  "event",
Index: gtk/gtkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.c,v
retrieving revision 1.98
diff -u -p -r1.98 gtkwindow.c
--- gtk/gtkwindow.c	2001/02/27 20:40:12	1.98
+++ gtk/gtkwindow.c	2001/02/28 14:48:54
@@ -314,6 +314,7 @@ gtk_window_init (GtkWindow *window)
   window->frame_right = 0;
   window->frame_top = 0;
   window->frame_bottom = 0;
+  window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;

   gtk_widget_ref (GTK_WIDGET (window));
   gtk_object_sink (GTK_OBJECT (window));
@@ -974,6 +975,26 @@ gtk_window_set_transient_for  (GtkWindow
 }

 /**
+ * gtk_window_set_type_hint:
+ * @window: a #GtkWindow
+ * @hint: the window type
+ *
+ * By hinting about the intended function of the window you allow
+ * window managers to decorate and handle different kind of windows
+ * in a consistant way. gtk_dialog_new_with_buttons() and other
+ * convenience functions in GTK+ will sometimes call
+ * gtk_window_set_type_hint() on your behalf.
+ *
+ **/
+void
+gtk_window_set_type_hint (GtkWindow           *window,
+			  GdkWindowTypeHint    hint)
+{
+  g_return_if_fail (GTK_IS_WINDOW (window));
+  window->type_hint = hint;
+}
+
+/**
  * gtk_window_set_destroy_with_parent:
  * @window: a #GtkWindow
  * @setting: whether to destroy @window with its transient parent
@@ -1428,6 +1449,14 @@ gtk_window_realize (GtkWidget *widget)
       GTK_WIDGET_REALIZED (window->transient_parent))
     gdk_window_set_transient_for (widget->window,
 				  GTK_WIDGET (window->transient_parent)->window);
+
+  gdk_window_set_type_hint (widget->window, window->type_hint);
+
+  /* transient_for must be set to allow the modal hint */
+  if (window->transient_parent && window->modal)
+    gdk_window_set_modal_hint (widget->window, TRUE);
+  else
+    gdk_window_set_modal_hint (widget->window, FALSE);
 }

 static void
Index: gtk/gtkwindow.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.h,v
retrieving revision 1.26
diff -u -p -r1.26 gtkwindow.h
--- gtk/gtkwindow.h	2001/02/27 20:40:14	1.26
+++ gtk/gtkwindow.h	2001/02/28 14:48:54
@@ -94,6 +94,8 @@ struct _GtkWindow
   guint frame_top;
   guint frame_right;
   guint frame_bottom;
+
+  GdkWindowTypeHint type_hint;
 };

 struct _GtkWindowClass
@@ -129,6 +131,8 @@ gint	   gtk_window_activate_default

 void       gtk_window_set_transient_for        (GtkWindow           *window,
 						GtkWindow           *parent);
+void       gtk_window_set_type_hint            (GtkWindow           *window,
+						GdkWindowTypeHint    hint);
 void       gtk_window_set_destroy_with_parent  (GtkWindow           *window,
                                                 gboolean             setting);
 void       gtk_window_set_geometry_hints       (GtkWindow           *window,





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