tiling: Better heuristic
This commit is contained in:
parent
3ebeab17b7
commit
d132722bd0
2 changed files with 53 additions and 51 deletions
|
|
@ -3,13 +3,10 @@ use smithay::{
|
|||
desktop::{Space, Window},
|
||||
reexports::wayland_protocols::xdg_shell::server::xdg_toplevel::ResizeEdge,
|
||||
wayland::{
|
||||
compositor::with_states,
|
||||
seat::{PointerGrabStartData, Seat},
|
||||
shell::xdg::XdgToplevelSurfaceRoleAttributes,
|
||||
Serial,
|
||||
},
|
||||
};
|
||||
use std::sync::Mutex;
|
||||
|
||||
struct Filtered;
|
||||
|
||||
|
|
@ -18,15 +15,11 @@ pub struct Combined<A: Layout, B: Layout> {
|
|||
second: B,
|
||||
windows_a: 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> {
|
||||
pub fn new(
|
||||
first: A,
|
||||
second: B,
|
||||
filter: impl Fn(Option<&str>, Option<&str>) -> bool + 'static,
|
||||
) -> Combined<A, B> {
|
||||
pub fn new(first: A, second: B, filter: impl Fn(&Window) -> bool + 'static) -> Combined<A, B> {
|
||||
Combined {
|
||||
first,
|
||||
second,
|
||||
|
|
@ -45,40 +38,23 @@ impl<A: Layout, B: Layout> Layout for Combined<A, B> {
|
|||
seat: &Seat,
|
||||
focus_stack: Box<dyn Iterator<Item = &'a Window> + 'a>,
|
||||
) {
|
||||
if let Some(surface) = window.toplevel().get_surface() {
|
||||
let filtered = with_states(surface, |states| {
|
||||
let attrs = states
|
||||
.data_map
|
||||
.get::<Mutex<XdgToplevelSurfaceRoleAttributes>>()
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
if (self.filter)(attrs.app_id.as_deref(), attrs.title.as_deref()) {
|
||||
window.user_data().insert_if_missing(|| Filtered);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.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())),
|
||||
);
|
||||
}
|
||||
if (self.filter)(window) {
|
||||
self.windows_b.push(window.clone());
|
||||
self.second.map_window(
|
||||
space,
|
||||
window,
|
||||
seat,
|
||||
Box::new(focus_stack.filter(|w| w.user_data().get::<Filtered>().is_some())),
|
||||
)
|
||||
} else {
|
||||
self.windows_a.push(window.clone());
|
||||
self.first.map_window(
|
||||
space,
|
||||
window,
|
||||
seat,
|
||||
Box::new(focus_stack.filter(|w| w.user_data().get::<Filtered>().is_none())),
|
||||
)
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -4,11 +4,14 @@ use smithay::{
|
|||
desktop::{Space, Window},
|
||||
reexports::wayland_protocols::xdg_shell::server::xdg_toplevel::ResizeEdge,
|
||||
wayland::{
|
||||
compositor::with_states,
|
||||
output::Output,
|
||||
seat::{PointerGrabStartData, Seat},
|
||||
shell::xdg::XdgToplevelSurfaceRoleAttributes,
|
||||
Serial,
|
||||
},
|
||||
};
|
||||
use std::sync::Mutex;
|
||||
|
||||
pub mod combined;
|
||||
pub mod floating;
|
||||
|
|
@ -70,15 +73,38 @@ pub fn new_default_layout(idx: u8) -> Box<dyn Layout> {
|
|||
Box::new(combined::Combined::new(
|
||||
tiling::TilingLayout::new(idx),
|
||||
floating::FloatingLayout,
|
||||
|app_id, title| {
|
||||
slog_scope::debug!(
|
||||
"New filter input: ({}:{})",
|
||||
app_id.unwrap_or("<unknown>"),
|
||||
title.unwrap_or("<no title>")
|
||||
);
|
||||
match (app_id.unwrap_or(""), title.unwrap_or("")) {
|
||||
("gcr-prompter", _) => true,
|
||||
_ => false,
|
||||
|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
|
||||
}
|
||||
},
|
||||
))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue