autocommit 2022-04-16 13:42:13 CEST
This commit is contained in:
parent
4826305236
commit
50b792db78
27 changed files with 217 additions and 60 deletions
|
|
@ -2,7 +2,7 @@ use {
|
||||||
chrono::{format::StrftimeItems, Local, Timelike},
|
chrono::{format::StrftimeItems, Local, Timelike},
|
||||||
jay_config::{
|
jay_config::{
|
||||||
config,
|
config,
|
||||||
drm::{get_connector, on_connector_connected, on_new_connector},
|
drm::{get_connector, on_connector_connected, on_graphics_initialized, on_new_connector},
|
||||||
embedded::grab_input_device,
|
embedded::grab_input_device,
|
||||||
get_timer, get_workspace,
|
get_timer, get_workspace,
|
||||||
input::{
|
input::{
|
||||||
|
|
@ -144,7 +144,10 @@ pub fn configure() {
|
||||||
}
|
}
|
||||||
|
|
||||||
set_env("GTK_THEME", "Adwaita:dark");
|
set_env("GTK_THEME", "Adwaita:dark");
|
||||||
Command::new("mako").spawn();
|
|
||||||
|
on_graphics_initialized(|| {
|
||||||
|
Command::new("mako").spawn();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
config!(configure);
|
config!(configure);
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ pub(crate) struct Client {
|
||||||
on_new_seat: RefCell<Option<Rc<dyn Fn(Seat)>>>,
|
on_new_seat: RefCell<Option<Rc<dyn Fn(Seat)>>>,
|
||||||
on_new_input_device: RefCell<Option<Rc<dyn Fn(InputDevice)>>>,
|
on_new_input_device: RefCell<Option<Rc<dyn Fn(InputDevice)>>>,
|
||||||
on_connector_connected: RefCell<Option<Rc<dyn Fn(Connector)>>>,
|
on_connector_connected: RefCell<Option<Rc<dyn Fn(Connector)>>>,
|
||||||
|
on_graphics_initialized: Cell<Option<Box<dyn FnOnce()>>>,
|
||||||
on_new_connector: RefCell<Option<Rc<dyn Fn(Connector)>>>,
|
on_new_connector: RefCell<Option<Rc<dyn Fn(Connector)>>>,
|
||||||
bufs: RefCell<Vec<Vec<u8>>>,
|
bufs: RefCell<Vec<Vec<u8>>>,
|
||||||
}
|
}
|
||||||
|
|
@ -120,6 +121,7 @@ pub unsafe extern "C" fn init(
|
||||||
on_new_seat: Default::default(),
|
on_new_seat: Default::default(),
|
||||||
on_new_input_device: Default::default(),
|
on_new_input_device: Default::default(),
|
||||||
on_connector_connected: Default::default(),
|
on_connector_connected: Default::default(),
|
||||||
|
on_graphics_initialized: Default::default(),
|
||||||
on_new_connector: Default::default(),
|
on_new_connector: Default::default(),
|
||||||
bufs: Default::default(),
|
bufs: Default::default(),
|
||||||
});
|
});
|
||||||
|
|
@ -411,6 +413,10 @@ impl Client {
|
||||||
*self.on_connector_connected.borrow_mut() = Some(Rc::new(f));
|
*self.on_connector_connected.borrow_mut() = Some(Rc::new(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_graphics_initialized<F: FnOnce() + 'static>(&self, f: F) {
|
||||||
|
self.on_graphics_initialized.set(Some(Box::new(f)));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_seat(&self, device: InputDevice, seat: Seat) {
|
pub fn set_seat(&self, device: InputDevice, seat: Seat) {
|
||||||
self.send(&ClientMessage::SetSeat { device, seat })
|
self.send(&ClientMessage::SetSeat { device, seat })
|
||||||
}
|
}
|
||||||
|
|
@ -551,6 +557,11 @@ impl Client {
|
||||||
handler();
|
handler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ServerMessage::GraphicsInitialized => {
|
||||||
|
if let Some(handler) = self.on_graphics_initialized.take() {
|
||||||
|
handler();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ use {
|
||||||
#[derive(Encode, BorrowDecode, Debug)]
|
#[derive(Encode, BorrowDecode, Debug)]
|
||||||
pub enum ServerMessage {
|
pub enum ServerMessage {
|
||||||
Configure,
|
Configure,
|
||||||
|
GraphicsInitialized,
|
||||||
Response {
|
Response {
|
||||||
response: Response,
|
response: Response,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,10 @@ pub fn on_connector_connected<F: Fn(Connector) + 'static>(f: F) {
|
||||||
get!().on_connector_connected(f)
|
get!().on_connector_connected(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn on_graphics_initialized<F: FnOnce() + 'static>(f: F) {
|
||||||
|
get!().on_graphics_initialized(f)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_connector(id: impl ToConnectorId) -> Connector {
|
pub fn get_connector(id: impl ToConnectorId) -> Connector {
|
||||||
let (ty, idx) = match id.to_connector_id() {
|
let (ty, idx) = match id.to_connector_id() {
|
||||||
Ok(id) => id,
|
Ok(id) => id,
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ pub enum InputDeviceAccelProfile {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum BackendEvent {
|
pub enum BackendEvent {
|
||||||
|
GraphicsInitialized,
|
||||||
NewConnector(Rc<dyn Connector>),
|
NewConnector(Rc<dyn Connector>),
|
||||||
NewInputDevice(Rc<dyn InputDevice>),
|
NewInputDevice(Rc<dyn InputDevice>),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
async_engine::{AsyncError, AsyncFd, SpawnedFuture},
|
async_engine::{AsyncError, AsyncFd, SpawnedFuture},
|
||||||
backend::{
|
backend::{
|
||||||
Backend, InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId,
|
Backend, BackendEvent, InputDevice, InputDeviceAccelProfile, InputDeviceCapability,
|
||||||
InputEvent, KeyState,
|
InputDeviceId, InputEvent, KeyState,
|
||||||
},
|
},
|
||||||
backends::metal::video::{MetalDrmDevice, PendingDrmDevice},
|
backends::metal::video::{MetalDrmDevice, PendingDrmDevice},
|
||||||
dbus::{DbusError, SignalHandler},
|
dbus::{DbusError, SignalHandler},
|
||||||
|
|
@ -128,6 +128,9 @@ impl MetalBackend {
|
||||||
if let Err(e) = self.enumerate_devices() {
|
if let Err(e) = self.enumerate_devices() {
|
||||||
return Err(MetalError::Enumerate(Box::new(e)));
|
return Err(MetalError::Enumerate(Box::new(e)));
|
||||||
}
|
}
|
||||||
|
self.state
|
||||||
|
.backend_events
|
||||||
|
.push(BackendEvent::GraphicsInitialized);
|
||||||
pending().await
|
pending().await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,10 @@ pub struct XBackend {
|
||||||
|
|
||||||
impl XBackend {
|
impl XBackend {
|
||||||
async fn run(self: Rc<Self>) -> Result<(), XBackendError> {
|
async fn run(self: Rc<Self>) -> Result<(), XBackendError> {
|
||||||
|
self.state
|
||||||
|
.backend_events
|
||||||
|
.push(BackendEvent::GraphicsInitialized);
|
||||||
|
|
||||||
self.query_devices(INPUT_DEVICE_ALL_MASTER).await?;
|
self.query_devices(INPUT_DEVICE_ALL_MASTER).await?;
|
||||||
|
|
||||||
let _events = self.state.eng.spawn(self.clone().event_handler());
|
let _events = self.state.eng.spawn(self.clone().event_handler());
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,8 @@ impl Clients {
|
||||||
tracker: Default::default(),
|
tracker: Default::default(),
|
||||||
xwayland_queue,
|
xwayland_queue,
|
||||||
secure,
|
secure,
|
||||||
|
last_serial: Cell::new(0),
|
||||||
|
last_enter_serial: Cell::new(0),
|
||||||
});
|
});
|
||||||
track!(data, data);
|
track!(data, data);
|
||||||
let display = Rc::new(WlDisplay::new(&data));
|
let display = Rc::new(WlDisplay::new(&data));
|
||||||
|
|
@ -224,6 +226,8 @@ pub struct Client {
|
||||||
pub tracker: Tracker<Client>,
|
pub tracker: Tracker<Client>,
|
||||||
pub xwayland_queue: Option<Rc<AsyncQueue<XWaylandEvent>>>,
|
pub xwayland_queue: Option<Rc<AsyncQueue<XWaylandEvent>>>,
|
||||||
pub secure: bool,
|
pub secure: bool,
|
||||||
|
pub last_serial: Cell<u32>,
|
||||||
|
pub last_enter_serial: Cell<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
|
|
@ -251,6 +255,18 @@ impl Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn validate_serial(&self, serial: u32) -> Result<(), ClientError> {
|
||||||
|
if serial > self.last_serial.get() {
|
||||||
|
Err(ClientError::InvalidSerial)
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next_serial(&self) -> u32 {
|
||||||
|
self.state.next_serial(Some(self))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_id<T: From<ObjectId>>(&self) -> Result<T, ClientError> {
|
pub fn new_id<T: From<ObjectId>>(&self) -> Result<T, ClientError> {
|
||||||
self.objects.id(self)
|
self.objects.id(self)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ 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")]
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,7 @@ fn start_compositor2(
|
||||||
handler: Default::default(),
|
handler: Default::default(),
|
||||||
},
|
},
|
||||||
socket_path: Default::default(),
|
socket_path: Default::default(),
|
||||||
|
serial: Default::default(),
|
||||||
});
|
});
|
||||||
create_dummy_output(&state);
|
create_dummy_output(&state);
|
||||||
let socket_path = Acceptor::install(&state)?;
|
let socket_path = Acceptor::install(&state)?;
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,10 @@ impl ConfigProxy {
|
||||||
device: InputDevice(dev.raw() as _),
|
device: InputDevice(dev.raw() as _),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn graphics_initialized(&self) {
|
||||||
|
self.handler.send(&ServerMessage::GraphicsInitialized);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for ConfigProxy {
|
impl Drop for ConfigProxy {
|
||||||
|
|
|
||||||
|
|
@ -61,10 +61,10 @@ impl WlDataDevice {
|
||||||
self.manager.client.event(Leave { self_id: self.id })
|
self.manager.client.event(Leave { self_id: self.id })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_enter(&self, surface: WlSurfaceId, x: Fixed, y: Fixed, offer: WlDataOfferId) {
|
pub fn send_enter(&self, surface: WlSurfaceId, x: Fixed, y: Fixed, offer: WlDataOfferId, serial: u32) {
|
||||||
self.manager.client.event(Enter {
|
self.manager.client.event(Enter {
|
||||||
self_id: self.id,
|
self_id: self.id,
|
||||||
serial: 0,
|
serial,
|
||||||
surface,
|
surface,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
|
|
@ -87,6 +87,7 @@ 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)?;
|
||||||
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)?)
|
||||||
|
|
@ -100,18 +101,29 @@ impl WlDataDevice {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
self.seat.global.start_drag(&origin, source, icon)?;
|
self.seat
|
||||||
|
.global
|
||||||
|
.start_drag(&origin, source, icon, req.serial)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
.seat
|
||||||
|
.global
|
||||||
|
.may_modify_selection(&self.seat.client, req.serial)
|
||||||
|
{
|
||||||
|
log::warn!("Ignoring disallowed set_selection request");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
let src = if req.source.is_none() {
|
let src = if req.source.is_none() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(self.manager.client.lookup(req.source)?)
|
Some(self.manager.client.lookup(req.source)?)
|
||||||
};
|
};
|
||||||
self.seat.global.set_selection(src)?;
|
self.seat.global.set_selection(src, Some(req.serial))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ impl WlDataOffer {
|
||||||
|
|
||||||
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)?;
|
||||||
|
let _ = req.serial; // unused
|
||||||
let mut state = self.data.shared.state.get();
|
let mut state = self.data.shared.state.get();
|
||||||
if state.contains(OFFER_STATE_FINISHED) {
|
if state.contains(OFFER_STATE_FINISHED) {
|
||||||
return Err(AcceptError::AlreadyFinished);
|
return Err(AcceptError::AlreadyFinished);
|
||||||
|
|
|
||||||
|
|
@ -63,12 +63,17 @@ 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.seat.global.may_modify_primary_selection(&self.seat.client, req.serial) {
|
||||||
|
log::warn!("Ignoring disallowed set_selection request");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
let src = if req.source.is_none() {
|
let src = if req.source.is_none() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(self.manager.client.lookup(req.source)?)
|
Some(self.manager.client.lookup(req.source)?)
|
||||||
};
|
};
|
||||||
self.seat.global.set_primary_selection(src)?;
|
self.seat.global.set_primary_selection(src, Some(req.serial))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ use {
|
||||||
copyhashmap::CopyHashMap,
|
copyhashmap::CopyHashMap,
|
||||||
errorfmt::ErrorFmt,
|
errorfmt::ErrorFmt,
|
||||||
linkedlist::{LinkedList, LinkedNode},
|
linkedlist::{LinkedList, LinkedNode},
|
||||||
numcell::NumCell,
|
|
||||||
rc_eq::rc_eq,
|
rc_eq::rc_eq,
|
||||||
},
|
},
|
||||||
wire::{
|
wire::{
|
||||||
|
|
@ -127,10 +126,11 @@ pub struct WlSeatGlobal {
|
||||||
kb_map: CloneCell<Rc<XkbKeymap>>,
|
kb_map: CloneCell<Rc<XkbKeymap>>,
|
||||||
kb_state: RefCell<XkbState>,
|
kb_state: RefCell<XkbState>,
|
||||||
cursor: CloneCell<Option<Rc<dyn Cursor>>>,
|
cursor: CloneCell<Option<Rc<dyn Cursor>>>,
|
||||||
serial: NumCell<u32>,
|
|
||||||
tree_changed: Rc<AsyncEvent>,
|
tree_changed: Rc<AsyncEvent>,
|
||||||
selection: CloneCell<Option<Rc<WlDataSource>>>,
|
selection: CloneCell<Option<Rc<WlDataSource>>>,
|
||||||
|
selection_serial: Cell<u32>,
|
||||||
primary_selection: CloneCell<Option<Rc<ZwpPrimarySelectionSourceV1>>>,
|
primary_selection: CloneCell<Option<Rc<ZwpPrimarySelectionSourceV1>>>,
|
||||||
|
primary_selection_serial: Cell<u32>,
|
||||||
pointer_owner: PointerOwnerHolder,
|
pointer_owner: PointerOwnerHolder,
|
||||||
kb_owner: KbOwnerHolder,
|
kb_owner: KbOwnerHolder,
|
||||||
dropped_dnd: RefCell<Option<DroppedDnd>>,
|
dropped_dnd: RefCell<Option<DroppedDnd>>,
|
||||||
|
|
@ -164,10 +164,11 @@ impl WlSeatGlobal {
|
||||||
kb_map: CloneCell::new(state.default_keymap.clone()),
|
kb_map: CloneCell::new(state.default_keymap.clone()),
|
||||||
kb_state: RefCell::new(state.default_keymap.state().unwrap()),
|
kb_state: RefCell::new(state.default_keymap.state().unwrap()),
|
||||||
cursor: Default::default(),
|
cursor: Default::default(),
|
||||||
serial: Default::default(),
|
|
||||||
tree_changed: Default::default(),
|
tree_changed: Default::default(),
|
||||||
selection: Default::default(),
|
selection: Default::default(),
|
||||||
|
selection_serial: Cell::new(0),
|
||||||
primary_selection: Default::default(),
|
primary_selection: Default::default(),
|
||||||
|
primary_selection_serial: Cell::new(0),
|
||||||
pointer_owner: Default::default(),
|
pointer_owner: Default::default(),
|
||||||
kb_owner: Default::default(),
|
kb_owner: Default::default(),
|
||||||
dropped_dnd: RefCell::new(None),
|
dropped_dnd: RefCell::new(None),
|
||||||
|
|
@ -333,8 +334,9 @@ impl WlSeatGlobal {
|
||||||
origin: &Rc<WlSurface>,
|
origin: &Rc<WlSurface>,
|
||||||
source: Option<Rc<WlDataSource>>,
|
source: Option<Rc<WlDataSource>>,
|
||||||
icon: Option<Rc<WlSurface>>,
|
icon: Option<Rc<WlSurface>>,
|
||||||
|
serial: u32,
|
||||||
) -> Result<(), WlSeatError> {
|
) -> Result<(), WlSeatError> {
|
||||||
self.pointer_owner.start_drag(self, origin, source, icon)
|
self.pointer_owner.start_drag(self, origin, source, icon, serial)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cancel_dnd(self: &Rc<Self>) {
|
pub fn cancel_dnd(self: &Rc<Self>) {
|
||||||
|
|
@ -342,24 +344,49 @@ impl WlSeatGlobal {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unset_selection(self: &Rc<Self>) {
|
pub fn unset_selection(self: &Rc<Self>) {
|
||||||
let _ = self.set_selection(None);
|
let _ = self.set_selection(None, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_selection(
|
pub fn set_selection(
|
||||||
self: &Rc<Self>,
|
self: &Rc<Self>,
|
||||||
selection: Option<Rc<WlDataSource>>,
|
selection: Option<Rc<WlDataSource>>,
|
||||||
|
serial: Option<u32>,
|
||||||
) -> Result<(), WlSeatError> {
|
) -> Result<(), WlSeatError> {
|
||||||
|
if let Some(serial) = serial {
|
||||||
|
self.selection_serial.set(serial);
|
||||||
|
}
|
||||||
self.set_selection_::<WlDataDevice>(&self.selection, selection)
|
self.set_selection_::<WlDataDevice>(&self.selection, selection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn may_modify_selection(&self, client: &Rc<Client>, serial: u32) -> bool {
|
||||||
|
let dist = serial.wrapping_sub(self.selection_serial.get()) as i32;
|
||||||
|
if dist < 0 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
self.keyboard_node.get().node_client_id() == Some(client.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn may_modify_primary_selection(&self, client: &Rc<Client>, serial: u32) -> bool {
|
||||||
|
let dist = serial.wrapping_sub(self.primary_selection_serial.get()) as i32;
|
||||||
|
if dist < 0 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
self.keyboard_node.get().node_client_id() == Some(client.id)
|
||||||
|
|| self.pointer_node().and_then(|n| n.node_client_id()) == Some(client.id)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn unset_primary_selection(self: &Rc<Self>) {
|
pub fn unset_primary_selection(self: &Rc<Self>) {
|
||||||
let _ = self.set_primary_selection(None);
|
let _ = self.set_primary_selection(None, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_primary_selection(
|
pub fn set_primary_selection(
|
||||||
self: &Rc<Self>,
|
self: &Rc<Self>,
|
||||||
selection: Option<Rc<ZwpPrimarySelectionSourceV1>>,
|
selection: Option<Rc<ZwpPrimarySelectionSourceV1>>,
|
||||||
|
serial: Option<u32>,
|
||||||
) -> Result<(), WlSeatError> {
|
) -> Result<(), WlSeatError> {
|
||||||
|
if let Some(serial) = serial {
|
||||||
|
self.primary_selection_serial.set(serial);
|
||||||
|
}
|
||||||
self.set_selection_::<ZwpPrimarySelectionDeviceV1>(&self.primary_selection, selection)
|
self.set_selection_::<ZwpPrimarySelectionDeviceV1>(&self.primary_selection, selection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -457,12 +457,17 @@ impl WlSeatGlobal {
|
||||||
|
|
||||||
// Button callbacks
|
// Button callbacks
|
||||||
impl WlSeatGlobal {
|
impl WlSeatGlobal {
|
||||||
pub fn button_surface(self: &Rc<Self>, surface: &Rc<WlSurface>, button: u32, state: KeyState) {
|
pub fn button_surface(
|
||||||
|
self: &Rc<Self>,
|
||||||
|
surface: &Rc<WlSurface>,
|
||||||
|
button: u32,
|
||||||
|
state: KeyState,
|
||||||
|
serial: u32,
|
||||||
|
) {
|
||||||
let (state, pressed) = match state {
|
let (state, pressed) = match state {
|
||||||
KeyState::Released => (wl_pointer::RELEASED, false),
|
KeyState::Released => (wl_pointer::RELEASED, false),
|
||||||
KeyState::Pressed => (wl_pointer::PRESSED, true),
|
KeyState::Pressed => (wl_pointer::PRESSED, true),
|
||||||
};
|
};
|
||||||
let serial = self.serial.fetch_add(1);
|
|
||||||
self.surface_pointer_event(0, surface, |p| p.send_button(serial, 0, button, state));
|
self.surface_pointer_event(0, surface, |p| p.send_button(serial, 0, button, state));
|
||||||
self.surface_pointer_frame(surface);
|
self.surface_pointer_frame(surface);
|
||||||
if pressed && surface.accepts_kb_focus() {
|
if pressed && surface.accepts_kb_focus() {
|
||||||
|
|
@ -522,7 +527,8 @@ impl WlSeatGlobal {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enter_surface(&self, n: &WlSurface, x: Fixed, y: Fixed) {
|
pub fn enter_surface(&self, n: &WlSurface, x: Fixed, y: Fixed) {
|
||||||
let serial = self.serial.fetch_add(1);
|
let serial = n.client.next_serial();
|
||||||
|
n.client.last_enter_serial.set(serial);
|
||||||
self.surface_pointer_event(0, n, |p| p.send_enter(serial, n.id, x, y));
|
self.surface_pointer_event(0, n, |p| p.send_enter(serial, n.id, x, y));
|
||||||
self.surface_pointer_frame(n);
|
self.surface_pointer_frame(n);
|
||||||
}
|
}
|
||||||
|
|
@ -531,7 +537,7 @@ impl WlSeatGlobal {
|
||||||
// Leave callbacks
|
// Leave callbacks
|
||||||
impl WlSeatGlobal {
|
impl WlSeatGlobal {
|
||||||
pub fn leave_surface(&self, n: &WlSurface) {
|
pub fn leave_surface(&self, n: &WlSurface) {
|
||||||
let serial = self.serial.fetch_add(1);
|
let serial = n.client.next_serial();
|
||||||
self.surface_pointer_event(0, n, |p| p.send_leave(serial, n.id));
|
self.surface_pointer_event(0, n, |p| p.send_leave(serial, n.id));
|
||||||
self.surface_pointer_frame(n);
|
self.surface_pointer_frame(n);
|
||||||
}
|
}
|
||||||
|
|
@ -540,7 +546,8 @@ impl WlSeatGlobal {
|
||||||
// Unfocus callbacks
|
// Unfocus callbacks
|
||||||
impl WlSeatGlobal {
|
impl WlSeatGlobal {
|
||||||
pub fn unfocus_surface(&self, surface: &WlSurface) {
|
pub fn unfocus_surface(&self, surface: &WlSurface) {
|
||||||
self.surface_kb_event(0, surface, |k| k.send_leave(0, surface.id))
|
let serial = surface.client.next_serial();
|
||||||
|
self.surface_kb_event(0, surface, |k| k.send_leave(serial, surface.id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -548,7 +555,7 @@ impl WlSeatGlobal {
|
||||||
impl WlSeatGlobal {
|
impl WlSeatGlobal {
|
||||||
pub fn focus_surface(&self, surface: &WlSurface) {
|
pub fn focus_surface(&self, surface: &WlSurface) {
|
||||||
let pressed_keys: Vec<_> = self.pressed_keys.borrow().iter().copied().collect();
|
let pressed_keys: Vec<_> = self.pressed_keys.borrow().iter().copied().collect();
|
||||||
let serial = self.serial.fetch_add(1);
|
let serial = surface.client.next_serial();
|
||||||
self.surface_kb_event(0, surface, |k| {
|
self.surface_kb_event(0, surface, |k| {
|
||||||
k.send_enter(serial, surface.id, &pressed_keys)
|
k.send_enter(serial, surface.id, &pressed_keys)
|
||||||
});
|
});
|
||||||
|
|
@ -559,7 +566,7 @@ impl WlSeatGlobal {
|
||||||
group,
|
group,
|
||||||
..
|
..
|
||||||
} = self.kb_state.borrow().mods();
|
} = self.kb_state.borrow().mods();
|
||||||
let serial = self.serial.fetch_add(1);
|
let serial = surface.client.next_serial();
|
||||||
self.surface_kb_event(0, surface, |k| {
|
self.surface_kb_event(0, surface, |k| {
|
||||||
k.send_modifiers(serial, mods_depressed, mods_latched, mods_locked, group)
|
k.send_modifiers(serial, mods_depressed, mods_latched, mods_locked, group)
|
||||||
});
|
});
|
||||||
|
|
@ -577,7 +584,7 @@ impl WlSeatGlobal {
|
||||||
// Key callbacks
|
// Key callbacks
|
||||||
impl WlSeatGlobal {
|
impl WlSeatGlobal {
|
||||||
pub fn key_surface(&self, surface: &WlSurface, key: u32, state: u32) {
|
pub fn key_surface(&self, surface: &WlSurface, key: u32, state: u32) {
|
||||||
let serial = self.serial.fetch_add(1);
|
let serial = surface.client.next_serial();
|
||||||
self.surface_kb_event(0, surface, |k| k.send_key(serial, 0, key, state));
|
self.surface_kb_event(0, surface, |k| k.send_key(serial, 0, key, state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -585,7 +592,7 @@ impl WlSeatGlobal {
|
||||||
// Modifiers callbacks
|
// Modifiers callbacks
|
||||||
impl WlSeatGlobal {
|
impl WlSeatGlobal {
|
||||||
pub fn mods_surface(&self, surface: &WlSurface, mods: ModifierState) {
|
pub fn mods_surface(&self, surface: &WlSurface, mods: ModifierState) {
|
||||||
let serial = self.serial.fetch_add(1);
|
let serial = surface.client.next_serial();
|
||||||
self.surface_kb_event(0, surface, |k| {
|
self.surface_kb_event(0, surface, |k| {
|
||||||
k.send_modifiers(
|
k.send_modifiers(
|
||||||
serial,
|
serial,
|
||||||
|
|
@ -624,16 +631,16 @@ impl WlSeatGlobal {
|
||||||
surface.client.flush();
|
surface.client.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dnd_surface_enter(&self, surface: &WlSurface, dnd: &Dnd, x: Fixed, y: Fixed) {
|
pub fn dnd_surface_enter(&self, surface: &WlSurface, dnd: &Dnd, x: Fixed, y: Fixed, serial: u32) {
|
||||||
if let Some(src) = &dnd.src {
|
if let Some(src) = &dnd.src {
|
||||||
ipc::offer_source_to::<WlDataDevice>(src, &surface.client);
|
ipc::offer_source_to::<WlDataDevice>(src, &surface.client);
|
||||||
src.for_each_data_offer(|offer| {
|
src.for_each_data_offer(|offer| {
|
||||||
offer.device.send_enter(surface.id, x, y, offer.id);
|
offer.device.send_enter(surface.id, x, y, offer.id, serial);
|
||||||
offer.send_source_actions();
|
offer.send_source_actions();
|
||||||
})
|
})
|
||||||
} else if surface.client.id == dnd.client.id {
|
} else if surface.client.id == dnd.client.id {
|
||||||
self.for_each_data_device(0, dnd.client.id, |dd| {
|
self.for_each_data_device(0, dnd.client.id, |dd| {
|
||||||
dd.send_enter(surface.id, x, y, WlDataOfferId::NONE);
|
dd.send_enter(surface.id, x, y, WlDataOfferId::NONE, serial);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
surface.client.flush();
|
surface.client.flush();
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,11 @@ impl PointerOwnerHolder {
|
||||||
origin: &Rc<WlSurface>,
|
origin: &Rc<WlSurface>,
|
||||||
source: Option<Rc<WlDataSource>>,
|
source: Option<Rc<WlDataSource>>,
|
||||||
icon: Option<Rc<WlSurface>>,
|
icon: Option<Rc<WlSurface>>,
|
||||||
|
serial: u32,
|
||||||
) -> Result<(), WlSeatError> {
|
) -> Result<(), WlSeatError> {
|
||||||
self.owner.get().start_drag(seat, origin, source, icon)
|
self.owner
|
||||||
|
.get()
|
||||||
|
.start_drag(seat, origin, source, icon, serial)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cancel_dnd(&self, seat: &Rc<WlSeatGlobal>) {
|
pub fn cancel_dnd(&self, seat: &Rc<WlSeatGlobal>) {
|
||||||
|
|
@ -103,6 +106,7 @@ trait PointerOwner {
|
||||||
origin: &Rc<WlSurface>,
|
origin: &Rc<WlSurface>,
|
||||||
source: Option<Rc<WlDataSource>>,
|
source: Option<Rc<WlDataSource>>,
|
||||||
icon: Option<Rc<WlSurface>>,
|
icon: Option<Rc<WlSurface>>,
|
||||||
|
serial: u32,
|
||||||
) -> Result<(), WlSeatError>;
|
) -> Result<(), WlSeatError>;
|
||||||
fn cancel_dnd(&self, seat: &Rc<WlSeatGlobal>);
|
fn cancel_dnd(&self, seat: &Rc<WlSeatGlobal>);
|
||||||
fn revert_to_default(&self, seat: &Rc<WlSeatGlobal>);
|
fn revert_to_default(&self, seat: &Rc<WlSeatGlobal>);
|
||||||
|
|
@ -116,6 +120,7 @@ struct DefaultPointerOwner;
|
||||||
struct GrabPointerOwner {
|
struct GrabPointerOwner {
|
||||||
buttons: SmallMap<u32, (), 1>,
|
buttons: SmallMap<u32, (), 1>,
|
||||||
node: Rc<dyn Node>,
|
node: Rc<dyn Node>,
|
||||||
|
serial: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DndPointerOwner {
|
struct DndPointerOwner {
|
||||||
|
|
@ -136,12 +141,14 @@ impl PointerOwner for DefaultPointerOwner {
|
||||||
Some(n) => n,
|
Some(n) => n,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
let serial = seat.state.next_serial(pn.node_client().as_deref());
|
||||||
seat.pointer_owner.owner.set(Rc::new(GrabPointerOwner {
|
seat.pointer_owner.owner.set(Rc::new(GrabPointerOwner {
|
||||||
buttons: SmallMap::new_with(button, ()),
|
buttons: SmallMap::new_with(button, ()),
|
||||||
node: pn.clone(),
|
node: pn.clone(),
|
||||||
|
serial,
|
||||||
}));
|
}));
|
||||||
pn.node_seat_state().add_pointer_grab(seat);
|
pn.node_seat_state().add_pointer_grab(seat);
|
||||||
pn.node_button(seat, button, state);
|
pn.node_button(seat, button, state, serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn axis_node(&self, seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
|
fn axis_node(&self, seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
|
||||||
|
|
@ -217,6 +224,7 @@ impl PointerOwner for DefaultPointerOwner {
|
||||||
_origin: &Rc<WlSurface>,
|
_origin: &Rc<WlSurface>,
|
||||||
source: Option<Rc<WlDataSource>>,
|
source: Option<Rc<WlDataSource>>,
|
||||||
_icon: Option<Rc<WlSurface>>,
|
_icon: Option<Rc<WlSurface>>,
|
||||||
|
_serial: u32,
|
||||||
) -> Result<(), WlSeatError> {
|
) -> Result<(), WlSeatError> {
|
||||||
if let Some(src) = source {
|
if let Some(src) = source {
|
||||||
src.send_cancelled();
|
src.send_cancelled();
|
||||||
|
|
@ -262,7 +270,8 @@ impl PointerOwner for GrabPointerOwner {
|
||||||
self.buttons.insert(button, ());
|
self.buttons.insert(button, ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.node.clone().node_button(seat, button, state);
|
let serial = seat.state.next_serial(self.node.node_client().as_deref());
|
||||||
|
self.node.clone().node_button(seat, button, state, serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn axis_node(&self, _seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
|
fn axis_node(&self, _seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
|
||||||
|
|
@ -284,6 +293,7 @@ impl PointerOwner for GrabPointerOwner {
|
||||||
origin: &Rc<WlSurface>,
|
origin: &Rc<WlSurface>,
|
||||||
src: Option<Rc<WlDataSource>>,
|
src: Option<Rc<WlDataSource>>,
|
||||||
icon: Option<Rc<WlSurface>>,
|
icon: Option<Rc<WlSurface>>,
|
||||||
|
serial: u32,
|
||||||
) -> Result<(), WlSeatError> {
|
) -> Result<(), WlSeatError> {
|
||||||
let button = match self.buttons.iter().next() {
|
let button = match self.buttons.iter().next() {
|
||||||
Some((b, _)) => b,
|
Some((b, _)) => b,
|
||||||
|
|
@ -292,6 +302,9 @@ impl PointerOwner for GrabPointerOwner {
|
||||||
if self.buttons.len() != 1 {
|
if self.buttons.len() != 1 {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
if serial != self.serial {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
if self.node.node_id() != origin.node_id {
|
if self.node.node_id() != origin.node_id {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
@ -413,7 +426,7 @@ impl PointerOwner for DndPointerOwner {
|
||||||
target.node_dnd_leave(&self.dnd);
|
target.node_dnd_leave(&self.dnd);
|
||||||
target.node_seat_state().remove_dnd_target(seat);
|
target.node_seat_state().remove_dnd_target(seat);
|
||||||
target = node;
|
target = node;
|
||||||
target.node_dnd_enter(&self.dnd, x, y);
|
target.node_dnd_enter(&self.dnd, x, y, seat.state.next_serial(target.node_client().as_deref()));
|
||||||
target.node_seat_state().add_dnd_target(seat);
|
target.node_seat_state().add_dnd_target(seat);
|
||||||
self.target.set(target);
|
self.target.set(target);
|
||||||
} else if (self.pos_x.get(), self.pos_y.get()) != (x, y) {
|
} else if (self.pos_x.get(), self.pos_y.get()) != (x, y) {
|
||||||
|
|
@ -429,6 +442,7 @@ impl PointerOwner for DndPointerOwner {
|
||||||
_origin: &Rc<WlSurface>,
|
_origin: &Rc<WlSurface>,
|
||||||
source: Option<Rc<WlDataSource>>,
|
source: Option<Rc<WlDataSource>>,
|
||||||
_icon: Option<Rc<WlSurface>>,
|
_icon: Option<Rc<WlSurface>>,
|
||||||
|
_serial: u32,
|
||||||
) -> Result<(), WlSeatError> {
|
) -> Result<(), WlSeatError> {
|
||||||
if let Some(src) = source {
|
if let Some(src) = source {
|
||||||
src.send_cancelled();
|
src.send_cancelled();
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,7 @@ 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)?;
|
||||||
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)?;
|
||||||
|
|
@ -163,7 +164,7 @@ impl WlPointer {
|
||||||
cursor.set_hotspot(req.hotspot_x, req.hotspot_y);
|
cursor.set_hotspot(req.hotspot_x, req.hotspot_y);
|
||||||
cursor_opt = Some(cursor as Rc<dyn Cursor>);
|
cursor_opt = Some(cursor as Rc<dyn Cursor>);
|
||||||
}
|
}
|
||||||
let pointer_node = match self.seat.global.pointer_stack.borrow().last().cloned() {
|
let pointer_node = match self.seat.global.pointer_node() {
|
||||||
Some(n) => n,
|
Some(n) => n,
|
||||||
_ => {
|
_ => {
|
||||||
// cannot happen
|
// cannot happen
|
||||||
|
|
@ -173,6 +174,9 @@ impl WlPointer {
|
||||||
if pointer_node.node_client_id() != Some(self.seat.client.id) {
|
if pointer_node.node_client_id() != Some(self.seat.client.id) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
if req.serial != self.seat.client.last_enter_serial.get() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
self.seat.global.set_app_cursor(cursor_opt);
|
self.seat.global.set_app_cursor(cursor_opt);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -795,8 +795,8 @@ impl SizedNode for WlSurface {
|
||||||
seat.mods_surface(self, mods);
|
seat.mods_surface(self, mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn button(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) {
|
fn button(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState, serial: u32) {
|
||||||
seat.button_surface(&self, button, state);
|
seat.button_surface(&self, button, state, serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn axis_event(self: &Rc<Self>, seat: &WlSeatGlobal, event: &PendingScroll) {
|
fn axis_event(self: &Rc<Self>, seat: &WlSeatGlobal, event: &PendingScroll) {
|
||||||
|
|
@ -859,8 +859,8 @@ impl SizedNode for WlSurface {
|
||||||
dnd.seat.dnd_surface_leave(self, dnd);
|
dnd.seat.dnd_surface_leave(self, dnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dnd_enter(&self, dnd: &Dnd, x: Fixed, y: Fixed) {
|
fn dnd_enter(&self, dnd: &Dnd, x: Fixed, y: Fixed, serial: u32) {
|
||||||
dnd.seat.dnd_surface_enter(self, dnd, x, y);
|
dnd.seat.dnd_surface_enter(self, dnd, x, y, serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed) {
|
fn dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed) {
|
||||||
|
|
|
||||||
|
|
@ -278,9 +278,12 @@ impl Xwindow {
|
||||||
match map_change {
|
match map_change {
|
||||||
Change::None => return,
|
Change::None => return,
|
||||||
Change::Unmap => {
|
Change::Unmap => {
|
||||||
self.data.info.pending_extents.set(self.data.info.extents.take());
|
self.data
|
||||||
|
.info
|
||||||
|
.pending_extents
|
||||||
|
.set(self.data.info.extents.take());
|
||||||
self.node_destroy(true);
|
self.node_destroy(true);
|
||||||
},
|
}
|
||||||
Change::Map if self.data.info.override_redirect.get() => {
|
Change::Map if self.data.info.override_redirect.get() => {
|
||||||
self.change_extents(&self.data.info.pending_extents.get());
|
self.change_extents(&self.data.info.pending_extents.get());
|
||||||
*self.display_link.borrow_mut() =
|
*self.display_link.borrow_mut() =
|
||||||
|
|
|
||||||
13
src/state.rs
13
src/state.rs
|
|
@ -27,7 +27,8 @@ use {
|
||||||
},
|
},
|
||||||
utils::{
|
utils::{
|
||||||
asyncevent::AsyncEvent, clonecell::CloneCell, copyhashmap::CopyHashMap,
|
asyncevent::AsyncEvent, clonecell::CloneCell, copyhashmap::CopyHashMap,
|
||||||
errorfmt::ErrorFmt, fdcloser::FdCloser, linkedlist::LinkedList, queue::AsyncQueue,
|
errorfmt::ErrorFmt, fdcloser::FdCloser, linkedlist::LinkedList, numcell::NumCell,
|
||||||
|
queue::AsyncQueue,
|
||||||
},
|
},
|
||||||
wheel::Wheel,
|
wheel::Wheel,
|
||||||
xkbcommon::{XkbContext, XkbKeymap},
|
xkbcommon::{XkbContext, XkbKeymap},
|
||||||
|
|
@ -37,6 +38,7 @@ use {
|
||||||
jay_config::Direction,
|
jay_config::Direction,
|
||||||
std::{
|
std::{
|
||||||
cell::{Cell, RefCell},
|
cell::{Cell, RefCell},
|
||||||
|
num::Wrapping,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
|
|
@ -84,6 +86,7 @@ pub struct State {
|
||||||
pub run_args: RunArgs,
|
pub run_args: RunArgs,
|
||||||
pub xwayland: XWaylandState,
|
pub xwayland: XWaylandState,
|
||||||
pub socket_path: CloneCell<Rc<String>>,
|
pub socket_path: CloneCell<Rc<String>>,
|
||||||
|
pub serial: NumCell<Wrapping<u32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct XWaylandState {
|
pub struct XWaylandState {
|
||||||
|
|
@ -325,4 +328,12 @@ impl State {
|
||||||
*handler = Some(self.eng.spawn(xwayland::manage(self.clone())));
|
*handler = Some(self.eng.spawn(xwayland::manage(self.clone())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
serial
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,11 @@ impl BackendEventHandler {
|
||||||
match event {
|
match event {
|
||||||
BackendEvent::NewConnector(connector) => connector::handle(&self.state, &connector),
|
BackendEvent::NewConnector(connector) => connector::handle(&self.state, &connector),
|
||||||
BackendEvent::NewInputDevice(s) => input_device::handle(&self.state, s),
|
BackendEvent::NewInputDevice(s) => input_device::handle(&self.state, s),
|
||||||
|
BackendEvent::GraphicsInitialized => {
|
||||||
|
if let Some(config) = self.state.config.get() {
|
||||||
|
config.graphics_initialized();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,8 +100,8 @@ fn now() -> c::timespec {
|
||||||
|
|
||||||
fn duration_since(start: c::timespec) -> Duration {
|
fn duration_since(start: c::timespec) -> Duration {
|
||||||
let now = now();
|
let now = now();
|
||||||
let mut nanos =
|
let mut nanos = (now.tv_sec as i64 - start.tv_sec as i64) * 1_000_000_000
|
||||||
(now.tv_sec as i64 - start.tv_sec as i64) * 1_000_000_000 + (now.tv_nsec as i64 - start.tv_nsec as i64);
|
+ (now.tv_nsec as i64 - start.tv_nsec as i64);
|
||||||
if nanos < 0 {
|
if nanos < 0 {
|
||||||
log::error!("Time has gone backwards.");
|
log::error!("Time has gone backwards.");
|
||||||
nanos = 0;
|
nanos = 0;
|
||||||
|
|
|
||||||
30
src/tree.rs
30
src/tree.rs
|
|
@ -195,10 +195,11 @@ pub trait SizedNode: Sized + 'static {
|
||||||
let _ = mods;
|
let _ = mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn button(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) {
|
fn button(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState, serial: u32) {
|
||||||
let _ = seat;
|
let _ = seat;
|
||||||
let _ = button;
|
let _ = button;
|
||||||
let _ = state;
|
let _ = state;
|
||||||
|
let _ = serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn axis_event(self: &Rc<Self>, seat: &WlSeatGlobal, event: &PendingScroll) {
|
fn axis_event(self: &Rc<Self>, seat: &WlSeatGlobal, event: &PendingScroll) {
|
||||||
|
|
@ -346,10 +347,11 @@ pub trait SizedNode: Sized + 'static {
|
||||||
let _ = dnd;
|
let _ = dnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dnd_enter(&self, dnd: &Dnd, x: Fixed, y: Fixed) {
|
fn dnd_enter(&self, dnd: &Dnd, x: Fixed, y: Fixed, serial: u32) {
|
||||||
let _ = dnd;
|
let _ = dnd;
|
||||||
let _ = x;
|
let _ = x;
|
||||||
let _ = y;
|
let _ = y;
|
||||||
|
let _ = serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed) {
|
fn dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed) {
|
||||||
|
|
@ -397,7 +399,13 @@ pub trait Node {
|
||||||
fn node_active_changed(&self, active: bool);
|
fn node_active_changed(&self, active: bool);
|
||||||
fn node_key(&self, seat: &WlSeatGlobal, key: u32, state: u32);
|
fn node_key(&self, seat: &WlSeatGlobal, key: u32, state: u32);
|
||||||
fn node_mods(&self, seat: &WlSeatGlobal, mods: ModifierState);
|
fn node_mods(&self, seat: &WlSeatGlobal, mods: ModifierState);
|
||||||
fn node_button(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState);
|
fn node_button(
|
||||||
|
self: Rc<Self>,
|
||||||
|
seat: &Rc<WlSeatGlobal>,
|
||||||
|
button: u32,
|
||||||
|
state: KeyState,
|
||||||
|
serial: u32,
|
||||||
|
);
|
||||||
fn node_axis_event(self: Rc<Self>, seat: &WlSeatGlobal, event: &PendingScroll);
|
fn node_axis_event(self: Rc<Self>, seat: &WlSeatGlobal, event: &PendingScroll);
|
||||||
fn node_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>);
|
fn node_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>);
|
||||||
fn node_focus_parent(&self, seat: &Rc<WlSeatGlobal>);
|
fn node_focus_parent(&self, seat: &Rc<WlSeatGlobal>);
|
||||||
|
|
@ -431,7 +439,7 @@ pub trait Node {
|
||||||
fn node_into_surface(self: Rc<Self>) -> Option<Rc<WlSurface>>;
|
fn node_into_surface(self: Rc<Self>) -> Option<Rc<WlSurface>>;
|
||||||
fn node_dnd_drop(&self, dnd: &Dnd);
|
fn node_dnd_drop(&self, dnd: &Dnd);
|
||||||
fn node_dnd_leave(&self, dnd: &Dnd);
|
fn node_dnd_leave(&self, dnd: &Dnd);
|
||||||
fn node_dnd_enter(&self, dnd: &Dnd, x: Fixed, y: Fixed);
|
fn node_dnd_enter(&self, dnd: &Dnd, x: Fixed, y: Fixed, serial: u32);
|
||||||
fn node_dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed);
|
fn node_dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -537,8 +545,14 @@ impl<T: SizedNode> Node for T {
|
||||||
fn node_mods(&self, seat: &WlSeatGlobal, mods: ModifierState) {
|
fn node_mods(&self, seat: &WlSeatGlobal, mods: ModifierState) {
|
||||||
<Self as SizedNode>::mods(self, seat, mods)
|
<Self as SizedNode>::mods(self, seat, mods)
|
||||||
}
|
}
|
||||||
fn node_button(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) {
|
fn node_button(
|
||||||
<Self as SizedNode>::button(&self, seat, button, state)
|
self: Rc<Self>,
|
||||||
|
seat: &Rc<WlSeatGlobal>,
|
||||||
|
button: u32,
|
||||||
|
state: KeyState,
|
||||||
|
serial: u32,
|
||||||
|
) {
|
||||||
|
<Self as SizedNode>::button(&self, seat, button, state, serial)
|
||||||
}
|
}
|
||||||
fn node_axis_event(self: Rc<Self>, seat: &WlSeatGlobal, event: &PendingScroll) {
|
fn node_axis_event(self: Rc<Self>, seat: &WlSeatGlobal, event: &PendingScroll) {
|
||||||
<Self as SizedNode>::axis_event(&self, seat, event)
|
<Self as SizedNode>::axis_event(&self, seat, event)
|
||||||
|
|
@ -639,8 +653,8 @@ impl<T: SizedNode> Node for T {
|
||||||
fn node_dnd_leave(&self, dnd: &Dnd) {
|
fn node_dnd_leave(&self, dnd: &Dnd) {
|
||||||
<Self as SizedNode>::dnd_leave(self, dnd)
|
<Self as SizedNode>::dnd_leave(self, dnd)
|
||||||
}
|
}
|
||||||
fn node_dnd_enter(&self, dnd: &Dnd, x: Fixed, y: Fixed) {
|
fn node_dnd_enter(&self, dnd: &Dnd, x: Fixed, y: Fixed, serial: u32) {
|
||||||
<Self as SizedNode>::dnd_enter(self, dnd, x, y)
|
<Self as SizedNode>::dnd_enter(self, dnd, x, y, serial)
|
||||||
}
|
}
|
||||||
fn node_dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed) {
|
fn node_dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed) {
|
||||||
<Self as SizedNode>::dnd_motion(self, dnd, x, y)
|
<Self as SizedNode>::dnd_motion(self, dnd, x, y)
|
||||||
|
|
|
||||||
|
|
@ -1040,7 +1040,13 @@ impl SizedNode for ContainerNode {
|
||||||
self.parent.get().node_child_active_changed(self, active, 1);
|
self.parent.get().node_child_active_changed(self, active, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn button(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) {
|
fn button(
|
||||||
|
self: &Rc<Self>,
|
||||||
|
seat: &Rc<WlSeatGlobal>,
|
||||||
|
button: u32,
|
||||||
|
state: KeyState,
|
||||||
|
_serial: u32,
|
||||||
|
) {
|
||||||
if button != BTN_LEFT {
|
if button != BTN_LEFT {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -377,7 +377,13 @@ impl SizedNode for FloatNode {
|
||||||
self.position.get()
|
self.position.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn button(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) {
|
fn button(
|
||||||
|
self: &Rc<Self>,
|
||||||
|
seat: &Rc<WlSeatGlobal>,
|
||||||
|
button: u32,
|
||||||
|
state: KeyState,
|
||||||
|
_serial: u32,
|
||||||
|
) {
|
||||||
if button != BTN_LEFT {
|
if button != BTN_LEFT {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1359,14 +1359,6 @@ impl Wm {
|
||||||
Some(d) => d,
|
Some(d) => d,
|
||||||
_ => return Ok(()),
|
_ => return Ok(()),
|
||||||
};
|
};
|
||||||
let extents = Rect::new_sized(
|
|
||||||
event.x as _,
|
|
||||||
event.y as _,
|
|
||||||
event.width as _,
|
|
||||||
event.height as _,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
// log::info!("xwin {} configure_notify {:?}", data.window_id, extents);
|
|
||||||
self.update_override_redirect(data, event.override_redirect);
|
self.update_override_redirect(data, event.override_redirect);
|
||||||
if data.info.override_redirect.get() {
|
if data.info.override_redirect.get() {
|
||||||
let extents = Rect::new_sized(
|
let extents = Rect::new_sized(
|
||||||
|
|
@ -1375,7 +1367,7 @@ impl Wm {
|
||||||
event.width as _,
|
event.width as _,
|
||||||
event.height as _,
|
event.height as _,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if let Some(window) = data.window.get() {
|
if let Some(window) = data.window.get() {
|
||||||
window.change_extents(&extents);
|
window.change_extents(&extents);
|
||||||
self.state.tree_changed();
|
self.state.tree_changed();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue