Table of Contents
- First Things First
- Implications of Smaller Pixels
- HiDPI and Scaling
- DPI awareness and Smarter Scaling
- Windows HiDPI and Scaling
- Overriding using the registry
- A System-wide Default?
- About the Other 5% of Cases
- Going Deeper
- TL;DR Solution
If you’re a Windows user and keep your display scaling at anything other than 100%, you’re probably familiar with this blur problem:
Expectation:
Reality:
It usually happens if you have a laptop, because their screens are small and dense and everything looks too small at 100%, so you scale up to, say 125%, which looks great, except that now you open some apps and they look all blurry, sometimes to a point where the app becomes unusable. This article will help you learn more about what this is and why it happens. If you’re here just to get a quick solution, jump to the TL;DR.
First Things First
Your screen is made up of pixels (bet you didn’t know that). Screens and pixels come in all sorts of shapes and sizes, but for simplicity, we’ll consider rectangular screens made up of square pixels. Each pixel has a size, say 0.1mm x 0.1mm. This means there are 100 pixels along a 1cm line. However, another screen can have a pixel size of 0.05mm x 0.05mm, half the side length of the previous pixels. Meaning there are 200 such pixels along the same 1cm line. The same idea holds for a 2D grid instead of a 1D line. Clearly, two screens of the same size don’t necessarily have the same number of pixels. If a screen has smaller pixels, then more of them can be fit in the same region, increasing its pixel density. The density can be measured in pixels per centimeter, or the more widespread unit, Pixels per Inch (PPI). This is the PPI you see in a smartphone spec sheet. Higher the density (PPI), more the number of pixels that can fit in a region, hence smaller the pixels, and harder to see with the naked eye.
A screen is just a grid of pixels. The dimensions of that grid, measured in pixels, are called the resolution of that screen, usually written as <width>x<height>. For example, a 1920x1080 screen has 1920 pixels along its width and 1080 pixels along its height. You can have a TV, a laptop, and a smartphone, all with 1920x1080 screens, but from what we saw above, if the resolution is the same, smaller screens must be denser and with smaller pixels, as compared to the larger screens.
Implications of Smaller Pixels
Pixel size and density matter because while developing a software’s GUI, the developer has to specify the size of its controls, i.e. the buttons, labels, checkboxes, etc. This size can be given in absolute physical units, like cm, mm, in, etc., pretty self-explanatory, or in relative units, like px, dp, sp in Android; em, vh, vw, etc. in CSS, etc. Relative units are relative to something about the screen. The important thing to note here is that a button of width 1vw (in CSS) may be 5mm wide on one screen, but 3mm wide on another. The physical size of something defined using a relative unit is not fixed, and changes with screen and pixel size and density.
You can probably see the problem by now. If a button is defined relative units, say a width of 50 pixels, its actual physical length on a screen depends on that screen itself. A bigger, less dense screen like a TV will show a big button, but a smaller, denser screen like a smartphone will show a much smaller button, because of smaller pixels. This is exactly the reason why everything seems smaller on a 1920x1080 laptop screen, as compared to a slightly bigger desktop monitor of the same resolution. It makes sense if you think about it. Everything on the bigger screen needs to fit as-is on the smaller screen, so it has to be shrunk, making everything smaller.
HiDPI and Scaling
Such dense screens with tiny pixels are called HiDPI or High DPI screens. DPI stands for Dots per Inch, which was used for printers. Just like a screen’s granularity is measured in pixels per inch, a printer’s granularity is measured in dots per inch, or at least it used to be, which is why the term DPI was used and it stuck. To make things simpler, you can replace HiDPI with HiPPI instead without losing any information, as it makes more sense.
If you take a screenshot on your laptop and view it on your smartphone, you’re viewing a 1920x1080 photo (the screenshot) on a 1920x1080 screen (the smartphone), but the screen is much, much smaller so you’re unable to see anything clearly. What do you do? Zoom in. Scaling is just another word for it (zoom in = scale up, zoom out = scale down). For exactly the same reason, you can’t see the text in the app clearly on your laptop, because the screen has smaller pixels and the text size was specified in pixels by the developer (this isn’t entirely true, but it makes things simpler). So you zoom everything in. You go to Windows display settings and set the scale to 125%. This basically does what you did on your phone. Windows takes a screenshot of the app window and zooms it in by 25%.
DPI awareness and Smarter Scaling
You know how you zoom low-resolution photos and they soon start to become blurry, and eventually pixelated? Because Windows does something similar, as mentioned above, you get the same problem, which is why the apps look blurry. This, however, can be fixed. Consider this: you have some text with a font size of 100, and you take its photo and zoom it in by 25%. The text is bigger, but looks blurry. Instead, if you just change its font size by 25%, setting it to 125, the text is now bigger, but not blurry.
To some, it might seem similar to raster vs vector image scaling, and it is. Vector images don’t become blurry because they’re not stretched blindly, but almost as if told to grow bigger.
Because it is almost as if the text was told to become bigger, it could handle the scaling on its own terms, maintaining clarity. What if you told the whole application window to grow bigger, instead of blindly stretching it? A 100-size text would become a 125-size text, a 50-pixel button would become a 63-pixel button, etc., all while maintaining clarity. Unsurprisingly, this “smart scaling” solves the whole problem, if, the application knows how to grow bigger.
Similar to how a vector image like a .svg knows how to grow bigger so it does, maintaining clarity, unlike a raster image like a .png, which doesn’t.
Applications like these that know how to grow bigger, and can grow when told to, are called DPI-aware. It can become complicated to handle DPI awareness manually as a developer. As screens got denser and HiDPI became more prevalent, DPI awareness became more and more important, so modern UI frameworks now handle it all by themselves, sometimes to a point where you make an app without knowing DPI awareness is a thing, and it still works fine on HiDPI screens! All because the UI framework gracefully handled all of it for you. This is also the reason that it’s usually the older applications that become blurry, because they were made at a time when DPI awareness wasn’t a problem, so there was no support for it.
Okay, so we know that HiDPI screens cause an inconvenience because of their tiny pixels. The solution is to scale applications up, but it resulted in blurry apps, so we needed a “smarter” scaling solution, with support from the applications themselves, making them DPI-aware. They can now scale properly when told to. Making apps DPI-aware was only half of the solution, implemented by the developer. The other half is to tell those apps to scale, which needs support from Windows, and potentially, you, the user.
Windows HiDPI and Scaling
Because not every app is DPI-aware, it is sensible to assume by default that an app is DPI-unaware and needs to be upscaled using the screenshot and zoom method, also called bitmap scaling. This makes sure that all apps are upscaled alike. But those apps that Windows knows are DPI-aware will be told to scale up instead. How do you tell Windows that an app is DPI-aware? Well, multiple ways.
The developer can add metadata in the application that tells Windows that it’s DPI-aware, which is what many modern apps do, and work fine. But some apps are DPI-aware because of the underlying GUI framework, but fail to advertise it. In cases like these, the user can come in and tell Windows instead. If you right-click on a .exe file in Windows and go to Properties, you’ll see a Compatibility tab. This tab is all about making sure that apps that used to run fine earlier, run fine now, in the modern world with modern hardware and software. It contains a button labeled “Change high DPI settings” near the bottom. Clicking on it brings up the High DPI and scaling settings for that app.
If you don’t see the compatibility tab, jump to Going Deeper to see a possible reason, and how to solve the issue in that case. Until then, you can just follow this article using another app.
You’re free to read what the new popup says. It is all about HiDPI and scaling. What’s interesting to us is the lower section titled “High DPI scaling override”. The options in this section override the default DPI awareness assumption and scaling mechanism. If you click the checkbox to override the default, you have three options to override it with:
- Application - Assume that the application is DPI-aware skip bitmap scaling.
- System - Assume that the application is DPI-unaware and apply bitmap scaling if needed.
- System (Enhanced) - Same as above, but use a better form of scaling (called GDI scaling).
There is a distinction between the last two because even though the third one seems to be the most sensible default, it’s only available on later versions of Windows.
Remember how we saw that by default Windows assumes that any app is DPI-unaware and performs bitmap scaling unless told otherwise by the application itself? Here you can override that. System is the default scaling mechanism. If you set it to System (Enhanced), Windows will perform GDI scaling (better than the previous one), possibly increasing the clarity. If set to Application, Windows will skip the scaling altogether, and just notify the app that it should scale itself now.
If the app that was giving you the blur problem is DPI-aware, overriding the DPI scaling to the option Application will fix it. Try it! It will solve your problem for 95% of the apps.
Overriding using the registry
When you override the High DPI settings, Windows stores it in the registry at \Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
in HKCU
for the current user or in HKLM
for all users. “AppCompatFlags” clearly indicates it’s used to store compatibility options. Each entry in this key has a file path as the value/data, which indicates the app for which to change compatibility options, and the options themselves as data. A good reference for options that can be specified is at SS64 here.
The High DPI override options correspond to data according to the following mapping:
- Application -
~ HIGHDPIAWARE
- System -
~ DPIUNAWARE
- System (Enhanced) -
~ GDIDPISCALING DPIUNAWARE
So every time you set the High DPI override to Application, Windows adds an entry here, with the app path as the value and ~ HIGHDPIAWARE
as the data. You can do it manually too, if you don’t have access to the GUI or just don’t want to use it. Windows comes with a built-in registry editor (Start > type regedit.exe > Open Registry Editor) if you need it.
A System-wide Default?
it can be tedious to do this for every single app if there are many blurry apps that you regularly use, plus any new app that you install. Is there a system-wide default to change Windows’ default to Application or ~ HIGHDPIAWARE
? Unfortunately, at the time of writing this, there isn’t (I would be very happy if someone corrects me here). However, if it changes in the future, and I remember to update this article, I will.
About the Other 5% of Cases
A while ago I mentioned that changing the High DPI settings for an app will solve 95% of your cases. The rest 5% are however a bit problematic, and honestly, annoying. A prime example of this is the Microsoft Management Console (MMC) and its snap-ins, like Services, Task Scheduler, etc. The compatibility tab for system tabs is hidden, so you have to use the registry. For other apps like the MMC, that doesn’t work either, so you have to use more hacks, using the registry and overriding the app manifest by creating one and putting it beside the .exe file as explained here. Another case you might come across is when the Open File dialog is blurry, which can be fixed by overriding the settings for the app that prompted the dialog to open.
A bad case would be when the application is DPI-unaware. Remember that overriding these settings can only tell Windows to assume that the app is DPI-aware and skip the scaling. But if the app isn’t DPI-aware, there’s nothing you can do, and have to let Windows handle the scaling. Your best option is to either leave it to default or use GDI scaling by overriding the option to System (Enhanced) or ~ GDIDPISCALING DPIUNAWARE
, whichever works better. There is one particular case I’ve come across personally that I don’t know how to solve yet, and that is when there is occasionally a Windows toast notification (that desktop notification you get) that is blurry. I don’t know what causes it or how it can be solved. Fortunately, it’s very rare, so it can be ignored altogether.
Going Deeper
This article was intentionally made simple to provide a foundation for the topic and the blur problem. Hopefully, it managed to do that for you. Naturally, in making it simple, information had to be dropped. If you’re interested in going deeper and learning more about this topic, there are a few good places to start. There is a Windows Developer blog that goes in-depth about the GDI scaling that I smoothly glossed over in this article. It also mentions another way of changing the settings using Windows policies. The SS64 page mentioned earlier is good for the registry options available. If you’re comfortable with it, editing and overriding app manifests can be a viable solution too. The ServerFault question mentioned earlier contains the answers mentioned in this article, with some helpful scripts for the more developer oriented. There is a Microsoft Support article on the topic too. Happy Reading!
TL;DR Solution
If you read the whole article, thank you! You can close it now. This section is for those who jumped here for a quick solution. Here’s a rundown of solutions that can help you, in order:
-
Right-click on the blurry app’s .exe file and go to Compatibility > Change high DPI settings > High DPI scaling override. Check the checkbox and choose Application from the dropdown menu. Click OK and then OK again.
-
If there’s no Compatibility tab: Click Start, type regedit.exe, and press Enter. In the Registry Editor, go to
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
and add a new name/data pair (Right click > New > String value) with the name being the blurry app’s .exe’s complete file path, and the data being~ HIGHDPIAWARE
. -
If it isn’t solved yet, try the previous step again, but set the data to
~ GDIDPISCALING DPIUNAWARE
instead. This may improve the clarity if you’re using a later version of Windows. This and the step above may be helpful in cases involving system apps such as MMC, Services, etc. -
If it still isn’t solved or improved, you’re out of luck. You might try a more advanced solution using the Windows policy editor as mentioned here, but that’s it. Hope it helped!