diff --git a/include/wx/private/display.h b/include/wx/private/display.h index 1cd7bae8d0..053885d05a 100644 --- a/include/wx/private/display.h +++ b/include/wx/private/display.h @@ -81,8 +81,11 @@ public: // return the depth or 0 if unknown virtual int GetDepth() const = 0; - // return the resolution of the display, uses GetSizeMM() by default but - // can be also overridden directly + // 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 diff --git a/src/common/dpycmn.cpp b/src/common/dpycmn.cpp index d0073ee32c..b72f72c8f6 100644 --- a/src/common/dpycmn.cpp +++ b/src/common/dpycmn.cpp @@ -195,9 +195,7 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode) wxSize wxDisplayImpl::GetPPI() const { - const wxSize pixels = GetGeometry().GetSize(); const wxSize mm = GetSizeMM(); - if ( !mm.x || !mm.y ) { // Physical size is unknown, return a special value indicating that we @@ -205,6 +203,10 @@ wxSize wxDisplayImpl::GetPPI() const return wxSize(0, 0); } + // We need physical pixels here, not logical ones returned by + // GetGeometry(), to compute the real DPI. + const wxSize pixels = GetGeometry().GetSize()*GetScaleFactor(); + return wxSize(wxRound((pixels.x * inches2mm) / mm.x), wxRound((pixels.y * inches2mm) / mm.y)); } diff --git a/src/gtk/display.cpp b/src/gtk/display.cpp index 07e1fc45f3..b5eedeab71 100644 --- a/src/gtk/display.cpp +++ b/src/gtk/display.cpp @@ -46,6 +46,7 @@ public: virtual wxRect GetGeometry() const wxOVERRIDE; virtual wxRect GetClientArea() const wxOVERRIDE; virtual int GetDepth() const wxOVERRIDE; + virtual double GetScaleFactor() const wxOVERRIDE; virtual wxSize GetSizeMM() const wxOVERRIDE; #if wxUSE_DISPLAY @@ -121,6 +122,11 @@ int wxDisplayImplGTK::GetDepth() const return 24; } +double wxDisplayImplGTK::GetScaleFactor() const +{ + return gdk_monitor_get_scale_factor(m_monitor); +} + wxSize wxDisplayImplGTK::GetSizeMM() const { return wxSize @@ -222,6 +228,9 @@ public: virtual wxRect GetGeometry() const wxOVERRIDE; virtual wxRect GetClientArea() const wxOVERRIDE; virtual int GetDepth() const wxOVERRIDE; +#if GTK_CHECK_VERSION(3,10,0) + virtual double GetScaleFactor() const wxOVERRIDE; +#endif // GTK+ 3.10 virtual wxSize GetSizeMM() const wxOVERRIDE; #if wxUSE_DISPLAY @@ -293,6 +302,16 @@ int wxDisplayImplGTK::GetDepth() const return gdk_visual_get_depth(gdk_window_get_visual(wxGetTopLevelGDK())); } +#if GTK_CHECK_VERSION(3,10,0) +double wxDisplayImplGTK::GetScaleFactor() const +{ + if ( gtk_check_version(3,10,0) == NULL ) + return gdk_screen_get_monitor_scale_factor(m_screen, m_index); + + return 1.0; +} +#endif // GTK+ 3.10 + wxSize wxDisplayImplGTK::GetSizeMM() const { // At least in some configurations, gdk_screen_xxx_mm() functions return