Add opt-in global brightness shortcuts - #2
Draft
LinkaiQi wants to merge 5 commits into
Draft
Conversation
Step every connected Apple display by 1% from any app. Shortcuts are registered with RegisterHotKey against the main window's HWND — the same window that already receives WM_DEVICECHANGE — so they keep working while NitTray sits in the tray. - Defaults to Win+Ctrl+Up / Win+Ctrl+Down, the least contended arrow combination Windows leaves unassigned, and they are configurable. - Off until enabled, persisted to %LOCALAPPDATA%\NitTray\settings.json. - MOD_NOREPEAT is not set so holding a key ramps; DisplayViewModel already coalesces the writes. - A combination another app owns (ERROR_HOTKEY_ALREADY_REGISTERED) is reported inline in the new Settings window instead of failing silently, and live registrations are suspended while recording a new one. - A click-through, never-activated overlay reports the new level, since the window is normally hidden. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
WPF's Keyboard.Modifiers only reports Alt, Ctrl, and Shift — it never sets ModifierKeys.Windows — so the recorder silently downgraded Win+Ctrl+Up to plain Ctrl+Up and registered that instead, without telling the user. Probe Key.LWin/Key.RWin directly. Also require Ctrl, Alt, or Win in a binding: Shift alone would have taken over ordinary text-selection chords system-wide. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
One press is now one 10% step, so ten presses covers the full range. Register the shortcuts with MOD_NOREPEAT to match: a held key auto-repeats about 30 times a second, which at this step size would cross the whole range in roughly a third of a second. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Two windows for a few hundred pixels of content was clutter, and each one carried its own title bar. Settings now hosts a NavigationView rail with Shortcuts in MenuItems and About in FooterMenuItems, which is where Windows 11 Settings puts its own About page. Both tray items and both footer links still work; they just land on different pages of one window. About was centred while the settings body was a left-aligned form, and putting them a click apart exposed the clash, so About is re-laid-out into the same left-aligned cards. NavigationView constructs pages itself, so each page sets its own DataContext and navigation deliberately passes no dataContext — WPF-UI's activator only overwrites DataContext when handed a non-null one. That makes SettingsViewModel a singleton on App, which it wasn't before: it used to be rebuilt on every open, and its constructor was the only thing that ever surfaced a registration collision. CancelCapture also blanked the message unconditionally, so backing out of a recording erased the very warning that prompted it. Reporting the live registration state instead, and refreshing on open, keeps the InfoBar honest. The key recorder stays on the window rather than the page so it fires wherever focus sits, and capture is now cancelled on page change as well as on deactivation and close. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Adds two system-wide keyboard shortcuts that step every connected Apple display's brightness by 10%, without stealing focus from whatever you're doing. Along the way, Settings and About become one window.
Off by default — nothing is taken over until you turn it on in tray → Settings.
Why these defaults
Win+Ctrl+↑/↓is one of the few arrow combinations Windows leaves free. Ruled out along the way:Win+↑/↓(snap),Win+Shift+↑/↓(stretch across monitors),Win+Alt+↑/↓(Win11 22H2 half-snap),Ctrl+Alt+arrows(Intel GPU rotation),Ctrl+Shift+arrows(text selection),Win + Plus/Minus(Magnifier). OnlyWin+Ctrl+←/→is taken, by virtual desktops.Both combinations are user-configurable anyway, and a collision is reported rather than swallowed.
How the shortcuts work
RegisterHotKeybinds to the main window's HWND — the same window that already receivesWM_DEVICECHANGE, so the shortcuts keep working while the window is hidden in the tray.WM_HOTKEYis dispatched through anHwndSourcehook, exactly like the device-change watch.MOD_NOREPEATis set, so one press is one 10% step. Without it a held key auto-repeats ~30×/sec, crossing the whole range in about a third of a second.ERROR_HOTKEY_ALREADY_REGISTERED(1409) becomes an inline warning naming the combination; anything else is logged with its Win32 error.WM_HOTKEYand it would never reach the settings window as a key press.%LOCALAPPDATA%\NitTray\settings.json, beside the diagnostic log. Load/Save never throw.One settings window instead of two
Two separate windows for a few hundred pixels of content — each with its own title bar — was clutter.
SettingsWindownow hosts aNavigationViewrail with Shortcuts inMenuItemsand About inFooterMenuItems, mirroring where Windows 11 Settings puts its own About page.AboutWindowis gone; both tray entries and both footer links still work, they just land on different pages of the same window.About used to be centred while the settings body was a left-aligned form. Putting them one click apart exposed the clash, so About is re-laid-out into the same left-aligned cards.
Notes for reviewers
Two non-obvious framework behaviours drove the design, both verified against source rather than assumed:
Keyboard.Modifiersnever reports the Windows key —KeyboardDevice.csonly computes Alt/Ctrl/Shift. The recorder probesKey.LWin/Key.RWindirectly; without that,Win+Ctrl+Upsilently records asCtrl+Up.NavigationViewconstructs pages itself, so each page sets its ownDataContextand navigation passes nodataContext—NavigationViewActivatoronly overwritesDataContextwhen handed a non-null one.That second point makes
SettingsViewModela singleton onApp, where it used to be rebuilt on every open. Its constructor was the only thing that ever surfaced a registration collision, andCancelCaptureblanked the status message unconditionally — so backing out of a recording erased the very warning that prompted it. It now reports the live registration state and refreshes on open.Known limitation, documented in the UI: Windows doesn't deliver shortcuts to ordinary apps while an elevated window has focus.
Win+Ctrl+↑intact; a deliberate collision shows the warning; the nav window opens on the right page from each entry point; and the overlay lands correctly on a scaled or multi-monitor setup.