cosmic-comp/src/shell/layout/mod.rs

142 lines
4.1 KiB
Rust
Raw Normal View History

2022-03-24 20:32:31 +01:00
// SPDX-License-Identifier: GPL-3.0-only
use crate::input::ActiveOutput;
use smithay::{
desktop::{Space, Window},
reexports::wayland_protocols::xdg_shell::server::xdg_toplevel::ResizeEdge,
wayland::{
2022-03-30 16:27:39 +02:00
compositor::with_states,
2022-03-24 20:32:31 +01:00
output::Output,
seat::{PointerGrabStartData, Seat},
2022-03-30 16:27:39 +02:00
shell::xdg::XdgToplevelSurfaceRoleAttributes,
2022-03-24 20:32:31 +01:00
Serial,
},
};
2022-03-30 16:27:39 +02:00
use std::sync::Mutex;
2022-03-24 20:32:31 +01:00
pub mod combined;
pub mod floating;
pub mod tiling;
#[derive(Debug, serde::Deserialize, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Orientation {
Horizontal,
Vertical,
}
#[derive(Debug, serde::Deserialize, Clone, Copy, PartialEq, Eq)]
pub enum FocusDirection {
Left,
Right,
Up,
Down,
}
2022-03-24 20:32:31 +01:00
pub trait Layout {
fn map_window<'a>(
&mut self,
space: &mut Space,
window: &Window,
seat: &Seat,
focus_stack: Box<dyn Iterator<Item = &'a Window> + 'a>,
); //working around object safety..
fn refresh(&mut self, space: &mut Space);
2022-03-30 22:11:29 +02:00
fn unmap_window(&mut self, space: &mut Space, window: &Window);
2022-03-24 20:32:31 +01:00
fn move_focus<'a>(
&mut self,
direction: FocusDirection,
seat: &Seat,
space: &mut Space,
focus_stack: Box<dyn Iterator<Item = &'a Window> + 'a>,
) -> Option<Window> {
let _ = (direction, seat, space, focus_stack);
None
}
fn update_orientation<'a>(
&mut self,
orientation: Orientation,
seat: &Seat,
space: &mut Space,
focus_stack: Box<dyn Iterator<Item = &'a Window> + 'a>,
) {
let _ = (orientation, seat, space, focus_stack);
}
2022-03-24 20:32:31 +01:00
fn maximize_request(&mut self, space: &mut Space, window: &Window, output: &Output) {
let _ = (space, window, output);
}
fn move_request(
&mut self,
space: &mut Space,
window: &Window,
seat: &Seat,
serial: Serial,
start_data: PointerGrabStartData,
) {
let _ = (space, window, seat, serial, start_data);
}
fn resize_request(
&mut self,
space: &mut Space,
window: &Window,
seat: &Seat,
serial: Serial,
start_data: PointerGrabStartData,
edges: ResizeEdge,
) {
let _ = (space, window, seat, serial, start_data, edges);
}
}
2022-03-29 13:24:35 +02:00
pub fn new_default_layout(idx: u8) -> Box<dyn Layout> {
2022-03-24 20:32:31 +01:00
Box::new(combined::Combined::new(
2022-03-29 13:24:35 +02:00
tiling::TilingLayout::new(idx),
2022-03-24 20:32:31 +01:00
floating::FloatingLayout,
2022-03-30 16:27:39 +02:00
|window| {
if let Some(surface) = window.toplevel().get_surface() {
with_states(surface, |states| {
let attrs = states
.data_map
.get::<Mutex<XdgToplevelSurfaceRoleAttributes>>()
.unwrap()
.lock()
.unwrap();
// simple heuristic taken from
// sway/desktop/xdg_shell.c:188 @ 0ee54a52
if attrs.parent.is_some()
|| (attrs.min_size.w != 0
&& attrs.min_size.h != 0
&& attrs.min_size == attrs.max_size)
{
return true;
}
// else take a look at our exceptions
match (
attrs.app_id.as_deref().unwrap_or(""),
attrs.title.as_deref().unwrap_or(""),
) {
("gcr-prompter", _) => true,
_ => false,
}
})
.unwrap_or(false)
} else {
false
2022-03-24 20:32:31 +01:00
}
},
))
}
fn output_from_seat(seat: &Seat, space: &Space) -> Output {
seat.user_data()
.get::<ActiveOutput>()
.map(|active| active.0.borrow().clone())
.or_else(|| {
seat.get_pointer()
.map(|ptr| space.output_under(ptr.current_location()).next().unwrap())
.cloned()
})
.unwrap_or_else(|| space.outputs().next().cloned().unwrap())
}