[Rebased] [x11-backend] Retrieve DPI from Xft.dpi XResource (#824)

* [x11-backend] Retrieve DPI from Xft.dpi XResource

* Update CHANGELOG.md

* Update window.rs

* Update CHANGELOG.md
This commit is contained in:
mitchmindtree 2019-04-08 02:48:21 +10:00 committed by Victor Berger
parent 20b09c4514
commit 4515b77aa5
3 changed files with 29 additions and 5 deletions

View file

@ -41,6 +41,7 @@
- On Windows, fix `CursorMoved(0, 0)` getting dispatched on window focus. - On Windows, fix `CursorMoved(0, 0)` getting dispatched on window focus.
- On macOS, fix command key event left and right reverse. - On macOS, fix command key event left and right reverse.
- On FreeBSD, NetBSD, and OpenBSD, fix build of X11 backend. - 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) # Version 0.19.0 (2019-03-06)

View file

@ -79,6 +79,24 @@ impl From<*mut ffi::XRRCrtcInfo> for MonitorRepr {
} }
impl XConnection { impl XConnection {
// Retrieve DPI from Xft.dpi property
pub unsafe fn get_xft_dpi(&self) -> Option<f64> {
(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( pub unsafe fn get_output_info(
&self, &self,
resources: *mut ffi::XRRScreenResources, resources: *mut ffi::XRRScreenResources,
@ -101,10 +119,15 @@ impl XConnection {
(*output_info).nameLen as usize, (*output_info).nameLen as usize,
); );
let name = String::from_utf8_lossy(name_slice).into(); let name = String::from_utf8_lossy(name_slice).into();
let hidpi_factor = calc_dpi_factor( let hidpi_factor = if let Some(dpi) = self.get_xft_dpi() {
repr.get_dimensions(), dpi / 96.
((*output_info).mm_width as u64, (*output_info).mm_height as u64), } else {
); calc_dpi_factor(
repr.get_dimensions(),
((*output_info).mm_width as u64, (*output_info).mm_height as u64),
)
};
(self.xrandr.XRRFreeOutputInfo)(output_info); (self.xrandr.XRRFreeOutputInfo)(output_info);
Some((name, hidpi_factor)) Some((name, hidpi_factor))
} }

View file

@ -477,7 +477,7 @@ impl Window {
/// ///
/// ## Platform-specific /// ## Platform-specific
/// ///
/// - **X11:** Can be overridden using the `WINIT_HIDPI_FACTOR` environment variable. /// - **X11:** This respects Xft.dpi, and can be overridden using the `WINIT_HIDPI_FACTOR` environment variable.
/// - **Android:** Always returns 1.0. /// - **Android:** Always returns 1.0.
#[inline] #[inline]
pub fn get_hidpi_factor(&self) -> f64 { pub fn get_hidpi_factor(&self) -> f64 {