wayland: toplevel management protocol
This commit is contained in:
parent
4f142d50b3
commit
6b659eb107
9 changed files with 340 additions and 54 deletions
42
Cargo.lock
generated
42
Cargo.lock
generated
|
|
@ -361,11 +361,10 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-protocols"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/cosmic-protocols?branch=main#55f15e8b05fc983ab36b65b4c027b59f5876a181"
|
||||
source = "git+https://github.com/pop-os/cosmic-protocols?branch=main#81d6a50bdc91af5968f87785fc19a16cf261c96b"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"wayland-backend",
|
||||
"wayland-client 0.30.0-beta.8",
|
||||
"wayland-protocols 0.30.0-beta.8",
|
||||
"wayland-scanner 0.30.0-beta.8",
|
||||
"wayland-server",
|
||||
|
|
@ -649,21 +648,6 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
|
||||
|
||||
[[package]]
|
||||
name = "gbm"
|
||||
version = "0.8.0"
|
||||
|
|
@ -1569,7 +1553,7 @@ dependencies = [
|
|||
"memmap2",
|
||||
"nix 0.22.3",
|
||||
"pkg-config",
|
||||
"wayland-client 0.29.4",
|
||||
"wayland-client",
|
||||
"wayland-cursor",
|
||||
"wayland-protocols 0.29.4",
|
||||
]
|
||||
|
|
@ -1844,21 +1828,6 @@ dependencies = [
|
|||
"wayland-sys 0.29.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-client"
|
||||
version = "0.30.0-beta.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f9e0d862c23f07b2c4b49de66b0680948af5dd1d2def17f1ddc16520352bf14"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"nix 0.24.2",
|
||||
"thiserror",
|
||||
"wayland-backend",
|
||||
"wayland-scanner 0.30.0-beta.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-commons"
|
||||
version = "0.29.4"
|
||||
|
|
@ -1878,7 +1847,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c52758f13d5e7861fc83d942d3d99bf270c83269575e52ac29e5b73cb956a6bd"
|
||||
dependencies = [
|
||||
"nix 0.22.3",
|
||||
"wayland-client 0.29.4",
|
||||
"wayland-client",
|
||||
"xcursor",
|
||||
]
|
||||
|
||||
|
|
@ -1900,7 +1869,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "60147ae23303402e41fe034f74fb2c35ad0780ee88a1c40ac09a3be1e7465741"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"wayland-client 0.29.4",
|
||||
"wayland-client",
|
||||
"wayland-commons",
|
||||
"wayland-scanner 0.29.4",
|
||||
]
|
||||
|
|
@ -1913,7 +1882,6 @@ checksum = "e47c45a60d531d5a513601f47f51a4743901836778ddae208ae9124606be1719"
|
|||
dependencies = [
|
||||
"bitflags",
|
||||
"wayland-backend",
|
||||
"wayland-client 0.30.0-beta.8",
|
||||
"wayland-scanner 0.30.0-beta.8",
|
||||
"wayland-server",
|
||||
]
|
||||
|
|
@ -2102,7 +2070,7 @@ dependencies = [
|
|||
"raw-window-handle",
|
||||
"smithay-client-toolkit",
|
||||
"wasm-bindgen",
|
||||
"wayland-client 0.29.4",
|
||||
"wayland-client",
|
||||
"wayland-protocols 0.29.4",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ atomic_float = "0.1"
|
|||
libsystemd = "0.5"
|
||||
wayland-backend = "=0.1.0-beta.8"
|
||||
wayland-scanner = "=0.30.0-beta.8"
|
||||
cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", branch = "main" }
|
||||
cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"] }
|
||||
|
||||
[dependencies.smithay]
|
||||
version = "0.3"
|
||||
|
|
|
|||
|
|
@ -22,9 +22,11 @@ use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::State
|
|||
|
||||
use crate::{
|
||||
config::{Config, WorkspaceMode as ConfigMode},
|
||||
//state::ClientState,
|
||||
utils::prelude::*,
|
||||
wayland::protocols::{
|
||||
toplevel_info::ToplevelInfoState,
|
||||
toplevel_management::{ToplevelManagementState, ManagementCapabilities},
|
||||
workspace::{
|
||||
WorkspaceCapabilities, WorkspaceGroupHandle, WorkspaceHandle, WorkspaceState,
|
||||
WorkspaceUpdateGuard,
|
||||
|
|
@ -52,6 +54,7 @@ pub struct Shell {
|
|||
// wayland_state
|
||||
pub layer_shell_state: WlrLayerShellState,
|
||||
pub toplevel_info_state: ToplevelInfoState<State>,
|
||||
pub toplevel_management_state: ToplevelManagementState,
|
||||
pub xdg_shell_state: XdgShellState,
|
||||
pub workspace_state: WorkspaceState<State>,
|
||||
}
|
||||
|
|
@ -81,10 +84,24 @@ const UNINIT_SPACE: MaybeUninit<Workspace> = MaybeUninit::uninit();
|
|||
|
||||
impl Shell {
|
||||
pub fn new(config: &Config, dh: &DisplayHandle) -> Self {
|
||||
// TODO: Privileged protocols
|
||||
let layer_shell_state = WlrLayerShellState::new::<State, _>(dh, None);
|
||||
let toplevel_info_state = ToplevelInfoState::new(dh, |_| true);
|
||||
let xdg_shell_state = XdgShellState::new::<State, _>(dh, None);
|
||||
let mut workspace_state = WorkspaceState::new(dh, |_| true);
|
||||
let toplevel_info_state = ToplevelInfoState::new(
|
||||
dh,
|
||||
//|client| client.get_data::<ClientState>().unwrap().privileged,
|
||||
|_| true);
|
||||
let toplevel_management_state = ToplevelManagementState::new::<State, _>(
|
||||
dh,
|
||||
vec![ManagementCapabilities::Close, ManagementCapabilities::Activate],
|
||||
//|client| client.get_data::<ClientState>().unwrap().privileged,
|
||||
|_| true,
|
||||
);
|
||||
let mut workspace_state = WorkspaceState::new(
|
||||
dh,
|
||||
//|client| client.get_data::<ClientState>().unwrap().privileged,
|
||||
|_| true,
|
||||
);
|
||||
|
||||
let mut spaces = unsafe {
|
||||
let mut spaces = [UNINIT_SPACE; MAX_WORKSPACES];
|
||||
|
|
@ -116,6 +133,7 @@ impl Shell {
|
|||
|
||||
layer_shell_state,
|
||||
toplevel_info_state,
|
||||
toplevel_management_state,
|
||||
xdg_shell_state,
|
||||
workspace_state,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use smithay::{
|
|||
use std::collections::HashMap;
|
||||
|
||||
pub struct Workspace {
|
||||
pub(super) idx: u8,
|
||||
pub idx: u8,
|
||||
pub space: Space,
|
||||
pub tiling_layer: TilingLayout,
|
||||
pub floating_layer: FloatingLayout,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ pub mod primary_selection;
|
|||
pub mod seat;
|
||||
pub mod shm;
|
||||
pub mod toplevel_info;
|
||||
pub mod toplevel_management;
|
||||
pub mod viewporter;
|
||||
pub mod wl_drm;
|
||||
pub mod workspace;
|
||||
|
|
|
|||
45
src/wayland/handlers/toplevel_management.rs
Normal file
45
src/wayland/handlers/toplevel_management.rs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use smithay::{
|
||||
desktop::{Kind, Window},
|
||||
reexports::wayland_server::DisplayHandle,
|
||||
wayland::seat::Seat,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
utils::prelude::*,
|
||||
wayland::protocols::toplevel_management::{
|
||||
delegate_toplevel_management, ToplevelManagementHandler, ToplevelManagementState,
|
||||
},
|
||||
};
|
||||
|
||||
impl ToplevelManagementHandler for State {
|
||||
fn toplevel_management_state(&mut self) -> &mut ToplevelManagementState {
|
||||
&mut self.common.shell.toplevel_management_state
|
||||
}
|
||||
|
||||
fn activate(&mut self, dh: &DisplayHandle, window: &Window, seat: Option<Seat<Self>>) {
|
||||
if let Some(idx) = self.common.shell.space_for_window(window.toplevel().wl_surface()).map(|w| w.idx) {
|
||||
let seat = seat.unwrap_or(self.common.last_active_seat.clone());
|
||||
let output = active_output(&seat, &self.common);
|
||||
if self.common.shell.active_space(&output).idx != idx {
|
||||
self.common.shell.activate(&seat, &output, idx as usize);
|
||||
}
|
||||
self.common.set_focus(
|
||||
dh,
|
||||
Some(window.toplevel().wl_surface()),
|
||||
&seat,
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn close(&mut self, _dh: &DisplayHandle, window: &Window) {
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
if let Kind::Xdg(xdg) = &window.toplevel() {
|
||||
xdg.send_close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delegate_toplevel_management!(State);
|
||||
|
|
@ -3,4 +3,5 @@
|
|||
pub mod drm;
|
||||
pub mod output_configuration;
|
||||
pub mod toplevel_info;
|
||||
pub mod toplevel_management;
|
||||
pub mod workspace;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use std::sync::Mutex;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::Mutex,
|
||||
};
|
||||
|
||||
use smithay::{
|
||||
desktop::Window,
|
||||
|
|
@ -8,11 +11,12 @@ use smithay::{
|
|||
wayland_protocols::xdg::shell::server::xdg_toplevel,
|
||||
wayland_server::{
|
||||
backend::{ClientId, GlobalId, ObjectId},
|
||||
protocol::wl_surface::WlSurface,
|
||||
Client, DataInit, Dispatch, DisplayHandle,
|
||||
GlobalDispatch, New, Resource,
|
||||
},
|
||||
},
|
||||
utils::IsAlive,
|
||||
utils::{IsAlive, Rectangle, Logical},
|
||||
wayland::{
|
||||
compositor::with_states, output::Output, shell::xdg::XdgToplevelSurfaceRoleAttributes,
|
||||
},
|
||||
|
|
@ -27,7 +31,7 @@ use cosmic_protocols::toplevel_info::v1::server::{
|
|||
|
||||
pub struct ToplevelInfoState<D> {
|
||||
dh: DisplayHandle,
|
||||
toplevels: Vec<Window>,
|
||||
pub(super) toplevels: Vec<Window>,
|
||||
instances: Vec<ZcosmicToplevelInfoV1>,
|
||||
global: GlobalId,
|
||||
_dispatch_data: std::marker::PhantomData<D>,
|
||||
|
|
@ -43,24 +47,40 @@ pub struct ToplevelInfoGlobalData {
|
|||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ToplevelStateInner {
|
||||
pub(super) struct ToplevelStateInner {
|
||||
instances: Vec<ZcosmicToplevelHandleV1>,
|
||||
outputs: Vec<Output>,
|
||||
workspaces: Vec<WorkspaceHandle>,
|
||||
minimized: bool,
|
||||
pub(super) rectangles: HashMap<ClientId, (WlSurface, Rectangle<i32, Logical>)>,
|
||||
}
|
||||
type ToplevelState = Mutex<ToplevelStateInner>;
|
||||
pub(super) type ToplevelState = Mutex<ToplevelStateInner>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ToplevelHandleStateInner {
|
||||
outputs: Vec<Output>,
|
||||
workspaces: Vec<WorkspaceHandle>,
|
||||
title: String,
|
||||
app_id: String,
|
||||
states: Vec<States>,
|
||||
pub(super) window: Window,
|
||||
}
|
||||
pub type ToplevelHandleState = Mutex<ToplevelHandleStateInner>;
|
||||
|
||||
impl ToplevelHandleStateInner {
|
||||
fn from_window(window: &Window) -> ToplevelHandleState {
|
||||
ToplevelHandleState::new(
|
||||
ToplevelHandleStateInner {
|
||||
outputs: Vec::new(),
|
||||
workspaces: Vec::new(),
|
||||
title: String::new(),
|
||||
app_id: String::new(),
|
||||
states: Vec::new(),
|
||||
window: window.clone(),
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D> GlobalDispatch<ZcosmicToplevelInfoV1, ToplevelInfoGlobalData, D>
|
||||
for ToplevelInfoState<D>
|
||||
where
|
||||
|
|
@ -82,6 +102,7 @@ where
|
|||
for window in &state.toplevel_info_state().toplevels {
|
||||
send_toplevel_to_client::<D>(dh, Some(state.workspace_state()), &instance, window);
|
||||
}
|
||||
state.toplevel_info_state_mut().instances.push(instance);
|
||||
}
|
||||
|
||||
fn can_view(client: Client, global_data: &ToplevelInfoGlobalData) -> bool {
|
||||
|
|
@ -229,18 +250,21 @@ where
|
|||
|
||||
pub fn refresh(&mut self, workspace_state: Option<&WorkspaceState<D>>) {
|
||||
self.toplevels.retain(|window| {
|
||||
let mut state = window
|
||||
.user_data()
|
||||
.get::<ToplevelState>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
state.rectangles
|
||||
.retain(|_, (surface, _)| surface.alive());
|
||||
if window.alive() {
|
||||
std::mem::drop(state);
|
||||
for instance in &self.instances {
|
||||
send_toplevel_to_client::<D>(&self.dh, workspace_state, instance, window);
|
||||
}
|
||||
true
|
||||
} else {
|
||||
let state = window
|
||||
.user_data()
|
||||
.get::<ToplevelState>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
for handle in &state.instances {
|
||||
// don't send events to stopped instances
|
||||
if self
|
||||
|
|
@ -291,7 +315,7 @@ fn send_toplevel_to_client<D>(
|
|||
.create_resource::<ZcosmicToplevelHandleV1, _, D>(
|
||||
dh,
|
||||
info.version(),
|
||||
ToplevelHandleState::default(),
|
||||
ToplevelHandleStateInner::from_window(window),
|
||||
)
|
||||
{
|
||||
state.instances.push(toplevel_handle);
|
||||
|
|
@ -448,6 +472,16 @@ fn send_toplevel_to_client<D>(
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn window_from_handle(handle: ZcosmicToplevelHandleV1) -> Window {
|
||||
handle
|
||||
.data::<ToplevelHandleState>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.window
|
||||
.clone()
|
||||
}
|
||||
|
||||
macro_rules! delegate_toplevel_info {
|
||||
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
|
||||
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
|
||||
|
|
|
|||
219
src/wayland/protocols/toplevel_management.rs
Normal file
219
src/wayland/protocols/toplevel_management.rs
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use smithay::{
|
||||
desktop::Window,
|
||||
reexports::{
|
||||
wayland_server::{
|
||||
backend::{ClientId, GlobalId, ObjectId},
|
||||
protocol::wl_surface::WlSurface,
|
||||
Client, DataInit, Dispatch, DisplayHandle,
|
||||
GlobalDispatch, New, Resource,
|
||||
},
|
||||
},
|
||||
utils::{Logical, Rectangle},
|
||||
wayland::{
|
||||
output::Output,
|
||||
seat::Seat,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
use cosmic_protocols::toplevel_management::v1::server::{
|
||||
zcosmic_toplevel_manager_v1::{self, ZcosmicToplevelManagerV1},
|
||||
};
|
||||
pub use cosmic_protocols::toplevel_management::v1::server::zcosmic_toplevel_manager_v1::ZcosmicToplelevelManagementCapabilitiesV1 as ManagementCapabilities;
|
||||
|
||||
use super::toplevel_info::{ToplevelInfoHandler, ToplevelHandleState, ToplevelState, window_from_handle};
|
||||
|
||||
|
||||
pub struct ToplevelManagementState {
|
||||
instances: Vec<ZcosmicToplevelManagerV1>,
|
||||
capabilities: Vec<ManagementCapabilities>,
|
||||
global: GlobalId,
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub trait ToplevelManagementHandler: ToplevelInfoHandler {
|
||||
fn toplevel_management_state(&mut self) -> &mut ToplevelManagementState;
|
||||
|
||||
fn activate(&mut self, dh: &DisplayHandle, window: &Window, seat: Option<Seat<Self>>) {}
|
||||
fn close(&mut self, dh: &DisplayHandle, window: &Window) {}
|
||||
|
||||
fn fullscreen(&mut self, dh: &DisplayHandle, window: &Window, output: Option<Output>) {}
|
||||
fn unfullscreen(&mut self, dh: &DisplayHandle, window: &Window) {}
|
||||
fn maximize(&mut self, dh: &DisplayHandle, window: &Window) {}
|
||||
fn unmaximize(&mut self, dh: &DisplayHandle, window: &Window) {}
|
||||
fn minimize(&mut self, dh: &DisplayHandle, window: &Window) {}
|
||||
fn unminimize(&mut self, dh: &DisplayHandle, window: &Window) {}
|
||||
}
|
||||
|
||||
pub struct ToplevelManagerGlobalData {
|
||||
filter: Box<dyn for<'a> Fn(&'a Client) -> bool + Send + Sync>,
|
||||
}
|
||||
|
||||
impl ToplevelManagementState {
|
||||
pub fn new<D, F>(dh: &DisplayHandle, capabilities: Vec<ManagementCapabilities>, client_filter: F) -> ToplevelManagementState
|
||||
where
|
||||
D: GlobalDispatch<ZcosmicToplevelManagerV1, ToplevelManagerGlobalData>
|
||||
+ Dispatch<ZcosmicToplevelManagerV1, ()>
|
||||
+ ToplevelManagementHandler
|
||||
+ 'static,
|
||||
F: for<'a> Fn(&'a Client) -> bool + Send + Sync + 'static
|
||||
{
|
||||
let global = dh.create_global::<D, ZcosmicToplevelManagerV1, _>(
|
||||
1,
|
||||
ToplevelManagerGlobalData {
|
||||
filter: Box::new(client_filter),
|
||||
},
|
||||
);
|
||||
ToplevelManagementState {
|
||||
capabilities,
|
||||
instances: Vec::new(),
|
||||
global,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rectangle_for(&mut self, window: &Window, client: &ClientId) -> Option<(WlSurface, Rectangle<i32, Logical>)> {
|
||||
if let Some(state) = window.user_data().get::<ToplevelState>() {
|
||||
state.lock().unwrap().rectangles.get(client).cloned()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn global_id(&self) -> GlobalId {
|
||||
self.global.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D> GlobalDispatch<ZcosmicToplevelManagerV1, ToplevelManagerGlobalData, D> for ToplevelManagementState
|
||||
where
|
||||
D: GlobalDispatch<ZcosmicToplevelManagerV1, ToplevelManagerGlobalData>
|
||||
+ Dispatch<ZcosmicToplevelManagerV1, ()>
|
||||
+ ToplevelManagementHandler
|
||||
+ 'static
|
||||
{
|
||||
fn bind(
|
||||
state: &mut D,
|
||||
_dh: &DisplayHandle,
|
||||
_client: &Client,
|
||||
resource: New<ZcosmicToplevelManagerV1>,
|
||||
_global_data: &ToplevelManagerGlobalData,
|
||||
data_init: &mut DataInit<'_, D>,
|
||||
) {
|
||||
let instance = data_init.init(resource, ());
|
||||
let capabilities = {
|
||||
let mut caps = state.toplevel_management_state().capabilities.clone();
|
||||
let ratio = std::mem::size_of::<ManagementCapabilities>() / std::mem::size_of::<u8>();
|
||||
let ptr = caps.as_mut_ptr() as *mut u8;
|
||||
let len = caps.len() * ratio;
|
||||
let cap = caps.capacity() * ratio;
|
||||
std::mem::forget(caps);
|
||||
unsafe { Vec::from_raw_parts(ptr, len, cap) }
|
||||
};
|
||||
instance.capabilities(capabilities);
|
||||
state.toplevel_management_state().instances.push(instance);
|
||||
}
|
||||
|
||||
fn can_view(client: Client, global_data: &ToplevelManagerGlobalData) -> bool {
|
||||
(global_data.filter)(&client)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<D> Dispatch<ZcosmicToplevelManagerV1, (), D> for ToplevelManagementState
|
||||
where
|
||||
D: GlobalDispatch<ZcosmicToplevelManagerV1, ToplevelManagerGlobalData>
|
||||
+ Dispatch<ZcosmicToplevelManagerV1, ()>
|
||||
+ ToplevelManagementHandler
|
||||
+ 'static
|
||||
{
|
||||
fn request(
|
||||
state: &mut D,
|
||||
_client: &Client,
|
||||
_obj: &ZcosmicToplevelManagerV1,
|
||||
request: zcosmic_toplevel_manager_v1::Request,
|
||||
_data: &(),
|
||||
dh: &DisplayHandle,
|
||||
_data_init: &mut DataInit<'_, D>,
|
||||
) {
|
||||
match request {
|
||||
zcosmic_toplevel_manager_v1::Request::Activate { toplevel, seat } => {
|
||||
let window = window_from_handle(toplevel);
|
||||
state.activate(dh, &window, Seat::from_resource(&seat));
|
||||
},
|
||||
zcosmic_toplevel_manager_v1::Request::Close { toplevel } => {
|
||||
let window = window_from_handle(toplevel);
|
||||
state.close(dh, &window);
|
||||
},
|
||||
zcosmic_toplevel_manager_v1::Request::SetFullscreen { toplevel, output } => {
|
||||
let window = window_from_handle(toplevel);
|
||||
state.fullscreen(dh, &window, output.as_ref().and_then(Output::from_resource))
|
||||
},
|
||||
zcosmic_toplevel_manager_v1::Request::UnsetFullscreen { toplevel } => {
|
||||
let window = window_from_handle(toplevel);
|
||||
state.unfullscreen(dh, &window);
|
||||
},
|
||||
zcosmic_toplevel_manager_v1::Request::SetMaximized { toplevel } => {
|
||||
let window = window_from_handle(toplevel);
|
||||
state.maximize(dh, &window);
|
||||
},
|
||||
zcosmic_toplevel_manager_v1::Request::UnsetMaximized { toplevel } => {
|
||||
let window = window_from_handle(toplevel);
|
||||
state.unmaximize(dh, &window);
|
||||
},
|
||||
zcosmic_toplevel_manager_v1::Request::SetMinimized { toplevel } => {
|
||||
let window = window_from_handle(toplevel);
|
||||
state.minimize(dh, &window);
|
||||
},
|
||||
zcosmic_toplevel_manager_v1::Request::UnsetMinimized { toplevel } => {
|
||||
let window = window_from_handle(toplevel);
|
||||
state.unminimize(dh, &window);
|
||||
},
|
||||
zcosmic_toplevel_manager_v1::Request::SetRectangle { toplevel, surface, x, y, width, height } => {
|
||||
let window = toplevel
|
||||
.data::<ToplevelHandleState>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.window
|
||||
.clone();
|
||||
if let Some(toplevel_state) = window.user_data().get::<ToplevelState>() {
|
||||
let mut toplevel_state = toplevel_state.lock().unwrap();
|
||||
if let Some(client) = surface.client_id() {
|
||||
if width == 0 && height == 0 {
|
||||
toplevel_state.rectangles.remove(&client);
|
||||
} else {
|
||||
toplevel_state.rectangles.insert(client, (surface, Rectangle::from_loc_and_size((x, y), (width, height))));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn destroyed(state: &mut D, client: ClientId, resource: ObjectId, _data: &()) {
|
||||
let mng_state = state.toplevel_management_state();
|
||||
mng_state.instances.retain(|i| i.id() != resource);
|
||||
if !mng_state.instances.iter().any(|i| i.client_id().map(|c| c == client).unwrap_or(false)) {
|
||||
for toplevel in state.toplevel_info_state_mut().toplevels.iter() {
|
||||
if let Some(toplevel_state) = toplevel.user_data().get::<ToplevelState>() {
|
||||
toplevel_state.lock().unwrap().rectangles.remove(&client);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! delegate_toplevel_management {
|
||||
($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
|
||||
smithay::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
|
||||
cosmic_protocols::toplevel_management::v1::server::zcosmic_toplevel_manager_v1::ZcosmicToplevelManagerV1: $crate::wayland::protocols::toplevel_management::ToplevelManagerGlobalData
|
||||
] => $crate::wayland::protocols::toplevel_management::ToplevelManagementState);
|
||||
smithay::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
|
||||
cosmic_protocols::toplevel_management::v1::server::zcosmic_toplevel_manager_v1::ZcosmicToplevelManagerV1: ()
|
||||
] => $crate::wayland::protocols::toplevel_management::ToplevelManagementState);
|
||||
};
|
||||
}
|
||||
pub(crate) use delegate_toplevel_management;
|
||||
Loading…
Add table
Add a link
Reference in a new issue