diff --git a/meson.build b/meson.build index 98afc98fd..f2b7f2c85 100644 --- a/meson.build +++ b/meson.build @@ -127,6 +127,7 @@ if scdoc.found() 'sway/sway-output.5.scd', 'swaybar/swaybar-protocol.7.scd', 'swaymsg/swaymsg.1.scd', + 'swaysavetree/sway-save-tree.1.scd', ] if get_option('swaynag') diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 952d243d2..a56ec5c0f 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -414,6 +414,46 @@ set|plus|minus|toggle The following commands may be used either in the configuration file or at runtime. +*append_layout* + Appends the container tree described by the JSON file at _path_ to the + currently focused workspace. Useful for restoring a saved layout: each + leaf container in the JSON is a _placeholder_ with a *swallows* array of + matchers; when a window opens whose properties match an unmatched + placeholder, sway installs that window into the placeholder's slot + instead of the usual focus-based placement. + + The format mirrors i3's, with one extension: in addition to i3's + *class*, *instance*, *title*, *window_role*, and *window_type* keys + (which target xwayland views), each *swallows* entry may include + *app_id* to match Wayland views. The *machine* key is logged and + ignored. All values are PCRE2 regex strings. + + A minimal example targeting one Wayland and one xwayland window in + a vertical split: + +``` +[ + { + "layout": "splitv", + "nodes": [ + { "swallows": [{ "app_id": "^foot$" }] }, + { "swallows": [{ "class": "^Firefox$" }] } + ] + } +] +``` + + The companion command-line tool *sway-save-tree*(1) generates such + files from a live workspace. The i3-save-tree(1) concatenated-object + output form is also accepted. + + Floating placeholders (the *floating_nodes* JSON array) are not + supported in this release; entries are skipped with a debug-log entry. + Placeholder match runs before *assign* rules: an explicit slot wins + over workspace assignment. *for_window* rules still run on the + swallowed view after placement. If multiple placeholders match the + same incoming view, the depth-first, document-order first match wins. + *assign* [→] [workspace] [number] Assigns windows matching _criteria_ (see *CRITERIA* for details) to _workspace_. The → (U+2192) is optional and cosmetic. This command is diff --git a/swaysavetree/sway-save-tree.1.scd b/swaysavetree/sway-save-tree.1.scd new file mode 100644 index 000000000..7d00902ae --- /dev/null +++ b/swaysavetree/sway-save-tree.1.scd @@ -0,0 +1,52 @@ +sway-save-tree(1) + +# NAME + +sway-save-tree - Dump a workspace's tiling tree as append_layout-compatible JSON. + +# SYNOPSIS + +_sway-save-tree_ --workspace + +# DESCRIPTION + +Reads the live tree of the running sway instance over the IPC socket, walks +the named workspace, prunes runtime fields, and emits a JSON document +suitable for *swaymsg append_layout*(5). Each leaf view becomes a +placeholder entry whose *swallows* array contains a regex-anchored match on +the view's *app_id* (Wayland) or *class* / *instance* (xwayland). + +The output is sent to standard output. Pre-existing placeholders that were +loaded by *append_layout* and have not yet swallowed a window are echoed +verbatim from their *swallows* array. + +This is the sway counterpart of i3-save-tree(1). + +# OPTIONS + +*--workspace* + Name (or number, as a string) of the workspace to dump. Required. + +*-h, --help* + Show help and exit. + +# LIMITATIONS + +Floating windows are skipped in this release; only tiling children of the +workspace are emitted. A warning is printed to stderr when floating windows +are present. + +# EXAMPLES + +Save the layout of workspace 1 to a file, kill the running windows, and +restore the layout: + +``` +$ sway-save-tree --workspace 1 > /tmp/layout.json +$ swaymsg [workspace=1] kill +$ swaymsg append_layout /tmp/layout.json +``` + +# SEE ALSO + +*sway*(5), *sway*(1), *swaymsg*(1)