autocommit 2022-04-17 17:08:31 CEST
This commit is contained in:
parent
50b792db78
commit
a30306e3d5
23 changed files with 390 additions and 42 deletions
|
|
@ -61,7 +61,14 @@ impl WlDataDevice {
|
|||
self.manager.client.event(Leave { self_id: self.id })
|
||||
}
|
||||
|
||||
pub fn send_enter(&self, surface: WlSurfaceId, x: Fixed, y: Fixed, offer: WlDataOfferId, serial: u32) {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -64,7 +64,11 @@ 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) {
|
||||
if !self
|
||||
.seat
|
||||
.global
|
||||
.may_modify_primary_selection(&self.seat.client, req.serial)
|
||||
{
|
||||
log::warn!("Ignoring disallowed set_selection request");
|
||||
return Ok(());
|
||||
}
|
||||
|
|
@ -73,7 +77,9 @@ impl ZwpPrimarySelectionDeviceV1 {
|
|||
} else {
|
||||
Some(self.manager.client.lookup(req.source)?)
|
||||
};
|
||||
self.seat.global.set_primary_selection(src, Some(req.serial))?;
|
||||
self.seat
|
||||
.global
|
||||
.set_primary_selection(src, Some(req.serial))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ use {
|
|||
std::{ops::Deref, rc::Rc},
|
||||
thiserror::Error,
|
||||
};
|
||||
use crate::ifs::jay_idle::JayIdle;
|
||||
|
||||
pub struct JayCompositorGlobal {
|
||||
name: GlobalName,
|
||||
|
|
@ -140,6 +141,18 @@ impl JayCompositor {
|
|||
self.client.remove_obj(ss.deref())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_idle(&self, parser: MsgParser<'_, '_>) -> Result<(), JayCompositorError> {
|
||||
let req: GetIdle = self.client.parse(self, parser)?;
|
||||
let idle = Rc::new(JayIdle {
|
||||
id: req.id,
|
||||
client: self.client.clone(),
|
||||
tracker: Default::default(),
|
||||
});
|
||||
track!(self.client, idle);
|
||||
self.client.add_client_obj(&idle)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
object_base2! {
|
||||
|
|
@ -150,11 +163,12 @@ object_base2! {
|
|||
QUIT => quit,
|
||||
SET_LOG_LEVEL => set_log_level,
|
||||
TAKE_SCREENSHOT => take_screenshot,
|
||||
GET_IDLE => get_idle,
|
||||
}
|
||||
|
||||
impl Object for JayCompositor {
|
||||
fn num_requests(&self) -> u32 {
|
||||
TAKE_SCREENSHOT + 1
|
||||
GET_IDLE + 1
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
68
src/ifs/jay_idle.rs
Normal file
68
src/ifs/jay_idle.rs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
use std::time::Duration;
|
||||
use thiserror::Error;
|
||||
use {
|
||||
crate::{
|
||||
client::Client,
|
||||
leaks::Tracker,
|
||||
object::Object,
|
||||
wire::{jay_idle::*},
|
||||
},
|
||||
std::rc::Rc,
|
||||
};
|
||||
use crate::client::ClientError;
|
||||
use crate::utils::buffd::{MsgParser, MsgParserError};
|
||||
use crate::wire::JayIdleId;
|
||||
|
||||
pub struct JayIdle {
|
||||
pub id: JayIdleId,
|
||||
pub client: Rc<Client>,
|
||||
pub tracker: Tracker<Self>,
|
||||
}
|
||||
|
||||
impl JayIdle {
|
||||
fn send_interval(&self) {
|
||||
let to = self.client.state.idle.timeout.get();
|
||||
self.client.event(Interval {
|
||||
self_id: self.id,
|
||||
interval: to.as_secs(),
|
||||
});
|
||||
}
|
||||
|
||||
fn get_status(&self, parser: MsgParser<'_, '_>) -> Result<(), JayIdleError> {
|
||||
let _req: GetStatus = self.client.parse(self, parser)?;
|
||||
self.send_interval();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_interval(&self, parser: MsgParser<'_, '_>) -> Result<(), JayIdleError> {
|
||||
let req: SetInterval = self.client.parse(self, parser)?;
|
||||
let interval = Duration::from_secs(req.interval);
|
||||
self.client.state.idle.set_timeout(interval);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
object_base2! {
|
||||
JayIdle;
|
||||
|
||||
GET_STATUS => get_status,
|
||||
SET_INTERVAL => set_interval,
|
||||
}
|
||||
|
||||
impl Object for JayIdle {
|
||||
fn num_requests(&self) -> u32 {
|
||||
SET_INTERVAL + 1
|
||||
}
|
||||
}
|
||||
|
||||
simple_add_obj!(JayIdle);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum JayIdleError {
|
||||
#[error("Parsing failed")]
|
||||
MsgParserError(#[source] Box<MsgParserError>),
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(JayIdleError, ClientError);
|
||||
efrom!(JayIdleError, MsgParserError);
|
||||
|
|
@ -53,8 +53,8 @@ impl WlCompositor {
|
|||
let surface = Rc::new(WlSurface::new(surface.id, &self.client));
|
||||
track!(self.client, surface);
|
||||
self.client.add_client_obj(&surface)?;
|
||||
if let Some(queue) = &self.client.xwayland_queue {
|
||||
queue.push(XWaylandEvent::SurfaceCreated(surface.clone()));
|
||||
if self.client.is_xwayland {
|
||||
self.client.state.xwayland.queue.push(XWaylandEvent::SurfaceCreated(surface.clone()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -336,7 +336,8 @@ impl WlSeatGlobal {
|
|||
icon: Option<Rc<WlSurface>>,
|
||||
serial: u32,
|
||||
) -> Result<(), WlSeatError> {
|
||||
self.pointer_owner.start_drag(self, origin, source, icon, serial)
|
||||
self.pointer_owner
|
||||
.start_drag(self, origin, source, icon, serial)
|
||||
}
|
||||
|
||||
pub fn cancel_dnd(self: &Rc<Self>) {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ use {
|
|||
pub struct NodeSeatState {
|
||||
pointer_foci: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
|
||||
kb_foci: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
|
||||
grabs: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
|
||||
pointer_grabs: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
|
||||
dnd_targets: SmallMap<SeatId, Rc<WlSeatGlobal>, 1>,
|
||||
}
|
||||
|
||||
|
|
@ -59,11 +59,11 @@ impl NodeSeatState {
|
|||
}
|
||||
|
||||
pub(super) fn add_pointer_grab(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
self.grabs.insert(seat.id, seat.clone());
|
||||
self.pointer_grabs.insert(seat.id, seat.clone());
|
||||
}
|
||||
|
||||
pub(super) fn remove_pointer_grab(&self, seat: &WlSeatGlobal) {
|
||||
self.grabs.remove(&seat.id);
|
||||
self.pointer_grabs.remove(&seat.id);
|
||||
}
|
||||
|
||||
pub(super) fn add_dnd_target(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
|
|
@ -89,10 +89,10 @@ impl NodeSeatState {
|
|||
}
|
||||
|
||||
fn release_kb_focus2(&self, focus_last: bool) {
|
||||
self.release_kb_grab();
|
||||
while let Some((_, seat)) = self.kb_foci.pop() {
|
||||
seat.ungrab_kb();
|
||||
seat.keyboard_node.set(seat.state.root.clone());
|
||||
log::info!("keyboard_node = root");
|
||||
// log::info!("keyboard_node = root");
|
||||
if focus_last {
|
||||
if let Some(tl) = seat.toplevel_focus_history.last() {
|
||||
seat.focus_node(tl.focus_surface(seat.id));
|
||||
|
|
@ -116,7 +116,7 @@ impl NodeSeatState {
|
|||
fn destroy_node2(&self, node: &dyn Node, focus_last: bool) {
|
||||
// NOTE: Also called by set_visible(false)
|
||||
|
||||
while let Some((_, seat)) = self.grabs.pop() {
|
||||
while let Some((_, seat)) = self.pointer_grabs.pop() {
|
||||
seat.pointer_owner.revert_to_default(&seat);
|
||||
}
|
||||
let node_id = node.node_id();
|
||||
|
|
@ -631,7 +631,14 @@ impl WlSeatGlobal {
|
|||
surface.client.flush();
|
||||
}
|
||||
|
||||
pub fn dnd_surface_enter(&self, surface: &WlSurface, dnd: &Dnd, x: Fixed, y: Fixed, serial: u32) {
|
||||
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| {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use {
|
|||
crate::{ifs::wl_seat::WlSeatGlobal, tree::Node, utils::clonecell::CloneCell},
|
||||
std::rc::Rc,
|
||||
};
|
||||
use crate::xwayland::XWaylandEvent;
|
||||
|
||||
pub struct KbOwnerHolder {
|
||||
default: Rc<DefaultKbOwner>,
|
||||
|
|
@ -58,6 +59,9 @@ impl KbOwner for DefaultKbOwner {
|
|||
return;
|
||||
}
|
||||
log::info!("unfocus {}", old.node_id());
|
||||
if old.node_is_xwayland_surface() && !node.node_is_xwayland_surface() {
|
||||
seat.state.xwayland.queue.push(XWaylandEvent::ActivateRoot);
|
||||
}
|
||||
old.node_unfocus(seat);
|
||||
if old.node_seat_state().unfocus(seat) {
|
||||
old.node_active_changed(false);
|
||||
|
|
|
|||
|
|
@ -426,7 +426,12 @@ 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, seat.state.next_serial(target.node_client().as_deref()));
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -866,6 +866,10 @@ impl SizedNode for WlSurface {
|
|||
fn dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed) {
|
||||
dnd.seat.dnd_surface_motion(self, dnd, x, y);
|
||||
}
|
||||
|
||||
fn is_xwayland_surface(&self) -> bool {
|
||||
self.client.is_xwayland
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use {
|
|||
},
|
||||
utils::{
|
||||
clonecell::CloneCell, copyhashmap::CopyHashMap, linkedlist::LinkedNode,
|
||||
queue::AsyncQueue, smallmap::SmallMap,
|
||||
smallmap::SmallMap,
|
||||
},
|
||||
wire::WlSurfaceId,
|
||||
wire_xcon::CreateNotify,
|
||||
|
|
@ -139,7 +139,6 @@ pub struct Xwindow {
|
|||
pub surface: Rc<WlSurface>,
|
||||
pub parent_node: CloneCell<Option<Rc<dyn Node>>>,
|
||||
pub focus_history: SmallMap<SeatId, LinkedNode<Rc<dyn ToplevelNode>>, 1>,
|
||||
pub events: Rc<AsyncQueue<XWaylandEvent>>,
|
||||
pub workspace: CloneCell<Option<Rc<WorkspaceNode>>>,
|
||||
pub display_link: RefCell<Option<LinkedNode<Rc<dyn Node>>>>,
|
||||
pub toplevel_data: ToplevelData,
|
||||
|
|
@ -207,7 +206,6 @@ impl Xwindow {
|
|||
pub fn new(
|
||||
data: &Rc<XwindowData>,
|
||||
surface: &Rc<WlSurface>,
|
||||
events: &Rc<AsyncQueue<XWaylandEvent>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
id: data.state.node_ids.next(),
|
||||
|
|
@ -216,7 +214,6 @@ impl Xwindow {
|
|||
surface: surface.clone(),
|
||||
parent_node: Default::default(),
|
||||
focus_history: Default::default(),
|
||||
events: events.clone(),
|
||||
workspace: Default::default(),
|
||||
display_link: Default::default(),
|
||||
toplevel_data: Default::default(),
|
||||
|
|
@ -249,7 +246,11 @@ impl Xwindow {
|
|||
_ => return,
|
||||
};
|
||||
let extents = self.surface.extents.get();
|
||||
// parent.child_active_changed(self, self.active_surfaces.get() > 0);
|
||||
parent.clone().node_child_active_changed(
|
||||
self,
|
||||
self.toplevel_data.active_surfaces.get() > 0,
|
||||
1,
|
||||
);
|
||||
parent.node_child_size_changed(self, extents.width(), extents.height());
|
||||
parent.node_child_title_changed(
|
||||
self,
|
||||
|
|
@ -322,8 +323,7 @@ impl SurfaceExt for Xwindow {
|
|||
self.surface.unset_ext();
|
||||
self.data.window.set(None);
|
||||
self.data.surface_id.set(None);
|
||||
self.events
|
||||
.push(XWaylandEvent::SurfaceDestroyed(self.surface.id));
|
||||
self.data.state.xwayland.queue.push(XWaylandEvent::SurfaceDestroyed(self.surface.id));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -389,7 +389,7 @@ impl SizedNode for Xwindow {
|
|||
}
|
||||
|
||||
fn close(&self) {
|
||||
self.events.push(XWaylandEvent::Close(self.data.clone()));
|
||||
self.data.state.xwayland.queue.push(XWaylandEvent::Close(self.data.clone()));
|
||||
}
|
||||
|
||||
fn absolute_position(&self) -> Rect {
|
||||
|
|
@ -427,7 +427,7 @@ impl SizedNode for Xwindow {
|
|||
let old = self.data.info.extents.replace(*rect);
|
||||
if old != *rect {
|
||||
if !self.data.info.override_redirect.get() {
|
||||
self.events.push(XWaylandEvent::Configure(self.clone()));
|
||||
self.data.state.xwayland.queue.push(XWaylandEvent::Configure(self.clone()));
|
||||
}
|
||||
if old.position() != rect.position() {
|
||||
self.surface.set_absolute_position(rect.x1(), rect.y1());
|
||||
|
|
@ -482,7 +482,7 @@ impl ToplevelNode for Xwindow {
|
|||
}
|
||||
|
||||
fn activate(&self) {
|
||||
self.events.push(XWaylandEvent::Activate(self.data.clone()));
|
||||
self.data.state.xwayland.queue.push(XWaylandEvent::Activate(self.data.clone()));
|
||||
}
|
||||
|
||||
fn toggle_floating(self: Rc<Self>) {
|
||||
|
|
@ -503,7 +503,7 @@ impl ToplevelNode for Xwindow {
|
|||
}
|
||||
|
||||
fn close(&self) {
|
||||
self.events.push(XWaylandEvent::Close(self.data.clone()));
|
||||
self.data.state.xwayland.queue.push(XWaylandEvent::Close(self.data.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue