2023-09-05 12:58:51 +04:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
use std::str::FromStr;
|
|
|
|
|
|
|
|
|
|
use bitflags::bitflags;
|
|
|
|
|
use directories::ProjectDirs;
|
|
|
|
|
use miette::{miette, Context, IntoDiagnostic};
|
2023-09-24 11:04:30 +04:00
|
|
|
use smithay::input::keyboard::keysyms::KEY_NoSymbol;
|
|
|
|
|
use smithay::input::keyboard::xkb::{keysym_from_name, KEYSYM_CASE_INSENSITIVE};
|
2023-09-05 12:58:51 +04:00
|
|
|
use smithay::input::keyboard::Keysym;
|
|
|
|
|
|
|
|
|
|
#[derive(knuffel::Decode, Debug, PartialEq)]
|
|
|
|
|
pub struct Config {
|
|
|
|
|
#[knuffel(child, default)]
|
|
|
|
|
pub input: Input,
|
2023-09-21 13:48:32 +04:00
|
|
|
#[knuffel(children(name = "output"))]
|
|
|
|
|
pub outputs: Vec<Output>,
|
2023-09-21 19:58:03 +04:00
|
|
|
#[knuffel(children(name = "spawn-at-startup"))]
|
|
|
|
|
pub spawn_at_startup: Vec<SpawnAtStartup>,
|
2023-09-05 12:58:51 +04:00
|
|
|
#[knuffel(child, default)]
|
2023-09-26 13:09:33 +04:00
|
|
|
pub focus_ring: FocusRing,
|
|
|
|
|
#[knuffel(child, default)]
|
2023-09-26 13:44:37 +04:00
|
|
|
pub prefer_no_csd: bool,
|
|
|
|
|
#[knuffel(child, default)]
|
2023-10-01 17:42:56 +04:00
|
|
|
pub cursor: Cursor,
|
|
|
|
|
#[knuffel(child, default)]
|
2023-09-05 12:58:51 +04:00
|
|
|
pub binds: Binds,
|
2023-09-06 15:49:46 +04:00
|
|
|
#[knuffel(child, default)]
|
|
|
|
|
pub debug: DebugConfig,
|
2023-09-05 12:58:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FIXME: Add other devices.
|
|
|
|
|
#[derive(knuffel::Decode, Debug, Default, PartialEq)]
|
|
|
|
|
pub struct Input {
|
|
|
|
|
#[knuffel(child, default)]
|
|
|
|
|
pub keyboard: Keyboard,
|
|
|
|
|
#[knuffel(child, default)]
|
|
|
|
|
pub touchpad: Touchpad,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(knuffel::Decode, Debug, Default, PartialEq, Eq)]
|
|
|
|
|
pub struct Keyboard {
|
|
|
|
|
#[knuffel(child, default)]
|
|
|
|
|
pub xkb: Xkb,
|
2023-09-16 20:01:52 +04:00
|
|
|
// The defaults were chosen to match wlroots and sway.
|
|
|
|
|
#[knuffel(child, unwrap(argument), default = 600)]
|
2023-09-16 12:37:23 +04:00
|
|
|
pub repeat_delay: u16,
|
|
|
|
|
#[knuffel(child, unwrap(argument), default = 25)]
|
|
|
|
|
pub repeat_rate: u8,
|
2023-09-05 12:58:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(knuffel::Decode, Debug, Default, PartialEq, Eq)]
|
|
|
|
|
pub struct Xkb {
|
|
|
|
|
#[knuffel(child, unwrap(argument), default)]
|
|
|
|
|
pub rules: String,
|
|
|
|
|
#[knuffel(child, unwrap(argument), default)]
|
|
|
|
|
pub model: String,
|
|
|
|
|
#[knuffel(child, unwrap(argument))]
|
|
|
|
|
pub layout: Option<String>,
|
|
|
|
|
#[knuffel(child, unwrap(argument), default)]
|
|
|
|
|
pub variant: String,
|
|
|
|
|
#[knuffel(child, unwrap(argument))]
|
|
|
|
|
pub options: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FIXME: Add the rest of the settings.
|
|
|
|
|
#[derive(knuffel::Decode, Debug, Default, PartialEq)]
|
|
|
|
|
pub struct Touchpad {
|
|
|
|
|
#[knuffel(child)]
|
|
|
|
|
pub tap: bool,
|
|
|
|
|
#[knuffel(child)]
|
|
|
|
|
pub natural_scroll: bool,
|
|
|
|
|
#[knuffel(child, unwrap(argument), default)]
|
|
|
|
|
pub accel_speed: f64,
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-21 13:48:32 +04:00
|
|
|
#[derive(knuffel::Decode, Debug, Clone, PartialEq)]
|
|
|
|
|
pub struct Output {
|
|
|
|
|
#[knuffel(argument)]
|
|
|
|
|
pub name: String,
|
|
|
|
|
#[knuffel(child, unwrap(argument), default = 1.)]
|
|
|
|
|
pub scale: f64,
|
2023-09-30 11:33:02 +04:00
|
|
|
#[knuffel(child)]
|
|
|
|
|
pub position: Option<Position>,
|
2023-09-21 13:48:32 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for Output {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
name: String::new(),
|
|
|
|
|
scale: 1.,
|
2023-09-30 11:33:02 +04:00
|
|
|
position: None,
|
2023-09-21 13:48:32 +04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-30 11:33:02 +04:00
|
|
|
#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
|
|
|
|
|
pub struct Position {
|
|
|
|
|
#[knuffel(property)]
|
|
|
|
|
pub x: i32,
|
|
|
|
|
#[knuffel(property)]
|
|
|
|
|
pub y: i32,
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-21 19:58:03 +04:00
|
|
|
#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
|
|
|
|
|
pub struct SpawnAtStartup {
|
|
|
|
|
#[knuffel(arguments)]
|
|
|
|
|
pub command: Vec<String>,
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-26 13:09:33 +04:00
|
|
|
#[derive(knuffel::Decode, Debug, Clone, PartialEq)]
|
|
|
|
|
pub struct FocusRing {
|
|
|
|
|
#[knuffel(child)]
|
|
|
|
|
pub off: bool,
|
|
|
|
|
#[knuffel(child, unwrap(argument), default = 4)]
|
|
|
|
|
pub width: u16,
|
|
|
|
|
#[knuffel(child, default = Color::new(0.5, 0.8, 1.0, 1.0))]
|
|
|
|
|
pub active_color: Color,
|
|
|
|
|
#[knuffel(child, default = Color::new(0.3, 0.3, 0.3, 1.0))]
|
|
|
|
|
pub inactive_color: Color,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for FocusRing {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
off: false,
|
|
|
|
|
width: 4,
|
|
|
|
|
active_color: Color::new(0.5, 0.8, 1.0, 1.0),
|
|
|
|
|
inactive_color: Color::new(0.3, 0.3, 0.3, 1.0),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(knuffel::Decode, Debug, Default, Clone, Copy, PartialEq)]
|
|
|
|
|
pub struct Color {
|
|
|
|
|
#[knuffel(argument)]
|
|
|
|
|
pub r: f32,
|
|
|
|
|
#[knuffel(argument)]
|
|
|
|
|
pub g: f32,
|
|
|
|
|
#[knuffel(argument)]
|
|
|
|
|
pub b: f32,
|
|
|
|
|
#[knuffel(argument)]
|
|
|
|
|
pub a: f32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Color {
|
|
|
|
|
pub fn new(r: f32, g: f32, b: f32, a: f32) -> Self {
|
|
|
|
|
Self { r, g, b, a }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<Color> for [f32; 4] {
|
|
|
|
|
fn from(c: Color) -> Self {
|
|
|
|
|
[c.r, c.g, c.b, c.a]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-01 17:42:56 +04:00
|
|
|
#[derive(knuffel::Decode, Debug, PartialEq)]
|
|
|
|
|
pub struct Cursor {
|
|
|
|
|
#[knuffel(child, unwrap(argument), default = String::from("default"))]
|
|
|
|
|
pub xcursor_theme: String,
|
|
|
|
|
#[knuffel(child, unwrap(argument), default = 24)]
|
|
|
|
|
pub xcursor_size: u8,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for Cursor {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
xcursor_theme: String::from("default"),
|
|
|
|
|
xcursor_size: 24,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-05 12:58:51 +04:00
|
|
|
#[derive(knuffel::Decode, Debug, Default, PartialEq, Eq)]
|
|
|
|
|
pub struct Binds(#[knuffel(children)] pub Vec<Bind>);
|
|
|
|
|
|
|
|
|
|
#[derive(knuffel::Decode, Debug, PartialEq, Eq)]
|
|
|
|
|
pub struct Bind {
|
|
|
|
|
#[knuffel(node_name)]
|
|
|
|
|
pub key: Key,
|
|
|
|
|
#[knuffel(children)]
|
|
|
|
|
pub actions: Vec<Action>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
|
pub struct Key {
|
|
|
|
|
pub keysym: Keysym,
|
|
|
|
|
pub modifiers: Modifiers,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bitflags! {
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
|
|
|
pub struct Modifiers : u8 {
|
|
|
|
|
const CTRL = 1;
|
|
|
|
|
const SHIFT = 2;
|
|
|
|
|
const ALT = 4;
|
|
|
|
|
const SUPER = 8;
|
|
|
|
|
const COMPOSITOR = 16;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(knuffel::Decode, Debug, Clone, PartialEq, Eq)]
|
|
|
|
|
pub enum Action {
|
|
|
|
|
#[knuffel(skip)]
|
|
|
|
|
None,
|
|
|
|
|
Quit,
|
|
|
|
|
#[knuffel(skip)]
|
|
|
|
|
ChangeVt(i32),
|
|
|
|
|
Suspend,
|
|
|
|
|
ToggleDebugTint,
|
|
|
|
|
Spawn(#[knuffel(arguments)] Vec<String>),
|
|
|
|
|
Screenshot,
|
|
|
|
|
CloseWindow,
|
|
|
|
|
FullscreenWindow,
|
|
|
|
|
FocusColumnLeft,
|
|
|
|
|
FocusColumnRight,
|
|
|
|
|
FocusWindowDown,
|
|
|
|
|
FocusWindowUp,
|
|
|
|
|
MoveColumnLeft,
|
|
|
|
|
MoveColumnRight,
|
|
|
|
|
MoveWindowDown,
|
|
|
|
|
MoveWindowUp,
|
|
|
|
|
ConsumeWindowIntoColumn,
|
|
|
|
|
ExpelWindowFromColumn,
|
|
|
|
|
FocusWorkspaceDown,
|
|
|
|
|
FocusWorkspaceUp,
|
2023-09-16 12:14:02 +04:00
|
|
|
FocusWorkspace(#[knuffel(argument)] u8),
|
2023-09-05 12:58:51 +04:00
|
|
|
MoveWindowToWorkspaceDown,
|
|
|
|
|
MoveWindowToWorkspaceUp,
|
2023-09-16 12:14:02 +04:00
|
|
|
MoveWindowToWorkspace(#[knuffel(argument)] u8),
|
2023-09-05 12:58:51 +04:00
|
|
|
FocusMonitorLeft,
|
|
|
|
|
FocusMonitorRight,
|
|
|
|
|
FocusMonitorDown,
|
|
|
|
|
FocusMonitorUp,
|
|
|
|
|
MoveWindowToMonitorLeft,
|
|
|
|
|
MoveWindowToMonitorRight,
|
|
|
|
|
MoveWindowToMonitorDown,
|
|
|
|
|
MoveWindowToMonitorUp,
|
|
|
|
|
SwitchPresetColumnWidth,
|
|
|
|
|
MaximizeColumn,
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-06 15:49:46 +04:00
|
|
|
#[derive(knuffel::Decode, Debug, PartialEq)]
|
|
|
|
|
pub struct DebugConfig {
|
|
|
|
|
#[knuffel(child, unwrap(argument), default = 1.)]
|
|
|
|
|
pub animation_slowdown: f64,
|
2023-09-08 17:54:02 +04:00
|
|
|
#[knuffel(child)]
|
2023-09-20 09:28:23 +04:00
|
|
|
pub dbus_interfaces_in_non_session_instances: bool,
|
2023-09-14 09:33:42 +04:00
|
|
|
#[knuffel(child)]
|
|
|
|
|
pub wait_for_frame_completion_before_queueing: bool,
|
2023-09-14 22:33:49 +04:00
|
|
|
#[knuffel(child)]
|
|
|
|
|
pub enable_color_transformations_capability: bool,
|
2023-09-14 22:43:12 +04:00
|
|
|
#[knuffel(child)]
|
|
|
|
|
pub enable_overlay_planes: bool,
|
2023-09-06 15:49:46 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for DebugConfig {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
animation_slowdown: 1.,
|
2023-09-20 09:28:23 +04:00
|
|
|
dbus_interfaces_in_non_session_instances: false,
|
2023-09-14 09:33:42 +04:00
|
|
|
wait_for_frame_completion_before_queueing: false,
|
2023-09-14 22:33:49 +04:00
|
|
|
enable_color_transformations_capability: false,
|
2023-09-14 22:43:12 +04:00
|
|
|
enable_overlay_planes: false,
|
2023-09-06 15:49:46 +04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-05 12:58:51 +04:00
|
|
|
impl Config {
|
2023-09-26 19:24:50 +04:00
|
|
|
pub fn load(path: Option<PathBuf>) -> miette::Result<(Self, PathBuf)> {
|
2023-09-05 12:58:51 +04:00
|
|
|
let path = if let Some(path) = path {
|
|
|
|
|
path
|
|
|
|
|
} else {
|
|
|
|
|
let mut path = ProjectDirs::from("", "", "niri")
|
|
|
|
|
.ok_or_else(|| miette!("error retrieving home directory"))?
|
|
|
|
|
.config_dir()
|
|
|
|
|
.to_owned();
|
|
|
|
|
path.push("config.kdl");
|
|
|
|
|
path
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let contents = std::fs::read_to_string(&path)
|
|
|
|
|
.into_diagnostic()
|
|
|
|
|
.with_context(|| format!("error reading {path:?}"))?;
|
|
|
|
|
|
|
|
|
|
let config = Self::parse("config.kdl", &contents).context("error parsing")?;
|
|
|
|
|
debug!("loaded config from {path:?}");
|
2023-09-26 19:24:50 +04:00
|
|
|
Ok((config, path))
|
2023-09-05 12:58:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn parse(filename: &str, text: &str) -> Result<Self, knuffel::Error> {
|
|
|
|
|
knuffel::parse(filename, text)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for Config {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Config::parse(
|
|
|
|
|
"default-config.kdl",
|
|
|
|
|
include_str!("../resources/default-config.kdl"),
|
|
|
|
|
)
|
|
|
|
|
.unwrap()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl FromStr for Key {
|
|
|
|
|
type Err = miette::Error;
|
|
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
|
|
|
let mut modifiers = Modifiers::empty();
|
|
|
|
|
|
|
|
|
|
let mut split = s.split('+');
|
|
|
|
|
let key = split.next_back().unwrap();
|
|
|
|
|
|
|
|
|
|
for part in split {
|
|
|
|
|
let part = part.trim();
|
|
|
|
|
if part.eq_ignore_ascii_case("mod") {
|
|
|
|
|
modifiers |= Modifiers::COMPOSITOR
|
|
|
|
|
} else if part.eq_ignore_ascii_case("ctrl") || part.eq_ignore_ascii_case("control") {
|
|
|
|
|
modifiers |= Modifiers::CTRL;
|
|
|
|
|
} else if part.eq_ignore_ascii_case("shift") {
|
|
|
|
|
modifiers |= Modifiers::SHIFT;
|
|
|
|
|
} else if part.eq_ignore_ascii_case("alt") {
|
|
|
|
|
modifiers |= Modifiers::ALT;
|
|
|
|
|
} else if part.eq_ignore_ascii_case("super") || part.eq_ignore_ascii_case("win") {
|
|
|
|
|
modifiers |= Modifiers::SUPER;
|
|
|
|
|
} else {
|
|
|
|
|
return Err(miette!("invalid modifier: {part}"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let keysym = keysym_from_name(key, KEYSYM_CASE_INSENSITIVE);
|
2023-09-24 11:04:30 +04:00
|
|
|
if keysym.raw() == KEY_NoSymbol {
|
2023-09-05 12:58:51 +04:00
|
|
|
return Err(miette!("invalid key: {key}"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(Key { keysym, modifiers })
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
#[track_caller]
|
|
|
|
|
fn check(text: &str, expected: Config) {
|
|
|
|
|
let parsed = Config::parse("test.kdl", text)
|
|
|
|
|
.map_err(miette::Report::new)
|
|
|
|
|
.unwrap();
|
|
|
|
|
assert_eq!(parsed, expected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn parse() {
|
|
|
|
|
check(
|
|
|
|
|
r#"
|
|
|
|
|
input {
|
|
|
|
|
keyboard {
|
2023-09-16 20:01:52 +04:00
|
|
|
repeat-delay 600
|
2023-09-16 12:37:23 +04:00
|
|
|
repeat-rate 25
|
2023-09-05 12:58:51 +04:00
|
|
|
xkb {
|
|
|
|
|
layout "us,ru"
|
|
|
|
|
options "grp:win_space_toggle"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
touchpad {
|
|
|
|
|
tap
|
|
|
|
|
accel-speed 0.2
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-21 13:48:32 +04:00
|
|
|
output "eDP-1" {
|
|
|
|
|
scale 2.0
|
2023-09-30 11:33:02 +04:00
|
|
|
position x=10 y=20
|
2023-09-21 13:48:32 +04:00
|
|
|
}
|
|
|
|
|
|
2023-09-21 19:58:03 +04:00
|
|
|
spawn-at-startup "alacritty" "-e" "fish"
|
|
|
|
|
|
2023-09-26 13:09:33 +04:00
|
|
|
focus-ring {
|
|
|
|
|
width 5
|
|
|
|
|
active-color 0.0 0.25 0.5 1.0
|
|
|
|
|
inactive-color 1.0 0.5 0.25 0.0
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-26 13:44:37 +04:00
|
|
|
prefer-no-csd
|
|
|
|
|
|
2023-10-01 17:42:56 +04:00
|
|
|
cursor {
|
|
|
|
|
xcursor-theme "breeze_cursors"
|
|
|
|
|
xcursor-size 16
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-05 12:58:51 +04:00
|
|
|
binds {
|
|
|
|
|
Mod+T { spawn "alacritty"; }
|
|
|
|
|
Mod+Q { close-window; }
|
|
|
|
|
Mod+Shift+H { focus-monitor-left; }
|
|
|
|
|
Mod+Ctrl+Shift+L { move-window-to-monitor-right; }
|
|
|
|
|
Mod+Comma { consume-window-into-column; }
|
2023-09-16 12:14:02 +04:00
|
|
|
Mod+1 { focus-workspace 1;}
|
2023-09-05 12:58:51 +04:00
|
|
|
}
|
2023-09-06 15:49:46 +04:00
|
|
|
|
|
|
|
|
debug {
|
|
|
|
|
animation-slowdown 2.0
|
|
|
|
|
}
|
2023-09-05 12:58:51 +04:00
|
|
|
"#,
|
|
|
|
|
Config {
|
|
|
|
|
input: Input {
|
|
|
|
|
keyboard: Keyboard {
|
|
|
|
|
xkb: Xkb {
|
|
|
|
|
layout: Some("us,ru".to_owned()),
|
|
|
|
|
options: Some("grp:win_space_toggle".to_owned()),
|
|
|
|
|
..Default::default()
|
|
|
|
|
},
|
2023-09-16 20:01:52 +04:00
|
|
|
repeat_delay: 600,
|
2023-09-16 12:37:23 +04:00
|
|
|
repeat_rate: 25,
|
2023-09-05 12:58:51 +04:00
|
|
|
},
|
|
|
|
|
touchpad: Touchpad {
|
|
|
|
|
tap: true,
|
|
|
|
|
natural_scroll: false,
|
|
|
|
|
accel_speed: 0.2,
|
|
|
|
|
},
|
|
|
|
|
},
|
2023-09-21 13:48:32 +04:00
|
|
|
outputs: vec![Output {
|
|
|
|
|
name: "eDP-1".to_owned(),
|
|
|
|
|
scale: 2.,
|
2023-09-30 11:33:02 +04:00
|
|
|
position: Some(Position { x: 10, y: 20 }),
|
2023-09-21 13:48:32 +04:00
|
|
|
}],
|
2023-09-21 19:58:03 +04:00
|
|
|
spawn_at_startup: vec![SpawnAtStartup {
|
|
|
|
|
command: vec!["alacritty".to_owned(), "-e".to_owned(), "fish".to_owned()],
|
|
|
|
|
}],
|
2023-09-26 13:09:33 +04:00
|
|
|
focus_ring: FocusRing {
|
|
|
|
|
off: false,
|
|
|
|
|
width: 5,
|
|
|
|
|
active_color: Color {
|
|
|
|
|
r: 0.,
|
|
|
|
|
g: 0.25,
|
|
|
|
|
b: 0.5,
|
|
|
|
|
a: 1.,
|
|
|
|
|
},
|
|
|
|
|
inactive_color: Color {
|
|
|
|
|
r: 1.,
|
|
|
|
|
g: 0.5,
|
|
|
|
|
b: 0.25,
|
|
|
|
|
a: 0.,
|
|
|
|
|
},
|
|
|
|
|
},
|
2023-09-26 13:44:37 +04:00
|
|
|
prefer_no_csd: true,
|
2023-10-01 17:42:56 +04:00
|
|
|
cursor: Cursor {
|
|
|
|
|
xcursor_theme: String::from("breeze_cursors"),
|
|
|
|
|
xcursor_size: 16,
|
|
|
|
|
},
|
2023-09-05 12:58:51 +04:00
|
|
|
binds: Binds(vec![
|
|
|
|
|
Bind {
|
|
|
|
|
key: Key {
|
2023-09-24 11:04:30 +04:00
|
|
|
keysym: Keysym::t,
|
2023-09-05 12:58:51 +04:00
|
|
|
modifiers: Modifiers::COMPOSITOR,
|
|
|
|
|
},
|
|
|
|
|
actions: vec![Action::Spawn(vec!["alacritty".to_owned()])],
|
|
|
|
|
},
|
|
|
|
|
Bind {
|
|
|
|
|
key: Key {
|
2023-09-24 11:04:30 +04:00
|
|
|
keysym: Keysym::q,
|
2023-09-05 12:58:51 +04:00
|
|
|
modifiers: Modifiers::COMPOSITOR,
|
|
|
|
|
},
|
|
|
|
|
actions: vec![Action::CloseWindow],
|
|
|
|
|
},
|
|
|
|
|
Bind {
|
|
|
|
|
key: Key {
|
2023-09-24 11:04:30 +04:00
|
|
|
keysym: Keysym::h,
|
2023-09-05 12:58:51 +04:00
|
|
|
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT,
|
|
|
|
|
},
|
|
|
|
|
actions: vec![Action::FocusMonitorLeft],
|
|
|
|
|
},
|
|
|
|
|
Bind {
|
|
|
|
|
key: Key {
|
2023-09-24 11:04:30 +04:00
|
|
|
keysym: Keysym::l,
|
2023-09-05 12:58:51 +04:00
|
|
|
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT | Modifiers::CTRL,
|
|
|
|
|
},
|
|
|
|
|
actions: vec![Action::MoveWindowToMonitorRight],
|
|
|
|
|
},
|
|
|
|
|
Bind {
|
|
|
|
|
key: Key {
|
2023-09-24 11:04:30 +04:00
|
|
|
keysym: Keysym::comma,
|
2023-09-05 12:58:51 +04:00
|
|
|
modifiers: Modifiers::COMPOSITOR,
|
|
|
|
|
},
|
|
|
|
|
actions: vec![Action::ConsumeWindowIntoColumn],
|
|
|
|
|
},
|
2023-09-16 12:14:02 +04:00
|
|
|
Bind {
|
|
|
|
|
key: Key {
|
2023-09-24 11:04:30 +04:00
|
|
|
keysym: Keysym::_1,
|
2023-09-16 12:14:02 +04:00
|
|
|
modifiers: Modifiers::COMPOSITOR,
|
|
|
|
|
},
|
|
|
|
|
actions: vec![Action::FocusWorkspace(1)],
|
|
|
|
|
},
|
2023-09-05 12:58:51 +04:00
|
|
|
]),
|
2023-09-06 15:49:46 +04:00
|
|
|
debug: DebugConfig {
|
|
|
|
|
animation_slowdown: 2.,
|
2023-09-08 17:54:02 +04:00
|
|
|
..Default::default()
|
2023-09-06 15:49:46 +04:00
|
|
|
},
|
2023-09-05 12:58:51 +04:00
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn can_create_default_config() {
|
|
|
|
|
let _ = Config::default();
|
|
|
|
|
}
|
|
|
|
|
}
|