autocommit 2022-04-18 13:38:52 CEST
This commit is contained in:
parent
c11d299fb8
commit
085ca95835
12 changed files with 86 additions and 28 deletions
|
|
@ -1,3 +1,4 @@
|
|||
use std::collections::VecDeque;
|
||||
use bstr::ByteSlice;
|
||||
pub use error::{ClientError, MethodError, ObjectError};
|
||||
use {
|
||||
|
|
@ -134,9 +135,9 @@ impl Clients {
|
|||
tracker: Default::default(),
|
||||
is_xwayland,
|
||||
secure,
|
||||
last_serial: Cell::new(0),
|
||||
last_enter_serial: Cell::new(0),
|
||||
pid_info: get_pid_info(uid, pid),
|
||||
serials: Default::default(),
|
||||
});
|
||||
track!(data, data);
|
||||
let display = Rc::new(WlDisplay::new(&data));
|
||||
|
|
@ -241,9 +242,16 @@ pub struct Client {
|
|||
pub tracker: Tracker<Client>,
|
||||
pub is_xwayland: bool,
|
||||
pub secure: bool,
|
||||
pub last_serial: Cell<u32>,
|
||||
pub last_enter_serial: Cell<u32>,
|
||||
pub pid_info: PidInfo,
|
||||
pub serials: RefCell<VecDeque<SerialRange>>,
|
||||
}
|
||||
|
||||
pub const NUM_CACHED_SERIAL_RANGES: usize = 64;
|
||||
|
||||
pub struct SerialRange {
|
||||
pub lo: u32,
|
||||
pub hi: u32,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
|
|
@ -271,12 +279,17 @@ impl Client {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn validate_serial(&self, serial: u32) -> Result<(), ClientError> {
|
||||
if serial > self.last_serial.get() {
|
||||
Err(ClientError::InvalidSerial)
|
||||
} else {
|
||||
Ok(())
|
||||
pub fn valid_serial(&self, serial: u32) -> bool {
|
||||
let serials = self.serials.borrow_mut();
|
||||
for range in serials.iter().rev() {
|
||||
if serial.wrapping_sub(range.hi) as i32 > 0 {
|
||||
return false;
|
||||
}
|
||||
if serial.wrapping_sub(range.lo) as i32 >= 0 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
serials.len() == NUM_CACHED_SERIAL_RANGES
|
||||
}
|
||||
|
||||
pub fn next_serial(&self) -> u32 {
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@ use {
|
|||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ClientError {
|
||||
#[error("Client sent an invalid serial")]
|
||||
InvalidSerial,
|
||||
#[error("An error occurred in the async engine")]
|
||||
Async(#[from] AsyncError),
|
||||
#[error("An error occurred reading from/writing to the client")]
|
||||
|
|
|
|||
|
|
@ -94,7 +94,10 @@ impl WlDataDevice {
|
|||
|
||||
fn start_drag(&self, parser: MsgParser<'_, '_>) -> Result<(), StartDragError> {
|
||||
let req: StartDrag = self.manager.client.parse(self, parser)?;
|
||||
self.manager.client.validate_serial(req.serial)?;
|
||||
if !self.manager.client.valid_serial(req.serial) {
|
||||
log::warn!("Client tried to start_drag with an invalid serial");
|
||||
return Ok(());
|
||||
}
|
||||
let origin = self.manager.client.lookup(req.origin)?;
|
||||
let source = if req.source.is_some() {
|
||||
Some(self.manager.client.lookup(req.source)?)
|
||||
|
|
@ -116,7 +119,10 @@ impl WlDataDevice {
|
|||
|
||||
fn set_selection(&self, parser: MsgParser<'_, '_>) -> Result<(), SetSelectionError> {
|
||||
let req: SetSelection = self.manager.client.parse(self, parser)?;
|
||||
self.manager.client.validate_serial(req.serial)?;
|
||||
if !self.manager.client.valid_serial(req.serial) {
|
||||
log::warn!("Client tried to set_selection with an invalid serial");
|
||||
return Ok(());
|
||||
}
|
||||
if !self
|
||||
.seat
|
||||
.global
|
||||
|
|
|
|||
|
|
@ -63,7 +63,10 @@ impl ZwpPrimarySelectionDeviceV1 {
|
|||
|
||||
fn set_selection(&self, parser: MsgParser<'_, '_>) -> Result<(), SetSelectionError> {
|
||||
let req: SetSelection = self.manager.client.parse(self, parser)?;
|
||||
self.seat.client.validate_serial(req.serial)?;
|
||||
if !self.manager.client.valid_serial(req.serial) {
|
||||
log::warn!("Client tried to set_selection with an invalid serial");
|
||||
return Ok(());
|
||||
}
|
||||
if !self
|
||||
.seat
|
||||
.global
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ impl KbOwner for DefaultKbOwner {
|
|||
if old.node_id() == node.node_id() {
|
||||
return;
|
||||
}
|
||||
log::info!("unfocus {}", old.node_id());
|
||||
// log::info!("unfocus {}", old.node_id());
|
||||
if old.node_is_xwayland_surface() && !node.node_is_xwayland_surface() {
|
||||
seat.state.xwayland.queue.push(XWaylandEvent::ActivateRoot);
|
||||
}
|
||||
|
|
@ -72,7 +72,7 @@ impl KbOwner for DefaultKbOwner {
|
|||
if node.node_seat_state().focus(seat) {
|
||||
node.node_active_changed(true);
|
||||
}
|
||||
log::info!("focus {}", node.node_id());
|
||||
// log::info!("focus {}", node.node_id());
|
||||
node.clone().node_focus(seat);
|
||||
seat.keyboard_node.set(node.clone());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,7 +156,10 @@ impl WlPointer {
|
|||
|
||||
fn set_cursor(&self, parser: MsgParser<'_, '_>) -> Result<(), SetCursorError> {
|
||||
let req: SetCursor = self.seat.client.parse(self, parser)?;
|
||||
self.seat.client.validate_serial(req.serial)?;
|
||||
if !self.seat.client.valid_serial(req.serial) {
|
||||
log::warn!("Client tried to set_cursor with an invalid serial");
|
||||
return Ok(());
|
||||
}
|
||||
let mut cursor_opt = None;
|
||||
if req.surface.is_some() {
|
||||
let surface = self.seat.client.lookup(req.surface)?;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use {
|
|||
leaks::Tracker,
|
||||
object::Object,
|
||||
utils::buffd::{MsgParser, MsgParserError},
|
||||
wire::{zwp_idle_inhibitor_v1::*, WlSurfaceId, ZwpIdleInhibitorV1Id},
|
||||
wire::{zwp_idle_inhibitor_v1::*, ZwpIdleInhibitorV1Id},
|
||||
},
|
||||
std::rc::Rc,
|
||||
thiserror::Error,
|
||||
|
|
@ -23,6 +23,7 @@ pub struct ZwpIdleInhibitorV1 {
|
|||
|
||||
impl ZwpIdleInhibitorV1 {
|
||||
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), ZwpIdleInhibitorV1Error> {
|
||||
log::info!("destroy {}", self.id);
|
||||
let _req: Destroy = self.client.parse(self, parser)?;
|
||||
self.client.remove_obj(self)?;
|
||||
if self.surface.idle_inhibitors.remove(&self.id).is_some() {
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ impl ZwpIdleInhibitManagerV1 {
|
|||
) -> Result<(), ZwpIdleInhibitManagerV1Error> {
|
||||
let req: CreateInhibitor = self.client.parse(self, parser)?;
|
||||
let surface = self.client.lookup(req.surface)?;
|
||||
log::info!("create {}", req.id);
|
||||
let inhibit = Rc::new(ZwpIdleInhibitorV1 {
|
||||
id: req.id,
|
||||
inhibit_id: self.client.state.idle_inhibitor_ids.next(),
|
||||
|
|
|
|||
20
src/state.rs
20
src/state.rs
|
|
@ -47,6 +47,7 @@ use {
|
|||
time::Duration,
|
||||
},
|
||||
};
|
||||
use crate::client::{NUM_CACHED_SERIAL_RANGES, SerialRange};
|
||||
|
||||
pub struct State {
|
||||
pub xkb_ctx: XkbContext,
|
||||
|
|
@ -359,8 +360,23 @@ impl State {
|
|||
pub fn next_serial(&self, client: Option<&Client>) -> u32 {
|
||||
let serial = self.serial.fetch_add(Wrapping(1)).0;
|
||||
if let Some(client) = client {
|
||||
client.last_serial.set(serial);
|
||||
'update_range: {
|
||||
let mut serials = client.serials.borrow_mut();
|
||||
if let Some(last) = serials.back_mut() {
|
||||
if last.hi.wrapping_add(1) == serial {
|
||||
last.hi = serial;
|
||||
break 'update_range;
|
||||
}
|
||||
}
|
||||
if serials.len() >= NUM_CACHED_SERIAL_RANGES {
|
||||
serials.pop_front();
|
||||
}
|
||||
serials.push_back(SerialRange {
|
||||
lo: serial,
|
||||
hi: serial,
|
||||
});
|
||||
}
|
||||
}
|
||||
serial
|
||||
serial as _
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -435,9 +435,9 @@ impl Wm {
|
|||
}
|
||||
|
||||
async fn focus_window(&mut self, window: Option<&Rc<XwindowData>>) {
|
||||
log::info!("xwm focus_window {:?}", window.map(|w| w.window_id));
|
||||
// log::info!("xwm focus_window {:?}", window.map(|w| w.window_id));
|
||||
if let Some(old) = mem::replace(&mut self.focus_window, window.cloned()) {
|
||||
log::info!("xwm unfocus {:?}", old.window_id);
|
||||
// log::info!("xwm unfocus {:?}", old.window_id);
|
||||
self.set_net_wm_state(&old).await;
|
||||
}
|
||||
let window = match window {
|
||||
|
|
@ -458,7 +458,7 @@ impl Wm {
|
|||
}
|
||||
};
|
||||
if window.info.override_redirect.get() {
|
||||
log::info!("xwm or => return");
|
||||
// log::info!("xwm or => return");
|
||||
return;
|
||||
}
|
||||
if let Some(window) = window.window.get() {
|
||||
|
|
@ -558,7 +558,7 @@ impl Wm {
|
|||
return;
|
||||
}
|
||||
}
|
||||
log::info!("{} role {}", data.window_id, buf.as_bstr());
|
||||
// log::info!("{} role {}", data.window_id, buf.as_bstr());
|
||||
*data.info.role.borrow_mut() = Some(buf.into());
|
||||
}
|
||||
|
||||
|
|
@ -995,13 +995,13 @@ impl Wm {
|
|||
|
||||
async fn handle_focus_in(&mut self, revent: &Event) -> Result<(), XWaylandError> {
|
||||
let event: FocusIn = revent.parse()?;
|
||||
log::info!("xwm focus_in {}", event.event);
|
||||
// log::info!("xwm focus_in {}", event.event);
|
||||
if matches!(event.mode, NOTIFY_MODE_GRAB | NOTIFY_MODE_UNGRAB) {
|
||||
log::info!("xwm GRAB/UNGRAB");
|
||||
// log::info!("xwm GRAB/UNGRAB");
|
||||
return Ok(());
|
||||
}
|
||||
if matches!(event.detail, NOTIFY_DETAIL_POINTER) {
|
||||
log::info!("xwm POINTER");
|
||||
// log::info!("xwm POINTER");
|
||||
return Ok(());
|
||||
}
|
||||
let new_window = self.windows.get(&event.event);
|
||||
|
|
@ -1014,7 +1014,7 @@ impl Wm {
|
|||
&& prev_pid == new_pid
|
||||
&& revent.serial() >= self.last_input_serial
|
||||
{
|
||||
log::info!("xwm ACCEPT");
|
||||
// log::info!("xwm ACCEPT");
|
||||
focus_window = new_window;
|
||||
}
|
||||
}
|
||||
|
|
@ -1036,7 +1036,7 @@ impl Wm {
|
|||
}
|
||||
|
||||
async fn activate_window(&mut self, window: Option<&Rc<XwindowData>>) {
|
||||
log::info!("xwm activate_window {:?}", window.map(|w| w.window_id));
|
||||
// log::info!("xwm activate_window {:?}", window.map(|w| w.window_id));
|
||||
if self.focus_window.as_ref().map(|w| w.window_id) == window.map(|w| w.window_id) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -1126,7 +1126,7 @@ impl Wm {
|
|||
Some(w) => w,
|
||||
_ => return Ok(()),
|
||||
};
|
||||
log::info!("xwm destroy_notify {}", event.window);
|
||||
// log::info!("xwm destroy_notify {}", event.window);
|
||||
data.destroyed.set(true);
|
||||
if let Some(sid) = data.surface_id.take() {
|
||||
self.windows_by_surface_id.remove(&sid);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue