Fixing -1/-2 problem with set uposition



Here's a patch to solve the problem that GTK+ has had for
a long time where a GtkWindow can't be position at a
x or y location of -1/-2.

Essence:

 GtkAuxInfo structure is changed to have flags for whether
 x or y is set instead of using -1 as a flag value.

 Code is adopted to this; X,Y properties for GtkWidget
 use the same -1 flag values as before. gtk_widget_set_uposition
 still uses -1/-2 as flag values.p

 Havoc's new gtk_window_set_location() can take arbitrary 
 x,y.

A slightly bigger / less compatible change would be to not use -1/-2
as flag values for setting the X and Y position and to have a separate
position_set argument. That might be cleaner, though I think
setting windows offscreen from a GUI builder is going to 
be unusual.

Regards,
                                        Owen

[ The following patch won't quite apply since it is extracted
  from a larger patch including all of Havoc's widget
  positioning changes ]

Index: gdk/x11/gdkwindow-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkwindow-x11.c,v
retrieving revision 1.109
diff -u -r1.109 gdkwindow-x11.c
--- gdk/x11/gdkwindow-x11.c	2001/03/05 15:08:36	1.109
+++ gdk/x11/gdkwindow-x11.c	2001/03/29 02:07:41
@@ -1344,7 +1344,8 @@
   if (geom_mask & GDK_HINT_WIN_GRAVITY)
     {
       size_hints.flags |= PWinGravity;
-      size_hints.width_inc = geometry->win_gravity;
+
+      size_hints.win_gravity = geometry->win_gravity;
     }
   
   /* FIXME: Would it be better to delete this property of
@@ -1609,6 +1610,19 @@
     }
 }
 
+/**
+ * gdk_window_get_origin:
+ * @window: a #GdkWindow
+ * @x: return location for X coordinate
+ * @y: return location for Y coordinate
+ * 
+ * Obtains the position of a window in root window coordinates.
+ * (Compare with gdk_window_get_position() and
+ * gdk_window_get_geometry() which return the position of a window
+ * relative to its parent window.)
+ * 
+ * Return value: not meaningful, ignore
+ **/
 gint
 gdk_window_get_origin (GdkWindow *window,
 		       gint      *x,
@@ -1641,6 +1655,21 @@
   return return_val;
 }
 
+/**
+ * gdk_window_get_deskrelative_origin:
+ * @window: a #GdkWindow
+ * @x: return location for X coordinate
+ * @y: return location for Y coordinate
+ * 
+ * This gets the origin of a #GdkWindow relative to
+ * an Enlightenment-window-manager desktop. As long as you don't
+ * assume that the user's desktop/workspace covers the entire
+ * root window (i.e. you don't assume that the desktop begins
+ * at root window coordinate 0,0) this function is not necessary.
+ * It's deprecated for that reason.
+ * 
+ * Return value: not meaningful
+ **/
 gboolean
 gdk_window_get_deskrelative_origin (GdkWindow *window,
 				    gint      *x,
@@ -1705,11 +1734,49 @@
   return return_val;
 }
 
+/**
+ * gdk_window_get_root_origin:
+ * @window: a #GdkWindow
+ * @x: return location for X position of window frame
+ * @y: return location for Y position of window frame
+ *
+ * Obtains the top-left corner of the window manager frame in root
+ * window coordinates.
+ * 
+ **/
 void
 gdk_window_get_root_origin (GdkWindow *window,
 			    gint      *x,
 			    gint      *y)
 {
+  GdkRectangle rect;
+
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  gdk_window_get_frame_extents (window, &rect, NULL, NULL);
+
+  if (x)
+    *x = rect.x;
+
+  if (y)
+    *y = rect.y;
+}
+
+/**
+ * gdk_window_get_frame_extents:
+ * @window: a #GdkWindow
+ * @rect: rectangle to fill with bounding box of the window frame
+ *
+ * Obtains the bounding box of the window, including window manager
+ * titlebar/borders if any. The frame position is given in root window
+ * coordinates. To get the position of the window itself (rather than
+ * the frame) in root window coordinates, use gdk_window_get_origin().
+ * 
+ **/
+void
+gdk_window_get_frame_extents (GdkWindow    *window,
+                              GdkRectangle *rect)
+{
   GdkWindowObject *private;
   Window xwindow;
   Window xparent;
@@ -1717,15 +1784,16 @@
   Window *children;
   unsigned int nchildren;
   
-  g_return_if_fail (window != NULL);
   g_return_if_fail (GDK_IS_WINDOW (window));
+  g_return_if_fail (rect != NULL);
   
   private = (GdkWindowObject*) window;
-  if (x)
-    *x = 0;
-  if (y)
-    *y = 0;
-
+  
+  rect->x = 0;
+  rect->y = 0;
+  rect->width = 1;
+  rect->height = 1;
+  
   if (GDK_WINDOW_DESTROYED (window))
     return;
   
@@ -1755,10 +1823,10 @@
       
       if (XGetGeometry (GDK_WINDOW_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
 	{
-	  if (x)
-	    *x = wx;
-	  if (y)
-	    *y = wy;
+          rect->x = wx;
+          rect->y = wy;
+          rect->width = ww;
+          rect->height = wh;
 	}
     }
 }
Index: gtk/gtklabel.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtklabel.c,v
retrieving revision 1.83
diff -u -r1.83 gtklabel.c
--- gtk/gtklabel.c	2001/03/23 22:21:06	1.83
+++ gtk/gtklabel.c	2001/03/29 02:07:41
@@ -1013,7 +1013,7 @@
       gint width, height;
       gint real_width;
 
-      aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
+      aux_info = _gtk_widget_get_aux_info (widget, FALSE);
       if (aux_info && aux_info->width > 0)
 	{
 	  pango_layout_set_width (label->layout, aux_info->width * PANGO_SCALE);
Index: gtk/gtkscrolledwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkscrolledwindow.c,v
retrieving revision 1.48
diff -u -r1.48 gtkscrolledwindow.c
--- gtk/gtkscrolledwindow.c	2001/03/19 21:06:37	1.48
+++ gtk/gtkscrolledwindow.c	2001/03/29 02:07:41
@@ -666,20 +666,14 @@
   
   if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
     {
-      static guint quark_aux_info = 0;
-
-      if (!quark_aux_info)
-	quark_aux_info = g_quark_from_static_string ("gtk-aux-info");
-
       gtk_widget_size_request (bin->child, &child_requisition);
 
       if (scrolled_window->hscrollbar_policy == GTK_POLICY_NEVER)
 	requisition->width += child_requisition.width;
       else
 	{
-	  GtkWidgetAuxInfo *aux_info;
+	  GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (bin->child, FALSE);
 
-	  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (bin->child), quark_aux_info);
 	  if (aux_info && aux_info->width > 0)
 	    {
 	      requisition->width += aux_info->width;
@@ -693,9 +687,7 @@
 	requisition->height += child_requisition.height;
       else
 	{
-	  GtkWidgetAuxInfo *aux_info;
-
-	  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (bin->child), quark_aux_info);
+	  GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (bin->child, FALSE);
 	  if (aux_info && aux_info->height > 0)
 	    {
 	      requisition->height += aux_info->height;
Index: gtk/gtkwidget.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwidget.c,v
retrieving revision 1.200
diff -u -r1.200 gtkwidget.c
--- gtk/gtkwidget.c	2001/03/29 00:24:57	1.200
+++ gtk/gtkwidget.c	2001/03/29 02:07:41
@@ -198,6 +198,8 @@
 static GtkWidgetAuxInfo* gtk_widget_aux_info_new     (void);
 static void		 gtk_widget_aux_info_destroy (GtkWidgetAuxInfo *aux_info);
 
+static void  gtk_widget_do_uposition (GtkWidget *widget);
+     
 static gpointer         parent_class = NULL;
 static guint            widget_signals[LAST_SIGNAL] = { 0 };
 
@@ -837,6 +839,7 @@
 		    guint	 arg_id)
 {
   GtkWidget *widget;
+  GtkWidgetAuxInfo *aux_info;
 
   widget = GTK_WIDGET (object);
 
@@ -851,10 +854,26 @@
       gtk_container_add (GTK_CONTAINER (GTK_VALUE_OBJECT (*arg)), widget);
       break;
     case ARG_X:
-      gtk_widget_set_uposition (widget, GTK_VALUE_INT (*arg), -2);
+      aux_info = _gtk_widget_get_aux_info (widget, TRUE);
+      if (GTK_VALUE_INT (*arg) == -1)
+	aux_info->x_set = FALSE;
+      else
+	{
+	  aux_info->x_set = TRUE;
+	  aux_info->x = GTK_VALUE_INT (*arg);
+	}
+      gtk_widget_do_uposition (widget);
       break;
     case ARG_Y:
-      gtk_widget_set_uposition (widget, -2, GTK_VALUE_INT (*arg));
+      aux_info = _gtk_widget_get_aux_info (widget, TRUE);
+      if (GTK_VALUE_INT (*arg) == -1)
+	aux_info->y_set = FALSE;
+      else
+	{
+	  aux_info->y_set = TRUE;
+	  aux_info->y = GTK_VALUE_INT (*arg);
+	}
+      gtk_widget_do_uposition (widget);
       break;
     case ARG_WIDTH:
       gtk_widget_set_usize (widget, GTK_VALUE_INT (*arg), -2);
@@ -960,28 +979,28 @@
       GTK_VALUE_OBJECT (*arg) = (GtkObject*) widget->parent;
       break;
     case ARG_X:
-      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
-      if (!aux_info)
+      aux_info =_gtk_widget_get_aux_info (widget, FALSE);
+      if (!aux_info || !aux_info->x_set)
 	GTK_VALUE_INT (*arg) = -1;
       else
 	GTK_VALUE_INT (*arg) = aux_info->x;
       break;
     case ARG_Y:
-      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
-      if (!aux_info)
+      aux_info =_gtk_widget_get_aux_info (widget, FALSE);
+      if (!aux_info || !aux_info->y_set)
 	GTK_VALUE_INT (*arg) = -1;
       else
 	GTK_VALUE_INT (*arg) = aux_info->y;
       break;
     case ARG_WIDTH:
-      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
+      aux_info =_gtk_widget_get_aux_info (widget, FALSE);
       if (!aux_info)
 	GTK_VALUE_INT (*arg) = -1;
       else
 	GTK_VALUE_INT (*arg) = aux_info->width;
       break;
     case ARG_HEIGHT:
-      aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
+      aux_info =_gtk_widget_get_aux_info (widget, FALSE);
       if (!aux_info)
 	GTK_VALUE_INT (*arg) = -1;
       else
@@ -1970,7 +1989,7 @@
 
   *requisition = widget->requisition;
   
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
+  aux_info =_gtk_widget_get_aux_info (widget, FALSE);
   if (aux_info)
     {
       if (aux_info->width > 0)
@@ -2001,7 +2020,7 @@
   g_return_if_fail (GTK_IS_WIDGET (widget));
   
   real_allocation = *allocation;
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
+  aux_info =_gtk_widget_get_aux_info (widget, FALSE);
   
   if (aux_info)
     {
@@ -3930,11 +3949,26 @@
   return (parent_window != NULL) ? parent_window : widget->parent->window;
 }
 
+/* Update the position from aux_info. Used from gtk_widget_set_uposition
+ * and gtk_widget_set_arg().
+ */
+static void
+gtk_widget_do_uposition (GtkWidget *widget)
+{
+  GtkWidgetAuxInfo *aux_info =_gtk_widget_get_aux_info (widget, FALSE);
+
+  if (GTK_IS_WINDOW (widget) && aux_info->x_set && aux_info->y_set)
+    gtk_window_reposition (GTK_WINDOW (widget), aux_info->x, aux_info->y);
+  
+  if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
+    gtk_widget_size_allocate (widget, &widget->allocation);
+}
+
 /**
  * gtk_widget_set_uposition:
  * @widget: a #GtkWidget
- * @x: x position
- * @y: y position
+ * @x: x position; -1 to unset x; -2 to leave x unchanged
+ * @y: y position; -1 to unset y; -2 to leave y unchanged
  * 
  *
  * Sets the position of a widget. The funny "u" in the name comes from
@@ -3958,25 +3997,33 @@
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_WIDGET (widget));
   
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
-  if (!aux_info)
-    {
-      aux_info = gtk_widget_aux_info_new ();
-      gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_aux_info, aux_info);
-    }
+  aux_info =_gtk_widget_get_aux_info (widget, TRUE);
 
-  /* keep this in sync with gtk_window_compute_reposition() */
+  /* keep this in sync with gtk_window_set_location() */
   
   if (x > -2)
-    aux_info->x = x;
+    {
+      if (x == -1)
+	aux_info->x_set = FALSE;
+      else
+	{
+	  aux_info->x_set = TRUE;
+	  aux_info->x = x;
+	}
+    }
+
   if (y > -2)
-    aux_info->y = y;
-  
-  if (GTK_IS_WINDOW (widget) && (aux_info->x != -1) && (aux_info->y != -1))
-    gtk_window_reposition (GTK_WINDOW (widget), x, y);
-  
-  if (GTK_WIDGET_VISIBLE (widget) && widget->parent)
-    gtk_widget_size_allocate (widget, &widget->allocation);
+    {
+      if (y == -1)
+	aux_info->y_set = FALSE;
+      else
+	{
+	  aux_info->y_set = TRUE;
+	  aux_info->y = y;
+	}
+    }
+
+  gtk_widget_do_uposition (widget);
 }
 
 /**
@@ -4014,12 +4061,7 @@
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_WIDGET (widget));
   
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
-  if (!aux_info)
-    {
-      aux_info = gtk_widget_aux_info_new ();
-      gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_aux_info, aux_info);
-    }
+  aux_info =_gtk_widget_get_aux_info (widget, TRUE);
   
   if (width > -2)
     aux_info->width = width;
@@ -4742,7 +4784,7 @@
   if (widget->name)
     g_free (widget->name);
   
-  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
+  aux_info =_gtk_widget_get_aux_info (widget, FALSE);
   if (aux_info)
     gtk_widget_aux_info_destroy (aux_info);
   
@@ -4978,6 +5020,36 @@
     }
 }
 
+/**
+ * _gtk_widget_get_aux_info:
+ * @widget: a #GtkWidget
+ * @create: if %TRUE, create the structure if it doesn't exist
+ * 
+ * Get the #GtkWidgetAuxInfo structure for the widget.
+ * 
+ * Return value: the #GtkAuxInfo structure for the widget, or
+ *    %NULL if @create is %FALSE and one doesn't already exist.
+ **/
+GtkWidgetAuxInfo *
+_gtk_widget_get_aux_info (GtkWidget *widget,
+			  gboolean   create)
+{
+  GtkWidgetAuxInfo *aux_info;
+  
+  aux_info = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_aux_info);
+  if (!aux_info && create)
+    {
+      aux_info = gtk_widget_aux_info_new ();
+      gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_aux_info, aux_info);
+
+      aux_info->width = aux_info->height = -1;
+      aux_info->x = aux_info->y = 0;
+      aux_info->x_set = aux_info->y_set = FALSE;
+    }
+  
+  return aux_info;
+}
+
 /*****************************************
  * gtk_widget_aux_info_new:
  *
@@ -5426,3 +5498,4 @@
       g_strreverse (*path_p);
     }
 }
+
Index: gtk/gtkwidget.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwidget.h,v
retrieving revision 1.103
diff -u -r1.103 gtkwidget.h
--- gtk/gtkwidget.h	2001/03/29 00:24:58	1.103
+++ gtk/gtkwidget.h	2001/03/29 02:07:41
@@ -394,6 +394,8 @@
   gint y;
   gint width;
   gint height;
+  guint x_set : 1;
+  guint y_set : 1;
 };
 
 struct _GtkWidgetShapeInfo
@@ -679,6 +681,8 @@
 #  define gtk_widget_unref gtk_object_unref
 #endif	/* GTK_TRACE_OBJECTS && __GNUC__ */
 
+GtkWidgetAuxInfo *_gtk_widget_get_aux_info (GtkWidget *widget,
+					    gboolean   create);
 
 #ifdef __cplusplus
 }
Index: gtk/gtkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.c,v
retrieving revision 1.109
diff -u -r1.109 gtkwindow.c
--- gtk/gtkwindow.c	2001/03/26 20:54:17	1.109
+++ gtk/gtkwindow.c	2001/03/29 02:07:41
@@ -2946,8 +2968,8 @@
   ux = 0;
   uy = 0;
   
-  aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
-  if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
+  aux_info = _gtk_widget_get_aux_info (widget, FALSE);
+  if (aux_info && aux_info->x_set && aux_info->y_set)
     {
       ux = aux_info->x;
       uy = aux_info->y;
@@ -3008,13 +3030,16 @@
       new_geometry->max_width = requisition.width;
       new_geometry->max_height = requisition.height;
     }
+
+  *new_flags |= GDK_HINT_WIN_GRAVITY;
+  new_geometry->win_gravity = window->gravity;
 }
 
 /* Compute a new position for the window based on a new
- * size. *x and *y will be set to the new coordinates, or to -1 if the
- * window does not need to be moved
+ * size. *x and *y will be set to the new coordinates. Returns
+ * TRUE if the window needs to be moved;
  */
-static void 
+static gboolean
 gtk_window_compute_reposition (GtkWindow  *window,
 			       gint        new_width,
 			       gint        new_height,
@@ -3024,12 +3049,10 @@
   GtkWidget *widget;
   GtkWindowPosition pos;
   GtkWidget *parent_widget;
+  gboolean result = FALSE;
   
   widget = GTK_WIDGET (window);
 
-  *x = -1;
-  *y = -1;
-
   parent_widget = (GtkWidget*) window->transient_parent;
   
   pos = window->position;
@@ -3049,6 +3072,8 @@
 	  
 	  *x = (screen_width - new_width) / 2;
 	  *y = (screen_height - new_height) / 2;
+
+	  result = TRUE;
 	}
       break;
 
@@ -3061,6 +3086,8 @@
                                  
           *x = ox + (parent_widget->allocation.width - new_width) / 2;
           *y = oy + (parent_widget->allocation.height - new_height) / 2;
+
+	  result = TRUE;
         }
       break;
 
