-
-
Notifications
You must be signed in to change notification settings - Fork 0
The Desktop
The bar, the desktop widgets, the desktop icons and the theme manager. All of it is drawn by SynapseOS itself — waybar is gone, replaced by a native quickshell bar in synui pkgrel 154.
For the compositing side (glass, blur, shadows, CRT filters) see Window Effects.
One bar per monitor, live across hotplug (Variants over Quickshell.screens).
Modules, left to right: workspaces, window title, media, then on the right
tray · network · bluetooth · volume · CPU · memory · battery · game mode · clock.
| Do this | Get that |
|---|---|
Tap Super, or click the ◢ SYNAPSE badge |
Start menu |
| Right-click the bar | Bar settings — position, auto-hide, per monitor |
| Click the clock | Calendar |
| Click volume / network / bluetooth | The relevant panel |
| Right-click volume | Mixer — per-device and per-application levels |
Settings are per monitor. Auto-hide reveals on a dwell at the screen edge, not instantly, so crossing the edge on the way somewhere else does not flap it open.
menu.c — synui's in-compositor start menu — existed for one reason: waybar's
GTK was never handed keyboard focus, so a menu drawn by the bar could not be
arrow-navigated. That turned out to be a GTK/waybar limitation, not a layer-shell
or synui one.
Verified end to end before committing to the port: a
PanelWindow { focusable: true } with WlrKeyboardFocus.Exclusive received
20 real key events and arrow-navigated its list on a live session. So a QML
start menu was viable, and the start button, menu and everything else moved into
the bar. menu.c was moved in and then deleted (pkgrel 163).
Of the 14 Wayland protocols quickshell's module uses, synui advertises 12 —
checked with wayland-info, not by reading code. The two missing are
zwp_keyboard_shortcuts_inhibit_manager_v1 (so ShortcutInhibitor is unusable)
and ext_image_copy_capture_manager_v1 (screencopy v3 covers it).
Right-clicking the volume module opens a native mixer (synui pkgrel 197) —
output and input devices with a (•) radio that sets the default, then
per-application playback streams, then capture streams when there are any.
It is drawn by the bar itself rather than launching pavucontrol, which is not
installed. That is the actual history: the tooltip advertised "right-click for
mixer" while the handler ran a command that did not exist, so the right-click
did nothing, silently. The fix was to write the mixer, not to add the dependency.
quickshell's
Pipewire.nodesis empty until something tracks an object — the service does not open its connection until a first consumer asks. And an untracked node reports its name and type but an emptypropertiesmap with placeholder volumes, so the panel tracks its whole node set continuously instead of on open; otherwise every slider draws at 100% for a frame and snaps.
synui-apply-theme writes ~/.config/synui/theme.json, and Theme.qml reads it
with FileView { watchChanges: true }. A theme switch repaints the running bar
with no restart — verified by rewriting the palette under a live process.
QML
colorcannot parse CSSrgba()— only#RRGGBBand SVG names. The bar therefore can never just read the generated waybar CSS; it would fall back silently and look fixed while doing nothing. The JSON carries[r,g,b]triples plus a separate alpha, which is why the theme script keepsbar_baseandbar_alphaapart instead of pre-bakingrgba()strings.
Written temp + rename(): watchChanges fires on a partial write otherwise, and
the bar repaints from half a palette.
State colours (green = charging, red = dying battery) are deliberately not themed — they only switch on light/dark, because the pastels are unreadable on a pale bar.
Four optional widgets: an audio visualiser, a system monitor, a big
clock, and a quick-launch strip. They sit on the Bottom layer — wallpaper
under them, any window over them.
All off by default, and ~/.config/synui/widgets.state does not exist until
one is switched on. Decoration must not appear on an upgrade nobody asked for.
Super+Shift+A opens the widget manager — one row per widget. Space
from any row is a group flip: all off if any is on, so one key is always a
reliable "clear the desktop".
From the command line:
synui-widgets show the current state
synui-widgets sysmon on turn one on
synui-widgets visualizer toggle flip one
synui-widgets all off turn everything off
synui-widgets toggle group flip (all off if any is on, else all on)
Widgets: visualizer sysmon clock launcher.
The visualiser needs cava (an optdepend); without it the widget stays dark however the state file is set.
synui-widgets is the single writer of widgets.state, and WidgetState.qml
watches that file with FileView.watchChanges — so a toggle repaints the desktop
live, with no restart and no IPC. The keybind, the manager panel and the
control panel row all run the command rather than writing the file themselves:
one format, one bug surface. Written temp + rename, because the bar is watching.
Every widget needs mask: Region {}. Without it a widget is an invisible
rectangle that eats every click over it — for the visualiser, a full-width strip
along the bottom of the screen. QuickLaunch is the deliberate exception
(it has things to click), and the price is that the desktop right-click menu is
unreachable underneath it.
The visualiser needs cava because quickshell's PipeWire exposes a single
peak — no spectrum, no FFT. cava's config is written at spawn into
$XDG_RUNTIME_DIR/synui-cava.conf rather than installed, so it works identically
from the packaged tree or a user copy. It repaints at 60fps for as long as it is
visible (cava emits zeros in silence, not nothing), so cava is stopped when the
widget hides.
Widgets defer instead of duplicating. QuickLaunch's app-menu and wallpaper
rows run synctl dispatch menu / synctl dispatch wallpaper — the exact keybind
actions, so they cannot drift. BigClock is driven by synui-clock, for the same
reason the bar's clock is: formatting a date in QML would strand the Date & Time
panel's toggles.
Primary output only, re-probed on Quickshell.onScreensChanged — but still
instantiated per screen, so unplugging the primary cannot strand a widget.
Off by default. desktop_icons = on in synuirc, or the tick in the desktop
right-click menu (which persists across sessions).
-
Drag to place. A placement is stored as
pin_x/pin_yand survives the session. - Arrange by name, type, size or date from the right-click menu.
The bar reserves its strip after startup. Icon layout pass 1 therefore saw the whole output and packed icons under where the bar was about to be. The layout re-runs once the exclusive zone lands.
Super+T opens the theme manager. Themes are a full palette applied across the
stack — synui's own chrome, the bar, GTK, Qt/KDE, foot, and Firefox — by
synui-apply-theme.
Ships with SYNAPSE, Dark, XP and 95 plus six riced themes (gruvbox and friends,
including a bubblegum pink). The 95 theme uses SYN_CHROME_BEVEL chrome, which
returns a shadow of 0 — a Win95 window legitimately has no drop shadow.
Super+W is the wallpaper picker: built-in Synapse (static) and Matrix
(animated GLES2 rain), a browser for ~/Pictures, per-monitor scoping on Tab,
and Steam Workshop wallpapers when that package is installed — all of it on its
own page, Wallpapers.
synui-apply-themehardcodes$HOME. A nested test compositor started with a scratchXDG_CONFIG_HOMEwill still re-theme the live desktop, so stub it onPATHbefore any nested-session testing. See Development Notes.
Super+Tab cycles the current desktop through four layouts, in this
order, and a toast names the one you land on:
tiling → floating → monocle → AI → back to tiling
Each of the nine desktops has its own layout, so you can keep one tiled and another floating. They all start on tiling at login; the choice is not remembered across a restart.
Super+Shift+T (retile) jumps straight back to tiling from anywhere,
which is usually what you want instead of pressing Super+Tab three more
times.
It is also in the control panel (Super+C ▸ Desktop ▸ Layout), which
is the easier way in if you have not memorised the key. The row reads the
current layout and which desktop it belongs to — tiling · desktop 1 — and
Enter cycles it exactly as Super+Tab does.
| Layout | What it does |
|---|---|
| Tiling | Master/stack. The first window takes the left 60%, the rest share the right. Super+H / Super+Shift+L move the split. |
| Floating | Nothing is placed for you — windows go where you put them. |
| Monocle | One window at a time per monitor, filling the screen. See below. |
| AI | Asks synapd where the windows should go, based on what they are. Falls back to tiling if the AI is unavailable. |
Floating, maximized and fullscreen windows sit outside all of this — every
layout skips them. That is worth knowing because dragging a window to move it,
snapping it to a screen edge and maximizing it all mark a window floating, so
a tiling desktop can quietly end up with nothing left to tile. Super+F
clears one window; retile clears the lot.
Monocle shows you one window per monitor and hides that monitor's others. The one you see is the one with focus, so on a three-monitor desk you get three windows, one filling each screen — not one window and two blank screens.
-
Change which one with the normal focus keys.
Alt+Tab(most recently used),Super+J/Super+K(stacking order), or clicking the window in the dock. There is no separate monocle-only switcher. -
Floating windows are exempt — they stay visible, on top, at their own
size. So
Super+Fis how you get a second thing on screen: float the dialog, the video or the terminal you want to keep an eye on, and it sits over the full-screen window instead of replacing it. -
It is not fullscreen. The bar, the dock and any panels keep their space,
and windows keep their titlebars. For real fullscreen use
Super+Shift+F. - Minimized windows are skipped and never become the shown one.
- Monocle is one of the two layouts (with floating) that still honours remembered per-app geometry — see below. Tiling and AI ignore it, because they place windows themselves.
remember_geometry = on reopens a floating window at the box it had last time,
per application.
Two bugs are baked into the current design as guard rails:
- The geometry table was written but never read for two pkgrels — the persist path looked complete from the writing side alone.
- The restore then asked the new view whether it was floating, and a view
that has just mapped is not floating yet, so nothing ever restored. The
floating state is persisted alongside the box (
floating=) for exactly this reason.
See also: Wallpapers, Window Effects, Sound Themes, Cursor Themes, synui, Keybindings.
Using it
- Installation
- Updating
- Software
- Files
- Keybindings
- Commands
- Nix
- Gaming
- DaVinci Resolve
- Secure Boot
- Troubleshooting
Customising it
Components
Apps
Hacking on it