From 8b97874fbeaf8ae3052f3954c3a0824f614991a7 Mon Sep 17 00:00:00 2001 From: Candifloss Date: Sun, 16 Nov 2025 22:36:52 +0530 Subject: [PATCH] Initial commit - Default settings, sample code from repo --- .gitignore | 6 +++ Cargo.toml | 8 ++++ src/main.rs | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore index ab951f8..64a2289 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,9 @@ Cargo.lock # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + + +# Added by cargo + +/target +/test \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..514fc26 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "gingerbread" +version = "0.1.0" +edition = "2024" + +[dependencies] +penrose = "0.4.0" +tracing-subscriber = { version = "0.3.20", features = ["env-filter"] } diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..d9729d3 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,118 @@ +//! penrose :: minimal configuration +//! +//! This file will give you a functional if incredibly minimal window manager that +//! has multiple workspaces and simple client / workspace movement. +#[cfg(not(target_os = "macos"))] +use penrose::x11rb::RustConn; +use penrose::{ + Result, + builtin::{ + actions::{ + exit, + floating::{MouseDragHandler, MouseResizeHandler, sink_focused}, + modify_with, send_layout_message, spawn, + }, + layout::messages::{ExpandMain, IncMain, ShrinkMain}, + }, + core::{ + Config, WindowManager, + bindings::{ + KeyEventHandler, MouseEventHandler, MouseState, click_handler, + parse_keybindings_with_xmodmap, + }, + }, + map, +}; + +use std::collections::HashMap; +use tracing_subscriber::{self, prelude::*}; + +#[cfg(not(target_os = "macos"))] +fn raw_key_bindings() -> HashMap>> { + let mut raw_bindings = map! { + map_keys: |k: &str| k.to_string(); + + "M-j" => modify_with(|cs| cs.focus_down()), + "M-k" => modify_with(|cs| cs.focus_up()), + "M-S-j" => modify_with(|cs| cs.swap_down()), + "M-S-k" => modify_with(|cs| cs.swap_up()), + "M-S-q" => modify_with(|cs| cs.kill_focused()), + "M-Tab" => modify_with(|cs| cs.toggle_tag()), + "M-bracketright" => modify_with(|cs| cs.next_screen()), + "M-bracketleft" => modify_with(|cs| cs.previous_screen()), + "M-grave" => modify_with(|cs| cs.next_layout()), + "M-S-grave" => modify_with(|cs| cs.previous_layout()), + "M-S-Up" => send_layout_message(|| IncMain(1)), + "M-S-Down" => send_layout_message(|| IncMain(-1)), + "M-S-Right" => send_layout_message(|| ExpandMain), + "M-S-Left" => send_layout_message(|| ShrinkMain), + "M-semicolon" => spawn("dmenu_run"), + "M-Return" => spawn("st"), + "M-A-Escape" => exit(), + }; + + for tag in &["1", "2", "3", "4", "5", "6", "7", "8", "9"] { + raw_bindings.extend([ + ( + format!("M-{tag}"), + modify_with(move |client_set| client_set.focus_tag(tag)), + ), + ( + format!("M-S-{tag}"), + modify_with(move |client_set| client_set.move_focused_to_tag(tag)), + ), + ]); + } + + raw_bindings +} + +#[cfg(not(target_os = "macos"))] +fn mouse_bindings() -> HashMap>> { + use penrose::core::bindings::{ + ModifierKey::{Meta, Shift}, + MouseButton::{Left, Middle, Right}, + }; + + map! { + map_keys: |(button, modifiers)| MouseState { button, modifiers }; + + (Left, vec![Shift, Meta]) => MouseDragHandler::boxed_default(), + (Right, vec![Shift, Meta]) => MouseResizeHandler::boxed_default(), + (Middle, vec![Shift, Meta]) => click_handler(sink_focused()), + } +} + +#[cfg(not(target_os = "macos"))] +fn main() -> Result<()> { + tracing_subscriber::fmt() + .with_env_filter("info") + .finish() + .init(); + + let conn = RustConn::new()?; + let key_bindings = parse_keybindings_with_xmodmap(raw_key_bindings())?; + let wm = WindowManager::new(Config::default(), key_bindings, mouse_bindings(), conn)?; + + wm.run() +} + +#[cfg(target_os = "macos")] +fn main() -> Result<()> { + panic!("not supported on OSX"); +} + +#[cfg(not(target_os = "macos"))] +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn bindings_parse_correctly_with_xmodmap() { + let res = parse_keybindings_with_xmodmap(raw_key_bindings()); + + if let Err(e) = res { + panic!("{e}"); + } + } +}