diff --git a/api/rust/examples/example_config.rs b/api/rust/examples/example_config.rs index 26b117c..5cfa167 100644 --- a/api/rust/examples/example_config.rs +++ b/api/rust/examples/example_config.rs @@ -1,22 +1,122 @@ -use pinnacle_api::{Modifier, MouseButton, MouseEdge}; +use pinnacle_api::prelude::*; fn main() { pinnacle_api::setup(|pinnacle| { - pinnacle.output.connect_for_all(move |output| { - pinnacle.tag.add(&output, &["1", "2", "3", "4", "5"]); - pinnacle.tag.get("1", Some(&output)).unwrap().toggle(); + let input = pinnacle.input; + let window = pinnacle.window; + let process = pinnacle.process; + let tag = pinnacle.tag; + let output = pinnacle.output; + + let mod_key = Modifier::Ctrl; + + let terminal = "alacritty"; + + // TODO: set env + + input.mousebind(&[mod_key], MouseButton::Left, MouseEdge::Press, move || { + window.begin_move(MouseButton::Left); }); - pinnacle.input.keybind(&[Modifier::Ctrl], 'a', move || { - pinnacle.process.spawn(vec!["alacritty"]).unwrap(); - }); - - pinnacle.input.mousebind( - &[Modifier::Ctrl], - MouseButton::Left, + input.mousebind( + &[mod_key], + MouseButton::Right, MouseEdge::Press, - || {}, + move || { + window.begin_resize(MouseButton::Right); + }, ); + + input.keybind(&[mod_key, Modifier::Alt], 'q', move || pinnacle.quit()); + + input.keybind(&[mod_key, Modifier::Alt], 'c', move || { + if let Some(window) = window.get_focused() { + window.close(); + } + }); + + input.keybind(&[mod_key], xkbcommon::xkb::keysyms::KEY_Return, move || { + process.spawn(vec![terminal]).unwrap(); + }); + + input.keybind( + &[mod_key, Modifier::Alt], + xkbcommon::xkb::keysyms::KEY_space, + move || { + if let Some(window) = window.get_focused() { + window.toggle_floating(); + } + }, + ); + + input.keybind(&[mod_key], 'f', move || { + if let Some(window) = window.get_focused() { + window.toggle_fullscreen(); + } + }); + + input.keybind(&[mod_key], 'm', move || { + if let Some(window) = window.get_focused() { + window.toggle_maximized(); + } + }); + + let tags = ["1", "2", "3", "4", "5"]; + + output.connect_for_all(move |output| { + tag.add(&output, tags.as_slice()); + tag.get("1", Some(&output)).unwrap().toggle(); + }); + + // let layout_cycler = tag.layout_cycler(&[ + // Layout::MasterStack, + // Layout::Dwindle, + // Layout::Spiral, + // Layout::CornerTopLeft, + // Layout::CornerTopRight, + // Layout::CornerBottomLeft, + // Layout::CornerBottomRight, + // ]); + // + // input.keybind(&[mod_key], xkbcommon::xkb::keysyms::KEY_space, move || { + // layout_cycler.next(None); + // }); + + for tag_name in tags.iter().map(|t| t.to_string()) { + let t = tag_name.clone(); + input.keybind(&[mod_key], tag_name.chars().next().unwrap(), move || { + println!("tag name is {t}"); + tag.get(&t, None).unwrap().switch_to(); + }); + let t = tag_name.clone(); + input.keybind( + &[mod_key, Modifier::Shift], + tag_name.chars().next().unwrap(), + move || { + tag.get(&t, None).unwrap().toggle(); + }, + ); + let t = tag_name.clone(); + input.keybind( + &[mod_key, Modifier::Alt], + tag_name.chars().next().unwrap(), + move || { + if let Some(window) = window.get_focused() { + window.move_to_tag(&tag.get(&t, None).unwrap()); + } + }, + ); + let t = tag_name.clone(); + input.keybind( + &[mod_key, Modifier::Shift, Modifier::Alt], + tag_name.chars().next().unwrap(), + move || { + if let Some(window) = window.get_focused() { + window.toggle_tag(&tag.get(&t, None).unwrap()); + } + }, + ); + } }) .unwrap(); } diff --git a/api/rust/src/input.rs b/api/rust/src/input.rs index 475b928..62ae517 100644 --- a/api/rust/src/input.rs +++ b/api/rust/src/input.rs @@ -9,7 +9,12 @@ use crate::{ use self::libinput::Libinput; +/// Input management. +#[derive(Clone, Copy)] pub struct Input { + /// Libinput settings. + /// + /// Here you can set stuff like pointer acceleration. pub libinput: Libinput, } diff --git a/api/rust/src/input/libinput.rs b/api/rust/src/input/libinput.rs index 9f2a7d3..db3ad45 100644 --- a/api/rust/src/input/libinput.rs +++ b/api/rust/src/input/libinput.rs @@ -1,5 +1,6 @@ use crate::{msg::Msg, send_msg}; +#[derive(Clone, Copy)] pub struct Libinput; impl Libinput { diff --git a/api/rust/src/lib.rs b/api/rust/src/lib.rs index 6bdc922..dc86d32 100644 --- a/api/rust/src/lib.rs +++ b/api/rust/src/lib.rs @@ -11,15 +11,45 @@ mod window; use input::libinput::Libinput; use input::Input; -pub use input::Modifier; -pub use input::MouseButton; -pub use input::MouseEdge; use output::Output; use tag::Tag; use window::rules::WindowRules; use window::Window; -pub use xkbcommon::xkb::keysyms; -pub use xkbcommon::xkb::Keysym; + +/// The xkbcommon crate, re-exported for your convenience. +pub use xkbcommon; + +/// The prelude for the Pinnacle API. +/// +/// This contains useful imports that you will likely need. +/// To that end, you can do `use pinnacle_api::prelude::*` to +/// prevent your config file from being cluttered with imports. +pub mod prelude { + pub use crate::input::Modifier; + pub use crate::input::MouseButton; + pub use crate::input::MouseEdge; + pub use crate::output::AlignmentHorizontal; + pub use crate::output::AlignmentVertical; + pub use crate::tag::Layout; + pub use crate::window::rules::WindowRule; + pub use crate::window::rules::WindowRuleCondition; + pub use crate::window::FloatingOrTiled; + pub use crate::window::FullscreenOrMaximized; +} + +/// Re-exports of every config struct. +/// +/// Usually you can just use the [`Pinnacle`][crate::Pinnacle] struct passed into +/// the `setup` function, but if you need access to these elsewhere, here they are. +pub mod modules { + pub use crate::input::libinput::Libinput; + pub use crate::input::Input; + pub use crate::output::Output; + pub use crate::process::Process; + pub use crate::tag::Tag; + pub use crate::window::rules::WindowRules; + pub use crate::window::Window; +} use std::{ collections::HashMap, @@ -181,6 +211,7 @@ fn request(request: Request) -> RequestResponse { /// The entry to configuration. /// /// This struct houses every submodule you'll need to configure Pinnacle. +#[derive(Clone, Copy)] pub struct Pinnacle { /// Process management. pub process: Process, @@ -193,3 +224,9 @@ pub struct Pinnacle { /// Tag management. pub tag: Tag, } + +impl Pinnacle { + pub fn quit(&self) { + send_msg(Msg::Quit).unwrap(); + } +} diff --git a/api/rust/src/msg.rs b/api/rust/src/msg.rs index 73b5115..e24441e 100644 --- a/api/rust/src/msg.rs +++ b/api/rust/src/msg.rs @@ -1,11 +1,10 @@ use std::num::NonZeroU32; use crate::{ - input::libinput::LibinputSetting, + input::{libinput::LibinputSetting, Modifier, MouseEdge}, output::OutputName, tag::{Layout, TagId}, window::{FloatingOrTiled, FullscreenOrMaximized, WindowId}, - Modifier, MouseEdge, }; #[derive(Debug, Hash, PartialEq, Eq, serde::Serialize, serde::Deserialize, Clone, Copy)] diff --git a/api/rust/src/output.rs b/api/rust/src/output.rs index b0d56c9..ab40f57 100644 --- a/api/rust/src/output.rs +++ b/api/rust/src/output.rs @@ -12,6 +12,7 @@ use crate::{ pub struct OutputName(pub String); /// Output management. +#[derive(Clone, Copy)] pub struct Output; impl Output { @@ -246,12 +247,14 @@ enum LeftOrRight { Right, } +#[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum AlignmentHorizontal { Left, Center, Right, } +#[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum AlignmentVertical { Top, Center, diff --git a/api/rust/src/process.rs b/api/rust/src/process.rs index 83d222d..e7aea51 100644 --- a/api/rust/src/process.rs +++ b/api/rust/src/process.rs @@ -3,6 +3,7 @@ use crate::{ send_msg, CALLBACK_VEC, }; +#[derive(Clone, Copy)] pub struct Process; impl Process { diff --git a/api/rust/src/tag.rs b/api/rust/src/tag.rs index 74466de..5c338fd 100644 --- a/api/rust/src/tag.rs +++ b/api/rust/src/tag.rs @@ -6,6 +6,7 @@ use crate::{ request, send_msg, }; +#[derive(Clone, Copy)] pub struct Tag; impl Tag { @@ -16,9 +17,10 @@ impl Tag { pub fn get(&self, name: &str, output: Option<&OutputHandle>) -> Option { self.get_all() .filter(|tag| { - tag.properties() - .output - .is_some_and(|op| Some(&op) == output) + tag.properties().output.is_some_and(|op| match output { + Some(output) => &op == output, + None => Some(op) == Output.get_focused(), + }) }) .find(|tag| tag.properties().name.is_some_and(|s| s == name)) } @@ -29,7 +31,10 @@ impl Tag { unreachable!() }; - tag_ids.into_iter().map(TagHandle) + tag_ids.into_iter().map(|t| { + println!("got tag id {t:?}"); + TagHandle(t) + }) } // TODO: return taghandles here @@ -124,6 +129,7 @@ pub enum TagId { pub struct TagHandle(pub TagId); +#[derive(Debug)] pub struct TagProperties { active: Option, name: Option, diff --git a/api/rust/src/window.rs b/api/rust/src/window.rs index d27b562..8ea195a 100644 --- a/api/rust/src/window.rs +++ b/api/rust/src/window.rs @@ -1,10 +1,10 @@ pub mod rules; use crate::{ + input::MouseButton, msg::{Msg, Request, RequestResponse}, request, send_msg, tag::TagHandle, - MouseButton, }; use self::rules::WindowRules; @@ -19,6 +19,7 @@ pub enum WindowId { Some(u32), } +#[derive(Clone, Copy)] pub struct Window { pub rules: WindowRules, } diff --git a/api/rust/src/window/rules.rs b/api/rust/src/window/rules.rs index 2648d16..1d6a6d0 100644 --- a/api/rust/src/window/rules.rs +++ b/api/rust/src/window/rules.rs @@ -4,6 +4,7 @@ use crate::{msg::Msg, output::OutputHandle, send_msg, tag::TagHandle}; use super::{FloatingOrTiled, FullscreenOrMaximized}; +#[derive(Clone, Copy)] pub struct WindowRules; impl WindowRules {