srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/native_lock.rs
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2026-05-11 16:44:00 +0200
committersrdusr <[email protected]>2026-05-11 16:44:00 +0200
commitcaec1e7c355bbe6437afe87cd3dab6b64fb91e0a (patch)
tree5ecab25d2ebc36949ac4129b35e35334a575d563 /crates/wayland/src/native_lock.rs
parentbaabd91411dacd179c690f724b6cbfe6270cb131 (diff)
downloadsrdwm-caec1e7c355bbe6437afe87cd3dab6b64fb91e0a.tar.gz
srdwm-caec1e7c355bbe6437afe87cd3dab6b64fb91e0a.zip
Three live bug reports after a restart: icon drag, lock cursor, lock box
All three reported directly after the owner restarted into today's build. Desktop icons could not be dragged at all in single-click mode. The press handler opened the icon immediately when general.desktop_icon_single_click was on, so the branch that starts a drag was unreachable and an icon could never be moved. Deciding activation on press cannot distinguish a click from the first instant of a drag. Every press on an icon now starts a potential drag and release decides which it was, using a 4px movement threshold that latches once exceeded. Double-click mode goes through the same path, so both modes now drag identically. The lock screen drew no cursor. The cursor push in the udev render loop sits inside `if !locked`, and a locked head renders only the lock element list, so nothing drew a pointer - and on a bare TTY nothing else does. The on-screen keyboard's clicks were being handled correctly the whole time (native_lock_click); they simply could not be aimed. The pointer is now prepended to the lock element list, above the UI it is used to click. The password field's opaque panel is gone. New LockConfig::box_opacity, default 0.0: no fill, no border, no rounded rectangle, just the dots and status text over the blurred background. Raising it restores the panel at that opacity for anyone who wants a solid field. Drawing text on a transparent surface needed a new blit_glyph_over: the existing blit_glyph blends against one flat opaque colour and writes alpha 255, which would have turned every glyph into a block of the assumed background - the same box with its middle removed. VERIFICATION STATUS, stated plainly: all three are code-complete and the suite passes, but none is confirmed on screen. The nested backend's capture pass does not draw the desktop icon grid (a gap already recorded in winit/capture.rs), so the icon drag cannot be checked by screenshot there, and aiming blind is what this project's own rules forbid. The two lock changes were not visually checked either. 515 tests pass, clippy clean.
Diffstat (limited to 'crates/wayland/src/native_lock.rs')
-rw-r--r--crates/wayland/src/native_lock.rs31
1 files changed, 25 insertions, 6 deletions
diff --git a/crates/wayland/src/native_lock.rs b/crates/wayland/src/native_lock.rs
index 14c4f21..96e4ac9 100644
--- a/crates/wayland/src/native_lock.rs
+++ b/crates/wayland/src/native_lock.rs
@@ -780,14 +780,22 @@ fn render_header_box(native: &NativeLock, theme: &srdwm_core::LockConfig) -> (Ve
/// `rgb_to_bgra`), promoted to `pub(crate)` there rather than duplicated
/// here.
fn render_ui_box(native: &NativeLock, theme: &srdwm_core::LockConfig) -> (Vec<u8>, (i32, i32)) {
- use crate::decoration::{blit_glyph, find_system_font, rgb_to_bgra, round_bottom_corners, round_top_corners, FONT_PIXELS, TEXT_LEFT_PADDING};
+ use crate::decoration::{blit_glyph_over, find_system_font, rgb_to_bgra, round_bottom_corners, round_top_corners, FONT_PIXELS, TEXT_LEFT_PADDING};
const WIDTH: usize = 340;
const HEIGHT: usize = 120;
let mut buf = vec![0u8; WIDTH * HEIGHT * 4];
- let bg = rgb_to_bgra(theme.box_bg, 255);
- for px in buf.chunks_exact_mut(4) {
- px.copy_from_slice(&bg);
+ // `box_opacity` 0 (the default) leaves the buffer fully transparent, so
+ // the dots and status text sit straight on the blurred background with
+ // no panel behind them at all - see `LockConfig::box_opacity`. Above
+ // 0 the panel comes back at that opacity, border and rounded corners
+ // included, exactly as it used to look at 1.0.
+ let panel_alpha = (theme.box_opacity.clamp(0.0, 1.0) * 255.0).round() as u8;
+ if panel_alpha > 0 {
+ let bg = rgb_to_bgra(theme.box_bg, panel_alpha);
+ for px in buf.chunks_exact_mut(4) {
+ px.copy_from_slice(&bg);
+ }
}
let font = find_system_font();
@@ -814,7 +822,7 @@ fn render_ui_box(native: &NativeLock, theme: &srdwm_core::LockConfig) -> (Vec<u8
if metrics.width > 0 && metrics.height > 0 {
let glyph_x = pen_x + metrics.xmin as f32;
let glyph_y = y - metrics.height as f32 - metrics.ymin as f32;
- blit_glyph(&mut buf, WIDTH, HEIGHT, glyph_x.round() as i32, glyph_y.round() as i32, &metrics, &coverage, theme.box_bg, color);
+ blit_glyph_over(&mut buf, WIDTH, HEIGHT, glyph_x.round() as i32, glyph_y.round() as i32, &metrics, &coverage, color);
}
pen_x += metrics.advance_width;
}
@@ -827,7 +835,11 @@ fn render_ui_box(native: &NativeLock, theme: &srdwm_core::LockConfig) -> (Vec<u8
// (GNOME, macOS): dimmer than the real text colour, never mistakable
// for an actual password once one is entered.
if native.password.is_empty() && !native.show_error {
- let placeholder = crate::decoration::mix_rgb(theme.text_color, theme.box_bg, 0.5);
+ // Dimmed toward the panel colour when there is a panel, and toward
+ // plain black otherwise - mixing toward a background that is not
+ // actually drawn would tint the placeholder for no visible reason.
+ let toward = if panel_alpha > 0 { theme.box_bg } else { (0, 0, 0) };
+ let placeholder = crate::decoration::mix_rgb(theme.text_color, toward, 0.5);
draw_line_centered("Enter Password", 65.0, placeholder);
} else {
let dots: String = std::iter::repeat_n(theme.dot_char, native.password.chars().count()).collect();
@@ -850,6 +862,13 @@ fn render_ui_box(native: &NativeLock, theme: &srdwm_core::LockConfig) -> (Vec<u8
// this box's size read as a thin, easy-to-miss hairline rather than a
// deliberate frame around the box.
const BORDER: usize = 2;
+ // Border and corner rounding belong to the panel: with no panel there
+ // is nothing to frame, and a floating rounded outline around bare text
+ // is the "horrendus box" with its middle removed rather than the box
+ // gone.
+ if panel_alpha == 0 {
+ return (buf, (WIDTH as i32, HEIGHT as i32));
+ }
let border_px = rgb_to_bgra(theme.box_border, 255);
for t in 0..BORDER {
for x in 0..WIDTH {