Index: xpra/client.py
===================================================================
--- xpra/client.py	(revision 2792)
+++ xpra/client.py	(working copy)
@@ -186,6 +186,11 @@
         self.change_speed = False
         self.readonly = opts.readonly
         self.windows_enabled = opts.windows
+        self.max_width, self.max_height = 0, 0
+        if opts.max_size:
+            parts = opts.max_size.split("x")
+            assert len(parts)==2, "invalid max_size: %s" % opts.max_size
+            self.max_width, self.max_height = int(parts[0]), int(parts[1])
         self._client_extras = ClientExtras(self, opts, conn)
         self.client_supports_notifications = opts.notifications and self._client_extras.can_notify()
         self.client_supports_system_tray = opts.system_tray and self._client_extras.supports_system_tray()
@@ -1128,7 +1133,8 @@
                 self._pid_to_group_leader[pid] = group_leader
                 log("new hidden group leader window %s for pid=%s", group_leader, pid)
             self._group_leader_wids.setdefault(group_leader, []).append(wid)
-        window = ClientWindowClass(self, group_leader, wid, x, y, w, h, metadata, override_redirect, client_properties, auto_refresh_delay)
+        window = ClientWindowClass(self, group_leader, wid, x, y, w, h, metadata, override_redirect,
+                                   client_properties, auto_refresh_delay, self.max_width, self.max_height)
         self._id_to_window[wid] = window
         self._window_to_id[window] = wid
         window.show_all()
Index: xpra/client_window.py
===================================================================
--- xpra/client_window.py	(revision 2792)
+++ xpra/client_window.py	(working copy)
@@ -191,16 +191,24 @@
 
 
 class ClientWindow(gtk.Window):
-    def __init__(self, client, group_leader, wid, x, y, w, h, metadata, override_redirect, client_properties, auto_refresh_delay):
+    def __init__(self, client, group_leader, wid, x, y, w, h, metadata, override_redirect,
+                 client_properties, auto_refresh_delay, max_width, max_height):
         if override_redirect:
             init_window(self, WINDOW_POPUP)
         else:
             init_window(self, WINDOW_TOPLEVEL)
+        log.info("new window %sx%s with metadata=%s", w, h, metadata)
         self._client = client
         self.group_leader = group_leader
         self._id = wid
         self._pos = (-1, -1)
         self._size = (1, 1)
+        self._max_width = max_width
+        self._max_height = max_height
+        if self._max_width>0:
+            w = min(w, self._max_width)
+        if self._max_height>0:
+            h = min(h, self._max_height)
         self._backing = None
         self.new_backing(w, h)
         self._metadata = {}
@@ -333,6 +341,19 @@
                 if v:
                     v1, v2 = v
                     hints[h] = float(v1)/float(v2)
+            if self._max_width>0:
+                maxw = hints.get("max_width", 2**16)
+                hints["max_width"] = min(maxw, self._max_width)
+                minw = hints.get("min_width")
+                if minw is not None and minw>self._max_width:
+                    hints["min_width"] = self._max_width
+            if self._max_height>0:
+                maxh = hints.get("max_height", 2**16)
+                hints["max_height"] = min(maxh, self._max_height)
+                minh = hints.get("min_height")
+                if minh is not None and minh>self._max_height:
+                    hints["max_height"] = self._max_height
+            log.info("hints=%s", hints)
             try:
                 set_geometry_hints(self, hints)
             except:
@@ -351,7 +372,7 @@
                                                  ("xpra", "Xpra")))
 
         modal = self._metadata.get("modal", False)
-        self.set_modal(modal or False)
+        self.set_modal(modal)
 
         if "icon" in self._metadata:
             width, height, coding, data = self._metadata["icon"]
@@ -474,7 +495,7 @@
             
 
     def do_map_event(self, event):
-        log("Got map event: %s", event)
+        log.info("Got map event: %s", event)
         gtk.Window.do_map_event(self, event)
         if self.group_leader:
             self.window.set_group(self.group_leader)
@@ -494,13 +515,18 @@
         gobject.idle_add(self._focus_change)
 
     def do_configure_event(self, event):
-        log("Got configure event: %s", event)
+        log.info("Got configure event: %s", event)
         gtk.Window.do_configure_event(self, event)
         if self._override_redirect:
             return
         x, y, w, h = get_window_geometry(self)
         w = max(1, w)
         h = max(1, h)