@@ -3075,43 +3102,37 @@
 	  *y -= new_height / 2;
 	  *x = CLAMP (*x, 0, screen_width - new_width);
 	  *y = CLAMP (*y, 0, screen_height - new_height);
+
+	  result = TRUE;
 	}
       break;
     default:
       if (window->use_uposition)
 	{
-	  GtkWidgetAuxInfo *aux_info;
-	  
-	  aux_info = gtk_object_get_data (GTK_OBJECT (window), "gtk-aux-info");
-	  if (aux_info &&
-	      aux_info->x != -1 && aux_info->y != -1 &&
-	      aux_info->x != -2 && aux_info->y != -2)
+	  GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
+	  if (aux_info && aux_info->x_set && aux_info->y_set)
 	    {
 	      *x = aux_info->x;
 	      *y = aux_info->y;
 	    }
+
+	  result = TRUE;
 	}
       break;
     }
 
-  if (*x != -1 && *y != -1)
+  if (result)
     {
-      GtkWidgetAuxInfo *aux_info;
-      
-      /* we handle necessary window positioning by hand here,
-       * so we can coalesce the window movement with possible
-       * resizes to get only one configure event.
-       * keep this in sync with gtk_widget_set_uposition()
-       * and gtk_window_reposition().
-       */
-      gtk_widget_set_uposition (widget, -1, -1); /* ensure we have aux_info */
+      GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, TRUE);
       
