essej / sooperlooper

GNU General Public License v2.0
192 stars 48 forks source link

Improper top window resize when add/remove loops if OS has extra window border (happens in some Linuxes) #18

Closed ericfont closed 1 year ago

ericfont commented 3 years ago

I was investigating earlier https://github.com/ericfont/sooperlooper/issues/1

Turns out I can get the resizing to work properly on my arch linux machine if I configure my desktop's window properties to disable the top border. So instead of:

arch-wiith-border

If I disable the border (on KDE, right click the border, click "More Actions", and set "No Border"), then the resize is nice:

arch-wihtout-border

So the trick to fixing this issue will be to making sure the sizing code includes the existence or non-existence of the OSes border.

(I have no idea how things work on Mac.)

ericfont commented 3 years ago

I'm not going to waste any time trying to fix...I think really wxwidgets should have provide the tools to be able to be aware of possoble window decoration when user sets the minimum desired window size. Or maybe even gtk.

ericfont commented 3 years ago

Making a note to myself maybe try wxFRAME_TOOL_WINDOW for the frame so there isn't a big title bar...

ericfont commented 3 years ago

and this is interesting...it seems on Debian 12 when running wxWidgets v3.1.5, that the line responsible for setting minimize size of the window:

https://github.com/essej/sooperlooper/blob/9a99524e262b35ebc54157a068bdd50ac62db155/src/gui/gui_app.cpp#L345

is not working properly. I seem to be able to drag the window to be as small as just containing the first row of the main panel, which is too small:

image

ericfont commented 3 years ago

chaning that line to:

_frame->SetMinSize(wxSize(850, 210));

works as that line was intended. I'm also noticing a little note in https://docs.wxwidgets.org/3.0/classwx_window.html#a307329dc3b10f5584aeb2cbce9293ffd image

Though the _frame is a top-level window, so I don't know what the deal is with SetSizeHints not working...though maybe with v3.1.5 that doesn't work as the same as it did earlier.

ericfont commented 3 years ago

hmm...though I'm not sure that SetSizeHints is causing that problem on wx v3.1.5, because the following works:

#include <wx/wx.h>

namespace Examples {
  class Application : public wxApp {
    bool OnInit() override {
      wxFrame *_frame = new wxFrame(nullptr, wxID_ANY, wxEmptyString);
      _frame->SetSizeHints( wxSize(100, 100) );
      _frame->Show();
      return true;
    }
  };
}

wxIMPLEMENT_APP(Examples::Application);

same as if i usedd _frame->SetMinSize( wxSize(100, 100) );.

ericfont commented 3 years ago

so this is very interesting on 3.1.5...the ordering of the current code does not properly set the minimum size:

    _frame->SetSizeHints(850, 210);
    _frame->SetSize(_screen_pos.x, _screen_pos.y, 860, 215);

    SetTopWindow(_frame);

    _frame->Show(FALSE);
    _frame->Raise();
    _frame->Show(TRUE);

But if I move that SetSizeHints() to after the Show(), then it properly sets the minimum size in v3.1.5:

    _frame->SetSize(_screen_pos.x, _screen_pos.y, 860, 215);

    SetTopWindow(_frame);

    _frame->Show(FALSE);
    _frame->Raise();
    _frame->Show(TRUE);
    _frame->SetSizeHints(850, 210);

Since using SetMinSize always works regardless of what ordering it is placed in in v3.1.5, I'm thinking SetMinSize is the safer call.

ericfont commented 3 years ago

well I do wonder if the following calls of SetSizeHints():

https://github.com/essej/sooperlooper/blob/9a99524e262b35ebc54157a068bdd50ac62db155/src/gui/main_panel.cpp#L379

https://github.com/essej/sooperlooper/blob/9a99524e262b35ebc54157a068bdd50ac62db155/src/gui/main_panel.cpp#L404

https://github.com/essej/sooperlooper/blob/9a99524e262b35ebc54157a068bdd50ac62db155/src/gui/main_panel.cpp#L410

need to be replaced by SetMinSize() because they aren't a wxTopLevelWindow, cause according to that same warning sounds like SetSizeHints() doesn't do anything if they aren't: https://docs.wxwidgets.org/3.1/classwx_sizer.html#abc460cd0e2bb3bde72142fdb434bc546 image

Maybe if I get those sizers' min size working correctly, then maybe the top window frame would just use that sizer info to figure out the minimum size.

fernando-inf commented 3 years ago

Hello, good job, I had noticed it, but had not worried until now, since I usually use it in headless mode, good luck, greetings.

XFCE 4.16 :

sooperlooper-windows-error

ericfont commented 3 years ago

thanks for verifying the improper resize happens on your system too.

ericfont commented 3 years ago

I did checkout some basic wxWidget examples and made a test example of just a wxFrame with SetMinSize(100,100) and with only a MainMenu added to it:

https://github.com/ericfont/Examples_wxWidgets/blob/ea3eeba8eae514a66b4a101f896462c020fb545c/src/MenusAndToolbars/MainMenu/MainMenu.cpp

And I've found that the minimum height of the interior part of the frame plus menubar is 100, regardless of whether I remove or readd the title bar after the program starts. (that's on wx 3.1.5 on KDE debian 12 at least...)