Add support for experimental xx_foreign_toplevel_geometry_tracker_v1 as
well as tracking_manager_v1.
This commit is contained in:
parent
4e9b6def83
commit
59c2b53350
10 changed files with 284 additions and 8 deletions
|
|
@ -233,5 +233,7 @@ bitflags! {
|
|||
pub const CC_GAMMA_CONTROL_MANAGER = 1 << 14,
|
||||
/// Grants access to the `zwlr_virtual_pointer_manager_v1` global.
|
||||
pub const CC_VIRTUAL_POINTER = 1 << 15,
|
||||
/// Grants access to the `ext_foreign_toplevel_geometry_tracking_manager_v1` global.
|
||||
pub const CC_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING = 1 << 16,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ bitflags! {
|
|||
CAP_HEAD_MANAGER = 1 << 13,
|
||||
CAP_GAMMA_CONTROL_MANAGER = 1 << 14,
|
||||
CAP_VIRTUAL_POINTER_MANAGER = 1 << 15,
|
||||
CAP_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING = 1 << 16,
|
||||
}
|
||||
|
||||
impl StaticText for ClientCapsEnum {
|
||||
|
|
@ -89,6 +90,9 @@ impl StaticText for ClientCapsEnum {
|
|||
ClientCapsEnum::CAP_HEAD_MANAGER => "head-manager",
|
||||
ClientCapsEnum::CAP_GAMMA_CONTROL_MANAGER => "gamma-control-manager",
|
||||
ClientCapsEnum::CAP_VIRTUAL_POINTER_MANAGER => "virtual-pointer",
|
||||
ClientCapsEnum::CAP_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING => {
|
||||
"foreign-toplevel-geometry-tracking"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ use {
|
|||
xdg_toplevel_tag_manager_v1::XdgToplevelTagManagerV1Global,
|
||||
xdg_wm_base::XdgWmBaseGlobal,
|
||||
xdg_wm_dialog_v1::XdgWmDialogV1Global,
|
||||
xx_foreign_toplevel_geometry_tracking_manager_v1::XxForeignToplevelGeometryTrackingManagerV1Global,
|
||||
zwlr_foreign_toplevel_manager_v1::ZwlrForeignToplevelManagerV1Global,
|
||||
zwlr_gamma_control_manager_v1::ZwlrGammaControlManagerV1Global,
|
||||
zwlr_layer_shell_v1::ZwlrLayerShellV1Global,
|
||||
|
|
@ -252,6 +253,7 @@ singletons! {
|
|||
WpLinuxDrmSyncobjManagerV1,
|
||||
WpPresentation,
|
||||
ZwlrVirtualPointerManagerV1,
|
||||
XxForeignToplevelGeometryTrackingManagerV1,
|
||||
}
|
||||
|
||||
pub struct Globals {
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ pub mod xdg_toplevel_drag_v1;
|
|||
pub mod xdg_toplevel_tag_manager_v1;
|
||||
pub mod xdg_wm_base;
|
||||
pub mod xdg_wm_dialog_v1;
|
||||
pub mod xx_foreign_toplevel_geometry_tracker_v1;
|
||||
pub mod xx_foreign_toplevel_geometry_tracking_manager_v1;
|
||||
pub mod zwlr_foreign_toplevel_handle_v1;
|
||||
pub mod zwlr_foreign_toplevel_manager_v1;
|
||||
pub mod zwlr_gamma_control_manager_v1;
|
||||
|
|
|
|||
99
src/ifs/xx_foreign_toplevel_geometry_tracker_v1.rs
Normal file
99
src/ifs/xx_foreign_toplevel_geometry_tracker_v1.rs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
use {
|
||||
crate::{
|
||||
client::{Client, ClientError},
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
rect::Rect,
|
||||
state::State,
|
||||
tree::ToplevelOpt,
|
||||
wire::{
|
||||
XxForeignToplevelGeometryTrackerV1Id,
|
||||
xx_foreign_toplevel_geometry_tracker_v1::*,
|
||||
},
|
||||
},
|
||||
std::rc::Rc,
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
pub struct XxForeignToplevelGeometryTrackerV1 {
|
||||
pub id: XxForeignToplevelGeometryTrackerV1Id,
|
||||
pub client: Rc<Client>,
|
||||
pub tracker: Tracker<Self>,
|
||||
pub toplevel: ToplevelOpt,
|
||||
pub version: Version,
|
||||
}
|
||||
|
||||
impl XxForeignToplevelGeometryTrackerV1 {
|
||||
fn detach(&self) {
|
||||
if let Some(tl) = self.toplevel.get() {
|
||||
tl.tl_data()
|
||||
.geometry_trackers
|
||||
.remove(&(self.client.id, self.id));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send_finished(&self) {
|
||||
self.client.event(Finished { self_id: self.id });
|
||||
}
|
||||
|
||||
pub fn send_geometry_update(&self, rect: &Rect, state: &State) {
|
||||
if rect.is_empty() {
|
||||
self.client.event(Done { self_id: self.id });
|
||||
return;
|
||||
}
|
||||
for output in state.globals.outputs.lock().values() {
|
||||
let output_pos = output.pos.get();
|
||||
if !rect.intersects(&output_pos) {
|
||||
continue;
|
||||
}
|
||||
let scale = output.persistent.scale.get().to_f64();
|
||||
let rel_x = rect.x1() - output_pos.x1();
|
||||
let rel_y = rect.y1() - output_pos.y1();
|
||||
let hw_x = (rel_x as f64 * scale).round() as i32;
|
||||
let hw_y = (rel_y as f64 * scale).round() as i32;
|
||||
let hw_w = (rect.width() as f64 * scale).round() as u32;
|
||||
let hw_h = (rect.height() as f64 * scale).round() as u32;
|
||||
self.client.event(Geometry {
|
||||
self_id: self.id,
|
||||
output: output.name.raw(),
|
||||
x: hw_x,
|
||||
y: hw_y,
|
||||
width: hw_w,
|
||||
height: hw_h,
|
||||
});
|
||||
}
|
||||
self.client.event(Done { self_id: self.id });
|
||||
}
|
||||
}
|
||||
|
||||
impl XxForeignToplevelGeometryTrackerV1RequestHandler
|
||||
for XxForeignToplevelGeometryTrackerV1
|
||||
{
|
||||
type Error = XxForeignToplevelGeometryTrackerV1Error;
|
||||
|
||||
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
self.detach();
|
||||
self.client.remove_obj(self)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
object_base! {
|
||||
self = XxForeignToplevelGeometryTrackerV1;
|
||||
version = self.version;
|
||||
}
|
||||
|
||||
impl Object for XxForeignToplevelGeometryTrackerV1 {
|
||||
fn break_loops(&self) {
|
||||
self.detach();
|
||||
}
|
||||
}
|
||||
|
||||
simple_add_obj!(XxForeignToplevelGeometryTrackerV1);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum XxForeignToplevelGeometryTrackerV1Error {
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(XxForeignToplevelGeometryTrackerV1Error, ClientError);
|
||||
125
src/ifs/xx_foreign_toplevel_geometry_tracking_manager_v1.rs
Normal file
125
src/ifs/xx_foreign_toplevel_geometry_tracking_manager_v1.rs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
use {
|
||||
crate::{
|
||||
client::{CAP_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING, Client, ClientCaps, ClientError},
|
||||
globals::{Global, GlobalName},
|
||||
ifs::{
|
||||
xx_foreign_toplevel_geometry_tracker_v1::XxForeignToplevelGeometryTrackerV1,
|
||||
ext_foreign_toplevel_handle_v1::ExtForeignToplevelHandleV1,
|
||||
},
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
wire::{
|
||||
XxForeignToplevelGeometryTrackingManagerV1Id,
|
||||
xx_foreign_toplevel_geometry_tracking_manager_v1::*,
|
||||
},
|
||||
},
|
||||
std::rc::Rc,
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
pub struct XxForeignToplevelGeometryTrackingManagerV1Global {
|
||||
pub name: GlobalName,
|
||||
}
|
||||
|
||||
impl XxForeignToplevelGeometryTrackingManagerV1Global {
|
||||
pub fn new(name: GlobalName) -> Self {
|
||||
Self { name }
|
||||
}
|
||||
|
||||
fn bind_(
|
||||
self: Rc<Self>,
|
||||
id: XxForeignToplevelGeometryTrackingManagerV1Id,
|
||||
client: &Rc<Client>,
|
||||
version: Version,
|
||||
) -> Result<(), XxForeignToplevelGeometryTrackingManagerV1Error> {
|
||||
let obj = Rc::new(XxForeignToplevelGeometryTrackingManagerV1 {
|
||||
id,
|
||||
client: client.clone(),
|
||||
tracker: Default::default(),
|
||||
version,
|
||||
});
|
||||
track!(client, obj);
|
||||
client.add_client_obj(&obj)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct XxForeignToplevelGeometryTrackingManagerV1 {
|
||||
pub id: XxForeignToplevelGeometryTrackingManagerV1Id,
|
||||
pub client: Rc<Client>,
|
||||
pub tracker: Tracker<Self>,
|
||||
pub version: Version,
|
||||
}
|
||||
|
||||
impl XxForeignToplevelGeometryTrackingManagerV1RequestHandler
|
||||
for XxForeignToplevelGeometryTrackingManagerV1
|
||||
{
|
||||
type Error = XxForeignToplevelGeometryTrackingManagerV1Error;
|
||||
|
||||
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
self.client.remove_obj(self)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_geometry_tracker(
|
||||
&self,
|
||||
req: GetGeometryTracker,
|
||||
_slf: &Rc<Self>,
|
||||
) -> Result<(), Self::Error> {
|
||||
let handle: Rc<ExtForeignToplevelHandleV1> = self.client.lookup(req.toplevel)?;
|
||||
let toplevel = handle.toplevel.clone();
|
||||
let tracker_obj = Rc::new(XxForeignToplevelGeometryTrackerV1 {
|
||||
id: req.tracker,
|
||||
client: self.client.clone(),
|
||||
tracker: Default::default(),
|
||||
toplevel: toplevel.clone(),
|
||||
version: self.version,
|
||||
});
|
||||
track!(self.client, tracker_obj);
|
||||
self.client.add_client_obj(&tracker_obj)?;
|
||||
if let Some(tl) = toplevel.get() {
|
||||
let data = tl.tl_data();
|
||||
data.geometry_trackers
|
||||
.set((self.client.id, req.tracker), tracker_obj.clone());
|
||||
let rect = tl.node_absolute_position();
|
||||
tracker_obj.send_geometry_update(&rect, &data.state);
|
||||
} else {
|
||||
tracker_obj.send_finished();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
global_base!(
|
||||
XxForeignToplevelGeometryTrackingManagerV1Global,
|
||||
XxForeignToplevelGeometryTrackingManagerV1,
|
||||
XxForeignToplevelGeometryTrackingManagerV1Error
|
||||
);
|
||||
|
||||
impl Global for XxForeignToplevelGeometryTrackingManagerV1Global {
|
||||
fn version(&self) -> u32 {
|
||||
1
|
||||
}
|
||||
|
||||
fn required_caps(&self) -> ClientCaps {
|
||||
CAP_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING
|
||||
}
|
||||
}
|
||||
|
||||
simple_add_global!(XxForeignToplevelGeometryTrackingManagerV1Global);
|
||||
|
||||
object_base! {
|
||||
self = XxForeignToplevelGeometryTrackingManagerV1;
|
||||
version = self.version;
|
||||
}
|
||||
|
||||
impl Object for XxForeignToplevelGeometryTrackingManagerV1 {}
|
||||
|
||||
simple_add_obj!(XxForeignToplevelGeometryTrackingManagerV1);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum XxForeignToplevelGeometryTrackingManagerV1Error {
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(XxForeignToplevelGeometryTrackingManagerV1Error, ClientError);
|
||||
|
|
@ -21,6 +21,7 @@ use {
|
|||
xdg_surface::xdg_toplevel::XdgToplevelToplevelData,
|
||||
},
|
||||
wp_content_type_v1::ContentType,
|
||||
xx_foreign_toplevel_geometry_tracker_v1::XxForeignToplevelGeometryTrackerV1,
|
||||
zwlr_foreign_toplevel_handle_v1::ZwlrForeignToplevelHandleV1,
|
||||
zwlr_foreign_toplevel_manager_v1::ZwlrForeignToplevelManagerV1,
|
||||
},
|
||||
|
|
@ -37,7 +38,7 @@ use {
|
|||
},
|
||||
wire::{
|
||||
ExtForeignToplevelHandleV1Id, ExtImageCopyCaptureSessionV1Id, JayScreencastId,
|
||||
JayToplevelId, ZwlrForeignToplevelHandleV1Id,
|
||||
JayToplevelId, XxForeignToplevelGeometryTrackerV1Id, ZwlrForeignToplevelHandleV1Id,
|
||||
},
|
||||
},
|
||||
jay_config::{window, window::WindowType},
|
||||
|
|
@ -195,7 +196,13 @@ impl<T: ToplevelNodeBase> ToplevelNode for T {
|
|||
data.float_width.set(rect.width());
|
||||
data.float_height.set(rect.height());
|
||||
}
|
||||
self.tl_change_extents_impl(rect)
|
||||
let _ = data;
|
||||
let slf = self.clone();
|
||||
self.tl_change_extents_impl(rect);
|
||||
let data = slf.tl_data();
|
||||
for tracker in data.geometry_trackers.lock().values() {
|
||||
tracker.send_geometry_update(rect, &data.state);
|
||||
}
|
||||
}
|
||||
|
||||
fn tl_set_visible(&self, visible: bool) {
|
||||
|
|
@ -401,6 +408,10 @@ pub struct ToplevelData {
|
|||
pub identifier: Cell<ToplevelIdentifier>,
|
||||
pub handles:
|
||||
CopyHashMap<(ClientId, ExtForeignToplevelHandleV1Id), Rc<ExtForeignToplevelHandleV1>>,
|
||||
pub geometry_trackers: CopyHashMap<
|
||||
(ClientId, XxForeignToplevelGeometryTrackerV1Id),
|
||||
Rc<XxForeignToplevelGeometryTrackerV1>,
|
||||
>,
|
||||
pub manager_handles:
|
||||
CopyHashMap<(ClientId, ZwlrForeignToplevelHandleV1Id), Rc<ZwlrForeignToplevelHandleV1>>,
|
||||
pub render_highlight: NumCell<u32>,
|
||||
|
|
@ -459,6 +470,7 @@ impl ToplevelData {
|
|||
app_id: Default::default(),
|
||||
identifier: Cell::new(id),
|
||||
handles: Default::default(),
|
||||
geometry_trackers: Default::default(),
|
||||
manager_handles: Default::default(),
|
||||
render_highlight: Default::default(),
|
||||
jay_toplevels: Default::default(),
|
||||
|
|
@ -563,6 +575,12 @@ impl ToplevelData {
|
|||
handle.send_closed();
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut trackers = self.geometry_trackers.lock();
|
||||
for tracker in trackers.drain_values() {
|
||||
tracker.send_finished();
|
||||
}
|
||||
}
|
||||
self.detach_node(node);
|
||||
self.property_changed(TL_CHANGED_DESTROYED);
|
||||
}
|
||||
|
|
@ -951,7 +969,6 @@ impl ToplevelData {
|
|||
};
|
||||
parent.node_is_workspace()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Drop for ToplevelData {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ use {
|
|||
},
|
||||
},
|
||||
jay_config::client::{
|
||||
CC_DATA_CONTROL, CC_DRM_LEASE, CC_FOREIGN_TOPLEVEL_LIST, CC_FOREIGN_TOPLEVEL_MANAGER,
|
||||
CC_DATA_CONTROL, CC_DRM_LEASE, CC_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING,
|
||||
CC_FOREIGN_TOPLEVEL_LIST, CC_FOREIGN_TOPLEVEL_MANAGER,
|
||||
CC_GAMMA_CONTROL_MANAGER, CC_HEAD_MANAGER, CC_IDLE_NOTIFIER, CC_INPUT_METHOD,
|
||||
CC_LAYER_SHELL, CC_SCREENCOPY, CC_SEAT_MANAGER, CC_SESSION_LOCK, CC_VIRTUAL_KEYBOARD,
|
||||
CC_VIRTUAL_POINTER, CC_WORKSPACE_MANAGER, ClientCapabilities,
|
||||
|
|
@ -49,6 +50,7 @@ impl Parser for CapabilitiesParser {
|
|||
"head-manager" => CC_HEAD_MANAGER,
|
||||
"gamma-control-manager" => CC_GAMMA_CONTROL_MANAGER,
|
||||
"virtual-pointer" => CC_VIRTUAL_POINTER,
|
||||
"foreign-toplevel-geometry-tracking" => CC_FOREIGN_TOPLEVEL_GEOMETRY_TRACKING,
|
||||
_ => {
|
||||
return Err(
|
||||
CapabilitiesParserError::UnknownCapability(string.to_owned()).spanned(span),
|
||||
|
|
|
|||
16
wire/xx_foreign_toplevel_geometry_tracker_v1.txt
Normal file
16
wire/xx_foreign_toplevel_geometry_tracker_v1.txt
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
request destroy (destructor) {
|
||||
}
|
||||
|
||||
event finished {
|
||||
}
|
||||
|
||||
event done {
|
||||
}
|
||||
|
||||
event geometry {
|
||||
output: u32,
|
||||
x: i32,
|
||||
y: i32,
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
request destroy (destructor) {
|
||||
}
|
||||
|
||||
request get_geometry_tracker {
|
||||
tracker: id(xx_foreign_toplevel_geometry_tracker_v1) (new),
|
||||
toplevel: id(ext_foreign_toplevel_handle_v1),
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue