Add Rust default config comments, batch tag calls

This commit is contained in:
Ottatop 2024-03-16 21:03:01 -05:00
parent 2538ef5b74
commit 0bd64ee3aa
2 changed files with 97 additions and 30 deletions

View file

@ -1,15 +1,21 @@
use pinnacle_api::layout::{ use pinnacle_api::layout::{
CornerLayout, CyclingLayoutManager, DwindleLayout, FairLayout, MasterStackLayout, SpiralLayout, CornerLayout, CornerLocation, CyclingLayoutManager, DwindleLayout, FairLayout, MasterSide,
MasterStackLayout, SpiralLayout,
}; };
use pinnacle_api::signal::WindowSignal; use pinnacle_api::signal::WindowSignal;
use pinnacle_api::util::{Axis, Batch};
use pinnacle_api::xkbcommon::xkb::Keysym; use pinnacle_api::xkbcommon::xkb::Keysym;
use pinnacle_api::{ use pinnacle_api::{
input::{Mod, MouseButton, MouseEdge}, input::{Mod, MouseButton, MouseEdge},
ApiModules, ApiModules,
}; };
// Pinnacle needs to perform some setup before and after your config.
// The `#[pinnacle_api::config(modules)]` attribute does so and
// will bind all the config structs to the provided identifier.
#[pinnacle_api::config(modules)] #[pinnacle_api::config(modules)]
async fn main() { async fn main() {
// Deconstruct to get all the APIs.
let ApiModules { let ApiModules {
pinnacle, pinnacle,
process, process,
@ -24,7 +30,9 @@ async fn main() {
let terminal = "alacritty"; let terminal = "alacritty";
// Mousebinds //------------------------
// Mousebinds |
//------------------------
// `mod_key + left click` starts moving a window // `mod_key + left click` starts moving a window
input.mousebind([mod_key], MouseButton::Left, MouseEdge::Press, || { input.mousebind([mod_key], MouseButton::Left, MouseEdge::Press, || {
@ -36,7 +44,9 @@ async fn main() {
window.begin_resize(MouseButton::Right); window.begin_resize(MouseButton::Right);
}); });
// Keybinds //------------------------
// Keybinds |
//------------------------
// `mod_key + alt + q` quits Pinnacle // `mod_key + alt + q` quits Pinnacle
input.keybind([mod_key, Mod::Alt], 'q', || { input.keybind([mod_key, Mod::Alt], 'q', || {
@ -76,25 +86,82 @@ async fn main() {
} }
}); });
// Window rules //------------------------
// // Window rules |
//------------------------
// You can define window rules to get windows to open with desired properties. // You can define window rules to get windows to open with desired properties.
// See `pinnacle_api::window::rules` in the docs for more information. // See `pinnacle_api::window::rules` in the docs for more information.
// Layouts //------------------------
// Layouts |
//------------------------
let master_stack = Box::<MasterStackLayout>::default(); // Pinnacle does not manage layouts compositor-side.
let dwindle = Box::<DwindleLayout>::default(); // Instead, it delegates computation of layouts to your config,
let spiral = Box::<SpiralLayout>::default(); // which provides an interface to calculate the size and location of
let corner = Box::<CornerLayout>::default(); // windows that the compositor will use to position windows.
let fair = Box::<FairLayout>::default(); //
// If you're familiar with River's layout generators, you'll understand the system here
// a bit better.
//
// The Rust API provides two layout system abstractions:
// 1. Layout managers, and
// 2. Layout generators.
//
// ### Layout Managers ###
// A layout manager is a struct that implements the `LayoutManager` trait.
// A manager is meant to keep track of and choose various layout generators
// across your usage of the compositor.
//
// ### Layout generators ###
// A layout generator is a struct that implements the `LayoutGenerator` trait.
// It takes in layout arguments and computes a vector of geometries that will
// determine the size and position of windows being laid out.
//
// There is one built-in layout manager and five built-in layout generators,
// as shown below.
//
// Additionally, this system is designed to be user-extensible;
// you are free to create your own layout managers and generators for
// maximum customizability! Docs for doing so are in the works, so sit tight.
// Create a `CyclingLayoutManager` that can cycle between layouts on different tags.
//
// It takes in some layout generators that need to be boxed and dyn-coerced.
let layout_requester = layout.set_manager(CyclingLayoutManager::new([ let layout_requester = layout.set_manager(CyclingLayoutManager::new([
master_stack as _, Box::<MasterStackLayout>::default() as _,
dwindle as _, Box::new(MasterStackLayout {
spiral as _, master_side: MasterSide::Right,
corner as _, ..Default::default()
fair as _, }) as _,
Box::new(MasterStackLayout {
master_side: MasterSide::Top,
..Default::default()
}) as _,
Box::new(MasterStackLayout {
master_side: MasterSide::Bottom,
..Default::default()
}) as _,
Box::<DwindleLayout>::default() as _,
Box::<SpiralLayout>::default() as _,
Box::<CornerLayout>::default() as _,
Box::new(CornerLayout {
corner_loc: CornerLocation::TopRight,
..Default::default()
}) as _,
Box::new(CornerLayout {
corner_loc: CornerLocation::BottomLeft,
..Default::default()
}) as _,
Box::new(CornerLayout {
corner_loc: CornerLocation::BottomRight,
..Default::default()
}) as _,
Box::<FairLayout>::default() as _,
Box::new(FairLayout {
axis: Axis::Horizontal,
..Default::default()
}) as _,
])); ]));
let mut layout_requester_clone = layout_requester.clone(); let mut layout_requester_clone = layout_requester.clone();
@ -102,11 +169,10 @@ async fn main() {
// `mod_key + space` cycles to the next layout // `mod_key + space` cycles to the next layout
input.keybind([mod_key], Keysym::space, move || { input.keybind([mod_key], Keysym::space, move || {
let Some(focused_op) = output.get_focused() else { return }; let Some(focused_op) = output.get_focused() else { return };
let Some(first_active_tag) = focused_op let Some(first_active_tag) = focused_op.tags().batch_find(
.tags() |tg| Box::pin(tg.active_async()),
.into_iter() |active| active == &Some(true),
.find(|tg| tg.active().unwrap_or(false)) ) else {
else {
return; return;
}; };
@ -117,11 +183,10 @@ async fn main() {
// `mod_key + shift + space` cycles to the previous layout // `mod_key + shift + space` cycles to the previous layout
input.keybind([mod_key, Mod::Shift], Keysym::space, move || { input.keybind([mod_key, Mod::Shift], Keysym::space, move || {
let Some(focused_op) = output.get_focused() else { return }; let Some(focused_op) = output.get_focused() else { return };
let Some(first_active_tag) = focused_op let Some(first_active_tag) = focused_op.tags().batch_find(
.tags() |tg| Box::pin(tg.active_async()),
.into_iter() |active| active == &Some(true),
.find(|tg| tg.active().unwrap_or(false)) ) else {
else {
return; return;
}; };
@ -129,7 +194,9 @@ async fn main() {
layout_requester_clone.request_layout_on_output(&focused_op); layout_requester_clone.request_layout_on_output(&focused_op);
}); });
// Tags //------------------------
// Tags |
//------------------------
let tag_names = ["1", "2", "3", "4", "5"]; let tag_names = ["1", "2", "3", "4", "5"];
@ -141,8 +208,6 @@ async fn main() {
tags.first().unwrap().set_active(true); tags.first().unwrap().set_active(true);
}); });
process.spawn_once([terminal]);
for tag_name in tag_names { for tag_name in tag_names {
// `mod_key + 1-5` switches to tag "1" to "5" // `mod_key + 1-5` switches to tag "1" to "5"
input.keybind([mod_key], tag_name, move || { input.keybind([mod_key], tag_name, move || {
@ -181,4 +246,6 @@ async fn main() {
window.connect_signal(WindowSignal::PointerEnter(Box::new(|win| { window.connect_signal(WindowSignal::PointerEnter(Box::new(|win| {
win.set_focused(true); win.set_focused(true);
}))); })));
process.spawn_once([terminal]);
} }

View file

@ -29,7 +29,7 @@ use crate::{
OUTPUT, TAG, WINDOW, OUTPUT, TAG, WINDOW,
}; };
/// A struct that allows you to add and remove tags and get [`TagHandle`]s. /// A struct that allows you to manage layouts.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Layout { pub struct Layout {
layout_client: LayoutServiceClient<Channel>, layout_client: LayoutServiceClient<Channel>,