Diff
diff --git a/src/config.rs b/src/config.rs
index 90905fa..2f8e292 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -84,6 +84,7 @@ pub const KEYBINDINGS: &[Key] = &[
Key::new(&[MODKEY], keycodes::D, KeyAction::Spawn, Arg::Array(DMENU_CMD)),
Key::new(&[MODKEY], keycodes::Q, KeyAction::KillClient, Arg::None),
Key::new(&[MODKEY, SHIFT], keycodes::Q, KeyAction::Quit, Arg::None),
+ Key::new(&[MODKEY, SHIFT], keycodes::R, KeyAction::Restart, Arg::None),
Key::new(&[MODKEY], keycodes::J, KeyAction::FocusStack, Arg::Int(-1)),
Key::new(&[MODKEY], keycodes::K, KeyAction::FocusStack, Arg::Int(1)),
@@ -149,3 +150,4 @@ pub const STATUS_BLOCKS: &[BlockConfig] = &[
];
const SHIFT: KeyButMask = KeyButMask::SHIFT;
+pub const WM_BINARY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/target/release/oxwm");
diff --git a/src/keyboard/handlers.rs b/src/keyboard/handlers.rs
index 294c724..b9deb25 100644
--- a/src/keyboard/handlers.rs
+++ b/src/keyboard/handlers.rs
@@ -9,6 +9,7 @@ pub enum KeyAction {
KillClient,
FocusStack,
Quit,
+ Restart,
ViewTag,
MoveToTag,
None,
diff --git a/src/keyboard/keycodes.rs b/src/keyboard/keycodes.rs
index 3b57218..a01fd0f 100644
--- a/src/keyboard/keycodes.rs
+++ b/src/keyboard/keycodes.rs
@@ -21,6 +21,7 @@ pub const F: u8 = 41;
pub const J: u8 = 44;
pub const K: u8 = 45;
pub const L: u8 = 46;
+pub const R: u8 = 27;
pub const KEY_1: u8 = 10;
pub const KEY_2: u8 = 11;
diff --git a/src/main.rs b/src/main.rs
index 2b0cfa7..121bf64 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,6 +6,19 @@ mod layout;
mod window_manager;
fn main() -> Result<()> {
- let mut window_manager = window_manager::WindowManager::new()?;
- return window_manager.run();
+ loop {
+ let mut window_manager = window_manager::WindowManager::new()?;
+ let should_restart = window_manager.run()?;
+
+ if !should_restart {
+ break;
+ }
+
+ use std::os::unix::process::CommandExt;
+ let err = std::process::Command::new(config::WM_BINARY).exec();
+ eprintln!("Failed to restart: {}", err);
+ break;
+ }
+
+ Ok(())
}
diff --git a/src/window_manager.rs b/src/window_manager.rs
index 672dace..3d4f08a 100644
--- a/src/window_manager.rs
+++ b/src/window_manager.rs
@@ -1,13 +1,13 @@
use crate::bar::Bar;
use crate::config::{BORDER_FOCUSED, BORDER_UNFOCUSED, BORDER_WIDTH, TAG_COUNT};
use crate::keyboard::{self, Arg, KeyAction};
-use crate::layout::tiling::TilingLayout;
use crate::layout::Layout;
+use crate::layout::tiling::TilingLayout;
use anyhow::Result;
use x11rb::connection::Connection;
-use x11rb::protocol::xproto::*;
use x11rb::protocol::Event;
+use x11rb::protocol::xproto::*;
use x11rb::rust_connection::RustConnection;
pub type TagMask = u32;
@@ -48,7 +48,7 @@ impl WindowManager {
let bar = Bar::new(&connection, &screen, screen_number)?;
- return Ok(Self {
+ let mut window_manger = Self {
connection,
screen_number,
root,
@@ -59,21 +59,46 @@ impl WindowManager {
window_tags: std::collections::HashMap::new(),
selected_tags: tag_mask(0),
bar,
- });
+ };
+
+ window_manger.scan_existing_windows()?;
+
+ Ok(window_manger)
+ }
+
+ fn scan_existing_windows(&mut self) -> Result<()> {
+ let tree = self.connection.query_tree(self.root)?.reply()?;
+
+ for &window in &tree.children {
+ if let Ok(attrs) = self.connection.get_window_attributes(window)?.reply() {
+ if window != self.bar.window()
+ && attrs.map_state == MapState::VIEWABLE
+ && !attrs.override_redirect
+ {
+ self.windows.push(window);
+ self.window_tags.insert(window, self.selected_tags);
+ }
+ }
+ }
+ if let Some(&first) = self.windows.first() {
+ self.set_focus(Some(first))?;
+ }
+ Ok(())
}
- pub fn run(&mut self) -> Result<()> {
+ pub fn run(&mut self) -> Result<bool> {
println!("oxwm started on display {}", self.screen_number);
keyboard::setup_keybinds(&self.connection, self.root)?;
-
self.update_bar()?;
loop {
self.bar.update_blocks()?;
if let Ok(Some(event)) = self.connection.poll_for_event() {
- self.handle_event(event)?;
+ if let Some(should_restart) = self.handle_event(event)? {
+ return Ok(should_restart);
+ }
}
if self.bar.needs_redraw() {
@@ -84,19 +109,6 @@ impl WindowManager {
}
}
- // pub fn run(&mut self) -> Result<()> {
- // println!("oxwm started on display {}", self.screen_number);
- //
- // keyboard::setup_keybinds(&self.connection, self.root)?;
- //
- // self.update_bar()?;
- //
- // loop {
- // let event = self.connection.wait_for_event()?;
- // self.handle_event(event)?;
- // }
- // }
-
fn update_bar(&mut self) -> Result<()> {
let mut occupied_tags: TagMask = 0;
for &tags in self.window_tags.values() {
@@ -139,8 +151,8 @@ impl WindowManager {
self.cycle_focus(*direction)?;
}
}
- KeyAction::Quit => {
- std::process::exit(0);
+ KeyAction::Quit | KeyAction::Restart => {
+ //no-op
}
KeyAction::ViewTag => {
if let Arg::Int(tag_index) = arg {
@@ -280,7 +292,7 @@ impl WindowManager {
Ok(())
}
- fn handle_event(&mut self, event: Event) -> Result<()> {
+ fn handle_event(&mut self, event: Event) -> Result<Option<bool>> {
match event {
Event::MapRequest(event) => {
self.connection.map_window(event.window)?;
@@ -302,7 +314,12 @@ impl WindowManager {
}
Event::KeyPress(event) => {
let (action, arg) = keyboard::handle_key_press(event)?;
- self.handle_key_action(action, arg)?;
+
+ match action {
+ KeyAction::Quit => return Ok(Some(false)),
+ KeyAction::Restart => return Ok(Some(true)),
+ _ => self.handle_key_action(action, arg)?,
+ }
}
Event::ButtonPress(event) => {
if event.event == self.bar.window() {
@@ -319,9 +336,8 @@ impl WindowManager {
}
_ => {}
}
- Ok(())
+ Ok(None)
}
-
fn apply_layout(&self) -> Result<()> {
let screen_width = self.screen.width_in_pixels as u32;
let screen_height = self.screen.height_in_pixels as u32;