Created
October 31, 2022 14:07
-
-
Save sminez/fba0f1ab12bce7ac56a0e60b81bd2306 to your computer and use it in GitHub Desktop.
Example Penrose WM
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use penrose::{ | |
builtin::{ | |
actions::{exit, log_current_state}, | |
layout::{ | |
messages::{ExpandMain, IncMain, ShrinkMain}, | |
transformers::{Gaps, ReserveTop}, | |
MainAndStack, Monocle, | |
}, | |
}, | |
core::{ | |
actions::{modify_with, send_layout_message, spawn}, | |
bindings::{parse_keybindings_with_xmodmap, KeyEventHandler}, | |
layout::LayoutStack, | |
Config, WindowManager, | |
}, | |
extensions::{ | |
actions::dmenu_focus_client, | |
hooks::{ | |
add_ewmh_hooks, add_named_scratchpads, manage::FloatingCentered, NamedScratchPad, | |
SpawnOnStartup, ToggleNamedScratchPad, | |
}, | |
}, | |
map, stack, | |
x::{query::ClassName, XConn}, | |
x11rb::RustConn, | |
Color, Result, | |
}; | |
use penrose_ui::{ | |
bar::{ | |
widgets::{ActiveWindowName, CurrentLayout, RootWindowName, Workspaces}, | |
Position, StatusBar, | |
}, | |
core::TextStyle, | |
}; | |
use std::collections::HashMap; | |
use tracing_subscriber::{self, prelude::*}; | |
const FONT: &str = "ProFontIIx Nerd Font"; | |
const BLACK: u32 = 0x282828ff; | |
const WHITE: u32 = 0xebdbb2ff; | |
const GREY: u32 = 0x3c3836ff; | |
const BLUE: u32 = 0x458588ff; | |
const MAX_MAIN: u32 = 1; | |
const RATIO: f32 = 0.6; | |
const RATIO_STEP: f32 = 0.1; | |
const OUTER_PX: u32 = 5; | |
const INNER_PX: u32 = 5; | |
const BAR_HEIGHT_PX: u32 = 18; | |
const MAX_ACTIVE_WINDOW_CHARS: usize = 50; | |
fn raw_key_bindings( | |
toggle_scratch: ToggleNamedScratchPad, | |
) -> HashMap<String, Box<dyn KeyEventHandler<RustConn>>> { | |
let mut raw_bindings = map! { | |
// map_keys: |k: &str| format!("C-{k}"); | |
map_keys: |k: &str| k.to_owned(); | |
"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-S-c" => dmenu_focus_client(Default::default()), | |
"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-S-bracketright" => modify_with(|cs| cs.drag_workspace_forward()), | |
"M-S-bracketleft" => modify_with(|cs| cs.drag_workspace_backward()), | |
"M-grave" => modify_with(|cs| cs.next_layout()), | |
"M-S-grave" => modify_with(|cs| cs.previous_layout()), | |
"M-Up" => send_layout_message(|| IncMain(1)), | |
"M-Down" => send_layout_message(|| IncMain(-1)), | |
"M-Right" => send_layout_message(|| ExpandMain), | |
"M-Left" => send_layout_message(|| ShrinkMain), | |
"M-semicolon" => spawn("rofi-apps"), | |
"M-S-s" => log_current_state(), | |
"M-Return" => spawn("st"), | |
"M-slash" => Box::new(toggle_scratch), | |
"M-A-l" => spawn("xflock4"), | |
"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.pull_tag_to_screen(tag)), | |
), | |
( | |
format!("M-S-{tag}"), | |
modify_with(move |client_set| client_set.move_focused_to_tag(tag)), | |
), | |
]); | |
} | |
raw_bindings | |
} | |
fn layouts() -> LayoutStack { | |
stack!( | |
MainAndStack::side(MAX_MAIN, RATIO, RATIO_STEP), | |
MainAndStack::side_mirrored(MAX_MAIN, RATIO, RATIO_STEP), | |
MainAndStack::bottom(MAX_MAIN, RATIO, RATIO_STEP), | |
Monocle::boxed() | |
) | |
.map(|layout| ReserveTop::wrap(Gaps::wrap(layout, OUTER_PX, INNER_PX), BAR_HEIGHT_PX)) | |
} | |
pub fn status_bar<X: XConn>(position: Position) -> penrose_ui::Result<StatusBar<X>> { | |
let highlight: Color = BLUE.into(); | |
let empty_ws: Color = GREY.into(); | |
let style = TextStyle { | |
font: FONT.to_string(), | |
point_size: 8, | |
fg: WHITE.into(), | |
bg: Some(BLACK.into()), | |
padding: (2.0, 2.0), | |
}; | |
StatusBar::try_new( | |
position, | |
BAR_HEIGHT_PX, | |
style.bg.unwrap_or_else(|| 0x000000.into()), | |
&[&style.font], | |
vec![ | |
Box::new(Workspaces::new(&style, highlight, empty_ws)), | |
Box::new(CurrentLayout::new(&style)), | |
// Box::new(penrose_bar::widgets::debug::StateSummary::new(style)), | |
Box::new(ActiveWindowName::new( | |
MAX_ACTIVE_WINDOW_CHARS, | |
&TextStyle { | |
bg: Some(highlight), | |
padding: (6.0, 4.0), | |
..style.clone() | |
}, | |
true, | |
false, | |
)), | |
Box::new(RootWindowName::new( | |
&TextStyle { | |
padding: (4.0, 2.0), | |
..style.clone() | |
}, | |
false, | |
true, | |
)), | |
], | |
) | |
} | |
fn main() -> Result<()> { | |
tracing_subscriber::fmt() | |
.with_env_filter("debug") | |
.finish() | |
.init(); | |
// Run my init script on startup | |
let startup_hook = SpawnOnStartup::boxed("/usr/local/scripts/penrose-startup.sh"); | |
// Float st-terminal windows spawned as fzf helpers from kakoune | |
let manage_hook = (ClassName("floatTerm"), FloatingCentered::new(0.8, 0.6)); | |
let config = add_ewmh_hooks(Config { | |
default_layouts: layouts(), | |
manage_hook: Some(Box::new(manage_hook)), | |
startup_hook: Some(startup_hook), | |
..Config::default() | |
}); | |
// Create a new named scratchpad and toggle handle for use in keybindings. | |
let (nsp, toggle_scratch) = NamedScratchPad::new( | |
"terminal", | |
"st -c StScratchpad", | |
ClassName("StScratchpad"), | |
FloatingCentered::new(0.8, 0.8), | |
true, | |
); | |
let conn = RustConn::new()?; | |
let key_bindings = parse_keybindings_with_xmodmap(raw_key_bindings(toggle_scratch))?; | |
// Initialise the required state extension and hooks for handling the named scratchpad | |
let wm = add_named_scratchpads( | |
WindowManager::new(config, key_bindings, HashMap::new(), conn)?, | |
vec![nsp], | |
); | |
let bar = status_bar(Position::Top).unwrap(); | |
let wm = bar.add_to(wm); | |
wm.run() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment