1
0
Fork 0
forked from wry/wry

autocommit 2022-04-18 13:38:52 CEST

This commit is contained in:
Julian Orth 2022-04-18 13:38:52 +02:00
parent c11d299fb8
commit 085ca95835
12 changed files with 86 additions and 28 deletions

16
protocols.md Normal file
View file

@ -0,0 +1,16 @@
- wayland
- wl_compositor
- todo: version 5
- wl_shm
- support for more formats
- wl_surface
- set_input_region
- damage
- transform
- scale
- offset
- wl_touch
- todo
- xdg-shell
- oeuo.e

View file

@ -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 {

View file

@ -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")]

View file

@ -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

View file

@ -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

View file

@ -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());
}

View file

@ -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)?;

View file

@ -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() {

View file

@ -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(),

View file

@ -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 _
}
}

View file

@ -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);

View file

@ -7,6 +7,7 @@
# done
- idle inhibit
- layer shell
- Float moving
- Float toggle