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},
|
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) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue