Xpra: Ticket #263: add a --max-size option to limit the maximum window size

On a 2560x1600 monitor, having maximized windows is generally not a good thing: latency goes way up and the refresh rate collapses, basically the application becomes unusable. (and as big monitors become cheaper, this problem will only worsen - LAN bandwidth has remain pretty static over the last 10 years)

This flag should be either a "server default with client override" or a "server constraint that client can restrict further if desired" (both solutions are acceptable). We just need to be careful that:

Thu, 21 Feb 2013 14:58:04 GMT - Antoine Martin: status changed; owner set

Oh well, I was hoping that it would be a simple matter of setting some properties using gtk.Window.set-geometry-hints, but unfortunately that does not affect the maximize button... so we'll need something else for that (and probably also deal with fullscreen properly as per #264) On X11 clients, I was hoping we could just remove maximize from _NET_WM_ALLOWED_ACTIONS, but this is managed by the client window manager - so we shouldn't touch it I think.

Here's a trivial hard-coded patch which limits resizing to 800x600:

--- src/xpra/server_source.py	(revision 2745)
+++ src/xpra/server_source.py	(working copy)
@@ -640,6 +640,15 @@
                     v = getattr(hints, attr)
                     if v is not None:
                         hints_metadata[metakey] = v
+            MAXW = 800
+            MAXH = 600
+            if True:
+                ms = hints_metadata.get("maximum-size")
+                if ms:
+                    mw, mh = ms
+                else:
+                    mw, mh = 0, 0
+                hints_metadata["maximum-size"] = max(mw, MAXW), max(mh, MAXH)
             return {"size-constraints": hints_metadata}
         elif propname == "class-instance":
             c_i = window.get_property("class-instance")

It looks like (preventing window maximisation/minimisation in x window system) it is not possible (at least with x11, and therefore probably with gtk too) to prevent maximization... We can only detect it and resize back down to our maximum size (which will flicker briefly). When doing this, we will have to be careful to not send the maximized dimensions to the server with each resize event (these sizes also need to be clamped).

So, if we go with native code instead, we find:

So I think we should go with the easy option for now, and revisit later.

Mon, 25 Feb 2013 17:52:17 GMT - Antoine Martin:

Well, that's a problem... I was making progress on Linux, then when I tried on win32 I found that gtk/win32 does not honour window sizes:

import gtk
x.set_geometry_hints(max_width=600, max_height=400)

You can resize it to any size you like, though interestingly the "maximize" button is greyed out.

Mon, 25 Feb 2013 18:23:17 GMT - Antoine Martin: attachment set

adds --max-size option (but does not work on win32..)

Mon, 25 Feb 2013 19:06:56 GMT - Antoine Martin:

According to MINMAXINFO.ptMaxTrackSize should be set to the maximum dimensions when gdk receives the WM_GETMINMAXINFO event. But the example from comment:2 seems to prove that it does not?

Wed, 27 Feb 2013 09:29:33 GMT - Antoine Martin:

Sent question to the set_geometry_hints max_width/max_height not honoured on win32

Sun, 17 Mar 2013 11:24:29 GMT - Antoine Martin:

Since I've had no reply on the mailing list, I've filed a bug on gnome's bugzilla

Fri, 22 Mar 2013 13:20:52 GMT - Antoine Martin: milestone changed

Still no answer there - I think we should look at using a different toolkit for the client code, qt or even native versions.


Fri, 17 May 2013 07:53:25 GMT - Antoine Martin:

See also #338

Mon, 19 May 2014 11:58:22 GMT - Antoine Martin:

GTK2 is dead, I'm adding this to #90 instead.

Mon, 19 May 2014 11:58:35 GMT - Antoine Martin: status changed; resolution set

Thu, 12 Jun 2014 04:41:40 GMT - Antoine Martin:

Looks like the bug got fixed in GDK_HINT_MAX_SIZE ignored on Win32

Now if we could only get a new win32 build of gtk + pygtk... I have found some newer documentation on how to do it here: GTK+ for Windows, and it doesn't look too bad... So we could get a newer GTK build, with newer libpng, etc.. (see #544) without needing to wait for GTK3 (#90)

See for example:

Mon, 15 Sep 2014 16:37:59 GMT - Antoine Martin:

FWIW: the GTK3 builds don't honour it either :(

