config: add window-rule infrastructure
This commit is contained in:
parent
a6257910bb
commit
59f8acdfde
26 changed files with 1829 additions and 38 deletions
|
|
@ -14,7 +14,7 @@ use {
|
|||
config::{
|
||||
Action, ClientRule, Config, ConfigConnector, ConfigDrmDevice, ConfigKeymap,
|
||||
ConnectorMatch, DrmDeviceMatch, Exec, Input, InputMatch, Output, OutputMatch, Shortcut,
|
||||
SimpleCommand, Status, Theme, parse_config,
|
||||
SimpleCommand, Status, Theme, WindowRule, parse_config,
|
||||
},
|
||||
rules::{MatcherTemp, RuleMapper},
|
||||
},
|
||||
|
|
@ -47,6 +47,7 @@ use {
|
|||
on_new_connector, on_new_drm_device, set_direct_scanout_enabled, set_gfx_api,
|
||||
set_tearing_mode, set_vrr_cursor_hz, set_vrr_mode,
|
||||
},
|
||||
window::Window,
|
||||
xwayland::set_x_scaling_mode,
|
||||
},
|
||||
run_on_drop::on_drop,
|
||||
|
|
@ -100,24 +101,39 @@ impl Action {
|
|||
}};
|
||||
}
|
||||
let s = state.persistent.seat;
|
||||
macro_rules! window_or_seat {
|
||||
($name:ident, $expr:expr) => {{
|
||||
let state = state.clone();
|
||||
B::new(move || {
|
||||
if let Some($name) = state.window.get() {
|
||||
if let Some($name) = $name {
|
||||
$expr;
|
||||
}
|
||||
} else {
|
||||
let $name = s;
|
||||
$expr;
|
||||
}
|
||||
})
|
||||
}};
|
||||
}
|
||||
match self {
|
||||
Action::SimpleCommand { cmd } => match cmd {
|
||||
SimpleCommand::Focus(dir) => B::new(move || s.focus(dir)),
|
||||
SimpleCommand::Move(dir) => B::new(move || s.move_(dir)),
|
||||
SimpleCommand::Split(axis) => B::new(move || s.create_split(axis)),
|
||||
SimpleCommand::ToggleSplit => B::new(move || s.toggle_split()),
|
||||
SimpleCommand::SetSplit(b) => B::new(move || s.set_split(b)),
|
||||
SimpleCommand::ToggleMono => B::new(move || s.toggle_mono()),
|
||||
SimpleCommand::SetMono(b) => B::new(move || s.set_mono(b)),
|
||||
SimpleCommand::ToggleFullscreen => B::new(move || s.toggle_fullscreen()),
|
||||
SimpleCommand::SetFullscreen(b) => B::new(move || s.set_fullscreen(b)),
|
||||
SimpleCommand::Move(dir) => window_or_seat!(s, s.move_(dir)),
|
||||
SimpleCommand::Split(axis) => window_or_seat!(s, s.create_split(axis)),
|
||||
SimpleCommand::ToggleSplit => window_or_seat!(s, s.toggle_split()),
|
||||
SimpleCommand::SetSplit(b) => window_or_seat!(s, s.set_split(b)),
|
||||
SimpleCommand::ToggleMono => window_or_seat!(s, s.toggle_mono()),
|
||||
SimpleCommand::SetMono(b) => window_or_seat!(s, s.set_mono(b)),
|
||||
SimpleCommand::ToggleFullscreen => window_or_seat!(s, s.toggle_fullscreen()),
|
||||
SimpleCommand::SetFullscreen(b) => window_or_seat!(s, s.set_fullscreen(b)),
|
||||
SimpleCommand::FocusParent => B::new(move || s.focus_parent()),
|
||||
SimpleCommand::Close => B::new(move || s.close()),
|
||||
SimpleCommand::Close => window_or_seat!(s, s.close()),
|
||||
SimpleCommand::DisablePointerConstraint => {
|
||||
B::new(move || s.disable_pointer_constraint())
|
||||
}
|
||||
SimpleCommand::ToggleFloating => B::new(move || s.toggle_floating()),
|
||||
SimpleCommand::SetFloating(b) => B::new(move || s.set_floating(b)),
|
||||
SimpleCommand::ToggleFloating => window_or_seat!(s, s.toggle_floating()),
|
||||
SimpleCommand::SetFloating(b) => window_or_seat!(s, s.set_floating(b)),
|
||||
SimpleCommand::Quit => B::new(quit),
|
||||
SimpleCommand::ReloadConfigToml => {
|
||||
let persistent = state.persistent.clone();
|
||||
|
|
@ -133,8 +149,10 @@ impl Action {
|
|||
B::new(move || set_float_above_fullscreen(bool))
|
||||
}
|
||||
SimpleCommand::ToggleFloatAboveFullscreen => B::new(toggle_float_above_fullscreen),
|
||||
SimpleCommand::SetFloatPinned(pinned) => B::new(move || s.set_float_pinned(pinned)),
|
||||
SimpleCommand::ToggleFloatPinned => B::new(move || s.toggle_float_pinned()),
|
||||
SimpleCommand::SetFloatPinned(pinned) => {
|
||||
window_or_seat!(s, s.set_float_pinned(pinned))
|
||||
}
|
||||
SimpleCommand::ToggleFloatPinned => window_or_seat!(s, s.toggle_float_pinned()),
|
||||
SimpleCommand::KillClient => client_action!(c, c.kill()),
|
||||
},
|
||||
Action::Multi { actions } => {
|
||||
|
|
@ -153,7 +171,7 @@ impl Action {
|
|||
}
|
||||
Action::MoveToWorkspace { name } => {
|
||||
let workspace = get_workspace(&name);
|
||||
B::new(move || s.set_workspace(workspace))
|
||||
window_or_seat!(s, s.set_workspace(workspace))
|
||||
}
|
||||
Action::ConfigureConnector { con } => B::new(move || {
|
||||
for c in connectors() {
|
||||
|
|
@ -689,6 +707,8 @@ struct State {
|
|||
action_depth: Cell<u64>,
|
||||
|
||||
client: Cell<Option<Client>>,
|
||||
|
||||
window: Cell<Option<Option<Window>>>,
|
||||
}
|
||||
|
||||
impl Drop for State {
|
||||
|
|
@ -897,13 +917,23 @@ impl State {
|
|||
|
||||
fn with_client(&self, client: Client, check: bool, f: impl FnOnce()) {
|
||||
let mut opt = Some(client);
|
||||
if check && client.does_not_exist() {
|
||||
if client.0 == 0 || (check && client.does_not_exist()) {
|
||||
opt = None;
|
||||
}
|
||||
self.client.set(opt);
|
||||
f();
|
||||
self.client.set(None);
|
||||
}
|
||||
|
||||
fn with_window(&self, window: Window, check: bool, f: impl FnOnce()) {
|
||||
let mut w = Some(window);
|
||||
if check && !window.exists() {
|
||||
w = None;
|
||||
}
|
||||
self.window.set(Some(w));
|
||||
f();
|
||||
self.window.set(None);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Hash)]
|
||||
|
|
@ -922,6 +952,7 @@ struct PersistentState {
|
|||
actions: RefCell<AHashMap<Rc<String>, Rc<dyn Fn()>>>,
|
||||
client_rules: Cell<Vec<MatcherTemp<ClientRule>>>,
|
||||
client_rule_mapper: RefCell<Option<RuleMapper<ClientRule>>>,
|
||||
window_rules: Cell<Vec<MatcherTemp<WindowRule>>>,
|
||||
}
|
||||
|
||||
fn load_config(initial_load: bool, persistent: &Rc<PersistentState>) {
|
||||
|
|
@ -1003,10 +1034,13 @@ fn load_config(initial_load: bool, persistent: &Rc<PersistentState>) {
|
|||
action_depth_max: config.max_action_depth,
|
||||
action_depth: Cell::new(0),
|
||||
client: Default::default(),
|
||||
window: Default::default(),
|
||||
});
|
||||
let (client_rules, client_rule_mapper) = state.create_rules(&config.client_rules);
|
||||
persistent.client_rules.set(client_rules);
|
||||
*state.persistent.client_rule_mapper.borrow_mut() = Some(client_rule_mapper);
|
||||
let (window_rules, _) = state.create_rules(&config.window_rules);
|
||||
persistent.window_rules.set(window_rules);
|
||||
state.set_status(&config.status);
|
||||
persistent.actions.borrow_mut().clear();
|
||||
for a in config.named_actions {
|
||||
|
|
@ -1231,6 +1265,7 @@ pub fn configure() {
|
|||
actions: Default::default(),
|
||||
client_rules: Default::default(),
|
||||
client_rule_mapper: Default::default(),
|
||||
window_rules: Default::default(),
|
||||
});
|
||||
{
|
||||
let p = persistent.clone();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue