cosmic-comp/src/shell/workspace.rs

210 lines
6.8 KiB
Rust
Raw Normal View History

use crate::{
2022-07-04 16:00:29 +02:00
shell::layout::{floating::FloatingLayout, tiling::TilingLayout},
state::State,
wayland::protocols::workspace::WorkspaceHandle,
};
2022-03-24 20:32:31 +01:00
use smithay::{
desktop::{Kind, Space, Window},
reexports::{
wayland_protocols::xdg::shell::server::xdg_toplevel::{self, ResizeEdge},
wayland_server::DisplayHandle,
},
2022-07-04 16:00:29 +02:00
utils::IsAlive,
2022-03-24 20:32:31 +01:00
wayland::{
output::Output,
seat::{PointerGrabStartData, Seat},
Serial,
},
};
use std::collections::HashMap;
2022-03-30 22:00:44 +02:00
2022-03-24 20:32:31 +01:00
pub struct Workspace {
2022-03-30 22:11:29 +02:00
pub(super) idx: u8,
2022-03-24 20:32:31 +01:00
pub space: Space,
pub tiling_layer: TilingLayout,
pub floating_layer: FloatingLayout,
2022-07-07 22:41:17 +02:00
tiling_enabled: bool,
2022-04-22 15:18:28 +02:00
pub fullscreen: HashMap<String, Window>,
pub handle: WorkspaceHandle,
2022-03-24 20:32:31 +01:00
}
impl Workspace {
pub fn new(idx: u8, handle: WorkspaceHandle) -> Workspace {
2022-03-24 20:32:31 +01:00
Workspace {
2022-03-30 22:00:44 +02:00
idx,
2022-03-24 20:32:31 +01:00
space: Space::new(None),
tiling_layer: TilingLayout::new(),
floating_layer: FloatingLayout::new(),
2022-07-07 22:41:17 +02:00
tiling_enabled: true,
2022-04-22 15:18:28 +02:00
fullscreen: HashMap::new(),
handle,
2022-03-24 20:32:31 +01:00
}
}
pub fn refresh(&mut self, dh: &DisplayHandle) {
2022-04-22 15:18:28 +02:00
let outputs = self.space.outputs().collect::<Vec<_>>();
2022-05-03 13:37:51 +02:00
let dead_output_windows = self
.fullscreen
2022-04-22 15:18:28 +02:00
.iter()
2022-05-03 13:37:51 +02:00
.filter(|(name, _)| !outputs.iter().any(|o| o.name() == **name))
2022-04-22 15:18:28 +02:00
.map(|(_, w)| w)
.cloned()
.collect::<Vec<_>>();
for window in dead_output_windows {
self.unfullscreen_request(&window);
}
self.fullscreen.retain(|_, w| w.alive());
self.floating_layer.refresh(&mut self.space);
self.tiling_layer.refresh(&mut self.space);
self.space.refresh(dh);
}
2022-03-24 20:32:31 +01:00
pub fn maximize_request(&mut self, window: &Window, output: &Output) {
2022-04-22 15:18:28 +02:00
if self.fullscreen.values().any(|w| w == window) {
return;
}
if self.floating_layer.windows.contains(window) {
2022-07-04 16:00:29 +02:00
self.floating_layer
.maximize_request(&mut self.space, window, output);
}
2022-03-24 20:32:31 +01:00
}
pub fn move_request(
&mut self,
window: &Window,
seat: &Seat<State>,
2022-03-24 20:32:31 +01:00
serial: Serial,
start_data: PointerGrabStartData,
) {
2022-04-22 15:18:28 +02:00
if self.fullscreen.values().any(|w| w == window) {
return;
}
if self.floating_layer.windows.contains(window) {
2022-07-04 16:00:29 +02:00
self.floating_layer
.move_request(&mut self.space, window, seat, serial, start_data)
}
2022-03-24 20:32:31 +01:00
}
pub fn resize_request(
&mut self,
window: &Window,
seat: &Seat<State>,
2022-03-24 20:32:31 +01:00
serial: Serial,
start_data: PointerGrabStartData,
edges: ResizeEdge,
) {
2022-04-22 15:18:28 +02:00
if self.fullscreen.values().any(|w| w == window) {
return;
}
if self.floating_layer.windows.contains(window) {
2022-07-04 16:00:29 +02:00
self.floating_layer.resize_request(
&mut self.space,
window,
seat,
serial,
start_data.clone(),
edges,
)
}
if self.tiling_layer.windows.contains(window) {
2022-07-04 16:00:29 +02:00
self.tiling_layer.resize_request(
&mut self.space,
window,
seat,
serial,
start_data,
edges,
)
}
2022-03-24 20:32:31 +01:00
}
2022-04-22 15:18:28 +02:00
pub fn fullscreen_request(&mut self, window: &Window, output: &Output) {
if self.fullscreen.contains_key(&output.name()) {
return;
}
#[allow(irrefutable_let_patterns)]
if let Kind::Xdg(xdg) = &window.toplevel() {
xdg.with_pending_state(|state| {
state.states.set(xdg_toplevel::State::Fullscreen);
state.size = Some(
output
.current_mode()
.map(|m| m.size)
.unwrap_or((0, 0).into())
.to_f64()
.to_logical(output.current_scale().fractional_scale())
.to_i32_round(),
);
});
xdg.send_configure();
self.fullscreen.insert(output.name(), window.clone());
2022-04-22 15:18:28 +02:00
}
}
2022-05-03 13:37:51 +02:00
2022-04-22 15:18:28 +02:00
pub fn unfullscreen_request(&mut self, window: &Window) {
if self.fullscreen.values().any(|w| w == window) {
#[allow(irrefutable_let_patterns)]
if let Kind::Xdg(xdg) = &window.toplevel() {
xdg.with_pending_state(|state| {
state.states.unset(xdg_toplevel::State::Fullscreen);
state.size = None;
});
self.floating_layer.refresh(&mut self.space);
self.tiling_layer.refresh(&mut self.space);
xdg.send_configure();
2022-04-22 15:18:28 +02:00
}
self.fullscreen.retain(|_, w| w != window);
}
}
pub fn fullscreen_toggle(&mut self, window: &Window, output: &Output) {
if self.fullscreen.contains_key(&output.name()) {
self.unfullscreen_request(window)
} else {
self.fullscreen_request(window, output)
}
}
pub fn get_fullscreen(&self, output: &Output) -> Option<&Window> {
if !self.space.outputs().any(|o| o == output) {
return None;
}
2022-07-04 16:00:29 +02:00
self.fullscreen.get(&output.name()).filter(|w| w.alive())
2022-04-22 15:18:28 +02:00
}
2022-07-07 22:41:17 +02:00
pub fn toggle_tiling(&mut self, seat: &Seat<State>) {
if self.tiling_enabled {
for window in self.tiling_layer.windows.clone().into_iter() {
self.tiling_layer.unmap_window(&mut self.space, &window);
self.floating_layer.map_window(&mut self.space, window, seat);
}
self.tiling_enabled = false;
} else {
let focus_stack = self.focus_stack(seat);
for window in self.floating_layer.windows.clone().into_iter() {
self.floating_layer.unmap_window(&mut self.space, &window);
self.tiling_layer.map_window(&mut self.space, window, seat, focus_stack.iter())
}
self.tiling_enabled = true;
}
}
pub fn toggle_floating_window(&mut self, seat: &Seat<State>) {
if self.tiling_enabled {
if let Some(window) = self.focus_stack(seat).iter().next().cloned() {
if self.tiling_layer.windows.contains(&window) {
self.tiling_layer.unmap_window(&mut self.space, &window);
self.floating_layer.map_window(&mut self.space, window, seat);
} else if self.floating_layer.windows.contains(&window) {
let focus_stack = self.focus_stack(seat);
self.floating_layer.unmap_window(&mut self.space, &window);
self.tiling_layer.map_window(&mut self.space, window, seat, focus_stack.iter())
}
}
}
}
2022-03-24 20:32:31 +01:00
}