Add support for “Per monitor DPI scaling” on Windows 8.1 and later using a “Use system DPI” preference
ClosedPublic

Authored by Brecht Van Lommel (brecht) on Feb 28 2017, 11:46 PM.

Details

Summary

What?
Blender currently does not support “per monitor DPI scaling”. This is a feature introduced in Windows 8.1 that allows users to assign different logical DPI values to different monitors. This is useful when the user has multiple monitors with different resolutions and/or physical sizes. (for example: mixing HD and 4k screens, or connecting a 27” monitor to a 15” laptop). Per monitor DPI scaling allows users to choose the most comfortable rendering size on a per monitor basis.

What is the problem?
By default, for legacy reasons, applications are marked as “not per-monitor-dpi compatible”. This makes it so that win32 reports the same DPI value for all monitors. Applications that are moved to a different screen get rendered at the same resolution and then get upscaled/downscaled (depends on which monitor is the main monitor) by Windows. This results in a visibly blurry low-quality image.

Blender without the patch:

4K monitor as main, Blender on 4K screen4K monitor as main, Blender on HD screenHD monitor as main, Blender on 4K screenHD monitor as main, Blender on HD screen

How to fix this?
By calling SetProcessDpiAwareness an application can mark itself a per-monitor-DPI aware. This makes it so that its windows receive a dpi-change message when they are moved to a different monitor. The application can then redraw its window contents at the new, correct DPI. This results in a clear, sharp image.

What does this patch do?
This patch modifies the GHOST library to mark Blender as “per-monitor-dpi aware” for Windows. A function “getDPIHint” is added to the GHOST window classes that returns the DPI setting recommended by the operating system. Furthermore, a new event “GHOST_kEventWindowDPIHintChanged” is introduced to signal a change in the system recommended DPI (for example: a window is moved to a different monitor).
An implementation for getDPIHint is also provided for X11 and SDL, which makes Blender responsive to system DPI scaling on those platforms. For X11, the Xft.dpi setting is used if present, otherwise the DPI is identical to the one set using “xrandr --dpi”. On SDL “SDL_GetDisplayDPI” is used.

The patch adds two user preferences: use_system_dpi and dpi_multiplier.
The first specifies whether or not the user wants to use the dpi returned by getDPIHint.
The second specifies a scaling factor that is used on getDPIHint before using it.

Blender with the patch:

4K monitor as main, Blender on 4K screen4K monitor as main, Blender on HD screenHD monitor as main, Blender on 4K screenHD monitor as main, Blender on HD screen

Extra info:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd464646(v=vs.85).aspx
https://wiki.archlinux.org/index.php/HiDPI
https://wiki.libsdl.org/SDL_GetDisplayDPI

Diff Detail

Repository
rB Blender
Wouter (Waterflames) retitled this revision from to Add support for “Per monitor DPI scaling” on Windows 8.1 and later using a “Use system DPI” preference.Feb 28 2017, 11:46 PM
Wouter (Waterflames) updated this object.

While I have no technical objections, (however since it touches the linux backends as well I would like @Sergey Sharybin (sergey) to have a look at this) the ui part of this patch is a little wonky, when you click 'use system dpi' the dpi changes from 72 to 96, but when you uncheck it, it doesn't undo the damage it has done, and things stay at 96, so this checkbox works more like a 'get system dpi' button than a checkbox. The UI team might have some guidance here, @Julian Eisel (Severin) ?

I agree with @LazyDodo (LazyDodo) the dpi should return the previous setting when toggling use system dpi on and off.

release/scripts/startup/bl_ui/space_userpref.py
406

I think it would make more sense to use .enabled for the dpi keeping for the multiplier is still ok though.

  • The .enabled property is now used instead of .active for the DPI slider.
  • The user-defined DPI setting is now restored when the user unchecks "Use system DPI"

It's great to see this issue being addressed, it's been a weakness for a long time. Especially great that it's for both Windows and Linux.

Testing this patch on macOS, enabling Use System DPI changes the DPI from 72 to 96. This makes the buttons too big compared to other applications in the operating system. Does this also change the default size of buttons on other operating systems? If the Blender UI interpretation of the DPI is a bit different than that of the operating system we might want to add an internal multiplier to adjust for that.

We could go even further to simplify DPI settings for users, if the UI team agrees. Buttons should just have an appropriate size by default, and all the user may want to change is if they should be a bit bigger or smaller.

So I think that all we need is a DPI multiplier setting on system DPI, and the Use System DPI, DPI and Virtual Pixel Mode settings could be removed. Pixel size to draw lines with double thickness could be automatically derived from the DPI. We could preserve backwards compatibility by setting the DPI multiplier to the previously configured DPI divided by the automatic DPI.

Testing this patch on macOS, enabling Use System DPI changes the DPI from 72 to 96. This makes the buttons too big compared to other applications in the operating system. Does this also change the default size of buttons on other operating systems?

Yup, but i kinda expected it since i was increasing the dpi?

Yup, but i kinda expected it since i was increasing the dpi?

Blender should show buttons at a good default size, regardless if you're using Use System DPI or not. The fact that Blender assumes DPI 72 as the default may be a mistake, I'm not sure. But we should fix it or compensate for it then. Simplest would be multiplying by 72.0/96.0 in wm_window_get_dpi, more invasive would be changing the assumptions in the UI code.

But as I mentioned above, I think all we really need is an Interface Size % in the user preferences, users do not need to be aware of absolute DPI values.

Testing this patch on macOS, enabling Use System DPI changes the DPI from 72 to 96. This makes the buttons too big compared to other applications in the operating system.

Ah yes, this may be incorrect behaviour. Both Windows and X11 have 96 as the default dpi value, but it seems macOS used 72 by default. (unless a retina device is used)
This is easily fixable by either changing the default implementation of getDPIHint to return 96, or by having a Cocoa specific override return 72 (possible multiplied by m_window-> backingScaleFactor if you want to account for HiDPI).

However, I do not own a macOS device and I cannot get blender to work in a macOS virtual machine.

Blender should show buttons at a good default size, regardless if you're using Use System DPI or not. The fact that Blender assumes DPI 72 as the default may be a mistake, I'm not sure. But we should fix it or compensate for it then. Simplest would be multiplying by 72.0/96.0 in wm_window_get_dpi, more invasive would be changing the assumptions in the UI code.

Seems to me the cleanest way to compensate would be change the default dpi_multiplier value to 0.75 instead of 1.0

However, I do not own a macOS device and I cannot get blender to work in a macOS virtual machine.

I can do any code changes or testing on macOS. However I'm not sure if it helps to change the default DPI on macOS? As I understand it the appropriate button size in pixel units is basically the same on platforms. So if we get a different default DPI for macOS, we'd have to undo that elsewhere.

Seems to me the cleanest way to compensate would be change the default dpi_multiplier value to 0.75 instead of 1.0

That seems like showing an implementation detail to the user, and we also like user preferences to be transferable between different operating systems.

If we never show DPI values to the user, we can smooth over any OS differences internally.

I added a snippet of code to s_wndProc in GHOST_SystemWin32.cpp that calls EnableNonClientDpiScaling.
Calling SetProcessDpiAwareness disables Windows built-in scaling of the window contents so we can render natively at the correct dpi, but Windows assumes that we also handle the caption bar.
Apparently you need to call EnableNonClientDpiScaling to make sure the non-client parts (such as the title bar) are correctly scaled.
Info: https://msdn.microsoft.com/en-us/library/windows/desktop/mt748621(v=vs.85).aspx

This fixes the huge title bar that can be seen in the screenshots I posted for this patch. Take a look at the two "4K monitor as main, Blender on HD screen" screenshots and compare the title bar.

Testing on Ubuntu Linux with Unity desktop, it seems to be working correctly.

Here's a patch on top of this diff to simplify the UI to a single Interface Size setting relative to the system DPI. It also keeps the UI size the same for existing user preferences.

It would be good to hear from the UI team if they agree with this simplification.

1diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
2index 3302bdb..2c9fe25 100644
3--- a/release/scripts/startup/bl_ui/space_userpref.py
4+++ b/release/scripts/startup/bl_ui/space_userpref.py
5@@ -400,18 +400,7 @@ class USERPREF_PT_system(Panel):
6
7​ col = colsplit.column()
8​ col.label(text="General:")
9- col.prop(system, "use_system_dpi")
10-
11- sub = col.column()
12- sub.enabled = not system.use_system_dpi
13- sub.prop(system, "dpi")
14-
15- sub = col.column()
16- sub.active = system.use_system_dpi
17- sub.prop(system, "dpi_multiplier")
18-
19- col.label("Virtual Pixel Mode:")
20- col.prop(system, "virtual_pixel_mode", text="")
21+ col.prop(system, "interface_size")
22
23​ col.separator()
24
25diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
26index 99d9e14..4f6eb70 100644
27--- a/source/blender/blenloader/intern/versioning_defaults.c
28+++ b/source/blender/blenloader/intern/versioning_defaults.c
29@@ -68,6 +68,10 @@ void BLO_update_defaults_userpref_blend(void)
30​ * but take care since some hardware has driver bugs here (T46962).
31​ * Further hardware workarounds should be made in gpu_extensions.c */
32​ U.glalphaclip = (1.0f / 255);
33+
34+ /* default so DPI is detected automatically */
35+ U.dpi = 0;
36+ U.interface_size = 100;
37​ }
38
39​ /**
40diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
41index 31068fc..3e7c3b6 100644
42--- a/source/blender/makesdna/DNA_userdef_types.h
43+++ b/source/blender/makesdna/DNA_userdef_types.h
44@@ -467,9 +467,11 @@ typedef struct UserDef {
45​ int audioformat;
46​ int audiochannels;
47
48- int scrollback; /* console scrollback limit */
49- int dpi; /* range 48-128? */
50- char node_margin; /* node insert offset (aka auto-offset) margin, but might be useful for later stuff as well */
51+ int scrollback; /* console scrollback limit */
52+ int dpi; /* range 48-128? */
53+ int interface_size; /* interface size % */
54+ int pad1;
55+ char node_margin; /* node insert offset (aka auto-offset) margin, but might be useful for later stuff as well */
56​ char pad2;
57​ short transopts;
58​ short menuthreshold1, menuthreshold2;
59@@ -570,11 +572,7 @@ typedef struct UserDef {
60​ struct WalkNavigation walk_navigation;
61
62​ short opensubdiv_compute_type;
63-
64- char pad5;
65-
66- char use_system_dpi; /* let GHOST choose dpi */
67- float dpi_multiplier;
68+ char pad5[6];
69​ } UserDef;
70
71​ extern UserDef U; /* from blenkernel blender.c */
72diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
73index ee9098d..b01d776 100644
74--- a/source/blender/makesrna/intern/rna_userdef.c
75+++ b/source/blender/makesrna/intern/rna_userdef.c
76@@ -137,48 +137,8 @@ static void rna_userdef_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe
77​ WM_main_add_notifier(NC_WINDOW, NULL);
78​ }
79
80-static void rna_userdef_dpi_set(PointerRNA *ptr, int value)
81-{
82- UserDef *userdef = (UserDef *)ptr->data;
83-
84- userdef->user_selected_dpi = value;
85- if(!userdef->use_system_dpi)
86- {
87- userdef->dpi = value;
88- }
89-}
90-
91​ /* also used by buffer swap switching */
92-static void rna_userdef_dpi_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
93-{
94- /* font's are stored at each DPI level, without this we can easy load 100's of fonts */
95- BLF_cache_clear();
96-
97- BKE_blender_userdef_refresh();
98- WM_main_add_notifier(NC_WINDOW, NULL); /* full redraw */
99- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); /* refresh region sizes */
100-}
101-
102-static void rna_userdef_use_system_dpi_set(PointerRNA *ptr, int value)
103-{
104- UserDef *userdef = (UserDef *)ptr->data;
105-
106- if(value && !userdef->use_system_dpi) //System DPI was not being used, but will now be.
107- {
108- //Make sure user selected DPI is stored
109- userdef->user_selected_dpi = userdef->dpi;
110- }
111-
112- userdef->use_system_dpi = value;
113-
114- if (!userdef->use_system_dpi) //Use System DPI disabled?
115- {
116- //Restore user selected DPI.
117- userdef->dpi = userdef->user_selected_dpi;
118- }
119-}
120-
121-static void rna_userdef_virtual_pixel_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
122+static void rna_userdef_dpi_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
123​ {
124​ /* font's are stored at each DPI level, without this we can easy load 100's of fonts */
125​ BLF_cache_clear();
126@@ -3946,12 +3906,6 @@ static void rna_def_userdef_system(BlenderRNA *brna)
127​ {0, NULL, 0, NULL, NULL}
128​ };
129
130- static EnumPropertyItem virtual_pixel_mode_items[] = {
131- {VIRTUAL_PIXEL_NATIVE, "NATIVE", 0, "Native", "Use native pixel size of the display"},
132- {VIRTUAL_PIXEL_DOUBLE, "DOUBLE", 0, "Double", "Use double the native pixel size of the display"},
133- {0, NULL, 0, NULL, NULL}
134- };
135-
136​ srna = RNA_def_struct(brna, "UserPreferencesSystem", NULL);
137​ RNA_def_struct_sdna(srna, "UserDef");
138​ RNA_def_struct_nested(brna, srna, "UserPreferences");
139@@ -3965,31 +3919,16 @@ static void rna_def_userdef_system(BlenderRNA *brna)
140​ RNA_def_property_ui_text(prop, "International Fonts", "Use international fonts");
141​ RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_language_update");
142
143- prop = RNA_def_property(srna, "dpi", PROP_INT, PROP_NONE);
144- RNA_def_property_int_sdna(prop, NULL, "dpi");
145- RNA_def_property_range(prop, 48, 144);
146- RNA_def_property_ui_text(prop, "DPI", "Font size and resolution for display");
147- RNA_def_property_int_funcs(prop, NULL, "rna_userdef_dpi_set", NULL);
148- RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
149-
150- prop = RNA_def_property(srna, "use_system_dpi", PROP_BOOLEAN, PROP_NONE);
151- RNA_def_property_boolean_sdna(prop, NULL, "use_system_dpi", 1);
152- RNA_def_property_ui_text(prop, "Use system DPI", "Use the DPI settings recommended by the OS");
153- RNA_def_property_boolean_funcs(prop, NULL, "rna_userdef_use_system_dpi_set");
154- RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
155-
156- prop = RNA_def_property(srna, "dpi_multiplier", PROP_FLOAT, PROP_NONE);
157- RNA_def_property_float_sdna(prop, NULL, "dpi_multiplier");
158- RNA_def_property_ui_text(prop, "DPI scaling factor", "The factor by which the current DPI setting is multiplied.");
159- RNA_def_property_ui_range(prop, 0.5f, 2.0f, 0.1f, 2);
160- RNA_def_property_float_default(prop, 1.0f);
161+ prop = RNA_def_property(srna, "interface_size", PROP_INT, PROP_PERCENTAGE);
162+ RNA_def_property_ui_text(prop, "Interface Size", "Changes the size of the fonts and buttons in the interface");
163+ RNA_def_property_range(prop, 25, 400);
164+ RNA_def_property_ui_range(prop, 75, 125, 10, 1);
165+ RNA_def_property_int_default(prop, 100);
166​ RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
167
168- prop = RNA_def_property(srna, "virtual_pixel_mode", PROP_ENUM, PROP_NONE);
169- RNA_def_property_enum_sdna(prop, NULL, "virtual_pixel");
170- RNA_def_property_enum_items(prop, virtual_pixel_mode_items);
171- RNA_def_property_ui_text(prop, "Virtual Pixel Mode", "Modify the pixel size for hi-res devices");
172- RNA_def_property_update(prop, 0, "rna_userdef_virtual_pixel_update");
173+ prop = RNA_def_property(srna, "dpi", PROP_INT, PROP_NONE);
174+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
175+ RNA_def_property_ui_text(prop, "DPI", "Font size and resolution for display");
176
177​ prop = RNA_def_property(srna, "pixel_size", PROP_FLOAT, PROP_NONE);
178​ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
179diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
180index 99943f6..1e23d00 100644
181--- a/source/blender/windowmanager/intern/wm_window.c
182+++ b/source/blender/windowmanager/intern/wm_window.c
183@@ -375,31 +375,42 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win)
184​ }
185​ }
186
187-static float wm_window_get_virtual_pixelsize(void)
188+static int wm_window_get_auto_dpi(wmWindow *win)
189​ {
190- return ((U.virtual_pixel == VIRTUAL_PIXEL_NATIVE) ? 1.0f : 2.0f);
191-}
192+ int auto_dpi = GHOST_GetDPIHint(win->ghostwin);
193
194-static int wm_window_get_dpi(wmWindow *win)
195-{
196- if(U.dpi_multiplier == 0.0f)
197- {
198- U.dpi_multiplier = 1.0f;
199+ /* Lazily init interface size, preserving backwards compatibility by
200+ * computing interface size % from ratio of previous DPI and auto DPI */
201+ if (U.interface_size == 0) {
202+ if (U.dpi == 0) {
203+ U.interface_size = 100;
204+ }
205+ else {
206+ U.interface_size = (100 * U.dpi * 96) / (auto_dpi * 72);
207+ }
208​ }
209
210- CLAMP(U.dpi_multiplier, 0.5f, 2.0f);
211+ /* Blender's UI drawing assumes DPI 72 as a good default following macOS
212+ * while Windows and Linux use DPI 96. GHOST assumes a default 96 so we
213+ * remap the DPI to Blender's convention. */
214+ return auto_dpi * U.interface_size * 0.01f * 72.0/96.0f;
215+}
216
217- if(U.use_system_dpi)
218- {
219- return GHOST_GetDPIHint(win->ghostwin) * U.dpi_multiplier;
220- }
221+static int wm_window_get_dpi(wmWindow *win)
222+{
223+ int dpi = wm_window_get_auto_dpi(win);
224+ return dpi / MAX2(1, dpi / 72);
225+}
226
227- return U.dpi;
228+static int wm_window_get_virtual_pixelsize(wmWindow *win)
229+{
230+ int dpi = wm_window_get_auto_dpi(win);
231+ return MAX2(1, dpi / 72);
232​ }
233
234​ float wm_window_pixelsize(wmWindow *win)
235​ {
236- return (GHOST_GetNativePixelSize(win->ghostwin) * wm_window_get_virtual_pixelsize());
237+ return (GHOST_GetNativePixelSize(win->ghostwin) * wm_window_get_virtual_pixelsize(win));
238​ }
239
240​ /* belongs to below */
241@@ -645,7 +656,7 @@ wmWindow *WM_window_open_temp(bContext *C, const rcti *rect_init, int type)
242​ Scene *scene = CTX_data_scene(C);
243​ const char *title;
244​ rcti rect = *rect_init;
245- const short px_virtual = (short)wm_window_get_virtual_pixelsize();
246+ const int px_virtual = wm_window_get_virtual_pixelsize(win_prev);
247
248​ /* changes rect to fit within desktop */
249​ wm_window_check_position(&rect);

source/blender/windowmanager/intern/wm_window.c
1148

Any reason this is commented out?

Testing on Ubuntu Linux with Unity desktop, it seems to be working correctly.

Here's a patch on top of this diff to simplify the UI to a single Interface Size setting relative to the system DPI. It also keeps the UI size the same for existing user preferences.

This works correctly for me on Windows 10.

Wouldn't it make sense to move the 'Interface size' setting to the 'Interface' tab?

source/blender/windowmanager/intern/wm_window.c
1148

No reason. I must have forgotten to uncomment this line after debugging.

About moving to the interface tab, I'm fine with that, not really sure where it fits better since it can be system specific too.

I can commit this in a few days, unless there is more feedback from others here.

This revision is now accepted and ready to land.Mar 12 2017, 5:41 PM

I'd really like the ui team to have a say in this before we commit , @Julian Eisel (Severin) ? docs might also want to be kept in the loop @Aaron Carlisle (Blendify)

Docs are always in the loop ;)

