2022-03-24 20:32:31 +01:00
|
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
2022-07-04 15:28:03 +02:00
|
|
|
|
2024-04-03 16:02:27 +02:00
|
|
|
use cosmic_settings_config::shortcuts::action::Orientation;
|
2022-07-06 23:36:25 +02:00
|
|
|
use regex::RegexSet;
|
2022-03-24 20:32:31 +01:00
|
|
|
use smithay::{
|
2024-02-21 13:24:56 -08:00
|
|
|
desktop::WindowSurface,
|
2023-01-16 15:12:25 +01:00
|
|
|
wayland::{compositor::with_states, shell::xdg::XdgToplevelSurfaceData},
|
|
|
|
|
xwayland::xwm::WmWindowType,
|
2022-03-24 20:32:31 +01:00
|
|
|
};
|
2023-01-16 15:12:25 +01:00
|
|
|
|
2024-08-14 21:56:20 +03:00
|
|
|
use crate::config::Config;
|
|
|
|
|
|
2023-01-16 15:12:25 +01:00
|
|
|
use super::CosmicSurface;
|
2022-03-24 20:32:31 +01:00
|
|
|
|
|
|
|
|
pub mod floating;
|
|
|
|
|
pub mod tiling;
|
|
|
|
|
|
2024-01-08 18:09:43 +00:00
|
|
|
pub fn is_dialog(window: &CosmicSurface) -> bool {
|
2023-01-16 15:12:25 +01:00
|
|
|
// Check "window type"
|
2024-02-21 13:24:56 -08:00
|
|
|
match window.0.underlying_surface() {
|
|
|
|
|
WindowSurface::Wayland(toplevel) => {
|
|
|
|
|
if with_states(toplevel.wl_surface(), |states| {
|
2023-01-16 15:12:25 +01:00
|
|
|
let attrs = states
|
|
|
|
|
.data_map
|
|
|
|
|
.get::<XdgToplevelSurfaceData>()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.lock()
|
|
|
|
|
.unwrap();
|
|
|
|
|
attrs.parent.is_some()
|
|
|
|
|
}) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2022-07-04 15:28:03 +02:00
|
|
|
}
|
2024-02-21 13:24:56 -08:00
|
|
|
WindowSurface::X11(surface) => {
|
2023-01-16 15:12:25 +01:00
|
|
|
if surface.is_override_redirect()
|
|
|
|
|
|| surface.is_popup()
|
|
|
|
|
|| !matches!(
|
|
|
|
|
surface.window_type(),
|
|
|
|
|
None | Some(WmWindowType::Normal) | Some(WmWindowType::Utility)
|
|
|
|
|
)
|
|
|
|
|
{
|
2022-07-06 23:36:25 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
2022-07-04 15:28:03 +02:00
|
|
|
}
|
2023-01-16 15:12:25 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Check if sizing suggest dialog
|
|
|
|
|
let max_size = window.max_size();
|
|
|
|
|
let min_size = window.min_size();
|
|
|
|
|
|
|
|
|
|
if min_size.is_some() && min_size == max_size {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-08 18:09:43 +00:00
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-14 21:56:20 +03:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub struct TilingExceptions {
|
|
|
|
|
app_ids: RegexSet,
|
|
|
|
|
titles: RegexSet,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl TilingExceptions {
|
|
|
|
|
pub fn new(config: &Config) -> Self {
|
|
|
|
|
let mut app_ids = Vec::new();
|
|
|
|
|
let mut titles = Vec::new();
|
|
|
|
|
|
|
|
|
|
for app in &config.cosmic_conf.tiling_exceptions {
|
|
|
|
|
for title in &app.titles {
|
|
|
|
|
app_ids.push(app.appid.clone());
|
|
|
|
|
titles.push(title.clone());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Self {
|
|
|
|
|
app_ids: RegexSet::new(app_ids).unwrap(),
|
|
|
|
|
titles: RegexSet::new(titles).unwrap(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn has_floating_exception(exceptions: &TilingExceptions, window: &CosmicSurface) -> bool {
|
2023-01-16 15:12:25 +01:00
|
|
|
// else take a look at our exceptions
|
2024-08-14 21:56:20 +03:00
|
|
|
let appid_matches = exceptions.app_ids.matches(&window.app_id());
|
|
|
|
|
let title_matches = exceptions.titles.matches(&window.title());
|
2023-01-16 15:12:25 +01:00
|
|
|
for idx in appid_matches.into_iter() {
|
|
|
|
|
if title_matches.matched(idx) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-06 23:36:25 +02:00
|
|
|
|
2023-01-16 15:12:25 +01:00
|
|
|
false
|
2022-03-24 20:32:31 +01:00
|
|
|
}
|