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..
geometryproperty 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_geometryreturns the value of the
_geometryattribute, 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
int x, y; /* location of window */ int width, height; /* width and height of window */ int border_width; /* border width of window */
do_xpra_configure_eventis 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_dimensionsare just shorthand versions for accessing parts of the geometry
The real trickery starts in WindowModel:
_NET_MOVERESIZE_WINDOWmessages cause the window geometry to get updated, after sanitizing the event data with the size-hints, we call ConfigureNotify
size-hintsshould 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-sizeshould be the same as size portion of the geometry?
requested-sizefrom the data we get back from calling XGetGeometry
do_xpra_configure_eventis a little bit different and calls
resize_corral_windowwhich may or may not update
do_child_configure_request_eventis 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-size(is that right??) - the actual updating is done via
And the real ugly parts:
ownership_electionprobably 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_foris similar: checks for ownership may call
_do_update_client_geometrywith values it gets from the owner (if there is one), or from
_do_update_client_geometrydoes geometry calculations (honour "size-hints", etc) and then does the configure + notify
The WM object:
do_child_configure_request_eventdoes 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:
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.
size-hintsto window model
get_positionand r11031 removes
actual-size, we now use the geometry attribute instead
get_dimensionswould be too hard for now - and as of r11031 it's implemented just once in core, cleanly
actual-sizeshould always be the same as the corral window size - the only external caller is the x11 server's
_window_resized_signaledwhich could access the corral window if needed
requested-positionare 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_foralready handles most of this
do_get_property_geometryugly accessor method, it should never be used if we keep the geometry up to date, and use
updatepropto 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.client-geometry=(370, 132, 499, 316) window.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).
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.
Breakage found: #1120.
See also #1121.
this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/990