Add window rules

This commit is contained in:
Ottatop 2023-10-19 20:43:35 -05:00
parent 9da918bc40
commit 8fd50eff5a
4 changed files with 145 additions and 44 deletions

View file

@ -15,6 +15,7 @@ pub use input::MouseButton;
pub use input::MouseEdge; pub use input::MouseEdge;
use output::Output; use output::Output;
use tag::Tag; use tag::Tag;
use window::rules::WindowRules;
use window::Window; use window::Window;
pub use xkbcommon::xkb::keysyms; pub use xkbcommon::xkb::keysyms;
pub use xkbcommon::xkb::Keysym; pub use xkbcommon::xkb::Keysym;
@ -53,7 +54,7 @@ pub fn setup(config_func: impl FnOnce(Pinnacle)) -> anyhow::Result<()> {
let pinnacle = Pinnacle { let pinnacle = Pinnacle {
process: Process, process: Process,
input: Input, input: Input,
window: Window, window: Window { rules: WindowRules },
output: Output, output: Output,
tag: Tag, tag: Tag,
}; };

View file

@ -10,6 +10,48 @@ use crate::{
#[derive(Debug, Hash, PartialEq, Eq, serde::Serialize, serde::Deserialize, Clone, Copy)] #[derive(Debug, Hash, PartialEq, Eq, serde::Serialize, serde::Deserialize, Clone, Copy)]
pub struct CallbackId(pub u32); pub struct CallbackId(pub u32);
#[derive(Default, Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct WindowRuleCondition {
/// This condition is met when any of the conditions provided is met.
#[serde(default)]
pub cond_any: Option<Vec<WindowRuleCondition>>,
/// This condition is met when all of the conditions provided are met.
#[serde(default)]
pub cond_all: Option<Vec<WindowRuleCondition>>,
/// This condition is met when the class matches.
#[serde(default)]
pub class: Option<Vec<String>>,
/// This condition is met when the title matches.
#[serde(default)]
pub title: Option<Vec<String>>,
/// This condition is met when the tag matches.
#[serde(default)]
pub tag: Option<Vec<TagId>>,
}
#[derive(Default, Debug, Clone, PartialEq, Eq, serde::Serialize)]
pub struct WindowRule {
/// Set the output the window will open on.
#[serde(default)]
pub output: Option<OutputName>,
/// Set the tags the output will have on open.
#[serde(default)]
pub tags: Option<Vec<TagId>>,
/// Set the window to floating or tiled on open.
#[serde(default)]
pub floating_or_tiled: Option<FloatingOrTiled>,
/// Set the window to fullscreen, maximized, or force it to neither.
#[serde(default)]
pub fullscreen_or_maximized: Option<FullscreenOrMaximized>,
/// Set the window's initial size.
#[serde(default)]
pub size: Option<(NonZeroU32, NonZeroU32)>,
/// Set the window's initial location. If the window is tiled, it will snap to this position
/// when set to floating.
#[serde(default)]
pub location: Option<(i32, i32)>,
}
#[derive(Debug, PartialEq, Copy, Clone, serde::Serialize)] #[derive(Debug, PartialEq, Copy, Clone, serde::Serialize)]
pub enum AccelProfile { pub enum AccelProfile {
Flat, Flat,
@ -58,48 +100,6 @@ pub enum LibinputSetting {
#[derive(Debug, Hash, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[derive(Debug, Hash, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct RequestId(pub u32); pub struct RequestId(pub u32);
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct WindowRuleCondition {
/// This condition is met when any of the conditions provided is met.
#[serde(default)]
cond_any: Option<Vec<WindowRuleCondition>>,
/// This condition is met when all of the conditions provided are met.
#[serde(default)]
cond_all: Option<Vec<WindowRuleCondition>>,
/// This condition is met when the class matches.
#[serde(default)]
class: Option<Vec<String>>,
/// This condition is met when the title matches.
#[serde(default)]
title: Option<Vec<String>>,
/// This condition is met when the tag matches.
#[serde(default)]
tag: Option<Vec<TagId>>,
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
pub struct WindowRule {
/// Set the output the window will open on.
#[serde(default)]
pub output: Option<OutputName>,
/// Set the tags the output will have on open.
#[serde(default)]
pub tags: Option<Vec<TagId>>,
/// Set the window to floating or tiled on open.
#[serde(default)]
pub floating_or_tiled: Option<FloatingOrTiled>,
/// Set the window to fullscreen, maximized, or force it to neither.
#[serde(default)]
pub fullscreen_or_maximized: Option<FullscreenOrMaximized>,
/// Set the window's initial size.
#[serde(default)]
pub size: Option<(NonZeroU32, NonZeroU32)>,
/// Set the window's initial location. If the window is tiled, it will snap to this position
/// when set to floating.
#[serde(default)]
pub location: Option<(i32, i32)>,
}
#[derive(Debug, serde::Serialize)] #[derive(Debug, serde::Serialize)]
pub(crate) enum Msg { pub(crate) enum Msg {
// Input // Input

View file

@ -1,3 +1,5 @@
pub mod rules;
use crate::{ use crate::{
msg::{Msg, Request, RequestResponse}, msg::{Msg, Request, RequestResponse},
request, send_msg, request, send_msg,
@ -5,6 +7,8 @@ use crate::{
MouseButton, MouseButton,
}; };
use self::rules::WindowRules;
/// A unique identifier for each window. /// A unique identifier for each window.
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum WindowId { pub enum WindowId {
@ -15,7 +19,9 @@ pub enum WindowId {
Some(u32), Some(u32),
} }
pub struct Window; pub struct Window {
pub rules: WindowRules,
}
impl Window { impl Window {
pub fn get_by_class<'a>(&self, class: &'a str) -> impl Iterator<Item = WindowHandle> + 'a { pub fn get_by_class<'a>(&self, class: &'a str) -> impl Iterator<Item = WindowHandle> + 'a {

View file

@ -0,0 +1,94 @@
use std::num::NonZeroU32;
use crate::{msg::Msg, output::OutputHandle, send_msg, tag::TagHandle};
use super::{FloatingOrTiled, FullscreenOrMaximized};
pub struct WindowRules;
impl WindowRules {
pub fn add(&self, cond: WindowRuleCondition, rule: WindowRule) {
let msg = Msg::AddWindowRule {
cond: cond.0,
rule: rule.0,
};
send_msg(msg).unwrap();
}
}
#[derive(Default)]
pub struct WindowRule(crate::msg::WindowRule);
impl WindowRule {
pub fn new() -> Self {
Default::default()
}
pub fn output(mut self, output: &OutputHandle) -> Self {
self.0.output = Some(output.0.clone());
self
}
pub fn tags(mut self, tags: &[TagHandle]) -> Self {
self.0.tags = Some(tags.iter().map(|tag| tag.0).collect());
self
}
pub fn floating_or_tiled(mut self, floating_or_tiled: FloatingOrTiled) -> Self {
self.0.floating_or_tiled = Some(floating_or_tiled);
self
}
pub fn fullscreen_or_maximized(
mut self,
fullscreen_or_maximized: FullscreenOrMaximized,
) -> Self {
self.0.fullscreen_or_maximized = Some(fullscreen_or_maximized);
self
}
pub fn size(mut self, width: NonZeroU32, height: NonZeroU32) -> Self {
self.0.size = Some((width, height));
self
}
pub fn location(mut self, x: i32, y: i32) -> Self {
self.0.location = Some((x, y));
self
}
}
#[derive(Default, Debug)]
pub struct WindowRuleCondition(crate::msg::WindowRuleCondition);
impl WindowRuleCondition {
pub fn new() -> Self {
Default::default()
}
pub fn any(mut self, conds: &[WindowRuleCondition]) -> Self {
self.0.cond_any = Some(conds.iter().map(|cond| cond.0.clone()).collect());
self
}
pub fn all(mut self, conds: &[WindowRuleCondition]) -> Self {
self.0.cond_all = Some(conds.iter().map(|cond| cond.0.clone()).collect());
self
}
pub fn class(mut self, classes: &[&str]) -> Self {
self.0.class = Some(classes.iter().map(|s| s.to_string()).collect());
self
}
pub fn title(mut self, titles: &[&str]) -> Self {
self.0.title = Some(titles.iter().map(|s| s.to_string()).collect());
self
}
pub fn tag(mut self, tags: &[TagHandle]) -> Self {
self.0.tag = Some(tags.iter().map(|tag| tag.0).collect());
self
}
}