Julian Eisel (Severin) requested changes to this revision.EditedMar 12 2017, 7:19 PM

I'm glad this is being tackled too.
I assume plan is to apply @Brecht Van Lommel (brecht)'s patch on top of this? Better update the diff to avoid confusion if so. Without it I get a far too big UI drawing here because of the UI code assuming 72 DPI.

What I'm unsure about is if we should really remove the virtual pixelsize option:

  • How can devs test if double pixel size works fine now? I often used the option during development, it was really handy.
  • Can we really trust systems to report us the correct DPI? Will we always get the doubled DPI when a user uses a 4K screen (or at least if he has configured the system for it)?

I'm also a bit unsure if 125% for the max interface size is enough? I'd say to match old max-size of 144 DPI we should allow up to 200%?

I also think there should be some version conversion here, some people have changed the DPI so that the UI is a bit more readable, this patch would break that afaics. The 2.79 UI with settings from 2.78 should look the same as 2.78.

Note that there are also quite some code style issues, but I guess @Brecht Van Lommel (brecht) planed to address them before pushing to master ;)

This revision now requires changes to proceed.Mar 12 2017, 7:19 PM

I'll update the diff with my changes. @Wouter (Waterflames), feel free to commandeer it back if you want to make any others.

What I'm unsure about is if we should really remove the virtual pixelsize option:

  • How can devs test if double pixel size works fine now? I often used the option during development, it was really handy.

By typing in 200% for the interface size.

  • Can we really trust systems to report us the correct DPI? Will we always get the doubled DPI when a user uses a 4K screen (or at least if he has configured the system for it)?

There may be cases where it fails, but I expect this will work correct almost always. Applications like Chrome and Firefox rely on the same system settings. Users can still adjust the size if needed.

I'm also a bit unsure if 125% for the max interface size is enough? I'd say to match old max-size of 144 DPI we should allow up to 200%?

It's a soft limit, the hard range is 25% to 400%. It seems enough to me under the assumption that the auto DPI works well.

I also think there should be some version conversion here, some people have changed the DPI so that the UI is a bit more readable, this patch would break that afaics. The 2.79 UI with settings from 2.78 should look the same as 2.78.

My patch handles versioning, keeping the UI size the same.

Note that there are also quite some code style issues, but I guess @Brecht Van Lommel (brecht) planed to address them before pushing to master ;)

My updates fixes the code style issues I found.

Brecht Van Lommel (brecht) updated this object.

Simplify DPI settings, backwards compatibility, style fixes.

Testing on Ubuntu Linux with Unity desktop, it seems to be working correctly.

Here's a patch on top of this diff to simplify the UI to a single Interface Size setting relative to the system DPI. It also keeps the UI size the same for existing user preferences.

It would be good to hear from the UI team if they agree with this simplification.

I've not had a chance to test the patch, but in essence I agree with the approach to hide the DPI setting from the user, presenting instead a single Interface Size option in the Interface tab of the User Preferences, which is consistent across all OSs.

A user never needs to know what DPI value is being used. So long as the UI renders at the same default size across all machines/versions and existing preferences are maintained then my initials are addressed.

This revision was automatically updated to reflect the committed changes.

Committed now, moving the button to the Interface tab, and increasing the default range to 0.5..2.0x, and more tweaks for forward/backward compatibility.

It's all in one commit with @Wouter (Waterflames) set as author, but if anything breaks in terms of compatibility I'm the one to blame.

Hey @Brecht Van Lommel (brecht), something did indeed break, hehe.
For me Blender is segfaulting on startup (linux). Here is an asan log:

=================================================================
==15131==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f4392681d36 bp 0x7ffc21efaa80 sp 0x7ffc21efa1f8 T0)
    #0 0x7f4392681d35 in strlen (/usr/lib/libc.so.6+0x81d35)
    #1 0x7f4397ecbe3b in __interceptor_strlen /build/gcc/src/gcc/libsanitizer/asan/asan_interceptors.cc:577
    #2 0x7f4393633b34  (/usr/lib/libX11.so.6+0x48b34)
    #3 0x7f4393634e8a in XrmGetStringDatabase (/usr/lib/libX11.so.6+0x49e8a)
    #4 0x4ab41bf in GHOST_WindowX11::getDPIHint() /home/luca/Blender/blender/intern/ghost/intern/GHOST_WindowX11.cpp:1686
    #5 0x4a97d3b in GHOST_GetDPIHint /home/luca/Blender/blender/intern/ghost/intern/GHOST_C-api.cpp:920
    #6 0x1f1388d in wm_window_set_dpi /home/luca/Blender/blender/source/blender/windowmanager/intern/wm_window.c:380
    #7 0x1f144a8 in wm_window_ghostwindow_add /home/luca/Blender/blender/source/blender/windowmanager/intern/wm_window.c:486
    #8 0x1f149d6 in wm_window_ghostwindows_ensure /home/luca/Blender/blender/source/blender/windowmanager/intern/wm_window.c:565
    #9 0x1eb1128 in WM_check /home/luca/Blender/blender/source/blender/windowmanager/intern/wm.c:395
    #10 0x1ed8cd4 in wm_homefile_read /home/luca/Blender/blender/source/blender/windowmanager/intern/wm_files.c:834
    #11 0x1ee36ac in WM_init /home/luca/Blender/blender/source/blender/windowmanager/intern/wm_init_exit.c:195
    #12 0x1ea7786 in main /home/luca/Blender/blender/source/creator/creator.c:431
    #13 0x7f4392620510 in __libc_start_main (/usr/lib/libc.so.6+0x20510)
    #14 0x1ea6f49 in _start (/home/luca/Blender/build_linux_debug/bin/blender+0x1ea6f49)

Do you want me to open a report, or is this fine?

@Luca Rood (LucaRood), here is fine, I committed a possible fix now in rB393efccb19e4: Fix GHOST crash on X11 with recent DPI changes on some systems..

Which Linux distribution and window manager did this happen with?

Yes, that fixed it. Thanks @Brecht Van Lommel (brecht) :)
Just for reference, I'm running Arch with OpenBox.