made border colors configurable in the config file
This commit is contained in:
parent
3a56102ec2
commit
ece0eb7903
|
@ -7,7 +7,7 @@ edition = "2018"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
x11 = {version = "2.18.2", features = ["xlib"] }
|
x11 = {version = "2.18.2", features = ["xlib", "xft"] }
|
||||||
log = "0.4.13"
|
log = "0.4.13"
|
||||||
simple_logger = "1.11.0"
|
simple_logger = "1.11.0"
|
||||||
dirs = "3.0.2"
|
dirs = "3.0.2"
|
||||||
|
|
|
@ -40,6 +40,9 @@ pub trait WindowServerBackend {
|
||||||
|
|
||||||
fn all_windows(&self) -> Option<Vec<Self::Window>>;
|
fn all_windows(&self) -> Option<Vec<Self::Window>>;
|
||||||
|
|
||||||
|
fn set_active_window_border_color(&mut self, color_name: &str);
|
||||||
|
fn set_inactive_window_border_color(&mut self, color_name: &str);
|
||||||
|
|
||||||
fn resize_window(&self, window: Self::Window, new_size: Point<i32>) {
|
fn resize_window(&self, window: Self::Window, new_size: Point<i32>) {
|
||||||
self.configure_window(window, Some(new_size), None, None);
|
self.configure_window(window, Some(new_size), None, None);
|
||||||
}
|
}
|
||||||
|
|
45
src/backends/xlib/color.rs
Normal file
45
src/backends/xlib/color.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
use std::mem::MaybeUninit;
|
||||||
|
|
||||||
|
use x11::{xft, xlib};
|
||||||
|
|
||||||
|
use super::Display;
|
||||||
|
|
||||||
|
pub struct XftColor {
|
||||||
|
inner: xft::XftColor,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl XftColor {
|
||||||
|
pub fn pixel(&self) -> u64 {
|
||||||
|
self.inner.pixel
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn color(&self) -> x11::xrender::XRenderColor {
|
||||||
|
self.inner.color
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(
|
||||||
|
dpy: Display,
|
||||||
|
screen: i32,
|
||||||
|
mut color_name: String,
|
||||||
|
) -> Result<Self, std::io::Error> {
|
||||||
|
color_name.push('\0');
|
||||||
|
let mut color = MaybeUninit::<xft::XftColor>::zeroed();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
xft::XftColorAllocName(
|
||||||
|
dpy.get(),
|
||||||
|
xlib::XDefaultVisual(dpy.get(), screen),
|
||||||
|
xlib::XDefaultColormap(dpy.get(), screen),
|
||||||
|
color_name.as_ptr() as *mut _,
|
||||||
|
color.as_mut_ptr(),
|
||||||
|
) != 0
|
||||||
|
}
|
||||||
|
.then(|| Self {
|
||||||
|
inner: unsafe { color.assume_init() },
|
||||||
|
})
|
||||||
|
.ok_or(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::NotFound,
|
||||||
|
"Unable to allocate color.",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ use super::{
|
||||||
WindowServerBackend,
|
WindowServerBackend,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub mod color;
|
||||||
pub mod keysym;
|
pub mod keysym;
|
||||||
|
|
||||||
pub type XLibWindowEvent = WindowEvent<xlib::Window>;
|
pub type XLibWindowEvent = WindowEvent<xlib::Window>;
|
||||||
|
@ -100,31 +101,6 @@ impl From<u8> for XlibError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl Into<i32> for XlibError {
|
|
||||||
// fn into(self) -> i32 {
|
|
||||||
// match self {
|
|
||||||
// XlibError::BadAccess => xlib::BadAccess.into(),
|
|
||||||
// XlibError::BadAlloc => xlib::BadAlloc.into(),
|
|
||||||
// XlibError::BadAtom => xlib::BadAtom.into(),
|
|
||||||
// XlibError::BadColor => xlib::BadColor.into(),
|
|
||||||
// XlibError::BadCursor => xlib::BadCursor.into(),
|
|
||||||
// XlibError::BadDrawable => xlib::BadDrawable.into(),
|
|
||||||
// XlibError::BadFont => xlib::BadFont.into(),
|
|
||||||
// XlibError::BadGC => xlib::BadGC.into(),
|
|
||||||
// XlibError::BadIDChoice => xlib::BadIDChoice.into(),
|
|
||||||
// XlibError::BadImplementation => xlib::BadImplementation.into(),
|
|
||||||
// XlibError::BadLength => xlib::BadLength.into(),
|
|
||||||
// XlibError::BadMatch => xlib::BadMatch.into(),
|
|
||||||
// XlibError::BadName => xlib::BadName.into(),
|
|
||||||
// XlibError::BadPixmap => xlib::BadPixmap.into(),
|
|
||||||
// XlibError::BadRequest => xlib::BadRequest.into(),
|
|
||||||
// XlibError::BadValue => xlib::BadValue.into(),
|
|
||||||
// XlibError::BadWindow => xlib::BadWindow.into(),
|
|
||||||
// XlibError::InvalidError(err) => err,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
impl Display {
|
impl Display {
|
||||||
pub fn new(display: *mut x11::xlib::Display) -> Self {
|
pub fn new(display: *mut x11::xlib::Display) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -144,6 +120,8 @@ pub struct XLib {
|
||||||
screen: i32,
|
screen: i32,
|
||||||
atoms: XLibAtoms,
|
atoms: XLibAtoms,
|
||||||
keybinds: Vec<KeyOrMouseBind>,
|
keybinds: Vec<KeyOrMouseBind>,
|
||||||
|
active_border_color: Option<color::XftColor>,
|
||||||
|
inactive_border_color: Option<color::XftColor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for XLib {
|
impl Drop for XLib {
|
||||||
|
@ -174,6 +152,8 @@ impl XLib {
|
||||||
modifier_state: ModifierState::empty(),
|
modifier_state: ModifierState::empty(),
|
||||||
atoms,
|
atoms,
|
||||||
keybinds: Vec::new(),
|
keybinds: Vec::new(),
|
||||||
|
active_border_color: None,
|
||||||
|
inactive_border_color: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,12 +664,18 @@ impl WindowServerBackend for XLib {
|
||||||
xlib::CurrentTime,
|
xlib::CurrentTime,
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: make painting the window border a seperate function, and configurable
|
let border_color = self
|
||||||
let screen = xlib::XDefaultScreenOfDisplay(self.dpy()).as_ref();
|
.active_border_color
|
||||||
|
.as_ref()
|
||||||
|
.map(|color| color.pixel())
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
xlib::XDefaultScreenOfDisplay(self.dpy())
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.white_pixel
|
||||||
|
});
|
||||||
|
|
||||||
if let Some(screen) = screen {
|
xlib::XSetWindowBorder(self.dpy(), window, border_color);
|
||||||
xlib::XSetWindowBorder(self.dpy(), window, screen.white_pixel);
|
|
||||||
}
|
|
||||||
|
|
||||||
xlib::XChangeProperty(
|
xlib::XChangeProperty(
|
||||||
self.dpy(),
|
self.dpy(),
|
||||||
|
@ -716,11 +702,19 @@ impl WindowServerBackend for XLib {
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: make painting the window border a seperate function, and configurable
|
// TODO: make painting the window border a seperate function, and configurable
|
||||||
let screen = xlib::XDefaultScreenOfDisplay(self.dpy()).as_ref();
|
|
||||||
|
|
||||||
if let Some(screen) = screen {
|
let border_color = self
|
||||||
xlib::XSetWindowBorder(self.dpy(), window, screen.black_pixel);
|
.inactive_border_color
|
||||||
}
|
.as_ref()
|
||||||
|
.map(|color| color.pixel())
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
xlib::XDefaultScreenOfDisplay(self.dpy())
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.black_pixel
|
||||||
|
});
|
||||||
|
|
||||||
|
xlib::XSetWindowBorder(self.dpy(), window, border_color);
|
||||||
|
|
||||||
xlib::XDeleteProperty(
|
xlib::XDeleteProperty(
|
||||||
self.dpy(),
|
self.dpy(),
|
||||||
|
@ -885,6 +879,24 @@ impl WindowServerBackend for XLib {
|
||||||
windows
|
windows
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_active_window_border_color(&mut self, color_name: &str) {
|
||||||
|
self.active_border_color = color::XftColor::new(
|
||||||
|
self.display.clone(),
|
||||||
|
self.screen,
|
||||||
|
color_name.to_owned(),
|
||||||
|
)
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_inactive_window_border_color(&mut self, color_name: &str) {
|
||||||
|
self.inactive_border_color = color::XftColor::new(
|
||||||
|
self.display.clone(),
|
||||||
|
self.screen,
|
||||||
|
color_name.to_owned(),
|
||||||
|
)
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XLibAtoms {
|
struct XLibAtoms {
|
||||||
|
|
|
@ -858,7 +858,7 @@ impl VirtualScreenStore {
|
||||||
fn go_to_nth(&mut self, n: usize) -> usize {
|
fn go_to_nth(&mut self, n: usize) -> usize {
|
||||||
self.last_idx = Some(self.current_idx);
|
self.last_idx = Some(self.current_idx);
|
||||||
|
|
||||||
self.current_idx = n % self.screens.len();
|
self.current_idx = n.min(self.screens.len() - 1);
|
||||||
|
|
||||||
self.current_idx
|
self.current_idx
|
||||||
}
|
}
|
||||||
|
|
47
src/state.rs
47
src/state.rs
|
@ -34,6 +34,35 @@ pub struct WMConfig {
|
||||||
mod_key: ModifierKey,
|
mod_key: ModifierKey,
|
||||||
gap: Option<i32>,
|
gap: Option<i32>,
|
||||||
kill_clients_on_exit: bool,
|
kill_clients_on_exit: bool,
|
||||||
|
#[serde(default = "WMConfig::default_active_window_border_color")]
|
||||||
|
active_window_border_color: String,
|
||||||
|
#[serde(default = "WMConfig::default_inactive_window_border_color")]
|
||||||
|
inactive_window_border_color: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WMConfig {
|
||||||
|
fn default_active_window_border_color() -> String {
|
||||||
|
"#ffffff".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_inactive_window_border_color() -> String {
|
||||||
|
"#444444".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for WMConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
num_virtualscreens: 10,
|
||||||
|
mod_key: ModifierKey::Super,
|
||||||
|
gap: Some(2),
|
||||||
|
kill_clients_on_exit: false,
|
||||||
|
active_window_border_color:
|
||||||
|
Self::default_active_window_border_color(),
|
||||||
|
inactive_window_border_color:
|
||||||
|
Self::default_inactive_window_border_color(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WindowManager<B = XLib>
|
pub struct WindowManager<B = XLib>
|
||||||
|
@ -256,6 +285,13 @@ where
|
||||||
|
|
||||||
self.add_vs_switch_keybinds();
|
self.add_vs_switch_keybinds();
|
||||||
|
|
||||||
|
self.backend.set_active_window_border_color(
|
||||||
|
&self.config.active_window_border_color,
|
||||||
|
);
|
||||||
|
self.backend.set_inactive_window_border_color(
|
||||||
|
&self.config.inactive_window_border_color,
|
||||||
|
);
|
||||||
|
|
||||||
// add all already existing windows to the WM
|
// add all already existing windows to the WM
|
||||||
if let Some(windows) = self.backend.all_windows() {
|
if let Some(windows) = self.backend.all_windows() {
|
||||||
windows
|
windows
|
||||||
|
@ -869,17 +905,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WMConfig {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
num_virtualscreens: 10,
|
|
||||||
mod_key: ModifierKey::Super,
|
|
||||||
gap: Some(2),
|
|
||||||
kill_clients_on_exit: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Direction {
|
impl Direction {
|
||||||
fn west() -> Self {
|
fn west() -> Self {
|
||||||
Direction::West(1)
|
Direction::West(1)
|
||||||
|
|
Loading…
Reference in a new issue