xwayland: Use a fixed DPI value for core protocol
The way Xwayland works (like all Wayland clients), it first queries the Wayland registry, set up all relevant protocols and then initializes its own structures. That means Xwayland will get the Wayland outputs from the Wayland compositor, compute the physical size of the combined outputs and set the corresponding Xwayland screen properties accordingly. Then it creates the X11 screen using fbScreenInit() but does so by using a default DPI value of 96. That value is used to set the physical size of the X11 screen, hence overriding the value computed from the actual physical size provided by the Wayland compositor. As a result, the DPI computed by tools such as xdpyinfo will always be 96 regardless of the actual screen size and resolution. However, if the Wayland outputs get reconfigured, or new outputs added, or existing outputs removed, Xwayland will recompute and update the physical size of the screen, leading to an unexpected change of DPI. To avoid that discrepancy, use a fixed size DPI (defaults to 96, and can be set using the standard command lime option "-dpi") and compute a physical screen size to match that DPI setting. Note that only affects legacy core protocols, X11 clients can still get the actual physical output size as reported by the Wayland compositor using the RandR protocol, which also allows for the size to be 0 if the size is unknown or meaningless. Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Simon Ser <contact@emersion.fr> Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/731
This commit is contained in:
parent
6748a40941
commit
b0413b6e99
|
@ -35,7 +35,6 @@
|
||||||
|
|
||||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
#define DEFAULT_DPI 96
|
|
||||||
#define ALL_ROTATIONS (RR_Rotate_0 | \
|
#define ALL_ROTATIONS (RR_Rotate_0 | \
|
||||||
RR_Rotate_90 | \
|
RR_Rotate_90 | \
|
||||||
RR_Rotate_180 | \
|
RR_Rotate_180 | \
|
||||||
|
@ -148,34 +147,6 @@ output_get_new_size(struct xwl_output *xwl_output,
|
||||||
*height = xwl_output->y + output_height;
|
*height = xwl_output->y + output_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Approximate some kind of mmpd (m.m. per dot) of the screen given the outputs
|
|
||||||
* associated with it.
|
|
||||||
*
|
|
||||||
* It either calculates the mean mmpd of all the outputs or, if no reasonable
|
|
||||||
* value could be calculated, defaults to the mmpd of a screen with a DPI value
|
|
||||||
* of DEFAULT_DPI.
|
|
||||||
*/
|
|
||||||
static double
|
|
||||||
approximate_mmpd(struct xwl_screen *xwl_screen)
|
|
||||||
{
|
|
||||||
struct xwl_output *it;
|
|
||||||
int total_width_mm = 0;
|
|
||||||
int total_width = 0;
|
|
||||||
|
|
||||||
xorg_list_for_each_entry(it, &xwl_screen->output_list, link) {
|
|
||||||
if (it->randr_output->mmWidth == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
total_width_mm += it->randr_output->mmWidth;
|
|
||||||
total_width += it->width;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (total_width_mm != 0)
|
|
||||||
return (double)total_width_mm / total_width;
|
|
||||||
else
|
|
||||||
return 25.4 / DEFAULT_DPI;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xwl_set_pixmap_visit_window(WindowPtr window, void *data)
|
xwl_set_pixmap_visit_window(WindowPtr window, void *data)
|
||||||
{
|
{
|
||||||
|
@ -214,7 +185,6 @@ static void
|
||||||
update_screen_size(struct xwl_output *xwl_output, int width, int height)
|
update_screen_size(struct xwl_output *xwl_output, int width, int height)
|
||||||
{
|
{
|
||||||
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
|
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
|
||||||
double mmpd;
|
|
||||||
|
|
||||||
if (xwl_screen->root_clip_mode == ROOT_CLIP_FULL)
|
if (xwl_screen->root_clip_mode == ROOT_CLIP_FULL)
|
||||||
SetRootClip(xwl_screen->screen, ROOT_CLIP_NONE);
|
SetRootClip(xwl_screen->screen, ROOT_CLIP_NONE);
|
||||||
|
@ -226,15 +196,8 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height)
|
||||||
xwl_screen->height = height;
|
xwl_screen->height = height;
|
||||||
xwl_screen->screen->width = width;
|
xwl_screen->screen->width = width;
|
||||||
xwl_screen->screen->height = height;
|
xwl_screen->screen->height = height;
|
||||||
|
xwl_screen->screen->mmWidth = (width * 25.4) / monitorResolution;
|
||||||
if (xwl_output->width == width && xwl_output->height == height) {
|
xwl_screen->screen->mmHeight = (height * 25.4) / monitorResolution;
|
||||||
xwl_screen->screen->mmWidth = xwl_output->randr_output->mmWidth;
|
|
||||||
xwl_screen->screen->mmHeight = xwl_output->randr_output->mmHeight;
|
|
||||||
} else {
|
|
||||||
mmpd = approximate_mmpd(xwl_screen);
|
|
||||||
xwl_screen->screen->mmWidth = width * mmpd;
|
|
||||||
xwl_screen->screen->mmHeight = height * mmpd;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetRootClip(xwl_screen->screen, xwl_screen->root_clip_mode);
|
SetRootClip(xwl_screen->screen, xwl_screen->root_clip_mode);
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,8 @@
|
||||||
static DevPrivateKeyRec xwl_screen_private_key;
|
static DevPrivateKeyRec xwl_screen_private_key;
|
||||||
static DevPrivateKeyRec xwl_client_private_key;
|
static DevPrivateKeyRec xwl_client_private_key;
|
||||||
|
|
||||||
|
#define DEFAULT_DPI 96
|
||||||
|
|
||||||
_X_NORETURN
|
_X_NORETURN
|
||||||
static void _X_ATTRIBUTE_PRINTF(1, 2)
|
static void _X_ATTRIBUTE_PRINTF(1, 2)
|
||||||
xwl_give_up(const char *f, ...)
|
xwl_give_up(const char *f, ...)
|
||||||
|
@ -594,6 +596,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
||||||
xorg_list_init(&xwl_screen->window_list);
|
xorg_list_init(&xwl_screen->window_list);
|
||||||
xwl_screen->depth = 24;
|
xwl_screen->depth = 24;
|
||||||
|
|
||||||
|
if (!monitorResolution)
|
||||||
|
monitorResolution = DEFAULT_DPI;
|
||||||
|
|
||||||
xwl_screen->display = wl_display_connect(NULL);
|
xwl_screen->display = wl_display_connect(NULL);
|
||||||
if (xwl_screen->display == NULL) {
|
if (xwl_screen->display == NULL) {
|
||||||
ErrorF("could not connect to wayland server\n");
|
ErrorF("could not connect to wayland server\n");
|
||||||
|
@ -624,7 +629,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
||||||
|
|
||||||
ret = fbScreenInit(pScreen, NULL,
|
ret = fbScreenInit(pScreen, NULL,
|
||||||
xwl_screen->width, xwl_screen->height,
|
xwl_screen->width, xwl_screen->height,
|
||||||
96, 96, 0,
|
monitorResolution, monitorResolution, 0,
|
||||||
BitsPerPixel(xwl_screen->depth));
|
BitsPerPixel(xwl_screen->depth));
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user