Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cd42df1095 | |||
| f7e258d402 | |||
| de97d6658e | |||
| 9c1e00d0ef | |||
| 874888391e |
@@ -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
|
- `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)
|
- `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)
|
- `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 mit Hotplug via `items-changed` auf Monitor-ListModel (one greeter window per monitor, first gets keyboard), systemd-journal-logger
|
||||||
- `resources/style.css` — Catppuccin-inspiriertes Theme
|
- `resources/style.css` — Catppuccin-inspiriertes Theme
|
||||||
|
|
||||||
## Design Decisions
|
## Design Decisions
|
||||||
|
|||||||
Generated
+1
-1
@@ -575,7 +575,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "moongreet"
|
name = "moongreet"
|
||||||
version = "0.7.1"
|
version = "0.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gdk-pixbuf",
|
"gdk-pixbuf",
|
||||||
"gdk4",
|
"gdk4",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "moongreet"
|
name = "moongreet"
|
||||||
version = "0.7.2"
|
version = "0.8.2"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
description = "A greetd greeter for Wayland with GTK4 and Layer Shell"
|
description = "A greetd greeter for Wayland with GTK4 and Layer Shell"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
+26
-5
@@ -1,29 +1,50 @@
|
|||||||
# Decisions
|
# Decisions
|
||||||
|
|
||||||
|
## 2026-04-09 – Monitor hotplug via ListModel items-changed
|
||||||
|
|
||||||
|
- **Who**: ClaudeCode, Dom
|
||||||
|
- **Why**: Greeter windows were only created at startup. If a monitor was hotplugged (e.g. HDMI reconnect), it would show no greeter UI. Aligned with moonlock's hotplug fix (same day).
|
||||||
|
- **Tradeoffs**: Hotplugged monitors get greeter windows without keyboard input (keyboard stays on the primary monitor). Acceptable — user can still interact on the primary screen.
|
||||||
|
- **How**: Connect to `display.monitors().connect_items_changed()` and create new greeter windows for added monitors. Shared state (config, texture, blur_cache) moved to Rc for the closure.
|
||||||
|
|
||||||
|
## 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
|
||||||
|
- **Why**: GTK4 under greetd does not reliably read `/etc/xdg/gtk-4.0/settings.ini` — likely requires a settings daemon that doesn't run in the greeter session. moongreet fell back to Adwaita/Colloid-default (blue accent) instead of Colloid-Grey-Dark-Catppuccin.
|
||||||
|
- **Tradeoffs**: Reverts `094878f` ("Remove gtk-theme from app config, use system-wide GTK settings instead"). Duplicates the theme name between settings.ini and moongreet.toml, but the explicit set via `set_gtk_theme_name()` is the only reliable path in a greetd context.
|
||||||
|
- **How**: Added `gtk-theme = "Colloid-Grey-Dark-Catppuccin"` to example config and deployed `/etc/moongreet/moongreet.toml`.
|
||||||
|
|
||||||
## 2026-04-02 – Replace hardcoded CSS colors with GTK theme variables
|
## 2026-04-02 – Replace hardcoded CSS colors with GTK theme variables
|
||||||
|
|
||||||
- **Who**: Ragnar, Dom
|
- **Who**: ClaudeCode, Dom
|
||||||
- **Why**: moongreet used hardcoded colors (#1a1a2e, white, #ff6b6b) while moonset already used @theme_bg_color, @theme_fg_color, @error_color etc. Inconsistent across the ecosystem and broke theme flexibility.
|
- **Why**: moongreet used hardcoded colors (#1a1a2e, white, #ff6b6b) while moonset already used @theme_bg_color, @theme_fg_color, @error_color etc. Inconsistent across the ecosystem and broke theme flexibility.
|
||||||
- **Tradeoffs**: Depends on the active GTK theme defining standard color variables. Catppuccin Colloid provides all needed vars (@theme_bg_color, @theme_fg_color, @error_color, @success_color, @theme_selected_bg_color). Fallback behavior if a theme lacks vars is GTK's default colors — acceptable.
|
- **Tradeoffs**: Depends on the active GTK theme defining standard color variables. Catppuccin Colloid provides all needed vars (@theme_bg_color, @theme_fg_color, @error_color, @success_color, @theme_selected_bg_color). Fallback behavior if a theme lacks vars is GTK's default colors — acceptable.
|
||||||
- **How**: Replaced all hardcoded hex/named colors with GTK theme variables. Coordinated change across moongreet, moonlock, and moonset (all three now use identical pattern).
|
- **How**: Replaced all hardcoded hex/named colors with GTK theme variables. Coordinated change across moongreet, moonlock, and moonset (all three now use identical pattern).
|
||||||
|
|
||||||
## 2026-03-31 – Fourth audit: power timeout, timing mitigation, release profile, GREETD_SOCK caching
|
## 2026-03-31 – Fourth audit: power timeout, timing mitigation, release profile, GREETD_SOCK caching
|
||||||
|
|
||||||
- **Who**: Ragnar, Dom
|
- **Who**: ClaudeCode, Dom
|
||||||
- **Why**: Fourth triple audit found moongreet power.rs had no timeout on loginctl (greeter could freeze), username enumeration via timing differential, GREETD_SOCK re-read on every login, missing release profile, and missing GResource compression.
|
- **Why**: Fourth triple audit found moongreet power.rs had no timeout on loginctl (greeter could freeze), username enumeration via timing differential, GREETD_SOCK re-read on every login, missing release profile, and missing GResource compression.
|
||||||
- **Tradeoffs**: 500ms minimum login response time adds slight delay on fast auth but prevents timing-based username enumeration. Power timeout (30s + SIGKILL) matches moonset pattern — aggressive but prevents greeter freeze.
|
- **Tradeoffs**: 500ms minimum login response time adds slight delay on fast auth but prevents timing-based username enumeration. Power timeout (30s + SIGKILL) matches moonset pattern — aggressive but prevents greeter freeze.
|
||||||
- **How**: (1) power.rs adapted from moonset with 30s timeout + SIGKILL (nix dependency added). (2) 500ms min response floor in attempt_login via Instant + glib::timeout_future. (3) GREETD_SOCK cached in GreeterState at startup. (4) `[profile.release]` with LTO, codegen-units=1, strip. (5) `compressed="true"` on GResource entries. (6) SYNC comments on duplicated blur/background functions.
|
- **How**: (1) power.rs adapted from moonset with 30s timeout + SIGKILL (nix dependency added). (2) 500ms min response floor in attempt_login via Instant + glib::timeout_future. (3) GREETD_SOCK cached in GreeterState at startup. (4) `[profile.release]` with LTO, codegen-units=1, strip. (5) `compressed="true"` on GResource entries. (6) SYNC comments on duplicated blur/background functions.
|
||||||
|
|
||||||
## 2026-03-30 – Full audit fix: security, quality, performance (v0.6.2)
|
## 2026-03-30 – Full audit fix: security, quality, performance (v0.6.2)
|
||||||
|
|
||||||
- **Who**: Ragnar, Dom
|
- **Who**: ClaudeCode, Dom
|
||||||
- **Why**: Three parallel audits (security, code quality, performance) identified 10 actionable findings across the codebase — from world-readable cache dirs to a GPU blur geometry bug to a race condition in fingerprint probing.
|
- **Why**: Three parallel audits (security, code quality, performance) identified 10 actionable findings across the codebase — from world-readable cache dirs to a GPU blur geometry bug to a race condition in fingerprint probing.
|
||||||
- **Tradeoffs**: `too_many_arguments` Clippy warnings suppressed with `#[allow]` rather than introducing a `UiWidgets` struct — GTK's `clone!` macro with `#[weak]` refs requires individual widget parameters, a struct would fight the idiom. Async avatar loading skipped because `Pixbuf` is `!Send`; cache already prevents repeat loads. TOCTOU socket pre-check removed entirely — `connect()` in login_worker already handles errors, the `metadata()` check gave false security guarantees.
|
- **Tradeoffs**: `too_many_arguments` Clippy warnings suppressed with `#[allow]` rather than introducing a `UiWidgets` struct — GTK's `clone!` macro with `#[weak]` refs requires individual widget parameters, a struct would fight the idiom. Async avatar loading skipped because `Pixbuf` is `!Send`; cache already prevents repeat loads. TOCTOU socket pre-check removed entirely — `connect()` in login_worker already handles errors, the `metadata()` check gave false security guarantees.
|
||||||
- **How**: Cache dirs use `DirBuilder::mode(0o700)` instead of `create_dir_all`. Blur config clamped to `0.0..=200.0` with `is_finite()` guard. Blur texture cached in `Rc<RefCell<Option<gdk::Texture>>>` across monitors. FingerprintProbe device proxy cached in `GreeterState` with generation counter to prevent stale async writes. GPU blur geometry fixed (`-pad` origin shift instead of texture stretching). `is_valid_gtk_theme` extracted as testable function. 9 new tests.
|
- **How**: Cache dirs use `DirBuilder::mode(0o700)` instead of `create_dir_all`. Blur config clamped to `0.0..=200.0` with `is_finite()` guard. Blur texture cached in `Rc<RefCell<Option<gdk::Texture>>>` across monitors. FingerprintProbe device proxy cached in `GreeterState` with generation counter to prevent stale async writes. GPU blur geometry fixed (`-pad` origin shift instead of texture stretching). `is_valid_gtk_theme` extracted as testable function. 9 new tests.
|
||||||
|
|
||||||
## 2026-03-29 – Fingerprint authentication via greetd multi-stage PAM
|
## 2026-03-29 – Fingerprint authentication via greetd multi-stage PAM
|
||||||
|
|
||||||
- **Who**: Ragnar, Dom
|
- **Who**: ClaudeCode, Dom
|
||||||
- **Why**: moonlock supports fprintd but moongreet rejected multi-stage auth. Users with enrolled fingerprints couldn't use them at the login screen.
|
- **Why**: moonlock supports fprintd but moongreet rejected multi-stage auth. Users with enrolled fingerprints couldn't use them at the login screen.
|
||||||
- **Tradeoffs**: Direct fprintd D-Bus verification (like moonlock) can't start a greetd session — greetd controls session creation via PAM. Using greetd multi-stage means PAM decides the auth order (fingerprint first, then password fallback), not truly parallel. Acceptable — matches standard pam_fprintd behavior.
|
- **Tradeoffs**: Direct fprintd D-Bus verification (like moonlock) can't start a greetd session — greetd controls session creation via PAM. Using greetd multi-stage means PAM decides the auth order (fingerprint first, then password fallback), not truly parallel. Acceptable — matches standard pam_fprintd behavior.
|
||||||
- **How**: Replace single-pass auth with a loop over auth_message rounds. Secret prompts get the password, non-secret prompts (fprintd) get None and block until PAM resolves. fprintd D-Bus probe (gio::DBusProxy) only for UI — detecting device availability and enrolled fingers. 60s socket timeout when fingerprint available. Config option `fingerprint-enabled` (default true).
|
- **How**: Replace single-pass auth with a loop over auth_message rounds. Secret prompts get the password, non-secret prompts (fprintd) get None and block until PAM resolves. fprintd D-Bus probe (gio::DBusProxy) only for UI — detecting device availability and enrolled fingers. 60s socket timeout when fingerprint available. Config option `fingerprint-enabled` (default true).
|
||||||
@@ -37,7 +58,7 @@
|
|||||||
|
|
||||||
## 2026-03-28 – GPU blur via GskBlurNode replaces CPU blur
|
## 2026-03-28 – GPU blur via GskBlurNode replaces CPU blur
|
||||||
|
|
||||||
- **Who**: Ragnar, Dom
|
- **Who**: ClaudeCode, Dom
|
||||||
- **Why**: CPU-side Gaussian blur (`image` crate) blocked the GTK main thread for 500ms–2s on 4K wallpapers at cold cache. Disk cache and async orchestration added significant complexity.
|
- **Why**: CPU-side Gaussian blur (`image` crate) blocked the GTK main thread for 500ms–2s on 4K wallpapers at cold cache. Disk cache and async orchestration added significant complexity.
|
||||||
- **Tradeoffs**: GPU blur quality is slightly different (box-blur approximation vs true Gaussian), acceptable for wallpaper backgrounds. Removes `image` crate dependency entirely (~15 transitive crates eliminated). No disk cache needed.
|
- **Tradeoffs**: GPU blur quality is slightly different (box-blur approximation vs true Gaussian), acceptable for wallpaper backgrounds. Removes `image` crate dependency entirely (~15 transitive crates eliminated). No disk cache needed.
|
||||||
- **How**: `Snapshot::push_blur()` + `GskRenderer::render_texture()` on `connect_realize`. Blur happens once on the GPU when the widget gets its renderer, producing a concrete `gdk::Texture`. Zero startup latency. Symmetric with moonlock and moonset.
|
- **How**: `Snapshot::push_blur()` + `GskRenderer::render_texture()` on `connect_realize`. Blur happens once on the GPU when the widget gets its renderer, producing a concrete `gdk::Texture`. Zero startup latency. Symmetric with moonlock and moonset.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Part of the Moonarch ecosystem.
|
|||||||
- **Last user/session** — Remembered in `/var/cache/moongreet/`
|
- **Last user/session** — Remembered in `/var/cache/moongreet/`
|
||||||
- **Power actions** — Reboot / Shutdown via `loginctl`
|
- **Power actions** — Reboot / Shutdown via `loginctl`
|
||||||
- **Layer Shell** — Fullscreen via gtk4-layer-shell (TOP layer)
|
- **Layer Shell** — Fullscreen via gtk4-layer-shell (TOP layer)
|
||||||
- **Multi-monitor** — Greeter on primary, wallpaper on all monitors
|
- **Multi-monitor + hotplug** — Full greeter UI on all monitors (keyboard input on first), hotplugged monitors get windows automatically
|
||||||
- **GPU blur** — Background blur via GskBlurNode (shared cache across monitors)
|
- **GPU blur** — Background blur via GskBlurNode (shared cache across monitors)
|
||||||
- **i18n** — German and English (auto-detected from system locale)
|
- **i18n** — German and English (auto-detected from system locale)
|
||||||
- **Faillock warning** — Warns after 2 failed attempts, locked message after 3
|
- **Faillock warning** — Warns after 2 failed attempts, locked message after 3
|
||||||
|
|||||||
@@ -4,3 +4,7 @@
|
|||||||
[appearance]
|
[appearance]
|
||||||
# Absolute path to wallpaper image
|
# Absolute path to wallpaper image
|
||||||
background = "/usr/share/backgrounds/wallpaper.jpg"
|
background = "/usr/share/backgrounds/wallpaper.jpg"
|
||||||
|
|
||||||
|
# GTK theme name — must match a directory in /usr/share/themes/
|
||||||
|
# Required because GTK4 under greetd does not reliably read settings.ini
|
||||||
|
gtk-theme = "Colloid-Grey-Dark-Catppuccin"
|
||||||
|
|||||||
+12
-18
@@ -188,24 +188,6 @@ fn render_blurred_texture(
|
|||||||
Some(renderer.render_texture(&node, Some(&viewport)))
|
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.
|
/// 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.
|
/// Uses `blur_cache` to compute the blurred texture only once across all monitors.
|
||||||
fn create_background_picture(
|
fn create_background_picture(
|
||||||
@@ -553,6 +535,18 @@ pub fn create_greeter_window(
|
|||||||
));
|
));
|
||||||
window.add_controller(key_controller);
|
window.add_controller(key_controller);
|
||||||
|
|
||||||
|
// Grab keyboard focus after map — layer-shell keyboard grab is only
|
||||||
|
// confirmed by the compositor at map time, not at realize time.
|
||||||
|
window.connect_map(clone!(
|
||||||
|
#[weak]
|
||||||
|
password_entry,
|
||||||
|
move |_| {
|
||||||
|
glib::idle_add_local_once(move || {
|
||||||
|
password_entry.grab_focus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
// Defer initial user selection until realized (for correct theme colors)
|
// Defer initial user selection until realized (for correct theme colors)
|
||||||
window.connect_realize(clone!(
|
window.connect_realize(clone!(
|
||||||
#[strong]
|
#[strong]
|
||||||
|
|||||||
+40
-14
@@ -11,9 +11,11 @@ mod sessions;
|
|||||||
mod users;
|
mod users;
|
||||||
|
|
||||||
use gdk4 as gdk;
|
use gdk4 as gdk;
|
||||||
|
use glib::clone;
|
||||||
use gtk4::prelude::*;
|
use gtk4::prelude::*;
|
||||||
use gtk4::{self as gtk, gio};
|
use gtk4::{self as gtk, gio};
|
||||||
use gtk4_layer_shell::LayerShell;
|
use gtk4_layer_shell::LayerShell;
|
||||||
|
use std::rc::Rc;
|
||||||
fn load_css(display: &gdk::Display) {
|
fn load_css(display: &gdk::Display) {
|
||||||
let css_provider = gtk::CssProvider::new();
|
let css_provider = gtk::CssProvider::new();
|
||||||
css_provider.load_from_resource("/dev/moonarch/moongreet/style.css");
|
css_provider.load_from_resource("/dev/moonarch/moongreet/style.css");
|
||||||
@@ -63,30 +65,54 @@ fn activate(app: >k::Application) {
|
|||||||
let use_layer_shell = std::env::var("MOONGREET_NO_LAYER_SHELL").is_err();
|
let use_layer_shell = std::env::var("MOONGREET_NO_LAYER_SHELL").is_err();
|
||||||
log::debug!("Layer shell: {use_layer_shell}");
|
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 {
|
if use_layer_shell {
|
||||||
setup_layer_shell(&greeter_window, true, gtk4_layer_shell::Layer::Top);
|
// One greeter window per monitor — only the first gets keyboard input
|
||||||
}
|
|
||||||
greeter_window.present();
|
|
||||||
|
|
||||||
// Wallpaper-only windows on all monitors (only with layer shell)
|
|
||||||
if use_layer_shell
|
|
||||||
&& let Some(ref texture) = bg_texture
|
|
||||||
{
|
|
||||||
let monitors = display.monitors();
|
let monitors = display.monitors();
|
||||||
log::debug!("Monitor count: {}", monitors.n_items());
|
log::debug!("Monitor count: {}", monitors.n_items());
|
||||||
|
let mut first = true;
|
||||||
for i in 0..monitors.n_items() {
|
for i in 0..monitors.n_items() {
|
||||||
if let Some(monitor) = monitors
|
if let Some(monitor) = monitors
|
||||||
.item(i)
|
.item(i)
|
||||||
.and_then(|obj| obj.downcast::<gdk::Monitor>().ok())
|
.and_then(|obj| obj.downcast::<gdk::Monitor>().ok())
|
||||||
{
|
{
|
||||||
let wallpaper = greeter::create_wallpaper_window(texture, config.background_blur, &blur_cache, app);
|
let window = greeter::create_greeter_window(bg_texture.as_ref(), &config, &blur_cache, app);
|
||||||
setup_layer_shell(&wallpaper, false, gtk4_layer_shell::Layer::Bottom);
|
setup_layer_shell(&window, first, gtk4_layer_shell::Layer::Top);
|
||||||
wallpaper.set_monitor(Some(&monitor));
|
window.set_monitor(Some(&monitor));
|
||||||
wallpaper.present();
|
window.present();
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle monitor hotplug — create greeter windows for newly added monitors
|
||||||
|
// (without keyboard, since the primary monitor already has it)
|
||||||
|
let bg_texture = Rc::new(bg_texture);
|
||||||
|
let config = Rc::new(config);
|
||||||
|
monitors.connect_items_changed(clone!(
|
||||||
|
#[weak]
|
||||||
|
app,
|
||||||
|
#[strong]
|
||||||
|
blur_cache,
|
||||||
|
move |list, position, _removed, added| {
|
||||||
|
for i in position..position + added {
|
||||||
|
if let Some(monitor) = list
|
||||||
|
.item(i)
|
||||||
|
.and_then(|obj| obj.downcast::<gdk::Monitor>().ok())
|
||||||
|
{
|
||||||
|
log::debug!("Monitor hotplug: creating greeter window");
|
||||||
|
let window = greeter::create_greeter_window(
|
||||||
|
bg_texture.as_ref().as_ref(), &config, &blur_cache, &app,
|
||||||
|
);
|
||||||
|
setup_layer_shell(&window, false, gtk4_layer_shell::Layer::Top);
|
||||||
|
window.set_monitor(Some(&monitor));
|
||||||
|
window.present();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
} 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user