A native Windows desktop sidebar built with Tauri 2, Rust, and React/TypeScript that registers with the Windows Shell as an Application Desktop Toolbar (AppBar) — so maximized windows dock around it instead of opening behind it.
- Why an AppBar?
- Features
- Getting started
- Development
- Build the Windows installer
- How the native AppBar works
- Multi-monitor behavior
- Fullscreen limitation
- Project structure
- Documentation
- Contributing
- Security
- License
A normal alwaysOnTop window floats above your maximized apps. DeskNote
instead tells Windows: "reserve this strip of the work area for me." The Shell
honors that reservation for every normal maximized window, so the sidebar sits
permanently beside your content without covering it — the same mechanism the
Windows taskbar uses.
- Real Windows Shell AppBar registration (
ABM_NEW/ABM_REMOVE) - Work-area reservation via
ABM_QUERYPOS/ABM_SETPOS, kept in sync withABN_POSCHANGEDnotifications - Responds to display, DPI, settings, and native sizing-loop changes
- Left or right docking, multi-monitor selection
- DPI-aware logical sidebar width
- Optional topmost z-order
- Native Windows drag-to-resize divider (
WM_SIZINGsizing loop — no JS/IPC spam while dragging) - Collapsible 56 px rail
- Persistent notes using WebView local storage
- Persistent UI settings
- Cleans up the AppBar reservation on exit
- Windows CI, lint checks, and a tag-triggered release pipeline
- Non-Windows preview mode compiles without the native AppBar behavior
- Windows 10 or 11
- Node.js 20 or newer
- Rust stable with the MSVC toolchain:
rustup default stable-msvc
- Microsoft C++ Build Tools with Desktop development with C++
- WebView2 Runtime (normally preinstalled on current Windows)
git clone https://github.com/rafa57600/desknote-sidebar.git
cd desknote-sidebar
npm install
npm run tauri devThe app starts docked to the right side at 360 logical pixels. Open or maximize another desktop application to verify that Windows reserves the sidebar area.
| Command | Purpose |
|---|---|
npm run dev |
Vite dev server (frontend only) |
npm run build |
TypeScript check + production frontend build |
npm run tauri dev |
Full app in dev mode with hot reload |
npm run tauri build |
Production bundle (MSI/NSIS installers) |
See CONTRIBUTING.md for the full contributor setup, project layout, and code style.
npm install
npm run tauri buildTauri writes release artifacts under:
src-tauri/target/release/bundle/
src-tauri/src/appbar/windows_impl.rs does the following:
- Gets the Tauri window's native
HWND. - Registers a private callback message with
RegisterWindowMessageW. - Registers the window as an AppBar using
SHAppBarMessage(ABM_NEW, ...). - Installs a safe Win32 subclass callback using
SetWindowSubclass. - Locates the selected monitor.
- Reads effective DPI for the selected monitor and converts logical width to physical pixels.
- Calls
ABM_QUERYPOSso Windows can account for the taskbar and other AppBars. - Calls
ABM_SETPOSto reserve the resulting rectangle. - Calls
SetWindowPosto place the Tauri window in that exact rectangle. - Uses Tauri's native resize-drag command only to enter the Windows sizing
loop;
WM_SIZINGthen constrains and reserves the AppBar rectangle while the pointer moves. - Responds to Shell
ABN_POSCHANGEDnotifications by recalculating the position. - Recalculates on
WM_DISPLAYCHANGE,WM_DPICHANGED, andWM_SETTINGCHANGE. - Removes Windows 11 rounded corners/DWM border where supported and disables the Tauri window shadow so the dock is flush.
- Sends
ABM_REMOVEduring normal exit or window destruction.
The UI lists monitors exposed by Tauri and stores the chosen monitor. The
native AppBar stores an anchor point on that monitor and uses
MonitorFromPoint(..., MONITOR_DEFAULTTONEAREST) when it recalculates its
position.
If the physical monitor topology changes significantly (for example, monitors
are unplugged and Windows reorders coordinates), use Settings → Refresh
monitors and reselect the desired monitor. The native WM_DISPLAYCHANGE
handler also recalculates against the nearest valid monitor.
A Windows AppBar controls the normal desktop work area, so normal maximized windows respect it. Browser-style fullscreen often still allows a topmost AppBar to remain visible, but an exclusive fullscreen application or game can take ownership of the entire display. No normal desktop AppBar can guarantee that it remains beside every exclusive fullscreen application.
desknote-sidebar/
├─ src/ React/TypeScript UI
│ ├─ App.tsx Main UI component
│ ├─ main.tsx
│ ├─ native.ts Typed Tauri command wrappers
│ ├─ storage.ts Persistent notes/settings
│ └─ styles.css
├─ src-tauri/
│ ├─ src/
│ │ ├─ appbar/
│ │ │ ├─ windows_impl.rs Native Windows AppBar implementation
│ │ │ ├─ unsupported.rs Non-Windows preview implementation
│ │ │ └─ mod.rs
│ │ ├─ commands.rs Tauri IPC commands
│ │ ├─ lib.rs App setup + exit cleanup
│ │ └─ main.rs
│ ├─ capabilities/default.json
│ ├─ icons/
│ ├─ Cargo.toml
│ └─ tauri.conf.json
├─ docs/
│ └─ screenshot.png
└─ .github/workflows/ CI + release pipelines
- docs/ARCHITECTURE.md — component boundaries, the IPC bridge, and the AppBar lifecycle in depth
- CHANGELOG.md — release history
- CONTRIBUTING.md — contributor guide
Bug reports, feature requests, and pull requests are welcome. Please read CONTRIBUTING.md first, and use the issue templates:
Security issues should be reported privately via GitHub Security Advisories, not as public issues. See SECURITY.md.
MIT © 2026 rafa57600
