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