From 52b25211c8c388d9b9435f1572337be41ac92e2f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 6 Aug 2020 23:54:48 +0200 Subject: [PATCH 01/16] Add wxDisplay::GetStdPPIValue() and GetStdPPI() Provide public way to access the default platform DPI, which was previously a constant private to src/common/wincmn.cpp. --- include/wx/display.h | 15 +++++++++++++++ interface/wx/display.h | 27 +++++++++++++++++++++++++++ src/common/wincmn.cpp | 23 ++++++++++------------- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/include/wx/display.h b/include/wx/display.h index b9fec42aba..d6f501cd7e 100644 --- a/include/wx/display.h +++ b/include/wx/display.h @@ -87,6 +87,21 @@ public: // get the resolution of this monitor in pixels per inch wxSize GetPPI() const; + // get the default resolution for displays on this platform + static int GetStdPPIValue() + { +#ifdef __WXOSX__ + return 72; +#else + return 96; +#endif + } + + static wxSize GetStdPPI() + { + return wxSize(GetStdPPIValue(), GetStdPPIValue()); + } + // name may be empty wxString GetName() const; diff --git a/interface/wx/display.h b/interface/wx/display.h index 2085ff15db..b71cbb0d72 100644 --- a/interface/wx/display.h +++ b/interface/wx/display.h @@ -143,6 +143,33 @@ public: */ wxSize GetPPI() const; + /** + Returns default display resolution for the current platform in pixels + per inch. + + This function mostly used internally, use GetPPI() to get the actual + display resolution. + + Currently the standard PPI is the same in both horizontal and vertical + directions on all platforms and its value is 96 everywhere except under + Apple devices (those running macOS, iOS, watchOS etc), where it is 72. + + @see GetStdPPI() + + @since 3.1.5 + */ + static int GetStdPPIValue(); + + /** + Returns default display resolution for the current platform as wxSize. + + This function is equivalent to constructing wxSize object with both + components set to GetStdPPIValue(). + + @since 3.1.5 + */ + static wxSize GetStdPPI(); + /** Returns @true if the display is the primary display. The primary display is the one whose index is 0. diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 9b2e522920..563406a801 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -101,13 +101,6 @@ bool IsInCaptureStack(wxWindowBase* win); } // wxMouseCapture -// Most platforms use 96 DPI by default, but Mac traditionally uses 72. -#ifdef __WXOSX__ -static const int BASELINE_DPI = 72; -#else -static const int BASELINE_DPI = 96; -#endif - // ---------------------------------------------------------------------------- // static data // ---------------------------------------------------------------------------- @@ -805,7 +798,7 @@ static wxSize GetDPIHelper(const wxWindowBase* w) if ( !dpi.x || !dpi.y ) dpi = wxScreenDC().GetPPI(); if ( !dpi.x || !dpi.y ) - dpi = wxSize(BASELINE_DPI, BASELINE_DPI); + dpi = wxDisplay::GetStdPPI(); return dpi; } @@ -829,7 +822,7 @@ double wxWindowBase::GetDPIScaleFactor() const // We use just the vertical component of the DPI because it's the one // that counts most and, in practice, it's equal to the horizontal one // anyhow. - return dpi.y / (double)BASELINE_DPI; + return dpi.y / (double)wxDisplay::GetStdPPIValue(); } // helper of GetWindowBorderSize(): as many ports don't implement support for @@ -2900,10 +2893,12 @@ wxWindowBase::FromDIP(const wxSize& sz, const wxWindowBase* w) { const wxSize dpi = GetDPIHelper(w); + const int baseline = wxDisplay::GetStdPPIValue(); + // Take care to not scale -1 because it has a special meaning of // "unspecified" which should be preserved. - return wxSize(sz.x == -1 ? -1 : wxMulDivInt32(sz.x, dpi.x, BASELINE_DPI), - sz.y == -1 ? -1 : wxMulDivInt32(sz.y, dpi.y, BASELINE_DPI)); + return wxSize(sz.x == -1 ? -1 : wxMulDivInt32(sz.x, dpi.x, baseline), + sz.y == -1 ? -1 : wxMulDivInt32(sz.y, dpi.y, baseline)); } /* static */ @@ -2912,10 +2907,12 @@ wxWindowBase::ToDIP(const wxSize& sz, const wxWindowBase* w) { const wxSize dpi = GetDPIHelper(w); + const int baseline = wxDisplay::GetStdPPIValue(); + // Take care to not scale -1 because it has a special meaning of // "unspecified" which should be preserved. - return wxSize(sz.x == -1 ? -1 : wxMulDivInt32(sz.x, BASELINE_DPI, dpi.x), - sz.y == -1 ? -1 : wxMulDivInt32(sz.y, BASELINE_DPI, dpi.y)); + return wxSize(sz.x == -1 ? -1 : wxMulDivInt32(sz.x, baseline, dpi.x), + sz.y == -1 ? -1 : wxMulDivInt32(sz.y, baseline, dpi.y)); } #endif // !wxHAVE_DPI_INDEPENDENT_PIXELS From e902050002dae11871eff89151dec7a8a895f3a6 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 6 Aug 2020 23:58:05 +0200 Subject: [PATCH 02/16] Return "logical" PPI from wxDisplay::GetPPI() in wxGTK3 Just scale the standard PPI by the scaling factor instead of trying to compute the actual physical PPI, as the latter is not useful and is incompatible with the value used by all the other applications. --- src/gtk/display.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/gtk/display.cpp b/src/gtk/display.cpp index b1bdacb196..b21a0c2295 100644 --- a/src/gtk/display.cpp +++ b/src/gtk/display.cpp @@ -350,7 +350,17 @@ double wxDisplayImplGTK::GetScaleFactor() const return 1.0; } -#endif // GTK+ 3.10 + +wxSize wxDisplayImplGTK::GetPPI() const +{ + // The useful value of PPI is the scaled value of the default PPI and not + // the actual PPI computed by dividing the number of pixels by the physical + // screen size: this is what everyone else uses, and so we should do it + // too. + return wxDisplay::GetStdPPI()*GetScaleFactor(); +} + +#else // GTK+ < 3.10 wxSize wxDisplayImplGTK::GetPPI() const { @@ -370,6 +380,8 @@ wxSize wxDisplayImplGTK::GetPPI() const return ppi; } +#endif // GTK+ 3.10 + wxSize wxDisplayImplGTK::GetSizeMM() const { wxSize sizeMM; From 19fd0fcfd74ca2bd8c4f02035dd76a854817e2f2 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Aug 2020 00:10:22 +0200 Subject: [PATCH 03/16] Add wxDisplay::GetScaleFactor() This is conceptually the same as the ratio of the current DPI to the standard one, but can be implemented more directly for wxGTK3 and wxOSX (although the latter doesn't implement it yet). --- include/wx/display.h | 3 +++ interface/wx/display.h | 13 +++++++++++++ src/common/dpycmn.cpp | 19 +++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/include/wx/display.h b/include/wx/display.h index d6f501cd7e..a5e8271e9b 100644 --- a/include/wx/display.h +++ b/include/wx/display.h @@ -102,6 +102,9 @@ public: return wxSize(GetStdPPIValue(), GetStdPPIValue()); } + // get the scaling used by this display + double GetScaleFactor() const; + // name may be empty wxString GetName() const; diff --git a/interface/wx/display.h b/interface/wx/display.h index b71cbb0d72..e9a51cc4c0 100644 --- a/interface/wx/display.h +++ b/interface/wx/display.h @@ -143,6 +143,19 @@ public: */ wxSize GetPPI() const; + /** + Returns scaling factor used by this display. + + The scaling factor is the ratio between GetPPI() and GetStdPPI() + (it is implicitly assumed that this ratio is the same for both + horizontal and vertical components). + + @see wxWindow::GetContentScaleFactor(), wxWindow::GetDPIScaleFactor() + + @since 3.1.5 + */ + double GetScaleFactor() const; + /** Returns default display resolution for the current platform in pixels per inch. diff --git a/src/common/dpycmn.cpp b/src/common/dpycmn.cpp index 4f0d537ef1..c968f9c960 100644 --- a/src/common/dpycmn.cpp +++ b/src/common/dpycmn.cpp @@ -149,6 +149,25 @@ wxSize wxDisplay::GetPPI() const return m_impl->GetPPI(); } +double wxDisplay::GetScaleFactor() const +{ + wxCHECK_MSG( IsOk(), 0, wxT("invalid wxDisplay object") ); + +#ifdef wxHAVE_DPI_INDEPENDENT_PIXELS + // Use wxDisplayImpl::GetScaleFactor() directly, it should be implemented + // correctly for the platforms doing pixel scaling and using it simpler and + // more efficient than using GetPPI(). + return m_impl->GetScaleFactor(); +#else + // Under the other platforms, we just compute the DPI ratio ourselves. + // + // We use just the vertical component of the DPI because it's the one + // that counts most and, in practice, it's equal to the horizontal one + // anyhow. + return m_impl->GetPPI().y / (double)GetStdPPIValue(); +#endif +} + int wxDisplay::GetDepth() const { wxCHECK_MSG( IsOk(), 0, wxT("invalid wxDisplay object") ); From f572797965158a7df0f302758f9f61295e058814 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Aug 2020 00:15:26 +0200 Subject: [PATCH 04/16] Use wxDisplay::GetScaleFactor() in wxWindow::GetDPIScaleFactor() This can be more direct and efficient than computing the ratio of DPIs in wxWindow. --- src/common/wincmn.cpp | 45 +++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 563406a801..2919c60416 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -786,25 +786,6 @@ wxSize wxWindowBase::DoGetBestSize() const return best; } -namespace -{ - -static wxSize GetDPIHelper(const wxWindowBase* w) -{ - wxSize dpi; - - if ( w ) - dpi = w->GetDPI(); - if ( !dpi.x || !dpi.y ) - dpi = wxScreenDC().GetPPI(); - if ( !dpi.x || !dpi.y ) - dpi = wxDisplay::GetStdPPI(); - - return dpi; -} - -} - double wxWindowBase::GetContentScaleFactor() const { // By default, we assume that there is no mapping between logical and @@ -817,12 +798,7 @@ double wxWindowBase::GetContentScaleFactor() const double wxWindowBase::GetDPIScaleFactor() const { - const wxSize dpi = GetDPIHelper(this); - - // We use just the vertical component of the DPI because it's the one - // that counts most and, in practice, it's equal to the horizontal one - // anyhow. - return dpi.y / (double)wxDisplay::GetStdPPIValue(); + return wxDisplay(static_cast(this)).GetScaleFactor(); } // helper of GetWindowBorderSize(): as many ports don't implement support for @@ -2887,6 +2863,25 @@ wxSize wxWindowBase::GetDPI() const #ifndef wxHAVE_DPI_INDEPENDENT_PIXELS +namespace +{ + +static wxSize GetDPIHelper(const wxWindowBase* w) +{ + wxSize dpi; + + if ( w ) + dpi = w->GetDPI(); + if ( !dpi.x || !dpi.y ) + dpi = wxScreenDC().GetPPI(); + if ( !dpi.x || !dpi.y ) + dpi = wxDisplay::GetStdPPI(); + + return dpi; +} + +} + /* static */ wxSize wxWindowBase::FromDIP(const wxSize& sz, const wxWindowBase* w) From 16ff1f8f7c2c7193ce119c221885b3e96249eb74 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Fri, 7 Aug 2020 16:34:27 +0200 Subject: [PATCH 05/16] macOS Implementation for wxDisplay::GetScaleFactor --- src/osx/core/display.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/osx/core/display.cpp b/src/osx/core/display.cpp index 796a7ef7cb..1892743377 100644 --- a/src/osx/core/display.cpp +++ b/src/osx/core/display.cpp @@ -104,6 +104,7 @@ public: virtual wxRect GetClientArea() const wxOVERRIDE; virtual int GetDepth() const wxOVERRIDE; virtual wxSize GetSizeMM() const wxOVERRIDE; + virtual double GetScaleFactor() const wxOVERRIDE; virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const wxOVERRIDE; virtual wxVideoMode GetCurrentMode() const wxOVERRIDE; @@ -270,6 +271,14 @@ wxSize wxDisplayImplMacOSX::GetSizeMM() const return wxGetDisplaySizeMM(m_id); } +double wxDisplayImplMacOSX::GetScaleFactor() const +{ + wxCFRef mode = CGDisplayCopyDisplayMode(m_id); + size_t width = CGDisplayModeGetWidth(mode); + size_t pixelsw = CGDisplayModeGetPixelWidth(mode); + return (double)pixelsw / width; +} + static int wxOSXCGDisplayModeGetBitsPerPixel( CGDisplayModeRef theValue ) { wxCFRef pixelEncoding( CGDisplayModeCopyPixelEncoding(theValue) ); From d5180d3604b67ac5e64d2fbc157bea006ba1a4ea Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Fri, 7 Aug 2020 18:17:47 +0200 Subject: [PATCH 06/16] add a GetFromWindow implementation to wxDisplayFactory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit on displays with different resolutions we must make sure we pick one that matches the frame’s contentScale --- src/osx/core/display.cpp | 83 +++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 19 deletions(-) diff --git a/src/osx/core/display.cpp b/src/osx/core/display.cpp index 1892743377..b85cc3e081 100644 --- a/src/osx/core/display.cpp +++ b/src/osx/core/display.cpp @@ -29,6 +29,7 @@ #include "wx/log.h" #include "wx/string.h" #include "wx/gdicmn.h" + #include "wx/nonownedwnd.h" #endif #include "wx/osx/private.h" @@ -126,6 +127,7 @@ public: virtual wxDisplayImpl *CreateDisplay(unsigned n) wxOVERRIDE; virtual unsigned GetCount() wxOVERRIDE; virtual int GetFromPoint(const wxPoint& pt) wxOVERRIDE; + virtual int GetFromWindow(const wxWindow *window) wxOVERRIDE; protected: wxDECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX); @@ -178,29 +180,14 @@ static CGDisplayErr wxOSXGetDisplayList(CGDisplayCount maxDisplays, return error; } -unsigned wxDisplayFactoryMacOSX::GetCount() +static int wxOSXGetDisplayFromID( CGDirectDisplayID theID ) { - CGDisplayCount count; - CGDisplayErr err = wxOSXGetDisplayList(0, NULL, &count); - - wxCHECK_MSG( err == CGDisplayNoErr, 0, "wxOSXGetDisplayList() failed" ); - - return count; -} - -int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint& p) -{ - CGPoint thePoint = {(float)p.x, (float)p.y}; - CGDirectDisplayID theID; - CGDisplayCount theCount; - CGDisplayErr err = CGGetDisplaysWithPoint(thePoint, 1, &theID, &theCount); - wxASSERT(err == CGDisplayNoErr); - int nWhich = wxNOT_FOUND; + CGDisplayCount theCount; + CGDisplayErr err = wxOSXGetDisplayList(0, NULL, &theCount); - if (theCount) + if (err == CGDisplayNoErr && theCount > 0 ) { - theCount = GetCount(); CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount]; err = wxOSXGetDisplayList(theCount, theIDs, &theCount); wxASSERT(err == CGDisplayNoErr); @@ -223,6 +210,64 @@ int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint& p) return nWhich; } +unsigned wxDisplayFactoryMacOSX::GetCount() +{ + CGDisplayCount count; + CGDisplayErr err = wxOSXGetDisplayList(0, NULL, &count); + + wxCHECK_MSG( err == CGDisplayNoErr, 0, "wxOSXGetDisplayList() failed" ); + + return count; +} + +int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint& p) +{ + CGPoint thePoint = {(float)p.x, (float)p.y}; + CGDirectDisplayID theID; + CGDisplayCount theCount; + CGDisplayErr err = CGGetDisplaysWithPoint(thePoint, 1, &theID, &theCount); + wxASSERT(err == CGDisplayNoErr); + + if (theCount) + return wxOSXGetDisplayFromID(theID); + + return wxNOT_FOUND; +} + +int wxDisplayFactoryMacOSX::GetFromWindow(const wxWindow *window) +{ + wxCHECK_MSG( window, wxNOT_FOUND, "window can't be NULL" ); + + wxNonOwnedWindow* const tlw = window->MacGetTopLevelWindow(); + int x,y,w,h; + + tlw->GetPosition(&x, &y); + tlw->GetSize(&w, &h); + + CGRect r = CGRectMake(x, y, w, h); + CGDisplayCount theCount; + CGDisplayErr err = CGGetDisplaysWithRect(r, 0, NULL, &theCount); + wxASSERT(err == CGDisplayNoErr); + + wxScopedArray theIDs(theCount); + err = CGGetDisplaysWithRect(r, theCount, theIDs.get(), &theCount); + wxASSERT(err == CGDisplayNoErr); + + for ( int i = 0 ; i < theCount; ++i ) + { + // find a screen intersecting having the same contentScale as the window itself + wxCFRef mode = CGDisplayCopyDisplayMode(theIDs[i]); + size_t width = CGDisplayModeGetWidth(mode); + size_t pixelsw = CGDisplayModeGetPixelWidth(mode); + if ( fabs( (double)pixelsw / width - tlw->GetContentScaleFactor() ) < 0.01 ) + { + return wxOSXGetDisplayFromID(theIDs[i]); + } + } + + return wxNOT_FOUND; +} + wxDisplayImpl *wxDisplayFactoryMacOSX::CreateDisplay(unsigned n) { CGDisplayCount theCount = GetCount(); From 8bad3b5e8032db1958e1eb9a2d0d236bad7d2183 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Fri, 7 Aug 2020 18:52:37 +0200 Subject: [PATCH 07/16] macOS clientRect implementation for non-primary displays --- src/osx/cocoa/utils.mm | 18 ++++++++++++++++++ src/osx/core/display.cpp | 9 ++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/osx/cocoa/utils.mm b/src/osx/cocoa/utils.mm index 97b3a8822c..d73bffe8b6 100644 --- a/src/osx/cocoa/utils.mm +++ b/src/osx/cocoa/utils.mm @@ -485,6 +485,24 @@ wxRect wxOSXGetMainDisplayClientArea() return wxFromNSRect( NULL, displayRect ); } +static NSScreen* wxOSXGetScreenFromDisplay( CGDirectDisplayID ID) +{ + for (NSScreen* screen in [NSScreen screens]) + { + CGDirectDisplayID displayID = [[[screen deviceDescription] objectForKey:@"NSScreenNumber"] intValue]; + if ( displayID == ID ) + return screen; + } + return NULL; +} + +extern // used from src/osx/core/display.cpp +wxRect wxOSXGetDisplayClientArea(CGDirectDisplayID ID) +{ + NSRect displayRect = [wxOSXGetScreenFromDisplay(ID) visibleFrame]; + return wxFromNSRect( NULL, displayRect ); +} + void wxGetMousePosition( int* x, int* y ) { wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]); diff --git a/src/osx/core/display.cpp b/src/osx/core/display.cpp index b85cc3e081..9d1131dc4e 100644 --- a/src/osx/core/display.cpp +++ b/src/osx/core/display.cpp @@ -40,6 +40,7 @@ // This one is defined in Objective C++ code. extern wxRect wxOSXGetMainDisplayClientArea(); +extern wxRect wxOSXGetDisplayClientArea(CGDirectDisplayID id); namespace { @@ -297,13 +298,7 @@ wxRect wxDisplayImplMacOSX::GetGeometry() const wxRect wxDisplayImplMacOSX::GetClientArea() const { - // VZ: I don't know how to get client area for arbitrary display but - // wxGetClientDisplayRect() does work correctly for at least the main - // one (TODO: do it correctly for the other displays too) - if ( IsPrimary() ) - return wxOSXGetMainDisplayClientArea(); - - return wxDisplayImpl::GetClientArea(); + return wxOSXGetDisplayClientArea(m_id); } int wxDisplayImplMacOSX::GetDepth() const From 7dc67a1f9f338fd76bbfebaab946313b6121b226 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sat, 8 Aug 2020 18:43:55 +0200 Subject: [PATCH 08/16] making GetDPIScaleFactor virtual, adding macOS direct impl --- include/wx/osx/window.h | 1 + include/wx/window.h | 2 +- src/osx/window_osx.cpp | 9 ++++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/wx/osx/window.h b/include/wx/osx/window.h index 76ec9bdb1c..e327b0a55b 100644 --- a/include/wx/osx/window.h +++ b/include/wx/osx/window.h @@ -121,6 +121,7 @@ public: #endif // wxUSE_HOTKEY virtual wxSize GetDPI() const wxOVERRIDE; + virtual double GetDPIScaleFactor() const wxOVERRIDE; #if wxUSE_DRAG_AND_DROP virtual void SetDropTarget( wxDropTarget *dropTarget ) wxOVERRIDE; diff --git a/include/wx/window.h b/include/wx/window.h index 68e91ad291..1c3cc3d759 100644 --- a/include/wx/window.h +++ b/include/wx/window.h @@ -537,7 +537,7 @@ public: // Return the ratio of the DPI used by this window to the standard DPI, // e.g. 1 for standard DPI screens and 2 for "200% scaling". - double GetDPIScaleFactor() const; + virtual double GetDPIScaleFactor() const; // return the size of the left/right and top/bottom borders in x and y // components of the result respectively diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 4e5db615b2..65dd5d2fed 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -2629,6 +2629,12 @@ wxSize wxWindowMac::OSXMakeDPIFromScaleFactor(double scaleFactor) } wxSize wxWindowMac::GetDPI() const +{ + return OSXMakeDPIFromScaleFactor(GetDPIScaleFactor()); +} + +// on mac ContentScale and DPIScale are identical +double wxWindowMac::GetDPIScaleFactor() const { double scaleFactor; if ( wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ) @@ -2636,9 +2642,10 @@ wxSize wxWindowMac::GetDPI() const else scaleFactor = wxOSXGetMainScreenContentScaleFactor(); - return OSXMakeDPIFromScaleFactor(scaleFactor); + return scaleFactor; } + // // wxWidgetImpl // From 99f7c8f3a4e8e01708dcc3f9ddcb874adc4f36ac Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Fri, 14 Aug 2020 14:43:04 +0200 Subject: [PATCH 09/16] using common method for determining scale from displayID --- src/osx/core/display.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/osx/core/display.cpp b/src/osx/core/display.cpp index 9d1131dc4e..48e76b003c 100644 --- a/src/osx/core/display.cpp +++ b/src/osx/core/display.cpp @@ -45,6 +45,14 @@ extern wxRect wxOSXGetDisplayClientArea(CGDirectDisplayID id); namespace { +double wxGetScaleFactor( CGDirectDisplayID ID) +{ + wxCFRef mode = CGDisplayCopyDisplayMode(ID); + size_t width = CGDisplayModeGetWidth(mode); + size_t pixelsw = CGDisplayModeGetPixelWidth(mode); + return (double)pixelsw/width; +} + wxRect wxGetDisplayGeometry(CGDirectDisplayID id) { CGRect theRect = CGDisplayBounds(id); @@ -257,10 +265,8 @@ int wxDisplayFactoryMacOSX::GetFromWindow(const wxWindow *window) for ( int i = 0 ; i < theCount; ++i ) { // find a screen intersecting having the same contentScale as the window itself - wxCFRef mode = CGDisplayCopyDisplayMode(theIDs[i]); - size_t width = CGDisplayModeGetWidth(mode); - size_t pixelsw = CGDisplayModeGetPixelWidth(mode); - if ( fabs( (double)pixelsw / width - tlw->GetContentScaleFactor() ) < 0.01 ) + double scale = wxGetScaleFactor(theIDs[i]); + if ( fabs(scale - tlw->GetContentScaleFactor() ) < 0.01 ) { return wxOSXGetDisplayFromID(theIDs[i]); } @@ -313,10 +319,7 @@ wxSize wxDisplayImplMacOSX::GetSizeMM() const double wxDisplayImplMacOSX::GetScaleFactor() const { - wxCFRef mode = CGDisplayCopyDisplayMode(m_id); - size_t width = CGDisplayModeGetWidth(mode); - size_t pixelsw = CGDisplayModeGetPixelWidth(mode); - return (double)pixelsw / width; + return wxGetScaleFactor(m_id); } static int wxOSXCGDisplayModeGetBitsPerPixel( CGDisplayModeRef theValue ) From 6a820a8f9ab7095f3fb42e0641bf2043a8eaf658 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 14 Aug 2020 14:53:41 +0200 Subject: [PATCH 10/16] Implement GetDPIScaleFactor() more efficiently in wxGTK Don't pass via wxDisplay, but use gtk_widget_get_scale_factor() (almost) directly instead. --- include/wx/gtk/window.h | 1 + src/gtk/window.cpp | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index 9ca1202da1..9ec33b88ab 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -97,6 +97,7 @@ public: virtual int GetCharHeight() const wxOVERRIDE; virtual int GetCharWidth() const wxOVERRIDE; virtual double GetContentScaleFactor() const wxOVERRIDE; + virtual double GetDPIScaleFactor() const wxOVERRIDE; virtual void SetScrollbar( int orient, int pos, int thumbVisible, int range, bool refresh = true ) wxOVERRIDE; diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 4e33c1ff06..e7c8ecbe39 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -4363,6 +4363,13 @@ double wxWindowGTK::GetContentScaleFactor() const return scaleFactor; } +double wxWindowGTK::GetDPIScaleFactor() const +{ + // Under GTK 3 DPI scale factor is the same as content scale factor, while + // under GTK 2 both are always 1, so they're still the same. + return GetContentScaleFactor(); +} + void wxWindowGTK::GTKDisableFocusOutEvent() { g_signal_handlers_block_by_func( m_focusWidget, From 4e6df3f7b23e26ce3636f1c016a6dd8033f392ff Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 14 Aug 2020 14:59:23 +0200 Subject: [PATCH 11/16] Implement GetDPIScaleFactor() more directly for wxMSW too Use the existing GetDPI() implementation instead of forwarding to wxDisplay. --- include/wx/msw/window.h | 2 ++ src/msw/window.cpp | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index 7f2f5c9575..b5d21eb7b8 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -100,6 +100,8 @@ public: virtual bool Reparent(wxWindowBase *newParent) wxOVERRIDE; virtual wxSize GetDPI() const wxOVERRIDE; + virtual double GetDPIScaleFactor() const wxOVERRIDE; + virtual void WarpPointer(int x, int y) wxOVERRIDE; virtual bool EnableTouchEvents(int eventsMask) wxOVERRIDE; diff --git a/src/msw/window.cpp b/src/msw/window.cpp index d086477c9b..123eb58bde 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -105,6 +105,7 @@ #include "wx/notebook.h" #include "wx/listctrl.h" #include "wx/dynlib.h" +#include "wx/display.h" #include @@ -4858,6 +4859,11 @@ wxSize wxWindowMSW::GetDPI() const return dpi; } +double wxWindowMSW::GetDPIScaleFactor() const +{ + return GetDPI().y / (double)wxDisplay::GetStdPPIValue(); +} + void wxWindowMSW::MSWUpdateFontOnDPIChange(const wxSize& newDPI) { if ( m_font.IsOk() ) From bcb101b9e935a5de8b6b3030cd5b05e1ea2240bf Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 14 Aug 2020 15:17:59 +0200 Subject: [PATCH 12/16] Simplify PPI and scale factor handling in wxDisplay Don't try computing the PPI ourselves from the physical size and the number of pixels, this doesn't work and nobody else does it like this. Just assume that we're using standard PPI by default and use toolkit-specific functions for the platforms with support for high DPI. --- include/wx/private/display.h | 15 ++++--------- src/common/dpycmn.cpp | 41 ------------------------------------ src/gtk/display.cpp | 35 ++---------------------------- src/msw/display.cpp | 7 ++++++ 4 files changed, 13 insertions(+), 85 deletions(-) diff --git a/include/wx/private/display.h b/include/wx/private/display.h index 3f74f3dc99..55ece769ed 100644 --- a/include/wx/private/display.h +++ b/include/wx/private/display.h @@ -115,13 +115,11 @@ public: // return the scale factor used to convert logical pixels to physical ones virtual double GetScaleFactor() const { return 1.0; } - // return the resolution of the display, uses GetSize(), GetScaleFactor() - // and GetSizeMM() by default but can be also overridden directly - virtual wxSize GetPPI() const; + // return the resolution of the display, by default uses GetScaleFactor(), + // but can be also overridden directly, as is done in wxMSW + virtual wxSize GetPPI() const { return wxDisplay::GetStdPPI()*GetScaleFactor(); } - // return the physical size of the display or (0, 0) if unknown: this is - // only used by GetPPI() implementation in the base class, so if GetPPI() - // is overridden, this one doesn't have to be implemented + // return the physical size of the display or (0, 0) if unknown virtual wxSize GetSizeMM() const { return wxSize(0, 0); } // return the name (may be empty) @@ -149,11 +147,6 @@ protected: // create the object providing access to the display with the given index wxDisplayImpl(unsigned n) : m_index(n) { } - // Compute PPI from the sizes in pixels and mm. - // - // Return (0, 0) if physical size (in mm) is not known, i.e. 0. - static wxSize ComputePPI(int pxX, int pxY, int mmX, int mmY); - // the index of this display (0 is always the primary one) const unsigned m_index; diff --git a/src/common/dpycmn.cpp b/src/common/dpycmn.cpp index c968f9c960..4d2feeac56 100644 --- a/src/common/dpycmn.cpp +++ b/src/common/dpycmn.cpp @@ -153,19 +153,7 @@ double wxDisplay::GetScaleFactor() const { wxCHECK_MSG( IsOk(), 0, wxT("invalid wxDisplay object") ); -#ifdef wxHAVE_DPI_INDEPENDENT_PIXELS - // Use wxDisplayImpl::GetScaleFactor() directly, it should be implemented - // correctly for the platforms doing pixel scaling and using it simpler and - // more efficient than using GetPPI(). return m_impl->GetScaleFactor(); -#else - // Under the other platforms, we just compute the DPI ratio ourselves. - // - // We use just the vertical component of the DPI because it's the one - // that counts most and, in practice, it's equal to the horizontal one - // anyhow. - return m_impl->GetPPI().y / (double)GetStdPPIValue(); -#endif } int wxDisplay::GetDepth() const @@ -226,35 +214,6 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode) return *gs_factory; } -// ============================================================================ -// wxDisplayImpl implementation -// ============================================================================ - -/* static */ -wxSize wxDisplayImpl::ComputePPI(int pxX, int pxY, int mmX, int mmY) -{ - if ( !mmX || !mmY ) - { - // Physical size is unknown, return a special value indicating that we - // can't compute the resolution -- what else can we do? - return wxSize(0, 0); - } - - return wxSize(wxRound((pxX * inches2mm) / mmX), - wxRound((pxY * inches2mm) / mmY)); -} - -wxSize wxDisplayImpl::GetPPI() const -{ - const wxSize mm = GetSizeMM(); - - // We need physical pixels here, not logical ones returned by - // GetGeometry(), to compute the real DPI. - const wxSize pixels = GetGeometry().GetSize()*GetScaleFactor(); - - return ComputePPI(pixels.x, pixels.y, mm.x, mm.y); -} - // ============================================================================ // wxDisplayFactory implementation // ============================================================================ diff --git a/src/gtk/display.cpp b/src/gtk/display.cpp index b21a0c2295..6bacd94456 100644 --- a/src/gtk/display.cpp +++ b/src/gtk/display.cpp @@ -255,7 +255,6 @@ public: #if GTK_CHECK_VERSION(3,10,0) virtual double GetScaleFactor() const wxOVERRIDE; #endif // GTK+ 3.10 - virtual wxSize GetPPI() const wxOVERRIDE; virtual wxSize GetSizeMM() const wxOVERRIDE; #if wxUSE_DISPLAY @@ -350,36 +349,6 @@ double wxDisplayImplGTK::GetScaleFactor() const return 1.0; } - -wxSize wxDisplayImplGTK::GetPPI() const -{ - // The useful value of PPI is the scaled value of the default PPI and not - // the actual PPI computed by dividing the number of pixels by the physical - // screen size: this is what everyone else uses, and so we should do it - // too. - return wxDisplay::GetStdPPI()*GetScaleFactor(); -} - -#else // GTK+ < 3.10 - -wxSize wxDisplayImplGTK::GetPPI() const -{ - // Try the base class version which uses our GetSizeMM() and returns - // per-display PPI value if it works. - wxSize ppi = wxDisplayImpl::GetPPI(); - - if ( !ppi.x || !ppi.y ) - { - // But if it didn't work, fall back to the global DPI value common to - // all displays -- this is still better than nothing and more - // compatible with the previous wxWidgets versions. - ppi = ComputePPI(gdk_screen_width(), gdk_screen_height(), - gdk_screen_width_mm(), gdk_screen_height_mm()); - } - - return ppi; -} - #endif // GTK+ 3.10 wxSize wxDisplayImplGTK::GetSizeMM() const @@ -403,9 +372,9 @@ wxSize wxDisplayImplGTK::GetSizeMM() const // When we have only a single display, we can use global GTK+ functions. // Note that at least in some configurations, these functions return valid // values when gdk_screen_get_monitor_xxx_mm() only return -1, so it's - // always worth fallng back on them, but we can't do it when using + // always worth falling back on them, but we can't do it when using // multiple displays because they combine the sizes of all displays in this - // case, which would result in a completely wrong value for GetPPI(). + // case, which would result in a completely wrong value. if ( !(sizeMM.x && sizeMM.y) && gdk_screen_get_n_monitors(m_screen) == 1 ) { sizeMM.x = gdk_screen_width_mm(); diff --git a/src/msw/display.cpp b/src/msw/display.cpp index 3b96ac7ab8..73ff8dd754 100644 --- a/src/msw/display.cpp +++ b/src/msw/display.cpp @@ -141,6 +141,7 @@ public: virtual wxRect GetClientArea() const wxOVERRIDE; virtual int GetDepth() const wxOVERRIDE; virtual wxSize GetPPI() const wxOVERRIDE; + virtual double GetScaleFactor() const wxOVERRIDE; virtual wxString GetName() const wxOVERRIDE; virtual bool IsPrimary() const wxOVERRIDE; @@ -332,6 +333,12 @@ wxSize wxDisplayMSW::GetPPI() const return IsPrimary() ? wxDisplayImplSingleMSW().GetPPI() : wxSize(0, 0); } +double wxDisplayMSW::GetScaleFactor() const +{ + const int ppi = GetPPI().y; + return ppi ? ppi / (double)wxDisplay::GetStdPPIValue() : 1.0; +} + wxString wxDisplayMSW::GetName() const { return m_info.monInfo.szDevice; From 434faa39e63cb82d80f5a74a47434b799640adee Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 14 Aug 2020 15:25:13 +0200 Subject: [PATCH 13/16] Remove unused wxDisplayImpl::GetSizeMM() This is not needed any longer after the changes of the last commit. Note that the (still existent) public wxGetDisplaySizeMM() didn't use this function, but used PPI instead. --- include/wx/private/display.h | 3 --- src/gtk/display.cpp | 44 ------------------------------------ src/msw/display.cpp | 7 ------ src/osx/core/display.cpp | 17 -------------- src/qt/display.cpp | 8 ------- src/unix/displayx11.cpp | 10 -------- 6 files changed, 89 deletions(-) diff --git a/include/wx/private/display.h b/include/wx/private/display.h index 55ece769ed..b45bfed6c9 100644 --- a/include/wx/private/display.h +++ b/include/wx/private/display.h @@ -119,9 +119,6 @@ public: // but can be also overridden directly, as is done in wxMSW virtual wxSize GetPPI() const { return wxDisplay::GetStdPPI()*GetScaleFactor(); } - // return the physical size of the display or (0, 0) if unknown - virtual wxSize GetSizeMM() const { return wxSize(0, 0); } - // return the name (may be empty) virtual wxString GetName() const { return wxString(); } diff --git a/src/gtk/display.cpp b/src/gtk/display.cpp index 6bacd94456..783912a2c7 100644 --- a/src/gtk/display.cpp +++ b/src/gtk/display.cpp @@ -50,7 +50,6 @@ public: virtual wxRect GetClientArea() const wxOVERRIDE; virtual int GetDepth() const wxOVERRIDE; virtual double GetScaleFactor() const wxOVERRIDE; - virtual wxSize GetSizeMM() const wxOVERRIDE; #if wxUSE_DISPLAY virtual bool IsPrimary() const wxOVERRIDE; @@ -151,15 +150,6 @@ double wxDisplayImplGTK::GetScaleFactor() const return gdk_monitor_get_scale_factor(m_monitor); } -wxSize wxDisplayImplGTK::GetSizeMM() const -{ - return wxSize - ( - gdk_monitor_get_width_mm(m_monitor), - gdk_monitor_get_height_mm(m_monitor) - ); -} - #if wxUSE_DISPLAY bool wxDisplayImplGTK::IsPrimary() const { @@ -255,7 +245,6 @@ public: #if GTK_CHECK_VERSION(3,10,0) virtual double GetScaleFactor() const wxOVERRIDE; #endif // GTK+ 3.10 - virtual wxSize GetSizeMM() const wxOVERRIDE; #if wxUSE_DISPLAY virtual bool IsPrimary() const wxOVERRIDE; @@ -351,39 +340,6 @@ double wxDisplayImplGTK::GetScaleFactor() const } #endif // GTK+ 3.10 -wxSize wxDisplayImplGTK::GetSizeMM() const -{ - wxSize sizeMM; -#if GTK_CHECK_VERSION(2,14,0) - if ( wx_is_at_least_gtk2(14) ) - { - // Take care not to return (-1, -1) from here, the caller expects us to - // return (0, 0) if we can't retrieve this information. - int rc = gdk_screen_get_monitor_width_mm(m_screen, m_index); - if ( rc != -1 ) - sizeMM.x = rc; - - rc = gdk_screen_get_monitor_height_mm(m_screen, m_index); - if ( rc != -1 ) - sizeMM.y = rc; - } -#endif // GTK+ 2.14 - - // When we have only a single display, we can use global GTK+ functions. - // Note that at least in some configurations, these functions return valid - // values when gdk_screen_get_monitor_xxx_mm() only return -1, so it's - // always worth falling back on them, but we can't do it when using - // multiple displays because they combine the sizes of all displays in this - // case, which would result in a completely wrong value. - if ( !(sizeMM.x && sizeMM.y) && gdk_screen_get_n_monitors(m_screen) == 1 ) - { - sizeMM.x = gdk_screen_width_mm(); - sizeMM.y = gdk_screen_height_mm(); - } - - return sizeMM; -} - #if wxUSE_DISPLAY bool wxDisplayImplGTK::IsPrimary() const { diff --git a/src/msw/display.cpp b/src/msw/display.cpp index 73ff8dd754..bc40019045 100644 --- a/src/msw/display.cpp +++ b/src/msw/display.cpp @@ -67,13 +67,6 @@ public: { return wxGetHDCDepth(ScreenHDC()); } - - virtual wxSize GetSizeMM() const wxOVERRIDE - { - ScreenHDC dc; - - return wxSize(::GetDeviceCaps(dc, HORZSIZE), ::GetDeviceCaps(dc, VERTSIZE)); - } }; class wxDisplayFactorySingleMSW : public wxDisplayFactorySingle diff --git a/src/osx/core/display.cpp b/src/osx/core/display.cpp index 48e76b003c..0a0296259b 100644 --- a/src/osx/core/display.cpp +++ b/src/osx/core/display.cpp @@ -85,12 +85,6 @@ int wxGetDisplayDepth(CGDirectDisplayID id) return theDepth; } -wxSize wxGetDisplaySizeMM(CGDirectDisplayID id) -{ - const CGSize size = CGDisplayScreenSize(id); - return wxSize(wxRound(size.width), wxRound(size.height)); -} - } // anonymous namespace #if wxUSE_DISPLAY @@ -113,7 +107,6 @@ public: virtual wxRect GetGeometry() const wxOVERRIDE; virtual wxRect GetClientArea() const wxOVERRIDE; virtual int GetDepth() const wxOVERRIDE; - virtual wxSize GetSizeMM() const wxOVERRIDE; virtual double GetScaleFactor() const wxOVERRIDE; virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const wxOVERRIDE; @@ -312,11 +305,6 @@ int wxDisplayImplMacOSX::GetDepth() const return wxGetDisplayDepth(m_id); } -wxSize wxDisplayImplMacOSX::GetSizeMM() const -{ - return wxGetDisplaySizeMM(m_id); -} - double wxDisplayImplMacOSX::GetScaleFactor() const { return wxGetScaleFactor(m_id); @@ -437,11 +425,6 @@ public: { return wxGetDisplayDepth(CGMainDisplayID()); } - - virtual wxSize GetSizeMM() const wxOVERRIDE - { - return wxGetDisplaySizeMM(CGMainDisplayID()); - } }; class wxDisplayFactorySingleMacOSX : public wxDisplayFactorySingle diff --git a/src/qt/display.cpp b/src/qt/display.cpp index 18eb47e286..6d3de3ac2e 100644 --- a/src/qt/display.cpp +++ b/src/qt/display.cpp @@ -22,7 +22,6 @@ public: virtual wxRect GetGeometry() const wxOVERRIDE; virtual wxRect GetClientArea() const wxOVERRIDE; virtual int GetDepth() const wxOVERRIDE; - virtual wxSize GetSizeMM() const wxOVERRIDE; #if wxUSE_DISPLAY virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const wxOVERRIDE; @@ -51,13 +50,6 @@ int wxDisplayImplQt::GetDepth() const return IsPrimary() ? QApplication::desktop()->depth() : 0; } -wxSize wxDisplayImplQt::GetSizeMM() const -{ - return IsPrimary() ? wxSize(QApplication::desktop()->widthMM(), - QApplication::desktop()->heightMM()) - : wxSize(0, 0); -} - #if wxUSE_DISPLAY wxArrayVideoModes wxDisplayImplQt::GetModes(const wxVideoMode& WXUNUSED(mode)) const { diff --git a/src/unix/displayx11.cpp b/src/unix/displayx11.cpp index e2e67970c0..14f6d6e416 100644 --- a/src/unix/displayx11.cpp +++ b/src/unix/displayx11.cpp @@ -76,11 +76,6 @@ public: { return wxGetMainScreenDepth(); } - - virtual wxSize GetSizeMM() const wxOVERRIDE - { - return wxGetMainScreenSizeMM(); - } }; class wxDisplayFactorySingleX11 : public wxDisplayFactorySingle @@ -159,11 +154,6 @@ public: return wxGetMainScreenDepth(); } - virtual wxSize GetSizeMM() const wxOVERRIDE - { - // TODO: how to get physical size or resolution of the other monitors? - return IsPrimary() ? wxGetMainScreenSizeMM() : wxSize(0, 0); - } virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const wxOVERRIDE; virtual wxVideoMode GetCurrentMode() const wxOVERRIDE; From c346fd0321e2b6838184b6cfe6c30f7d30fb9dce Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 14 Aug 2020 15:35:00 +0200 Subject: [PATCH 14/16] Show scale factor in the display sample too Show it for consistency with all the other wxDisplay accessors and to make it simpler to test its return value. --- samples/display/display.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/samples/display/display.cpp b/samples/display/display.cpp index 199e0e275d..c6de01aae4 100644 --- a/samples/display/display.cpp +++ b/samples/display/display.cpp @@ -292,6 +292,11 @@ void MyFrame::PopuplateWithDisplayInfo() sizer->Add(new wxStaticText(page, wxID_ANY, wxString::Format("%d", display.GetDepth()))); + sizer->Add(new wxStaticText(page, wxID_ANY, "Scaling: ")); + sizer->Add(new wxStaticText(page, wxID_ANY, + wxString::Format("%.2f", + display.GetScaleFactor()))); + sizer->Add(new wxStaticText(page, wxID_ANY, "Name: ")); sizer->Add(new wxStaticText(page, wxID_ANY, display.GetName())); From 08a63c3b498d14db275b8c349d64d5349c4f03cc Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Fri, 14 Aug 2020 15:52:48 +0200 Subject: [PATCH 15/16] use common contentScaleFactor also for DPI on macOS and give a reasonable default for missing tlw --- src/osx/cocoa/window.mm | 5 ++++- src/osx/window_osx.cpp | 8 +------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index 62fb443d5e..80a0838032 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -2648,7 +2648,10 @@ void wxWidgetCocoaImpl::SetVisibility( bool visible ) double wxWidgetCocoaImpl::GetContentScaleFactor() const { NSWindow* tlw = [m_osxView window]; - return [tlw backingScaleFactor]; + if ( tlw ) + return [tlw backingScaleFactor]; + else + return wxOSXGetMainScreenContentScaleFactor(); } // ---------------------------------------------------------------------------- diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 65dd5d2fed..46fa8188a1 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -2636,13 +2636,7 @@ wxSize wxWindowMac::GetDPI() const // on mac ContentScale and DPIScale are identical double wxWindowMac::GetDPIScaleFactor() const { - double scaleFactor; - if ( wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ) - scaleFactor = tlw->GetContentScaleFactor(); - else - scaleFactor = wxOSXGetMainScreenContentScaleFactor(); - - return scaleFactor; + return GetContentScaleFactor(); } From 41142dff20d8d00c98cd05b901a76280a8ce1d7f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 15 Aug 2020 00:27:07 +0200 Subject: [PATCH 16/16] Make a minor optimization in Mac wxDisplay::GetFromWindow() Call GetContentScaleFactor() only once, which doesn't cost anything and could be minutely faster on systems with multiple displays. --- src/osx/core/display.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/osx/core/display.cpp b/src/osx/core/display.cpp index 0a0296259b..06f968edc9 100644 --- a/src/osx/core/display.cpp +++ b/src/osx/core/display.cpp @@ -255,11 +255,12 @@ int wxDisplayFactoryMacOSX::GetFromWindow(const wxWindow *window) err = CGGetDisplaysWithRect(r, theCount, theIDs.get(), &theCount); wxASSERT(err == CGDisplayNoErr); + const double scaleWindow = tlw->GetContentScaleFactor(); for ( int i = 0 ; i < theCount; ++i ) { // find a screen intersecting having the same contentScale as the window itself double scale = wxGetScaleFactor(theIDs[i]); - if ( fabs(scale - tlw->GetContentScaleFactor() ) < 0.01 ) + if ( fabs(scale - scaleWindow) < 0.01 ) { return wxOSXGetDisplayFromID(theIDs[i]); }