diff --git a/include/wx/display.h b/include/wx/display.h index b9fec42aba..a5e8271e9b 100644 --- a/include/wx/display.h +++ b/include/wx/display.h @@ -87,6 +87,24 @@ 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()); + } + + // get the scaling used by this display + double GetScaleFactor() const; + // name may be empty wxString GetName() const; 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/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/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/private/display.h b/include/wx/private/display.h index 3f74f3dc99..b45bfed6c9 100644 --- a/include/wx/private/display.h +++ b/include/wx/private/display.h @@ -115,14 +115,9 @@ 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 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 - virtual wxSize GetSizeMM() const { return wxSize(0, 0); } + // 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 name (may be empty) virtual wxString GetName() const { return wxString(); } @@ -149,11 +144,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/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/interface/wx/display.h b/interface/wx/display.h index 2085ff15db..e9a51cc4c0 100644 --- a/interface/wx/display.h +++ b/interface/wx/display.h @@ -143,6 +143,46 @@ 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. + + 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/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())); diff --git a/src/common/dpycmn.cpp b/src/common/dpycmn.cpp index 4f0d537ef1..4d2feeac56 100644 --- a/src/common/dpycmn.cpp +++ b/src/common/dpycmn.cpp @@ -149,6 +149,13 @@ wxSize wxDisplay::GetPPI() const return m_impl->GetPPI(); } +double wxDisplay::GetScaleFactor() const +{ + wxCHECK_MSG( IsOk(), 0, wxT("invalid wxDisplay object") ); + + return m_impl->GetScaleFactor(); +} + int wxDisplay::GetDepth() const { wxCHECK_MSG( IsOk(), 0, wxT("invalid wxDisplay object") ); @@ -207,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/common/wincmn.cpp b/src/common/wincmn.cpp index 9b2e522920..2919c60416 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 // ---------------------------------------------------------------------------- @@ -793,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 = wxSize(BASELINE_DPI, BASELINE_DPI); - - return dpi; -} - -} - double wxWindowBase::GetContentScaleFactor() const { // By default, we assume that there is no mapping between logical and @@ -824,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)BASELINE_DPI; + return wxDisplay(static_cast(this)).GetScaleFactor(); } // helper of GetWindowBorderSize(): as many ports don't implement support for @@ -2894,16 +2863,37 @@ 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) { 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 +2902,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 diff --git a/src/gtk/display.cpp b/src/gtk/display.cpp index b1bdacb196..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,8 +245,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 virtual bool IsPrimary() const wxOVERRIDE; @@ -352,57 +340,6 @@ double wxDisplayImplGTK::GetScaleFactor() const } #endif // 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; -} - -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 fallng 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(). - 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/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, diff --git a/src/msw/display.cpp b/src/msw/display.cpp index 3b96ac7ab8..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 @@ -141,6 +134,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 +326,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; 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() ) 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/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/core/display.cpp b/src/osx/core/display.cpp index 796a7ef7cb..06f968edc9 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" @@ -39,10 +40,19 @@ // This one is defined in Objective C++ code. extern wxRect wxOSXGetMainDisplayClientArea(); +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); @@ -75,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 @@ -103,7 +107,7 @@ 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; virtual wxVideoMode GetCurrentMode() const wxOVERRIDE; @@ -125,6 +129,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); @@ -177,29 +182,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); @@ -222,6 +212,63 @@ 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); + + 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 - scaleWindow) < 0.01 ) + { + return wxOSXGetDisplayFromID(theIDs[i]); + } + } + + return wxNOT_FOUND; +} + wxDisplayImpl *wxDisplayFactoryMacOSX::CreateDisplay(unsigned n) { CGDisplayCount theCount = GetCount(); @@ -251,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 @@ -265,9 +306,9 @@ int wxDisplayImplMacOSX::GetDepth() const return wxGetDisplayDepth(m_id); } -wxSize wxDisplayImplMacOSX::GetSizeMM() const +double wxDisplayImplMacOSX::GetScaleFactor() const { - return wxGetDisplaySizeMM(m_id); + return wxGetScaleFactor(m_id); } static int wxOSXCGDisplayModeGetBitsPerPixel( CGDisplayModeRef theValue ) @@ -385,11 +426,6 @@ public: { return wxGetDisplayDepth(CGMainDisplayID()); } - - virtual wxSize GetSizeMM() const wxOVERRIDE - { - return wxGetDisplaySizeMM(CGMainDisplayID()); - } }; class wxDisplayFactorySingleMacOSX : public wxDisplayFactorySingle diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 4e5db615b2..46fa8188a1 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -2630,15 +2630,16 @@ wxSize wxWindowMac::OSXMakeDPIFromScaleFactor(double scaleFactor) wxSize wxWindowMac::GetDPI() const { - double scaleFactor; - if ( wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ) - scaleFactor = tlw->GetContentScaleFactor(); - else - scaleFactor = wxOSXGetMainScreenContentScaleFactor(); - - return OSXMakeDPIFromScaleFactor(scaleFactor); + return OSXMakeDPIFromScaleFactor(GetDPIScaleFactor()); } +// on mac ContentScale and DPIScale are identical +double wxWindowMac::GetDPIScaleFactor() const +{ + return GetContentScaleFactor(); +} + + // // wxWidgetImpl // 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;