feat: show greeter UI on all monitors, not just one (v0.8.0)
All checks were successful
Update PKGBUILD version / update-pkgver (push) Successful in 3s
All checks were successful
Update PKGBUILD version / update-pkgver (push) Successful in 3s
Wayland surfaces belong to exactly one output — mirroring is not an option. Create one full greeter window per monitor via set_monitor(), with only the first receiving KeyboardMode::Exclusive. Removes the old wallpaper-only secondary windows. Matches moonlock's per-monitor pattern.
This commit is contained in:
parent
de97d6658e
commit
f7e258d402
@ -47,7 +47,7 @@ cd pkg && makepkg -sf && sudo pacman -U moongreet-git-<version>-x86_64.pkg.tar.z
|
||||
- `fingerprint.rs` — fprintd D-Bus Probe (gio::DBusProxy) — Geräteerkennung und Enrollment-Check für UI-Feedback
|
||||
- `config.rs` — TOML-Config ([appearance] background, gtk-theme, fingerprint-enabled) + Wallpaper-Fallback + Blur-Validierung (finite, clamp 0–200)
|
||||
- `greeter.rs` — GTK4 UI (Overlay-Layout), Login-Flow via greetd IPC (Multi-Stage-Auth für fprintd), Faillock-Warnung, Avatar-Cache, Last-User/Last-Session Persistence (0o700 Dirs, 0o600 Files)
|
||||
- `main.rs` — Entry Point, GTK App, Layer Shell Setup, Multi-Monitor, systemd-journal-logger
|
||||
- `main.rs` — Entry Point, GTK App, Layer Shell Setup, Multi-Monitor (one greeter window per monitor, first gets keyboard), systemd-journal-logger
|
||||
- `resources/style.css` — Catppuccin-inspiriertes Theme
|
||||
|
||||
## Design Decisions
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "moongreet"
|
||||
version = "0.7.4"
|
||||
version = "0.8.0"
|
||||
edition = "2024"
|
||||
description = "A greetd greeter for Wayland with GTK4 and Layer Shell"
|
||||
license = "MIT"
|
||||
|
||||
@ -1,5 +1,12 @@
|
||||
# Decisions
|
||||
|
||||
## 2026-04-08 – Show greeter UI on all monitors instead of just one
|
||||
|
||||
- **Who**: ClaudeCode, Dom
|
||||
- **Why**: moonlock showed its UI on all monitors via ext-session-lock-v1, but moongreet only showed the login UI on one monitor (compositor-picked) with wallpaper-only windows on the rest. Inconsistent UX across the ecosystem.
|
||||
- **Tradeoffs**: Each monitor gets its own full greeter widget tree (slightly more memory), but the UI is lightweight. Screen mirroring (e.g., wl-mirror/screencopy) was considered and rejected — it requires an external process, compositor screencopy support, adds latency, and fights Wayland's per-output model. One-window-per-monitor is the established Wayland pattern (swaylock, hyprlock, moonlock all do this).
|
||||
- **How**: Create one `create_greeter_window()` per monitor with `set_monitor()`, only the first gets `KeyboardMode::Exclusive`. Removed `create_wallpaper_window()` (no longer needed). No layer shell fallback keeps single-window mode for development.
|
||||
|
||||
## 2026-04-06 – Restore explicit gtk-theme in moongreet config
|
||||
|
||||
- **Who**: ClaudeCode, Dom
|
||||
|
||||
@ -12,7 +12,7 @@ Part of the Moonarch ecosystem.
|
||||
- **Last user/session** — Remembered in `/var/cache/moongreet/`
|
||||
- **Power actions** — Reboot / Shutdown via `loginctl`
|
||||
- **Layer Shell** — Fullscreen via gtk4-layer-shell (TOP layer)
|
||||
- **Multi-monitor** — Greeter on primary, wallpaper on all monitors
|
||||
- **Multi-monitor** — Full greeter UI on all monitors (keyboard input on first)
|
||||
- **GPU blur** — Background blur via GskBlurNode (shared cache across monitors)
|
||||
- **i18n** — German and English (auto-detected from system locale)
|
||||
- **Faillock warning** — Warns after 2 failed attempts, locked message after 3
|
||||
|
||||
@ -188,24 +188,6 @@ fn render_blurred_texture(
|
||||
Some(renderer.render_texture(&node, Some(&viewport)))
|
||||
}
|
||||
|
||||
/// Create a wallpaper-only window for secondary monitors.
|
||||
pub fn create_wallpaper_window(
|
||||
texture: &gdk::Texture,
|
||||
blur_radius: Option<f32>,
|
||||
blur_cache: &Rc<RefCell<Option<gdk::Texture>>>,
|
||||
app: >k::Application,
|
||||
) -> gtk::ApplicationWindow {
|
||||
let window = gtk::ApplicationWindow::builder()
|
||||
.application(app)
|
||||
.build();
|
||||
window.add_css_class("wallpaper");
|
||||
|
||||
let background = create_background_picture(texture, blur_radius, blur_cache);
|
||||
window.set_child(Some(&background));
|
||||
|
||||
window
|
||||
}
|
||||
|
||||
/// Create a Picture widget for the wallpaper background, optionally with GPU blur.
|
||||
/// Uses `blur_cache` to compute the blurred texture only once across all monitors.
|
||||
fn create_background_picture(
|
||||
|
||||
25
src/main.rs
25
src/main.rs
@ -63,30 +63,27 @@ fn activate(app: >k::Application) {
|
||||
let use_layer_shell = std::env::var("MOONGREET_NO_LAYER_SHELL").is_err();
|
||||
log::debug!("Layer shell: {use_layer_shell}");
|
||||
|
||||
// Main greeter window (login UI) — compositor picks focused monitor
|
||||
let greeter_window = greeter::create_greeter_window(bg_texture.as_ref(), &config, &blur_cache, app);
|
||||
if use_layer_shell {
|
||||
setup_layer_shell(&greeter_window, true, gtk4_layer_shell::Layer::Top);
|
||||
}
|
||||
greeter_window.present();
|
||||
|
||||
// Wallpaper-only windows on all monitors (only with layer shell)
|
||||
if use_layer_shell
|
||||
&& let Some(ref texture) = bg_texture
|
||||
{
|
||||
// One greeter window per monitor — only the first gets keyboard input
|
||||
let monitors = display.monitors();
|
||||
log::debug!("Monitor count: {}", monitors.n_items());
|
||||
let mut first = true;
|
||||
for i in 0..monitors.n_items() {
|
||||
if let Some(monitor) = monitors
|
||||
.item(i)
|
||||
.and_then(|obj| obj.downcast::<gdk::Monitor>().ok())
|
||||
{
|
||||
let wallpaper = greeter::create_wallpaper_window(texture, config.background_blur, &blur_cache, app);
|
||||
setup_layer_shell(&wallpaper, false, gtk4_layer_shell::Layer::Bottom);
|
||||
wallpaper.set_monitor(Some(&monitor));
|
||||
wallpaper.present();
|
||||
let window = greeter::create_greeter_window(bg_texture.as_ref(), &config, &blur_cache, app);
|
||||
setup_layer_shell(&window, first, gtk4_layer_shell::Layer::Top);
|
||||
window.set_monitor(Some(&monitor));
|
||||
window.present();
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No layer shell — single window for development
|
||||
let greeter_window = greeter::create_greeter_window(bg_texture.as_ref(), &config, &blur_cache, app);
|
||||
greeter_window.present();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user