Skip to content

v0.1.12

Choose a tag to compare

@github-actions github-actions released this 08 May 00:51
· 476 commits to main since this release

Reliability

  • Add leopardwm-watchdog.exe, a tiny supervisor process that wraps the daemon. lwm run now spawns the watchdog by default; the watchdog spawns the daemon as its child and wait()s. On a clean exit (lwm stop, normal shutdown), the watchdog exits with the same status. On a non-zero / panic exit, the watchdog calls uncloak_all_visible_windows() from platform_win32 directly (no IPC needed) so any windows the daemon had cloaked off-screen become visible again, then auto-restarts the daemon and surfaces a Win10/11 toast ("LeopardWM recovered — the daemon crashed and was restarted automatically") via ToastNotificationManager with a registered AppUserModelID. Crash-loop budget: 3 abnormal exits within 60s causes the watchdog to give up, surface a warning toast ("LeopardWM disabled — run lwm doctor"), and exit so the user can investigate (%TEMP%\leopardwm-daemon.err.log). Prior to this, a hard daemon panic could leave windows cloaked off-screen until the user ran lwm panic-revert from another terminal — the watchdog closes that window. lwm run --no-watchdog opts out for development. The watchdog binary is bundled into the MSI installer, the GitHub-Releases zip, and the Scoop manifest's install directory (it's not shimmed onto PATH because users don't invoke it directly — lwm run finds it as a sibling of the CLI binary). The watchdog also installs itself into a Job Object with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE so the daemon dies with the supervisor (no orphaned daemon if the watchdog process is killed). The toast renders on a worker thread wrapped in catch_unwind with explicit CoInitializeEx(MTA) for WinRT, so a notification failure cannot take down the supervisor. Caveat: maximizebox restoration on hard taskkill /F of the daemon falls outside the watchdog's reach (the maximizebox set is process-local to the daemon); for that scenario, run lwm panic-revert. Most daemon panics fire the in-process panic hook, which handles maximizebox before exit

Improvements

  • Per-window focus-border corner radius. Trusts DWMWA_WINDOW_CORNER_PREFERENCE only when the app has explicitly opted into a non-default value: DWMWCP_DONOTROUND → 0 px / square, DWMWCP_ROUNDSMALL → 4 px, DWMWCP_ROUND → 8 px. Apps that report DWMWCP_DEFAULT (the value every app gets unless it overrides) fall back to the 8 px Win11 default — but apps like Firefox / Zen Picture-in-Picture report DEFAULT while drawing their own non-DWM-composited square frame, so a per-rule corner_style = "square" | "rounded" | "small_rounded" override is the escape hatch. The default config now ships with [[window_rules]] match_class = "MozillaDialogClass", corner_style = "square" as a working example users can edit or remove
  • Surface corner_style in the Settings WebView. The Window Rules table now has a Corners column with Auto / Square / Rounded / Small rounded values, round-tripping through save/load alongside the existing class/title/executable/action fields. Auto (the default) is omitted from the saved TOML so existing rules without corner_style round-trip unchanged