-      aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
+      aux_info->x_set = aux_info->y_set = TRUE;
       aux_info->x = *x;
       aux_info->y = *y;
 
       window->use_uposition = FALSE;
     }
+
+  return result;
 }
 
 /***********************
[...]
+/**
+ * gtk_window_set_location:
+ * @window: a #GtkWindow
+ * @root_x: X position of gravity-determined reference point in root window coordinates
+ * @root_y: Y position of gravity-determined reference point in root window coordinates
+ *
+ * Requests a new position for a #GtkWindow. The position is given in
+ * root window coordinates, and is the position of the window's
+ * "reference point" as determined by the window gravity (see
+ * gtk_window_set_gravity()). By default, the reference point is the
+ * northwest (top left) corner of the window's titlebar.  So if you
+ * set the window position to (0,0), the window's titlebar will end up
+ * in the top left corner of the root window. Note that the root
+ * window does not always correspond to the user's desktop area, so
+ * you may want to call gdk_workspace_get_extents() or
+ * gdk_desktop_get_extents() to decide where to place a window.  The
+ * extents of the root window can be obtained using gdk_screen_width()
+ * and gdk_screen_height().
+ * 
+ **/
+void
+gtk_window_set_location (GtkWindow *window,
+                         gint       root_x,
+                         gint       root_y)
+{
+  GtkWidgetAuxInfo *aux_info;
+
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  aux_info = _gtk_widget_get_aux_info (GTK_WIDGET (window), TRUE);
+
+  aux_info->x_set = aux_info->y_set = TRUE;
+  aux_info->x = root_x;
+  aux_info->y = root_y;
+  
+  gtk_window_reposition (window, root_x, root_y);
+}
+
+/**
+ * gtk_window_get_location:
+ * @window: a #GtkWindow
+ * @root_x: return location for X coordinate of gravity-determined reference point
+ * @root_y: return location for Y coordinate of gravity-determined reference point
+ *
+ * Attempts to obtain the current position of the reference point, as
+ * set by gtk_window_set_position(). This computation is accurate when
+ * the reference point is a corner of the window itself (as with
+ * #GDK_GRAVITY_STATIC), but may not be accurate when the reference
+ * point is a position on the titlebar or window border, because the X
+ * Window System does not provide a reliable way of obtaining this
+ * information. GTK+ will do a "best guess" which may not be fully
+ * accurate with some window managers, but will probably be
+ * reasonable.
+ * 
+ **/
+void
+gtk_window_get_location (GtkWindow *window,
+                         gint      *root_x,
+                         gint      *root_y)
+{
+  GdkRectangle frame_extents;
+  GtkWidget *widget;
+  GtkWidgetAuxInfo *aux_info;
+  
+  g_return_if_fail (GTK_IS_WINDOW (window));
+
+  widget = GTK_WIDGET (window);
+  
+  if (GTK_WIDGET_REALIZED (window))
+    {
+      if (window->gravity == GDK_GRAVITY_STATIC)
+        {
+          gdk_window_get_origin (widget->window, root_x, root_y);
+          return;
+        }
+      else
+        {
+          gint x, y;
+          
+          gdk_window_get_frame_extents (widget->window, &frame_extents);
+          
+          x = frame_extents.x;
+          y = frame_extents.y;
+
+          switch (window->gravity)
+            {
+            case GDK_GRAVITY_NORTH:
+            case GDK_GRAVITY_CENTER:
+            case GDK_GRAVITY_SOUTH:
+              x += frame_extents.width / 2;
+              break;
+            case GDK_GRAVITY_SOUTH_EAST:
+            case GDK_GRAVITY_EAST:
+            case GDK_GRAVITY_NORTH_EAST:
+              x += frame_extents.width;
+              break;
+            default:
+              break;
+            }
+
+          switch (window->gravity)
+            {
+            case GDK_GRAVITY_WEST:
+            case GDK_GRAVITY_CENTER:
+            case GDK_GRAVITY_EAST:
+              y += frame_extents.height / 2;
+              break;
+            case GDK_GRAVITY_SOUTH_WEST:
+            case GDK_GRAVITY_SOUTH:
+            case GDK_GRAVITY_SOUTH_EAST:
+              y += frame_extents.height;
+              break;
+            default:
+              break;
+            }
+
+          if (root_x)
+            *root_x = x;
+          if (root_y)
+            *root_y = y;
+        }
+    }
+  else
+    {
+      /* We really don't have a location yet, so we make up some stuff,
+       * using the uposition if it's been set.
+       */
+      if (root_x)
+        *root_x = 0;
 
+      if (root_y)
+        *root_y = 0;
+      
+      aux_info = _gtk_widget_get_aux_info (widget, FALSE);
+      if (aux_info && aux_info->x_set && aux_info->y_set)
+        {
+	  *root_x = aux_info->x;
+	  *root_y = aux_info->y;
+        }
+    }
+}





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