1
0
Fork 0
forked from wry/wry
wry/src/ifs/zwlr_foreign_toplevel_handle_v1.rs

210 lines
5.7 KiB
Rust

use {
crate::{
client::{Client, ClientError},
ifs::wl_output::WlOutput,
leaks::Tracker,
object::{Object, Version},
tree::{Direction, OutputNode, ToplevelOpt},
wire::{ZwlrForeignToplevelHandleV1Id, zwlr_foreign_toplevel_handle_v1::*},
},
arrayvec::ArrayVec,
std::rc::Rc,
thiserror::Error,
};
const STATE_ACTIVATED: u32 = 2;
const STATE_FULLSCREEN: u32 = 3;
const FULLSCREEN_SINCE: Version = Version(2);
pub struct ZwlrForeignToplevelHandleV1 {
pub id: ZwlrForeignToplevelHandleV1Id,
pub client: Rc<Client>,
pub tracker: Tracker<Self>,
pub toplevel: ToplevelOpt,
pub version: Version,
}
impl ZwlrForeignToplevelHandleV1 {
fn detach(&self) {
if let Some(tl) = self.toplevel.get() {
tl.tl_data()
.manager_handles
.remove(&(self.client.id, self.id));
}
}
}
impl ZwlrForeignToplevelHandleV1RequestHandler for ZwlrForeignToplevelHandleV1 {
type Error = ZwlrForeignToplevelHandleV1Error;
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.detach();
self.client.remove_obj(self)?;
Ok(())
}
fn set_maximized(&self, _req: SetMaximized, _slf: &Rc<Self>) -> Result<(), Self::Error> {
Ok(())
}
fn unset_maximized(&self, _req: UnsetMaximized, _slf: &Rc<Self>) -> Result<(), Self::Error> {
Ok(())
}
fn set_minimized(&self, _req: SetMinimized, _slf: &Rc<Self>) -> Result<(), Self::Error> {
Ok(())
}
fn unset_minimized(&self, _req: UnsetMinimized, _slf: &Rc<Self>) -> Result<(), Self::Error> {
Ok(())
}
fn activate(&self, req: Activate, _slf: &Rc<Self>) -> Result<(), Self::Error> {
if let Some(toplevel) = self.toplevel.get() {
if !toplevel.node_visible() {
toplevel.clone().node_make_visible();
if !toplevel.node_visible() {
return Ok(());
}
}
let seat = self.client.lookup(req.seat)?;
toplevel.node_do_focus(&seat.global, Direction::Unspecified);
}
Ok(())
}
fn close(&self, _req: Close, _slf: &Rc<Self>) -> Result<(), Self::Error> {
if let Some(toplevel) = self.toplevel.get() {
toplevel.tl_close();
}
Ok(())
}
fn set_rectangle(&self, _req: SetRectangle, _slf: &Rc<Self>) -> Result<(), Self::Error> {
Ok(())
}
fn set_fullscreen(&self, req: SetFullscreen, _slf: &Rc<Self>) -> Result<(), Self::Error> {
if let Some(toplevel) = self.toplevel.get() {
let ws = if req.output.is_some() {
self.client
.lookup(req.output)?
.global
.node()
.map(|node| node.ensure_workspace())
} else {
None
};
toplevel.tl_set_fullscreen(true, ws);
}
Ok(())
}
fn unset_fullscreen(&self, _req: UnsetFullscreen, _slf: &Rc<Self>) -> Result<(), Self::Error> {
if let Some(toplevel) = self.toplevel.get() {
toplevel.tl_set_fullscreen(false, None);
}
Ok(())
}
}
impl ZwlrForeignToplevelHandleV1 {
pub fn leave_output(&self, output: &Rc<OutputNode>) {
let bindings = output.global.bindings.borrow();
if let Some(bindings) = bindings.get(&self.client.id) {
for binding in bindings.values() {
self.send_output_leave(binding);
}
}
}
pub fn enter_output(&self, output: &Rc<OutputNode>) {
let bindings = output.global.bindings.borrow();
if let Some(bindings) = bindings.get(&self.client.id) {
for binding in bindings.values() {
self.send_output_enter(binding);
}
}
}
pub fn send_closed(&self) {
self.client.event(Closed { self_id: self.id });
}
pub fn send_done(&self) {
self.client.event(Done { self_id: self.id });
}
pub fn send_title(&self, title: &str) {
self.client.event(Title {
self_id: self.id,
title,
});
}
pub fn send_app_id(&self, app_id: &str) {
self.client.event(AppId {
self_id: self.id,
app_id,
});
}
pub fn send_state(&self, activated: bool, fullscreen: bool) {
let mut state: ArrayVec<u32, 2> = ArrayVec::new();
if activated {
state.push(STATE_ACTIVATED);
}
if self.version >= FULLSCREEN_SINCE {
if fullscreen {
state.push(STATE_FULLSCREEN);
}
}
self.client.event(State {
self_id: self.id,
state: &state,
});
}
#[expect(dead_code)]
pub fn send_parent(&self, parent: &Rc<ZwlrForeignToplevelHandleV1>) {
self.client.event(Parent {
self_id: self.id,
parent: parent.id,
});
}
pub fn send_output_enter(&self, output: &Rc<WlOutput>) {
self.client.event(OutputEnter {
self_id: self.id,
output: output.id,
});
}
pub fn send_output_leave(&self, output: &Rc<WlOutput>) {
self.client.event(OutputLeave {
self_id: self.id,
output: output.id,
});
}
}
object_base! {
self = ZwlrForeignToplevelHandleV1;
version = self.version;
}
impl Object for ZwlrForeignToplevelHandleV1 {
fn break_loops(&self) {
self.detach();
}
}
simple_add_obj!(ZwlrForeignToplevelHandleV1);
#[derive(Debug, Error)]
pub enum ZwlrForeignToplevelHandleV1Error {
#[error(transparent)]
ClientError(Box<ClientError>),
}
efrom!(ZwlrForeignToplevelHandleV1Error, ClientError);