Layer::Window overlays: an OverlaySpec can now be an ordinary xdg toplevel, named through App::overlay_title; showcase persists the last pressed button too
CI / build + test (push) Has been cancelled
CI / cargo audit (push) Has been cancelled

A shell built on ltk had no way to show something as a regular window: every overlay is a layer-shell surface, and layer-shell surfaces are either below all application windows or above all of them. crustace's "closing applications…" card ran into exactly that — on the overlay layer it covered the applications' own "save changes?" prompts, on the bottom layer it vanished behind their windows — and what that card wants is to be one window among the others: decorated by the compositor, stackable, listed in the switcher and the dock.
`Layer` gains a `Window` variant. An `OverlaySpec` carrying it is materialised by the reconciler as an `xdg_toplevel` (sctk `Window`, server-side decorations) instead of a layer surface: `size` is its fixed size, applied through min/max size (a zero component falls back to a default, since a toplevel cannot "fill"); anchor, exclusive zone and keyboard exclusivity are ignored. The window's app_id is `App::app_id()` and its title comes from the new, defaulted `App::overlay_title( id )`, so the compositor's window lists show something meaningful. `WindowHandler::configure` and `request_close` now resolve which surface a window belongs to: the main window keeps its behaviour, an overlay window is configured through its own `SurfaceState` (with the window geometry set to the configured size) and the compositor's close button delivers the spec's `on_dismiss` instead of exiting the app. Layer-shell applications now bind `xdg_wm_base` when the compositor offers it, so they can open such a window later. Adding a variant keeps every existing `OverlaySpec` literal compiling; the new trait method has a default.
The showcase example now also saves and restores `last_pressed`, bumping its private state format to version 2 with the note kept last so its line breaks survive.
This commit is contained in:
2026-08-15 17:56:06 +02:00
parent ccf07de593
commit 3046d86337
6 changed files with 71 additions and 6 deletions
+13
View File
@@ -48,6 +48,13 @@ pub enum Layer
Background,
/// Below normal windows but above background.
Bottom,
/// Not a layer-shell surface at all: an ordinary `xdg_toplevel`
/// window stacked among the applications, decorated and listed by
/// the compositor like any other. [`OverlaySpec::size`] is its fixed
/// size (`0` falls back to a default, it cannot "fill"); anchor,
/// exclusive zone and keyboard exclusivity are ignored. The
/// compositor's close button delivers [`OverlaySpec::on_dismiss`].
Window,
/// Above normal windows (panels, docks).
Top,
/// Above everything (notifications, on-screen displays).
@@ -66,6 +73,8 @@ impl Layer
Layer::Bottom => WlrLayer::Bottom,
Layer::Top => WlrLayer::Top,
Layer::Overlay => WlrLayer::Overlay,
// Never reaches layer-shell; the reconciler creates a window first.
Layer::Window => WlrLayer::Top,
}
}
}
@@ -520,6 +529,10 @@ pub trait App: 'static
/// IDs that disappear cause the surface to be destroyed.
fn overlays( &self ) -> Vec<OverlaySpec<Self::Message>> { Vec::new() }
/// Title of a [`Layer::Window`] overlay, shown in its decoration and
/// in the compositor's window lists. Default: the [`app_id`](Self::app_id).
fn overlay_title( &self, _id: OverlayId ) -> Option<String> { None }
/// Describe the input-transparent child surfaces composited over the main
/// surface this frame. Each becomes a `wl_subsurface` the compositor moves
/// by position; see [`SubsurfaceSpec`]. Diffed across frames by