diff --git a/CHANGELOG.md b/CHANGELOG.md index 25b287ee76..9333b1d7da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - On Windows, fix `CursorMoved(0, 0)` getting dispatched on window focus. - On macOS, fix command key event left and right reverse. - On FreeBSD, NetBSD, and OpenBSD, fix build of X11 backend. +- On X11, change DPI scaling factor behavior. First, winit tries to read it from "Xft.dpi" XResource, and uses DPI calculation from xrandr dimensions as fallback behavior. # Version 0.19.0 (2019-03-06) diff --git a/src/platform/linux/x11/util/randr.rs b/src/platform/linux/x11/util/randr.rs index e730469ba3..5054dbdb01 100644 --- a/src/platform/linux/x11/util/randr.rs +++ b/src/platform/linux/x11/util/randr.rs @@ -79,6 +79,24 @@ impl From<*mut ffi::XRRCrtcInfo> for MonitorRepr { } impl XConnection { + // Retrieve DPI from Xft.dpi property + pub unsafe fn get_xft_dpi(&self) -> Option { + (self.xlib.XrmInitialize)(); + let resource_manager_str = (self.xlib.XResourceManagerString)(self.display); + if resource_manager_str == ptr::null_mut() { + return None; + } + if let Ok(res) = ::std::ffi::CStr::from_ptr(resource_manager_str).to_str() { + let name : &str = "Xft.dpi:\t"; + for pair in res.split("\n") { + if pair.starts_with(&name) { + let res = &pair[name.len()..]; + return f64::from_str(&res).ok(); + } + } + } + None + } pub unsafe fn get_output_info( &self, resources: *mut ffi::XRRScreenResources, @@ -101,10 +119,15 @@ impl XConnection { (*output_info).nameLen as usize, ); let name = String::from_utf8_lossy(name_slice).into(); - let hidpi_factor = calc_dpi_factor( - repr.get_dimensions(), - ((*output_info).mm_width as u64, (*output_info).mm_height as u64), - ); + let hidpi_factor = if let Some(dpi) = self.get_xft_dpi() { + dpi / 96. + } else { + calc_dpi_factor( + repr.get_dimensions(), + ((*output_info).mm_width as u64, (*output_info).mm_height as u64), + ) + }; + (self.xrandr.XRRFreeOutputInfo)(output_info); Some((name, hidpi_factor)) } diff --git a/src/window.rs b/src/window.rs index cf36044880..1bc0dbf618 100644 --- a/src/window.rs +++ b/src/window.rs @@ -485,7 +485,7 @@ impl MonitorId { /// /// ## Platform-specific /// - /// - **X11:** Can be overridden using the `WINIT_HIDPI_FACTOR` environment variable. + /// - **X11:** This respects Xft.dpi XResource, and can be overridden using the `WINIT_HIDPI_FACTOR` environment variable. /// - **Android:** Always returns 1.0. #[inline] pub fn get_hidpi_factor(&self) -> f64 {