refactor(wayland): update data in user data map for everything
This commit is contained in:
@@ -22,6 +22,15 @@ use std::sync::{Arc, Weak};
|
|||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
|
|
||||||
stardust_xr_server_codegen::codegen_item_panel_protocol!();
|
stardust_xr_server_codegen::codegen_item_panel_protocol!();
|
||||||
|
impl Default for Geometry {
|
||||||
|
fn default() -> Self {
|
||||||
|
Geometry {
|
||||||
|
origin: [0, 0].into(),
|
||||||
|
size: [0, 0].into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref ITEM_TYPE_INFO_PANEL: TypeInfo = TypeInfo {
|
pub static ref ITEM_TYPE_INFO_PANEL: TypeInfo = TypeInfo {
|
||||||
type_name: "panel",
|
type_name: "panel",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::{
|
use super::{
|
||||||
state::{ClientState, WaylandState},
|
state::{ClientState, WaylandState},
|
||||||
utils::WlSurfaceExt,
|
utils::{ChildInfoExt, WlSurfaceExt},
|
||||||
xdg_shell::{surface_panel_item, ChildInfoExt},
|
xdg_shell::surface_panel_item,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
nodes::items::panel::{ChildInfo, Geometry, SurfaceId},
|
nodes::items::panel::{ChildInfo, Geometry, SurfaceId},
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use super::{state::WaylandState, surface::CoreSurface};
|
use super::{state::WaylandState, surface::CoreSurface, utils::WlSurfaceExt};
|
||||||
use crate::{
|
use crate::{
|
||||||
core::task,
|
core::task,
|
||||||
nodes::{
|
nodes::{
|
||||||
@@ -76,8 +76,7 @@ pub struct CursorInfo {
|
|||||||
}
|
}
|
||||||
impl CursorInfo {
|
impl CursorInfo {
|
||||||
pub fn cursor_data(&self) -> Option<Geometry> {
|
pub fn cursor_data(&self) -> Option<Geometry> {
|
||||||
let cursor_size =
|
let cursor_size = self.surface.as_ref()?.upgrade().ok()?.get_size()?;
|
||||||
CoreSurface::from_wl_surface(&self.surface.as_ref()?.upgrade().ok()?)?.size()?;
|
|
||||||
Some(Geometry {
|
Some(Geometry {
|
||||||
origin: [self.hotspot_x, self.hotspot_y].into(),
|
origin: [self.hotspot_x, self.hotspot_y].into(),
|
||||||
size: cursor_size,
|
size: cursor_size,
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ use crate::{
|
|||||||
items::camera::TexWrapper,
|
items::camera::TexWrapper,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use mint::Vector2;
|
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use send_wrapper::SendWrapper;
|
use send_wrapper::SendWrapper;
|
||||||
@@ -35,7 +34,6 @@ pub static CORE_SURFACES: Registry<CoreSurface> = Registry::new();
|
|||||||
|
|
||||||
pub struct CoreSurfaceData {
|
pub struct CoreSurfaceData {
|
||||||
wl_tex: Option<SendWrapper<GlesTexture>>,
|
wl_tex: Option<SendWrapper<GlesTexture>>,
|
||||||
pub size: Vector2<u32>,
|
|
||||||
}
|
}
|
||||||
impl Drop for CoreSurfaceData {
|
impl Drop for CoreSurfaceData {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
@@ -156,16 +154,7 @@ impl CoreSurface {
|
|||||||
sk_mat.lock().0.queue_offset(*material_offset as i32);
|
sk_mat.lock().0.queue_offset(*material_offset as i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(surface_size) = wl_surface
|
|
||||||
.get_data_raw::<RendererSurfaceStateUserData, _, _>(|surface_states| {
|
|
||||||
surface_states.lock().unwrap().surface_size()
|
|
||||||
})
|
|
||||||
.flatten()
|
|
||||||
else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
let new_mapped_data = CoreSurfaceData {
|
let new_mapped_data = CoreSurfaceData {
|
||||||
size: Vector2::from([surface_size.w as u32, surface_size.h as u32]),
|
|
||||||
wl_tex: Some(SendWrapper::new(smithay_tex)),
|
wl_tex: Some(SendWrapper::new(smithay_tex)),
|
||||||
};
|
};
|
||||||
*mapped_data = Some(new_mapped_data);
|
*mapped_data = Some(new_mapped_data);
|
||||||
@@ -206,10 +195,6 @@ impl CoreSurface {
|
|||||||
pub fn wl_surface(&self) -> Option<WlSurface> {
|
pub fn wl_surface(&self) -> Option<WlSurface> {
|
||||||
self.weak_surface.upgrade().ok()
|
self.weak_surface.upgrade().ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn size(&self) -> Option<Vector2<u32>> {
|
|
||||||
self.mapped_data.lock().as_ref().map(|d| d.size)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
impl Drop for CoreSurface {
|
impl Drop for CoreSurface {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
|||||||
@@ -1,9 +1,25 @@
|
|||||||
use smithay::{reexports::wayland_server::protocol::wl_surface::WlSurface, wayland::compositor};
|
use mint::Vector2;
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
use smithay::{
|
||||||
|
backend::renderer::utils::RendererSurfaceStateUserData,
|
||||||
|
reexports::wayland_server::protocol::wl_surface::WlSurface,
|
||||||
|
wayland::{
|
||||||
|
compositor,
|
||||||
|
shell::xdg::{SurfaceCachedState, XdgToplevelSurfaceData},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::nodes::items::panel::{ChildInfo, Geometry, ToplevelInfo};
|
||||||
|
|
||||||
|
use super::xdg_shell::surface_panel_item;
|
||||||
pub trait WlSurfaceExt {
|
pub trait WlSurfaceExt {
|
||||||
fn insert_data<T: Send + Sync + 'static>(&self, data: T) -> bool;
|
fn insert_data<T: Send + Sync + 'static>(&self, data: T) -> bool;
|
||||||
fn get_data<T: Send + Sync + Clone + 'static>(&self) -> Option<T>;
|
fn get_data<T: Send + Sync + Clone + 'static>(&self) -> Option<T>;
|
||||||
fn get_data_raw<T: Send + Sync + 'static, O, F: FnOnce(&T) -> O>(&self, f: F) -> Option<O>;
|
fn get_data_raw<T: Send + Sync + 'static, O, F: FnOnce(&T) -> O>(&self, f: F) -> Option<O>;
|
||||||
|
fn get_current_surface_state(&self) -> SurfaceCachedState;
|
||||||
|
fn get_pending_surface_state(&self) -> SurfaceCachedState;
|
||||||
|
fn get_size(&self) -> Option<Vector2<u32>>;
|
||||||
|
fn get_geometry(&self) -> Option<Geometry>;
|
||||||
}
|
}
|
||||||
impl WlSurfaceExt for WlSurface {
|
impl WlSurfaceExt for WlSurface {
|
||||||
fn insert_data<T: Send + Sync + 'static>(&self, data: T) -> bool {
|
fn insert_data<T: Send + Sync + 'static>(&self, data: T) -> bool {
|
||||||
@@ -17,4 +33,97 @@ impl WlSurfaceExt for WlSurface {
|
|||||||
fn get_data_raw<T: Send + Sync + 'static, O, F: FnOnce(&T) -> O>(&self, f: F) -> Option<O> {
|
fn get_data_raw<T: Send + Sync + 'static, O, F: FnOnce(&T) -> O>(&self, f: F) -> Option<O> {
|
||||||
compositor::with_states(self, |d| Some((f)(d.data_map.get::<T>()?)))
|
compositor::with_states(self, |d| Some((f)(d.data_map.get::<T>()?)))
|
||||||
}
|
}
|
||||||
|
fn get_current_surface_state(&self) -> SurfaceCachedState {
|
||||||
|
compositor::with_states(self, |states| {
|
||||||
|
states
|
||||||
|
.cached_state
|
||||||
|
.get::<SurfaceCachedState>()
|
||||||
|
.current()
|
||||||
|
.clone()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn get_pending_surface_state(&self) -> SurfaceCachedState {
|
||||||
|
compositor::with_states(self, |states| {
|
||||||
|
states
|
||||||
|
.cached_state
|
||||||
|
.get::<SurfaceCachedState>()
|
||||||
|
.pending()
|
||||||
|
.clone()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn get_size(&self) -> Option<Vector2<u32>> {
|
||||||
|
self.get_data_raw::<RendererSurfaceStateUserData, _, _>(|surface_states| {
|
||||||
|
surface_states.lock().unwrap().surface_size()
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.map(|size| Vector2::from([size.w as u32, size.h as u32]))
|
||||||
|
}
|
||||||
|
fn get_geometry(&self) -> Option<Geometry> {
|
||||||
|
self.get_current_surface_state().geometry.map(|r| r.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ToplevelInfoExt {
|
||||||
|
fn get_toplevel_info(&self) -> Option<ToplevelInfo>;
|
||||||
|
fn with_toplevel_info<O, F: FnOnce(&mut ToplevelInfo) -> O>(&self, f: F) -> Option<O>;
|
||||||
|
|
||||||
|
fn get_parent(&self) -> Option<u64>;
|
||||||
|
fn get_app_id(&self) -> Option<String>;
|
||||||
|
fn get_title(&self) -> Option<String>;
|
||||||
|
fn min_size(&self) -> Option<Vector2<u32>>;
|
||||||
|
fn max_size(&self) -> Option<Vector2<u32>>;
|
||||||
|
}
|
||||||
|
impl ToplevelInfoExt for WlSurface {
|
||||||
|
fn get_toplevel_info(&self) -> Option<ToplevelInfo> {
|
||||||
|
self.get_data_raw::<Mutex<ToplevelInfo>, _, _>(|c| c.lock().clone())
|
||||||
|
}
|
||||||
|
fn with_toplevel_info<O, F: FnOnce(&mut ToplevelInfo) -> O>(&self, f: F) -> Option<O> {
|
||||||
|
self.get_data_raw::<Mutex<ToplevelInfo>, _, _>(|r| (f)(&mut r.lock()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_parent(&self) -> Option<u64> {
|
||||||
|
self.get_data_raw::<XdgToplevelSurfaceData, _, _>(|d| d.lock().unwrap().parent.clone())
|
||||||
|
.flatten()
|
||||||
|
.and_then(|p| surface_panel_item(&p))
|
||||||
|
.and_then(|p| p.node.upgrade())
|
||||||
|
.map(|p| p.get_id())
|
||||||
|
}
|
||||||
|
fn get_app_id(&self) -> Option<String> {
|
||||||
|
self.get_data_raw::<XdgToplevelSurfaceData, _, _>(|d| d.lock().ok()?.app_id.clone())
|
||||||
|
.flatten()
|
||||||
|
}
|
||||||
|
fn get_title(&self) -> Option<String> {
|
||||||
|
self.get_data_raw::<XdgToplevelSurfaceData, _, _>(|d| d.lock().ok()?.title.clone())
|
||||||
|
.flatten()
|
||||||
|
}
|
||||||
|
fn min_size(&self) -> Option<Vector2<u32>> {
|
||||||
|
let state = self.get_pending_surface_state();
|
||||||
|
let size = state.min_size;
|
||||||
|
if size.w == 0 && size.h == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(Vector2::from([size.w as u32, size.h as u32]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn max_size(&self) -> Option<Vector2<u32>> {
|
||||||
|
let state = self.get_pending_surface_state();
|
||||||
|
let size = state.max_size;
|
||||||
|
if size.w == 0 && size.h == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(Vector2::from([size.w as u32, size.h as u32]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub trait ChildInfoExt {
|
||||||
|
fn get_child_info(&self) -> Option<ChildInfo>;
|
||||||
|
fn with_child_info<O, F: FnOnce(&mut ChildInfo) -> O>(&self, f: F) -> Option<O>;
|
||||||
|
}
|
||||||
|
impl ChildInfoExt for WlSurface {
|
||||||
|
fn get_child_info(&self) -> Option<ChildInfo> {
|
||||||
|
self.get_data_raw::<Mutex<ChildInfo>, _, _>(|c| c.lock().clone())
|
||||||
|
}
|
||||||
|
fn with_child_info<O, F: FnOnce(&mut ChildInfo) -> O>(&self, f: F) -> Option<O> {
|
||||||
|
self.get_data_raw::<Mutex<ChildInfo>, _, _>(|r| (f)(&mut r.lock()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use super::{
|
|||||||
seat::{handle_cursor, SeatWrapper},
|
seat::{handle_cursor, SeatWrapper},
|
||||||
state::{ClientState, WaylandState},
|
state::{ClientState, WaylandState},
|
||||||
surface::CoreSurface,
|
surface::CoreSurface,
|
||||||
utils::WlSurfaceExt,
|
utils::*,
|
||||||
};
|
};
|
||||||
use crate::nodes::{
|
use crate::nodes::{
|
||||||
drawable::model::ModelPart,
|
drawable::model::ModelPart,
|
||||||
@@ -16,7 +16,6 @@ use parking_lot::Mutex;
|
|||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use smithay::{
|
use smithay::{
|
||||||
backend::renderer::utils::RendererSurfaceStateUserData,
|
|
||||||
delegate_xdg_shell,
|
delegate_xdg_shell,
|
||||||
reexports::{
|
reexports::{
|
||||||
wayland_protocols::xdg::{
|
wayland_protocols::xdg::{
|
||||||
@@ -30,16 +29,25 @@ use smithay::{
|
|||||||
},
|
},
|
||||||
utils::{Logical, Rectangle, Serial},
|
utils::{Logical, Rectangle, Serial},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::{self, add_post_commit_hook},
|
compositor::add_post_commit_hook,
|
||||||
shell::xdg::{
|
shell::xdg::{
|
||||||
PopupSurface, PositionerState, ShellClient, SurfaceCachedState, ToplevelSurface,
|
PopupSurface, PositionerState, ShellClient, ToplevelSurface, XdgShellHandler,
|
||||||
XdgShellHandler, XdgShellState, XdgToplevelSurfaceData,
|
XdgShellState,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
|
fn get_unconstrained_popup_geometry(positioner: &PositionerState) -> Geometry {
|
||||||
|
positioner
|
||||||
|
.get_unconstrained_geometry(Rectangle {
|
||||||
|
loc: (-100000, -100000).into(),
|
||||||
|
size: (200000, 200000).into(),
|
||||||
|
})
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Rectangle<i32, Logical>> for Geometry {
|
impl From<Rectangle<i32, Logical>> for Geometry {
|
||||||
fn from(value: Rectangle<i32, Logical>) -> Self {
|
fn from(value: Rectangle<i32, Logical>) -> Self {
|
||||||
Geometry {
|
Geometry {
|
||||||
@@ -49,49 +57,6 @@ impl From<Rectangle<i32, Logical>> for Geometry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub trait ToplevelInfoExt {
|
|
||||||
// fn get_toplevel_info(&self) -> Option<ToplevelInfo>;
|
|
||||||
// fn with_toplevel_info<O, F: FnOnce(&mut ToplevelInfo) -> O>(&self, f: F) -> Option<O>;
|
|
||||||
// fn get_toplevel_state(&self) -> Option<ToplevelState>;
|
|
||||||
|
|
||||||
// fn get_app_id(&self) -> Option<String>;
|
|
||||||
// fn get_title(&self) -> Option<String>;
|
|
||||||
// }
|
|
||||||
// impl ToplevelInfoExt for WlSurface {
|
|
||||||
// fn get_toplevel_info(&self) -> Option<ToplevelInfo> {
|
|
||||||
// self.get_data_raw::<Mutex<ToplevelInfo>, _, _>(|c| c.lock().clone())
|
|
||||||
// }
|
|
||||||
// fn with_toplevel_info<O, F: FnOnce(&mut ToplevelInfo) -> O>(&self, f: F) -> Option<O> {
|
|
||||||
// self.get_data_raw::<Mutex<ToplevelInfo>, _, _>(|r| (f)(&mut r.lock()))
|
|
||||||
// }
|
|
||||||
// fn get_toplevel_state(&self) -> Option<ToplevelState> {
|
|
||||||
// self.get_data_raw::<XdgToplevelSurfaceData, _, _>(|r| r.lock().unwrap().current.clone())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn get_app_id(&self) -> Option<String> {
|
|
||||||
// self.get_data_raw::<XdgToplevelSurfaceData, _, _>(|d| {
|
|
||||||
// d.lock().unwrap().app_id.clone().unwrap()
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// fn get_title(&self) -> Option<String> {
|
|
||||||
// self.get_data_raw::<XdgToplevelSurfaceData, _, _>(|d| {
|
|
||||||
// d.lock().unwrap().title.clone().unwrap()
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
pub trait ChildInfoExt {
|
|
||||||
fn get_child_info(&self) -> Option<ChildInfo>;
|
|
||||||
fn with_child_info<O, F: FnOnce(&mut ChildInfo) -> O>(&self, f: F) -> Option<O>;
|
|
||||||
}
|
|
||||||
impl ChildInfoExt for WlSurface {
|
|
||||||
fn get_child_info(&self) -> Option<ChildInfo> {
|
|
||||||
self.get_data_raw::<Mutex<ChildInfo>, _, _>(|c| c.lock().clone())
|
|
||||||
}
|
|
||||||
fn with_child_info<O, F: FnOnce(&mut ChildInfo) -> O>(&self, f: F) -> Option<O> {
|
|
||||||
self.get_data_raw::<Mutex<ChildInfo>, _, _>(|r| (f)(&mut r.lock()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn surface_panel_item(wl_surface: &WlSurface) -> Option<Arc<PanelItem<XdgBackend>>> {
|
pub fn surface_panel_item(wl_surface: &WlSurface) -> Option<Arc<PanelItem<XdgBackend>>> {
|
||||||
let panel_item = wl_surface
|
let panel_item = wl_surface
|
||||||
.get_data::<Weak<PanelItem<XdgBackend>>>()
|
.get_data::<Weak<PanelItem<XdgBackend>>>()
|
||||||
@@ -123,11 +88,76 @@ impl XdgShellHandler for WaylandState {
|
|||||||
s.states.unset(State::Fullscreen);
|
s.states.unset(State::Fullscreen);
|
||||||
});
|
});
|
||||||
toplevel.send_configure();
|
toplevel.send_configure();
|
||||||
|
|
||||||
|
let initial_size = toplevel
|
||||||
|
.wl_surface()
|
||||||
|
.get_size()
|
||||||
|
.unwrap_or(Vector2::from([0; 2]));
|
||||||
|
|
||||||
|
let initial_toplevel_info = ToplevelInfo {
|
||||||
|
parent: toplevel.wl_surface().get_parent(),
|
||||||
|
title: toplevel.wl_surface().get_title(),
|
||||||
|
app_id: toplevel.wl_surface().get_app_id(),
|
||||||
|
size: initial_size,
|
||||||
|
min_size: toplevel
|
||||||
|
.wl_surface()
|
||||||
|
.min_size()
|
||||||
|
.map(|s| Vector2::from([s.x as f32, s.y as f32])),
|
||||||
|
max_size: toplevel
|
||||||
|
.wl_surface()
|
||||||
|
.max_size()
|
||||||
|
.map(|s| Vector2::from([s.x as f32, s.y as f32])),
|
||||||
|
logical_rectangle: toplevel
|
||||||
|
.wl_surface()
|
||||||
|
.get_geometry()
|
||||||
|
.map(|r| r.into())
|
||||||
|
.unwrap_or(Geometry {
|
||||||
|
origin: [0; 2].into(),
|
||||||
|
size: initial_size,
|
||||||
|
}),
|
||||||
|
};
|
||||||
toplevel
|
toplevel
|
||||||
.wl_surface()
|
.wl_surface()
|
||||||
.insert_data(Mutex::new(Vector2::from([0_u32; 2])));
|
.insert_data(Mutex::new(initial_toplevel_info));
|
||||||
|
|
||||||
CoreSurface::add_to(toplevel.wl_surface());
|
CoreSurface::add_to(toplevel.wl_surface());
|
||||||
|
|
||||||
|
add_post_commit_hook(
|
||||||
|
toplevel.wl_surface(),
|
||||||
|
|_state: &mut WaylandState, _dh, surf| {
|
||||||
|
let parent = surf.get_parent();
|
||||||
|
let new_size = surf.get_size().unwrap_or(Vector2::from([0; 2]));
|
||||||
|
let min_size = surf
|
||||||
|
.min_size()
|
||||||
|
.map(|s| Vector2::from([s.x as f32, s.y as f32]));
|
||||||
|
let max_size = surf
|
||||||
|
.max_size()
|
||||||
|
.map(|s| Vector2::from([s.x as f32, s.y as f32]));
|
||||||
|
let logical_rectangle = surf.get_geometry().unwrap_or_default();
|
||||||
|
|
||||||
|
let mut size_changed = false;
|
||||||
|
surf.with_toplevel_info(|info| {
|
||||||
|
info.parent = parent;
|
||||||
|
if new_size != info.size {
|
||||||
|
info.size = new_size;
|
||||||
|
size_changed = true;
|
||||||
|
}
|
||||||
|
info.min_size = min_size;
|
||||||
|
info.max_size = max_size;
|
||||||
|
info.logical_rectangle = logical_rectangle;
|
||||||
|
});
|
||||||
|
|
||||||
|
if size_changed {
|
||||||
|
let Some(panel_item) = surface_panel_item(surf) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
if let Some(toplevel_info) = surf.get_toplevel_info() {
|
||||||
|
panel_item.toplevel_size_changed(toplevel_info.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
add_post_commit_hook(
|
add_post_commit_hook(
|
||||||
toplevel.wl_surface(),
|
toplevel.wl_surface(),
|
||||||
|state: &mut WaylandState, _dh, surf| {
|
|state: &mut WaylandState, _dh, surf| {
|
||||||
@@ -156,32 +186,6 @@ impl XdgShellHandler for WaylandState {
|
|||||||
surf.insert_data(node);
|
surf.insert_data(node);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
add_post_commit_hook(
|
|
||||||
toplevel.wl_surface(),
|
|
||||||
|_state: &mut WaylandState, _dh, surf| {
|
|
||||||
let Some(panel_item) = surface_panel_item(surf) else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
let Some(size) = surf
|
|
||||||
.get_data_raw::<RendererSurfaceStateUserData, _, _>(|surface_states| {
|
|
||||||
surface_states.lock().unwrap().surface_size()
|
|
||||||
})
|
|
||||||
.flatten()
|
|
||||||
else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
let size = [size.w as u32, size.h as u32].into();
|
|
||||||
surf.get_data_raw::<Mutex<Vector2<u32>>, _, _>(|old_size| {
|
|
||||||
let mut old_size = old_size.lock();
|
|
||||||
|
|
||||||
if *old_size != size {
|
|
||||||
panel_item.toplevel_size_changed(size);
|
|
||||||
*old_size = size;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
fn toplevel_destroyed(&mut self, toplevel: ToplevelSurface) {
|
fn toplevel_destroyed(&mut self, toplevel: ToplevelSurface) {
|
||||||
let Some(panel_item) = surface_panel_item(toplevel.wl_surface()) else {
|
let Some(panel_item) = surface_panel_item(toplevel.wl_surface()) else {
|
||||||
@@ -192,32 +196,35 @@ impl XdgShellHandler for WaylandState {
|
|||||||
panel_item.backend.children.lock().clear();
|
panel_item.backend.children.lock().clear();
|
||||||
}
|
}
|
||||||
fn app_id_changed(&mut self, toplevel: ToplevelSurface) {
|
fn app_id_changed(&mut self, toplevel: ToplevelSurface) {
|
||||||
let Some(panel_item) = surface_panel_item(toplevel.wl_surface()) else {
|
let wl_surface = toplevel.wl_surface();
|
||||||
|
let Some(app_id) = wl_surface.get_app_id() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
panel_item.toplevel_app_id_changed(
|
wl_surface.with_toplevel_info(|info| {
|
||||||
&toplevel
|
info.app_id = Some(app_id.clone());
|
||||||
.wl_surface()
|
});
|
||||||
.get_data_raw::<XdgToplevelSurfaceData, _, _>(|d| {
|
|
||||||
d.lock().unwrap().app_id.clone().unwrap()
|
let Some(panel_item) = surface_panel_item(wl_surface) else {
|
||||||
})
|
return;
|
||||||
.unwrap_or_default(),
|
};
|
||||||
)
|
panel_item.toplevel_app_id_changed(&app_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn title_changed(&mut self, toplevel: ToplevelSurface) {
|
fn title_changed(&mut self, toplevel: ToplevelSurface) {
|
||||||
let Some(panel_item) = surface_panel_item(toplevel.wl_surface()) else {
|
let wl_surface = toplevel.wl_surface();
|
||||||
|
let Some(title) = wl_surface.get_title() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
panel_item.toplevel_title_changed(
|
wl_surface.with_toplevel_info(|info| {
|
||||||
&toplevel
|
info.title = Some(title.clone());
|
||||||
.wl_surface()
|
});
|
||||||
.get_data_raw::<XdgToplevelSurfaceData, _, _>(|d| {
|
|
||||||
d.lock().unwrap().title.clone().unwrap()
|
let Some(panel_item) = surface_panel_item(wl_surface) else {
|
||||||
})
|
return;
|
||||||
.unwrap_or_default(),
|
};
|
||||||
)
|
panel_item.toplevel_title_changed(&title)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_popup(&mut self, popup: PopupSurface, positioner: PositionerState) {
|
fn new_popup(&mut self, popup: PopupSurface, positioner: PositionerState) {
|
||||||
@@ -232,12 +239,7 @@ impl XdgShellHandler for WaylandState {
|
|||||||
popup.wl_surface().insert_data(Mutex::new(ChildInfo {
|
popup.wl_surface().insert_data(Mutex::new(ChildInfo {
|
||||||
id,
|
id,
|
||||||
parent: parent.get_data::<SurfaceId>().unwrap(),
|
parent: parent.get_data::<SurfaceId>().unwrap(),
|
||||||
geometry: positioner
|
geometry: get_unconstrained_popup_geometry(&positioner),
|
||||||
.get_unconstrained_geometry(Rectangle {
|
|
||||||
loc: (-100000, -100000).into(),
|
|
||||||
size: (200000, 200000).into(),
|
|
||||||
})
|
|
||||||
.into(),
|
|
||||||
z_order: 1,
|
z_order: 1,
|
||||||
receives_input: true,
|
receives_input: true,
|
||||||
}));
|
}));
|
||||||
@@ -271,12 +273,7 @@ impl XdgShellHandler for WaylandState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
popup.wl_surface().with_child_info(|ci| {
|
popup.wl_surface().with_child_info(|ci| {
|
||||||
ci.geometry = positioner
|
ci.geometry = get_unconstrained_popup_geometry(&positioner);
|
||||||
.get_unconstrained_geometry(Rectangle {
|
|
||||||
loc: (-100000, -100000).into(),
|
|
||||||
size: (200000, 200000).into(),
|
|
||||||
})
|
|
||||||
.into()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
panel_item.backend.reposition_child(popup.wl_surface());
|
panel_item.backend.reposition_child(popup.wl_surface());
|
||||||
@@ -359,7 +356,6 @@ impl XdgBackend {
|
|||||||
XdgBackend {
|
XdgBackend {
|
||||||
toplevel: Mutex::new(Some(toplevel)),
|
toplevel: Mutex::new(Some(toplevel)),
|
||||||
children: Mutex::new(FxHashMap::default()),
|
children: Mutex::new(FxHashMap::default()),
|
||||||
// popups: Mutex::new(FxHashMap::default()),
|
|
||||||
seat,
|
seat,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -415,90 +411,18 @@ impl Backend for XdgBackend {
|
|||||||
.clone()
|
.clone()
|
||||||
.and_then(|s| s.upgrade().ok())
|
.and_then(|s| s.upgrade().ok())
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(CoreSurface::from_wl_surface)
|
.and_then(|c| c.get_size())
|
||||||
.and_then(|c| c.size())
|
|
||||||
.map(|size| Geometry {
|
.map(|size| Geometry {
|
||||||
origin: [0; 2].into(),
|
origin: [0; 2].into(),
|
||||||
size,
|
size,
|
||||||
});
|
});
|
||||||
|
|
||||||
let toplevel = self
|
let toplevel_info = self
|
||||||
.toplevel
|
.toplevel
|
||||||
.lock()
|
.lock()
|
||||||
.clone()
|
|
||||||
.ok_or(eyre!("Internal: no toplevel"))?;
|
|
||||||
let (app_id, title) = compositor::with_states(toplevel.wl_surface(), |states| {
|
|
||||||
let xdg_toplevel_data = states
|
|
||||||
.data_map
|
|
||||||
.get::<XdgToplevelSurfaceData>()
|
|
||||||
.ok_or(eyre!("Internal: XdgToplevelSurfaceData not found"))?;
|
|
||||||
|
|
||||||
let locked_data = xdg_toplevel_data
|
|
||||||
.lock()
|
|
||||||
.map_err(|_| eyre!("Internal: Failed to lock XdgToplevelSurfaceData"))?;
|
|
||||||
|
|
||||||
Ok::<_, color_eyre::eyre::Report>((
|
|
||||||
locked_data.app_id.clone(),
|
|
||||||
locked_data.title.clone(),
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
let toplevel_cached_state = compositor::with_states(toplevel.wl_surface(), |states| {
|
|
||||||
*states.cached_state.get::<SurfaceCachedState>().current()
|
|
||||||
});
|
|
||||||
let toplevel_core_surface = CoreSurface::from_wl_surface(toplevel.wl_surface())
|
|
||||||
.ok_or(eyre!("Internal: Failed to get CoreSurface from WlSurface"))?;
|
|
||||||
|
|
||||||
let size = toplevel
|
|
||||||
.current_state()
|
|
||||||
.size
|
|
||||||
.map(|s| Vector2::from([s.w as u32, s.h as u32]))
|
|
||||||
.or_else(|| toplevel_core_surface.size())
|
|
||||||
.unwrap_or(Vector2::from([0; 2]));
|
|
||||||
let parent = toplevel
|
|
||||||
.parent()
|
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(surface_panel_item)
|
.and_then(|toplevel| toplevel.wl_surface().get_toplevel_info())
|
||||||
.and_then(|p| p.node.upgrade())
|
.ok_or(eyre!("Internal: no toplevel or ToplevelInfo"))?;
|
||||||
.map(|p| p.get_id());
|
|
||||||
let toplevel = ToplevelInfo {
|
|
||||||
parent,
|
|
||||||
title,
|
|
||||||
app_id,
|
|
||||||
size,
|
|
||||||
min_size: if toplevel_cached_state.min_size.w != 0
|
|
||||||
&& toplevel_cached_state.min_size.h != 0
|
|
||||||
{
|
|
||||||
Some(
|
|
||||||
[
|
|
||||||
toplevel_cached_state.min_size.w as f32,
|
|
||||||
toplevel_cached_state.min_size.h as f32,
|
|
||||||
]
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
max_size: if toplevel_cached_state.max_size.w != 0
|
|
||||||
&& toplevel_cached_state.max_size.h != 0
|
|
||||||
{
|
|
||||||
Some(
|
|
||||||
[
|
|
||||||
toplevel_cached_state.max_size.w as f32,
|
|
||||||
toplevel_cached_state.max_size.h as f32,
|
|
||||||
]
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
logical_rectangle: toplevel_cached_state
|
|
||||||
.geometry
|
|
||||||
.map(Into::into)
|
|
||||||
.unwrap_or_else(|| Geometry {
|
|
||||||
origin: [0; 2].into(),
|
|
||||||
size,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
let children = self
|
let children = self
|
||||||
.children
|
.children
|
||||||
@@ -509,7 +433,7 @@ impl Backend for XdgBackend {
|
|||||||
|
|
||||||
Ok(PanelItemInitData {
|
Ok(PanelItemInitData {
|
||||||
cursor,
|
cursor,
|
||||||
toplevel,
|
toplevel: toplevel_info,
|
||||||
children,
|
children,
|
||||||
pointer_grab: None,
|
pointer_grab: None,
|
||||||
keyboard_grab: None,
|
keyboard_grab: None,
|
||||||
|
|||||||
Reference in New Issue
Block a user