Determining size of decorated window



I'm trying to position a top-level window so that its window manager
decorations are snug against the lower-right corner of the screen.
This would be similar to running "xclock -geometry -0-0".

To do this, I need to know the size of the window manager's window,
and the position of the top-level window relative to the WM window.  I
modified gdkwindow.c to include a gdk_window_get_root_geometry()
routine based on the gdk_window_get_origin() routine [patch included
in attachment], and used that and gdk_window_get_geometry() to obtain
the information that I need.

The test program below positions the window correctly, but has a
problem: the window first appears in the position selected by the
window manager, the quickly vanishes and reappears in its final
location when the gtk_widget_set_uposition() call is executed.

If I try to obtain the offsets from the window manager's window
earlier in the sequence of events (e.g., in the main routine, or in
response to a realize-event), the window hasn't been decorated yet, so
either an error results or the offsets are wrong.

I can't see any way to get this to work.  I know that it's possible to
do this, since xclock and all the other simple X apps are able to
position themselves correctly.  I just can't figure out how.

Any guidance would be much appreciated.

-- John Kodis.


#include <gtk/gtk.h>

static void
geo_locate(GtkWidget *widget)
{
  int tx, ty, tw, th, rx, ry, rw, rh, px, py;

  gdk_window_get_root_geometry(widget->window, &rx, &ry, &rw, &rh, NULL);
  gdk_window_get_geometry(widget->window, &tx, &ty, &tw, &th, NULL);
      
  px = gdk_screen_width() - rw + tx;
  py = gdk_screen_height() - rh + ty;
  gtk_widget_set_uposition(widget, px, py);

  g_print("geo: root=%dx%d%+d%+d, top=%dx%d%+d%+d, pos=%+d%+d\n",
    rw,rh,rx,ry, tw,th,tx,ty, px,py);
}

int
main(int argc, char **argv)
{
  GtkWidget *top;

  gtk_init(&argc, &argv);
  top = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_signal_connect(GTK_OBJECT(top), "map-event", geo_locate, NULL);
  gtk_widget_show(top);

  gtk_main();
  return 0;
}
Common subdirectories: gdk.orig/.libs and gdk/.libs
diff -u gdk.orig/gdk.h gdk/gdk.h
--- gdk.orig/gdk.h	Wed Feb 16 20:19:16 2000
+++ gdk/gdk.h	Mon May 29 13:24:55 2000
@@ -353,6 +353,12 @@
 gboolean      gdk_window_get_deskrelative_origin (GdkWindow	  *window,
 					  gint		  *x,
 					  gint		  *y);
+void	      gdk_window_get_root_geometry (GdkWindow	  *window,
+					  gint		  *x,
+					  gint		  *y,
+					  gint		  *width,
+					  gint		  *height,
+					  gint		  *depth);
 void	      gdk_window_get_root_origin (GdkWindow	  *window,
 					  gint		  *x,
 					  gint		  *y);
diff -u gdk.orig/gdkwindow.c gdk/gdkwindow.c
--- gdk.orig/gdkwindow.c	Mon Jan 31 17:26:03 2000
+++ gdk/gdkwindow.c	Mon May 29 13:50:46 2000
@@ -1567,9 +1567,12 @@
 }
 
 void
-gdk_window_get_root_origin (GdkWindow *window,
-			    gint      *x,
-			    gint      *y)
+gdk_window_get_root_geometry (GdkWindow *window,
+			      gint      *x,
+			      gint      *y,
+			      gint      *width,
+			      gint      *height,
+			      gint      *depth)
 {
   GdkWindowPrivate *private;
   Window xwindow;
@@ -1585,6 +1588,12 @@
     *x = 0;
   if (y)
     *y = 0;
+  if (width)
+    *width = 0;
+  if (height)
+    *height = 0;
+  if (depth)
+    *depth = 0;
   if (private->destroyed)
     return;
   
@@ -1618,8 +1627,22 @@
 	    *x = wx;
 	  if (y)
 	    *y = wy;
+	  if (width)
+	    *width = ww;
+	  if (height)
+	    *height = wh;
+	  if (depth)
+	    *depth = wd;
 	}
     }
+}
+
+void
+gdk_window_get_root_origin (GdkWindow *window,
+			    gint      *x,
+			    gint      *y)
+{
+  gdk_window_get_root_geometry(window, x, y, NULL, NULL, NULL);
 }
 
 GdkWindow*


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