From 14c074fb6be3fb1231df6b3ba6f88bfac1217fba Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Sat, 18 Nov 2017 23:23:24 -0500 Subject: [PATCH] screen: Disable trying to auto-compute the DPI by default. As long as Awesome provides APIs that uses pixels are points, this cannot be enabled by default. For example, a wibar size defined in pixels may be too small to render the text once a dense display is connected. --- lib/awful/screen.lua | 69 ++++++++++++++++++++++++++++++------ lib/beautiful/xresources.lua | 6 ++++ 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/lib/awful/screen.lua b/lib/awful/screen.lua index e2240405..e08b52a0 100644 --- a/lib/awful/screen.lua +++ b/lib/awful/screen.lua @@ -504,25 +504,78 @@ function screen.object.get_selected_tag(s) return screen.object.get_selected_tags(s)[1] end +--- Enable the automatic calculation of the screen DPI (experimental). +-- +-- This will cause many elements such as the font and some widgets to be scaled +-- so they look the same (physical) size on different devices with different +-- pixel density. +-- +-- It is calculated using the information provided from `xrandr`. +-- +-- When enabled, the theme and configuration must avoid using pixel sizes for +-- different elements as this will cause misalignment or hidden content on some +-- devices. +-- +-- Note that it has to be called early in `rc.lua` and requires restarting +-- awesome to take effect. It is disabled by default and changes introduced in +-- minor releases of Awesome may slightly break the behavior as more components +-- gain support for HiDPI. +-- +-- When disabled the DPI is acquired from the `Xft.dpi` X resource (xrdb), +-- defaulting to 96. +-- +-- @tparam boolean enabled Enable or disable automatic DPI support. +function screen.set_auto_dpi_enabled(enabled) + for s in capi.screen do + s.data.dpi_cache = nil + end + data.autodpi = enabled +end + + --- The number of pixels per inch of the screen. -- @property dpi -- @treturn number the DPI value. local xft_dpi, fallback_dpi +local function get_fallback() + local mm_per_inch = 25.4 + + -- Following Keith Packard's whitepaper on Xft, + -- https://keithp.com/~keithp/talks/xtc2001/paper/xft.html#sec-editing + -- the proper fallback for Xft.dpi is the vertical DPI reported by + -- the X server. This will generally be 96 on Xorg, unless the user + -- has configured it differently + if root and not fallback_dpi then + local _, h = root.size() + local _, hmm = root.size_mm() + fallback_dpi = hmm ~= 0 and h * mm_per_inch / hmm + end + + return fallback_dpi or 96 +end + function screen.object.get_dpi(s) local mm_per_inch = 25.4 - if s.data.dpi then - return s.data.dpi + if s.data.dpi or s.data.dpi_cache then + return s.data.dpi or s.data.dpi_cache end -- Xft.dpi is explicit user configuration, so honor it if not xft_dpi and awesome and awesome.xrdb_get_value then xft_dpi = tonumber(awesome.xrdb_get_value("", "Xft.dpi")) or false end + if xft_dpi then - return xft_dpi + s.data.dpi_cache = xft_dpi + return s.data.dpi_cache + end + + if not data.autodpi then + s.data.dpi_cache = get_fallback() + return s.data.dpi_cache end -- Try to compute DPI based on outputs (use the minimum) @@ -537,16 +590,12 @@ function screen.object.get_dpi(s) end end if dpi then + s.data.dpi_cache = dpi return dpi end - -- We have no outputs, so guess based on the size of the root window. - if root and not fallback_dpi then - local _, h = root.size() - local _, hmm = root.size_mm() - fallback_dpi = hmm ~= 0 and h * mm_per_inch / hmm - end - return fallback_dpi or 96 + s.data.dpi_cache = get_fallback() + return s.data.dpi_cache end function screen.object.set_dpi(s, dpi) diff --git a/lib/beautiful/xresources.lua b/lib/beautiful/xresources.lua index fae96b16..9fb0d141 100644 --- a/lib/beautiful/xresources.lua +++ b/lib/beautiful/xresources.lua @@ -69,8 +69,14 @@ local function get_screen(s) end --- Get global or per-screen DPI value falling back to xrdb. +-- +-- This function is deprecated. Use `s.dpi` and avoid getting the DPI without +-- a screen. +-- +-- @deprecated xresources.get_dpi -- @tparam[opt] integer|screen s The screen. -- @treturn number DPI value. + function xresources.get_dpi(s) s = get_screen(s) if s then