unblock brightness shortcut on lock screen

This commit is contained in:
Samuel Onoja committed 2026-10-13 13:10:53 +01:00
1 parent f0620e317b
commit 9163374cdb
3 files changed
+55 -5

No files matched your search

+51 -4
View File
@@ -51,22 +51,27 @@ impl Ferese {
let presented = self.presented_window_rect(*id)?; let presented = self.presented_window_rect(*id)?;
let (scale_x, scale_y) = self.visual_scale_for_window(window)?; let (scale_x, scale_y) = self.visual_scale_for_window(window)?;
let point = local.to_f64() + hint - geometry.loc.to_f64(); let point = local.to_f64() + hint - geometry.loc.to_f64();
return Some(Point::from(( return Some(Point::from((
presented.x + point.x * scale_x, presented.x + point.x * scale_x,
presented.y + point.y * scale_y, presented.y + point.y * scale_y,
))); )));
} }
for output in self.space.outputs() { for output in self.space.outputs() {
let output_geometry = self.space.output_geometry(output)?; let output_geometry = self.space.output_geometry(output)?;
let layers = smithay::desktop::layer_map_for_output(output); let layers = smithay::desktop::layer_map_for_output(output);
for layer in layers.layers() { for layer in layers.layers() {
let Some(local) = surface_tree_position(layer.wl_surface(), surface, (0, 0).into()) else { let Some(local) = surface_tree_position(layer.wl_surface(), surface, (0, 0).into()) else {
continue; continue;
}; };
let geometry = layers.layer_geometry(layer)?; let geometry = layers.layer_geometry(layer)?;
return Some((output_geometry.loc + geometry.loc + local).to_f64() + hint); return Some((output_geometry.loc + geometry.loc + local).to_f64() + hint);
} }
} }
None None
} }
@@ -77,6 +82,7 @@ impl Ferese {
if !hint.surface.is_alive() || self.session_lock.active() || self.input_capture.active() { if !hint.surface.is_alive() || self.session_lock.active() || self.input_capture.active() {
return; return;
} }
let Some(pointer) = self.seat.get_pointer() else { let Some(pointer) = self.seat.get_pointer() else {
return; return;
}; };
@@ -85,10 +91,12 @@ impl Ferese {
constraint.is_active() && matches!(&*constraint, PointerConstraint::Locked(_)) constraint.is_active() && matches!(&*constraint, PointerConstraint::Locked(_))
}) })
}); });
if locked { if locked {
self.locked_pointer_hint = Some(hint); self.locked_pointer_hint = Some(hint);
return; return;
} }
if pointer.current_focus().is_some_and(|surface| { if pointer.current_focus().is_some_and(|surface| {
with_pointer_constraint(&surface, &pointer, |constraint| { with_pointer_constraint(&surface, &pointer, |constraint| {
constraint.is_some_and(|constraint| constraint.is_active()) constraint.is_some_and(|constraint| constraint.is_active())
@@ -96,11 +104,13 @@ impl Ferese {
}) { }) {
return; return;
} }
let Some(global) = self.pointer_hint_position(&hint.surface, hint.local) else { let Some(global) = self.pointer_hint_position(&hint.surface, hint.local) else {
return; return;
}; };
let location = self.clamp_pointer_position(global); let location = self.clamp_pointer_position(global);
let focus = self.surface_under(location); let focus = self.surface_under(location);
pointer.motion( pointer.motion(
self, self,
focus, focus,
@@ -111,6 +121,7 @@ impl Ferese {
}, },
); );
pointer.frame(self); pointer.frame(self);
self.cursor_redraw_pending = true; self.cursor_redraw_pending = true;
} }
@@ -118,8 +129,10 @@ impl Ferese {
if self.input_capture.active() { if self.input_capture.active() {
self.set_binding_mode("default"); self.set_binding_mode("default");
} }
let seat = self.seat.clone(); let seat = self.seat.clone();
self.idle_notifier_state.notify_activity(&seat); self.idle_notifier_state.notify_activity(&seat);
if !matches!( if !matches!(
&event, &event,
InputEvent::DeviceAdded { .. } | InputEvent::DeviceRemoved { .. } | InputEvent::SwitchToggle { .. } InputEvent::DeviceAdded { .. } | InputEvent::DeviceRemoved { .. } | InputEvent::SwitchToggle { .. }
@@ -166,7 +179,9 @@ impl Ferese {
.any(|binding| binding.swipe_fingers(event.fingers())), .any(|binding| binding.swipe_fingers(event.fingers())),
self.input_settings.touchpad.swipe_threshold, self.input_settings.touchpad.swipe_threshold,
); );
self.swipe.start_time(std::time::Duration::from_micros(event.time())); self.swipe.start_time(std::time::Duration::from_micros(event.time()));
if self.swipe.active() { if self.swipe.active() {
self.focus_output_at(pointer.current_location()); self.focus_output_at(pointer.current_location());
} else { } else {
@@ -187,6 +202,7 @@ impl Ferese {
event.delta_y(), event.delta_y(),
std::time::Duration::from_micros(event.time()), std::time::Duration::from_micros(event.time()),
); );
if self.swipe_navigation_blocked() { if self.swipe_navigation_blocked() {
self.finish_workspace_swipe(None); self.finish_workspace_swipe(None);
self.finish_focus_swipe(None); self.finish_focus_swipe(None);
@@ -274,6 +290,7 @@ impl Ferese {
keyboard.set_focus(self, None, SERIAL_COUNTER.next_serial()); keyboard.set_focus(self, None, SERIAL_COUNTER.next_serial());
} }
} }
let serial = SERIAL_COUNTER.next_serial(); let serial = SERIAL_COUNTER.next_serial();
let interaction_focus = keyboard.current_focus(); let interaction_focus = keyboard.current_focus();
let client_grab = keyboard let client_grab = keyboard
@@ -293,6 +310,7 @@ impl Ferese {
data.finish_focus_cycle(); data.finish_focus_cycle();
} }
} }
if state == KeyState::Released { if state == KeyState::Released {
data.binding_mode_pressed.remove(&keycode); data.binding_mode_pressed.remove(&keycode);
data.binding_mode_repeats.remove(&keycode); data.binding_mode_repeats.remove(&keycode);
@@ -308,7 +326,31 @@ impl Ferese {
return FilterResult::Forward; return FilterResult::Forward;
} }
let raw_symbols = keysym.raw_syms().into_iter().map(|symbol| symbol.raw()).collect::<Vec<_>>(); let raw_symbols = keysym.raw_syms().into_iter().map(|symbol| symbol.raw()).collect::<Vec<_>>();
if !data.binding_mode_pressed.insert(keycode) { let first_press = data.binding_mode_pressed.insert(keycode);
if data.session_lock.active() {
// Preserve ownership of keys held across the lock transition.
if !first_press && !data.intercepted_keys.contains(&keycode) {
return FilterResult::Forward;
}
if let Some(step) = locked_brightness_step(keysym.modified_sym().raw()) {
data.intercepted_keys.insert(keycode);
// Never execute configurable commands while locked.
if let Some(child) = spawn_client(
data,
["brightnessctl", "set", step],
crate::private_client::ClientCapabilities::default(),
) {
crate::process::watch_client_exit(&data.loop_handle, child);
}
return FilterResult::Intercept(());
}
return if data.intercepted_keys.contains(&keycode) {
FilterResult::Intercept(())
} else {
FilterResult::Forward
};
}
if !first_press {
// A held key belongs to the recipient of its first // A held key belongs to the recipient of its first
// press, even when a mode or configuration changes. // press, even when a mode or configuration changes.
return if data.intercepted_keys.contains(&keycode) { return if data.intercepted_keys.contains(&keycode) {
@@ -331,9 +373,6 @@ impl Ferese {
FilterResult::Forward FilterResult::Forward
}; };
} }
if data.session_lock.active() {
return FilterResult::Forward;
}
let symbol = keysym.modified_sym().raw(); let symbol = keysym.modified_sym().raw();
if data.binding_modes.active().is_some() && symbol == keysyms::KEY_Escape { if data.binding_modes.active().is_some() && symbol == keysyms::KEY_Escape {
if state == KeyState::Pressed { if state == KeyState::Pressed {
@@ -1298,6 +1337,14 @@ fn surface_tree_offset(root: &WlSurface, target: &WlSurface) -> Option<Point<i32
found.get() found.get()
} }
fn locked_brightness_step(symbol: u32) -> Option<&'static str> {
match symbol {
keysyms::KEY_XF86MonBrightnessUp => Some("2%+"),
keysyms::KEY_XF86MonBrightnessDown => Some("2%-"),
_ => None,
}
}
fn virtual_terminal(symbol: u32, ctrl: bool, alt: bool, direct: bool) -> Option<i32> { fn virtual_terminal(symbol: u32, ctrl: bool, alt: bool, direct: bool) -> Option<i32> {
if !direct { if !direct {
return None; return None;
-1
View File
@@ -57,7 +57,6 @@ use calloop::signals::{Signal, Signals};
use process::{spawn_client, terminate_child, watch_client_exit}; use process::{spawn_client, terminate_child, watch_client_exit};
use smithay::reexports::calloop::EventLoop; use smithay::reexports::calloop::EventLoop;
use smithay::reexports::wayland_server::Display; use smithay::reexports::wayland_server::Display;
pub use state::{Ferese, RuntimeConfig};
use tracing::{info, warn}; use tracing::{info, warn};
use crate::backends::LaunchConfig; use crate::backends::LaunchConfig;
+4
View File
@@ -19,6 +19,10 @@ Press Escape to clear the password. The authentication status also shows whether
Caps Lock is on. A failed attempt displays an error and delays the next retry. Caps Lock is on. A failed attempt displays an error and delays the next retry.
Authentication uses the system's PAM policy; both password and account validation must succeed. Authentication uses the system's PAM policy; both password and account validation must succeed.
The screen brightness keys work while locked, including when brightness is zero.
They require `brightnessctl` and adjust brightness in 2% steps. While locked,
these keys use the compositor's brightness control instead of custom bindings.
## Automatic locking ## Automatic locking
Install `swayidle`, then add this to `~/.config/ferese/config.kdl` to lock after Install `swayidle`, then add this to `~/.config/ferese/config.kdl` to lock after