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",
],
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(),
items: 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 {
node: Weak<Node>,
client_credentials: Option<Credentials>,
@@ -498,7 +508,7 @@ impl PanelItem {
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(()) };
#[derive(Deserialize)]
#[derive(Debug, Deserialize)]
struct ConfigureToplevelInfo {
size: Option<Vector2<u32>>,
states: Vec<u8>,
@@ -547,6 +557,14 @@ impl PanelItem {
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) {
let Some(node) = self.node.upgrade() else { return };
let mut data = serialize(()).unwrap();

View File

@@ -1,7 +1,7 @@
use std::sync::Arc;
use super::{
panel_item::{PanelItem, ToplevelState},
panel_item::{PanelItem, RecommendedState, ToplevelState},
state::WaylandState,
};
use mint::Vector2;
@@ -280,6 +280,14 @@ pub struct XdgToplevelData {
pub state: Arc<Mutex<ToplevelState>>,
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 {
fn request(
_state: &mut WaylandState,
@@ -312,12 +320,19 @@ impl Dispatch<XdgToplevel, XdgToplevelData, WaylandState> for WaylandState {
x: _,
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 {
seat: _,
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 } => {
let mut state = data.state.lock();
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)
.then_some(Vector2::from([width as u32, height as u32]));
}
xdg_toplevel::Request::SetMaximized => (),
xdg_toplevel::Request::UnsetMaximized => (),
xdg_toplevel::Request::SetFullscreen { output: _ } => (),
xdg_toplevel::Request::UnsetFullscreen => (),
xdg_toplevel::Request::SetMinimized => (),
xdg_toplevel::Request::SetMaximized => {
let Some(panel_item) = data.panel_item() else { return };
panel_item.recommend_toplevel_state(RecommendedState::Maximize(true));
}
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 => {
let Ok(wl_surface) = data.xdg_surface_data.wl_surface.upgrade() else { return };
let Some(panel_item) = compositor::with_states(&wl_surface, |data| {
data.data_map.get::<Arc<PanelItem>>().cloned()
}) else { return };
let Some(panel_item) = data.panel_item() else { return };
panel_item.on_drop();
}
_ => unreachable!(),