+        uw, uh = w, h
+        if self._max_width>0:
+            w = min(w, self._max_width)
+        if self._max_height>0:
+            h = min(h, self._max_height)
         ox, oy = self._pos
         dx, dy = x-ox, y-oy
         self._pos = (x, y)
@@ -520,6 +546,9 @@
             for window in self._override_redirect_windows:
                 x, y = window.get_position()
                 window.move(x+dx, y+dy)
+        if uw!=w or uh!=h:
+            log.warn("forcing window size down to %sx%s (from %sx%s), size request=%s", w, h, uw, uh, self.get_size_request())
+            gobject.idle_add(self.resize, w, h)
         if (w, h) != self._size:
             self._size = (w, h)
             self.new_backing(w, h)
@@ -530,6 +559,10 @@
         assert self._override_redirect
         w = max(1, w)
         h = max(1, h)
+        if self._max_width>0:
+            w = min(self._max_width, w)
+        if self._max_height>0:
+            h = min(self._max_height, h)
         self.window.move_resize(x, y, w, h)
         self.new_backing(w, h)
 
Index: xpra/gl/gl_client_window.py
===================================================================
--- xpra/gl/gl_client_window.py	(revision 2766)
+++ xpra/gl/gl_client_window.py	(working copy)
@@ -15,9 +15,11 @@
     
     gl_pixmap_backing_class = GLPixmapBacking
 
-    def __init__(self, client, group_leader, wid, x, y, w, h, metadata, override_redirect, client_properties, auto_refresh_delay):
+    def __init__(self, client, group_leader, wid, x, y, w, h, metadata, override_redirect,
+                 client_properties, auto_refresh_delay, max_width, max_height):
         log("GLClientWindow(..)")
-        ClientWindow.__init__(self, client, group_leader, wid, x, y, w, h, metadata, override_redirect, client_properties, auto_refresh_delay)
+        ClientWindow.__init__(self, client, group_leader, wid, x, y, w, h, metadata, override_redirect,
+                              client_properties, auto_refresh_delay, max_width, max_height)
         self.set_reallocate_redraws(True)
         self.add(self._backing.glarea)
 
Index: xpra/scripts/config.py
===================================================================
--- xpra/scripts/config.py	(revision 2791)
+++ xpra/scripts/config.py	(working copy)
@@ -263,6 +263,7 @@
                     "socket-dir"        : str,
                     "log-file"          : str,
                     "mode"              : str,
+                    "max-size"          : str,
                     #int options:
                     "quality"           : int,
                     "min-quality"       : int,
@@ -337,6 +338,7 @@
                     "xvfb"              : "Xvfb +extension Composite -screen 0 3840x2560x24+32 -nolisten tcp -noreset -auth $XAUTHORITY",
                     "socket-dir"        : "",
                     "log-file"          : "$DISPLAY.log",
+                    "max-size"          : "",
                     "quality"           : -1,
                     "min-quality"       : 50,
                     "speed"             : -1,
Index: xpra/scripts/main.py
===================================================================
--- xpra/scripts/main.py	(revision 2790)
+++ xpra/scripts/main.py	(working copy)
@@ -197,6 +197,11 @@
                           metavar="SPEED",
                           dest="speed", type="int", default=defaults.speed,
                           help="Use x264 image compression with the given encoding speed (1-100, 0 to use automatic setting). Default: %default.")
+    group.add_option("--max-size", action="store",
+                      dest="max_size", default=defaults.max_size,
+                      metavar="MAX_SIZE",
+                      help="The maximum size for all windows (ie: 800x600)"
+                      + " Default: %default.")
     group.add_option("--auto-refresh-delay", action="store",
                       dest="auto_refresh_delay", type="float", default=defaults.auto_refresh_delay,
                       metavar="DELAY",
@@ -302,6 +307,17 @@
         int(options.dpi)
     except Exception, e:
         parser.error("invalid dpi: %s" % e)
+    if options.max_size:
+        parts = options.max_size.split("x")
+        if len(parts)!=2:
+            parser.error("invalid max_size: '%s', please use the format WxH (ie: 800x600)")
+        try:
+            w = int(parts[0])
+            h = int(parts[1])
+        except:
+            parser.error("invalid max_size: '%s', please use the format WxH (ie: 800x600)")
+        if w<=0 or h<=0:
+            parser.error("invalid max_size: '%s' both dimensions must be positive")            
     if len(ENCRYPTION_CIPHERS)==0:
         #if no encryption options are available the option is not shown
         #but we still need to set a value to avoid errors later on:
