Fix DPI scaling on X11 and Windows #922
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is another attempt to fix the DPI scaling issues seen in #868.
Before, Windows 11 without scaling (100%)
Before, Windows 11 with 175% scaling
After, Windows 11 with 175% scaling
Font Scaling
MainWindow::GetFontPrefwas attempting to apply DPI scaling to the font sizes it returns, which was causing double scaling of everything but the default font since ImGui now handles font scaling on its own inImGui::PushFont. The double scaling was inconsistent because we sometimes passed the size fromGetFontPreftoImDrawList::AddText, which does not perform font scaling, so text drawn that way was only scaled once. That's what was causing the weird headers in the filter graph: the height of the header was scaled twice but the header text was rendered throughImDrawListand so only scaled once.This fixes the double scaling issue by removing all of the application code which attempts to handle font scaling, leaving that responsibility to ImGui. I also removed everything that attempts to pass fonts explicitly to ImGui calls; now we always use the current font set by
ImGui::PushFontwhen drawing or measuring text. Calls toImDrawList::AddTexteither use the overload that uses the current font or, when that's not possible because we need to pass a wrap width, pass the font usingImGui::GetFont()andImGui::GetFontSize()to achieve the same result.Window / Panel Scaling
The Stream Browser panel was too narrow because it's 20% of the width of the main window, and the main window was proportionally too small when DPI scaling was active. Setting the
GLFW_SCALE_TO_MONITORhint fixes that by making GLFW scale the requested size of the main window to the DPI of the monitor it will appear on. That assumes the OS / window manager honors the requested size, but that problem already existed and is independent of DPI scaling.Similarly, the Filter Palette panel was too narrow because it was 20% of the width of the Filter Graph workspace. However, the splitting of the workspace appears to happen before it's docked to the main window and takes on its final size, so the size used for the split is always 800px and is not scaled based on DPI. I fixed the size of the panel by setting the split ratio to the ratio of the intended width to the current size of the parent panel. That's a little hacky, but the DockBuilder API doesn't provide a way to perform a split based on actual size, just by ratio.
ImGuiStyle Sizes
As documented in their FAQ, ImGui does not currently scale the size values in
ImGuiStyle(padding and so forth) automatically based on the DPI. Further, the existing style API is not conducive to maintaining a master style with nominal sizes and repeatedly scaling it as the DPI changes. Until ImGui implements a solution for style scaling upstream, this works around the issue by resetting the style to defaults and then scaling it based on the DPI at the top of each frame, and also every time the target viewport (and thus potentially the DPI) changes. As a side effect, the style editor in the ImGui debug tools no longer works (it still opens and displays the style, but changes are reset every frame).NodeEditor Scaling
It appears that imgui-node-editor is applying DPI scaling to its entire canvas somehow, though I haven't found the code that does that yet. Since ImGui is also applying DPI scaling to the fonts, and we scale everything we draw off the font size, everything being drawn to the canvas was being double scaled. I fixed that by turning off font DPI scaling while we're drawing to the NodeEditor canvas.