Add Nebula.Windows with Sway IPC backend

Introduces a new `core/windows` module (`Nebula.Windows`) with `WindowService`, window/workspace models, and a Sway IPC backend for live window tracking and control (focus, close, move/resize, snap, maximize/restore, minimize, workspace switch). The desktop shell now links this module, uses compositor focus for top-bar active app text, and adds an Open Windows section in the launcher with focus/close actions.

Also updates application metadata handling to parse `StartupWMClass` and map window `app_id`/class to friendly names and icons, and revises Sway config/docs for the new floating-first Desktop 0.2 behavior with temporary compositor-provided decorations.
This commit is contained in:
2026-08-26 18:20:56 +12:00
parent 8c07c10050
commit 2f59d3c115
29 changed files with 2177 additions and 35 deletions
+29 -6
View File
@@ -5,14 +5,15 @@ Sway is the **temporary** Wayland compositor while Nebula Desktop is developed.
Sway currently provides:
- Wayland compositor
- application window management
- floating-first application window management
- temporary title bars and borders on normal application windows
- XWayland
- input and the pointer cursor
- output handling
Nebula provides the visible shell (Qt Quick/QML via LayerShellQt). The Sway config must not enable a Sway bar.
Nebula provides the visible shell (Qt Quick/QML via LayerShellQt) and logical window management through `WindowService` (`core/windows`). The Sway config must not enable a Sway bar.
A custom Nebula compositor is a later milestone. Do not treat this Sway setup as the final architecture.
A custom Nebula compositor is a later milestone. Do not treat this Sway setup as the final architecture. QML must not call `swaymsg`; the Sway IPC backend is the only Sway-specific code, and it is isolated so it can be replaced.
```text
Ubuntu/Linux
@@ -26,6 +27,19 @@ Nebula Shell
Qt Quick/QML
```
## Floating-first session
Ordinary application windows open as floating windows, sized to about **70% of the current workspace** (the usable output area below the 40px Nebula top bar) and centred. Sway workspace geometry already excludes the top-bar exclusive zone, so placement stays on-screen at any resolution.
Rules match only normal application views:
- Wayland: `shell="xdg_shell"` (`app_id`)
- XWayland: `shell="xwayland"` (`class`)
Layer-shell surfaces (Nebula desktop, top bar, launcher, overlays) are a different shell and are not matched. They stay on BACKGROUND / TOP / OVERLAY.
Sway draws a restrained title bar and border on those application windows so they can be identified, dragged, and resized with the mouse. This is **temporary**. Custom Nebula decorations, CSD, and wrapping Wayland clients inside QML are out of scope.
## Development session
From the NebulaOS repository root:
@@ -50,7 +64,7 @@ NEBULA_SHELL_AUTOSTART=0 sh compositor/sway/dev/run-sway-vm.sh
### Output / resolution
The development config uses scale `1` and does not pin a resolution. Sway uses the output's preferred mode, which follows the current display size (including VMware Autofit Guest).
The development config uses scale `1` and does not pin a resolution. Sway uses the output's preferred mode, which follows the current display size (including VMware Autofit Guest). Window sizes use workspace-relative percentages, not hard-coded pixel dimensions.
```bash
swaymsg -t get_outputs
@@ -69,15 +83,24 @@ Requires `adwaita-icon-theme`. A Nebula-branded cursor theme is a later task.
`WLR_NO_HARDWARE_CURSORS=1` is VMware-specific and is set by `run-sway-vm.sh`, not by production session files.
### Emergency shortcuts
### Emergency / development shortcuts
Normal launching, focusing, and closing is done from the Nebula GUI. These remain compositor fallbacks:
| Shortcut | Action |
|----------|--------|
| Super+Enter | open Foot |
| Super+Left Mouse | move the floating window under the pointer |
| Super+Right Mouse | resize the floating window under the pointer |
| Super+Left | snap to left half of the usable area |
| Super+Right | snap to right half of the usable area |
| Super+Up | maximise to the usable area (below the top bar) |
| Super+Down | restore to the default ~70% centred size |
| Super+Shift+Q | close the focused window |
| Super+Shift+E | exit Sway |
| Super+Shift+C | reload Sway config |
Normal application launching is done from the Nebula launcher, not these shortcuts.
Title-bar drag and border resize should be the normal mouse path. Super+mouse is an emergency convenience.
### Rendering
+76 -7
View File
@@ -5,6 +5,11 @@ set $term foot
#
# Sway is invisible infrastructure. Nebula Desktop is the visible shell.
# Do NOT add a bar block; Nebula provides its own top bar.
#
# Nebula Desktop 0.2 is floating-first: ordinary application windows open
# as independently movable/resizable floating windows, not tiled to fill
# the workspace. Sway remains the temporary compositor/window manager.
# Custom Nebula window decoration is later work.
# -----------------------------------------------------------------------------
# Output / resolution
@@ -28,6 +33,76 @@ seat * xcursor_theme Adwaita 24
# WLR_NO_HARDWARE_CURSORS=1 sway -c compositor/sway/nebula-sway.conf
# compositor/sway/dev/run-sway-vm.sh sets that automatically.
# -----------------------------------------------------------------------------
# Focus / pointer
# -----------------------------------------------------------------------------
# Do not warp the pointer when focusing windows; this is a mouse-first desktop.
mouse_warping none
focus_follows_mouse yes
# -----------------------------------------------------------------------------
# Temporary window decorations
# -----------------------------------------------------------------------------
# Sway draws a restrained title bar and border on normal application windows
# so they can be identified, dragged, and resized with the mouse.
#
# This is temporary infrastructure. Nebula does not yet own client/server-side
# decorations. Do not treat these colours or metrics as the final design.
#
# Layer-shell surfaces (desktop, top bar, launcher) are not xdg_shell/XWayland
# views and are not decorated by these settings.
font pango:Ubuntu 10
titlebar_padding 7 3
titlebar_border_thickness 1
default_border normal 1
default_floating_border normal 1
hide_edge_borders none
# class border backgr. text indicator child_border
client.focused #3d4d62 #1a222e #e8ecf2 #7ea0c4 #3d4d62
client.focused_inactive #2a3342 #141a24 #8e99ab #2a3342 #2a3342
client.unfocused #1a2029 #10151c #6b7587 #1a2029 #1a2029
client.urgent #c98888 #1a222e #e8ecf2 #c98888 #c98888
client.placeholder #1a2029 #0b0f16 #6b7587 #1a2029 #1a2029
client.background #0b0f16
# -----------------------------------------------------------------------------
# Floating-first application windows
# -----------------------------------------------------------------------------
# Match only ordinary application views:
# Wayland → shell="xdg_shell" (app_id)
# XWayland → shell="xwayland" (class)
#
# Layer-shell clients (Nebula desktop, top bar, launcher, overlays) are a
# different shell and are not matched. They stay on BACKGROUND / TOP / OVERLAY.
#
# Size is a percentage of the *workspace* (ppt). Sway workspace geometry
# already excludes the 40px Nebula top-bar exclusive zone, so 70% × centred
# stays in the usable work area on any resolution. Do not hard-code pixels.
for_window [shell="xdg_shell"] floating enable, border normal, resize set width 70 ppt height 70 ppt, move position center
for_window [shell="xwayland"] floating enable, border normal, resize set width 70 ppt height 70 ppt, move position center
# -----------------------------------------------------------------------------
# Mouse move and resize
# -----------------------------------------------------------------------------
# Title bar: drag. Window edges: resize.
# Development fallback (does not replace title-bar interaction):
# Super + Left Mouse → move
# Super + Right Mouse → resize
floating_modifier $mod normal
# -----------------------------------------------------------------------------
# Development snap shortcuts
# -----------------------------------------------------------------------------
# Preparation for later Snap Layouts. Keyboard is not the only way to arrange
# windows; the mouse still moves and resizes floating windows directly.
# Percentages are workspace-relative (usable area below the top bar).
bindsym $mod+Left resize set width 50 ppt height 100 ppt, move position 0 ppt 0 ppt
bindsym $mod+Right resize set width 50 ppt height 100 ppt, move position 50 ppt 0 ppt
bindsym $mod+Up resize set width 100 ppt height 100 ppt, move position 0 ppt 0 ppt
bindsym $mod+Down resize set width 70 ppt height 70 ppt, move position center
# -----------------------------------------------------------------------------
# Nebula shell autostart
# -----------------------------------------------------------------------------
@@ -46,12 +121,6 @@ exec /bin/sh scripts/run-nebula-vm.sh
# Emergency development shortcuts (not the normal UX)
# -----------------------------------------------------------------------------
bindsym $mod+Return exec $term
bindsym $mod+Shift+q kill
bindsym $mod+Shift+e exec swaymsg exit
bindsym $mod+Shift+c reload
# Remove Sway window decorations
default_border pixel 0
default_floating_border pixel 0
# Basic floating controls for development
floating_modifier $mod normal