Commit Graph
9 Commits
Author SHA1 Message Date
ZacharyZhang-NY a9b39710a2 Add Simplified Chinese as a system language
The installer asks for the language before the keyboard, and
Setup > Language (omarchy language en|zh) switches it later. Under
zh_CN the menu reads its labels from omarchy-menu.zh-cn.jsonc, the
shell from I18nZh.js through I18n.tr, and notifications are worded
by their sender through omarchy-text, which reads the same table.
User text is never translated.
2026-10-12 02:56:40 -04:00
1498718969 Add a floating mode with titlebars to the workspace layout cycle (#14482)
* Let the workspace layout test's Lua assertions fail the suite

Lua 5.5's standalone interpreter exits 0 when the script that raised the error came in on stdin, and exits 1 for the same error in a script file. The block here was piped in through a heredoc, so every assertion in it reported as passing however wrong the value was: changing the expected layout to one the toggle never writes still left the file green.

* Add a floating mode to the workspace layout cycle

Super + L cycled a workspace between dwindle and scrolling. It now carries on into floating, where every window on the workspace floats.

Floating cannot be a third `layout` on the workspace rule. Hyprland has no layout by that name and accepts one anyway: `hl.workspace_rule({ layout = "floating" })` returns ok and silently leaves the workspace on dwindle, exactly as a misspelt name does. So the mode floats the windows themselves, through the same `float` dispatcher SUPER + T uses.

Ending the mode has to tile the windows the mode floated and only those, so each one is tagged with `omarchy-mode-floated`. A window already floating when the mode reaches it -- an app with a float rule of its own, a dialog, one popped out with SUPER + T -- is left unclaimed and is still floating when the mode ends. The tag lives on the window rather than in a table here: it dies with the window, follows it between workspaces, and survives the config reload that plugging in a monitor performs, none of which a table on this side would do. A pinned window is left alone entirely, because tiling one unpins it as well.

Windows arrive on a workspace three ways and a window rule only covers one of them, so the mode watches events: window.open for what opens there, window.move_to_workspace for what is carried in, and the same event for what is carried back out, which gives up the floating the mode gave it rather than staying floating on a workspace that tiles. Every tiled window is claimed before any of them is floated, because floating one member of a group floats the rest, and claiming as it went would find those already floating and leave them stranded.

The mode is read back from the saved file rather than from the compositor. Hyprland reports a workspace's tiled layout and floating is not one, so a floating workspace still answers dwindle or scrolling; trusting that answer would skip a step of the cycle. A file saved before floating existed names a layout rather than a mode and falls through to what Hyprland reports, so the cycle keeps working and the next press rewrites it.

Two faults in the old script had to go first, because saving the mode makes both persistent. Named workspaces report a negative id, which passed the `^-?[0-9]+$` guard, and Hyprland reads a leading "-" as a selector relative to the current workspace: pressing Super + L on a named workspace reconfigured workspace 1 instead, and would now save a file that did it again at every login. And the saved state was written under $HOME/.local/state while the Hyprland side reads XDG_STATE_HOME, which also had to reach package.path: the loader lists that directory but loads the files by module name, so a state home anywhere else listed the saved layouts and then loaded same-named ones from the home directory.

Saving is checked too. The mode reaching the compositor and the mode reaching disk are separate things that can fail separately, and a save that failed silently would leave the next press reading a file that never got written, cycling between two modes and never reaching the third.

The guard against named workspaces stops new files being written, but an earlier version already wrote them, and they go on being loaded at every login. A migration removes the saved layouts named for a negative id.

The keyword fallback is gone. `hyprctl keyword` refuses a Lua configuration outright -- "keyword can't work with non-legacy parsers. Use eval." -- and exits 0 while doing so, so as a fallback it neither worked nor reported that it had not. A failed apply now says so and saves nothing, rather than announcing a layout the screen does not show and restoring it at the next login.

Co-Authored-By: Codex XHigh <noreply@openai.com>

* Add titlebars, edge snapping, and a window Shelf to floating workspaces

Floating workspaces become a traditional desktop that works with every
theme. Windows get themed titlebars from the omarchy-hyprland-titlebars
plugin, which is loaded only while something floats. Dragging a titlebar
to the left or right edge snaps the window to that half, and dragging it
to the top or double-clicking maximizes it. The window floating mode
places is sized, centered, and cascaded, and floating workspaces focus
on click.

Super + M, or the minus button, sets a window aside on the Shelf, which
works from any workspace and restores the window onto the current one
in that workspace's layout. Float All Workspaces makes floating the
default while Super + L still sets a single workspace's layout.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Bring resize on border to tiling too

* Fix floating mode cleanup, fullscreen windows, and failed Shelf notes

Turning Float All Workspaces off with no workspace layouts left behind
started nothing to give the floated windows back. A window fullscreen
when its workspace began floating now floats once it leaves fullscreen.
A window whose Shelf note cannot be saved stays where it is, and the
titlebars read the theme from where omarchy-theme-set writes it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Place the Shelf on the bar once, instead of on every minimize

Putting it back on each minimize kept a Shelf the user moved where they
put it, but re-added one they had removed. A migration places it once for
existing bars; Super + Alt + M opens the Shelf either way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Raise titlebars off the window background

A titlebar in the theme's background color ran into the window under it.
It takes the theme's lighter background, the raised surface every theme
defines, and the selection color on themes that make the two the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop minimizing and edge snapping from floating workspaces

A floating workspace is now titlebars with maximize and close, and nothing
else. The Shelf (its bar widget, panel, commands, notes, Super + M and
Super + Alt + M) goes with the minimize button, and the titlebar plugin's
edge snapping is left off, along with the shell's snap preview.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Stop describing the titlebar package as snapping

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Name web app windows in their launchers

Chromium names a web app window after its URL, and titles it with the page
title or just the domain. StartupWMClass ties the window to its launcher,
so the titlebar plugin can show the launcher's Name instead: WhatsApp
rather than web.whatsapp.com. New web apps, the shipped ones, and existing
launchers (through a migration) all carry it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop the titlebar package comment from the base list

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Show the workspace layout in the bar and cycle it on click

The focused workspace's mark is a square for dwindle, a triangle for
scrolling, and a circle for floating, and clicking it cycles the layout
as Super + L does. Both layout toggles ask the bar to read the new mode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Show scrolling as a circle and floating as a triangle

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Move the look of the desktop to Trigger > Appearance

Menu Bar, Battery Percentage, Workspace Layout, Window Gaps, Animations,
and 1-Window Ratio change how the desktop looks rather than switching a
behavior, so they leave Trigger > Toggle for their own menu.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Choose a default workspace layout instead of floating everything

Trigger > Appearance > Workspace Layout sets the layout of every workspace
without one of its own: Tiling, Scrolling, or Floating. A tiled default
is Hyprland's own layout, and a floating one is the floating mode. It
replaces Float All Workspaces, which also overrode and set aside the
layouts workspaces had been given with Super + L.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Title the workspace layout menu Default Workspace Layout

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Use the animation icon for Appearance > Animations

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Open clipboard history from Trigger

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Leave edge resizing to looknfeel on floating workspaces

looknfeel now resizes from borders everywhere, so floating workspaces
only need to switch pointer focus to click.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Convert saved workspace layout rules to modes

Released versions saved a workspace's layout as a plain workspace rule,
which names no mode, so a floating default would override a workspace
set to scrolling, and the bar and Super + L would misread it. A migration
rewrites those files as modes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Cycle workspace layouts backwards with Super + Alt + L

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Test the Trigger > Appearance split and Clipboard History placement

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Decode escaped web app URLs before naming their windows

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Describe the workspace widget's layout mark and click

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Let a workspace cycled onto the default follow it again

Once Super + L gave a workspace a layout of its own, it kept it for good,
so a later change of the default never reached it. Cycling onto the
default layout now forgets the workspace's own instead of saving it.
Without a saved default, the default is Hyprland's own layout, which
the user's looknfeel may have set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: David Heinemeier Hansson <david@hey.com>
Co-authored-by: Codex XHigh <noreply@openai.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 08:20:45 +02:00
David Heinemeier HanssonandClaude Fable 5 2c8639ffbd Persist workspace layout toggles across Hyprland reloads
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 21:03:43 -07:00
David Heinemeier Hansson 4e2da8480a Standardize all notification sending 2026-05-17 19:51:29 +02:00
Ryan Hughes c101591284 Replace mako with quickshell-backed notification daemon
Adds first-party omarchy.notifications service plugin that hosts a
freedesktop notification server and renders popups + a history popup
inside the shell. Uninstalls mako and retargets every helper, keybind,
indicator, and migration entry to the new daemon.

Plugin (default/quickshell/omarchy-shell/plugins/notifications/):
- Service.qml: NotificationServer, popupModel + pendingModel + pastModel
  (two-tier history, see below), DND via PersistentProperties +
  cache-file backstop, image cache for /tmp screenshots, IpcHandler with
  toggleDnd/setDnd/isDnd/showHistory/clear/clearPending/markAllSeen/
  dismissAll/dismissOne/invokeLast/dismiss, per-theme override file
  ~/.config/omarchy/current/theme/notifications.json honoring
  borderColor/backgroundColor/textColor/countdownColor.
- components/NotificationCard.qml: theme-driven card (Color.foreground/
  background/border tokens from Commons/Color.qml), 32x32 icon slot,
  Nerd Font glyph fallback via omarchy-glyph hint, hero image strip
  for screenshot/image-path notifications, hover-pause progress bar,
  uses bar.fontFamily so all surfaces share one font.

Filtering and DND:
- transient hint and CLI-style senders (app_name in notify-send /
  omarchy-action) bypass history but still pop.
- DND only allows omarchy-action toasts and notify-send -u critical
  through; real-app urgency=critical (Discord, Slack, Vesktop) is
  silenced and lands in pending instead.
- Pending vs past split surfaced via tabs in the bar widget popup;
  past tab is auto-pruned at the 15-minute mark.
- Click-to-jump: notifications without a libnotify default action focus
  the matching Hyprland window via class lookup.

Shell host:
- shell.qml: generic first-party service loader (mirrors the existing
  noctalia-compat path) and an alias for the bar so plugins can read
  barSize / barHidden / position for anchoring.
- Commons/Color.qml: parses the theme's hyprland.conf for
  $activeBorderColor so notifications match Hyprland window borders;
  picks the explicit accent= key over the color4= alias.

Bar widget rebase (plugins/bar/widgets/notificationCenter.qml):
- Drops the chunk-1 stub server, binds count/dnd state to the service,
  hosts the history popup via PopupCard so it drops down from the
  notification glyph the same way Quick Settings does.
- Pending/Past tabs, dismiss-individual close X, mark-all-as-seen and
  clear-recent action buttons, theme-driven palette.

Quick Settings rework (plugins/bar/widgets/controlCenter.qml):
- DND tile binds directly to service.doNotDisturb for instant feedback.
- Drops the volume slider (already in audioPanel) and the no-op Theme
  tile; adds a Bluetooth toggle bound to Quickshell.Bluetooth.
- Bigger 44x44 wallet was scaled back to 32x32 for tighter rows.

Notification scripts (bin/omarchy-*):
- omarchy-notification-send: passes glyph as a custom hint instead of
  prepending to the summary; adds -a omarchy-action and -u urgency
  automatically; supports -e/--transient passthrough.
- User-action toasts in the capture / toggle / hyprland / default-*
  scripts and bindings/utilities.lua now tag themselves
  -a omarchy-action so DND treats them as intent-based bypass.
- omarchy-toggle-notification-silencing, omarchy-notification-dismiss,
  default/waybar/indicators/notification-silencing.sh, and the Hyprland
  comma-keybinds all route through omarchy-shell-ipc notifications.
- omarchy-capture-screenshot / -screenrecording set the image-path
  hint properly so the hero-image rendering kicks in.

Mako removal (migrations/1778743515.sh):
- pkill -x mako, systemctl --user stop mako.service, pacman -Rns mako
  (uninstalling deletes /usr/lib/systemd/user/mako.service so D-Bus
  activation can't respawn it). Removes ~/.config/mako/ and the legacy
  toggle file. Restarts quickshell so it claims the bus name.
- Drops mako from install/omarchy-base.packages, autostart.lua,
  install/config/theme.sh + toggles.sh, default/themed/mako.ini.tpl,
  default/mako/, the omarchy-menu Mako restart row, bin/omarchy
  GROUP_DESCRIPTIONS, the settings panel catalogue, and the
  default/omarchy-skill paths table.
- Removed scripts: bin/omarchy-restart-mako,
  bin/omarchy-style-corners-mako.
- bin/omarchy-style-corners summary updated; corner radius for the
  notification card reads ~/.local/state/omarchy/toggles/quickshell-menu.json
  alongside the rest of the shell.
2026-05-14 14:21:07 -04:00
Ryan Hughes 804571d8e2 Update all hyprland references to new lua ones 2026-05-11 10:40:26 -04:00
Ryan HughesandDavid Heinemeier Hansson d2a4cc0c4d Add omarchy CLI (#5477)
* Add omarchy CLI

* Remove outdated or internal

* Add bash completions for command

* Add omarchy command documentation

* Add missing docs

* Correct to what's now right

* Fix tests

---------

Co-authored-by: David Heinemeier Hansson <david@hey.com>
2026-05-01 17:40:22 +02:00
Patrick Bochenek 58a16dfebc Set low urgency for immediate-feedback notifications (#5056)
Some users may choose to disable notification timeout for normal-level
notifications to ensure no notifications are missed when the user is
away from the screen. However, there are several Omarchy notifications
that only serve as an immediate feedback for a user action, such as
"Screensaver enabled" or "Editing config file foo.conf", for which
disabling the timeout is not desirable. This commit drops the urgency
level for such notification to low, allowing configuring a different
timeout value for them.

Notifications with an explicitly set timeout are excluded from this
commit.
2026-03-24 14:56:12 +01:00
David Heinemeier Hansson 42a437ad48 Add toggle for switching between dwindle/scrolling layout per workspace on Super + L 2026-02-28 14:23:42 +01:00