Opened 3 years ago

Closed 2 years ago

#17585 closed defect (fixed)

GTK+3.20 sizing failures

Reported by: dghart Owned by:
Priority: normal Milestone: 3.0.3
Component: wxGTK Version: dev-latest
Keywords: gtk+3.20 sizing Cc: swt@…
Blocked By: Blocking:
Patch: no

Description

Fedora 24 has just been released, and its wx3 programs use gtk+3.20.6. Testing mine showed sizing issues that aren't present with earlier gtk3 versions. Obvious workarounds like Layout() and SendSizeEvent() calls, either immediate or delayed, failed to help. However resizing the program, by mouse or programmatically, does work. This happens with both wx3.0.2 and a recent wx3.1.1.

I've attached a diff to the 'minimal' sample that demonstrates the problem, which occurs when a notebook page contains a wxSplitterWindow. You can see clickable thumbnails of the results at http://4pane.co.uk/misc/wx/gtk3-3.20-sizing/Screenshots.htm

When the desktop environment is gnome, kde or xfce, page one shows only an 'icon', which is probably the shrunken contents. Adding a page and switching to it with the menu results in page 2 displaying correctly but page 1 not. Adding a page and switching to it using the keyboard (ctrl-a followed by the 'right' arrow) results in both pages showing only the icon. Resizing the sample makes all the current pages display correctly, but adding further pages with the keyboard again makes each show only the icon.
Terminal output will typical include:
(minimal:5399): Gtk-WARNING: Negative content width -13 (allocation 5, extents 9x9) while allocating gadget (node entry, owner GtkEntry)

When the DE is unity (testing on ubuntu 16.04 with a self-built gtk+3.20.6) the same thing happens initially, but almost anything fixes it e.g. clicking off the sample.

Running my program or the patched sample in LXDE shows similar problems, plus others. The sample starts empty. Adding pages with the keyboard shortcut doesn't alter the display. Using the menu does, and page 1 now displays both sides of the splitter in the top-left corner, small but recognisable. Moving the mouse into the wxGenericDirCtrl section usually expands the page. Once again, resizing the program corrects all current pages.

Unpatched samples that start empty in LXDE include combo, dialogs, erase, exec, htmlbox and splitter. Ones that don't include grid, richtext, text and widgets. Aui asserts and starts malformed.
The splitter sample starts empty, and when resized the initial display is incorrect. Splitting horizontally, then vertically again results in the correct appearance.
The text sample's multiline fields are initially too small, and the log section invisible. Resizing fixes both.

Finally, again in LXDE, some dialogs (e.g. most of those in the 'help' sample) display with a width of about 1, making them hard hard to locate let alone use. The terminal output for e.g. the 'help' File > About Help Demo dialog is:

(help:30006): Gtk-CRITICAL **: gtk_box_gadget_distribute: assertion 'size >= 0' failed in GtkScrollbar
(help:30006): Gtk-CRITICAL **: gtk_box_gadget_distribute: assertion 'size >= 0' failed in GtkScrollbar
(help:30006): Gtk-CRITICAL **: gtk_box_gadget_distribute: assertion 'size >= 0' failed in GtkScrollbar
(help:30006): Gtk-WARNING **: Negative content width -5 (allocation 2, extents 4x3) while allocating gadget (node toolbar, owner GtkToolbar)
(help:30006): Gtk-WARNING **: Negative content height -6 (allocation 1, extents 4x3) while allocating gadget (node toolbar, owner GtkToolbar)
(help:30006): Gtk-WARNING **: Negative content width -5 (allocation 2, extents 4x3) while allocating gadget (node toolbar, owner GtkToolbar)
(help:30006): Gtk-WARNING **: Negative content height -6 (allocation 1, extents 4x3) while allocating gadget (node toolbar, owner GtkToolbar)
(help:30006): Gtk-WARNING **: Negative content height -10 (allocation 1, extents 5x6) while allocating gadget (node button, owner GtkToggleButton)

Attachments (2)

minimal.diff download (3.2 KB) - added by dghart 3 years ago.
screenshot_1.png download (6.0 KB) - added by AmandaM 3 years ago.
Shows a sizing problem on a wxStaticText component.

Download all attachments as: .zip

Change History (18)

Changed 3 years ago by dghart

comment:1 Changed 3 years ago by swt2c

  • Cc swt@… added

Changed 3 years ago by AmandaM

Shows a sizing problem on a wxStaticText component.

comment:2 Changed 3 years ago by AmandaM

I can confirm this issue.

I created a very simple program which consists of a wxStaticText and a wxComboBox. If I change the font on the wxStaticText the text does not size correctly. Please see attachment.

The following code works perfectly on wxGTK2 but not wxGTK3.

My GTK version is 3.20.8 (vanilla source).

#include <wx/wx.h>
#include <wx/combobox.h>
#include <wx/sizer.h>
#include <wx/frame.h>
#include <wx/textctrl.h>

class Test_Frame : public wxFrame
{

public:
    Test_Frame() : wxFrame(NULL, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE)
    {

        wxPanel * panel = new wxPanel(this);

        wxFont font = wxFont(16, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false);
        wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
        wxStaticText* s1 = new wxStaticText(panel, wxID_ANY, "Label", wxDefaultPosition, wxDefaultSize, 0);
        wxComboBox* cbox = new wxComboBox(panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0);
        s1->SetFont(font);

        sizer->Add(s1, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
        sizer->Add(cbox, 1, wxALL | wxEXPAND, 5);

        panel->SetSizer(sizer);
        sizer->SetSizeHints(this);
        //sizer->Fit(this);
        SetSize(400, 100);
    }
    ~Test_Frame() { }

private:


};

class AS : public wxApp
{

public:
    virtual bool OnInit()
    {
        Test_Frame *mainApp = new Test_Frame;
        mainApp->Show(true);

        return true;
    }
};

IMPLEMENT_APP(AS);






comment:3 Changed 3 years ago by vadz

  • Milestone set to 3.2.0
  • Status changed from new to confirmed

I can indeed reproduce this with

  • samples/minimal/minimal.cpp

    diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
    index f765a70..8bf27a1 100644
    a b bool MyApp::OnInit() 
    177177    CreateStatusBar(2);
    178178    SetStatusText("Welcome to wxWidgets!");
    179179#endif // wxUSE_STATUSBAR
     180
     181    wxPanel * panel = new wxPanel(this);
     182
     183    wxFont font = wxFont(16, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false);
     184    wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
     185    wxStaticText* s1 = new wxStaticText(panel, wxID_ANY, "Label", wxDefaultPosition, wxDefaultSize, 0);
     186    wxComboBox* cbox = new wxComboBox(panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0);
     187    s1->SetFont(font);
     188
     189    sizer->Add(s1, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
     190    sizer->Add(cbox, 1, wxALL | wxEXPAND, 5);
     191
     192    panel->SetSizer(sizer);
     193    sizer->SetSizeHints(this);
     194    SetSize(400, 100);
    180195}
    181196
    182197

The key part is changing the static text font size, without it everything works correctly, so I'm not sure if it's exactly the same problem as the one that was originally reported (we don't change font size anywhere in the notebook code, do we?).

Concerning this bug, it looks like GTK+ doesn't take into account the font size change immediately any more somehow, i.e. for me wxStaticText::DoGetBestSize() returns 34*15 initially, before the font change, and still returns 34*15 later, during layout, when the new font should have been already taken into account, but does return 57*25 when resizing the window later, explaining that the layout jumps in place when you do it. No idea why/where does this happen yet, though...

comment:4 Changed 3 years ago by pcor

See #16088

comment:5 Changed 3 years ago by vadz

Sorry, I still don't understand what has changed in 3.20 as this particular example worked fine before (with 3.18, I think, and certainly with 3.16).

comment:6 Changed 3 years ago by dghart

Some updates, first about the font-size issue. As I've been bisecting gtk+ I checked this too and found that Paul is correct: it doesn't happen in gtk 3.4.0 but does on 3.6.0. It's also present on debian jessie's 3.14.5.

I expect I misunderstand the situation but, looking at the #16088 commit, rd2e4b3520ba2dec8348b2381de04917b56d22d38, I wonder if there could be e.g. a wxLogDebug warning given when wxWindowGTK::GTKSizeRevalidate is called? Or could it itself arrange a delayed resize?

comment:7 Changed 3 years ago by dghart

Bisecting gtk+ shows that the original problems are caused by two commits. The major one is https://git.gnome.org/browse/gtk+/commit/?id=6866d1 "widget: Make gtk_widget_queue_allocate() not resize. This commit toggles the big switch. We now don't run size_allocate() from the toplevel up anymore in cases where we don't need to..."

The 'samples starting empty' issue on LXDE is caused by https://git.gnome.org/browse/gtk+/commit/?id=6144b2 "window: Remove suspicious branch. This commit was found to make emacs windows shrink, but the reversal caused more widespread damage than initially expected...". The commit message goes on to say that the author would be willing to revert if it causes problems.

Reverting the second commit also solves the above issues in the LXDE 'minimal' and 'aui' samples and the 'help' dialogs, but not the 'splitter' size problem.

comment:8 Changed 3 years ago by pcor

  • Milestone changed from 3.2.0 to 3.0.3

Thanks for doing the work to bisect this. The font size stuff is clearly #16088. As for the original problems, I can't claim to understand what those commits are doing, but at least some of the problems are related to our deferred show mechanism. If I use SetClientSize() on the TLW, the modified minimal sample looks fine. So that's a possible workaround.

comment:9 Changed 3 years ago by Paul Cornett <paulcor@…>

In 3b4ee5a031b1c2fa29772b90751a82dd7f1d3de0/git-wxWidgets:

Fix some sizing problems with GTK3

A change in size-allocate handling with GTK+ 3.20 exposed a flaw in our method for
deferring queue-resize requests. Using an idle callback to process the requests
did not work well with the GdkFrameClock-based system used since GTK+ 3.8. Using
the "check-resize" signal works better. Also with GTK+ >= 3.20, it seems necessary
to manually work the queue-resize up to the TLW, as otherwise the resized widgets
don't get updated without an external size-allocate event.
See #17585

comment:10 Changed 3 years ago by dghart

Thanks for the fix! I confirm it works for the various sizing issues affecting my program in fedora 24.
It also fixes most of them both in the program and the samples when using LXDE in ubuntu; exceptions include the splitter layout before resplitting, and the width==1 'help' dialogs.

Do you think this will be back-portable to 3.0.3?

comment:11 Changed 3 years ago by pcor

Thanks for the feedback. Yes, I will backport this.

comment:12 Changed 3 years ago by Paul Cornett <paulcor@…>

In 6475376931bf316a4fd791114408f7c1fc2fe836/git-wxWidgets:

Fix some sizing problems with GTK3

A change in size-allocate handling with GTK+ 3.20 exposed a flaw in our method for
deferring queue-resize requests. Using an idle callback to process the requests
did not work well with the GdkFrameClock-based system used since GTK+ 3.8. Using
the "check-resize" signal works better. Also with GTK+ >= 3.20, it seems necessary
to manually work the queue-resize up to the TLW, as otherwise the resized widgets
don't get updated without an external size-allocate event.
See #17585

(backport of 3b4ee5a031b1c2fa29772b90751a82dd7f1d3de0)

comment:13 Changed 3 years ago by pcor

3b4ee5a0 / 64753769 causes a serious regression when not using "overlay scrolling". It's easily seen with the listctrl sample, resizing the window so a scroll bar is needed results in an infinite sizing loop.

comment:14 Changed 3 years ago by Paul Cornett <paulcor@…>

In d5681ee4a8e7140ebe3bf852f10eca56a8173b24/git-wxWidgets:

Fix infinite sizing loop caused by 3b4ee5a0

Avoid the problems 3b4ee5a0 attempted to address in a much simpler way:
when a "size-allocate" is in progress, call gtk_widget_size_allocate()
directly, rather than deferring a call to gtk_widget_queue_resize().
See #17585

comment:15 Changed 3 years ago by Paul Cornett <paulcor@…>

In 309f5fe529f3918a2b5e5b15cb7cb360ad5c6667/git-wxWidgets:

Fix infinite sizing loop caused by 64753769

Avoid the problems 64753769 attempted to address in a much simpler way:
when a "size-allocate" is in progress, call gtk_widget_size_allocate()
directly, rather than deferring a call to gtk_widget_queue_resize().
See #17585

(backport of d5681ee4a8e7140ebe3bf852f10eca56a8173b24)

comment:16 Changed 2 years ago by vadz

  • Resolution set to fixed
  • Status changed from confirmed to closed

This seems to be fixed according to the original reporter, so closing -- please reopen if it was left open intentionally.

Note: See TracTickets for help on using tickets.