Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add new config general.shutdown_commands and general.reload_commands and shutdown/reload Zebar along side the WM #713

Merged
merged 5 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ general:
# another application).
startup_commands: []

# Commands to run just before the WM is shutdown.
shutdown_commands : []

# Commands to run after the WM config has reloaded.
JonasWischeropp marked this conversation as resolved.
Show resolved Hide resolved
config_reload_commands: []

# Whether to automatically focus windows underneath the cursor.
focus_follows_cursor: false

Expand Down
2 changes: 1 addition & 1 deletion packages/watcher/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async fn main() -> anyhow::Result<()> {
match subscribe_res {
Ok(_) => info!("WM exited successfully. Skipping watcher cleanup."),
Err(err) => {
info!("Running watcher cleanup. WM exitted unexpectedly: {}", err);
info!("Running watcher cleanup. WM exited unexpectedly: {}", err);

let managed_windows = managed_handles
.into_iter()
Expand Down
51 changes: 49 additions & 2 deletions packages/wm/src/app_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
common::{
commands::{
cycle_focus, disable_binding_mode, enable_binding_mode,
reload_config, shell_exec,
platform_sync, reload_config, shell_exec,
},
Direction, LengthValue, RectDelta, TilingDirection,
},
Expand Down Expand Up @@ -604,6 +604,14 @@ impl InvokeCommand {
enable_binding_mode(name, state, config)
}
InvokeCommand::WmExit => {
Self::run_multiple(
config.value.general.shutdown_commands.clone(),
subject_container,
state,
config,
)?;
platform_sync(state, config)?;

state.emit_exit();
Ok(())
}
Expand All @@ -616,9 +624,48 @@ impl InvokeCommand {

Ok(())
}
InvokeCommand::WmReloadConfig => reload_config(state, config),
InvokeCommand::WmReloadConfig => {
reload_config(state, config)?;

Self::run_multiple(
config.value.general.config_reload_commands.clone(),
subject_container,
state,
config,
)?;
platform_sync(state, config)?;
Ok(())
}
}
}

pub fn run_multiple(
commands: Vec<InvokeCommand>,
subject_container: Container,
state: &mut WmState,
config: &mut UserConfig,
) -> anyhow::Result<Uuid> {
let mut current_subject_container = subject_container;

for command in commands {
command.run(current_subject_container.clone(), state, config)?;

// Update the subject container in case the container type changes.
// For example, when going from a tiling to a floating window.
current_subject_container =
match current_subject_container.is_detached() {
false => current_subject_container,
true => {
match state.container_by_id(current_subject_container.id()) {
Some(container) => container,
None => break,
}
}
}
}

Ok(current_subject_container.id())
}
}

impl<'de> Deserialize<'de> for InvokeCommand {
Expand Down
8 changes: 8 additions & 0 deletions packages/wm/src/user_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,14 @@ pub struct GeneralConfig {
/// launch another application).
#[serde(default)]
pub startup_commands: Vec<InvokeCommand>,

/// Commands to run just before the WM is shutdown.
#[serde(default)]
pub shutdown_commands: Vec<InvokeCommand>,

/// Commands to run after the WM config has reloaded.
#[serde(default)]
pub config_reload_commands: Vec<InvokeCommand>,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
Expand Down
25 changes: 8 additions & 17 deletions packages/wm/src/wm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use crate::{
},
platform::PlatformEvent,
},
containers::traits::CommonGetters,
user_config::UserConfig,
wm_event::WmEvent,
wm_state::WmState,
Expand Down Expand Up @@ -110,7 +109,7 @@ impl WindowManager {
let state = &mut self.state;

// Get the container to run WM commands with.
let mut subject_container = match subject_container_id {
let subject_container = match subject_container_id {
Some(id) => state.container_by_id(id).with_context(|| {
format!("No container found with the given ID '{}'.", id)
})?,
Expand All @@ -119,22 +118,14 @@ impl WindowManager {
.context("No subject container for command.")?,
};

for command in commands {
command.run(subject_container.clone(), state, config)?;

// Update the subject container in case the container type changes.
// For example, when going from a tiling to a floating window.
subject_container = match subject_container.is_detached() {
false => subject_container,
true => match state.container_by_id(subject_container.id()) {
Some(container) => container,
None => break,
},
}
}

let new_subject_container_id = InvokeCommand::run_multiple(
commands,
subject_container,
state,
config,
)?;
platform_sync(state, config)?;

Ok(subject_container.id())
Ok(new_subject_container_id)
}
}
10 changes: 10 additions & 0 deletions resources/assets/sample-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ general:
# Commands to run when the WM has started (e.g. to run a script or launch
# another application). Here we are running a batch script to start Zebar.
startup_commands: ['shell-exec %userprofile%/.glzr/zebar/start.bat']
# Similarly commands can be executed just before the WM is shutdown
# and after the config has reloaded.
# Here we shutdown Zebar when the WM is shutdown.
shutdown_commands: ['shell-exec taskkill /IM zebar.exe /F']
# Here we restart Zebar to reload the Zebar config when reloading the
# WM config.
config_reload_commands: [
'shell-exec taskkill /IM zebar.exe /F',
'shell-exec %userprofile%/.glzr/zebar/start.bat'
]

# Whether to automatically focus windows underneath the cursor.
focus_follows_cursor: false
Expand Down