Skip to content

Commit

Permalink
Impl xdg activation
Browse files Browse the repository at this point in the history
Currently only does simple logic and focuses the requesting window if it's on an active tag; no urgency yet as there's not really any way to show that
  • Loading branch information
Ottatop committed Jun 23, 2024
1 parent 7ae7a42 commit e50c24c
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 1 deletion.
99 changes: 98 additions & 1 deletion src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use smithay::{
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_keyboard_grab, delegate_xwayland_shell,
delegate_xdg_activation, delegate_xwayland_keyboard_grab, delegate_xwayland_shell,
desktop::{
self, find_popup_root_surface, get_popup_toplevel_coords, layer_map_for_output, PopupKind,
PopupManager, WindowSurfaceType,
Expand Down Expand Up @@ -76,6 +76,9 @@ use smithay::{
},
shm::{ShmHandler, ShmState},
tablet_manager::TabletSeatHandler,
xdg_activation::{
XdgActivationHandler, XdgActivationState, XdgActivationToken, XdgActivationTokenData,
},
xwayland_keyboard_grab::XWaylandKeyboardGrabHandler,
xwayland_shell::{XWaylandShellHandler, XWaylandShellState},
},
Expand Down Expand Up @@ -939,6 +942,100 @@ impl XWaylandKeyboardGrabHandler for State {
}
delegate_xwayland_keyboard_grab!(State);

enum ActivationContext {
FocusIfPossible,
UrgentOnly,
}

impl XdgActivationHandler for State {
fn activation_state(&mut self) -> &mut XdgActivationState {
&mut self.pinnacle.xdg_activation_state
}

fn token_created(&mut self, token: XdgActivationToken, data: XdgActivationTokenData) -> bool {
let Some((serial, seat)) = data.serial else {
data.user_data
.insert_if_missing(|| ActivationContext::UrgentOnly);
debug!(
?token,
"xdg-activation: created urgent-only token for missing seat/serial"
);
return true;
};

let Some(seat) = Seat::<State>::from_resource(&seat) else {
data.user_data
.insert_if_missing(|| ActivationContext::UrgentOnly);
debug!(
?token,
"xdg-activation: created urgent-only token for unknown seat"
);
return true;
};

let keyboard = seat.get_keyboard().unwrap();

let valid = keyboard
.last_enter()
.is_some_and(|last_enter| serial.is_no_older_than(&last_enter));

if valid {
data.user_data
.insert_if_missing(|| ActivationContext::FocusIfPossible);
debug!(?token, "xdg-activation: created focus-if-possible token");
} else {
debug!(?token, "xdg-activation: invalid token");
}

valid
}

fn request_activation(
&mut self,
_token: XdgActivationToken,
token_data: XdgActivationTokenData,
surface: WlSurface,
) {
let Some(context) = token_data.user_data.get::<ActivationContext>() else {
debug!("xdg-activation: request without context");
return;
};

let Some(window) = self.pinnacle.window_for_surface(&surface) else {
debug!("xdg-activation: no window for request");
return;
};

match context {
ActivationContext::FocusIfPossible => {
if window.is_on_active_tag() {
// TODO: add a holder for pending activations like cosmic-comp

let Some(output) = window.output(&self.pinnacle) else {
// TODO: make "no tags" be all tags on an output
debug!("xdg-activation: focus-if-possible request on window but it had no tags");
return;
};

self.pinnacle.raise_window(window.clone(), true);

output.with_state_mut(|state| {
state.focus_stack.set_focus(window);
});

self.update_keyboard_focus(&output);

self.schedule_render(&output);
}
}
ActivationContext::UrgentOnly => {
// TODO: add urgent state to windows, use in a focus border/taskbar flash
}
}
}
}
delegate_xdg_activation!(State);

impl Pinnacle {
fn position_popup(&self, popup: &PopupSurface) {
trace!("State::position_popup");
Expand Down
3 changes: 3 additions & 0 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ use smithay::{
socket::ListeningSocketSource,
tablet_manager::TabletManagerState,
viewporter::ViewporterState,
xdg_activation::XdgActivationState,
xwayland_keyboard_grab::XWaylandKeyboardGrabState,
xwayland_shell::XWaylandShellState,
},
Expand Down Expand Up @@ -120,6 +121,7 @@ pub struct Pinnacle {
pub tablet_manager_state: TabletManagerState,
pub keyboard_shortcuts_inhibit_state: KeyboardShortcutsInhibitState,
pub xwayland_keyboard_grab_state: XWaylandKeyboardGrabState,
pub xdg_activation_state: XdgActivationState,

pub lock_state: LockState,

Expand Down Expand Up @@ -347,6 +349,7 @@ impl Pinnacle {
&display_handle,
),
xwayland_keyboard_grab_state: XWaylandKeyboardGrabState::new::<State>(&display_handle),
xdg_activation_state: XdgActivationState::new::<State>(&display_handle),

lock_state: LockState::default(),

Expand Down

0 comments on commit e50c24c

Please sign in to comment.