mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-17 18:11:30 +01:00
Begin work on window rules
This commit is contained in:
parent
6d3c6e2c62
commit
d9ce324606
3 changed files with 110 additions and 1 deletions
|
@ -3,6 +3,8 @@
|
||||||
// The MessagePack format for these is a one-element map where the element's key is the enum name and its
|
// The MessagePack format for these is a one-element map where the element's key is the enum name and its
|
||||||
// value is a map of the enum's values
|
// value is a map of the enum's values
|
||||||
|
|
||||||
|
mod window_rules;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
output::OutputName,
|
output::OutputName,
|
||||||
|
|
107
src/api/msg/window_rules.rs
Normal file
107
src/api/msg/window_rules.rs
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
use std::num::NonZeroU32;
|
||||||
|
|
||||||
|
use smithay::wayland::{compositor, shell::xdg::XdgToplevelSurfaceData};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
output::OutputName,
|
||||||
|
state::{State, WithState},
|
||||||
|
tag::TagId,
|
||||||
|
window::{window_state::FullscreenOrMaximized, WindowElement},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub enum WindowRuleCondition {
|
||||||
|
/// This condition is met when any of the conditions provided is met.
|
||||||
|
CondAny(Vec<WindowRuleCondition>),
|
||||||
|
/// This condition is met when all of the conditions provided are met.
|
||||||
|
CondAll(Vec<WindowRuleCondition>),
|
||||||
|
/// This condition is met when the class matches.
|
||||||
|
Class(String),
|
||||||
|
/// This condition is met when the title matches.
|
||||||
|
Title(String),
|
||||||
|
/// This condition is met when the tag matches.
|
||||||
|
Tag(TagId),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowRuleCondition {
|
||||||
|
/// RefCell Safety: This method uses RefCells on `window`.
|
||||||
|
pub fn is_met(&self, state: &State, window: &WindowElement) -> bool {
|
||||||
|
match self {
|
||||||
|
WindowRuleCondition::CondAny(conds) => {
|
||||||
|
conds.iter().any(|cond| Self::is_met(cond, state, window))
|
||||||
|
}
|
||||||
|
WindowRuleCondition::CondAll(conds) => {
|
||||||
|
conds.iter().all(|cond| Self::is_met(cond, state, window))
|
||||||
|
}
|
||||||
|
WindowRuleCondition::Class(class) => {
|
||||||
|
let Some(wl_surf) = window.wl_surface() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
let current_class = compositor::with_states(&wl_surf, |states| {
|
||||||
|
states
|
||||||
|
.data_map
|
||||||
|
.get::<XdgToplevelSurfaceData>()
|
||||||
|
.expect("XdgToplevelSurfaceData wasn't in surface's data map")
|
||||||
|
.lock()
|
||||||
|
.expect("Failed to lock Mutex<XdgToplevelSurfaceData>")
|
||||||
|
.app_id
|
||||||
|
.clone()
|
||||||
|
});
|
||||||
|
|
||||||
|
current_class.as_ref() == Some(class)
|
||||||
|
}
|
||||||
|
WindowRuleCondition::Title(title) => {
|
||||||
|
let Some(wl_surf) = window.wl_surface() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
let current_title = compositor::with_states(&wl_surf, |states| {
|
||||||
|
states
|
||||||
|
.data_map
|
||||||
|
.get::<XdgToplevelSurfaceData>()
|
||||||
|
.expect("XdgToplevelSurfaceData wasn't in surface's data map")
|
||||||
|
.lock()
|
||||||
|
.expect("Failed to lock Mutex<XdgToplevelSurfaceData>")
|
||||||
|
.title
|
||||||
|
.clone()
|
||||||
|
});
|
||||||
|
|
||||||
|
current_title.as_ref() == Some(title)
|
||||||
|
}
|
||||||
|
WindowRuleCondition::Tag(tag) => {
|
||||||
|
let Some(tag) = tag.tag(state) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
window.with_state(|state| state.tags.contains(&tag))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub enum WindowRule {
|
||||||
|
/// Set the output the window will open on.
|
||||||
|
Output(OutputName),
|
||||||
|
/// Set the tags the output will have on open.
|
||||||
|
Tags(Vec<TagId>),
|
||||||
|
/// Set the window to floating or tiled on open.
|
||||||
|
FloatingOrTiled(FloatingOrTiled),
|
||||||
|
/// Set the window to fullscreen, maximized, or force it to neither.
|
||||||
|
FullscreenOrMaximized(FullscreenOrMaximized),
|
||||||
|
/// Set the window's initial size.
|
||||||
|
Size(NonZeroU32, NonZeroU32),
|
||||||
|
/// Set the window's initial location. If the window is tiled, it will snap to this position
|
||||||
|
/// when set to floating.
|
||||||
|
Location(i32, i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: just skip serializing fields on the other FloatingOrTiled
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub enum FloatingOrTiled {
|
||||||
|
Floating,
|
||||||
|
Tiled,
|
||||||
|
}
|
|
@ -301,7 +301,7 @@ impl FloatingOrTiled {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||||
pub enum FullscreenOrMaximized {
|
pub enum FullscreenOrMaximized {
|
||||||
Neither,
|
Neither,
|
||||||
Fullscreen,
|
Fullscreen,
|
||||||
|
|
Loading…
Reference in a new issue