tiling: Better heuristic

This commit is contained in:
Victoria Brekenfeld 2022-03-30 16:27:39 +02:00
parent 3ebeab17b7
commit d132722bd0
2 changed files with 53 additions and 51 deletions

View file

@ -3,13 +3,10 @@ use smithay::{
desktop::{Space, Window}, desktop::{Space, Window},
reexports::wayland_protocols::xdg_shell::server::xdg_toplevel::ResizeEdge, reexports::wayland_protocols::xdg_shell::server::xdg_toplevel::ResizeEdge,
wayland::{ wayland::{
compositor::with_states,
seat::{PointerGrabStartData, Seat}, seat::{PointerGrabStartData, Seat},
shell::xdg::XdgToplevelSurfaceRoleAttributes,
Serial, Serial,
}, },
}; };
use std::sync::Mutex;
struct Filtered; struct Filtered;
@ -18,15 +15,11 @@ pub struct Combined<A: Layout, B: Layout> {
second: B, second: B,
windows_a: Vec<Window>, windows_a: Vec<Window>,
windows_b: Vec<Window>, windows_b: Vec<Window>,
filter: Box<dyn Fn(Option<&str>, Option<&str>) -> bool>, filter: Box<dyn Fn(&Window) -> bool>,
} }
impl<A: Layout, B: Layout> Combined<A, B> { impl<A: Layout, B: Layout> Combined<A, B> {
pub fn new( pub fn new(first: A, second: B, filter: impl Fn(&Window) -> bool + 'static) -> Combined<A, B> {
first: A,
second: B,
filter: impl Fn(Option<&str>, Option<&str>) -> bool + 'static,
) -> Combined<A, B> {
Combined { Combined {
first, first,
second, second,
@ -45,40 +38,23 @@ impl<A: Layout, B: Layout> Layout for Combined<A, B> {
seat: &Seat, seat: &Seat,
focus_stack: Box<dyn Iterator<Item = &'a Window> + 'a>, focus_stack: Box<dyn Iterator<Item = &'a Window> + 'a>,
) { ) {
if let Some(surface) = window.toplevel().get_surface() { if (self.filter)(window) {
let filtered = with_states(surface, |states| { self.windows_b.push(window.clone());
let attrs = states self.second.map_window(
.data_map space,
.get::<Mutex<XdgToplevelSurfaceRoleAttributes>>() window,
.unwrap() seat,
.lock() Box::new(focus_stack.filter(|w| w.user_data().get::<Filtered>().is_some())),
.unwrap(); )
if (self.filter)(attrs.app_id.as_deref(), attrs.title.as_deref()) { } else {
window.user_data().insert_if_missing(|| Filtered); self.windows_a.push(window.clone());
true self.first.map_window(
} else { space,
false window,
} seat,
}) Box::new(focus_stack.filter(|w| w.user_data().get::<Filtered>().is_none())),
.unwrap_or(false); )
if filtered {
self.windows_b.push(window.clone());
return self.second.map_window(
space,
window,
seat,
Box::new(focus_stack.filter(|w| w.user_data().get::<Filtered>().is_some())),
);
}
} }
self.windows_a.push(window.clone());
return self.first.map_window(
space,
window,
seat,
Box::new(focus_stack.filter(|w| w.user_data().get::<Filtered>().is_none())),
);
} }
fn refresh(&mut self, space: &mut Space) { fn refresh(&mut self, space: &mut Space) {

View file

@ -4,11 +4,14 @@ use smithay::{
desktop::{Space, Window}, desktop::{Space, Window},
reexports::wayland_protocols::xdg_shell::server::xdg_toplevel::ResizeEdge, reexports::wayland_protocols::xdg_shell::server::xdg_toplevel::ResizeEdge,
wayland::{ wayland::{
compositor::with_states,
output::Output, output::Output,
seat::{PointerGrabStartData, Seat}, seat::{PointerGrabStartData, Seat},
shell::xdg::XdgToplevelSurfaceRoleAttributes,
Serial, Serial,
}, },
}; };
use std::sync::Mutex;
pub mod combined; pub mod combined;
pub mod floating; pub mod floating;
@ -70,15 +73,38 @@ pub fn new_default_layout(idx: u8) -> Box<dyn Layout> {
Box::new(combined::Combined::new( Box::new(combined::Combined::new(
tiling::TilingLayout::new(idx), tiling::TilingLayout::new(idx),
floating::FloatingLayout, floating::FloatingLayout,
|app_id, title| { |window| {
slog_scope::debug!( if let Some(surface) = window.toplevel().get_surface() {
"New filter input: ({}:{})", with_states(surface, |states| {
app_id.unwrap_or("<unknown>"), let attrs = states
title.unwrap_or("<no title>") .data_map
); .get::<Mutex<XdgToplevelSurfaceRoleAttributes>>()
match (app_id.unwrap_or(""), title.unwrap_or("")) { .unwrap()
("gcr-prompter", _) => true, .lock()
_ => false, .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
} }
}, },
)) ))