mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-09-12 21:02:08 +02:00
feat(wm): add replace configuration socket message
This commit introduces a new SocketMessage, ReplaceConfiguration, which attempts to replace a running instance of WindowManager with another created from a (presumably) different komorebi.json file. This will likely be useful for people who have multiple different monitor setups that they connect and disconnect from throughout the day, but definitely needs more testing. An experimental sub-widget which calls this SocketMessage has been added to komorebi-bar to aid with initial testing.
This commit is contained in:
@@ -133,6 +133,7 @@ pub enum SocketMessage {
|
||||
ClearNamedWorkspaceLayoutRules(String),
|
||||
// Configuration
|
||||
ReloadConfiguration,
|
||||
ReplaceConfiguration(PathBuf),
|
||||
ReloadStaticConfiguration(PathBuf),
|
||||
WatchConfiguration(bool),
|
||||
CompleteConfiguration,
|
||||
|
||||
@@ -220,6 +220,7 @@ fn main() -> Result<()> {
|
||||
Arc::new(Mutex::new(StaticConfig::preload(
|
||||
config,
|
||||
winevent_listener::event_rx(),
|
||||
None,
|
||||
)?))
|
||||
} else {
|
||||
Arc::new(Mutex::new(WindowManager::new(
|
||||
|
||||
@@ -56,6 +56,7 @@ use crate::window::Window;
|
||||
use crate::window_manager;
|
||||
use crate::window_manager::WindowManager;
|
||||
use crate::windows_api::WindowsApi;
|
||||
use crate::winevent_listener;
|
||||
use crate::GlobalState;
|
||||
use crate::Notification;
|
||||
use crate::NotificationEvent;
|
||||
@@ -1097,6 +1098,33 @@ impl WindowManager {
|
||||
SocketMessage::ReloadConfiguration => {
|
||||
Self::reload_configuration();
|
||||
}
|
||||
SocketMessage::ReplaceConfiguration(ref config) => {
|
||||
// Check that this is a valid static config file first
|
||||
if StaticConfig::read(config).is_ok() {
|
||||
// Clear workspace rules; these will need to be replaced
|
||||
WORKSPACE_RULES.lock().clear();
|
||||
// Pause so that restored windows come to the foreground from all workspaces
|
||||
self.is_paused = true;
|
||||
// Bring all windows to the foreground
|
||||
self.restore_all_windows()?;
|
||||
|
||||
// Create a new wm from the config path
|
||||
let mut wm = StaticConfig::preload(
|
||||
config,
|
||||
winevent_listener::event_rx(),
|
||||
self.command_listener.try_clone().ok(),
|
||||
)?;
|
||||
|
||||
// Initialize the new wm
|
||||
wm.init()?;
|
||||
|
||||
// This is equivalent to StaticConfig::postload for this use case
|
||||
StaticConfig::reload(config, &mut wm)?;
|
||||
|
||||
// Set self to the new wm instance
|
||||
*self = wm;
|
||||
}
|
||||
}
|
||||
SocketMessage::ReloadStaticConfiguration(ref pathbuf) => {
|
||||
self.reload_static_configuration(pathbuf)?;
|
||||
}
|
||||
|
||||
@@ -1027,26 +1027,32 @@ impl StaticConfig {
|
||||
pub fn preload(
|
||||
path: &PathBuf,
|
||||
incoming: Receiver<WindowManagerEvent>,
|
||||
unix_listener: Option<UnixListener>,
|
||||
) -> Result<WindowManager> {
|
||||
let content = std::fs::read_to_string(path)?;
|
||||
let mut value: Self = serde_json::from_str(&content)?;
|
||||
value.apply_globals()?;
|
||||
|
||||
let socket = DATA_DIR.join("komorebi.sock");
|
||||
let listener = match unix_listener {
|
||||
Some(listener) => listener,
|
||||
None => {
|
||||
let socket = DATA_DIR.join("komorebi.sock");
|
||||
|
||||
match std::fs::remove_file(&socket) {
|
||||
Ok(()) => {}
|
||||
Err(error) => match error.kind() {
|
||||
// Doing this because ::exists() doesn't work reliably on Windows via IntelliJ
|
||||
ErrorKind::NotFound => {}
|
||||
_ => {
|
||||
return Err(error.into());
|
||||
}
|
||||
},
|
||||
match std::fs::remove_file(&socket) {
|
||||
Ok(()) => {}
|
||||
Err(error) => match error.kind() {
|
||||
// Doing this because ::exists() doesn't work reliably on Windows via IntelliJ
|
||||
ErrorKind::NotFound => {}
|
||||
_ => {
|
||||
return Err(error.into());
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
UnixListener::bind(&socket)?
|
||||
}
|
||||
};
|
||||
|
||||
let listener = UnixListener::bind(&socket)?;
|
||||
|
||||
let mut wm = WindowManager {
|
||||
monitors: Ring::default(),
|
||||
incoming_events: incoming,
|
||||
|
||||
Reference in New Issue
Block a user