autocommit 2022-02-05 02:07:07 CET
This commit is contained in:
parent
89bfd2ffcd
commit
2d8b3a200e
21 changed files with 328 additions and 87 deletions
|
|
@ -6,7 +6,7 @@ use crate::ifs::wl_compositor::WlCompositorError;
|
||||||
use crate::ifs::wl_data_device::WlDataDeviceError;
|
use crate::ifs::wl_data_device::WlDataDeviceError;
|
||||||
use crate::ifs::wl_data_device_manager::WlDataDeviceManagerError;
|
use crate::ifs::wl_data_device_manager::WlDataDeviceManagerError;
|
||||||
use crate::ifs::wl_data_offer::WlDataOfferError;
|
use crate::ifs::wl_data_offer::WlDataOfferError;
|
||||||
use crate::ifs::wl_data_source::WlDataSourceError;
|
use crate::ifs::wl_data_source::{WlDataSourceError, WlDataSourceId};
|
||||||
use crate::ifs::wl_display::WlDisplayError;
|
use crate::ifs::wl_display::WlDisplayError;
|
||||||
use crate::ifs::wl_drm::WlDrmError;
|
use crate::ifs::wl_drm::WlDrmError;
|
||||||
use crate::ifs::wl_output::WlOutputError;
|
use crate::ifs::wl_output::WlOutputError;
|
||||||
|
|
@ -61,6 +61,8 @@ pub enum ClientError {
|
||||||
SurfaceDoesNotExist(WlSurfaceId),
|
SurfaceDoesNotExist(WlSurfaceId),
|
||||||
#[error("There is no xdg_surface with id {0}")]
|
#[error("There is no xdg_surface with id {0}")]
|
||||||
XdgSurfaceDoesNotExist(XdgSurfaceId),
|
XdgSurfaceDoesNotExist(XdgSurfaceId),
|
||||||
|
#[error("There is no wl_data_source with id {0}")]
|
||||||
|
WlDataSourceDoesNotExist(WlDataSourceId),
|
||||||
#[error("There is no xdg_toplevel with id {0}")]
|
#[error("There is no xdg_toplevel with id {0}")]
|
||||||
XdgToplevelDoesNotExist(XdgToplevelId),
|
XdgToplevelDoesNotExist(XdgToplevelId),
|
||||||
#[error("There is no xdg_positioner with id {0}")]
|
#[error("There is no xdg_positioner with id {0}")]
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use crate::ifs::wl_compositor::WlCompositorObj;
|
||||||
use crate::ifs::wl_data_device::WlDataDevice;
|
use crate::ifs::wl_data_device::WlDataDevice;
|
||||||
use crate::ifs::wl_data_device_manager::WlDataDeviceManagerObj;
|
use crate::ifs::wl_data_device_manager::WlDataDeviceManagerObj;
|
||||||
use crate::ifs::wl_data_offer::WlDataOffer;
|
use crate::ifs::wl_data_offer::WlDataOffer;
|
||||||
use crate::ifs::wl_data_source::WlDataSource;
|
use crate::ifs::wl_data_source::{WlDataSource, WlDataSourceId};
|
||||||
use crate::ifs::wl_display::WlDisplay;
|
use crate::ifs::wl_display::WlDisplay;
|
||||||
use crate::ifs::wl_drm::WlDrmObj;
|
use crate::ifs::wl_drm::WlDrmObj;
|
||||||
use crate::ifs::wl_output::WlOutputObj;
|
use crate::ifs::wl_output::WlOutputObj;
|
||||||
|
|
@ -42,6 +42,7 @@ use crate::ErrorFmt;
|
||||||
use ahash::AHashMap;
|
use ahash::AHashMap;
|
||||||
pub use error::ClientError;
|
pub use error::ClientError;
|
||||||
use std::cell::{Cell, RefCell, RefMut};
|
use std::cell::{Cell, RefCell, RefMut};
|
||||||
|
use std::error::Error;
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
@ -273,6 +274,22 @@ impl Client {
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn error(&self, message: impl Error) {
|
||||||
|
let msg = ErrorFmt(message).to_string();
|
||||||
|
log::error!("Client {}: A fatal error occurred: {}", self.id.0, msg,);
|
||||||
|
match self.display() {
|
||||||
|
Ok(d) => self.fatal_event(d.implementation_error(msg)),
|
||||||
|
Err(e) => {
|
||||||
|
log::error!(
|
||||||
|
"Could not retrieve display of client {}: {}",
|
||||||
|
self.id,
|
||||||
|
ErrorFmt(e),
|
||||||
|
);
|
||||||
|
self.state.clients.kill(self.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn protocol_error(&self, obj: &dyn Object, code: u32, message: String) {
|
pub fn protocol_error(&self, obj: &dyn Object, code: u32, message: String) {
|
||||||
if let Ok(d) = self.display() {
|
if let Ok(d) = self.display() {
|
||||||
self.fatal_event(d.error(obj.id(), code, message));
|
self.fatal_event(d.error(obj.id(), code, message));
|
||||||
|
|
@ -343,6 +360,13 @@ impl Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_wl_data_source(&self, id: WlDataSourceId) -> Result<Rc<WlDataSource>, ClientError> {
|
||||||
|
match self.objects.wl_data_source.get(&id) {
|
||||||
|
Some(r) => Ok(r),
|
||||||
|
_ => Err(ClientError::WlDataSourceDoesNotExist(id)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_xdg_toplevel(&self, id: XdgToplevelId) -> Result<Rc<XdgToplevel>, ClientError> {
|
pub fn get_xdg_toplevel(&self, id: XdgToplevelId) -> Result<Rc<XdgToplevel>, ClientError> {
|
||||||
match self.objects.xdg_toplevel.get(&id) {
|
match self.objects.xdg_toplevel.get(&id) {
|
||||||
Some(r) => Ok(r),
|
Some(r) => Ok(r),
|
||||||
|
|
@ -440,7 +464,6 @@ simple_add_obj!(WlTouch);
|
||||||
simple_add_obj!(WlDataDeviceManagerObj);
|
simple_add_obj!(WlDataDeviceManagerObj);
|
||||||
simple_add_obj!(WlDataDevice);
|
simple_add_obj!(WlDataDevice);
|
||||||
simple_add_obj!(WlDataOffer);
|
simple_add_obj!(WlDataOffer);
|
||||||
simple_add_obj!(WlDataSource);
|
|
||||||
simple_add_obj!(ZwpLinuxDmabufV1Obj);
|
simple_add_obj!(ZwpLinuxDmabufV1Obj);
|
||||||
simple_add_obj!(ZwpLinuxBufferParamsV1);
|
simple_add_obj!(ZwpLinuxBufferParamsV1);
|
||||||
simple_add_obj!(WlDrmObj);
|
simple_add_obj!(WlDrmObj);
|
||||||
|
|
@ -470,3 +493,4 @@ dedicated_add_obj!(WlBuffer, buffers);
|
||||||
dedicated_add_obj!(WlSeatObj, seats);
|
dedicated_add_obj!(WlSeatObj, seats);
|
||||||
dedicated_add_obj!(XdgPositioner, xdg_positioners);
|
dedicated_add_obj!(XdgPositioner, xdg_positioners);
|
||||||
dedicated_add_obj!(XdgToplevel, xdg_toplevel);
|
dedicated_add_obj!(XdgToplevel, xdg_toplevel);
|
||||||
|
dedicated_add_obj!(WlDataSource, wl_data_source);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::client::{Client, ClientError};
|
use crate::client::{Client, ClientError};
|
||||||
use crate::ifs::wl_buffer::{WlBuffer, WlBufferId};
|
use crate::ifs::wl_buffer::{WlBuffer, WlBufferId};
|
||||||
|
use crate::ifs::wl_data_source::{WlDataSource, WlDataSourceId};
|
||||||
use crate::ifs::wl_display::WlDisplay;
|
use crate::ifs::wl_display::WlDisplay;
|
||||||
use crate::ifs::wl_region::{WlRegion, WlRegionId};
|
use crate::ifs::wl_region::{WlRegion, WlRegionId};
|
||||||
use crate::ifs::wl_registry::{WlRegistry, WlRegistryId};
|
use crate::ifs::wl_registry::{WlRegistry, WlRegistryId};
|
||||||
|
|
@ -25,6 +26,7 @@ pub struct Objects {
|
||||||
pub surfaces: CopyHashMap<WlSurfaceId, Rc<WlSurface>>,
|
pub surfaces: CopyHashMap<WlSurfaceId, Rc<WlSurface>>,
|
||||||
pub xdg_surfaces: CopyHashMap<XdgSurfaceId, Rc<XdgSurface>>,
|
pub xdg_surfaces: CopyHashMap<XdgSurfaceId, Rc<XdgSurface>>,
|
||||||
pub xdg_toplevel: CopyHashMap<XdgToplevelId, Rc<XdgToplevel>>,
|
pub xdg_toplevel: CopyHashMap<XdgToplevelId, Rc<XdgToplevel>>,
|
||||||
|
pub wl_data_source: CopyHashMap<WlDataSourceId, Rc<WlDataSource>>,
|
||||||
pub xdg_positioners: CopyHashMap<XdgPositionerId, Rc<XdgPositioner>>,
|
pub xdg_positioners: CopyHashMap<XdgPositionerId, Rc<XdgPositioner>>,
|
||||||
pub regions: CopyHashMap<WlRegionId, Rc<WlRegion>>,
|
pub regions: CopyHashMap<WlRegionId, Rc<WlRegion>>,
|
||||||
pub buffers: CopyHashMap<WlBufferId, Rc<WlBuffer>>,
|
pub buffers: CopyHashMap<WlBufferId, Rc<WlBuffer>>,
|
||||||
|
|
@ -45,6 +47,7 @@ impl Objects {
|
||||||
surfaces: Default::default(),
|
surfaces: Default::default(),
|
||||||
xdg_surfaces: Default::default(),
|
xdg_surfaces: Default::default(),
|
||||||
xdg_toplevel: Default::default(),
|
xdg_toplevel: Default::default(),
|
||||||
|
wl_data_source: Default::default(),
|
||||||
xdg_positioners: Default::default(),
|
xdg_positioners: Default::default(),
|
||||||
regions: Default::default(),
|
regions: Default::default(),
|
||||||
buffers: Default::default(),
|
buffers: Default::default(),
|
||||||
|
|
@ -141,8 +144,9 @@ impl Objects {
|
||||||
return Err(ClientError::ServerIdOutOfBounds);
|
return Err(ClientError::ServerIdOutOfBounds);
|
||||||
}
|
}
|
||||||
ids[pos] |= 1 << seg_offset;
|
ids[pos] |= 1 << seg_offset;
|
||||||
|
} else {
|
||||||
|
client_data.event(client_data.display()?.delete_id(id));
|
||||||
}
|
}
|
||||||
client_data.event(client_data.display()?.delete_id(id));
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
use crate::client::{Client, DynEventFormatter};
|
use crate::client::{DynEventFormatter};
|
||||||
use crate::ifs::wl_data_device_manager::WlDataDeviceManagerObj;
|
use crate::ifs::wl_data_device_manager::WlDataDeviceManagerObj;
|
||||||
use crate::ifs::wl_data_offer::WlDataOfferId;
|
use crate::ifs::wl_data_offer::WlDataOfferId;
|
||||||
use crate::ifs::wl_seat::WlSeatObj;
|
use crate::ifs::wl_seat::{WlSeatObj};
|
||||||
use crate::object::{Interface, Object, ObjectId};
|
use crate::object::{Interface, Object, ObjectId};
|
||||||
use crate::utils::buffd::MsgParser;
|
use crate::utils::buffd::MsgParser;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
@ -28,7 +28,6 @@ id!(WlDataDeviceId);
|
||||||
pub struct WlDataDevice {
|
pub struct WlDataDevice {
|
||||||
pub id: WlDataDeviceId,
|
pub id: WlDataDeviceId,
|
||||||
pub manager: Rc<WlDataDeviceManagerObj>,
|
pub manager: Rc<WlDataDeviceManagerObj>,
|
||||||
client: Rc<Client>,
|
|
||||||
seat: Rc<WlSeatObj>,
|
seat: Rc<WlSeatObj>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,11 +40,17 @@ impl WlDataDevice {
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
manager: manager.clone(),
|
manager: manager.clone(),
|
||||||
client: seat.client().clone(),
|
|
||||||
seat: seat.clone(),
|
seat: seat.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn data_offer(self: &Rc<Self>, id: WlDataOfferId) -> DynEventFormatter {
|
||||||
|
Box::new(DataOffer {
|
||||||
|
obj: self.clone(),
|
||||||
|
id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn selection(self: &Rc<Self>, id: WlDataOfferId) -> DynEventFormatter {
|
pub fn selection(self: &Rc<Self>, id: WlDataOfferId) -> DynEventFormatter {
|
||||||
Box::new(Selection {
|
Box::new(Selection {
|
||||||
obj: self.clone(),
|
obj: self.clone(),
|
||||||
|
|
@ -54,19 +59,25 @@ impl WlDataDevice {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_drag(&self, parser: MsgParser<'_, '_>) -> Result<(), StartDragError> {
|
fn start_drag(&self, parser: MsgParser<'_, '_>) -> Result<(), StartDragError> {
|
||||||
let _req: StartDrag = self.client.parse(self, parser)?;
|
let _req: StartDrag = self.manager.client.parse(self, parser)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_selection(&self, parser: MsgParser<'_, '_>) -> Result<(), SetSelectionError> {
|
fn set_selection(&self, parser: MsgParser<'_, '_>) -> Result<(), SetSelectionError> {
|
||||||
let _req: SetSelection = self.client.parse(self, parser)?;
|
let req: SetSelection = self.manager.client.parse(self, parser)?;
|
||||||
|
let src = if req.source.is_none() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(self.manager.client.get_wl_data_source(req.source)?)
|
||||||
|
};
|
||||||
|
self.seat.global.set_selection(src)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn release(&self, parser: MsgParser<'_, '_>) -> Result<(), ReleaseError> {
|
fn release(&self, parser: MsgParser<'_, '_>) -> Result<(), ReleaseError> {
|
||||||
let _req: Release = self.client.parse(self, parser)?;
|
let _req: Release = self.manager.client.parse(self, parser)?;
|
||||||
self.seat.remove_data_device(self);
|
self.seat.remove_data_device(self);
|
||||||
self.client.remove_obj(self)?;
|
self.manager.client.remove_obj(self)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::client::{ClientError, EventFormatter, RequestParser};
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::wl_data_device::{WlDataDevice, DATA_OFFER, DROP, ENTER, LEAVE, MOTION, SELECTION};
|
use crate::ifs::wl_data_device::{WlDataDevice, DATA_OFFER, DROP, ENTER, LEAVE, MOTION, SELECTION};
|
||||||
use crate::ifs::wl_data_offer::WlDataOfferId;
|
use crate::ifs::wl_data_offer::WlDataOfferId;
|
||||||
use crate::ifs::wl_data_source::WlDataSourceId;
|
use crate::ifs::wl_data_source::{WlDataSourceError, WlDataSourceId};
|
||||||
use crate::ifs::wl_surface::WlSurfaceId;
|
use crate::ifs::wl_surface::WlSurfaceId;
|
||||||
use crate::object::Object;
|
use crate::object::Object;
|
||||||
use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError};
|
use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError};
|
||||||
|
|
@ -39,9 +39,12 @@ pub enum SetSelectionError {
|
||||||
ParseFailed(#[source] Box<MsgParserError>),
|
ParseFailed(#[source] Box<MsgParserError>),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
ClientError(Box<ClientError>),
|
ClientError(Box<ClientError>),
|
||||||
|
#[error(transparent)]
|
||||||
|
WlDataSourceError(Box<WlDataSourceError>),
|
||||||
}
|
}
|
||||||
efrom!(SetSelectionError, ParseFailed, MsgParserError);
|
efrom!(SetSelectionError, ParseFailed, MsgParserError);
|
||||||
efrom!(SetSelectionError, ClientError);
|
efrom!(SetSelectionError, ClientError);
|
||||||
|
efrom!(SetSelectionError, WlDataSourceError);
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum ReleaseError {
|
pub enum ReleaseError {
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ pub struct WlDataDeviceManagerGlobal {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WlDataDeviceManagerObj {
|
pub struct WlDataDeviceManagerObj {
|
||||||
id: WlDataDeviceManagerId,
|
pub id: WlDataDeviceManagerId,
|
||||||
client: Rc<Client>,
|
pub client: Rc<Client>,
|
||||||
pub version: u32,
|
pub version: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
use crate::client::Client;
|
use crate::client::{Client, DynEventFormatter};
|
||||||
|
use crate::ifs::wl_data_source::{WlDataSource};
|
||||||
|
use crate::ifs::wl_seat::WlSeatGlobal;
|
||||||
use crate::object::{Interface, Object, ObjectId};
|
use crate::object::{Interface, Object, ObjectId};
|
||||||
use crate::utils::buffd::MsgParser;
|
use crate::utils::buffd::MsgParser;
|
||||||
|
use crate::utils::clonecell::CloneCell;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
pub use types::*;
|
pub use types::*;
|
||||||
|
|
||||||
|
|
@ -27,24 +31,83 @@ const INVALID_OFFER: u32 = 3;
|
||||||
|
|
||||||
id!(WlDataOfferId);
|
id!(WlDataOfferId);
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
|
pub enum DataOfferRole {
|
||||||
|
Selection,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WlDataOffer {
|
pub struct WlDataOffer {
|
||||||
id: WlDataOfferId,
|
pub id: WlDataOfferId,
|
||||||
client: Rc<Client>,
|
pub client: Rc<Client>,
|
||||||
|
pub role: DataOfferRole,
|
||||||
|
pub source: CloneCell<Option<Rc<WlDataSource>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WlDataOffer {
|
impl WlDataOffer {
|
||||||
|
pub fn create(
|
||||||
|
client: &Rc<Client>,
|
||||||
|
role: DataOfferRole,
|
||||||
|
src: &Rc<WlDataSource>,
|
||||||
|
seat: &Rc<WlSeatGlobal>,
|
||||||
|
) -> Option<Rc<Self>> {
|
||||||
|
let id = match client.new_id() {
|
||||||
|
Ok(id) => id,
|
||||||
|
Err(e) => {
|
||||||
|
client.error(e);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let slf = Rc::new(Self {
|
||||||
|
id,
|
||||||
|
client: client.clone(),
|
||||||
|
role,
|
||||||
|
source: CloneCell::new(Some(src.clone())),
|
||||||
|
});
|
||||||
|
let mt = src.mime_types.borrow_mut();
|
||||||
|
seat.for_each_data_device(0, client.id, |device| {
|
||||||
|
client.event(device.data_offer(slf.id));
|
||||||
|
for mt in mt.deref() {
|
||||||
|
client.event(slf.offer(mt));
|
||||||
|
}
|
||||||
|
let ev = match role {
|
||||||
|
DataOfferRole::Selection => device.selection(id),
|
||||||
|
};
|
||||||
|
client.event(ev);
|
||||||
|
});
|
||||||
|
client.add_server_obj(&slf);
|
||||||
|
Some(slf)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn offer(self: &Rc<Self>, mime_type: &str) -> DynEventFormatter {
|
||||||
|
Box::new(Offer {
|
||||||
|
obj: self.clone(),
|
||||||
|
mime_type: mime_type.to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn accept(&self, parser: MsgParser<'_, '_>) -> Result<(), AcceptError> {
|
fn accept(&self, parser: MsgParser<'_, '_>) -> Result<(), AcceptError> {
|
||||||
let _req: Accept = self.client.parse(self, parser)?;
|
let _req: Accept = self.client.parse(self, parser)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive(&self, parser: MsgParser<'_, '_>) -> Result<(), ReceiveError> {
|
fn receive(&self, parser: MsgParser<'_, '_>) -> Result<(), ReceiveError> {
|
||||||
let _req: Receive = self.client.parse(self, parser)?;
|
let req: Receive = self.client.parse(self, parser)?;
|
||||||
|
if let Some(src) = self.source.get() {
|
||||||
|
src.client.event(src.send(req.mime_type, req.fd));
|
||||||
|
src.client.flush();
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn disconnect(&self) {
|
||||||
|
if let Some(src) = self.source.set(None) {
|
||||||
|
src.destroy_offer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
|
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
|
||||||
let _req: Destroy = self.client.parse(self, parser)?;
|
let _req: Destroy = self.client.parse(self, parser)?;
|
||||||
|
self.disconnect();
|
||||||
self.client.remove_obj(self)?;
|
self.client.remove_obj(self)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -90,4 +153,8 @@ impl Object for WlDataOffer {
|
||||||
fn num_requests(&self) -> u32 {
|
fn num_requests(&self) -> u32 {
|
||||||
SET_ACTIONS + 1
|
SET_ACTIONS + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn break_loops(&self) {
|
||||||
|
self.disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::client::{ClientError, EventFormatter, RequestParser};
|
||||||
use crate::ifs::wl_data_offer::{WlDataOffer, ACTION, OFFER, SOURCE_ACTIONS};
|
use crate::ifs::wl_data_offer::{WlDataOffer, ACTION, OFFER, SOURCE_ACTIONS};
|
||||||
use crate::object::Object;
|
use crate::object::Object;
|
||||||
use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError};
|
use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError};
|
||||||
use bstr::{BStr, BString};
|
use bstr::{BStr};
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
@ -83,7 +83,7 @@ impl<'a> RequestParser<'a> for Accept<'a> {
|
||||||
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
serial: parser.uint()?,
|
serial: parser.uint()?,
|
||||||
mime_type: parser.string()?,
|
mime_type: parser.bstr()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -98,13 +98,13 @@ impl Debug for Accept<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct Receive<'a> {
|
pub(super) struct Receive<'a> {
|
||||||
pub mime_type: &'a BStr,
|
pub mime_type: &'a str,
|
||||||
pub fd: OwnedFd,
|
pub fd: OwnedFd,
|
||||||
}
|
}
|
||||||
impl<'a> RequestParser<'a> for Receive<'a> {
|
impl<'a> RequestParser<'a> for Receive<'a> {
|
||||||
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
mime_type: parser.string()?,
|
mime_type: parser.str()?,
|
||||||
fd: parser.fd()?,
|
fd: parser.fd()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +168,7 @@ impl Debug for SetActions {
|
||||||
|
|
||||||
pub(super) struct Offer {
|
pub(super) struct Offer {
|
||||||
pub obj: Rc<WlDataOffer>,
|
pub obj: Rc<WlDataOffer>,
|
||||||
pub mime_type: BString,
|
pub mime_type: String,
|
||||||
}
|
}
|
||||||
impl EventFormatter for Offer {
|
impl EventFormatter for Offer {
|
||||||
fn format(self: Box<Self>, fmt: &mut MsgFormatter<'_>) {
|
fn format(self: Box<Self>, fmt: &mut MsgFormatter<'_>) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,15 @@
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
use crate::client::Client;
|
use crate::client::{Client, DynEventFormatter};
|
||||||
|
use crate::ifs::wl_data_offer::{DataOfferRole, WlDataOffer};
|
||||||
|
use crate::ifs::wl_seat::WlSeatGlobal;
|
||||||
use crate::object::{Interface, Object, ObjectId};
|
use crate::object::{Interface, Object, ObjectId};
|
||||||
use crate::utils::buffd::MsgParser;
|
use crate::utils::buffd::MsgParser;
|
||||||
|
use crate::utils::clonecell::{CloneCell, UnsafeCellCloneSafe};
|
||||||
|
use ahash::AHashSet;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use uapi::OwnedFd;
|
||||||
pub use types::*;
|
pub use types::*;
|
||||||
|
|
||||||
const OFFER: u32 = 0;
|
const OFFER: u32 = 0;
|
||||||
|
|
@ -24,9 +30,20 @@ const INVALID_SOURCE: u32 = 1;
|
||||||
|
|
||||||
id!(WlDataSourceId);
|
id!(WlDataSourceId);
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Attachment {
|
||||||
|
seat: Rc<WlSeatGlobal>,
|
||||||
|
role: DataOfferRole,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl UnsafeCellCloneSafe for Attachment {}
|
||||||
|
|
||||||
pub struct WlDataSource {
|
pub struct WlDataSource {
|
||||||
id: WlDataSourceId,
|
pub id: WlDataSourceId,
|
||||||
client: Rc<Client>,
|
pub client: Rc<Client>,
|
||||||
|
pub mime_types: RefCell<AHashSet<String>>,
|
||||||
|
attachment: CloneCell<Option<Attachment>>,
|
||||||
|
offer: CloneCell<Option<Rc<WlDataOffer>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WlDataSource {
|
impl WlDataSource {
|
||||||
|
|
@ -34,16 +51,101 @@ impl WlDataSource {
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
|
mime_types: RefCell::new(Default::default()),
|
||||||
|
attachment: Default::default(),
|
||||||
|
offer: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offer(&self, parser: MsgParser<'_, '_>) -> Result<(), OfferError> {
|
pub fn attach(
|
||||||
let _req: Offer = self.client.parse(self, parser)?;
|
&self,
|
||||||
|
seat: &Rc<WlSeatGlobal>,
|
||||||
|
role: DataOfferRole,
|
||||||
|
) -> Result<(), WlDataSourceError> {
|
||||||
|
let old = self.attachment.set(
|
||||||
|
Some(Attachment {
|
||||||
|
seat: seat.clone(),
|
||||||
|
role,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
if old.is_some() {
|
||||||
|
return Err(WlDataSourceError::AlreadyAttached);
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn detach(self: &Rc<Self>) {
|
||||||
|
self.attachment.set(None);
|
||||||
|
if let Some(offer) = self.offer.set(None) {
|
||||||
|
offer.source.set(None);
|
||||||
|
}
|
||||||
|
self.client.event(self.cancelled());
|
||||||
|
self.client.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_offer(self: &Rc<Self>, client: &Rc<Client>) {
|
||||||
|
let attachment = match self.attachment.get() {
|
||||||
|
Some(a) => a,
|
||||||
|
_ => {
|
||||||
|
log::error!("Trying to create an offer from a unattached data source");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let offer = WlDataOffer::create(client, attachment.role, self, &attachment.seat);
|
||||||
|
let old = self.offer.set(offer);
|
||||||
|
if let Some(offer) = old {
|
||||||
|
offer.source.set(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy_offer(&self) {
|
||||||
|
self.offer.take();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cancelled(self: &Rc<Self>) -> DynEventFormatter {
|
||||||
|
Box::new(Cancelled {
|
||||||
|
obj: self.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send(self: &Rc<Self>, mime_type: &str, fd: OwnedFd) -> DynEventFormatter {
|
||||||
|
Box::new(Send {
|
||||||
|
obj: self.clone(),
|
||||||
|
mime_type: mime_type.to_string(),
|
||||||
|
fd: Rc::new(fd),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn offer(&self, parser: MsgParser<'_, '_>) -> Result<(), OfferError> {
|
||||||
|
let req: Offer = self.client.parse(self, parser)?;
|
||||||
|
if self
|
||||||
|
.mime_types
|
||||||
|
.borrow_mut()
|
||||||
|
.insert(req.mime_type.to_string())
|
||||||
|
{
|
||||||
|
if let Some(offer) = self.offer.get() {
|
||||||
|
offer.client.event(offer.offer(req.mime_type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn disconnect(&self) {
|
||||||
|
if let Some(offer) = self.offer.take() {
|
||||||
|
offer.source.set(None);
|
||||||
|
}
|
||||||
|
if let Some(attachment) = self.attachment.get() {
|
||||||
|
match attachment.role {
|
||||||
|
DataOfferRole::Selection => {
|
||||||
|
let _ = attachment.seat.set_selection(None);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
|
fn destroy(&self, parser: MsgParser<'_, '_>) -> Result<(), DestroyError> {
|
||||||
let _req: Destroy = self.client.parse(self, parser)?;
|
let _req: Destroy = self.client.parse(self, parser)?;
|
||||||
|
self.disconnect();
|
||||||
self.client.remove_obj(self)?;
|
self.client.remove_obj(self)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -82,4 +184,8 @@ impl Object for WlDataSource {
|
||||||
fn num_requests(&self) -> u32 {
|
fn num_requests(&self) -> u32 {
|
||||||
SET_ACTIONS + 1
|
SET_ACTIONS + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn break_loops(&self) {
|
||||||
|
self.disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use crate::ifs::wl_data_source::{
|
||||||
};
|
};
|
||||||
use crate::object::Object;
|
use crate::object::Object;
|
||||||
use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError};
|
use crate::utils::buffd::{MsgFormatter, MsgParser, MsgParserError};
|
||||||
use bstr::{BStr, BString};
|
use bstr::{BString};
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
@ -20,6 +20,8 @@ pub enum WlDataSourceError {
|
||||||
DestroyError(#[from] DestroyError),
|
DestroyError(#[from] DestroyError),
|
||||||
#[error("Could not process `set_actions` request")]
|
#[error("Could not process `set_actions` request")]
|
||||||
SetActionsError(#[from] SetActionsError),
|
SetActionsError(#[from] SetActionsError),
|
||||||
|
#[error("The data source is already attached")]
|
||||||
|
AlreadyAttached,
|
||||||
}
|
}
|
||||||
efrom!(WlDataSourceError, ClientError);
|
efrom!(WlDataSourceError, ClientError);
|
||||||
|
|
||||||
|
|
@ -54,12 +56,12 @@ efrom!(SetActionsError, ParseFailed, MsgParserError);
|
||||||
efrom!(SetActionsError, ClientError);
|
efrom!(SetActionsError, ClientError);
|
||||||
|
|
||||||
pub(super) struct Offer<'a> {
|
pub(super) struct Offer<'a> {
|
||||||
pub mime_type: &'a BStr,
|
pub mime_type: &'a str,
|
||||||
}
|
}
|
||||||
impl<'a> RequestParser<'a> for Offer<'a> {
|
impl<'a> RequestParser<'a> for Offer<'a> {
|
||||||
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
mime_type: parser.string()?,
|
mime_type: parser.str()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +119,7 @@ impl Debug for Target {
|
||||||
|
|
||||||
pub(super) struct Send {
|
pub(super) struct Send {
|
||||||
pub obj: Rc<WlDataSource>,
|
pub obj: Rc<WlDataSource>,
|
||||||
pub mime_type: BString,
|
pub mime_type: String,
|
||||||
pub fd: Rc<OwnedFd>,
|
pub fd: Rc<OwnedFd>,
|
||||||
}
|
}
|
||||||
impl EventFormatter for Send {
|
impl EventFormatter for Send {
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ impl<'a> RequestParser<'a> for Bind<'a> {
|
||||||
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
name: parser.global()?,
|
name: parser.global()?,
|
||||||
interface: parser.string()?,
|
interface: parser.bstr()?,
|
||||||
version: parser.uint()?,
|
version: parser.uint()?,
|
||||||
id: parser.object()?,
|
id: parser.object()?,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::backend::{KeyState, OutputId, ScrollAxis, SeatEvent, SeatId};
|
||||||
use crate::client::{ClientId, DynEventFormatter};
|
use crate::client::{ClientId, DynEventFormatter};
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::wl_data_device::WlDataDevice;
|
use crate::ifs::wl_data_device::WlDataDevice;
|
||||||
use crate::ifs::wl_data_offer::WlDataOfferId;
|
use crate::ifs::wl_data_offer::{WlDataOfferId};
|
||||||
use crate::ifs::wl_seat::wl_keyboard::WlKeyboard;
|
use crate::ifs::wl_seat::wl_keyboard::WlKeyboard;
|
||||||
use crate::ifs::wl_seat::wl_pointer::{WlPointer, POINTER_FRAME_SINCE_VERSION};
|
use crate::ifs::wl_seat::wl_pointer::{WlPointer, POINTER_FRAME_SINCE_VERSION};
|
||||||
use crate::ifs::wl_seat::{
|
use crate::ifs::wl_seat::{
|
||||||
|
|
@ -241,7 +241,18 @@ impl WlSeatGlobal {
|
||||||
k.modifiers(serial, mods_depressed, mods_latched, mods_locked, group)
|
k.modifiers(serial, mods_depressed, mods_latched, mods_locked, group)
|
||||||
});
|
});
|
||||||
|
|
||||||
self.surface_data_device_event(0, &surface, |dd| dd.selection(WlDataOfferId::NONE));
|
if old.client_id() != Some(surface.client.id) {
|
||||||
|
match self.selection.get() {
|
||||||
|
None => {
|
||||||
|
self.surface_data_device_event(0, &surface, |dd| {
|
||||||
|
dd.selection(WlDataOfferId::NONE)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Some(sel) => {
|
||||||
|
sel.create_offer(&surface.client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_each_seat<C>(&self, ver: u32, client: ClientId, mut f: C)
|
fn for_each_seat<C>(&self, ver: u32, client: ClientId, mut f: C)
|
||||||
|
|
@ -282,7 +293,7 @@ impl WlSeatGlobal {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_each_data_device<C>(&self, ver: u32, client: ClientId, mut f: C)
|
pub fn for_each_data_device<C>(&self, ver: u32, client: ClientId, mut f: C)
|
||||||
where
|
where
|
||||||
C: FnMut(&Rc<WlDataDevice>),
|
C: FnMut(&Rc<WlDataDevice>),
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ use crate::cursor::{Cursor, KnownCursor};
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::globals::{Global, GlobalName};
|
use crate::globals::{Global, GlobalName};
|
||||||
use crate::ifs::wl_data_device::{WlDataDevice, WlDataDeviceId};
|
use crate::ifs::wl_data_device::{WlDataDevice, WlDataDeviceId};
|
||||||
|
use crate::ifs::wl_data_offer::{DataOfferRole, WlDataOfferId};
|
||||||
|
use crate::ifs::wl_data_source::{WlDataSource, WlDataSourceError};
|
||||||
use crate::ifs::wl_seat::wl_keyboard::{WlKeyboard, WlKeyboardId, REPEAT_INFO_SINCE};
|
use crate::ifs::wl_seat::wl_keyboard::{WlKeyboard, WlKeyboardId, REPEAT_INFO_SINCE};
|
||||||
use crate::ifs::wl_seat::wl_pointer::{WlPointer, WlPointerId};
|
use crate::ifs::wl_seat::wl_pointer::{WlPointer, WlPointerId};
|
||||||
use crate::ifs::wl_seat::wl_touch::WlTouch;
|
use crate::ifs::wl_seat::wl_touch::WlTouch;
|
||||||
|
|
@ -95,6 +97,7 @@ pub struct WlSeatGlobal {
|
||||||
serial: NumCell<u32>,
|
serial: NumCell<u32>,
|
||||||
grabber: RefCell<Option<PointerGrabber>>,
|
grabber: RefCell<Option<PointerGrabber>>,
|
||||||
tree_changed: Rc<AsyncEvent>,
|
tree_changed: Rc<AsyncEvent>,
|
||||||
|
selection: CloneCell<Option<Rc<WlDataSource>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WlSeatGlobal {
|
impl WlSeatGlobal {
|
||||||
|
|
@ -144,20 +147,31 @@ impl WlSeatGlobal {
|
||||||
serial: Default::default(),
|
serial: Default::default(),
|
||||||
grabber: RefCell::new(None),
|
grabber: RefCell::new(None),
|
||||||
tree_changed: tree_changed.clone(),
|
tree_changed: tree_changed.clone(),
|
||||||
|
selection: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn grab_pointer(self: &Rc<Self>, node: Rc<dyn Node>) -> Option<PointerGrab> {
|
pub fn set_selection(self: &Rc<Self>, selection: Option<Rc<WlDataSource>>) -> Result<(), WlDataSourceError> {
|
||||||
// let mut grabber = self.grabber.borrow_mut();
|
if let Some(new) = &selection {
|
||||||
// if grabber.is_some() {
|
new.attach(self, DataOfferRole::Selection)?;
|
||||||
// return None;
|
}
|
||||||
// }
|
if let Some(old) = self.selection.set(selection.clone()) {
|
||||||
// *grabber = Some(PointerGrabber {
|
old.detach();
|
||||||
// node,
|
}
|
||||||
// buttons: Default::default(),
|
if let Some(client) = self.keyboard_node.get().client() {
|
||||||
// });
|
match selection {
|
||||||
// Some(PointerGrab { seat: self.clone() })
|
Some(sel) => {
|
||||||
// }
|
sel.create_offer(&client);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self.for_each_data_device(0, client.id, |device| {
|
||||||
|
client.event(device.selection(WlDataOfferId::NONE));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_known_cursor(&self, cursor: KnownCursor) {
|
pub fn set_known_cursor(&self, cursor: KnownCursor) {
|
||||||
let cursors = match self.state.cursors.get() {
|
let cursors = match self.state.cursors.get() {
|
||||||
|
|
@ -292,10 +306,6 @@ impl WlSeatObj {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn client(&self) -> &Rc<Client> {
|
|
||||||
&self.client
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn move_(&self, node: &Rc<FloatNode>) {
|
pub fn move_(&self, node: &Rc<FloatNode>) {
|
||||||
self.global.move_(node);
|
self.global.move_(node);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ pub mod wl_subsurface;
|
||||||
pub mod xdg_surface;
|
pub mod xdg_surface;
|
||||||
|
|
||||||
use crate::backend::{KeyState, ScrollAxis, SeatId};
|
use crate::backend::{KeyState, ScrollAxis, SeatId};
|
||||||
use crate::client::{Client, ClientId, DynEventFormatter, RequestParser};
|
use crate::client::{Client, DynEventFormatter, RequestParser};
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::wl_buffer::WlBuffer;
|
use crate::ifs::wl_buffer::WlBuffer;
|
||||||
use crate::ifs::wl_callback::WlCallback;
|
use crate::ifs::wl_callback::WlCallback;
|
||||||
|
|
@ -17,7 +17,9 @@ use crate::object::{Interface, Object, ObjectId};
|
||||||
use crate::pixman::Region;
|
use crate::pixman::Region;
|
||||||
use crate::rect::Rect;
|
use crate::rect::Rect;
|
||||||
use crate::render::Renderer;
|
use crate::render::Renderer;
|
||||||
use crate::tree::{Node, NodeId};
|
use crate::tree::{
|
||||||
|
Node, NodeId,
|
||||||
|
};
|
||||||
use crate::utils::buffd::{MsgParser, MsgParserError};
|
use crate::utils::buffd::{MsgParser, MsgParserError};
|
||||||
use crate::utils::clonecell::CloneCell;
|
use crate::utils::clonecell::CloneCell;
|
||||||
use crate::utils::linkedlist::LinkedList;
|
use crate::utils::linkedlist::LinkedList;
|
||||||
|
|
@ -662,7 +664,7 @@ impl Node for WlSurface {
|
||||||
renderer.render_surface(self, x, y);
|
renderer.render_surface(self, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn client_id(&self) -> Option<ClientId> {
|
fn client(&self) -> Option<Rc<Client>> {
|
||||||
Some(self.client.id)
|
Some(self.client.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
use crate::client::{ClientId, DynEventFormatter};
|
use crate::client::{Client, DynEventFormatter};
|
||||||
use crate::cursor::KnownCursor;
|
use crate::cursor::KnownCursor;
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
||||||
|
|
@ -311,8 +311,8 @@ impl Node for XdgPopup {
|
||||||
self.xdg.set_workspace(ws);
|
self.xdg.set_workspace(ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn client_id(&self) -> Option<ClientId> {
|
fn client(&self) -> Option<Rc<Client>> {
|
||||||
Some(self.xdg.surface.client.id)
|
Some(self.xdg.surface.client.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ mod types;
|
||||||
|
|
||||||
use crate::backend::SeatId;
|
use crate::backend::SeatId;
|
||||||
use crate::bugs::Bugs;
|
use crate::bugs::Bugs;
|
||||||
use crate::client::{ClientId, DynEventFormatter};
|
use crate::client::{Client, DynEventFormatter};
|
||||||
use crate::cursor::KnownCursor;
|
use crate::cursor::KnownCursor;
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
use crate::ifs::wl_seat::{NodeSeatState, WlSeatGlobal};
|
||||||
|
|
@ -496,8 +496,8 @@ impl Node for XdgToplevel {
|
||||||
self.xdg.set_workspace(ws);
|
self.xdg.set_workspace(ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn client_id(&self) -> Option<ClientId> {
|
fn client(&self) -> Option<Rc<Client>> {
|
||||||
Some(self.xdg.surface.client.id)
|
Some(self.xdg.surface.client.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ pub(super) struct SetTitle<'a> {
|
||||||
impl<'a> RequestParser<'a> for SetTitle<'a> {
|
impl<'a> RequestParser<'a> for SetTitle<'a> {
|
||||||
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
title: parser.string()?,
|
title: parser.bstr()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -235,7 +235,7 @@ pub(super) struct SetAppId<'a> {
|
||||||
impl<'a> RequestParser<'a> for SetAppId<'a> {
|
impl<'a> RequestParser<'a> for SetAppId<'a> {
|
||||||
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
fn parse(parser: &mut MsgParser<'_, 'a>) -> Result<Self, MsgParserError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
app_id: parser.string()?,
|
app_id: parser.bstr()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
src/rect.rs
19
src/rect.rs
|
|
@ -1,17 +1,5 @@
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Default)]
|
|
||||||
pub struct Point {
|
|
||||||
pub x: i32,
|
|
||||||
pub y: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Point {
|
|
||||||
pub fn translate(&self, x: i32, y: i32) -> (i32, i32) {
|
|
||||||
(x - self.x, y - self.y)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Default)]
|
#[derive(Copy, Clone, Eq, PartialEq, Default)]
|
||||||
pub struct Rect {
|
pub struct Rect {
|
||||||
x1: i32,
|
x1: i32,
|
||||||
|
|
@ -65,13 +53,6 @@ impl Rect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_point(&self) -> Point {
|
|
||||||
Point {
|
|
||||||
x: self.x1,
|
|
||||||
y: self.y1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(x1: i32, y1: i32, x2: i32, y2: i32) -> Option<Self> {
|
pub fn new(x1: i32, y1: i32, x2: i32, y2: i32) -> Option<Self> {
|
||||||
if x2 < x1 || y2 < y1 {
|
if x2 < x1 || y2 < y1 {
|
||||||
return None;
|
return None;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::backend::{KeyState, OutputId, ScrollAxis};
|
use crate::backend::{KeyState, OutputId, ScrollAxis};
|
||||||
use crate::client::ClientId;
|
use crate::client::{Client, ClientId};
|
||||||
use crate::cursor::KnownCursor;
|
use crate::cursor::KnownCursor;
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::wl_output::WlOutputGlobal;
|
use crate::ifs::wl_output::WlOutputGlobal;
|
||||||
|
|
@ -169,9 +169,13 @@ pub trait Node {
|
||||||
let _ = ws;
|
let _ = ws;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn client_id(&self) -> Option<ClientId> {
|
fn client(&self) -> Option<Rc<Client>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn client_id(&self) -> Option<ClientId> {
|
||||||
|
self.client().map(|c| c.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FoundNode {
|
pub struct FoundNode {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ pub enum MsgParserError {
|
||||||
MissingFd,
|
MissingFd,
|
||||||
#[error("There is trailing data after the message")]
|
#[error("There is trailing data after the message")]
|
||||||
TrailingData,
|
TrailingData,
|
||||||
|
#[error("String is not UTF-8")]
|
||||||
|
NonUtf8,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MsgParser<'a, 'b> {
|
pub struct MsgParser<'a, 'b> {
|
||||||
|
|
@ -62,7 +64,7 @@ impl<'a, 'b> MsgParser<'a, 'b> {
|
||||||
self.int().map(Fixed)
|
self.int().map(Fixed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn string(&mut self) -> Result<&'b BStr, MsgParserError> {
|
pub fn bstr(&mut self) -> Result<&'b BStr, MsgParserError> {
|
||||||
let len = self.uint()? as usize;
|
let len = self.uint()? as usize;
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
return Err(MsgParserError::EmptyString);
|
return Err(MsgParserError::EmptyString);
|
||||||
|
|
@ -77,6 +79,13 @@ impl<'a, 'b> MsgParser<'a, 'b> {
|
||||||
Ok(s)
|
Ok(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn str(&mut self) -> Result<&'b str, MsgParserError> {
|
||||||
|
match self.bstr()?.to_str() {
|
||||||
|
Ok(s) => Ok(s),
|
||||||
|
_ => Err(MsgParserError::NonUtf8),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn fd(&mut self) -> Result<OwnedFd, MsgParserError> {
|
pub fn fd(&mut self) -> Result<OwnedFd, MsgParserError> {
|
||||||
match self.buf.get_fd() {
|
match self.buf.get_fd() {
|
||||||
Ok(fd) => Ok(fd),
|
Ok(fd) => Ok(fd),
|
||||||
|
|
|
||||||
7
todo.md
7
todo.md
|
|
@ -1,4 +1,5 @@
|
||||||
- Container resizing
|
# todo
|
||||||
|
|
||||||
- Container moving (mouse)
|
- Container moving (mouse)
|
||||||
- Container moving (kb)
|
- Container moving (kb)
|
||||||
- Float toggle
|
- Float toggle
|
||||||
|
|
@ -14,3 +15,7 @@
|
||||||
- presentation time
|
- presentation time
|
||||||
- viewporter
|
- viewporter
|
||||||
- session lock
|
- session lock
|
||||||
|
|
||||||
|
# done
|
||||||
|
|
||||||
|
- Container resizing
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue