From f0cdb235d71d4f0569d21a19c6878c29826e498e Mon Sep 17 00:00:00 2001 From: Poly Date: Sat, 31 Jul 2021 20:21:07 +0200 Subject: [PATCH] anvil: implement xdg-activation --- anvil/src/state.rs | 24 ++++++++++++++++++++++++ anvil/src/window_map.rs | 28 +++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/anvil/src/state.rs b/anvil/src/state.rs index ee6f9cd..72b977a 100644 --- a/anvil/src/state.rs +++ b/anvil/src/state.rs @@ -19,6 +19,7 @@ use smithay::{ seat::{CursorImageStatus, KeyboardHandle, PointerHandle, Seat, XkbConfig}, shm::init_shm_global, tablet_manager::{init_tablet_manager_global, TabletSeatTrait}, + xdg_activation::{init_xdg_activation_global, XdgActivationEvent}, }, }; @@ -85,6 +86,29 @@ impl AnvilState { let shell_handles = init_shell::(display.clone(), log.clone()); init_xdg_output_manager(&mut display.borrow_mut(), log.clone()); + init_xdg_activation_global( + &mut display.borrow_mut(), + |state, req, mut ddata| { + let anvil_state = ddata.get::>().unwrap(); + match req { + XdgActivationEvent::RequestActivation { + token, + token_data, + surface, + } => { + if token_data.timestamp.elapsed().as_secs() < 10 { + // Just grant the wish + anvil_state.window_map.borrow_mut().bring_surface_to_top(&surface); + } else { + // Discard the request + state.lock().unwrap().remove_request(&token); + } + } + XdgActivationEvent::DestroyActivationRequest { .. } => {} + } + }, + log.clone(), + ); let socket_name = if listen_on_socket { let socket_name = display diff --git a/anvil/src/window_map.rs b/anvil/src/window_map.rs index b96e334..100d8cc 100644 --- a/anvil/src/window_map.rs +++ b/anvil/src/window_map.rs @@ -2,7 +2,10 @@ use std::cell::RefCell; use std::sync::Mutex; use smithay::{ - reexports::{wayland_protocols::xdg_shell::server::xdg_toplevel, wayland_server::protocol::wl_surface}, + reexports::{ + wayland_protocols::xdg_shell::server::xdg_toplevel, + wayland_server::protocol::wl_surface::{self, WlSurface}, + }, utils::{Logical, Point, Rectangle}, wayland::{ compositor::{with_states, with_surface_tree_downward, SubsurfaceCachedState, TraversalAction}, @@ -297,6 +300,29 @@ impl WindowMap { None } + pub fn bring_surface_to_top(&mut self, surface: &WlSurface) { + let found = self.windows.iter().enumerate().find(|(_, w)| { + if let Some(s) = w.toplevel.get_surface() { + s.as_ref().equals(surface.as_ref()) + } else { + false + } + }); + + if let Some((i, _)) = found { + let winner = self.windows.remove(i); + + // Take activation away from all the windows + for window in self.windows.iter() { + window.toplevel.set_activated(false); + } + + // Give activation to our winner + winner.toplevel.set_activated(true); + self.windows.insert(0, winner); + } + } + pub fn get_surface_and_bring_to_top( &mut self, point: Point,