1
0
Fork 0
forked from wry/wry

autocommit 2022-04-17 17:08:31 CEST

This commit is contained in:
Julian Orth 2022-04-17 17:08:31 +02:00
parent 50b792db78
commit a30306e3d5
23 changed files with 390 additions and 42 deletions

View file

@ -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,

View file

@ -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(())
}

View file

@ -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
View 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);

View file

@ -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(())
}

View file

@ -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>) {

View file

@ -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| {

View file

@ -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);

View file

@ -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) {

View file

@ -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)]

View file

@ -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()));
}
}