1
0
Fork 0
forked from wry/wry

wl_usr: refactor interfaces

This commit is contained in:
Julian Orth 2026-02-22 00:14:19 +01:00
parent 4b3d3a50cd
commit 56290d5547
12 changed files with 121 additions and 82 deletions

View file

@ -2,6 +2,7 @@ use {
crate::{ crate::{
gfx_api::{GfxApi, GfxFormat, cross_intersect_formats}, gfx_api::{GfxApi, GfxFormat, cross_intersect_formats},
gfx_apis::create_gfx_context, gfx_apis::create_gfx_context,
globals::GlobalName,
ifs::wl_seat::POINTER, ifs::wl_seat::POINTER,
object::Version, object::Version,
portal::{ portal::{
@ -60,7 +61,7 @@ struct PortalDisplayPrelude {
con: Rc<UsrCon>, con: Rc<UsrCon>,
state: Rc<PortalState>, state: Rc<PortalState>,
registry: Rc<UsrWlRegistry>, registry: Rc<UsrWlRegistry>,
globals: RefCell<AHashMap<String, Vec<(u32, u32)>>>, globals: RefCell<AHashMap<String, Vec<(GlobalName, u32)>>>,
} }
shared_ids!(PortalDisplayId); shared_ids!(PortalDisplayId);
@ -80,8 +81,8 @@ pub struct PortalDisplay {
pub vp: Rc<UsrWpViewporter>, pub vp: Rc<UsrWpViewporter>,
pub render_ctx: CloneCell<Option<Rc<PortalServerRenderCtx>>>, pub render_ctx: CloneCell<Option<Rc<PortalServerRenderCtx>>>,
pub outputs: CopyHashMap<u32, Rc<PortalOutput>>, pub outputs: CopyHashMap<GlobalName, Rc<PortalOutput>>,
pub seats: CopyHashMap<u32, Rc<PortalSeat>>, pub seats: CopyHashMap<GlobalName, Rc<PortalSeat>>,
pub workspaces: CopyHashMap<u32, Rc<UsrJayWorkspace>>, pub workspaces: CopyHashMap<u32, Rc<UsrJayWorkspace>>,
pub windows: CopyHashMap<WlSurfaceId, Rc<WindowData>>, pub windows: CopyHashMap<WlSurfaceId, Rc<WindowData>>,
@ -89,14 +90,14 @@ pub struct PortalDisplay {
} }
pub struct PortalOutput { pub struct PortalOutput {
pub global_id: u32, pub global_id: GlobalName,
pub dpy: Rc<PortalDisplay>, pub dpy: Rc<PortalDisplay>,
pub wl: Rc<UsrWlOutput>, pub wl: Rc<UsrWlOutput>,
pub jay: Rc<UsrJayOutput>, pub jay: Rc<UsrJayOutput>,
} }
pub struct PortalSeat { pub struct PortalSeat {
pub global_id: u32, pub global_id: GlobalName,
pub dpy: Rc<PortalDisplay>, pub dpy: Rc<PortalDisplay>,
pub wl: Rc<UsrWlSeat>, pub wl: Rc<UsrWlSeat>,
pub jay_pointer: Rc<UsrJayPointer>, pub jay_pointer: Rc<UsrJayPointer>,
@ -128,32 +129,32 @@ impl UsrWlSeatOwner for PortalSeat {
} }
impl UsrWlPointerOwner for PortalSeat { impl UsrWlPointerOwner for PortalSeat {
fn enter(&self, ev: &wl_pointer::Enter) { fn enter(self: Rc<Self>, ev: &wl_pointer::Enter) {
if let Some(window) = self.dpy.windows.get(&ev.surface) { if let Some(window) = self.dpy.windows.get(&ev.surface) {
self.pointer_focus.set(Some(window.clone())); self.pointer_focus.set(Some(window.clone()));
window.motion(self, ev.surface_x, ev.surface_y, true); window.motion(&self, ev.surface_x, ev.surface_y, true);
} }
} }
fn leave(&self, _ev: &wl_pointer::Leave) { fn leave(self: Rc<Self>, _ev: &wl_pointer::Leave) {
self.pointer_focus.take(); self.pointer_focus.take();
} }
fn motion(&self, ev: &wl_pointer::Motion) { fn motion(self: Rc<Self>, ev: &wl_pointer::Motion) {
if let Some(window) = self.pointer_focus.get() { if let Some(window) = self.pointer_focus.get() {
window.motion(self, ev.surface_x, ev.surface_y, false); window.motion(&self, ev.surface_x, ev.surface_y, false);
} }
} }
fn button(&self, ev: &wl_pointer::Button) { fn button(self: Rc<Self>, ev: &wl_pointer::Button) {
if let Some(window) = self.pointer_focus.get() { if let Some(window) = self.pointer_focus.get() {
window.button(self, ev.button, ev.state); window.button(&self, ev.button, ev.state);
} }
} }
} }
impl UsrWlRegistryOwner for PortalDisplayPrelude { impl UsrWlRegistryOwner for PortalDisplayPrelude {
fn global(self: Rc<Self>, name: u32, interface: &str, version: u32) { fn global(self: Rc<Self>, name: GlobalName, interface: &str, version: u32) {
self.globals self.globals
.borrow_mut() .borrow_mut()
.entry(interface.to_string()) .entry(interface.to_string())
@ -237,7 +238,7 @@ impl UsrConOwner for PortalDisplay {
} }
impl UsrWlRegistryOwner for PortalDisplay { impl UsrWlRegistryOwner for PortalDisplay {
fn global(self: Rc<Self>, name: u32, interface: &str, version: u32) { fn global(self: Rc<Self>, name: GlobalName, interface: &str, version: u32) {
if interface == WlOutput.name() { if interface == WlOutput.name() {
add_output(&self, name, version); add_output(&self, name, version);
} else if interface == WlSeat.name() { } else if interface == WlSeat.name() {
@ -250,7 +251,7 @@ impl UsrWlRegistryOwner for PortalDisplay {
version: Version(version.min(5)), version: Version(version.min(5)),
}); });
self.con.add_object(ls.clone()); self.con.add_object(ls.clone());
self.registry.request_bind(name, ls.version.0, ls.deref()); self.registry.bind(name, ls.deref());
self.dmabuf.set(Some(ls)); self.dmabuf.set(Some(ls));
} }
} }
@ -353,7 +354,7 @@ fn finish_display_connect(dpy: Rc<PortalDisplayPrelude>) {
version: Version(version.min(12)), version: Version(version.min(12)),
}); });
dpy.con.add_object(jc.clone()); dpy.con.add_object(jc.clone());
dpy.registry.request_bind(name, jc.version.0, jc.deref()); dpy.registry.bind(name, jc.deref());
jc_opt = Some(jc); jc_opt = Some(jc);
} else if interface == WpFractionalScaleManagerV1.name() { } else if interface == WpFractionalScaleManagerV1.name() {
let ls = Rc::new(UsrWpFractionalScaleManager { let ls = Rc::new(UsrWpFractionalScaleManager {
@ -362,7 +363,7 @@ fn finish_display_connect(dpy: Rc<PortalDisplayPrelude>) {
version: Version(version.min(1)), version: Version(version.min(1)),
}); });
dpy.con.add_object(ls.clone()); dpy.con.add_object(ls.clone());
dpy.registry.request_bind(name, ls.version.0, ls.deref()); dpy.registry.bind(name, ls.deref());
fsm_opt = Some(ls); fsm_opt = Some(ls);
} else if interface == ZwlrLayerShellV1.name() { } else if interface == ZwlrLayerShellV1.name() {
let ls = Rc::new(UsrWlrLayerShell { let ls = Rc::new(UsrWlrLayerShell {
@ -371,7 +372,7 @@ fn finish_display_connect(dpy: Rc<PortalDisplayPrelude>) {
version: Version(version.min(5)), version: Version(version.min(5)),
}); });
dpy.con.add_object(ls.clone()); dpy.con.add_object(ls.clone());
dpy.registry.request_bind(name, ls.version.0, ls.deref()); dpy.registry.bind(name, ls.deref());
ls_opt = Some(ls); ls_opt = Some(ls);
} else if interface == WpViewporter.name() { } else if interface == WpViewporter.name() {
let ls = Rc::new(UsrWpViewporter { let ls = Rc::new(UsrWpViewporter {
@ -380,7 +381,7 @@ fn finish_display_connect(dpy: Rc<PortalDisplayPrelude>) {
version: Version(version.min(1)), version: Version(version.min(1)),
}); });
dpy.con.add_object(ls.clone()); dpy.con.add_object(ls.clone());
dpy.registry.request_bind(name, ls.version.0, ls.deref()); dpy.registry.bind(name, ls.deref());
vp_opt = Some(ls); vp_opt = Some(ls);
} else if interface == WlCompositor.name() { } else if interface == WlCompositor.name() {
let ls = Rc::new(UsrWlCompositor { let ls = Rc::new(UsrWlCompositor {
@ -389,7 +390,7 @@ fn finish_display_connect(dpy: Rc<PortalDisplayPrelude>) {
version: Version(version.min(6)), version: Version(version.min(6)),
}); });
dpy.con.add_object(ls.clone()); dpy.con.add_object(ls.clone());
dpy.registry.request_bind(name, ls.version.0, ls.deref()); dpy.registry.bind(name, ls.deref());
comp_opt = Some(ls); comp_opt = Some(ls);
} else if interface == ZwpLinuxDmabufV1.name() { } else if interface == ZwpLinuxDmabufV1.name() {
let ls = Rc::new(UsrLinuxDmabuf { let ls = Rc::new(UsrLinuxDmabuf {
@ -399,7 +400,7 @@ fn finish_display_connect(dpy: Rc<PortalDisplayPrelude>) {
version: Version(version.min(5)), version: Version(version.min(5)),
}); });
dpy.con.add_object(ls.clone()); dpy.con.add_object(ls.clone());
dpy.registry.request_bind(name, ls.version.0, ls.deref()); dpy.registry.bind(name, ls.deref());
dmabuf_opt = Some(ls); dmabuf_opt = Some(ls);
} else if interface == WlOutput.name() { } else if interface == WlOutput.name() {
outputs.push((name, version)); outputs.push((name, version));
@ -465,7 +466,7 @@ fn finish_display_connect(dpy: Rc<PortalDisplayPrelude>) {
log::info!("Display {} initialized", dpy.id); log::info!("Display {} initialized", dpy.id);
} }
fn add_seat(dpy: &Rc<PortalDisplay>, name: u32, version: u32) { fn add_seat(dpy: &Rc<PortalDisplay>, name: GlobalName, version: u32) {
let wl = Rc::new(UsrWlSeat { let wl = Rc::new(UsrWlSeat {
id: dpy.con.id(), id: dpy.con.id(),
con: dpy.con.clone(), con: dpy.con.clone(),
@ -473,7 +474,7 @@ fn add_seat(dpy: &Rc<PortalDisplay>, name: u32, version: u32) {
version: Version(version.min(9)), version: Version(version.min(9)),
}); });
dpy.con.add_object(wl.clone()); dpy.con.add_object(wl.clone());
dpy.registry.request_bind(name, wl.version.0, wl.deref()); dpy.registry.bind(name, wl.deref());
let jay_pointer = dpy.jc.get_pointer(&wl); let jay_pointer = dpy.jc.get_pointer(&wl);
let js = Rc::new(PortalSeat { let js = Rc::new(PortalSeat {
global_id: name, global_id: name,
@ -489,7 +490,7 @@ fn add_seat(dpy: &Rc<PortalDisplay>, name: u32, version: u32) {
dpy.seats.set(name, js); dpy.seats.set(name, js);
} }
fn add_output(dpy: &Rc<PortalDisplay>, name: u32, version: u32) { fn add_output(dpy: &Rc<PortalDisplay>, name: GlobalName, version: u32) {
let wl = Rc::new(UsrWlOutput { let wl = Rc::new(UsrWlOutput {
id: dpy.con.id(), id: dpy.con.id(),
con: dpy.con.clone(), con: dpy.con.clone(),
@ -498,7 +499,7 @@ fn add_output(dpy: &Rc<PortalDisplay>, name: u32, version: u32) {
name: Default::default(), name: Default::default(),
}); });
dpy.con.add_object(wl.clone()); dpy.con.add_object(wl.clone());
dpy.registry.request_bind(name, wl.version.0, wl.deref()); dpy.registry.bind(name, wl.deref());
let jo = dpy.jc.get_output(&wl); let jo = dpy.jc.get_output(&wl);
let po = Rc::new(PortalOutput { let po = Rc::new(PortalOutput {
global_id: name, global_id: name,

View file

@ -1,5 +1,6 @@
use { use {
crate::{ crate::{
globals::GlobalName,
ifs::wl_seat::{BTN_LEFT, wl_pointer::PRESSED}, ifs::wl_seat::{BTN_LEFT, wl_pointer::PRESSED},
portal::{ portal::{
ptl_display::{PortalDisplay, PortalOutput, PortalSeat}, ptl_display::{PortalDisplay, PortalOutput, PortalSeat},
@ -21,7 +22,7 @@ const V_MARGIN: f32 = 20.0;
pub struct SelectionGui { pub struct SelectionGui {
remote_desktop_session: Rc<PortalSession>, remote_desktop_session: Rc<PortalSession>,
dpy: Rc<PortalDisplay>, dpy: Rc<PortalDisplay>,
surfaces: CopyHashMap<u32, Rc<SelectionGuiSurface>>, surfaces: CopyHashMap<GlobalName, Rc<SelectionGuiSurface>>,
} }
pub struct SelectionGuiSurface { pub struct SelectionGuiSurface {

View file

@ -1,5 +1,6 @@
use { use {
crate::{ crate::{
globals::GlobalName,
ifs::wl_seat::{BTN_LEFT, wl_pointer::PRESSED}, ifs::wl_seat::{BTN_LEFT, wl_pointer::PRESSED},
portal::{ portal::{
ptl_display::{PortalDisplay, PortalOutput, PortalSeat}, ptl_display::{PortalDisplay, PortalOutput, PortalSeat},
@ -29,7 +30,7 @@ const V_MARGIN: f32 = 20.0;
pub struct SelectionGui { pub struct SelectionGui {
screencast_session: Rc<PortalSession>, screencast_session: Rc<PortalSession>,
dpy: Rc<PortalDisplay>, dpy: Rc<PortalDisplay>,
surfaces: CopyHashMap<u32, Rc<SelectionGuiSurface>>, surfaces: CopyHashMap<GlobalName, Rc<SelectionGuiSurface>>,
} }
pub struct SelectionGuiSurface { pub struct SelectionGuiSurface {
@ -254,7 +255,7 @@ impl UsrJaySelectToplevelOwner for SelectingWindowScreencast {
} }
impl UsrJaySelectWorkspaceOwner for SelectingWorkspaceScreencast { impl UsrJaySelectWorkspaceOwner for SelectingWorkspaceScreencast {
fn done(&self, output: u32, ws: Option<Rc<UsrJayWorkspace>>) { fn done(&self, output: GlobalName, ws: Option<Rc<UsrJayWorkspace>>) {
let Some(ws) = ws else { let Some(ws) = ws else {
log::info!("User has aborted the selection"); log::info!("User has aborted the selection");
self.core.session.kill(); self.core.session.kill();

View file

@ -10,6 +10,7 @@ use {
AcquireSync, AlphaMode, GfxContext, GfxFramebuffer, GfxTexture, ReleaseSync, AcquireSync, AlphaMode, GfxContext, GfxFramebuffer, GfxTexture, ReleaseSync,
needs_render_usage, needs_render_usage,
}, },
globals::GlobalName,
ifs::zwlr_layer_shell_v1::OVERLAY, ifs::zwlr_layer_shell_v1::OVERLAY,
portal::{ portal::{
ptl_display::{PortalDisplay, PortalOutput, PortalSeat}, ptl_display::{PortalDisplay, PortalOutput, PortalSeat},
@ -29,6 +30,7 @@ use {
wl_usr::usr_ifs::{ wl_usr::usr_ifs::{
usr_linux_buffer_params::{UsrLinuxBufferParams, UsrLinuxBufferParamsOwner}, usr_linux_buffer_params::{UsrLinuxBufferParams, UsrLinuxBufferParamsOwner},
usr_wl_buffer::{UsrWlBuffer, UsrWlBufferOwner}, usr_wl_buffer::{UsrWlBuffer, UsrWlBufferOwner},
usr_wl_callback::UsrWlCallbackOwner,
usr_wl_surface::UsrWlSurface, usr_wl_surface::UsrWlSurface,
usr_wlr_layer_surface::{UsrWlrLayerSurface, UsrWlrLayerSurfaceOwner}, usr_wlr_layer_surface::{UsrWlrLayerSurface, UsrWlrLayerSurfaceOwner},
usr_wp_fractional_scale::{UsrWpFractionalScale, UsrWpFractionalScaleOwner}, usr_wp_fractional_scale::{UsrWpFractionalScale, UsrWpFractionalScaleOwner},
@ -116,7 +118,7 @@ pub struct Button {
pub data: GuiElementData, pub data: GuiElementData,
pub tex_off_x: Cell<f32>, pub tex_off_x: Cell<f32>,
pub tex_off_y: Cell<f32>, pub tex_off_y: Cell<f32>,
pub hover: RefCell<AHashSet<u32>>, pub hover: RefCell<AHashSet<GlobalName>>,
pub padding: Cell<f32>, pub padding: Cell<f32>,
pub border: Cell<f32>, pub border: Cell<f32>,
pub border_color: Cell<Color>, pub border_color: Cell<Color>,
@ -504,7 +506,7 @@ pub struct WindowData {
pub width: Cell<i32>, pub width: Cell<i32>,
pub height: Cell<i32>, pub height: Cell<i32>,
pub owner: CloneCell<Option<Rc<dyn WindowDataOwner>>>, pub owner: CloneCell<Option<Rc<dyn WindowDataOwner>>>,
pub seats: CopyHashMap<u32, Rc<GuiWindowSeatState>>, pub seats: CopyHashMap<GlobalName, Rc<GuiWindowSeatState>>,
} }
#[derive(Default)] #[derive(Default)]
@ -666,15 +668,7 @@ impl WindowData {
self.frame_missed.set(false); self.frame_missed.set(false);
self.surface.frame({ self.surface.frame().owner.set(Some(self.clone()));
let slf = self.clone();
move || {
slf.have_frame.set(true);
if slf.frame_missed.get() {
slf.schedule_render();
}
}
});
self.have_frame.set(false); self.have_frame.set(false);
buf.free.set(false); buf.free.set(false);
@ -901,6 +895,15 @@ impl UsrWpFractionalScaleOwner for WindowData {
} }
} }
impl UsrWlCallbackOwner for WindowData {
fn done(self: Rc<Self>) {
self.have_frame.set(true);
if self.frame_missed.get() {
self.schedule_render();
}
}
}
impl UsrWlrLayerSurfaceOwner for OverlayWindow { impl UsrWlrLayerSurfaceOwner for OverlayWindow {
fn configure(&self, _ev: &Configure) { fn configure(&self, _ev: &Configure) {
self.data.schedule_render(); self.data.schedule_render();

View file

@ -40,7 +40,7 @@ use {
rc::Rc, rc::Rc,
}, },
thiserror::Error, thiserror::Error,
uapi::c, uapi::{OwnedFd, c},
}; };
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -119,6 +119,24 @@ impl UsrCon {
if let Err(e) = ring.connect(&socket, &addr).await { if let Err(e) = ring.connect(&socket, &addr).await {
return Err(UsrConError::Connect(e)); return Err(UsrConError::Connect(e));
} }
Ok(Self::from_socket(
ring,
wheel,
eng,
dma_buf_ids,
&socket,
server_id,
))
}
pub fn from_socket(
ring: &Rc<IoUring>,
wheel: &Rc<Wheel>,
eng: &Rc<AsyncEngine>,
dma_buf_ids: &Rc<DmaBufIds>,
socket: &Rc<OwnedFd>,
server_id: u32,
) -> Rc<Self> {
let mut obj_ids = Bitfield::default(); let mut obj_ids = Bitfield::default();
obj_ids.take(0); obj_ids.take(0);
obj_ids.take(1); obj_ids.take(1);
@ -150,7 +168,7 @@ impl UsrCon {
"wl_usr incoming", "wl_usr incoming",
Incoming { Incoming {
con: slf.clone(), con: slf.clone(),
buf: BufFdIn::new(&socket, &slf.ring), buf: BufFdIn::new(socket, &slf.ring),
data: vec![], data: vec![],
} }
.run(), .run(),
@ -161,13 +179,13 @@ impl UsrCon {
"wl_usr outgoing", "wl_usr outgoing",
Outgoing { Outgoing {
con: slf.clone(), con: slf.clone(),
buf: BufFdOut::new(&socket, &slf.ring), buf: BufFdOut::new(socket, &slf.ring),
buffers: Default::default(), buffers: Default::default(),
} }
.run(), .run(),
), ),
)); ));
Ok(slf) slf
} }
pub fn kill(&self) { pub fn kill(&self) {
@ -224,7 +242,8 @@ impl UsrCon {
where where
F: FnOnce() + 'static, F: FnOnce() + 'static,
{ {
let callback = Rc::new(UsrWlCallback::new(self, handler)); let callback = Rc::new(UsrWlCallback::new(self));
callback.owner.set(Some(Rc::new(Cell::new(Some(handler)))));
self.request(wl_display::Sync { self.request(wl_display::Sync {
self_id: WL_DISPLAY_ID, self_id: WL_DISPLAY_ID,
callback: callback.id, callback: callback.id,

View file

@ -1,5 +1,6 @@
use { use {
crate::{ crate::{
globals::GlobalName,
object::Version, object::Version,
utils::clonecell::CloneCell, utils::clonecell::CloneCell,
wire::{JaySelectWorkspaceId, jay_select_workspace::*}, wire::{JaySelectWorkspaceId, jay_select_workspace::*},
@ -9,7 +10,7 @@ use {
usr_object::UsrObject, usr_object::UsrObject,
}, },
}, },
std::{convert::Infallible, rc::Rc}, std::{cell::Cell, convert::Infallible, rc::Rc},
}; };
pub struct UsrJaySelectWorkspace { pub struct UsrJaySelectWorkspace {
@ -20,7 +21,7 @@ pub struct UsrJaySelectWorkspace {
} }
pub trait UsrJaySelectWorkspaceOwner { pub trait UsrJaySelectWorkspaceOwner {
fn done(&self, output: u32, ws: Option<Rc<UsrJayWorkspace>>); fn done(&self, output: GlobalName, ws: Option<Rc<UsrJayWorkspace>>);
} }
impl JaySelectWorkspaceEventHandler for UsrJaySelectWorkspace { impl JaySelectWorkspaceEventHandler for UsrJaySelectWorkspace {
@ -28,7 +29,7 @@ impl JaySelectWorkspaceEventHandler for UsrJaySelectWorkspace {
fn cancelled(&self, _ev: Cancelled, _slf: &Rc<Self>) -> Result<(), Self::Error> { fn cancelled(&self, _ev: Cancelled, _slf: &Rc<Self>) -> Result<(), Self::Error> {
if let Some(owner) = self.owner.get() { if let Some(owner) = self.owner.get() {
owner.done(0, None); owner.done(GlobalName::from_raw(0), None);
} }
self.con.remove_obj(self); self.con.remove_obj(self);
Ok(()) Ok(())
@ -41,7 +42,7 @@ impl JaySelectWorkspaceEventHandler for UsrJaySelectWorkspace {
owner: Default::default(), owner: Default::default(),
version: self.version, version: self.version,
linear_id: Default::default(), linear_id: Default::default(),
output: Default::default(), output: Cell::new(GlobalName::from_raw(0)),
name: Default::default(), name: Default::default(),
}); });
self.con.add_object(tl.clone()); self.con.add_object(tl.clone());

View file

@ -1,5 +1,6 @@
use { use {
crate::{ crate::{
globals::GlobalName,
object::Version, object::Version,
utils::clonecell::CloneCell, utils::clonecell::CloneCell,
wire::{JayWorkspaceId, jay_workspace::*}, wire::{JayWorkspaceId, jay_workspace::*},
@ -18,7 +19,7 @@ pub struct UsrJayWorkspace {
pub owner: CloneCell<Option<Rc<dyn UsrJayWorkspaceOwner>>>, pub owner: CloneCell<Option<Rc<dyn UsrJayWorkspaceOwner>>>,
pub version: Version, pub version: Version,
pub linear_id: Cell<u32>, pub linear_id: Cell<u32>,
pub output: Cell<u32>, pub output: Cell<GlobalName>,
pub name: RefCell<Option<String>>, pub name: RefCell<Option<String>>,
} }
@ -68,7 +69,7 @@ impl JayWorkspaceEventHandler for UsrJayWorkspace {
} }
fn output(&self, ev: Output, _slf: &Rc<Self>) -> Result<(), Self::Error> { fn output(&self, ev: Output, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.output.set(ev.global_name); self.output.set(GlobalName::from_raw(ev.global_name));
if let Some(owner) = self.owner.get() { if let Some(owner) = self.owner.get() {
owner.output(&ev); owner.output(&ev);
} }

View file

@ -1,11 +1,12 @@
use { use {
crate::{ crate::{
globals::GlobalName,
object::Version, object::Version,
utils::clonecell::CloneCell, utils::clonecell::CloneCell,
wire::{JayWorkspaceWatcherId, jay_workspace_watcher::*}, wire::{JayWorkspaceWatcherId, jay_workspace_watcher::*},
wl_usr::{UsrCon, usr_ifs::usr_jay_workspace::UsrJayWorkspace, usr_object::UsrObject}, wl_usr::{UsrCon, usr_ifs::usr_jay_workspace::UsrJayWorkspace, usr_object::UsrObject},
}, },
std::{convert::Infallible, ops::Deref, rc::Rc}, std::{cell::Cell, convert::Infallible, ops::Deref, rc::Rc},
}; };
pub struct UsrJayWorkspaceWatcher { pub struct UsrJayWorkspaceWatcher {
@ -32,7 +33,7 @@ impl JayWorkspaceWatcherEventHandler for UsrJayWorkspaceWatcher {
owner: Default::default(), owner: Default::default(),
version: self.version, version: self.version,
linear_id: Default::default(), linear_id: Default::default(),
output: Default::default(), output: Cell::new(GlobalName::from_raw(0)),
name: Default::default(), name: Default::default(),
}); });
self.con.add_object(jw.clone()); self.con.add_object(jw.clone());

View file

@ -10,19 +10,31 @@ use {
pub struct UsrWlCallback { pub struct UsrWlCallback {
pub id: WlCallbackId, pub id: WlCallbackId,
pub con: Rc<UsrCon>, pub con: Rc<UsrCon>,
pub handler: Cell<Option<Box<dyn FnOnce()>>>, pub owner: Cell<Option<Rc<dyn UsrWlCallbackOwner>>>,
pub version: Version, pub version: Version,
} }
pub trait UsrWlCallbackOwner {
fn done(self: Rc<Self>);
}
impl<T> UsrWlCallbackOwner for Cell<Option<T>>
where
T: FnOnce() + 'static,
{
fn done(self: Rc<Self>) {
if let Some(slf) = self.take() {
slf();
}
}
}
impl UsrWlCallback { impl UsrWlCallback {
pub fn new<F>(con: &Rc<UsrCon>, handler: F) -> Self pub fn new(con: &Rc<UsrCon>) -> Self {
where
F: FnOnce() + 'static,
{
Self { Self {
id: con.id(), id: con.id(),
con: con.clone(), con: con.clone(),
handler: Cell::new(Some(Box::new(handler))), owner: Default::default(),
version: Version(1), version: Version(1),
} }
} }
@ -32,8 +44,8 @@ impl WlCallbackEventHandler for UsrWlCallback {
type Error = Infallible; type Error = Infallible;
fn done(&self, _ev: Done, _slf: &Rc<Self>) -> Result<(), Self::Error> { fn done(&self, _ev: Done, _slf: &Rc<Self>) -> Result<(), Self::Error> {
if let Some(handler) = self.handler.take() { if let Some(handler) = self.owner.take() {
handler(); handler.done();
} }
self.con.remove_obj(self); self.con.remove_obj(self);
Ok(()) Ok(())
@ -51,6 +63,6 @@ impl UsrObject for UsrWlCallback {
} }
fn break_loops(&self) { fn break_loops(&self) {
self.handler.take(); self.owner.take();
} }
} }

View file

@ -3,7 +3,7 @@ use {
ifs::wl_seat::wl_pointer::PendingScroll, ifs::wl_seat::wl_pointer::PendingScroll,
object::Version, object::Version,
utils::clonecell::CloneCell, utils::clonecell::CloneCell,
wire::{WlPointerId, wl_pointer::*}, wire::{WlPointerId, WlSurfaceId, wl_pointer::*},
wl_usr::{UsrCon, usr_ifs::usr_wl_surface::UsrWlSurface, usr_object::UsrObject}, wl_usr::{UsrCon, usr_ifs::usr_wl_surface::UsrWlSurface, usr_object::UsrObject},
}, },
std::{cell::Cell, convert::Infallible, rc::Rc}, std::{cell::Cell, convert::Infallible, rc::Rc},
@ -19,34 +19,34 @@ pub struct UsrWlPointer {
} }
pub trait UsrWlPointerOwner { pub trait UsrWlPointerOwner {
fn enter(&self, ev: &Enter) { fn enter(self: Rc<Self>, ev: &Enter) {
let _ = ev; let _ = ev;
} }
fn leave(&self, ev: &Leave) { fn leave(self: Rc<Self>, ev: &Leave) {
let _ = ev; let _ = ev;
} }
fn motion(&self, ev: &Motion) { fn motion(self: Rc<Self>, ev: &Motion) {
let _ = ev; let _ = ev;
} }
fn button(&self, ev: &Button) { fn button(self: Rc<Self>, ev: &Button) {
let _ = ev; let _ = ev;
} }
fn scroll(&self, ps: &PendingScroll) { fn scroll(self: Rc<Self>, ps: &PendingScroll) {
let _ = ps; let _ = ps;
} }
} }
impl UsrWlPointer { impl UsrWlPointer {
#[expect(dead_code)] #[expect(dead_code)]
pub fn set_cursor(&self, serial: u32, cursor: &UsrWlSurface, hot_x: i32, hot_y: i32) { pub fn set_cursor(&self, serial: u32, cursor: Option<&UsrWlSurface>, hot_x: i32, hot_y: i32) {
self.con.request(SetCursor { self.con.request(SetCursor {
self_id: self.id, self_id: self.id,
serial, serial,
surface: cursor.id, surface: cursor.map(|c| c.id).unwrap_or(WlSurfaceId::NONE),
hotspot_x: hot_x, hotspot_x: hot_x,
hotspot_y: hot_y, hotspot_y: hot_y,
}); });

View file

@ -1,5 +1,6 @@
use { use {
crate::{ crate::{
globals::GlobalName,
object::Version, object::Version,
utils::clonecell::CloneCell, utils::clonecell::CloneCell,
wire::{WlRegistryId, wl_registry::*}, wire::{WlRegistryId, wl_registry::*},
@ -16,24 +17,24 @@ pub struct UsrWlRegistry {
} }
pub trait UsrWlRegistryOwner { pub trait UsrWlRegistryOwner {
fn global(self: Rc<Self>, name: u32, interface: &str, version: u32) { fn global(self: Rc<Self>, name: GlobalName, interface: &str, version: u32) {
let _ = name; let _ = name;
let _ = interface; let _ = interface;
let _ = version; let _ = version;
} }
fn global_remove(&self, name: u32) { fn global_remove(&self, name: GlobalName) {
let _ = name; let _ = name;
} }
} }
impl UsrWlRegistry { impl UsrWlRegistry {
pub fn request_bind(&self, name: u32, version: u32, obj: &dyn UsrObject) { pub fn bind(&self, name: GlobalName, obj: &dyn UsrObject) {
self.con.request(Bind { self.con.request(Bind {
self_id: self.id, self_id: self.id,
name, name: name.raw(),
interface: obj.interface().name(), interface: obj.interface().name(),
version, version: obj.version().0,
id: obj.id(), id: obj.id(),
}); });
} }
@ -44,14 +45,14 @@ impl WlRegistryEventHandler for UsrWlRegistry {
fn global(&self, ev: Global<'_>, _slf: &Rc<Self>) -> Result<(), Self::Error> { fn global(&self, ev: Global<'_>, _slf: &Rc<Self>) -> Result<(), Self::Error> {
if let Some(owner) = self.owner.get() { if let Some(owner) = self.owner.get() {
owner.global(ev.name, ev.interface, ev.version); owner.global(GlobalName::from_raw(ev.name), ev.interface, ev.version);
} }
Ok(()) Ok(())
} }
fn global_remove(&self, ev: GlobalRemove, _slf: &Rc<Self>) -> Result<(), Self::Error> { fn global_remove(&self, ev: GlobalRemove, _slf: &Rc<Self>) -> Result<(), Self::Error> {
if let Some(owner) = self.owner.get() { if let Some(owner) = self.owner.get() {
owner.global_remove(ev.name); owner.global_remove(GlobalName::from_raw(ev.name));
} }
Ok(()) Ok(())
} }

View file

@ -37,16 +37,14 @@ impl UsrWlSurface {
}); });
} }
pub fn frame<F>(&self, f: F) pub fn frame(&self) -> Rc<UsrWlCallback> {
where let cb = Rc::new(UsrWlCallback::new(&self.con));
F: FnOnce() + 'static,
{
let cb = Rc::new(UsrWlCallback::new(&self.con, f));
self.con.request(Frame { self.con.request(Frame {
self_id: self.id, self_id: self.id,
callback: cb.id, callback: cb.id,
}); });
self.con.add_object(cb); self.con.add_object(cb.clone());
cb
} }
pub fn commit(&self) { pub fn commit(&self) {