xanderfrangos / twinkle-tray

Easily manage the brightness of your monitors in Windows from the system tray
https://twinkletray.com
MIT License
5.24k stars 169 forks source link

Hotkeys for contrast too? #547

Open 205g0 opened 1 year ago

205g0 commented 1 year ago

Pretty much the title and this would be awesome!

205g0 commented 1 year ago

I've forgot to add the reason: You need different contrast settings for dark mode and light mode. Light mode && high contrast burns your eye, so I decrease contrast and keep brightness. Dark mode && low contrast is hard too read, so I increase contrast.

If you give us hotkeys (or a CLI) I could even script with Autohotkey the change of contrast on change of dark and light mode (I do latter already with a hotkey).

DRSAgile commented 1 year ago

I have a similar request, though in regard to command line.

But since the author of the utility is not available, the only solution seems to be to use AutoHotKey or AutoIt to emulate mouse click on the GUI elements -- first on the tray icon, then on the gauge that represents contrast (can be turned on in the utility's settings).

The issue is that this would, even though shortly, take focus away from whatever you are doing, and make things "blink" in the bottom right corner of your screen.

Both can be prohibitive, so this solution is really a solution.

205g0 commented 1 year ago

But since the author of the utility is not available,

Temporarily or permanently?

DRSAgile commented 1 year ago

Not sure, but basing on the activity, maybe he will come back within months.

205g0 commented 1 year ago

There's actually a full-blown Windows API which has everything we'd need to write some CLI at https://learn.microsoft.com/en-us/windows/win32/api/_monitor/

But I can't code in C++. On the other side, it'd be just about calling some functions...

DRSAgile commented 1 year ago

Thanks.

There is an AutoHotKey wrapper for this, but I did not try it.

It probably uses some Com objects/DLL calls to do it, so it it works, then it can replace the utility with your AHK script using the wrapper.

DRSAgile commented 1 year ago

It works -- I just created this AKH script:

#include Class_Monitor.ahk

for k, v in Monitor.GetContrast()   ; GetBrightness "\\.\DISPLAY2" or just "2"
    MsgBox % k ": " v

Monitor.SetContrast(20)
xanderfrangos commented 1 year ago

But since the author of the utility is not available,

Temporarily or permanently?

I'm always monitoring the opened issues and comments, but Twinkle Tray isn't something I always have time for.

Contrast control via hotkeys is something I plan to add eventually, but I'm not actively working on it at the moment. The hotkey system in general needs to be reworked, and supporting more features (like contrast) would be part of that.

xanderfrangos commented 1 year ago

There's actually a full-blown Windows API which has everything we'd need to write some CLI at https://learn.microsoft.com/en-us/windows/win32/api/_monitor/

But I can't code in C++. On the other side, it'd be just about calling some functions...

This is actually the same Windows API that Twinkle Tray uses, via node-ddcci. You can take a look at the project for reference if you want to throw together your own Node-based tool.

xanderfrangos commented 1 year ago

I have a similar request, though in regard to command line.

But since the author of the utility is not available, the only solution seems to be to use AutoHotKey or AutoIt to emulate mouse click on the GUI elements -- first on the tray icon, then on the gauge that represents contrast (can be turned on in the utility's settings).

The issue is that this would, even though shortly, take focus away from whatever you are doing, and make things "blink" in the bottom right corner of your screen.

Both can be prohibitive, so this solution is really a solution.

There is actually command line support in Twinkle Tray already, so this isn't necessary. Check my reply in your issue for more details. You can use that with an app like AHK or Logitech's app for their keyboards to map that to hotkeys. The command line option for contrast doesn't support offsets, so the hotkeys would only support preset values.

I hope that helps!

205g0 commented 1 year ago

Great thread btw!

@DRSAgile this Class_Monitor.ahk you've found is awesome, actually we don't need anything more (I mean, we wouldn't have the nice update indicator/modal frrom Twinkle Tray). However, I couldn't get it to work. I've #inluded the file which worked. but thi for loop is just being ignored, it didn't matter what monitor id I've entered. I've also tried to instantiate some class instance with monitor := ClassObj.call(Monitor) before and use that then but that didn't work either. So that short 6-liner you posted really works??

@xanderfrangos, thanks for chiming in and also for creating this beautiful piece of software. It feels so solid and round like none of my other Win apps, maybe VS Code is as polished haha. No seriously, it would be awesome if you had the time to implement the contrast thing, even if it's just on CLI level to spare you some UI work.

DRSAgile commented 1 year ago

@205g0 What do you mean by "thi for loop"?

You do not need to instantiate anything. A simpler example that works for me is this:

#SingleInstance force
#Include %a_scriptdir% 
#include Class_Monitor.ahk ; should be in the same directory as the script
Monitor.SetContrast(100)

This should work even if you have multiple monitors -- just one of them, a main one, should change the contrast.

By the way, TwinkleTray utility will not reflect the change, only your monitor will -- you should experience a new contrast visually and see the "100" figure in the monitor's onscreen menu. This is because the monitor sends a message back to the video card about the change of its state only if it was made via the monitor's own buttons. But in this case, we use a PC software to change the signal, and it is not TwinkleTray utility, so the latter does not know anything about it and will show that you have a previous value for the contrast.

205g0 commented 1 year ago

THANKS, this made my day! 😁 I was missing #Include %a_scriptdir%, now it's working like a dream. Here the script for full brightness, contrast control and reset for two monitors where monitor 1 is leading (change the F keys to whateveer you like). The script could be shortened with a function (sub routine) but not much.

#SingleInstance force
#include %a_scriptdir% 
#include Class_Monitor.ahk ; should be in the same directory as the script

mb := Monitor.GetBrightness(1).current
mc := Monitor.GetContrast(1).current

F9::
  If (mb > 95)
    mb := 100
  Else
    mb += 5
  Monitor.SetBrightness(mb, 1)
  Monitor.SetBrightness(mb, 2)
  Return
F6::
  If (mb < 5)
    mb := 0
  Else
    mb -= 5
  Monitor.SetBrightness(mb, 1)
  Monitor.SetBrightness(mb, 2)
  Return
F7::
  If (mc > 95)
    mc := 100
  Else
    mc += 5
  Monitor.SetContrast(mc, 1)
  Monitor.SetContrast(mc, 2)
  Return
F4::
  If (mc < 5)
    mc := 0
  Else
    mc -= 5
  Monitor.SetContrast(mc, 1)
  Monitor.SetContrast(mc, 2)
  Return
F3::
  mb = 50
  mc = 50
  Monitor.SetBrightness(mb, 1)
  Monitor.SetBrightness(mb, 2)
  Monitor.SetContrast(mc, 1)
  Monitor.SetContrast(mc, 2)
  Return
205g0 commented 1 year ago

Now shorter:

#SingleInstance force
#Include %a_scriptdir% 
#Include Class_Monitor.ahk ; should be in the same directory as the script

mb := Monitor.GetBrightness(1).current
mc := Monitor.GetContrast(1).current

mSB:
  Monitor.SetBrightness(mb, 1)
  Monitor.SetBrightness(mb, 2)
  Return
mSC:
  Monitor.SetContrast(mc, 1)
  Monitor.SetContrast(mc, 2)
  Return
F9::
  IfGreater, mb, 95, EnvSet, mb, 100
  Else mb += 5
  Gosub, mSB
  Return
F6::
  IfLess, mb, 5, EnvSet, mb, 0
  Else mb -= 5
  Gosub, mSB
  Return
F7::
  IfGreater, mc, 95, EnvSet, mc, 100
  Else mc += 5
  Gosub, mSC
  Return
F4::
  IfLess, mc, 5, EnvSet, mc, 0
  Else mc -= 5
  Gosub, mSC
  Return
F3::
  mb = 50
  mc = 50
  Gosub, mSB
  Gosub, mSC
  Return
DRSAgile commented 1 year ago

My goal is to make the monitor to auto adjust depending on light sensor data, but I do not have it yet.

So I have written an AHK script that automatically adjusts the monitor's contrast depending on the length of the day and whether it is clear or cloudy. The script uses curves by choice (circle, parabola, Bell) to increase the contrast, peaking at the zenith.

205g0 commented 1 year ago

Wow, this is really sophisticated. And all written in AHK, hope it wasn't too painful haha.

Re the light sensor: Why not just get a dedicated one? While notebooks have sometimes one, external monitors rarely have one: http://www.yoctopuce.com/EN/products/usb-environmental-sensors/yocto-light-v3

205g0 commented 1 year ago

And I've just seen that you wrote all of this in the past hour?! I'm pretty impressed

DRSAgile commented 1 year ago

Thanks for the link. I was doing extensive search for those, but the results were not returning this Yocto Light V3 product. That said, it does not seem to have drivers that relay the data to a virtual serial port, so it requires libraries to be used in a C/C++ code. Too heavy, in my opinion. If the library is a DLL, then it should be accessible in AHK via something like DllCall, it has to be seen.

In regard to my AHK code: alas, I am not that fast, I wrote it in multiple hours (lots of testing and research for data sources and processing, mathematic formulae, so on), I just uploaded it to GitHub recently.