-
Notifications
You must be signed in to change notification settings - Fork 164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Brightness slider not working when Windows 11 HDR is on #411
Comments
Thanks for reporting. |
@emoacht The original comment is extremely detailed and accurate on how HDR brightness works in windows. When HDR is enabled, monitor brightness should not be available by design. It would be great if Monitorian handled this case by having the brightness slider reflect what exists in the Windows HDR settings menu for SDR brightness (or at least have a different slider for SDR brightness when HDR is enabled). I saw someone on stackoverflow already ask about how to do this programmatically: https://stackoverflow.com/questions/74594751/controlling-sdr-content-brightness-programmatically-in-windows-11 And twinkle tray already has a pinned issue about this exact thing as well where they have made some progress: |
@fireph It primarily depends on whether the necessary information is made publicly available and techinicall feasible.
Could you give me a link to official documentation on this? |
The only available API related to SDR brightness which I could find is Windows.Graphics.Display.AdvancedColorInfo.SdrWhiteLevelInNits property which provides the current SDR luminance of a monitor where the window locates. However, it requires |
@emoacht That is not true anymore, winrt can be used in non packaged/non uwp apps just fine. You can also use DisplayConfigGetDeviceInfo to get DISPLAYCONFIG_SDR_WHITE_LEVEL. Brightness for SDR content can be set programmatically (see my answer on SO) |
@lulle2007200 Thanks for the information.
Could you elaborate how to call DisplayInformation.GetForCurrentView in an app other than UWP? Also, could you elaborate how to get DISPLAYCONFIG_SDR_WHITE_LEVEL? It seems a little complicated. Regarding SO's answer, it is interesting. But that method is undocumented and unnamed. Could you elaborate how did you find the method and its signature? |
Display settings are implemented in a DLL, separate from the settings app. I ran the settings app under debugger to find the event handler in the display settings DLL that gets called when the SDR brightness slider changes value, from there, i stepped through that event handler until i found the call to dwmapi.dll. The function name comes from debug symbols, the signature i found by reverse engineering.
This is not very useful as it only allows you to get the current white level, but not set it, but here is how you'd do it (error handling and cleanup omitted):
Basically exactly the same way as you would do it in an UWP app, e.g.
The catch with this is that it is tied to a specific window. E.g. the thread you call it from has to be associated to a window. |
@lulle2007200 Thank you for the information again. I tried to call the function of dwmapi.dll by name but failed. Then I checked dwmapi.dll with Dumpin and found that the method is unnamed. So the only way to call it is by its index number 171. Regarding DISPLAYCONFIG_SDR_WHITE_LEVEL with DisplayConfigGetDeviceInfo, I confirmed that the white level matches SdrWhiteLevelInNits obtained on UWP. Regarding DisplayInformation.GetForCurrentView on other platform, if I call it on WPF, it causes COMException and I have no idea to avoid it. Thus it is unusable.
|
Yeah, currently Maybe i put that badly. Generally you can use all of winrt in "normal" non UWP apps, however The exception rises, because the thread doesnt have an associated |
@lulle2007200 This app has been using some of WinRT APIs from early version. Some APIs that requires |
@emoacht There is a way to do that in non UWP apps/apps that don't use CoreApplicationView, but only if you are targeting Windows 11 build 22621 or later, otherwise you'd have to use the classic Win32 APIs. You can obtain a #include "winrt/base.h"
#include "winrt/Windows.Graphics.Display.h"
#include <windows.graphics.display.interop.h>
#include <iostream>
using namespace winrt;
using namespace Windows::Graphics::Display;
HMONITOR getCurrentMonitor() {
return MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY);
}
int main()
{
auto display_info_factory = get_activation_factory<DisplayInformation, IDisplayInformationStaticsInterop>();
HMONITOR h_monitor = getCurrentMonitor();
DisplayInformation display_info = nullptr;
display_info_factory->GetForMonitor(h_monitor, guid_of<DisplayInformation>(), put_abi(display_info));
AdvancedColorInfo advanced_color_info = display_info.GetAdvancedColorInfo();
std::cout << "max. nits: " << advanced_color_info.MaxLuminanceInNits() << std::endl;
} |
Thanks. I will wait for Microsoft to release C# equivalent. |
I'm not too familiar with c#, but this should work pretty much the same in c#. As for the |
I figured out the way to obtain DisplayInformation on WPF and incorporated the function to capture advanced color information in Ver 4.4.8. It can be enabled with The next challenge is the maximum value. As far as I tested it with Dell U2720QM and S2721QS, the |
When using DwmpSDRToHDRBoost, you can set the SDR white level from 80 nits up to whatever you want. However, if you set it higher than what your monitor actually can display, you get clipping. |
What I have observed is different. The following is the values of each monitor when HDR is on for that monitor.
Both monitors are connected to Surface Pro and Surface Pro's internal monitor is the primary. I confirmed each of them is associated with correct .icm file (Its file name includes each model name). This may depend on the devices. I thought the actual brightness of a monitor could saturate at its |
If the monitor is actually a bit brighter than what is reported, that makes sense. I guess its simple to test. Just look at some black to white gradient while increasing SDR brightness (in settings or using DwmpSdrToHdrBoost when you want to go beyond 480 nits). Once you loose contrast on the white side of the gradient, you reached maximum supported brightness. As for why the max. in settings is 480, maybe because minimum (vesa) HDR standard is HDR 400 which requires min. brightness of 400 nits? |
Yes, I am sure.
That is the question. I wish Microsoft could provide more information. |
I have PG49WCD and noticed the same issues with HDR mode set to on as others. Does the experimental changes from above should work in the 4.6.1.0 version? I tried to set brightness from cli with the |
@Draghmar Thank you for your interest. |
Hm...I've updated to the 4.6.3.0. I'm using MS Store for that. How can I launch app with the switch present?
still doesn't do anything. I'm getting this in response:
Launching app only with:
|
|
Hello. I really like Monitorian app, I've got an HDR monitor, and I've noticed that the slider actually changes brightness (Samsung lu28r550) I really want to have SDR content slider, but I don't have experience in XAML, here's what I've found: |
That SO question is alreadly discussed in this issue. |
I've checked 6 is max SDR brightness (around 480 nits), that stackoverflow code worked for me well. |
Does it match the OS's SDR settings? |
Interestingly, it changes monitor brightness well, but not OS's SDR settings, slider is stuck at previous value. |
It used to in some previous windows version. Now it is cached in multiple places and registry. There is also DISPLAYCONFIG_DEVICE_INFO_SET_SDR_WHITE_LEVEL that can be used with DisplayConfigSetDeviceInfo, that seems to do exactly what the OS setting does, but it's also undocumented and therefore subject to change. |
Yeah, that's the issue. |
@emoacht I did some more REing and found how to set it properly, see xanderfrangos/twinkle-tray#97 (comment) API's are still undocumented, but this sets the brightness properly. |
@lulle2007200 So have you found the new member of DISPLAYCONFIG_DEVICE_INFO_TYPE enumeration? The following is derived from wingdi.h of Windows SDK 10.0.26100.1.
|
The Monitorian slider for brightness does not change the brightness of my HDR-enabled monitors − tested on a Iiyama G-Master GB3467WQSU (400 cd/m² DisplayHDR through DisplayPort 1.4) and on an Atomos Ninja V+ (1000 cd/m² HDR through HDMI 2.0b).
(DisplayHDR 400 is not 10-bit HDR, but Windows 11 and Monitorian behave the same anyway.)
From my understanding of color science, I do believe Windows 11 must be using HLG, which enables SDR content (like the Windows UI itself) to be displayed with a relative base brightness; said base brightness can be changed in the Windows settings for displays, in the Use HDR section.
Currently, the brightness slider for Monitorian does not change brightness when the Use HDR option is On.
At the very least, I believe the brightness slider for Monitorian should change brightness the exact same way the SDR content brightess slider of Windows 11 does.
Optimally, Monitorian should be handling both regular brightness and SDR content brightness with different sliders (from my understanding, the latter slider only works when the monitor uses HLG, and should do nothing when the monitor uses PQ).
For screenshots and understanding of these Windows 11 menus, head over to Change HDR or SDR Content Brightness for HDR Display in Windows 11.
I would be happy to pay for a Monitorian subscription if HDR support was a paid option.
The text was updated successfully, but these errors were encountered: