Skip to content

feat(widgets): add Monitor Profile widget (WIP) - #1085

Open
tiagomta wants to merge 5 commits into
amnweb:mainfrom
tiagomta:main
Open

feat(widgets): add Monitor Profile widget (WIP)#1085
tiagomta wants to merge 5 commits into
amnweb:mainfrom
tiagomta:main

Conversation

@tiagomta

Copy link
Copy Markdown

Adds a new Monitor Profile widget that saves and switches between monitor layout profiles — monitor arrangements (active monitors, positions, resolution, refresh rate, orientation, primary) — similar to the classic "Monitor Profile Switcher" tool. Layouts are captured through the Windows CCD API (QueryDisplayConfig/SetDisplayConfig) and stored as JSON; applying a profile restores the exact arrangement via SetDisplayConfig.

Features
Profiles
Save current layout... — capture the live display configuration to a named profile (%USERPROFILE%.config\yasb\monitor_profiles<name>.json)
Apply — restore the saved arrangement; the label shows the matching profile name, or Custom when the current layout matches nothing saved
Options menu (⋯) per profile — Apply / Set Hotkey / Remove Hotkey / Delete
Two independently styleable card blocks in the popup (profiles + monitors) via .menu-block.profiles-block / .menu-block.monitors-block
Monitor control
Per-monitor disable (turn off without unplugging) and re-enable, via the same ⋯ menu
Disabled-but-connected monitors are detected via QDC_ALL_PATHS + targetAvailable
Section auto-hides when there's only one monitor and nothing disabled (toggle: menu.monitors_section)
Global hotkeys (runtime-registered)
Bind hotkeys to any profile or monitor toggle via a live key-capture dialog (press the combo — supports ctrl/alt/shift/win + letters, digits, F1–F24, named keys)
Hotkeys persist in hotkeys.json and register immediately, no restart; managed by a self-contained RuntimeHotkeyManager that runs its own RegisterHotKey thread and dispatches through the existing EventService → BaseWidget.handle_hotkey_event channel (no core modifications)
Conflicts handled: binding a combo twice unbinds the first action; keys owned by other apps log a warning
Implementation notes
core/utils/win32/bindings/display_config.py (new): ctypes prototypes for the CCD API (GetDisplayConfigBufferSizes, QueryDisplayConfig, SetDisplayConfig, DisplayConfigGetDeviceInfo) with full DISPLAYCONFIG
* struct definitions — including the packed 16-bit modeInfoIdx unions used by QDC_VIRTUAL_MODE_AWARE
core/widgets/services/monitor_profile/ — display-config service (capture/apply/validate/enable-disable) + runtime hotkey manager. Key findings baked in: monitor disable works by applying a path-subset config; monitor re-enable requires QDC_DATABASE_CURRENT applied with plain SDC_USE_SUPPLIED_DISPLAY_CONFIG | SDC_APPLY (other flag combos return ERROR_INVALID_PARAMETER)
Widget follows existing conventions (BaseWidget, Pydantic schema with extra="forbid", PopupWidget, QMenu + apply_qmenu_style for the ⋯ dropdowns, per-row class names for styling)
schema.json regenerated; docs page + sidebar + README widget table updated
Testing

tiagomta and others added 5 commits August 28, 2026 13:43
…creen bar hide

- Runtime hotkeys now dispatch through EventService directly with the widget's
  screen name (BarManager is a QObject, unreachable via topLevelWidgets)
- Purge dead widget instances before hotkey dispatch and guard label updates
  against destroyed QObjects, fixing a crash on config reload
- Add a 2s fallback poller in AppBarManager that heals missed
  ABN_FULLSCREENAPP notifications (fullscreen app running during bar
  registration) with per-monitor correctness
- Drop the bar out of the WS_EX_TOPMOST band (HWND_NOTOPMOST) before
  HWND_BOTTOM when hiding for fullscreen; restore with HWND_TOPMOST
- Add Rename... action to each profile row's options menu
- Refactor the input dialog into a reusable prompt dialog helper
- Renaming remaps any hotkey bound to the profile; refuses to overwrite
  an existing profile name
@tiagomta tiagomta changed the title feat(widgets): add Monitor Profile widget feat(widgets): add Monitor Profile widget (WIP) Aug 29, 2026
@tiagomta

Copy link
Copy Markdown
Author

Still testing and waiting feedback.
Couple more ideias to add:

  • Profile info after creation
  • Monitor settings options
  • Currently if a monitor is off applying the profile will not apply, trying to figure a work around on this, maybe a warning and applying per monitor active.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant