Customising it

The Desktop

Edit on GitHub · last edited

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.


The bar

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.

Two shells: synapse and antiquity

SynapseOS ships two complete bars, and bar_shell picks between them — either in ~/.config/synui/synuirc or from Control panel ▸ Desktop ▸ Bar shell.

bar_shell What you get
synapse (default) Everything described above — start menu, tray, mixer, widgets
antiquity A radial taskbar, a sidebar, and a tarot-card power menu

Antiquity is a port of linux-antiquity by diinki — her design, her QML, and the three wallpapers the theme was built around. It is redistributed here under the MIT licence she released it under (© 2026 diinki), with her notice kept intact in the tree as LICENSE.antiquity. She publishes the wallpapers separately too, in diinki/wallpapers, under the name Celestial Antiquity.

The two trees are independent by design — no shared QML. They disagree about nearly every visual decision, and a common base would only be a third thing to keep working.

Changing bar_shell does nothing until the bar restarts, i.e. the next login. synui parses the key so there is one spelling of it and so the control panel can persist it, but the compositor does not start the bar — synui-bar reads the setting for itself.

Antiquity keeps its settings in ~/.config/synui/antiquity/, not beside the shell: the shell itself lives under /usr/share, which you cannot write to.

Fonts bundled with it are documented in quickshell-antiquity/FONTS.md, which exists partly to satisfy a licence: Boska, Recia and Quilon are © Indian Type Foundry, and their embedded terms require naming the faces and crediting ITF's ownership wherever they are used. Three of the nine fonts upstream bundles were not redistributable and were removed rather than shipped.

Why waybar was replaced

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).

The mixer

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.nodes is 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 empty properties map 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.

Theming is live

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 color cannot parse CSS rgba() — only #RRGGBB and 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 keeps bar_base and bar_alpha apart instead of pre-baking rgba() 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.


Desktop widgets

Nine optional widgets: an audio visualiser, a system monitor, a big clock, an analog clock, a music card, a quick-launch strip, a post-it note, a pizza, and Tux. 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.

Turning them on

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 analog music launcher postit pizza tux. synui-widgets home <widget> puts a dragged one back where it started.

The analog clock has five facesminimal (four strokes and six dots), classic (a full railway dial), roman (XII … IIII, the numerals real dials use), neon (an accent glow ring with bloomed hands) and monster (a pink animal holding the dial in its belly). Set it at Control panel ▸ Desktop ▸ Analog clock face, and resize the widget by its corner.

monster is the one face that is not the theme's ink. The other four are chrome and follow the accent; this one is a character, and a character whose colour changes with the theme is a different character on every desktop — the same reason Tux is black and white wherever he is drawn. Its dial brings its own white face with it, so the time stays readable on a dark theme where light ink on a light belly would not be.

It is deliberately not click-to-cycle. Taking clicks would make it interactive, and a widget that takes clicks is one the desktop right-click menu cannot be opened through — a price the quick-launch strip and the post-it pay on purpose, and a clock has no business paying.

The music card picks a source and starts the music rather than only reporting what is already playing, draws a YouTube playlist's tracks by name, and fetches their cover art.

The visualiser needs cava (an optdepend); without it the widget stays dark however the state file is set.

How the toggle works

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.

Traps worth knowing

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.


Desktop icons

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_y and 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.

Dropping a file onto the desktop from a file manager works, and it is a move within your own session or a copy from another application — never a silent delete of somebody else's data.


The file manager

A folder opens in Files (synfiles), SynapseOS's own — tabs, a split view, thumbnails from the shared cache, search, the XDG trash, undo of anything that changed files, and a properties pane that reports image and video resolution. It replaced Dolphin as the default in August 2026, and Dolphin came off the image entirely shortly after — synpkg install dolphin is one command for anyone who wants the KDE one back.

Both file managers read the same kio/servicemenus, so the Extract / Crop / Mount ISO / Run with Wine / Set as Wallpaper entries synui installs appear in either one. A helper written once shows up in both.

Its own page: Files.


The terminal

Super+Return opens syntty, SynapseOS's own, and the default since synui 0.1.0-359. It links no GL at all — which is why it is also the terminal that still opens on a machine whose GPU stack does not.

Nothing in SynapseOS opens kitty any more; a synuirc written between synui 215 and 358 still names it and that is treated as a real choice rather than overwritten.

Its own page: Terminal.


The start menu

Tap Super, or click the ◢ SYNAPSE badge. Applications by category, with search.

It lists applications, not everything with a .desktop file. A Wine prefix invents new junk per installer — uninstallers, readmes, registration forms, "Visit SimCity Exchange", thirty-odd DirectX SDK tools — and on one machine the Wine page was 65 entries of which 15 were programs.

Two filters do it, because the two problems are different shapes:

  • Patterns, for what cannot be enumerated: an Exec that opens a document or a URL, uninstallers, SDK trees, and the vendor-shortcut vocabulary.
  • A shipped list (menu-hidden.conf), for what can: the diagnostic satellites a library installs for its own developers and that arrive as somebody else's dependency. Your own file is read second, so !name puts one back. Qt Designer, Linguist, Assistant and CMake are development tools, not satellites, and stay listed.

Filtered entries are hidden from search as well as from the pages. That is the part that is more than tidying: typing "sims" and being offered Uninstall The Sims one row above The Sims is a dangerous list to arrow through.


Screensaver, lock screen and Do Not Disturb

Super+Z is one panel for what the screen shows when nobody is at it — the screensaver, and the appearance of the lock and login screens.

Seven modes — blank, clock, starfield, slideshow, matrix, floaters, dvd — and it is off by default: with no timeout set, nothing about an existing install's idle behaviour changes until you ask.

floaters drifts the Synapse mark along curved paths, fading as it shrinks. dvd is the bounce everyone knows: constant speed, a new colour on every edge, and a count of the exact corner hits.

Up/Down moves between rows, Left/Right changes the value under the cursor, p previews the current mode straight away rather than making you wait out the timeout, s saves, Escape closes. The mouse does the same job — hover selects, left click steps a value on, right click steps it back.

screensaver          = starfield   # blank / clock / slideshow / matrix / floaters / dvd, or off
screensaver_timeout  = 300         # seconds; 0 = never
screensaver_lock     = on          # lock the session when it is dismissed
screensaver_dir      = ~/Pictures  # slideshow source (default: the wallpapers)
screensaver_interval = 30          # slideshow seconds per image

lock_background      = desktop     # or black, or image
lock_dim             = 55          # percent
lock_blur            = 16          # pixels
lock_accent          = #00e5ff     # naming one stops it following the theme

lock_media           = on          # now playing, with ⏮ ⏯ ⏭
lock_weather         = off         # ⚠ the only part of this screen that uses
                                   #   the network
lock_weather_unit    = auto        # auto reads the locale; or c / f
lock_layout          = auto        # the keyboard-layout chip; auto = only when
                                   #   xkb_layout names more than one

The saver is the fifth idle stage, so the power panel arms it: with power saving off (Super+P) nothing here can fire, and an application holding an idle inhibitor — a video, mpv, Steam — holds it off exactly as it holds off the screen blanking. The panel says which of those is happening rather than showing a countdown that cannot run.

The lock screen defaults to your desktop wallpaper, blurred and dimmed, and otherwise follows the desktop theme — the greeter inherits all of it, because the greeter is the lock screen. lock_background = image means the picture on the panel's Lock image row, which Left/Right walks through the same wallpapers Super+W browses.

A pick in the panel writes ~/.config/synui/saver.state, which overrides those keys the way wallpaper.state does; delete it to hand control back to synuirc.

What else is on that screen

Three things sit on the lock panel besides the clock, and because the login screen is the lock screen, all three are on the login screen too.

Now playing — title, artist, and ⏮ ⏯ ⏭, read over MPRIS from the same player the bar's media module and playerctl talk to. Click the buttons, or use the media keys on your keyboard: they reach the player while the screen is locked instead of typing invisible characters into the password field. Nothing is drawn when nothing is playing. lock_media = off removes it.

The weather is off until you ask for it — it is the one thing here that goes to the network. On, it asks Open-Meteo (no account, no key) every twenty minutes and caches the answer, so a lock screen shows a temperature in its first frame; with no network it keeps showing the last reading, dimmed and labelled with its age rather than pretending to be current.

There is one location on this machine and it is not set in synuirc. It is the file every weather widget here already reads:

omarchy-weather-location --set "Oslo" 59.9139,10.7522
omarchy-weather-location                      # what it is now
omarchy-weather-location --clear              # back to IP detection

The keyboard-layout chip, top right. This one is a fix rather than a feature:

A password typed in the wrong layout is rejected exactly like a wrong password, and nothing on the login screen could say which had happened. Worse, the login screen only ever had the system layout — so a password needing your second layout could not be typed there at all.

xkb_layout = us,no gives you two. Click the chip, or press Super+Space, to walk them; it appears on its own only when there is more than one to choose between. On the desktop the same walk is synctl layout next, or a bind:

xkb_layout = us,no
bind = super+shift+space kbd_layout next   # ⚠ not layout_cycle — that tiles

Your session publishes your layouts for the login screen the same way it publishes the lock wallpaper: the greeter runs as another account and can read neither your config nor your home. A brand-new install therefore logs in once on the system layout before the login screen knows about the second one.

Do Not Disturb

Super+Shift+M hides the toasts and mutes the chime. Suppressing only the drawing would leave the half people actually notice. Its own confirmation still shows, so the key never looks dead.


Themes

Super+T opens the theme manager. Themes are a full palette applied across the stack — synui's own chrome, the bar, GTK, Qt/KDE, the terminal, and Firefox — by synui-apply-theme.

Fifteen of them:

Theme theme = in synuirc
SYNAPSE Prism (what a fresh install boots into), Prism Light prism, prism-light
SYNAPSE (neon), Dark synapse, dark
Windows XP, Windows 95 winxp, win95
macOS 26, Aqua, Platinum — a Mac from three eras, new in 0.2.9 macos26, aqua, platinum
Catppuccin Mocha, Gruvbox, Tokyo Night, Nord, Dracula, Bubblegum catppuccin, gruvbox, tokyonight, nord, dracula, bubblegum

A theme is a style, not just a palette. What makes a window read as a Mac is that its controls are on the left and its caption is centred; after that it is per-era — Tahoe's flat glass, Aqua's pinstripes and glossy traffic lights, Platinum's racing stripes. Same precedent as XP and 95: the 95 theme uses SYN_CHROME_BEVEL chrome, which returns a shadow of 0, because a Win95 window legitimately has no drop shadow.

SYNAPSE Prism

The house theme, and the one a fresh install comes up in.

Prism has no colour of its own. It is one dark, desaturated, near-neutral surface at low alpha, and the wallpaper supplies the colour through it — measured live, on every wallpaper change. That is the whole theme. A greyscale wallpaper has no hue to give, and Prism falls back to the house cyan and says so in the journal.

Everything that is not the accent is fixed, and that is deliberate: a theme whose chrome colour also came off the wallpaper would be a different theme on every picture, and the glass would have nothing constant to be glass against.

Prism Light is the same theme with the surface inverted and deliberately nothing else changed — the same glass, the same accent off the wallpaper. Two things could not simply be inverted: the fallback accent measures 1.7:1 on a near-white panel, so it drops four stops to the same hue at 5.0:1, and the surface is #EEF1F6 rather than white so the contrast correctors have somewhere to work.

Dark is the default rather than light, and that is an argument about defaults rather than a claim that light cannot work. Glass over an arbitrary photograph is a contrast problem, and a pale glass over a white beach is a panel with no edges.

Glass

One slider for the whole desktop's see-through-ness, under Control panel ▸ Appearance, plus the switches around it.

Key Values What it does
glass_level auto off 0100 How much you see through. auto lets the theme answer
glass_sync on (default) Every surface below follows the slider. Change one by hand and it keeps its own until you switch this back on
glass_pinned bar_opacity dock_opacity … The rows taken off the slider. Written for you when you drag a driven row
glass_legibility on (default) A surface may raise its own alpha until its text clears AA against what is behind it. Off draws exactly what was asked, including nothing at all
scene_ink on (default) Menus and panels ink themselves off the window behind them rather than the wallpaper it covers
wallpaper_accent auto off on Take the accent off the wallpaper instead of the theme. auto is the two Prisms and nothing else
widget_glass auto off on Desktop widgets take the dock's glass instead of the HUD panel

The slider drives five surfaces, each with the number that surface needs — the two window opacities, the terminal, the bar and the dock. They are not proportional to each other: the same alpha that is pleasant on a 1200px window makes a dense panel row unreadable.

Two actions do the whole thing at once:

  • Appearance ▸ Make it all solid — glass off and windows opaque, in one press. Doing it by hand was three controls and the third was invisible until it bit.
  • Appearance ▸ Make it all clear — the mirror of it.

The Glass slider no longer bottoms out at nothing. At the top of the range the bar and the dock land on the thinnest surface that is still a surface (0.05), because the difference between 0.00 and 0.05 is not five percent of anything — it is whether the surface exists. At 0.00 the backdrop blur has nothing to mask and frosts each glyph instead of the strip; the legibility walk has no alpha to walk from; and a strip you can see straight through is one whose extent you cannot find. A genuinely clear bar is a thing to ask for — the row, or Make it all clear — rather than something two of the three glass themes handed you.

What a fresh install ships

Since 0.2.9.4 a new install boots into the house desktop rather than into Prism with everything else left at the compositor's defaults:

theme            = prism
glass_level      = auto       # the theme's own answer — see below
transparency     = on
bar_shape        = floating-pill
dock_radius      = 64         # clamped to a capsule
widget_glass     = on
wallpaper_accent = on
scene_ink        = on
wallpaper        = /usr/share/backgrounds/commons-st-louis-night.jpg

auto is the whole point. On Prism it resolves to the frosted 0.05 surface for the bar, the dock and the panels, and windows draw at the 0.90/0.84 pair the theme carries in its own preset. On Gruvbox, Win95 or any of the other twelve it resolves to whatever that theme was tuned with. Switch theme and the desktop follows, for ever, with nothing to undo.

This shipped as glass_level = 100 for one release, and that was a workaround rather than a decision. auto was not auto: a glass theme's panels fell through to a tuned ladder where an explicit level returned an absolute, and the dock had no way to ask its theme at all — so a Prism desktop left on auto came up with a see-through bar, see-through windows and a solid slab of a dock. Writing the number down was the only way to get the look the theme was drawn for, at the cost of pinning that look onto every other theme. Both halves are fixed in synui 467; auto and glass_level = 100 now produce the same desktop on Prism.

The two exceptions are bar_opacity and dock_opacity, which a fresh install writes as 0.05. They are not the glass level in disguise — the compositor resolves both from the theme and needs neither. The bar and the desktop widgets are a separate process (quickshell), and they read those keys out of theme.state, then settings.state, then synuirc. A machine that has only ever been told theme = prism has neither of the first two, because theme.state is written when somebody picks a theme. It is the same gap widget_glass = on works around, with the same way out: set them to auto once you have picked any theme from the manager.

A clear bar

bar_opacity is yours to set under any of the fifteen — it used to be the theme's to decide, so the only way to see through the bar was to run macOS 26 and the only way to stop was to leave it.

# ~/.config/synui/synuirc
bar_opacity = 0      # 0 = no background at all; `auto` = the theme decides
bar_shape   = full-width | rounded-ends | floating-pill

With the strip gone, the bar's ink is measured off the wallpaper underneath, so the clock stays legible over a bright picture instead of being whatever the palette said. The dock and the desktop widgets render through the same compositor glass.

bar_shape is what the bar does with the corner radius: rounded-ends curves the two corners facing the desktop, floating-pill also lifts it off the edge and insets it from both sides, closing it into a capsule. All three are no-ops with the corners off (radius 0, or a retro chrome) — it is "what shape when rounded", not a second switch.

Two wallpaper choices paint no picture there is anything to measure — none (a solid colour) and matrix (rendered into a GPU buffer the painter never sees). The bar keeps a solid strip on those rather than guessing.

RGB lighting

The desktop already decides one colour per wallpaper — synui measures the picture and the bar, the dock and the icons wear it. syn-rgb carries the same colour out to whatever OpenRGB can see: the RAM, the board, the keyboard.

syn-rgb on                # follow the wallpaper's accent
syn-rgb colour 8B00FF     # or pin one
syn-rgb follow theme      # or follow the theme instead of the picture
syn-rgb status            # what it thinks, and whether openrgb is there
syn-rgb dark              # lights off — a different thing from `off`

Control panel ▸ Appearance ▸ RGB lights is the same switch.

It is a bridge and nothing more: read the colour this desktop already chose, hand it to OpenRGB, get out of the way.

The watching is systemd's. A path unit fires when the measured palette changes, so there is no daemon, nothing polling, and nothing running at all between one wallpaper and the next.

openrgb is an optional dependency — a desktop with nothing in it that glows should not pull in a lighting daemon — and syn-rgb names the missing package rather than failing silently. A fresh install has this on; an existing machine keeps it off until asked, because hardware currently doing what its owner asked is not something an upgrade may take over.

A greyscale wallpaper is an answer, not a failure: there is no hue to follow, so the lights keep the last colour they were given rather than snapping to something invented.

Text

Family and scale, desktop-wide, under Control panel ▸ Appearance. Both live in font.state, which synui, synfiles, syntty and the rest of the suite all read — there is deliberately no second copy in synuirc. Leaving a font row applies it; closing the panel is "I am done", not "I changed my mind".

There was a second copy — ui_font in synuirc, which the compositor applied to everything it drew itself. So a font changed from any other window in the suite moved every application on the desktop and left the dock, the control panel, the notifications and the window titles on the previous face until the next login. It is retired: one setting, one file, every window.

Fifteen families ship with every install — sans, serif and mono, all OFL or Apache. A picker is only a setting if there is something in it, and a stock install used to carry Noto, DejaVu and a console face, which made "choose the font this desktop is drawn in" a choice between two. Studio's title lettering reads the same list.

synui-apply-font --size / --scale is the same thing from a script.

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. Super+Ctrl+W — or w in the picker — browses wallhaven.cc for more, and w there comes back to the picker. It is off until you turn it on, which the window itself asks the first time it opens.

synui-apply-theme hardcodes $HOME. A nested test compositor started with a scratch XDG_CONFIG_HOME will still re-theme the live desktop, so stub it on PATH before any nested-session testing. See Development Notes.


Language

The desktop draws its own words in fourteen languages: English, Deutsch, Français, Español, Português, Italiano, Nederlands, Polski, Русский, 日本語, 中文, 한국어, हिन्दी, العربية. It follows the locale — the language chosen at the boot menu or by the installer — and there is nothing to configure.

887 strings, complete in all thirteen catalogs. What speaks: the control panel, the dock, the desktop right-click menu, the lock screen, the screensaver, the power and idle panels, the CRT and filter panels, and the widget panel (Super+Shift+A).

And the bar, by a different road. quickshell ships no translator at all — there is no installTranslator anywhere in the binary — so qsTr() compiles, looks up nothing, and hands back its own argument while looking exactly like a marked string in review. The same .po files are compiled a second time into JSON, and a singleton reads them: 265 strings, one catalog per language, installed beside the singleton so it can find its own directory.

And the applications name themselves. A .desktop file carries its own translations (Name[de], Name[pt_BR], Name[sr@latin]) and most software ships them, so the application grid, the start menu and the desktop icons show each program's name in your language — matched on the spec's own candidate list, against the same locale the rest of the desktop is drawn in. A program that ships no translation keeps its English name, which is the right failure.

Still English: SynapseOS's own entries in that list — the thirty launchers synui ships for its panels — plus the desktop widgets the bar draws, and a handful of compositor panels: the wallpaper picker, notifications, the clock's date format, and most of the Bluetooth and news panels, which have their headings translated and little else.

Every one of those is a screen somebody can reach, which is why they are listed rather than rounded up to "translated".

Arabic and Hindi are shaped, not just translated

synui draws its own text through cairo rather than handing it to a toolkit, so it carries the layout stage itself: HarfBuzz for joining, mark positioning and Indic reordering, FriBidi for reading order. Arabic joins and runs right-to-left; Devanagari matras sit before the consonants they belong to; conjuncts form. Hebrew reorders the same way.

Latin, Cyrillic and CJK do not go near the shaper — they need no joining and no reordering, so they take the same drawing path they always did and lay out identically to before.

Both libraries were already on the system: harfbuzz under librsvg, fribidi under pango and GTK. Shaping adds nothing to the ISO.

Changing it after installing

The desktop reads the locale, so this is the same row as everything else that follows it — Settings ▸ Region, or:

syn-settings set locale ar_EG.UTF-8    # log out and back in

Catalogs install as .mo files, one per language:

ls /usr/share/locale/*/LC_MESSAGES/synui.mo
msgunfmt /usr/share/locale/ar/LC_MESSAGES/synui.mo | head   # what one holds

They are keyed by the English sentence rather than by an identifier, so a string with no translation prints the English. A partial catalog is usable, and no panel can ever show an identifier.


Scale — making the whole desktop bigger

Super+Ctrl+= and Super+Ctrl+-; Super+Ctrl+0 returns to 100%. Also Control panel ▸ Display ▸ Scale everything, and synctl dispatch display_scale 1.5.

This is an output scale — the same control GNOME puts under Display ▸ Scale and macOS under Displays. The compositor's own panels, every application and the cursor all grow together, drawn at the larger size rather than magnified, and synui advertises wp_fractional_scale_v1 so 125% and 150% are as sharp as 200%. It is remembered in outputs.conf, so it survives a login.

It applies to every screen at once. Growing one monitor of three has not made the desktop bigger — it has made the desk inconsistent and left you to find the other two. Per-monitor scale is and + in Super+D, where you are looking at one screen on purpose.

This is not Text scale. That setting, under Appearance, sizes the words inside SynapseOS's own windows; it cannot reach a panel the compositor draws itself, and it cannot reach Firefox. Both are real settings and neither is the other's spelling. If you want everything bigger, you want the scale on this page.

A scale that would leave the screen too small is refused, out loud. The Displays panel is 990px wide and the control panel 860, both laid out in columns — below about 1010 logical pixels they do not clip, they put their values and their key legend off the screen. Those are the panels you would use to undo a scale you regret, so the step is refused with the reason rather than doing nothing. On a 2560-wide monitor that allows up to 200%; on a 1366-wide laptop panel, up to 125%.

Screens

Super+D is the display panel: resolution, refresh rate, arrangement, p to set the primary output, and m to cycle the display mode.

display_mode = extend      # or mirror, or external
hdmi_audio   = auto        # or on, or off
Mode What it does
extend one desktop across every screen — the default
mirror every screen at the same origin and forced to the largest resolution they all share
external the built-in panel off and detached; refuses when there is no external screen

Mirror forces the shared resolution on purpose. Overlapping a 1080p laptop and a 720p projector without that is not duplication — it shows the projector a crop and calls it mirroring.

external re-runs itself on every hotplug, so unplugging the television gives a laptop its own screen back rather than leaving a machine with nothing lit and no way to say so.

So "switch the laptop panel off and use the television" is a mode you set once, not something to redo at each plug-in: external is remembered, and the hotplug re-run is what applies it to whatever you plug in next and takes it back off when you unplug. On a laptop the display key (XF86DisplayFn+F7 on a ThinkPad) cycles the three, which is the one way in that does not make you open a menu on the screen you are trying to switch off. The control panel's Display ▸ Screens row and synctl dispatch display_mode [name] are the other two.

A disabled output stays in the compositor's layout. wlroots' "which screen is at this point" answers for a dark screen as readily as a lit one, so saved window geometry kept re-homing windows onto a blanked laptop panel — the application opened, took focus, and was invisible. A detached output is removed from the layout now, and the windows on it are swept to a surviving screen, the same way an unplugged monitor's are.

HDR

Shift+D in the display panel drives the selected monitor in HDR10, on a monitor and a mode that will take it. The column beside each screen says which will:

Column What it means
HDR10 ON this screen is being driven in HDR right now
HDR10 it can be, and is not
HDR10 (—) the panel advertises HDR, and this cable or refresh rate will not carry it
(blank) an SDR panel

[ and ] move the SDR white level, 203 cd/m² by default. HDR measures brightness in real units rather than as a fraction of what a panel can do, so the desktop has to be told where its white goes. It is not a brightness control: it decides only where ordinary windows sit inside an HDR signal, which is what makes the desktop look right beside an HDR video instead of washed out next to it. 203 is the broadcast reference level and a sensible place to start; move it if white looks dim or glaring against HDR content.

Both the mode and the level are remembered per monitor, in outputs.conf, and restored at the next login only if that connector still accepts them.

From a script:

synctl hdr                        # what every screen will accept
synctl hdr on  DP-3               # drive it in HDR10
synctl hdr off DP-3
synctl hdr white DP-3 250         # cd/m², 80–600

Turning it on can fail — a cable, a refresh rate, or a monitor that will not carry the signal — and it answers with an error rather than a setting that quietly did nothing.

What is driven is the signal. The display is told it is receiving HDR10 and the desktop is mapped into it correctly, with 10-bit colour switched on alongside so dark gradients do not band. The desktop itself is still composited in 8-bit sRGB, so an HDR video does not gain highlights it did not have — that needs colour management inside the renderer and is not here. On a monitor that will only accept a BT.2020 container, colours run wide; the line under the monitor list says so when that is what happened.

Night light works on a screen in HDR, and warms it by the same amount as the screen next to it.

Screen audio

hdmi_audio = auto moves audio to a screen that can take it — on by default where it is wanted (a machine with a battery) and off where it is a nuisance (a desk whose monitors never leave). synui-hdmi-audio(1) does the graph work.

It keys off the ALSA ELD, never the sink name. "Switch to the sink with hdmi in its name" is the obvious rule and it is wrong: a GPU advertises an HDMI sink per pin whether or not anything is plugged into it. A pin with a display that can take audio reports monitor_present 1 and eld_valid 1, and carries the display's own name.

It waits for the sink rather than checking once — the ELD fill and wireplumber's profile switch take a second or two after the connector appears — and it will not move audio off a sink you chose by hand since it last acted.


Layouts

Super+Tab cycles the current desktop through seven layouts, in this order, and a toast names the one you land on:

tiling → floating → monocle → AI → niri → spiral → cascade → back to tiling

niri is scrollable tiling: one endless horizontal strip of columns per desktop and monitor, scrolled so the focused column is on screen. A new window does not shrink the others — the strip just gets longer. Super+, pulls the focused window into the column on its left and Super+. pushes it back out into a column of its own; Super+H / Super+Shift+L set a column's width, the same keys that size the master area on tiling.

Each of the nine desktops has its own layout, so you can keep one tiled and another floating — and the choice survives a restart. It is written the moment you change it and read back at startup, per desktop.

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.

The welcome guide names all seven on its Layouts page (Super+Escape, or synui-welcome page 3), in the order the key walks them.

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.
niri Scrollable tiling: an endless horizontal strip of columns, scrolled to the focused one. A new window lengthens the strip instead of shrinking the others. See below.
Spiral Fibonacci tiling. Each window takes half of what is left, the cut alternating and the side rotating clockwise, so the windows wind inward. Past three windows it trades area for shape: master-stack's slots get shorter without getting narrower, the spiral's stay roughly between 1:1 and 2:1. Its smallest window is smaller, not bigger — pick it when you want windows you can use, not when you want the last one to be roomy.
Cascade Overlapping cards, each offset down-and-right so every titlebar stays reachable, dealt into several piles rather than one long slide off the desk. The only layout whose windows overlap on purpose. Super+Shift+Y goes straight there.

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

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+F is 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, niri and AI ignore it, because they place windows themselves.

niri

Scrollable tiling. Instead of dividing the screen up, it lays your windows out in one endless horizontal strip of columns — per desktop and per monitor — and scrolls the strip so the focused column is on screen.

The point is what happens when you open something: a new window does not shrink the others. It gets a fresh column beside the one you were in and the strip simply gets longer, so a column is the same width whether you have two windows or ten. On tiling, every new window takes space off the stack.

  • Super+, pulls the focused window into the column on its left, and Super+. pushes it back out into a column of its own. Those two are the only moves that are not just walking along the strip, and they are what columns are for — stack a terminal under an editor, then pull them apart.
  • Super+Shift+J / Super+Shift+K walk the strip; the normal focus keys move the focus and the strip scrolls to follow.
  • Super+H / Super+Shift+L set the focused column's width — the same keys that move the master split on tiling.
  • You never see half a column. A column that does not fit entirely on the monitor is not drawn at all, rather than being cut off at the edge. On a multi-monitor desk a partially drawn column would spill onto the screen next door, so it waits until the strip scrolls it fully into view.
  • Like tiling and AI, niri places windows itself, so it ignores remembered per-app geometry.

Animations

Two things animate, and each is its own setting — in the control panel under Windows ▸ Animation, or in synuirc.

Setting Values Default
anim_window off, fade, rise (fades and glides up into place) fade
anim_window_ms 0–1000 ms; 0 is off. Also times the niri strip slide 140
anim_rise_px how far a rising window travels 24
anim_workspace off, fade (cross-fade), slide, cube fade
anim_workspace_ms 0–1000 ms; a slide wants longer than a fade, a cube longer again 140
anim_curve ease-out, linear, ease-in-out, ease-in — shared by both ease-out

Slide sends both desks off in the direction you switched: going to a higher-numbered desktop sends the old one off to the left, the way a pager reads. The windows keep full opacity while they go — they are leaving, not dissolving.

Cube turns the whole desk about a vertical axis. The desktop you are leaving and the one you are arriving at are two faces of a cube meeting at a right angle, on black, shaded so the corner between them reads, pulled back far enough that the turn fits on the screen. Give it 400–600 ms; at 140 it is over before the eye has followed it.

It is a different kind of animation from the other three and works differently. They move each window's frame, which the scene graph can do; a cube has to turn the whole picture in perspective, which it cannot. So the compositor takes the frame instead: it photographs the desktop being left, renders the incoming one live, and draws both as two surfaces through a GLES2 program of its own. Two consequences worth knowing:

  • The CRT filter is off for the length of the turn. Both are full-screen passes over the same buffer and only one can have it. It comes back when the desk lands.
  • A driver that cannot compile the shader gets an un-animated switch, not a broken one. Every failure path in the cube ends the turn and hands the frame back to the ordinary path.
  • A rotated monitor still turns about the axis you see as vertical. The compositor renders a 90°/270° screen into a buffer that is on its side, so a cube built out of buffer coordinates would roll like a drum on a portrait panel; the shader works in screen coordinates instead.

The turn begins and ends at exactly the picture an un-animated switch would draw, corner for corner, which is what lets it run on every switch rather than only on some of them.

The curve is deliberately shared rather than per-event. Two easings on one desktop read as two different desktops, and the niri strip slide is on it too.

A window closing is never animated, and cannot be here: the client's buffer is gone the moment it unmaps, so there is nothing left to fade. Nothing resizes a window to animate it either — that would re-configure the client every frame — so what moves, moves at a fixed size.

animation_ms still works and sets both lengths at once; it is what these two replaced.

Desktops and monitors

There are nine desktops, on Super+19 or a four-finger swipe left and right on a touchpad, and Super+Shift+19 sends the focused window to one. What that means on a desk with more than one monitor is a setting: Windows ▸ Desktops span in the control panel, workspace_mode in synuirc.

Value What a switch moves
shared (default) The whole desk. A desktop is one virtual desktop across every monitor, the way KDE, GNOME and Windows do it: Super+2 changes every screen at once
per-monitor One screen. Each monitor remembers the desktop it is showing, and the switch moves only the monitor the focus is on

What does not change between them is what a desktop is. Its window list still spans the desk and each window still records the monitor it sits on, so Super+O (move to the next monitor) and Super+Shift+2 (move to another desktop) stay the two independent axes they always were. per-monitor only removes the rule that every screen has to be looking at the same one.

Two monitors showing the same desktop is a perfectly good state under per-monitor, each drawing its own share of it. That is what keeps the keys honest: the desktop you ask for is never one another screen has claimed, so Super+2 always does what it says instead of finding the number taken.

Switching the mode back to shared brings the desk together again — every monitor returns to the desktop the focused one is on, with nothing stranded on a screen that is no longer showing it.

The bar follows. Each screen's row of desktop pills highlights the desktop that screen is showing, so a split desk reads correctly at a glance, and clicking a pill moves the monitor whose bar you clicked — the switch acts on the screen the pointer is on. Both shipped bars do this.

Per-app window geometry

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:

  1. The geometry table was written but never read for two pkgrels — the persist path looked complete from the writing side alone.
  2. 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.

The table answers a question about opening a window, and only that. Its coordinates are absolute, so an entry names a monitor as much as a position — and the entry is written when the app last closed. Leaving fullscreen used to consult it, which on a laptop plugged into a television meant un-fullscreening a video threw the window back onto the built-in panel, because that is where the browser had last been shut down. A window coming out of fullscreen now goes back to the box, and the screen, it had before it went in — nothing is looked up.


See also: Wallpapers, Window Effects, Sound Themes, Cursor Themes, synui, Keybindings.