From 76354fbc8dca127a28f499ddf7fdde27b4e324f2 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 12 Feb 2021 17:26:36 +0100 Subject: [PATCH 1/6] Fixed wxComboCtrlBase::ShowPopup() to show a popup control in respect to the display of the provided window instead of primary display. See issue The "Show" Dropdown list goes out of the screen #2999 (https://github.com/prusa3d/prusaslicer/issues/2999) --- src/common/combocmn.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/common/combocmn.cpp b/src/common/combocmn.cpp index 7383ea013d..c2f182f64d 100644 --- a/src/common/combocmn.cpp +++ b/src/common/combocmn.cpp @@ -20,6 +20,7 @@ #include "wx/combo.h" +#include "wx/display.h" #ifdef __WXMSW__ #include "wx/msw/private.h" @@ -2284,6 +2285,9 @@ void wxComboCtrlBase::ShowPopup() SetFocus(); + int displayIdx = wxDisplay::GetFromWindow(this); + wxRect displayRect = wxDisplay(displayIdx != wxNOT_FOUND ? displayIdx : 0u).GetGeometry(); + // Space above and below int screenHeight; wxPoint scrPos; @@ -2292,8 +2296,11 @@ void wxComboCtrlBase::ShowPopup() int maxHeightPopup; wxSize ctrlSz = GetSize(); - screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y, this ); - scrPos = GetScreenPosition(); + // wxSystemSettings::GetMetric( wxSYS_SCREEN_Y, this ) returns a geometry of the primary display + // And it causes wrong calculation of the popuping on secondary monitor. + // So, let's make all calculation in respect to the display of the provided window. + screenHeight = displayRect.height;//wxSystemSettings::GetMetric( wxSYS_SCREEN_Y, this ); + scrPos = GetScreenPosition() - displayRect.GetTopLeft(); spaceAbove = scrPos.y; spaceBelow = screenHeight - spaceAbove - ctrlSz.y; @@ -2357,20 +2364,20 @@ void wxComboCtrlBase::ShowPopup() wxSize szp = popup->GetSize(); int popupX; - int popupY = scrPos.y + ctrlSz.y; + int popupY = scrPos.y + ctrlSz.y + displayRect.GetTop(); // Default anchor is wxLEFT int anchorSide = m_anchorSide; if ( !anchorSide ) anchorSide = wxLEFT; - int rightX = scrPos.x + ctrlSz.x + m_extRight - szp.x; - int leftX = scrPos.x - m_extLeft; + int rightX = scrPos.x + ctrlSz.x + m_extRight - szp.x + displayRect.GetLeft(); + int leftX = scrPos.x - m_extLeft + displayRect.GetLeft(); if ( wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft ) leftX -= ctrlSz.x; - int screenWidth = wxSystemSettings::GetMetric( wxSYS_SCREEN_X, this ); + int screenWidth = displayRect.width;// wxSystemSettings::GetMetric( wxSYS_SCREEN_X, this ); // If there is not enough horizontal space, anchor on the other side. // If there is no space even then, place the popup at x 0. @@ -2407,7 +2414,7 @@ void wxComboCtrlBase::ShowPopup() if ( spaceBelow < szp.y ) { - popupY = scrPos.y - szp.y; + popupY = scrPos.y - szp.y + displayRect.GetTop(); showFlags |= ShowAbove; } From 01d8c1bf8ebbb6d67e8f661ff8f316cd51fde2ee Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sat, 13 Feb 2021 01:40:28 +0100 Subject: [PATCH 2/6] Improve wxComboCtrl popup position with multiple displays --- src/common/combocmn.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/common/combocmn.cpp b/src/common/combocmn.cpp index c2f182f64d..57e1c2b861 100644 --- a/src/common/combocmn.cpp +++ b/src/common/combocmn.cpp @@ -2296,13 +2296,10 @@ void wxComboCtrlBase::ShowPopup() int maxHeightPopup; wxSize ctrlSz = GetSize(); - // wxSystemSettings::GetMetric( wxSYS_SCREEN_Y, this ) returns a geometry of the primary display - // And it causes wrong calculation of the popuping on secondary monitor. - // So, let's make all calculation in respect to the display of the provided window. - screenHeight = displayRect.height;//wxSystemSettings::GetMetric( wxSYS_SCREEN_Y, this ); - scrPos = GetScreenPosition() - displayRect.GetTopLeft(); + screenHeight = displayRect.GetHeight(); + scrPos = GetScreenPosition(); - spaceAbove = scrPos.y; + spaceAbove = scrPos.y - displayRect.GetY(); spaceBelow = screenHeight - spaceAbove - ctrlSz.y; maxHeightPopup = spaceBelow; @@ -2364,20 +2361,20 @@ void wxComboCtrlBase::ShowPopup() wxSize szp = popup->GetSize(); int popupX; - int popupY = scrPos.y + ctrlSz.y + displayRect.GetTop(); + int popupY = scrPos.y + ctrlSz.y; // Default anchor is wxLEFT int anchorSide = m_anchorSide; if ( !anchorSide ) anchorSide = wxLEFT; - int rightX = scrPos.x + ctrlSz.x + m_extRight - szp.x + displayRect.GetLeft(); - int leftX = scrPos.x - m_extLeft + displayRect.GetLeft(); + int rightX = scrPos.x + ctrlSz.x + m_extRight - szp.x; + int leftX = scrPos.x - m_extLeft; if ( wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft ) leftX -= ctrlSz.x; - int screenWidth = displayRect.width;// wxSystemSettings::GetMetric( wxSYS_SCREEN_X, this ); + int screenWidth = displayRect.GetWidth(); // If there is not enough horizontal space, anchor on the other side. // If there is no space even then, place the popup at x 0. @@ -2414,7 +2411,7 @@ void wxComboCtrlBase::ShowPopup() if ( spaceBelow < szp.y ) { - popupY = scrPos.y - szp.y + displayRect.GetTop(); + popupY = scrPos.y - szp.y; showFlags |= ShowAbove; } From 9365df2322e4ddab96a2d26a3e61e88494d58b17 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sat, 13 Feb 2021 01:41:14 +0100 Subject: [PATCH 3/6] Improve wxPropertyGridEditor position with multiple displays --- src/propgrid/propgrid.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 8fa51de825..ae6a7f69a1 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -62,6 +62,7 @@ #include "wx/timer.h" #include "wx/dcbuffer.h" #include "wx/scopeguard.h" +#include "wx/display.h" // Two pics for the expand / collapse buttons. // Files are not supplied with this project (since it is @@ -1715,27 +1716,30 @@ wxPoint wxPropertyGrid::GetGoodEditorDialogPosition( wxPGProperty* p, ImprovedClientToScreen( &x, &y ); - int sw = wxSystemSettings::GetMetric( ::wxSYS_SCREEN_X, this ); - int sh = wxSystemSettings::GetMetric( ::wxSYS_SCREEN_Y, this ); + int displayIdx = wxDisplay::GetFromWindow(this); + wxRect displayRect = wxDisplay(displayIdx != wxNOT_FOUND ? displayIdx : 0u).GetGeometry(); + + x -= displayRect.GetX(); + y -= displayRect.GetY(); int new_x; int new_y; - if ( x > (sw/2) ) + if ( x > (displayRect.GetWidth()/2) ) // left new_x = x + (m_width-splitterX) - sz.x; else // right new_x = x; - if ( y > (sh/2) ) + if ( y > (displayRect.GetHeight()/2) ) // above new_y = y - sz.y; else // below new_y = y + m_lineHeight; - return wxPoint(new_x,new_y); + return wxPoint(new_x + displayRect.GetX(), new_y + displayRect.GetY()); } // ----------------------------------------------------------------------- From 1e17e8f500692df5d8e431596d3fe856f03de8b8 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sat, 13 Feb 2021 01:41:34 +0100 Subject: [PATCH 4/6] Improve per-monitor DPI in wxVListBoxComboPopup Adjust the default item height before the drawing size is calculated. --- include/wx/odcombo.h | 1 + src/generic/odcombo.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/include/wx/odcombo.h b/include/wx/odcombo.h index d147cd49b0..a8ffa9570a 100644 --- a/include/wx/odcombo.h +++ b/include/wx/odcombo.h @@ -93,6 +93,7 @@ public: virtual void OnComboDoubleClick() wxOVERRIDE; virtual bool LazyCreate() wxOVERRIDE; virtual bool FindItem(const wxString& item, wxString* trueItem) wxOVERRIDE; + virtual void OnDPIChanged(wxDPIChangedEvent& event); // Item management void SetSelection( int item ); diff --git a/src/generic/odcombo.cpp b/src/generic/odcombo.cpp index 49a3cd8141..22b4eefeda 100644 --- a/src/generic/odcombo.cpp +++ b/src/generic/odcombo.cpp @@ -84,6 +84,10 @@ bool wxVListBoxComboPopup::Create(wxWindow* parent) // TODO: Move this to SetFont m_itemHeight = m_combo->GetCharHeight(); + // Bind to the DPI event of the combobox. We get our own once the popup + // is shown, but this is too late, m_itemHeight is already being used. + m_combo->Bind(wxEVT_DPI_CHANGED, &wxVListBoxComboPopup::OnDPIChanged, this); + return true; } @@ -104,6 +108,11 @@ void wxVListBoxComboPopup::SetFocus() #endif } +void wxVListBoxComboPopup::OnDPIChanged(wxDPIChangedEvent& WXUNUSED(event)) +{ + m_itemHeight = m_combo->GetCharHeight(); +} + bool wxVListBoxComboPopup::LazyCreate() { // NB: There is a bug with wxVListBox that can be avoided by creating From dbcfe56ae53b949575aaecf4c47e512c8a07ab0b Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sat, 13 Feb 2021 01:42:10 +0100 Subject: [PATCH 5/6] Make wxPenStyleComboBox in Combo sample DPI aware --- samples/combo/combo.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/samples/combo/combo.cpp b/samples/combo/combo.cpp index 9a55db88de..6176989941 100644 --- a/samples/combo/combo.cpp +++ b/samples/combo/combo.cpp @@ -252,10 +252,7 @@ public: virtual wxCoord OnMeasureItem( size_t item ) const wxOVERRIDE { // Simply demonstrate the ability to have variable-height items - if ( item & 1 ) - return 36; - else - return 24; + return FromDIP( item & 1 ? 36 : 24 ); } virtual wxCoord OnMeasureItemWidth( size_t WXUNUSED(item) ) const wxOVERRIDE From e3491fc5370fbad53fce3d8092a21ab12dd068e2 Mon Sep 17 00:00:00 2001 From: Maarten Bent Date: Sat, 13 Feb 2021 21:11:18 +0100 Subject: [PATCH 6/6] Create a wxDisplay directly from wxWindow --- src/common/combocmn.cpp | 4 +--- src/propgrid/propgrid.cpp | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/common/combocmn.cpp b/src/common/combocmn.cpp index 57e1c2b861..b61aac35bf 100644 --- a/src/common/combocmn.cpp +++ b/src/common/combocmn.cpp @@ -2285,9 +2285,6 @@ void wxComboCtrlBase::ShowPopup() SetFocus(); - int displayIdx = wxDisplay::GetFromWindow(this); - wxRect displayRect = wxDisplay(displayIdx != wxNOT_FOUND ? displayIdx : 0u).GetGeometry(); - // Space above and below int screenHeight; wxPoint scrPos; @@ -2296,6 +2293,7 @@ void wxComboCtrlBase::ShowPopup() int maxHeightPopup; wxSize ctrlSz = GetSize(); + wxRect displayRect = wxDisplay(this).GetGeometry(); screenHeight = displayRect.GetHeight(); scrPos = GetScreenPosition(); diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index ae6a7f69a1..61be08bb01 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -1716,8 +1716,7 @@ wxPoint wxPropertyGrid::GetGoodEditorDialogPosition( wxPGProperty* p, ImprovedClientToScreen( &x, &y ); - int displayIdx = wxDisplay::GetFromWindow(this); - wxRect displayRect = wxDisplay(displayIdx != wxNOT_FOUND ? displayIdx : 0u).GetGeometry(); + wxRect displayRect = wxDisplay(this).GetGeometry(); x -= displayRect.GetX(); y -= displayRect.GetY();