Opened 17 months ago

Last modified 7 months ago

#14870 confirmed defect

wxTLW become resizable after SetSizeHints() call even if wxRESIZE_BORDER is not used

Reported by: michalbliznak Owned by:
Priority: normal Milestone:
Component: wxGTK Version: stable-latest
Keywords: dialog frame resize flag ubuntu unity Cc: cbright@…
Blocked By: Blocking:
Patch: no

Description

Dialogs and frames are resizable in wxGTK (at least under Ubuntu 12.04) if wxRESIZE_BORDER is not defined (the window is still resizable even if the style is set to 0 or to any custom combination of other flags).

Change History (16)

comment:1 Changed 17 months ago by pcor

  • Keywords ubuntu unity added
  • Priority changed from high to normal

Works for me on XFCE. Likely yet another defect in Unity.

comment:2 Changed 17 months ago by michalbliznak

Actually, I use Gnome-Shell, not Unity.

comment:3 follow-up: Changed 17 months ago by vadz

  • Milestone 2.9.5 deleted
  • Status changed from new to confirmed

I can confirm that this is broken with Unity, the frame is resizeable with this patch:

  • samples/minimal/minimal.cpp

    diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
    index a78e462..f369f83 100644
    a b bool MyApp::OnInit() 
    143143 
    144144// frame constructor 
    145145MyFrame::MyFrame(const wxString& title) 
    146        : wxFrame(NULL, wxID_ANY, title) 
     146       : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxCAPTION) 
    147147{ 
    148148    // set the frame icon 
    149149    SetIcon(wxICON(sample)); 

I don't know what to do about it though so resetting the milestone.

comment:4 Changed 9 months ago by cbright

I that noticed it works in 2.9.3, but is broken in 2.9.4 and still in the latest trunk.

comment:5 Changed 9 months ago by vadz

It would be very helpful if you could bisect the svn (or git) history to find out when exactly did they break. TIA!

comment:7 in reply to: ↑ 3 ; follow-up: Changed 8 months ago by pcor

Replying to vadz:

I can confirm that this is broken with Unity, the frame is resizeable with this patch:

Can't reproduce on Ubuntu 12.04.2 LTS x86_64 using Unity.

comment:8 in reply to: ↑ 7 ; follow-up: Changed 8 months ago by vadz

Replying to pcor:

Replying to vadz:

I can confirm that this is broken with Unity, the frame is resizeable with this patch:

Can't reproduce on Ubuntu 12.04.2 LTS x86_64 using Unity.

I still see this with the latest svn with the previously attached patch under exactly the same system. Try pressing Alt+F8 (or choosing "Resize" from the Alt+Space menu) and press cursor arrow keys.

I don't seem to be able to do this with the mouse (any more? I think I did it with mouse the last time...) but this seems to be entirely due to lack of borders as the cursor still changes to the resize one when hovering over the frame border, but it's impossible to click on it as it has 0 size.

comment:9 in reply to: ↑ 8 Changed 8 months ago by pcor

Replying to vadz:

I still see this with the latest svn with the previously attached patch under exactly the same system. Try pressing Alt+F8 (or choosing "Resize" from the Alt+Space menu) and press cursor arrow keys.

Alt+F8 does nothing, and "Resize" is disabled in the Alt+Space menu. There must be some difference between our systems, but I have no idea what it might be.

comment:10 Changed 8 months ago by vadz

I have no idea what could be the difference be neither. I'm running this system in a VM and I try to avoid modifying it as much as possible because I use it for testing only, so normally mine should be quite close to the default state. In particular, it uses the default theme, the default GTK+ packages and so on.

Can I debug what's going wrong somehow? I.e. can you point me to some code that should be executing (and is on your machine) but isn't it or anything like this?

Also, can anyone else reproduce this?

comment:11 Changed 8 months ago by cbright

  • Cc cbright@… added

I tracked down the problem to the addition of a DoSetSizeHints call in src/gtk/toplevel.cpp - http://svn.wxwidgets.org/viewvc/wx/wxWidgets/trunk/src/gtk/toplevel.cpp?r1=71464&r2=71465&pathrev=71465

If you remove that function call, it works like before.

comment:12 Changed 8 months ago by PC

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

(In [74685]) Remove DoSetSizeHints() call from Create()
The reason it was added does not seem to be reproducible anymore,
and it interferes with wxRESIZE_BORDER on Ubuntu.
Closes #14870

comment:13 Changed 7 months ago by vadz

  • Milestone set to 3.0
  • Resolution fixed deleted
  • Status changed from closed to reopened

As shown by #15549, this is not really fixed. With the one-liner from comment:3 we now get a 0-sized and hence invisible frame. If a call to SetSizeHints() is added to its ctor, with any values (even 0), the frame does get a reasonable size but also becomes resizeable. So IMO it's not the call to DoSetSizeHints() removed by r74685 that was the problem, but rather the implementation of this function. Apparently, gtk_window_set_geometry_hints() overrides gdk_window_set_functions().

Unfortunately I don't know how to fix this. I tried this first:

  • src/gtk/toplevel.cpp

    diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp
    index 66da4cb..c8eea0e 100644
    a b bool wxTopLevelWindowGTK::Create( wxWindow *parent, 
    756756    GTKDoGetSize(&w, &h); 
    757757    gtk_window_set_default_size(GTK_WINDOW(m_widget), w, h); 
    758758 
     759    // If we don't set the max geometry hint and the user code doesn't set the 
     760    // hints neither, the initial window size may be set to 0 for some reason, 
     761    // see #15549. 
     762    GdkGeometry hints; 
     763    hints.max_width = 
     764    hints.max_height = INT_MAX; 
     765    gtk_window_set_geometry_hints(GTK_WINDOW(m_widget), NULL, 
     766                                  &hints, GDK_HINT_MAX_SIZE); 
     767 
    759768    return true; 
    760769} 
    761770 

but even this still makes the window resizeable, i.e. not better than the original code.

I then tried this:

  • src/gtk/toplevel.cpp

    diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp
    index 66da4cb..469dcfb 100644
    a b void wxTopLevelWindowGTK::DoSetSizeHints( int minW, int minH, 
    12011201        hints.width_inc  = incW > 0 ? incW : 1; 
    12021202        hints.height_inc = incH > 0 ? incH : 1; 
    12031203    } 
     1204 
     1205    if ( !HasFlag(wxRESIZE_BORDER) ) 
     1206    { 
     1207        hints.max_width = hints.min_width; 
     1208        hints.max_height = hints.min_height; 
     1209    } 
     1210 
    12041211    gtk_window_set_geometry_hints( 
    12051212        (GtkWindow*)m_widget, NULL, &hints, (GdkWindowHints)hints_mask); 
    12061213} 

