From fa58dc2c4540a17c6459bad58c5795d5bedad09a Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sat, 18 Jul 2020 18:24:28 +0200 Subject: [PATCH 1/7] Generate wxEVT_DPI_CHANGED event under Mac --- src/osx/cocoa/nonownedwnd.mm | 39 +++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/osx/cocoa/nonownedwnd.mm b/src/osx/cocoa/nonownedwnd.mm index f38eeddde4..a0ad84b8d4 100644 --- a/src/osx/cocoa/nonownedwnd.mm +++ b/src/osx/cocoa/nonownedwnd.mm @@ -321,6 +321,7 @@ static void *EffectiveAppearanceContext = &EffectiveAppearanceContext; - (BOOL)windowShouldClose:(id)window; - (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame; - (void)windowWillEnterFullScreen:(NSNotification *)notification; +- (void)windowDidChangeBackingProperties:(NSNotification *)notification; @end @@ -612,7 +613,43 @@ extern int wxOSXGetIdFromSelector(SEL action ); [view setFrameSize: expectedframerect.size]; } } - + +// from https://developer.apple.com/library/archive/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/CapturingScreenContents/CapturingScreenContents.html + +- (void)windowDidChangeBackingProperties:(NSNotification *)notification +{ + NSWindow* theWindow = (NSWindow*)[notification object]; + wxNonOwnedWindowCocoaImpl* windowimpl = [theWindow WX_implementation]; + wxNonOwnedWindow* wxpeer = windowimpl ? windowimpl->GetWXPeer() : NULL; + if (wxpeer) + { + CGFloat newBackingScaleFactor = [theWindow backingScaleFactor]; + CGFloat oldBackingScaleFactor = [[[notification userInfo] + objectForKey:@"NSBackingPropertyOldScaleFactorKey"] + doubleValue]; + if (newBackingScaleFactor != oldBackingScaleFactor) + { + wxSize oldDPI((int)(oldBackingScaleFactor*72.0),(int)(oldBackingScaleFactor*72.0)); + wxSize newDPI((int)(newBackingScaleFactor*72.0),(int)(newBackingScaleFactor*72.0)); + + wxDPIChangedEvent event(oldDPI, newDPI); + event.SetEventObject(wxpeer); + wxpeer->HandleWindowEvent(event); + + } + + NSColorSpace *newColorSpace = [theWindow colorSpace]; + NSColorSpace *oldColorSpace = [[notification userInfo] + objectForKey:@"NSBackingPropertyOldColorSpaceKey"]; + if (![newColorSpace isEqual:oldColorSpace]) + { + wxSysColourChangedEvent event; + event.SetEventObject(wxpeer); + wxpeer->HandleWindowEvent(event); + } + } +} + - (void)addObservers:(NSWindow*)win { [win addObserver:self forKeyPath:@"effectiveAppearance" From 668f0e7c54a969df1ea643f038afbcae0cda6128 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sat, 18 Jul 2020 20:01:23 +0200 Subject: [PATCH 2/7] Implement wxWindow::GetDPI() on macOS and iOS --- include/wx/osx/window.h | 2 ++ src/osx/window_osx.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/include/wx/osx/window.h b/include/wx/osx/window.h index 19cd7d21d7..af92472618 100644 --- a/include/wx/osx/window.h +++ b/include/wx/osx/window.h @@ -120,6 +120,8 @@ public: virtual bool UnregisterHotKey(int hotkeyId) wxOVERRIDE; #endif // wxUSE_HOTKEY + virtual wxSize GetDPI() const wxOVERRIDE; + #if wxUSE_DRAG_AND_DROP virtual void SetDropTarget( wxDropTarget *dropTarget ) wxOVERRIDE; diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index beccd49723..6e0ab1cfe8 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -2599,6 +2599,19 @@ bool wxWindowMac::OSXHandleKeyEvent( wxKeyEvent& event ) return handled ; } +wxSize wxWindowMac::GetDPI() const +{ + wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ; + + double scaleFactor; + if ( tlw ) + scaleFactor = tlw->GetContentScaleFactor(); + else + scaleFactor = wxOSXGetMainScreenContentScaleFactor(); + + return wxSize(wxRound(scaleFactor*72.0),wxRound(scaleFactor*72.0)); +} + // // wxWidgetImpl // From 1deb003a7c7627600ca5e5c43a676b08b5927fbb Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sun, 19 Jul 2020 14:30:38 +0200 Subject: [PATCH 3/7] Propagate wxEVT_DPI_CHANGED to child windows in wxOSX too --- include/wx/osx/window.h | 1 + src/osx/window_osx.cpp | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/wx/osx/window.h b/include/wx/osx/window.h index af92472618..479307975e 100644 --- a/include/wx/osx/window.h +++ b/include/wx/osx/window.h @@ -151,6 +151,7 @@ public: // -------------- void OnMouseEvent( wxMouseEvent &event ); + void OnDPIChanged( wxDPIChangedEvent& event ); void MacOnScroll( wxScrollEvent&event ); diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 6e0ab1cfe8..0aac85e24a 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -79,6 +79,7 @@ wxBEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase) EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent) + EVT_DPI_CHANGED(wxWindowMac::OnDPIChanged) wxEND_EVENT_TABLE() #define wxMAC_DEBUG_REDRAW 0 @@ -2345,6 +2346,25 @@ void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) } } +// propagate the dpi changed event to the subwindows +void wxWindowMac::OnDPIChanged(wxDPIChangedEvent& event) +{ + wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); + while ( node ) + { + // Only propagate to non-top-level windows + wxWindow *win = node->GetData(); + if ( !win->IsTopLevel() ) + { + wxDPIChangedEvent event2( event.GetOldDPI(), event.GetNewDPI() ); + event2.SetEventObject(win); + win->GetEventHandler()->ProcessEvent(event2); + } + + node = node->GetNext(); + } +} + void wxWindowMac::TriggerScrollEvent( wxEventType WXUNUSED(scrollEvent) ) { } From 984e222519f32859198c5c1e90c0435ac1d388e9 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Sun, 19 Jul 2020 15:14:21 +0200 Subject: [PATCH 4/7] Fix content scale factor returned by wxScreenDC on Mac --- src/osx/carbon/dcscreen.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/osx/carbon/dcscreen.cpp b/src/osx/carbon/dcscreen.cpp index 234fd3934a..1c6a987f96 100644 --- a/src/osx/carbon/dcscreen.cpp +++ b/src/osx/carbon/dcscreen.cpp @@ -34,6 +34,7 @@ wxScreenDCImpl::wxScreenDCImpl( wxDC *owner ) : SetGraphicsContext( wxGraphicsContext::Create() ); m_ok = true ; #endif + m_contentScaleFactor = wxOSXGetMainScreenContentScaleFactor(); } wxScreenDCImpl::~wxScreenDCImpl() From af7a6ed2d0eaa004740598617d890f14c30f4ed9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 21 Jul 2020 17:09:43 +0200 Subject: [PATCH 5/7] Combine variable declaration and test in a single line No real changes, make the code slightly shorter. --- src/osx/window_osx.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 0aac85e24a..5520e1ba5f 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -2621,10 +2621,8 @@ bool wxWindowMac::OSXHandleKeyEvent( wxKeyEvent& event ) wxSize wxWindowMac::GetDPI() const { - wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ; - double scaleFactor; - if ( tlw ) + if ( wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ) scaleFactor = tlw->GetContentScaleFactor(); else scaleFactor = wxOSXGetMainScreenContentScaleFactor(); From a2c55fa834b02dfefcb4290acda701fce814d235 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 21 Jul 2020 17:11:14 +0200 Subject: [PATCH 6/7] Include wx/math.h in the file using wxRound() Although it seems to be already included from some other header implicitly, prefer to also include it explicitly to avoid any breakage later. --- src/osx/window_osx.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 5520e1ba5f..61bf54cbea 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -14,6 +14,7 @@ #ifndef WX_PRECOMP #include "wx/log.h" + #include "wx/math.h" #include "wx/app.h" #include "wx/utils.h" #include "wx/panel.h" From a8bb796f8c39cbca62ec93d262e006cbcd2671b4 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 21 Jul 2020 17:13:41 +0200 Subject: [PATCH 7/7] Add OSXMakeDPIFromScaleFactor() helper No real changes, just avoid repeating wxRound(scaleFactor*72) in several places and do it in this single function instead. --- include/wx/osx/window.h | 3 +++ src/osx/cocoa/nonownedwnd.mm | 4 ++-- src/osx/window_osx.cpp | 10 +++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/include/wx/osx/window.h b/include/wx/osx/window.h index 479307975e..76ec9bdb1c 100644 --- a/include/wx/osx/window.h +++ b/include/wx/osx/window.h @@ -294,6 +294,9 @@ public: // internal response to size events virtual void MacOnInternalSize() {} + // Return the DPI corresponding to the given scale factor. + static wxSize OSXMakeDPIFromScaleFactor(double scaleFactor); + protected: // For controls like radio buttons which are genuinely composite wxList m_subControls; diff --git a/src/osx/cocoa/nonownedwnd.mm b/src/osx/cocoa/nonownedwnd.mm index a0ad84b8d4..f118433a03 100644 --- a/src/osx/cocoa/nonownedwnd.mm +++ b/src/osx/cocoa/nonownedwnd.mm @@ -629,8 +629,8 @@ extern int wxOSXGetIdFromSelector(SEL action ); doubleValue]; if (newBackingScaleFactor != oldBackingScaleFactor) { - wxSize oldDPI((int)(oldBackingScaleFactor*72.0),(int)(oldBackingScaleFactor*72.0)); - wxSize newDPI((int)(newBackingScaleFactor*72.0),(int)(newBackingScaleFactor*72.0)); + const wxSize oldDPI = wxWindow::OSXMakeDPIFromScaleFactor(oldBackingScaleFactor); + const wxSize newDPI = wxWindow::OSXMakeDPIFromScaleFactor(newBackingScaleFactor); wxDPIChangedEvent event(oldDPI, newDPI); event.SetEventObject(wxpeer); diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 61bf54cbea..4e5db615b2 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -2620,6 +2620,14 @@ bool wxWindowMac::OSXHandleKeyEvent( wxKeyEvent& event ) return handled ; } +/* static */ +wxSize wxWindowMac::OSXMakeDPIFromScaleFactor(double scaleFactor) +{ + const int dpi = wxRound(scaleFactor*72.0); + + return wxSize(dpi, dpi); +} + wxSize wxWindowMac::GetDPI() const { double scaleFactor; @@ -2628,7 +2636,7 @@ wxSize wxWindowMac::GetDPI() const else scaleFactor = wxOSXGetMainScreenContentScaleFactor(); - return wxSize(wxRound(scaleFactor*72.0),wxRound(scaleFactor*72.0)); + return OSXMakeDPIFromScaleFactor(scaleFactor); } //