You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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