window geometry/positioning
- From: Havoc Pennington <hp redhat com>
- To: gtk-devel-list gnome org
- Subject: window geometry/positioning
- Date: 10 Mar 2001 00:36:02 -0500
Hi,
Owen and I discussed the issue of window positioning and geometry, and
worked out a proposal. This addresses bug:
http://bugzilla.gnome.org/show_bug.cgi?id=17167
I'm going to try to write it down, but it's late at night and I may
get stuff wrong.
The basic problem is that right now we have a haphazard and
not-very-logical set of functions for getting/setting window size and
position. The result is that people resort to all kinds of weird hacks
involving widget->window.
A brief catalog of what we have now:
gdk_window_get_origin(): gets the origin of a toplevel window
with respect to the root window; this is the origin of the window
itself, not the window manager decoration frame.
gdk_window_get_root_origin(): I believe this one gets the origin of a
toplevel window's frame. It uses the "walk up to one below the root
window" heuristic to find the frame (this could be improved a bit for
some WM's that set properties marking the frame).
gdk_window_get_deskrelative_origin(): gets the origin with respect to
enlightenment's weird desktops, on other window managers equivalent
to gdk_window_get_origin() I believe.
I could be wrong about these three, I'm just briefly glancing at them.
When you map a window or move it with gdk_window_move(), you are
positioning the "reference point" determined by the window
gravity. The reference point is the top left corner with the default
NorthWest gravity (GdkWindows default to NorthWest, and GTK 1.2 has no
way to set the gravity; GTK 2 adds gravity to GdkGeometry). However,
you aren't really positioning the window itself, but rather the window
frame. That is, if you map a window at position 0,0, then the window
gets shifted down to make room for the titlebar and border. At least
this is what I remember, my ICCCM is at work and I'm at home. ;-) So
if you specify the geometry +0+0, the frame goes at that position, not
the window itself. The exception is if you specify StaticGravity,
which means that your requested position is for the window itself, not
the frame.
The freedesktop.org window manager spec clarifies this issue because
lots of WMs screw it up:
http://www.freedesktop.org/standards/wm-spec/x277.html
If you gdk_window_resize(), then the reference point determined by the
gravity stays in a fixed position as the window resizes. Here I don't
think it makes a difference whether you think of the reference point
as a corner of the frame or a corner of the window itself.
On the GTK level, we have:
gtk_widget_set_uposition(): for toplevels, this oddly enough sets the
PPosition (program position) hint rather than the USPosition
(user-specified position) hint, and also calls gdk_window_move() if
the window is realized. So basically it positions the window frame
unless StaticGravity is set. I'm not clear on what effect setting the
PPosition hint actually has, since gdk_window_move() works anyway
(?).
gtk_window_set_default_size(): only works before mapping the window,
emulates the user setting the window size, sets the size of the
window itself not the frame
gtk_widget_set_usize(): on toplevels, changes the minimum size.
We came up with the following use-cases for where people are trying to
use these things on toplevels:
- "do your own session management" - since all session managers
seem to suck, apps try to save and restore window positions
and sizes.
- "Java IDE" - we saw a Java IDE - I think it was Forte - that did
this fairly broken thing attempting to tile its windows
itself. That is, it tried to snap the edges of window frames
together, basically do its own window management.
Another case of this: sometimes you see audio apps that are
conceptually a stack of stereo components, that can be stacked
together. (However those usually turn off frames, which makes
it a different use case.)
- XMMS/GtkHandleBox - this case is "I want to ignore the window
manager", you turn off decorations (or much worse, use
override redirect) and then move/resize the window using controls
inside the app
- --geometry command line option; here you want to set the window
position on startup
- XawTV: XawTV apparently wanted to retrieve the position of a window
in root window coordinates, so it could directly write into the
framebuffer at that point.
- Full-screen presentation application: here you want to
turn off decorations and set your size to the full screen size.
- panels, docks, etc. that position themselves manually and aren't
really window managed.
So we are proposing the following functions on the GTK level, with the
exact GDK implementation to be decided:
gtk_window_set_gravity ()
gtk_window_get_gravity ()
These are convenience functions to avoid using GdkGeometry.
gtk_window_set_size ()
gtk_window_get_size ()
These set and get the size of the frameless window; the resize
keeps the reference point determined by the window gravity in
a fixed location. The size is set as for
gtk_window_set_default_size(), as if the user had resized it.
gtk_window_set_position ()
gtk_window_get_position ()
These set and get the position of the reference point as determined
by the window gravity; so for StaticGravity, they are the same
as gdk_window_get_origin(), for NorthWest gravity the same as
gdk_window_get_root_origin(). The position is always in root window
coordinates, even on weird Enlightenment desktops where the
desktop's 0,0 may not be 0,0 on the root window.
gtk_window_set_frame_size ()
gtk_window_get_frame_size ()
Attempts as best we can to set and get the size of the window
_including the window manager frame_. These functions can't
be implemented reliably, but we can do a good bit better
than naive application authors might do.
gdk_workspace_get_extents ()
Returns the extents of the "workspace." This takes into
account Enlightenment's weird desktops, and also the WM spec
"struts". So the workspace is the area in which you might consider
positioning your app. If you want to position at 0,0, probably you
really want the top left corner of the workspace. If you want to
"maximize" an app, you'd really use gtk_window_maximize(), but
ignoring that you'd make it fill the workspace extents.
gdk_desktop_get_extents ()
(Not discussed with Owen, but I think needed for panels, fullscreen
apps, etc.)
Returns the full extents of the current desktop in root window
coordinates; this would normally be the area of the root window
which is on the user's monitor. Usually (0,0) to
(screen_width,screen_height) but may not be on odd window managers.
So then the use cases are supposed to work as follows:
- "do your own session management" just uses
gtk_window_get/set_size(), gtk_window_get/set_position().
In current GTK you have to gdk_window_get_root_origin(),
but it doesn't work with the Enlightenment desktop case.
Then you gtk_widget_set_uposition().
- "Java IDE" uses gtk_window_get/set_frame_size(). There's no
sane way to do this with current GTK (since there's no very good
way to implement it in X ...)
- XMMS and GtkHandleBox can actually use
gtk_window_begin_resize_drag() and gtk_window_begin_move_drag().
But if they didn't do that, they would use set_size() and
set_position().
With current GTK, you can just use gdk_window_move_resize(),
since there's no frame to worry about.
- --geometry command line arg just uses gtk_window_set_size()
and gtk_window_set_position(). Done in the same way as
"session management" with current GTK.
- XawTV would use gtk_window_get_position() after setting the
window to StaticGravity, or more likely just
gdk_window_get_origin().
- Full-screen presentation app would call gdk_desktop_get_extents()
then gtk_window_set_size() to those extents.
- Panels and docks could also just use set_size() and set_position().
With current GTK, the panels and the presentation app would
probably use gdk_screen_width()/gdk_screen_height() as the extents,
which may on occasion be wrong.
So find the bugs in this mail, I'm implementing this soon.
Havoc
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]