Impl keyboard shortcuts inhibit

And xwayland keyboard grab
This commit is contained in:
Ottatop 2024-06-22 17:08:30 -05:00
parent 36434806a5
commit 4e95a28ddb
4 changed files with 84 additions and 34 deletions

View file

@ -15,10 +15,11 @@ use smithay::{
renderer::utils::{self, with_renderer_surface_state},
},
delegate_compositor, delegate_cursor_shape, delegate_data_control, delegate_data_device,
delegate_fractional_scale, delegate_layer_shell, delegate_output, delegate_pointer_constraints,
delegate_presentation, delegate_primary_selection, delegate_relative_pointer, delegate_seat,
delegate_fractional_scale, delegate_keyboard_shortcuts_inhibit, delegate_layer_shell,
delegate_output, delegate_pointer_constraints, delegate_presentation,
delegate_primary_selection, delegate_relative_pointer, delegate_seat,
delegate_security_context, delegate_shm, delegate_tablet_manager, delegate_viewporter,
delegate_xwayland_shell,
delegate_xwayland_keyboard_grab, delegate_xwayland_shell,
desktop::{
self, find_popup_root_surface, get_popup_toplevel_coords, layer_map_for_output, PopupKind,
PopupManager, WindowSurfaceType,
@ -48,6 +49,10 @@ use smithay::{
},
dmabuf,
fractional_scale::{self, FractionalScaleHandler},
keyboard_shortcuts_inhibit::{
KeyboardShortcutsInhibitHandler, KeyboardShortcutsInhibitState,
KeyboardShortcutsInhibitor,
},
output::OutputHandler,
pointer_constraints::{with_pointer_constraint, PointerConstraintsHandler},
seat::WaylandFocus,
@ -71,6 +76,7 @@ use smithay::{
},
shm::{ShmHandler, ShmState},
tablet_manager::TabletSeatHandler,
xwayland_keyboard_grab::XWaylandKeyboardGrabHandler,
xwayland_shell::{XWaylandShellHandler, XWaylandShellState},
},
xwayland::XWaylandClientData,
@ -912,6 +918,27 @@ delegate_tablet_manager!(State);
delegate_cursor_shape!(State);
impl KeyboardShortcutsInhibitHandler for State {
fn keyboard_shortcuts_inhibit_state(&mut self) -> &mut KeyboardShortcutsInhibitState {
&mut self.pinnacle.keyboard_shortcuts_inhibit_state
}
fn new_inhibitor(&mut self, inhibitor: KeyboardShortcutsInhibitor) {
// TODO: Some way to not unconditionally activate the inhibitor
inhibitor.activate();
}
}
delegate_keyboard_shortcuts_inhibit!(State);
impl XWaylandKeyboardGrabHandler for State {
fn keyboard_focus_for_xsurface(&self, surface: &WlSurface) -> Option<Self::KeyboardFocus> {
self.pinnacle
.window_for_surface(surface)
.map(KeyboardFocusTarget::from)
}
}
delegate_xwayland_keyboard_grab!(State);
impl Pinnacle {
fn position_popup(&self, popup: &PopupSurface) {
trace!("State::position_popup");

View file

@ -35,6 +35,7 @@ use smithay::{
utils::{Logical, Point, Rectangle, SERIAL_COUNTER},
wayland::{
compositor::{self, RegionAttributes, SurfaceAttributes},
keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitorSeat,
pointer_constraints::{with_pointer_constraint, PointerConstraint},
seat::WaylandFocus,
shell::wlr_layer::{self, KeyboardInteractivity, LayerSurfaceCachedState},
@ -487,6 +488,17 @@ impl State {
}
}
let shortcuts_inhibited = keyboard
.current_focus()
.and_then(|focus| {
focus.wl_surface().and_then(|surf| {
self.pinnacle
.seat
.keyboard_shortcuts_inhibitor_for_surface(&surf)
})
})
.is_some_and(|inhibitor| inhibitor.is_active());
let action = keyboard.input(
self,
event.key_code(),
@ -510,36 +522,6 @@ impl State {
let raw_sym = keysym.raw_syms().iter().next();
let mod_sym = keysym.modified_sym();
if let Some(keybind_data) = state
.pinnacle
.input_state
.keybinds
.get(&(mod_mask, mod_sym))
.or_else(|| {
raw_sym.and_then(|raw_sym| {
state
.pinnacle
.input_state
.keybinds
.get(&(mod_mask, *raw_sym))
})
})
{
if state.pinnacle.lock_state.is_unlocked() {
return FilterResult::Intercept(KeyAction::CallCallback(
keybind_data.sender.clone(),
));
}
}
if kill_keybind == Some((mod_mask, mod_sym)) {
return FilterResult::Intercept(KeyAction::Quit);
}
if reload_keybind == Some((mod_mask, mod_sym)) {
return FilterResult::Intercept(KeyAction::ReloadConfig);
}
if let mut vt @ keysyms::KEY_XF86Switch_VT_1..=keysyms::KEY_XF86Switch_VT_12 =
keysym.modified_sym().raw()
{
@ -547,6 +529,38 @@ impl State {
tracing::info!("Switching to vt {vt}");
return FilterResult::Intercept(KeyAction::SwitchVt(vt as i32));
}
if !shortcuts_inhibited {
if let Some(keybind_data) = state
.pinnacle
.input_state
.keybinds
.get(&(mod_mask, mod_sym))
.or_else(|| {
raw_sym.and_then(|raw_sym| {
state
.pinnacle
.input_state
.keybinds
.get(&(mod_mask, *raw_sym))
})
})
{
if state.pinnacle.lock_state.is_unlocked() {
return FilterResult::Intercept(KeyAction::CallCallback(
keybind_data.sender.clone(),
));
}
}
if kill_keybind == Some((mod_mask, mod_sym)) {
return FilterResult::Intercept(KeyAction::Quit);
}
if reload_keybind == Some((mod_mask, mod_sym)) {
return FilterResult::Intercept(KeyAction::ReloadConfig);
}
}
}
FilterResult::Forward

View file

@ -24,7 +24,6 @@ use pinnacle::{
util::increase_nofile_rlimit,
};
use smithay::reexports::{calloop::EventLoop, rustix::process::geteuid};
use tokio::sync::oneshot::error::TryRecvError;
use tracing::{error, info, warn};
use tracing_appender::rolling::Rotation;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Layer};
@ -177,6 +176,8 @@ async fn main() -> anyhow::Result<()> {
#[cfg(feature = "snowcap")]
{
use tokio::sync::oneshot::error::TryRecvError;
let (sender, mut recv) = tokio::sync::oneshot::channel();
let join_handle = tokio::task::spawn_blocking(move || {
let _span = tracing::error_span!("snowcap");

View file

@ -41,6 +41,7 @@ use smithay::{
dmabuf::DmabufFeedback,
fractional_scale::FractionalScaleManagerState,
idle_notify::IdleNotifierState,
keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitState,
output::OutputManagerState,
pointer_constraints::PointerConstraintsState,
relative_pointer::RelativePointerManagerState,
@ -55,6 +56,7 @@ use smithay::{
socket::ListeningSocketSource,
tablet_manager::TabletManagerState,
viewporter::ViewporterState,
xwayland_keyboard_grab::XWaylandKeyboardGrabState,
xwayland_shell::XWaylandShellState,
},
xwayland::{X11Wm, XWaylandClientData},
@ -116,6 +118,8 @@ pub struct Pinnacle {
pub output_management_manager_state: OutputManagementManagerState,
pub output_power_management_state: OutputPowerManagementState,
pub tablet_manager_state: TabletManagerState,
pub keyboard_shortcuts_inhibit_state: KeyboardShortcutsInhibitState,
pub xwayland_keyboard_grab_state: XWaylandKeyboardGrabState,
pub lock_state: LockState,
@ -339,6 +343,10 @@ impl Pinnacle {
filter_restricted_client,
),
tablet_manager_state: TabletManagerState::new::<State>(&display_handle),
keyboard_shortcuts_inhibit_state: KeyboardShortcutsInhibitState::new::<State>(
&display_handle,
),
xwayland_keyboard_grab_state: XWaylandKeyboardGrabState::new::<State>(&display_handle),
lock_state: LockState::default(),