====== resize tweaks ====== First: the method gtk.Window.resize() doesnt't work with a single argument (setting the other to -1, as instead does gtk.Widget.set_size_request()). OK, this is documented, though ugly. Now: if a gtk.Window **w** has size (100,100) and we run the following code: w.resize(200,200) size = w.get_size() w.resize(*size) , then the window won't resize to 200,200, but to 100,100. In fact "resize" doesn't really resize, it just queues a resize process, while if we use get_size we get the //current// size, not the queued one. This means if several functions try to resize (and it makes sense, if each one takes care of a single dimension), we have race conditions. I solved that (both problems) with the following functions: def unset_real_size(window, event): """Fields 'real width' and 'real height' become obsolete (or at least useless) when a resize actually takes place. """ window.set_data('real width', None) window.set_data('real height', None) handler = window.get_data('configure handler') if handler: # The callback is now useless; remove it. window.disconnect(handler) window.set_data('configure handler', None) def ensure_configure_handler(window): """Ensure that unset_real_size is called. """ if not window.get_data('configure handler'): new_handler = window.connect('configure-event', unset_real_size) window.set_data('configure handler', new_handler) def get_width(window): width = window.get_data('real width') if not width: width = window.get_size()[0] return width def get_height(window): height = window.get_data('real height') if not height: height = window.get_size()[1] return height def set_width(window, width): ensure_configure_handler(window) window.set_data('real width', width) height = get_height(window) window.resize(width, height) def set_height(window, height): ensure_configure_handler(window) window.set_data('real height', height) width = get_width(window) window.resize(width, height) ==== set_size_request ==== Notice that set_size_request has a similar problem: if a gtk.Widget **widget**'s get_size_request gives (-1,-1) and I run the following code: widget.set_size_request(100,100) widget.set_size_request(-1, -1) , it won't expand at all, nothing will happen. This is an issue if you wanted to use this as a hack to resize the widget but let to the user the possibility to shrink it again; an hackish way to solve this is instead the following code: widget.set_size_request(100,100) gobject.idle_add(widget.set_size_request, -1, -1) ====== gtk.ScrolledWindow ====== While gtk.Containers usually propagate size requests from child(ren) to parent, gtk.ScrolledWindow doesn't; instead, it sets a predefined (hardcoded, presumably) size. Apparently, this makes sense: if you want the whole widget shown, why a ScrolledWindow?! However, there are 2 situations in which this is hateful: * we have a widget that should take all the space available, but without overflowing the screen; if space isn't enough, and only in that case, the Scrollbar should appear. Notice that to reach that behaviour, we should also change gtk.Window behaviour so that its child(ren)'s size_request don't expand it so much that it overflows the screen (if we really want it to be big, we have set_size_request()!). * we have a widget that should take all the space needed (even though not known precisely and then not hardcodeable) at startup, but its toplevel gtk.Window shouldn't resize every time it changes size, and in that case only the Scrollbars should appear if needed. I solved this with the following code (**widget** is the widget we want to resize so that it is fully shown), thanks to //owen// in freenode.irc's //#gtk+// for the hint: scrolledwindows = [] scrolledwindows_policies = [] scrolledwindows_hscrollbars = [] while widget: # The ScrolledWindows stop propagation of queue_redraws, unless they # have the scrollbars disabled, so here we disable them... if gobject.type_is_a(widget, gtk.ScrolledWindow): scrolledwindows.append(widget) scrolledwindows_policies.append(widget.get_policy()) widget.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER) scrolledwindows_hscrollbars.append(widget.get_hscrollbar()) widget = widget.get_parent() toplevel = treeview.get_toplevel() # ... then we can take the size... new_width = toplevel.size_request()[0] # ... add the size of bars... bars_width = 0 for index in range(len(scrolledwindows)): # (not needed if the policy hides it) if scrolledwindows_policies[index][0] == gtk.POLICY_ALWAYS: bars_width += scrolledwindows_hscrollbars[index].size_request()[0] scrolledwindows[index].set_policy(*scrolledwindows_policies[index]) # print "width:", new_width # ... and put together the total size. new_width += bars_width