Files
feresaria/compositor/src/handlers/activation.rs
T

63 lines
2.1 KiB
Rust

use std::time::Duration;
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
use smithay::utils::SERIAL_COUNTER;
use smithay::wayland::xdg_activation::{
XdgActivationHandler, XdgActivationState, XdgActivationToken, XdgActivationTokenData,
};
use crate::Ferese;
const TOKEN_MAX_AGE: Duration = Duration::from_secs(10);
impl XdgActivationHandler for Ferese {
fn activation_state(&mut self) -> &mut XdgActivationState {
&mut self.xdg_activation_state
}
fn token_created(&mut self, _token: XdgActivationToken, data: XdgActivationTokenData) -> bool {
data.serial.is_some() && data.timestamp.elapsed() <= TOKEN_MAX_AGE
}
fn request_activation(&mut self, token: XdgActivationToken, data: XdgActivationTokenData, surface: WlSurface) {
if self.session_lock.active || self.input_capture.captures(1) {
return;
}
let valid = data.serial.is_some() && data.timestamp.elapsed() <= TOKEN_MAX_AGE;
self.xdg_activation_state.remove_token(&token);
if !valid {
tracing::debug!("ignored stale or non-interactive activation request");
return;
}
let Some(window) = self
.space
.elements()
.find(|window| {
window
.toplevel()
.is_some_and(|toplevel| toplevel.wl_surface() == &surface)
})
.cloned()
else {
return;
};
self.focused_window = self.window_ids.get(&window).copied();
if let Some(focused) = self.focused_window
&& let Err(error) = self.workspaces.focus_window(focused)
{
tracing::error!(%error, ?focused, "failed to update workspace focus");
return;
}
self.raise_window(&window, true);
let keyboard = self.seat.get_keyboard().expect("seat has a keyboard");
keyboard.set_focus(self, Some(surface), SERIAL_COUNTER.next_serial());
self.space.elements().for_each(|window| {
if let Some(toplevel) = window.toplevel() {
toplevel.send_pending_configure();
}
});
}
}