I've added a simple test script which can be used from the command line natively on win32: r7633.

Tue, 16 Sep 2014 11:54:41 GMT - Antoine Martin: attachment set

patch for accessing the hwnd of a gi gdk window

Tue, 16 Sep 2014 13:15:11 GMT - Antoine Martin: status changed; resolution deleted

Still TODO for later:

afarr: please check that:


Tue, 16 Sep 2014 13:15:23 GMT - Antoine Martin: owner, status, milestone changed

Thu, 02 Oct 2014 03:34:04 GMT - Antoine Martin:

Bug reported in #263 which can be triggered using browser/xpra/trunk/src/tests/xpra/test_apps/test_window_maxsize.py (not sure how I missed that since this is exactly the code that the test was designed to exercise..):

2014-10-01 13:00:08,288 with hints={'min_width': 357, 'min_height': 82}
Traceback (most recent call last):
  File "xpra\client\client_window_base.pyc", line 237, in set_size_constraints
TypeError: apply_geometry_hints() takes exactly 2 arguments (1 given)

is fixed in r7858.

Thu, 02 Oct 2014 23:29:20 GMT - alas: owner changed

Testing with 0.156.0 r7865 windows client (windows 8.1) vs. 0.15.0 r7865 server (fedora 20) ... --max-size= works nicely indeed.

Testing with browser/xpra/trunk/src/tests/xpra/test_apps/test_window_maxsize.py behaves as expected, with the windows able to be stretched to new size limits if they are larger than previous, and with the window shrinking to fit new constraints if the new are smaller than the current size (with appropriate notifications server-side).

Testing by stretching xterms and browser windows also shows it to be working very well, with Uh-oh messages server side when the re-sizing limits are hit.

Fri, 03 Oct 2014 16:24:48 GMT - Antoine Martin:

with Uh-oh messages server side when the re-sizing limits are hit (..) Note, when a browser window (in this case google-chrome) is expanded to the limit size, and then moved around the workarea ...

Well spotted. That's because the max-size we allow the user to set may not be a valid dimension for the window (ie: an xterm requires: width_inc=6, height_inc=13, min_height=17, base_width=19, min_width=25, base_height=4), so we may have to round them down. Then I found out that the win32 api controls the window dimensions with the borders included, so these need substracting. Both done in r7870.

(..) google-chrome video fullscreen, then Esc key un-fullscreen .. I suspect it is a separate issue, will open a new ticket and include a before & after screenshot.

Please do.

Final note - the disabled maximize button ... it would be nice if that could be "controlled" to the same max-size as the connection CLI setting... but I suspect that's a whole new can of worms.

AFAIK, we have zero control over that unfortunately. Feel free to file an enhancement request with Microsoft, Apple, GTK, etc.. ;)

Fri, 03 Oct 2014 21:16:56 GMT - alas:

window[1].size=(1573, 1304)
window[2].size=(499, 316)
window[3].size=(1573, 1309)
window[8].size=(500, 200)

... where the 499x316 is a normal sized xterm, the 500x200 is a test_window_maxsize window, the 1573x1309 is a chrome window stretched to its limit, and the 1573x1304 is another xterm stretched to its limit. (I'm not sure this is anything to worry about, just thought I'd mention it.)

Sat, 22 Nov 2014 19:58:54 GMT - Antoine Martin: status changed; resolution set

Note, xterm seems to have a 5 pixel buffer on the second value that reduces its max-size on OSX

Not sure what that means.. but since things seem to work ok, I'm not going to worry about it!


Mon, 18 May 2015 16:20:04 GMT - Antoine Martin:

Started seeing this during testing on win32:

Traceback (most recent call last):
  File "_ctypes/callbacks.c", line 314, in 'calling callback function'
  File "xpra\platform\win32\window_hooks.pyc", line 109, in _wndproc
  File "xpra\platform\win32\window_hooks.pyc", line 74, in on_getminmaxinfo
TypeError: must be a ctypes type

The debug that was added in r9136 caused a name clash and broke the getminmaxinfo callback. Fixed in r9444 (backport in r9445).

Sat, 27 Jun 2015 13:11:18 GMT - Antoine Martin:

Note: this hook is no longer necessary with GTK3: as of r9737, we skip it with py3k.

Sat, 23 Jan 2021 04:49:57 GMT - migration script:

this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/263