feat(wayland): recommended_state

This commit is contained in:
Nova
2023-01-02 18:53:58 -05:00
parent 84a7546442
commit a483cdbc7d
2 changed files with 60 additions and 15 deletions

View File

@@ -58,7 +58,7 @@ lazy_static! {
"close", "close",
], ],
aliased_local_methods: vec![], aliased_local_methods: vec![],
aliased_remote_signals: vec!["commit_toplevel", "set_cursor",], aliased_remote_signals: vec!["commit_toplevel", "recommend_toplevel_state", "set_cursor"],
ui: Default::default(), ui: Default::default(),
items: Registry::new(), items: Registry::new(),
acceptors: Registry::new(), acceptors: Registry::new(),
@@ -96,6 +96,16 @@ impl Default for ToplevelState {
} }
} }
#[derive(Debug, Clone, Serialize)]
#[serde(tag = "type", content = "content")]
pub enum RecommendedState {
Maximize(bool),
Fullscreen(bool),
Minimize,
Move,
Resize(u32),
}
pub struct PanelItem { pub struct PanelItem {
node: Weak<Node>, node: Weak<Node>,
client_credentials: Option<Credentials>, client_credentials: Option<Credentials>,
@@ -498,7 +508,7 @@ impl PanelItem {
let Ok(xdg_toplevel) = panel_item.toplevel.upgrade() else { return Ok(()) }; let Ok(xdg_toplevel) = panel_item.toplevel.upgrade() else { return Ok(()) };
let Some(xdg_surface) = panel_item.toplevel_surface_data().and_then(|d| d.xdg_surface.upgrade().ok()) else { return Ok(()) }; let Some(xdg_surface) = panel_item.toplevel_surface_data().and_then(|d| d.xdg_surface.upgrade().ok()) else { return Ok(()) };
#[derive(Deserialize)] #[derive(Debug, Deserialize)]
struct ConfigureToplevelInfo { struct ConfigureToplevelInfo {
size: Option<Vector2<u32>>, size: Option<Vector2<u32>>,
states: Vec<u8>, states: Vec<u8>,
@@ -547,6 +557,14 @@ impl PanelItem {
let _ = node.send_remote_signal("commit_toplevel", &serialize(&*state).unwrap()); let _ = node.send_remote_signal("commit_toplevel", &serialize(&*state).unwrap());
} }
pub fn recommend_toplevel_state(&self, state: RecommendedState) {
let Some(node) = self.node.upgrade() else { return };
dbg!(&state);
let data = serialize(state).unwrap();
let _ = node.send_remote_signal("recommend_toplevel_state", &data);
}
pub fn set_cursor(&self, surface: Option<&WlSurface>, hotspot_x: i32, hotspot_y: i32) { pub fn set_cursor(&self, surface: Option<&WlSurface>, hotspot_x: i32, hotspot_y: i32) {
let Some(node) = self.node.upgrade() else { return }; let Some(node) = self.node.upgrade() else { return };
let mut data = serialize(()).unwrap(); let mut data = serialize(()).unwrap();

View File

@@ -1,7 +1,7 @@
use std::sync::Arc; use std::sync::Arc;
use super::{ use super::{
panel_item::{PanelItem, ToplevelState}, panel_item::{PanelItem, RecommendedState, ToplevelState},
state::WaylandState, state::WaylandState,
}; };
use mint::Vector2; use mint::Vector2;
@@ -280,6 +280,14 @@ pub struct XdgToplevelData {
pub state: Arc<Mutex<ToplevelState>>, pub state: Arc<Mutex<ToplevelState>>,
pub xdg_surface_data: XdgSurfaceData, pub xdg_surface_data: XdgSurfaceData,
} }
impl XdgToplevelData {
fn panel_item(&self) -> Option<Arc<PanelItem>> {
let wl_surface = self.xdg_surface_data.wl_surface.upgrade().ok()?;
compositor::with_states(&wl_surface, |data| {
data.data_map.get::<Arc<PanelItem>>().cloned()
})
}
}
impl Dispatch<XdgToplevel, XdgToplevelData, WaylandState> for WaylandState { impl Dispatch<XdgToplevel, XdgToplevelData, WaylandState> for WaylandState {
fn request( fn request(
_state: &mut WaylandState, _state: &mut WaylandState,
@@ -312,12 +320,19 @@ impl Dispatch<XdgToplevel, XdgToplevelData, WaylandState> for WaylandState {
x: _, x: _,
y: _, y: _,
} => (), } => (),
xdg_toplevel::Request::Move { seat: _, serial: _ } => (), xdg_toplevel::Request::Move { seat: _, serial: _ } => {
let Some(panel_item) = data.panel_item() else { return };
panel_item.recommend_toplevel_state(RecommendedState::Move);
}
xdg_toplevel::Request::Resize { xdg_toplevel::Request::Resize {
seat: _, seat: _,
serial: _, serial: _,
edges: _, edges,
} => (), } => {
let WEnum::Value(edges) = edges else { return };
let Some(panel_item) = data.panel_item() else { return };
panel_item.recommend_toplevel_state(RecommendedState::Resize(edges as u32));
}
xdg_toplevel::Request::SetMaxSize { width, height } => { xdg_toplevel::Request::SetMaxSize { width, height } => {
let mut state = data.state.lock(); let mut state = data.state.lock();
let queued_state = state.queued_state.as_mut().unwrap(); let queued_state = state.queued_state.as_mut().unwrap();
@@ -330,16 +345,28 @@ impl Dispatch<XdgToplevel, XdgToplevelData, WaylandState> for WaylandState {
queued_state.min_size = (width > 1 || height > 1) queued_state.min_size = (width > 1 || height > 1)
.then_some(Vector2::from([width as u32, height as u32])); .then_some(Vector2::from([width as u32, height as u32]));
} }
xdg_toplevel::Request::SetMaximized => (), xdg_toplevel::Request::SetMaximized => {
xdg_toplevel::Request::UnsetMaximized => (), let Some(panel_item) = data.panel_item() else { return };
xdg_toplevel::Request::SetFullscreen { output: _ } => (), panel_item.recommend_toplevel_state(RecommendedState::Maximize(true));
xdg_toplevel::Request::UnsetFullscreen => (), }
xdg_toplevel::Request::SetMinimized => (), xdg_toplevel::Request::UnsetMaximized => {
let Some(panel_item) = data.panel_item() else { return };
panel_item.recommend_toplevel_state(RecommendedState::Maximize(false));
}
xdg_toplevel::Request::SetFullscreen { output: _ } => {
let Some(panel_item) = data.panel_item() else { return };
panel_item.recommend_toplevel_state(RecommendedState::Fullscreen(true));
}
xdg_toplevel::Request::UnsetFullscreen => {
let Some(panel_item) = data.panel_item() else { return };
panel_item.recommend_toplevel_state(RecommendedState::Fullscreen(true));
}
xdg_toplevel::Request::SetMinimized => {
let Some(panel_item) = data.panel_item() else { return };
panel_item.recommend_toplevel_state(RecommendedState::Minimize);
}
xdg_toplevel::Request::Destroy => { xdg_toplevel::Request::Destroy => {
let Ok(wl_surface) = data.xdg_surface_data.wl_surface.upgrade() else { return }; let Some(panel_item) = data.panel_item() else { return };
let Some(panel_item) = compositor::with_states(&wl_surface, |data| {
data.data_map.get::<Arc<PanelItem>>().cloned()
}) else { return };
panel_item.on_drop(); panel_item.on_drop();
} }
_ => unreachable!(), _ => unreachable!(),