wxWidgets / Phoenix

wxPython's Project Phoenix. A new implementation of wxPython, better, stronger, faster than he was before.
http://wxpython.org/
2.29k stars 515 forks source link

Font sizes not considered correctly calculating display size using GridBagSizer (GTK3 version) #419

Closed tobschill closed 7 years ago

tobschill commented 7 years ago

I am having the impression that user defined font sized are not considered correctly calculating the display/layout size when using GridBagSizer in wxPython 4.0.0a3 (phoenix):

Trying to port a wxPython classic GUI to wxPython phoenix I noticed, that the displayed window is too small to show all defined widgts, e.g. some buttons where not shown completely. After some debugging I have found out, that all widgets are matched omitting my font definitions for labels and inputs.

I can reproduce this issue with an wxPython phoenix example for the GridBagSizer found here: http://xoomer.virgilio.it/infinity77/Phoenix/GridBagSizer.html

Here my adjusted version of example 2 (http://xoomer.virgilio.it/infinity77/Phoenix/_downloads/GridBagSizer.2.py) including wx.lib.inspection and some font definitions: GridBagSizer.2.debug.py.zip

Deactivating the SetFont definitions and thus using the default font size displays a frame showing all elements completely. The following sizes are reported for the frame:

Activating my settings with a 14 (point) size font, the Exit button is not displayed entirely. Now the following sizes are reported for the frame:

Using a even bigger font size of 24, the Exit button is missing completely:

So size and minsize don't have changed, bestsize matches the needed width and height for the frame.

I am using wxPython on Ubuntu 16.04 using the provided Python package and the latest wxPython phoenix 4.0.0a3 GTK3 wheel from https://wxpython.org/Phoenix/snapshot-builds/linux/gtk3/ubuntu-16.04/: Python 2.7.12 on linux2, wxPython 4.0.0a3.dev3059+4a5c5d9 gtk3 (phoenix)

Just to be improve my ticket I tried the wxPython phoenix GTK2 snapshot-build wheel - and to my surprise everything is working fine with the GTK2 version, the frame is correctly sized in the example and in my own project GUI. So the problems shown above seem to be related to GTK3, at least on Ubuntu 16.04. I currently don't have any other supported Linux distributions or Windows at hand to check further, sorry...

Thus I am not completely sure, if the effects I mentioned are really a bug of wxPython phoenix 4.0 or more a problem of GTK3..

So it would be nice if this could be checked - Thank you very much!

RobinD42 commented 7 years ago

First of all, I would replace the SetSizerAndFit with SetSizer because the former does not quite do what it's name implies and often leads to confusion. (IOW, it does more than SetSizer() and Fit()).

As to the sizing issue, I believe that this has to do with the asynchronous nature of X-Windows. At the time you are trying to size the frame to its contents the frame and the widgets and their fonts do not actually exist on the screen yet, there are just in-memory structures for them that still need to be flushed to the X-server. With GTK2 the system could calculate sizes before everything has been sent to the X-Server because it only supports one DPI at a time, but GTK3 is capable of supporting HiDPI screens and so on, so it doesn't know what the widget size will be with the new font at the point in time that you are telling the sizer to calculate the sizes and fit the frame.

The fix is easy however, just delay the Fit until after the frame is shown. And again, that does not happen when Show is called, it happens later when all the pending operations are flushed to the X-Server. However, it's easy to delay things until there's nothing else waiting to happen in wxPython using wx.CallAfter. So if you replace the SetSizerAndFit line with these then it should work as you expect:

self.SetSizer(sizer)
wx.CallAfter(self.Fit)