Commit b032e7aa authored by Glen Whitney's avatar Glen Whitney Committed by Romain Bouvier

Respect physical display sizes in xfce4-settings insofar as practical

  Prior to this change, on startup, xfsettingsd would always set the nominal
  physical dimensions of the (typically sole) virtual screen to correspond to
  265-micron pixel pitch (96 dpi). However, as physical displays with much
  smaller pixel pitches become common, this doesn't make much sense when all
  of the physical devices attached have significantly smaller pitches (even
  if they don't all match) and especially problematic when there is a single
  output (a relatively common case) with a very different pixel pitch.
  In this case, the physical dimensions are very meaningful, and altering
  them can lead to such symptoms as poorly chosen font sizes and widely varying
  font sizes among different applications.

  This commit always respects any physical dimensions reported by xrandr in
  the case of a single output and makes a best effort to patch together a
  ballpark reasonable physical dimension in the case of multiple outputs. (In
  any case, the computed effective physical dimensions will always reflect
  a pixel pitch that is between the smallest and largest pixel pitches
  reported by xrandr for any outputs.)

  Resolves (XFCE gitlab) issue #34 (formerly XFCE bugzilla issue 10633 and
  its various duplicates).
parent 77fa482c
Pipeline #774 passed with stages
in 3 minutes and 11 seconds
......@@ -181,6 +181,8 @@ struct _XfceRRCrtc
gint y;
gfloat scalex;
gfloat scaley;
gint eff_mm_width;
gint eff_mm_height;
gint noutput;
RROutput *outputs;
gint npossible;
......@@ -1053,8 +1055,10 @@ G_GNUC_END_IGNORE_DEPRECATIONS
/* Translate output->name into xfconf compatible format in place */
g_strcanon(output->info->name, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_<>", '_');
xfsettings_dbg (XFSD_DEBUG_DISPLAYS, "Detected output %lu %s.", output->id,
output->info->name);
xfsettings_dbg (XFSD_DEBUG_DISPLAYS,
"Detected output %lu %s, mm_w %ld mm_h %ld.",
output->id, output->info->name,
output->info->mm_width, output->info->mm_height);
/* cache it */
g_ptr_array_add (outputs, output);
......@@ -1121,6 +1125,8 @@ xfce_displays_helper_list_crtcs (XfceDisplaysHelper *helper)
crtc->y = crtc_info->y;
crtc->scalex = 1.0;
crtc->scaley = 1.0;
crtc->eff_mm_width = 0;
crtc->eff_mm_height = 0;
crtc->noutput = crtc_info->noutput;
crtc->outputs = NULL;
......@@ -1247,6 +1253,7 @@ static void
xfce_displays_helper_normalize_crtc (XfceRRCrtc *crtc,
XfceDisplaysHelper *helper)
{
gint sw, sh, x1, y1;
g_assert (XFCE_IS_DISPLAYS_HELPER (helper) && crtc);
/* ignore disabled outputs for size computations */
......@@ -1261,21 +1268,41 @@ xfce_displays_helper_normalize_crtc (XfceRRCrtc *crtc,
crtc->changed = TRUE;
}
xfsettings_dbg (XFSD_DEBUG_DISPLAYS, "Normalized CRTC %lu: size=%dx%d, pos=%dx%d.",
crtc->id, crtc->width, crtc->height, crtc->x, crtc->y);
/* calculate the total screen size */
helper->width = MAX (helper->width, crtc->x + crtc->width * crtc->scalex);
helper->height = MAX (helper->height, crtc->y + crtc->height * crtc->scaley);
/* The 'physical size' of an X screen is meaningless if that screen
* can consist of many monitors. So just pick a size that make the
* dpi 96.
*
* Firefox and Evince apparently believe what X tells them.
xfsettings_dbg (XFSD_DEBUG_DISPLAYS, "Normalized CRTC %lu: size=%dx%d, pos=%dx%d, phys=%dx%d.",
crtc->id, crtc->width, crtc->height, crtc->x, crtc->y,
crtc->eff_mm_width, crtc->eff_mm_height);
/* Calculate the total screen size, and extend physical size based on this crtc.
* We use the rough approximation that the pixels from the previous max up to the
* the new max based on this crtc are the same pitch as on this crtc, defaulting to
* 96 dpi if we can't tell the pitch on this crtc. We just want something reasonably
* in the ballpark since the physical screen dimensions are not very meaningful in
* the case of multiple monitors, but we do want to get them right if there is
* just one monitor.
*/
helper->mm_width = (helper->width / 96.0) * 25.4 + 0.5;
helper->mm_height = (helper->height / 96.0) * 25.4 + 0.5;
sw = crtc->width * crtc->scalex;
sh = crtc->height * crtc->scaley;
x1 = crtc->x + sw;
y1 = crtc->y + sh;
if (x1 > helper->width)
{
gint e_mm_width = crtc->eff_mm_width;
if (e_mm_width == 0)
e_mm_width = (sw * 25.4) / 96.0 + 0.5;
helper->mm_width += (x1 - helper->width) * e_mm_width / sw;
helper->width = x1;
}
if (y1 > helper->height)
{
gint e_mm_height = crtc->eff_mm_height;
if (e_mm_height == 0)
e_mm_height = (sh * 25.4) / 96.0 + 0.5;
helper->mm_height += (y1 - helper->height) * e_mm_height / sh;
helper->height = y1;
}
xfsettings_dbg (XFSD_DEBUG_DISPLAYS, " and screen so far: pix geom=%dx%d, mm geom=%dx%d.",
helper->width, helper->height, helper->mm_width, helper->mm_height);
}
......@@ -1398,7 +1425,7 @@ static void
xfce_displays_helper_set_outputs (XfceRRCrtc *crtc,
XfceRROutput *output)
{
gint n;
gint n, o_mm_width, o_mm_height;
g_assert (crtc && output);
......@@ -1406,6 +1433,21 @@ xfce_displays_helper_set_outputs (XfceRRCrtc *crtc,
xfsettings_dbg (XFSD_DEBUG_DISPLAYS, "CRTC %lu, output list[%d] -> %lu.", crtc->id, n,
crtc->outputs[n]);
/* update the physical dimensions of the crtc if need be */
o_mm_width = 0;
o_mm_height = 0;
if (output->info)
{
if (output->info->mm_width > 0)
o_mm_width = output->info->mm_width;
if (output->info->mm_height > 0)
o_mm_height = output->info->mm_height;
}
if (crtc->eff_mm_width == 0 || (o_mm_width > 0 && o_mm_width < crtc->eff_mm_width))
crtc->eff_mm_width = o_mm_width;
if (crtc->eff_mm_height == 0 || (o_mm_height > 0 && o_mm_height < crtc->eff_mm_height))
crtc->eff_mm_height = o_mm_height;
/* check if the output is already present */
for (n = 0; n < crtc->noutput; ++n)
{
......@@ -1413,7 +1455,6 @@ xfce_displays_helper_set_outputs (XfceRRCrtc *crtc,
return;
}
if (crtc->outputs)
crtc->outputs = g_realloc (crtc->outputs, (crtc->noutput + 1) * sizeof (RROutput));
else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment