From cb1fcfed6a918eba985530a262916b1b6a17f9b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20B=C3=BCrk?= Date: Fri, 23 Sep 2016 15:09:49 +0200 Subject: [PATCH 1/2] Use Xft.dpi for DPI if available. fixes #2465 --- i3-config-wizard/i3-config-wizard.mk | 4 +- i3-input/i3-input.mk | 4 +- i3-nagbar/i3-nagbar.mk | 4 +- i3bar/i3bar.mk | 4 +- include/libi3.h | 7 ++++ libi3/dpi.c | 57 +++++++++++++++++++++++++++- libi3/libi3.mk | 2 +- src/main.c | 7 ++-- 8 files changed, 75 insertions(+), 14 deletions(-) diff --git a/i3-config-wizard/i3-config-wizard.mk b/i3-config-wizard/i3-config-wizard.mk index 2a761433..9c01cdb6 100644 --- a/i3-config-wizard/i3-config-wizard.mk +++ b/i3-config-wizard/i3-config-wizard.mk @@ -4,8 +4,8 @@ CLEAN_TARGETS += clean-i3-config-wizard i3_config_wizard_SOURCES := $(wildcard i3-config-wizard/*.c) i3_config_wizard_HEADERS := $(wildcard i3-config-wizard/*.h) -i3_config_wizard_CFLAGS = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(PANGO_CFLAGS) $(XKB_COMMON_CFLAGS) $(XKB_COMMON_X11_CFLAGS) -i3_config_wizard_LIBS = $(XCB_LIBS) $(XCB_KBD_LIBS) $(PANGO_LIBS) $(XKB_COMMON_LIBS) $(XKB_COMMON_X11_LIBS) +i3_config_wizard_CFLAGS = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(PANGO_CFLAGS) $(XCB_XRM_CFLAGS) $(XKB_COMMON_CFLAGS) $(XKB_COMMON_X11_CFLAGS) +i3_config_wizard_LIBS = $(XCB_LIBS) $(XCB_KBD_LIBS) $(PANGO_LIBS) $(XCB_XRM_LIBS) $(XKB_COMMON_LIBS) $(XKB_COMMON_X11_LIBS) i3_config_wizard_OBJECTS := $(i3_config_wizard_SOURCES:.c=.o) diff --git a/i3-input/i3-input.mk b/i3-input/i3-input.mk index 2b1f451e..ce36f932 100644 --- a/i3-input/i3-input.mk +++ b/i3-input/i3-input.mk @@ -4,8 +4,8 @@ CLEAN_TARGETS += clean-i3-input i3_input_SOURCES := $(wildcard i3-input/*.c) i3_input_HEADERS := $(wildcard i3-input/*.h) -i3_input_CFLAGS = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(PANGO_CFLAGS) -i3_input_LIBS = $(XCB_LIBS) $(XCB_KBD_LIBS) $(PANGO_LIBS) +i3_input_CFLAGS = $(XCB_CFLAGS) $(XCB_KBD_CFLAGS) $(PANGO_CFLAGS) $(XCB_XRM_CFLAGS) +i3_input_LIBS = $(XCB_LIBS) $(XCB_KBD_LIBS) $(PANGO_LIBS) $(XCB_XRM_LIBS) i3_input_OBJECTS := $(i3_input_SOURCES:.c=.o) diff --git a/i3-nagbar/i3-nagbar.mk b/i3-nagbar/i3-nagbar.mk index 564a7bc2..c6c7a2ef 100644 --- a/i3-nagbar/i3-nagbar.mk +++ b/i3-nagbar/i3-nagbar.mk @@ -4,8 +4,8 @@ CLEAN_TARGETS += clean-i3-nagbar i3_nagbar_SOURCES := $(wildcard i3-nagbar/*.c) i3_nagbar_HEADERS := $(wildcard i3-nagbar/*.h) -i3_nagbar_CFLAGS = $(XCB_CFLAGS) $(XCB_CURSOR_CFLAGS) $(XCB_WM_CFLAGS) $(PANGO_CFLAGS) -i3_nagbar_LIBS = $(XCB_LIBS) $(XCB_CURSOR_LIBS) $(XCB_WM_LIBS) $(PANGO_LIBS) +i3_nagbar_CFLAGS = $(XCB_CFLAGS) $(XCB_CURSOR_CFLAGS) $(XCB_WM_CFLAGS) $(PANGO_CFLAGS) $(XCB_XRM_CFLAGS) +i3_nagbar_LIBS = $(XCB_LIBS) $(XCB_CURSOR_LIBS) $(XCB_WM_LIBS) $(PANGO_LIBS) $(XCB_XRM_LIBS) i3_nagbar_OBJECTS := $(i3_nagbar_SOURCES:.c=.o) diff --git a/i3bar/i3bar.mk b/i3bar/i3bar.mk index 114e9314..03c607dd 100644 --- a/i3bar/i3bar.mk +++ b/i3bar/i3bar.mk @@ -4,8 +4,8 @@ CLEAN_TARGETS += clean-i3bar i3bar_SOURCES := $(wildcard i3bar/src/*.c) i3bar_HEADERS := $(wildcard i3bar/include/*.h) -i3bar_CFLAGS = $(XCB_CFLAGS) $(XCB_CURSOR_CFLAGS) $(PANGO_CFLAGS) $(YAJL_CFLAGS) $(LIBEV_CFLAGS) -i3bar_LIBS = $(XCB_LIBS) $(XCB_CURSOR_LIBS) $(PANGO_LIBS) $(YAJL_LIBS) $(LIBEV_LIBS) $(XCB_XKB_LIBS) +i3bar_CFLAGS = $(XCB_CFLAGS) $(XCB_CURSOR_CFLAGS) $(PANGO_CFLAGS) $(XCB_XRM_CFLAGS) $(YAJL_CFLAGS) $(LIBEV_CFLAGS) +i3bar_LIBS = $(XCB_LIBS) $(XCB_CURSOR_LIBS) $(PANGO_LIBS) $(XCB_XRM_LIBS) $(YAJL_LIBS) $(LIBEV_LIBS) $(XCB_XKB_LIBS) i3bar_OBJECTS := $(i3bar_SOURCES:.c=.o) diff --git a/include/libi3.h b/include/libi3.h index da5ad891..c1fe770b 100644 --- a/include/libi3.h +++ b/include/libi3.h @@ -470,6 +470,13 @@ char *get_process_filename(const char *prefix); */ char *get_exe_path(const char *argv0); +/** + * Initialize the DPI setting. + * This will use the 'Xft.dpi' X resource if available and fall back to + * guessing the correct value otherwise. + */ +void init_dpi(void); + /** * Convert a logical amount of pixels (e.g. 2 pixels on a “standard” 96 DPI * screen) to a corresponding amount of physical pixels on a standard or retina diff --git a/libi3/dpi.c b/libi3/dpi.c index 897e6e40..f105ef9a 100644 --- a/libi3/dpi.c +++ b/libi3/dpi.c @@ -7,6 +7,61 @@ */ #include "libi3.h" #include +#include +#include + +static long dpi; + +static long init_dpi_fallback(void) { + return (double)root_screen->height_in_pixels * 25.4 / (double)root_screen->height_in_millimeters; +} + +/* + * Initialize the DPI setting. + * This will use the 'Xft.dpi' X resource if available and fall back to + * guessing the correct value otherwise. + */ +void init_dpi(void) { + xcb_xrm_database_t *database = NULL; + + if (conn == NULL) { + goto init_dpi_end; + } + + database = xcb_xrm_database_from_default(conn); + if (database == NULL) { + ELOG("Failed to open the resource database.\n"); + goto init_dpi_end; + } + + char *resource; + xcb_xrm_resource_get_string(database, "Xft.dpi", NULL, &resource); + if (resource == NULL) { + DLOG("Resource Xft.dpi not specified, skipping.\n"); + goto init_dpi_end; + } + + char *endptr; + dpi = strtol(resource, &endptr, 10); + if (dpi == LONG_MAX || dpi == LONG_MIN || dpi < 0 || *endptr != '\0' || endptr == resource) { + ELOG("Xft.dpi = %s is an invalid number and couldn't be parsed.\n", resource); + dpi = 0; + goto init_dpi_end; + } + + DLOG("Found Xft.dpi = %ld.\n", dpi); + +init_dpi_end: + if (database != NULL) { + xcb_xrm_database_free(database); + } + + if (dpi == 0) { + DLOG("Using fallback for calculating DPI.\n"); + dpi = init_dpi_fallback(); + DLOG("Using dpi = %ld\n", dpi); + } +} /* * Convert a logical amount of pixels (e.g. 2 pixels on a “standard” 96 DPI @@ -21,8 +76,6 @@ int logical_px(const int logical) { return logical; } - const int dpi = (double)root_screen->height_in_pixels * 25.4 / - (double)root_screen->height_in_millimeters; /* There are many misconfigurations out there, i.e. systems with screens * whose dpi is in fact higher than 96 dpi, but not significantly higher, * so software was never adapted. We could tell people to reconfigure their diff --git a/libi3/libi3.mk b/libi3/libi3.mk index d313a44e..16e1f149 100644 --- a/libi3/libi3.mk +++ b/libi3/libi3.mk @@ -2,7 +2,7 @@ CLEAN_TARGETS += clean-libi3 libi3_SOURCES := $(wildcard libi3/*.c) libi3_HEADERS := $(wildcard libi3/*.h) -libi3_CFLAGS = $(PANGO_CFLAGS) +libi3_CFLAGS = $(PANGO_CFLAGS) $(XCB_XRM_CFLAGS) libi3_LIBS = libi3_OBJECTS := $(libi3_SOURCES:.c=.o) diff --git a/src/main.c b/src/main.c index 5362d077..96eab671 100644 --- a/src/main.c +++ b/src/main.c @@ -503,10 +503,11 @@ int main(int argc, char *argv[]) { visual_type = get_visualtype(root_screen); } + init_dpi(); + DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_type->visual_id); - DLOG("root_screen->height_in_pixels = %d, root_screen->height_in_millimeters = %d, dpi = %d\n", - root_screen->height_in_pixels, root_screen->height_in_millimeters, - (int)((double)root_screen->height_in_pixels * 25.4 / (double)root_screen->height_in_millimeters)); + DLOG("root_screen->height_in_pixels = %d, root_screen->height_in_millimeters = %d\n", + root_screen->height_in_pixels, root_screen->height_in_millimeters); DLOG("One logical pixel corresponds to %d physical pixels on this display.\n", logical_px(1)); xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(conn, root); From 889d0abe8f397da9a39db9566e34cdfbb37d01fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20B=C3=BCrk?= Date: Sat, 24 Sep 2016 23:48:33 +0200 Subject: [PATCH 2/2] Set $HOME for tests. We add $HOME to the environment variables we define for a test case in order to redirect it from the user's actual home directory. This is necessary because xcb-util-xrm will fall back to $HOME/.Xresources when determining the DPI. If a user has this set to, e.g., 192 on their machine, this would break tests. Since tests shouldn't rely on the system they run in, we redirect the home directory altogether to simulate a clean slate. relates to #2465 --- testcases/lib/TestWorker.pm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testcases/lib/TestWorker.pm b/testcases/lib/TestWorker.pm index 140537d4..6371591f 100644 --- a/testcases/lib/TestWorker.pm +++ b/testcases/lib/TestWorker.pm @@ -112,8 +112,9 @@ sub worker_wait { $test->failure_output(\*STDERR); $test->todo_output(\*STDOUT); - @ENV{qw(DISPLAY TESTNAME OUTDIR VALGRIND STRACE XTRACE COVERAGE RESTART)} - = ($self->{display}, + @ENV{qw(HOME DISPLAY TESTNAME OUTDIR VALGRIND STRACE XTRACE COVERAGE RESTART)} + = ($outdir, + $self->{display}, basename($file), $outdir, $options->{valgrind},