but this still still results in 0-sized windows by default (fun fact: exchanging the assignments and using max as min crashes Metacity).

So how can we get a non-resizeable window of decent size with GTK? Maybe we should use gdk_window_set_geometry_hints() directly instead of gtk_window_set_geometry_hints() which seems to be involved into a lot of complicated things? Or would going down to GDK be even worse?

In any case, reverting r74685 would be better than the current situation so we ought to at least do this before 3.0. But really fixing the problem would be even better, of course...

comment:14 Changed 7 months ago by PC

(In [74942]) Fix default size of un-resizable windows, broken in r74685
see #14870
closes #15549

comment:15 Changed 7 months ago by pcor

So after r74942 is there still a problem here?

comment:16 Changed 7 months ago by vadz

  • Milestone 3.0 deleted
  • Status changed from reopened to confirmed
  • Summary changed from wxFrame and wxDialog are resizable even if wxRESIZE_BORDER is not defined to wxTLW become resizable after SetSizeHints() call even if wxRESIZE_BORDER is not used

It's much better, thanks, but still not perfect: with the diff from comment:3 the sample window now appears in a correct size and is not resizeable, i.e. everything works correctly.

Unfortunately adding a SetSizeHints() call still makes it resizeable (the "Resize" item in the window menu becomes enabled and it can be resized by dragging its -- otherwise invisible -- border), i.e. with this diff

  • samples/minimal/minimal.cpp

    diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
    index a78e462..6a7abe7 100644
    a b bool MyApp::OnInit() 
    143143 
    144144// frame constructor 
    145145MyFrame::MyFrame(const wxString& title) 
    146        : wxFrame(NULL, wxID_ANY, title) 
     146       : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxCAPTION) 
    147147{ 
     148    SetSizeHints(0, 0); 
     149 
    148150    // set the frame icon 
    149151    SetIcon(wxICON(sample)); 
    150152 

the behaviour is still wrong.

But this is not 3.0-critical any more IMHO.

Note: See TracTickets for help on using tickets.