From 32c21f4a947a731b385ca8bd7e75f884823532fa Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Thu, 17 Jun 2021 23:04:34 -0400 Subject: [PATCH] Fix several window sizing problems on macOS - Remove outdated y-offset that prevented restoring full-height (client area returned by wx is correct these days) - Clamp frame geometry to fit new display when display is changed - Handle when an automatic window reposition causes a DPI change Fixes https://gitlab.com/kicad/code/kicad/-/issues/8341 --- common/eda_base_frame.cpp | 83 +++++++++++++++++++++++++++++++++------ common/eda_draw_frame.cpp | 9 +++++ include/eda_base_frame.h | 5 +++ include/eda_draw_frame.h | 2 +- 4 files changed, 87 insertions(+), 12 deletions(-) diff --git a/common/eda_base_frame.cpp b/common/eda_base_frame.cpp index 0604d7e036..3cd30bb1e2 100644 --- a/common/eda_base_frame.cpp +++ b/common/eda_base_frame.cpp @@ -102,6 +102,7 @@ BEGIN_EVENT_TABLE( EDA_BASE_FRAME, wxFrame ) EVT_MENU_CLOSE( EDA_BASE_FRAME::OnMenuEvent ) EVT_MENU_HIGHLIGHT_ALL( EDA_BASE_FRAME::OnMenuEvent ) EVT_MOVE( EDA_BASE_FRAME::OnMove ) + EVT_SIZE( EDA_BASE_FRAME::OnSize ) EVT_MAXIMIZE( EDA_BASE_FRAME::OnMaximize ) EVT_SYS_COLOUR_CHANGED( EDA_BASE_FRAME::onSystemColorChange ) @@ -125,6 +126,7 @@ void EDA_BASE_FRAME::commonInit( FRAME_T aFrameType ) m_autoSaveTimer = new wxTimer( this, ID_AUTO_SAVE_TIMER ); m_mruPath = PATHS::GetDefaultUserProjectsPath(); m_frameSize = defaultSize( aFrameType ); + m_displayIndex = -1; m_auimgr.SetArtProvider( new WX_AUI_DOCK_ART() ); @@ -144,7 +146,6 @@ void EDA_BASE_FRAME::commonInit( FRAME_T aFrameType ) Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( EDA_BASE_FRAME::windowClosing ) ); initExitKey(); - } EDA_BASE_FRAME::EDA_BASE_FRAME( FRAME_T aFrameType, KIWAY* aKiway ) : @@ -504,6 +505,22 @@ void EDA_BASE_FRAME::ThemeChanged() } +void EDA_BASE_FRAME::OnSize( wxSizeEvent& aEvent ) +{ + int currentDisplay = wxDisplay::GetFromWindow( this ); + + if( m_displayIndex >= 0 && currentDisplay != m_displayIndex ) + { + wxLogTrace( traceDisplayLocation, "OnSize: current display changed %d to %d", + m_displayIndex, currentDisplay ); + m_displayIndex = currentDisplay; + ensureWindowIsOnScreen(); + } + + aEvent.Skip(); +} + + void EDA_BASE_FRAME::LoadWindowState( const wxString& aFileName ) { if( !Pgm().GetCommonSettings()->m_Session.remember_open_files ) @@ -583,16 +600,6 @@ void EDA_BASE_FRAME::LoadWindowState( const WINDOW_STATE& aState ) } } - // Ensure Window title bar is visible -#if defined( __WXOSX__ ) - // for macOSX, the window must be below system (macOSX) toolbar - int Ypos_min = 20; -#else - int Ypos_min = 0; -#endif - if( m_framePos.y < Ypos_min ) - m_framePos.y = Ypos_min; - wxLogTrace( traceDisplayLocation, "Final window position (%d, %d) with size (%d, %d)", m_framePos.x, m_framePos.y, m_frameSize.x, m_frameSize.y ); @@ -616,6 +623,60 @@ void EDA_BASE_FRAME::LoadWindowState( const WINDOW_STATE& aState ) wxLogTrace( traceDisplayLocation, "Maximizing window" ); Maximize(); } + + m_displayIndex = wxDisplay::GetFromWindow( this ); +} + + +void EDA_BASE_FRAME::ensureWindowIsOnScreen() +{ + wxDisplay display( wxDisplay::GetFromWindow( this ) ); + wxRect clientSize = display.GetClientArea(); + wxPoint pos = GetPosition(); + wxSize size = GetWindowSize(); + + wxLogTrace( traceDisplayLocation, + "ensureWindowIsOnScreen: clientArea (%d, %d) w %d h %d", clientSize.x, clientSize.y, + clientSize.width, clientSize.height ); + + if( pos.y < clientSize.y ) + { + wxLogTrace( traceDisplayLocation, + "ensureWindowIsOnScreen: y pos %d below minimum, setting to %d", pos.y, + clientSize.y ); + pos.y = clientSize.y; + } + + if( pos.x < clientSize.x ) + { + wxLogTrace( traceDisplayLocation, + "ensureWindowIsOnScreen: x pos %d is off the client rect, setting to %d", pos.x, + clientSize.x ); + pos.y = clientSize.x; + } + + if( pos.x + size.x - clientSize.x > clientSize.width ) + { + int newWidth = clientSize.width - pos.x; + wxLogTrace( traceDisplayLocation, + "ensureWindowIsOnScreen: effective width %d above available %d, setting to %d", + pos.x + size.x, clientSize.width, newWidth ); + size.x = newWidth; + } + + if( pos.y + size.y - clientSize.y > clientSize.height ) + { + int newHeight = clientSize.height - pos.y; + wxLogTrace( traceDisplayLocation, + "ensureWindowIsOnScreen: effective height %d above available %d, setting to %d", + pos.y + size.y, clientSize.height, newHeight ); + size.y = newHeight; + } + + wxLogTrace( traceDisplayLocation, "Updating window position (%d, %d) with size (%d, %d)", + pos.x, pos.y, size.x, size.y ); + + SetSize( pos.x, pos.y, size.x, size.y ); } diff --git a/common/eda_draw_frame.cpp b/common/eda_draw_frame.cpp index 15ec11a96d..b5d3596d43 100644 --- a/common/eda_draw_frame.cpp +++ b/common/eda_draw_frame.cpp @@ -155,6 +155,13 @@ EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame wxSize( m_frameSize.x, m_msgFrameHeight ) ); m_messagePanel->SetBackgroundColour( COLOR4D( LIGHTGRAY ).ToColour() ); + + Bind( wxEVT_DPI_CHANGED, + [&]( wxDPIChangedEvent& ) + { + wxMoveEvent dummy; + OnMove( dummy ); + } ); } @@ -531,6 +538,8 @@ void EDA_DRAW_FRAME::DisplayUnitsMsg() void EDA_DRAW_FRAME::OnSize( wxSizeEvent& SizeEv ) { + EDA_BASE_FRAME::OnSize( SizeEv ); + m_frameSize = GetClientSize( ); SizeEv.Skip(); diff --git a/include/eda_base_frame.h b/include/eda_base_frame.h index 67d63e7071..c07f72b6a8 100644 --- a/include/eda_base_frame.h +++ b/include/eda_base_frame.h @@ -195,6 +195,8 @@ public: aEvent.Skip(); } + virtual void OnSize( wxSizeEvent& aEvent ); + void OnMaximize( wxMaximizeEvent& aEvent ); void SetAutoSaveInterval( int aInterval ); @@ -646,6 +648,8 @@ protected: */ void initExitKey(); + void ensureWindowIsOnScreen(); + DECLARE_EVENT_TABLE() private: @@ -682,6 +686,7 @@ protected: wxPoint m_framePos; wxSize m_frameSize; bool m_maximizeByDefault; + int m_displayIndex; // These contain the frame size and position for when it is not maximized wxPoint m_normalFramePos; diff --git a/include/eda_draw_frame.h b/include/eda_draw_frame.h index 05b9fb26d1..f72678a09c 100644 --- a/include/eda_draw_frame.h +++ b/include/eda_draw_frame.h @@ -274,7 +274,7 @@ public: /** * Recalculate the size of toolbars and display panel when the frame size changes. */ - virtual void OnSize( wxSizeEvent& event ); + virtual void OnSize( wxSizeEvent& event ) override; void OnMove( wxMoveEvent& aEvent ) override;