feat: add tray layout controls
This commit is contained in:
@@ -18,6 +18,8 @@ The project uses pure Go and sets `CGO_ENABLED=0`. No C compiler, Windows SDK,
|
||||
|
||||
```text
|
||||
cmd/fancywin/ CLI entry point
|
||||
assets/fancywin.png Full-resolution generated icon source
|
||||
internal/assets/ Embedded runtime image assets
|
||||
internal/config/ YAML model, loading, and validation
|
||||
internal/layout/ Platform-neutral zone geometry
|
||||
internal/platform/platform_windows.go Win32 backend
|
||||
@@ -56,8 +58,10 @@ The script:
|
||||
5. Writes `dist\fancywin.exe` and copies the example to
|
||||
`dist\fancywin.yaml`.
|
||||
|
||||
The generated executable is a console subsystem application so users can see
|
||||
configuration and Win32 errors directly.
|
||||
The generated executable remains a console-subsystem application so diagnostics
|
||||
work without a second binary. Normal execution calls `FreeConsole` and operates
|
||||
through the notification-area icon. `--debug` retains the console, while
|
||||
startup failures in detached mode are shown with `MessageBoxW`.
|
||||
|
||||
## Cross-compiling
|
||||
|
||||
@@ -138,6 +142,13 @@ Test both x64 and ARM64 where hardware is available:
|
||||
same-integrity elevated run can do so.
|
||||
11. Disconnect and reconnect a monitor and confirm current work-area information
|
||||
is used for subsequent moves.
|
||||
12. Confirm the custom icon is crisp in the normal and overflow notification
|
||||
areas at 100%, 150%, and 200% scaling.
|
||||
13. Select each named layout from the tray, confirm the check mark and overlay
|
||||
change immediately, and verify `active_layout` changes without disturbing
|
||||
YAML comments or layout formatting.
|
||||
14. Right-click the tray icon, select `Exit`, and confirm the process and icon
|
||||
both disappear cleanly.
|
||||
|
||||
## Architecture
|
||||
|
||||
@@ -153,13 +164,29 @@ At startup the backend:
|
||||
|
||||
1. Requests per-monitor-v2 DPI awareness.
|
||||
2. Creates a named mutex for single-instance enforcement.
|
||||
3. Installs a `SetWinEventHook` covering `EVENT_SYSTEM_MOVESIZESTART` through
|
||||
3. Creates a hidden window and registers a notification-area icon with
|
||||
`Shell_NotifyIconW`.
|
||||
4. Installs a `SetWinEventHook` covering `EVENT_SYSTEM_MOVESIZESTART` through
|
||||
`EVENT_SYSTEM_MOVESIZEEND` with `WINEVENT_OUTOFCONTEXT` and
|
||||
`WINEVENT_SKIPOWNPROCESS`.
|
||||
4. Registers configured system-wide hotkeys against the current thread.
|
||||
5. Creates a two-second timer for configuration reload checks and a 25 ms timer
|
||||
5. Registers configured system-wide hotkeys against the current thread.
|
||||
6. Creates a two-second timer for configuration reload checks and a 25 ms timer
|
||||
for sampling the mouse button, Shift, and active drag state.
|
||||
6. Enters a standard Win32 `GetMessage` loop.
|
||||
7. Enters a standard Win32 `GetMessage` loop.
|
||||
|
||||
The tray icon is a generated FancyWin mark embedded as a 64×64 RGBA PNG. At
|
||||
startup the standard-library PNG decoder supplies premultiplied BGRA pixels to a
|
||||
32-bit GDI DIB section, which `CreateIconIndirect` converts to an alpha-aware
|
||||
native `HICON`; it never needs to be extracted to disk. A stock Windows icon is
|
||||
used only if conversion unexpectedly fails.
|
||||
|
||||
The tooltip contains the active layout. The context menu deduplicates configured
|
||||
layouts by case-insensitive name, checks the active one, and provides `Exit`.
|
||||
Selecting a layout updates runtime state immediately and rewrites only the
|
||||
top-level `active_layout` YAML line so the choice persists. `Exit` posts
|
||||
`WM_QUIT` to the existing message loop for orderly hook, hotkey, overlay, icon,
|
||||
and tray cleanup. A registered `TaskbarCreated` message restores the icon after
|
||||
Windows Explorer restarts.
|
||||
|
||||
### Mouse snapping
|
||||
|
||||
|
||||
Reference in New Issue
Block a user