Split from #907.
There are too many places recording the same information, all with slightly different intents: the X11 window itself (and its parents..), the window model classes, the desktop manager, (and of course: the client)... Also relevant: the ownership information, initial window position and size hints, multiple clients (#41), etc..
This is a blocker for a number of tickets: #846, #988, #881 - and probably many others.
The basics:
geometry
property of all window models claims to be current (border-corrected, relative to parent) coordinates (x, y, w, h) for the window, it is actually retrieved via:
do_get_property_geometry
returns the value of the _geometry
attribute, if it is still set to None this method will first attempt to populate it by calling XGetWindowAttributes and use the first 5 attributes from the XWindowAttributes
structure:
int x, y; /* location of window */ int width, height; /* width and height of window */ int border_width; /* border width of window */
do_xpra_configure_event
is the handler for ConfigureNotify X11 events, in the base class implementation it will simply update the window geometry with the event data and then fire the "geometry" notify signal
get_position
and get_dimensions
are just shorthand versions for accessing parts of the geometry
The real trickery starts in WindowModel:
_NET_MOVERESIZE_WINDOW
messages cause the window geometry to get updated, after sanitizing the event data with the size-hints, we call ConfigureNotify
size-hints
should be moved here - only used here and doesn't make sense for OR windows... (what about "strut" - does that make any sense for OR windows?)
actual-size
should be the same as size portion of the geometry?
requested-position
and requested-size
from the data we get back from calling XGetGeometry
do_xpra_configure_event
is a little bit different and calls resize_corral_window
which may or may not update actual-size
and user-friendly-size
and "geometry"
do_child_configure_request_event
is the handler for ConfigureRequest Events and will update the geometry using the event's attribute, for the attributes which aren't set it will fallback to using requested-position
and requested-size
(is that right??) - the actual updating is done via _update_client_geometry
And the real ugly parts:
ownership_election
probably deserves a entire wiki page to itself... it may reparent the window to the parking window, call _update_client_geometry
, raise the corral window, etc..
maybe_recalculate_geometry_for
is similar: checks for ownership may call _update_client_geometry
_update_client_geometry
will call _do_update_client_geometry
with values it gets from the owner (if there is one), or from requested-position
and requested-size
_do_update_client_geometry
does geometry calculations (honour "size-hints", etc) and then does the configure + notify
The WM object:
do_child_configure_request_event
does a configure + notify for windows that don't have a model yet
The WorldWindow is just about GTK / X11 focus hell. Not very relevant here.
The DesktopManager is a hidden gtk widget which sits between out server class and the window models, deal with the ownership election business. Each window is also recorded there using a (very confusingly named) model containing the following attributes:
maybe_recalculate_geometry_for
The Source and WindowSource try very hard not to deal with any geometry stuff, for 2 reasons:
The only call made is to get_dimensions
so we know the size of the window, and get_image
to get the window pixels.
The server is where some of the ugliest code lives:
_, _, w, h, _ = window.get_property("client-window").get_geometry() x, y, _, _, _ = window.corral_window.get_geometry()
if window.is_OR() or window.is_tray(): x, y, w, h = window.get_property("geometry")[:4] else: x, y, w, h = self._desktop_manager.window_geometry(window)[:4]
Maybe we should keep the desktop manager, but have one per client with some shared data structures? (for things like resize counter?) Maybe it should handle OR windows too? (and just delegate those calls so we don't have this ugly if/else mess)
Maybe start by exposing as much as we can via xpra info.
More notes:
size-hints
to window model
user-friendly-size
(not used)
get_position
and r11031 removes actual-size
, we now use the geometry attribute instead
get_dimensions
would be too hard for now - and as of r11031 it's implemented just once in core, cleanly
actual-size
should always be the same as the corral window size - the only external caller is the x11 server's _window_resized_signaled
which could access the corral window if needed
requested-size
and requested-position
are set from the window's initial geometry (queried via XGetGeometry
), we update it when receiving a configure request on the child window (when the application requests it), but not when we handle _NET_MOVERESIZE_WINDOW messages. They are only used for the geometry when: there is no owner, or when the configure request omits some values. This looks fine.
maybe_recalculate_geometry_for
already handles most of this
Remaining tasks:
do_get_property_geometry
ugly accessor method, it should never be used if we keep the geometry up to date, and use updateprop
to fire geometry notifications?
More updates, see:
Note: this removes the border attribute from geometry, which we never really used anyway.
Things that will need checking:
Summary: the window geometry code is cleaner and more consistent. It is now handled as a regular property.
The current geometry is always accessible with:
$ xpra info | grep -e "window.*geometry=" window[1].client-geometry=(370, 132, 499, 316) window[1].geometry=(370, 132, 499, 316)
(the client-geometry is for non-OR windows and shows where the window is mapped for this particular client - which should be the same as the server's geometry)
This the same geometry which is also used with xpra screenshot and with the sync-xvfb option (#988).
These changes need to be tested with most of the window test apps to make sure this has not caused any regressions. Will follow up in #41, #846 and #881.
Tested a Fedora 21 trunk r11118 Server from a Fedora 20 trunk r11118 Client:
Played around with the python test scripts for a while
Passing back to you for now. Pass it back to us (either afarr or myself) if you need some more testing, as always.
Does not seem to have caused any major breakage after all, will follow up in the other geometry related tickets: #723, #772, #994?, #809, #881, #846, #968, #911
Breakage found: #1120.
See also #1121.
this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/990