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
|
|
@ -61,10 +61,10 @@ impl WlDataDevice {
|
|||
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_id: self.id,
|
||||
serial: 0,
|
||||
serial,
|
||||
surface,
|
||||
x,
|
||||
y,
|
||||
|
|
@ -87,6 +87,7 @@ impl WlDataDevice {
|
|||
|
||||
fn start_drag(&self, parser: MsgParser<'_, '_>) -> Result<(), StartDragError> {
|
||||
let req: StartDrag = self.manager.client.parse(self, parser)?;
|
||||
self.manager.client.validate_serial(req.serial)?;
|
||||
let origin = self.manager.client.lookup(req.origin)?;
|
||||
let source = if req.source.is_some() {
|
||||
Some(self.manager.client.lookup(req.source)?)
|
||||
|
|
@ -100,18 +101,29 @@ impl WlDataDevice {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
self.seat.global.start_drag(&origin, source, icon)?;
|
||||
self.seat
|
||||
.global
|
||||
.start_drag(&origin, source, icon, req.serial)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_selection(&self, parser: MsgParser<'_, '_>) -> Result<(), SetSelectionError> {
|
||||
let req: SetSelection = self.manager.client.parse(self, parser)?;
|
||||
self.manager.client.validate_serial(req.serial)?;
|
||||
if !self
|
||||
.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() {
|
||||
None
|
||||
} else {
|
||||
Some(self.manager.client.lookup(req.source)?)
|
||||
};
|
||||
self.seat.global.set_selection(src)?;
|
||||
self.seat.global.set_selection(src, Some(req.serial))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ impl WlDataOffer {
|
|||
|
||||
fn accept(&self, parser: MsgParser<'_, '_>) -> Result<(), AcceptError> {
|
||||
let req: Accept = self.client.parse(self, parser)?;
|
||||
let _ = req.serial; // unused
|
||||
let mut state = self.data.shared.state.get();
|
||||
if state.contains(OFFER_STATE_FINISHED) {
|
||||
return Err(AcceptError::AlreadyFinished);
|
||||
|
|
|
|||
|
|
@ -63,12 +63,17 @@ impl ZwpPrimarySelectionDeviceV1 {
|
|||
|
||||
fn set_selection(&self, parser: MsgParser<'_, '_>) -> Result<(), SetSelectionError> {
|
||||
let req: SetSelection = self.manager.client.parse(self, parser)?;
|
||||
self.seat.client.validate_serial(req.serial)?;
|
||||
if !self.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() {
|
||||
None
|
||||
} else {
|
||||
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(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ use {
|
|||
copyhashmap::CopyHashMap,
|
||||
errorfmt::ErrorFmt,
|
||||
linkedlist::{LinkedList, LinkedNode},
|
||||
numcell::NumCell,
|
||||
rc_eq::rc_eq,
|
||||
},
|
||||
wire::{
|
||||
|
|
@ -127,10 +126,11 @@ pub struct WlSeatGlobal {
|
|||
kb_map: CloneCell<Rc<XkbKeymap>>,
|
||||
kb_state: RefCell<XkbState>,
|
||||
cursor: CloneCell<Option<Rc<dyn Cursor>>>,
|
||||
serial: NumCell<u32>,
|
||||
tree_changed: Rc<AsyncEvent>,
|
||||
selection: CloneCell<Option<Rc<WlDataSource>>>,
|
||||
selection_serial: Cell<u32>,
|
||||
primary_selection: CloneCell<Option<Rc<ZwpPrimarySelectionSourceV1>>>,
|
||||
primary_selection_serial: Cell<u32>,
|
||||
pointer_owner: PointerOwnerHolder,
|
||||
kb_owner: KbOwnerHolder,
|
||||
dropped_dnd: RefCell<Option<DroppedDnd>>,
|
||||
|
|
@ -164,10 +164,11 @@ impl WlSeatGlobal {
|
|||
kb_map: CloneCell::new(state.default_keymap.clone()),
|
||||
kb_state: RefCell::new(state.default_keymap.state().unwrap()),
|
||||
cursor: Default::default(),
|
||||
serial: Default::default(),
|
||||
tree_changed: Default::default(),
|
||||
selection: Default::default(),
|
||||
selection_serial: Cell::new(0),
|
||||
primary_selection: Default::default(),
|
||||
primary_selection_serial: Cell::new(0),
|
||||
pointer_owner: Default::default(),
|
||||
kb_owner: Default::default(),
|
||||
dropped_dnd: RefCell::new(None),
|
||||
|
|
@ -333,8 +334,9 @@ impl WlSeatGlobal {
|
|||
origin: &Rc<WlSurface>,
|
||||
source: Option<Rc<WlDataSource>>,
|
||||
icon: Option<Rc<WlSurface>>,
|
||||
serial: u32,
|
||||
) -> 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>) {
|
||||
|
|
@ -342,24 +344,49 @@ impl WlSeatGlobal {
|
|||
}
|
||||
|
||||
pub fn unset_selection(self: &Rc<Self>) {
|
||||
let _ = self.set_selection(None);
|
||||
let _ = self.set_selection(None, None);
|
||||
}
|
||||
|
||||
pub fn set_selection(
|
||||
self: &Rc<Self>,
|
||||
selection: Option<Rc<WlDataSource>>,
|
||||
serial: Option<u32>,
|
||||
) -> Result<(), WlSeatError> {
|
||||
if let Some(serial) = serial {
|
||||
self.selection_serial.set(serial);
|
||||
}
|
||||
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>) {
|
||||
let _ = self.set_primary_selection(None);
|
||||
let _ = self.set_primary_selection(None, None);
|
||||
}
|
||||
|
||||
pub fn set_primary_selection(
|
||||
self: &Rc<Self>,
|
||||
selection: Option<Rc<ZwpPrimarySelectionSourceV1>>,
|
||||
serial: Option<u32>,
|
||||
) -> Result<(), WlSeatError> {
|
||||
if let Some(serial) = serial {
|
||||
self.primary_selection_serial.set(serial);
|
||||
}
|
||||
self.set_selection_::<ZwpPrimarySelectionDeviceV1>(&self.primary_selection, selection)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -457,12 +457,17 @@ impl WlSeatGlobal {
|
|||
|
||||
// Button callbacks
|
||||
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 {
|
||||
KeyState::Released => (wl_pointer::RELEASED, false),
|
||||
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_frame(surface);
|
||||
if pressed && surface.accepts_kb_focus() {
|
||||
|
|
@ -522,7 +527,8 @@ impl WlSeatGlobal {
|
|||
}
|
||||
|
||||
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_frame(n);
|
||||
}
|
||||
|
|
@ -531,7 +537,7 @@ impl WlSeatGlobal {
|
|||
// Leave callbacks
|
||||
impl WlSeatGlobal {
|
||||
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_frame(n);
|
||||
}
|
||||
|
|
@ -540,7 +546,8 @@ impl WlSeatGlobal {
|
|||
// Unfocus callbacks
|
||||
impl WlSeatGlobal {
|
||||
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 {
|
||||
pub fn focus_surface(&self, surface: &WlSurface) {
|
||||
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| {
|
||||
k.send_enter(serial, surface.id, &pressed_keys)
|
||||
});
|
||||
|
|
@ -559,7 +566,7 @@ impl WlSeatGlobal {
|
|||
group,
|
||||
..
|
||||
} = 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| {
|
||||
k.send_modifiers(serial, mods_depressed, mods_latched, mods_locked, group)
|
||||
});
|
||||
|
|
@ -577,7 +584,7 @@ impl WlSeatGlobal {
|
|||
// Key callbacks
|
||||
impl WlSeatGlobal {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
@ -585,7 +592,7 @@ impl WlSeatGlobal {
|
|||
// Modifiers callbacks
|
||||
impl WlSeatGlobal {
|
||||
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| {
|
||||
k.send_modifiers(
|
||||
serial,
|
||||
|
|
@ -624,16 +631,16 @@ impl WlSeatGlobal {
|
|||
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 {
|
||||
ipc::offer_source_to::<WlDataDevice>(src, &surface.client);
|
||||
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();
|
||||
})
|
||||
} else if surface.client.id == dnd.client.id {
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -68,8 +68,11 @@ impl PointerOwnerHolder {
|
|||
origin: &Rc<WlSurface>,
|
||||
source: Option<Rc<WlDataSource>>,
|
||||
icon: Option<Rc<WlSurface>>,
|
||||
serial: u32,
|
||||
) -> 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>) {
|
||||
|
|
@ -103,6 +106,7 @@ trait PointerOwner {
|
|||
origin: &Rc<WlSurface>,
|
||||
source: Option<Rc<WlDataSource>>,
|
||||
icon: Option<Rc<WlSurface>>,
|
||||
serial: u32,
|
||||
) -> Result<(), WlSeatError>;
|
||||
fn cancel_dnd(&self, seat: &Rc<WlSeatGlobal>);
|
||||
fn revert_to_default(&self, seat: &Rc<WlSeatGlobal>);
|
||||
|
|
@ -116,6 +120,7 @@ struct DefaultPointerOwner;
|
|||
struct GrabPointerOwner {
|
||||
buttons: SmallMap<u32, (), 1>,
|
||||
node: Rc<dyn Node>,
|
||||
serial: u32,
|
||||
}
|
||||
|
||||
struct DndPointerOwner {
|
||||
|
|
@ -136,12 +141,14 @@ impl PointerOwner for DefaultPointerOwner {
|
|||
Some(n) => n,
|
||||
_ => return,
|
||||
};
|
||||
let serial = seat.state.next_serial(pn.node_client().as_deref());
|
||||
seat.pointer_owner.owner.set(Rc::new(GrabPointerOwner {
|
||||
buttons: SmallMap::new_with(button, ()),
|
||||
node: pn.clone(),
|
||||
serial,
|
||||
}));
|
||||
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>> {
|
||||
|
|
@ -217,6 +224,7 @@ impl PointerOwner for DefaultPointerOwner {
|
|||
_origin: &Rc<WlSurface>,
|
||||
source: Option<Rc<WlDataSource>>,
|
||||
_icon: Option<Rc<WlSurface>>,
|
||||
_serial: u32,
|
||||
) -> Result<(), WlSeatError> {
|
||||
if let Some(src) = source {
|
||||
src.send_cancelled();
|
||||
|
|
@ -262,7 +270,8 @@ impl PointerOwner for GrabPointerOwner {
|
|||
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>> {
|
||||
|
|
@ -284,6 +293,7 @@ impl PointerOwner for GrabPointerOwner {
|
|||
origin: &Rc<WlSurface>,
|
||||
src: Option<Rc<WlDataSource>>,
|
||||
icon: Option<Rc<WlSurface>>,
|
||||
serial: u32,
|
||||
) -> Result<(), WlSeatError> {
|
||||
let button = match self.buttons.iter().next() {
|
||||
Some((b, _)) => b,
|
||||
|
|
@ -292,6 +302,9 @@ impl PointerOwner for GrabPointerOwner {
|
|||
if self.buttons.len() != 1 {
|
||||
return Ok(());
|
||||
}
|
||||
if serial != self.serial {
|
||||
return Ok(());
|
||||
}
|
||||
if self.node.node_id() != origin.node_id {
|
||||
return Ok(());
|
||||
}
|
||||
|
|
@ -413,7 +426,7 @@ impl PointerOwner for DndPointerOwner {
|
|||
target.node_dnd_leave(&self.dnd);
|
||||
target.node_seat_state().remove_dnd_target(seat);
|
||||
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);
|
||||
self.target.set(target);
|
||||
} else if (self.pos_x.get(), self.pos_y.get()) != (x, y) {
|
||||
|
|
@ -429,6 +442,7 @@ impl PointerOwner for DndPointerOwner {
|
|||
_origin: &Rc<WlSurface>,
|
||||
source: Option<Rc<WlDataSource>>,
|
||||
_icon: Option<Rc<WlSurface>>,
|
||||
_serial: u32,
|
||||
) -> Result<(), WlSeatError> {
|
||||
if let Some(src) = source {
|
||||
src.send_cancelled();
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ impl WlPointer {
|
|||
|
||||
fn set_cursor(&self, parser: MsgParser<'_, '_>) -> Result<(), SetCursorError> {
|
||||
let req: SetCursor = self.seat.client.parse(self, parser)?;
|
||||
self.seat.client.validate_serial(req.serial)?;
|
||||
let mut cursor_opt = None;
|
||||
if req.surface.is_some() {
|
||||
let surface = self.seat.client.lookup(req.surface)?;
|
||||
|
|
@ -163,7 +164,7 @@ impl WlPointer {
|
|||
cursor.set_hotspot(req.hotspot_x, req.hotspot_y);
|
||||
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,
|
||||
_ => {
|
||||
// cannot happen
|
||||
|
|
@ -173,6 +174,9 @@ impl WlPointer {
|
|||
if pointer_node.node_client_id() != Some(self.seat.client.id) {
|
||||
return Ok(());
|
||||
}
|
||||
if req.serial != self.seat.client.last_enter_serial.get() {
|
||||
return Ok(());
|
||||
}
|
||||
self.seat.global.set_app_cursor(cursor_opt);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -795,8 +795,8 @@ impl SizedNode for WlSurface {
|
|||
seat.mods_surface(self, mods);
|
||||
}
|
||||
|
||||
fn button(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) {
|
||||
seat.button_surface(&self, button, state);
|
||||
fn button(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState, serial: u32) {
|
||||
seat.button_surface(&self, button, state, serial);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
fn dnd_enter(&self, dnd: &Dnd, x: Fixed, y: Fixed) {
|
||||
dnd.seat.dnd_surface_enter(self, dnd, x, y);
|
||||
fn dnd_enter(&self, dnd: &Dnd, x: Fixed, y: Fixed, serial: u32) {
|
||||
dnd.seat.dnd_surface_enter(self, dnd, x, y, serial);
|
||||
}
|
||||
|
||||
fn dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed) {
|
||||
|
|
|
|||
|
|
@ -278,9 +278,12 @@ impl Xwindow {
|
|||
match map_change {
|
||||
Change::None => return,
|
||||
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);
|
||||
},
|
||||
}
|
||||
Change::Map if self.data.info.override_redirect.get() => {
|
||||
self.change_extents(&self.data.info.pending_extents.get());
|
||||
*self.display_link.borrow_mut() =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue