feat(wm): add focus-workspaces cmd

This commit adds a new command, focus-workspaces, to allow the user to
change workspaces across all monitors at the same time. I'm not
convinced of the stability of this command and I would strongly
discourage using komorebi in this manner.

resolve #426
This commit is contained in:
LGUG2Z
2023-06-03 17:24:36 -07:00
parent 7ba7067c96
commit 9103ce2b2b
13 changed files with 130 additions and 89 deletions
+3
View File
@@ -0,0 +1,3 @@
{:
"path": "cz-conventional-changelog"
}
+9 -21
View File
@@ -24,31 +24,19 @@ impl ApplicationOptions {
pub fn raw_cfgen(&self, kind: &ApplicationIdentifier, id: &str) -> String { pub fn raw_cfgen(&self, kind: &ApplicationIdentifier, id: &str) -> String {
match self { match self {
ApplicationOptions::ObjectNameChange => { ApplicationOptions::ObjectNameChange => {
format!( format!("komorebic.exe identify-object-name-change-application {kind} \"{id}\"",)
"komorebic.exe identify-object-name-change-application {} \"{}\"",
kind, id
)
} }
ApplicationOptions::Layered => { ApplicationOptions::Layered => {
format!( format!("komorebic.exe identify-layered-application {kind} \"{id}\"",)
"komorebic.exe identify-layered-application {} \"{}\"",
kind, id
)
} }
ApplicationOptions::BorderOverflow => { ApplicationOptions::BorderOverflow => {
format!( format!("komorebic.exe identify-border-overflow-application {kind} \"{id}\"",)
"komorebic.exe identify-border-overflow-application {} \"{}\"",
kind, id
)
} }
ApplicationOptions::TrayAndMultiWindow => { ApplicationOptions::TrayAndMultiWindow => {
format!( format!("komorebic.exe identify-tray-application {kind} \"{id}\"",)
"komorebic.exe identify-tray-application {} \"{}\"",
kind, id
)
} }
ApplicationOptions::Force => { ApplicationOptions::Force => {
format!("komorebic.exe manage-rule {} \"{}\"", kind, id) format!("komorebic.exe manage-rule {kind} \"{id}\"")
} }
} }
} }
@@ -143,7 +131,7 @@ impl ApplicationConfigurationGenerator {
lines.push(format!("# {}", app.name)); lines.push(format!("# {}", app.name));
if let Some(options) = app.options { if let Some(options) = app.options {
for opt in options { for opt in options {
if let ApplicationOptions::TrayAndMultiWindow = opt { if matches!(opt, ApplicationOptions::TrayAndMultiWindow) {
lines.push(String::from("# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line")); lines.push(String::from("# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line"));
} }
@@ -161,7 +149,7 @@ impl ApplicationConfigurationGenerator {
float_rules.push(float_rule.clone()); float_rules.push(float_rule.clone());
if let Some(comment) = float.comment { if let Some(comment) = float.comment {
lines.push(format!("# {}", comment)); lines.push(format!("# {comment}"));
}; };
lines.push(float_rule); lines.push(float_rule);
@@ -192,7 +180,7 @@ impl ApplicationConfigurationGenerator {
lines.push(format!("; {}", app.name)); lines.push(format!("; {}", app.name));
if let Some(options) = app.options { if let Some(options) = app.options {
for opt in options { for opt in options {
if let ApplicationOptions::TrayAndMultiWindow = opt { if matches!(opt, ApplicationOptions::TrayAndMultiWindow) {
lines.push(String::from("; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line")); lines.push(String::from("; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line"));
} }
@@ -212,7 +200,7 @@ impl ApplicationConfigurationGenerator {
float_rules.push(float_rule.clone()); float_rules.push(float_rule.clone());
if let Some(comment) = float.comment { if let Some(comment) = float.comment {
lines.push(format!("; {}", comment)); lines.push(format!("; {comment}"));
}; };
lines.push(float_rule); lines.push(float_rule);
+1
View File
@@ -95,6 +95,7 @@ pub enum SocketMessage {
CycleFocusWorkspace(CycleDirection), CycleFocusWorkspace(CycleDirection),
FocusMonitorNumber(usize), FocusMonitorNumber(usize),
FocusWorkspaceNumber(usize), FocusWorkspaceNumber(usize),
FocusWorkspaceNumbers(usize),
FocusMonitorWorkspaceNumber(usize, usize), FocusMonitorWorkspaceNumber(usize, usize),
FocusNamedWorkspace(String), FocusNamedWorkspace(String),
ContainerPadding(usize, usize, i32), ContainerPadding(usize, usize, i32),
+15
View File
@@ -20,6 +20,9 @@ RunWait('komorebic.exe identify-border-overflow-application class "Photoshop"',
; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
RunWait('komorebic.exe identify-tray-application exe "Akiflow.exe"', , "Hide") RunWait('komorebic.exe identify-tray-application exe "Akiflow.exe"', , "Hide")
; Android Studio
RunWait('komorebic.exe identify-object-name-change-application exe "studio64.exe"', , "Hide")
; ArmCord ; ArmCord
RunWait('komorebic.exe identify-border-overflow-application exe "ArmCord.exe"', , "Hide") RunWait('komorebic.exe identify-border-overflow-application exe "ArmCord.exe"', , "Hide")
; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
@@ -274,6 +277,9 @@ RunWait('komorebic.exe identify-tray-application class "DocEditorsWindowClass"',
RunWait('komorebic.exe identify-border-overflow-application exe "Obsidian.exe"', , "Hide") RunWait('komorebic.exe identify-border-overflow-application exe "Obsidian.exe"', , "Hide")
RunWait('komorebic.exe manage-rule exe "Obsidian.exe"', , "Hide") RunWait('komorebic.exe manage-rule exe "Obsidian.exe"', , "Hide")
; OneDrive
RunWait('komorebic.exe float-rule class "OneDriveReactNativeWin32WindowClass"', , "Hide")
; OpenRGB ; OpenRGB
; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
RunWait('komorebic.exe identify-tray-application exe "OpenRGB.exe"', , "Hide") RunWait('komorebic.exe identify-tray-application exe "OpenRGB.exe"', , "Hide")
@@ -289,6 +295,8 @@ RunWait('komorebic.exe identify-border-overflow-application exe "Plexamp.exe"',
RunWait('komorebic.exe float-rule exe "PowerToys.ColorPickerUI.exe"', , "Hide") RunWait('komorebic.exe float-rule exe "PowerToys.ColorPickerUI.exe"', , "Hide")
; Target image resizer dialog ; Target image resizer dialog
RunWait('komorebic.exe float-rule exe "PowerToys.ImageResizer.exe"', , "Hide") RunWait('komorebic.exe float-rule exe "PowerToys.ImageResizer.exe"', , "Hide")
; Target Peek popup
RunWait('komorebic.exe float-rule exe "PowerToys.Peek.UI.exe"', , "Hide")
; Process Hacker ; Process Hacker
; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
@@ -420,6 +428,10 @@ RunWait('komorebic.exe float-rule exe "TranslucentTB.exe"', , "Hide")
; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
RunWait('komorebic.exe identify-tray-application exe "TranslucentTB.exe"', , "Hide") RunWait('komorebic.exe identify-tray-application exe "TranslucentTB.exe"', , "Hide")
; Unity Hub
; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
RunWait('komorebic.exe identify-tray-application exe "Unity Hub.exe"', , "Hide")
; Unreal Editor ; Unreal Editor
RunWait('komorebic.exe identify-border-overflow-application exe "UnrealEditor.exe"', , "Hide") RunWait('komorebic.exe identify-border-overflow-application exe "UnrealEditor.exe"', , "Hide")
; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
@@ -435,6 +447,9 @@ RunWait('komorebic.exe identify-object-name-change-application exe "devenv.exe"'
; Visual Studio Code ; Visual Studio Code
RunWait('komorebic.exe identify-border-overflow-application exe "Code.exe"', , "Hide") RunWait('komorebic.exe identify-border-overflow-application exe "Code.exe"', , "Hide")
; Visual Studio Code - Insiders
RunWait('komorebic.exe identify-border-overflow-application exe "Code - Insiders.exe"', , "Hide")
; Voice.ai ; Voice.ai
RunWait('komorebic.exe identify-border-overflow-application exe "VoiceAI.exe"', , "Hide") RunWait('komorebic.exe identify-border-overflow-application exe "VoiceAI.exe"', , "Hide")
; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line ; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
+15
View File
@@ -20,6 +20,9 @@ komorebic.exe identify-border-overflow-application class "Photoshop"
# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
komorebic.exe identify-tray-application exe "Akiflow.exe" komorebic.exe identify-tray-application exe "Akiflow.exe"
# Android Studio
komorebic.exe identify-object-name-change-application exe "studio64.exe"
# ArmCord # ArmCord
komorebic.exe identify-border-overflow-application exe "ArmCord.exe" komorebic.exe identify-border-overflow-application exe "ArmCord.exe"
# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
@@ -274,6 +277,9 @@ komorebic.exe identify-tray-application class "DocEditorsWindowClass"
komorebic.exe identify-border-overflow-application exe "Obsidian.exe" komorebic.exe identify-border-overflow-application exe "Obsidian.exe"
komorebic.exe manage-rule exe "Obsidian.exe" komorebic.exe manage-rule exe "Obsidian.exe"
# OneDrive
komorebic.exe float-rule class "OneDriveReactNativeWin32WindowClass"
# OpenRGB # OpenRGB
# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
komorebic.exe identify-tray-application exe "OpenRGB.exe" komorebic.exe identify-tray-application exe "OpenRGB.exe"
@@ -289,6 +295,8 @@ komorebic.exe identify-border-overflow-application exe "Plexamp.exe"
komorebic.exe float-rule exe "PowerToys.ColorPickerUI.exe" komorebic.exe float-rule exe "PowerToys.ColorPickerUI.exe"
# Target image resizer dialog # Target image resizer dialog
komorebic.exe float-rule exe "PowerToys.ImageResizer.exe" komorebic.exe float-rule exe "PowerToys.ImageResizer.exe"
# Target Peek popup
komorebic.exe float-rule exe "PowerToys.Peek.UI.exe"
# Process Hacker # Process Hacker
# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
@@ -420,6 +428,10 @@ komorebic.exe float-rule exe "TranslucentTB.exe"
# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
komorebic.exe identify-tray-application exe "TranslucentTB.exe" komorebic.exe identify-tray-application exe "TranslucentTB.exe"
# Unity Hub
# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
komorebic.exe identify-tray-application exe "Unity Hub.exe"
# Unreal Editor # Unreal Editor
komorebic.exe identify-border-overflow-application exe "UnrealEditor.exe" komorebic.exe identify-border-overflow-application exe "UnrealEditor.exe"
# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
@@ -435,6 +447,9 @@ komorebic.exe identify-object-name-change-application exe "devenv.exe"
# Visual Studio Code # Visual Studio Code
komorebic.exe identify-border-overflow-application exe "Code.exe" komorebic.exe identify-border-overflow-application exe "Code.exe"
# Visual Studio Code - Insiders
komorebic.exe identify-border-overflow-application exe "Code - Insiders.exe"
# Voice.ai # Voice.ai
komorebic.exe identify-border-overflow-application exe "VoiceAI.exe" komorebic.exe identify-border-overflow-application exe "VoiceAI.exe"
# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line # If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
+2 -3
View File
@@ -122,8 +122,7 @@ lazy_static! {
home home
} else { } else {
panic!( panic!(
"$Env:KOMOREBI_CONFIG_HOME is set to '{}', which is not a valid directory", "$Env:KOMOREBI_CONFIG_HOME is set to '{home_path}', which is not a valid directory",
home_path
); );
} }
}) })
@@ -344,7 +343,7 @@ pub fn notify_subscribers(notification: &str) -> Result<()> {
let mut stale_subscriptions = vec![]; let mut stale_subscriptions = vec![];
let mut subscriptions = SUBSCRIPTION_PIPES.lock(); let mut subscriptions = SUBSCRIPTION_PIPES.lock();
for (subscriber, pipe) in subscriptions.iter_mut() { for (subscriber, pipe) in subscriptions.iter_mut() {
match writeln!(pipe, "{}", notification) { match writeln!(pipe, "{notification}") {
Ok(_) => { Ok(_) => {
tracing::debug!("pushed notification to subscriber: {}", subscriber); tracing::debug!("pushed notification to subscriber: {}", subscriber);
} }
+36 -15
View File
@@ -97,7 +97,7 @@ pub fn listen_for_commands(wm: Arc<Mutex<WindowManager>>) {
#[tracing::instrument] #[tracing::instrument]
pub fn listen_for_commands_tcp(wm: Arc<Mutex<WindowManager>>, port: usize) { pub fn listen_for_commands_tcp(wm: Arc<Mutex<WindowManager>>, port: usize) {
let listener = let listener =
TcpListener::bind(format!("0.0.0.0:{}", port)).expect("could not start tcp server"); TcpListener::bind(format!("0.0.0.0:{port}")).expect("could not start tcp server");
std::thread::spawn(move || { std::thread::spawn(move || {
tracing::info!("listening on 0.0.0.0:43663"); tracing::info!("listening on 0.0.0.0:43663");
@@ -557,6 +557,29 @@ impl WindowManager {
self.show_border()?; self.show_border()?;
}; };
} }
SocketMessage::FocusWorkspaceNumbers(workspace_idx) => {
// This is to ensure that even on an empty workspace on a secondary monitor, the
// secondary monitor where the cursor is focused will be used as the target for
// the workspace switch op
if let Some(monitor_idx) = self.monitor_idx_from_current_pos() {
self.focus_monitor(monitor_idx)?;
}
let focused_monitor_idx = self.focused_monitor_idx();
for (i, monitor) in self.monitors_mut().iter_mut().enumerate() {
if i != focused_monitor_idx {
monitor.focus_workspace(workspace_idx)?;
monitor.load_focused_workspace(false)?;
}
}
self.focus_workspace(workspace_idx)?;
if BORDER_ENABLED.load(Ordering::SeqCst) {
self.show_border()?;
};
}
SocketMessage::FocusMonitorWorkspaceNumber(monitor_idx, workspace_idx) => { SocketMessage::FocusMonitorWorkspaceNumber(monitor_idx, workspace_idx) => {
self.focus_monitor(monitor_idx)?; self.focus_monitor(monitor_idx)?;
self.focus_workspace(workspace_idx)?; self.focus_workspace(workspace_idx)?;
@@ -688,8 +711,8 @@ impl WindowManager {
} }
} }
} }
// Otherwise proceed with the resizing logic for individual window containers in the // Otherwise proceed with the resizing logic for individual window containers in the
// assumed BSP layout // assumed BSP layout
} else { } else {
match axis { match axis {
Axis::Horizontal => { Axis::Horizontal => {
@@ -773,9 +796,10 @@ impl WindowManager {
} }
} }
FocusFollowsMouseImplementation::Windows => { FocusFollowsMouseImplementation::Windows => {
if let Some(FocusFollowsMouseImplementation::Komorebi) = if matches!(
self.focus_follows_mouse self.focus_follows_mouse,
{ Some(FocusFollowsMouseImplementation::Komorebi)
) {
tracing::warn!( tracing::warn!(
"the windows implementation of focus follows mouse cannot be enabled while the komorebi implementation is enabled" "the windows implementation of focus follows mouse cannot be enabled while the komorebi implementation is enabled"
); );
@@ -820,9 +844,10 @@ impl WindowManager {
} }
} }
FocusFollowsMouseImplementation::Windows => { FocusFollowsMouseImplementation::Windows => {
if let Some(FocusFollowsMouseImplementation::Komorebi) = if matches!(
self.focus_follows_mouse self.focus_follows_mouse,
{ Some(FocusFollowsMouseImplementation::Komorebi)
) {
tracing::warn!( tracing::warn!(
"the windows implementation of focus follows mouse cannot be toggled while the komorebi implementation is enabled" "the windows implementation of focus follows mouse cannot be toggled while the komorebi implementation is enabled"
); );
@@ -958,7 +983,7 @@ impl WindowManager {
} }
SocketMessage::AddSubscriber(ref subscriber) => { SocketMessage::AddSubscriber(ref subscriber) => {
let mut pipes = SUBSCRIPTION_PIPES.lock(); let mut pipes = SUBSCRIPTION_PIPES.lock();
let pipe_path = format!(r"\\.\pipe\{}", subscriber); let pipe_path = format!(r"\\.\pipe\{subscriber}");
let pipe = connect(&pipe_path).map_err(|_| { let pipe = connect(&pipe_path).map_err(|_| {
anyhow!("the named pipe '{}' has not yet been created; please create it before running this command", pipe_path) anyhow!("the named pipe '{}' has not yet been created; please create it before running this command", pipe_path)
})?; })?;
@@ -1286,11 +1311,7 @@ pub fn read_commands_tcp(
break; break;
} }
Ok(size) => { Ok(size) => {
let message = if let Ok(message) = let Ok(message) = SocketMessage::from_str(&String::from_utf8_lossy(&buf[..size])) else {
SocketMessage::from_str(&String::from_utf8_lossy(&buf[..size]))
{
message
} else {
tracing::warn!("client sent an invalid message, disconnecting: {addr}"); tracing::warn!("client sent an invalid message, disconnecting: {addr}");
let mut connections = TCP_CONNECTIONS.lock(); let mut connections = TCP_CONNECTIONS.lock();
connections.remove(addr); connections.remove(addr);
+4 -1
View File
@@ -18,7 +18,10 @@ pub fn listen_for_movements(wm: Arc<Mutex<WindowManager>>) {
loop { loop {
let focus_follows_mouse = wm.lock().focus_follows_mouse; let focus_follows_mouse = wm.lock().focus_follows_mouse;
if let Some(FocusFollowsMouseImplementation::Komorebi) = focus_follows_mouse { if matches!(
focus_follows_mouse,
Some(FocusFollowsMouseImplementation::Komorebi)
) {
match receiver.next_event() { match receiver.next_event() {
// Don't want to send any raise events while we are dragging or resizing // Don't want to send any raise events while we are dragging or resizing
Event::MouseButton { action, .. } => match action { Event::MouseButton { action, .. } => match action {
+4 -4
View File
@@ -45,20 +45,20 @@ impl Display for Window {
let mut display = format!("(hwnd: {}", self.hwnd); let mut display = format!("(hwnd: {}", self.hwnd);
if let Ok(title) = self.title() { if let Ok(title) = self.title() {
write!(display, ", title: {}", title)?; write!(display, ", title: {title}")?;
} }
if let Ok(exe) = self.exe() { if let Ok(exe) = self.exe() {
write!(display, ", exe: {}", exe)?; write!(display, ", exe: {exe}")?;
} }
if let Ok(class) = self.class() { if let Ok(class) = self.class() {
write!(display, ", class: {}", class)?; write!(display, ", class: {class}")?;
} }
write!(display, ")")?; write!(display, ")")?;
write!(f, "{}", display) write!(f, "{display}")
} }
} }
+4 -1
View File
@@ -984,7 +984,10 @@ impl WindowManager {
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
fn handle_unmanaged_window_behaviour(&self) -> Result<()> { fn handle_unmanaged_window_behaviour(&self) -> Result<()> {
if let OperationBehaviour::NoOp = self.unmanaged_window_operation_behaviour { if matches!(
self.unmanaged_window_operation_behaviour,
OperationBehaviour::NoOp
) {
let workspace = self.focused_workspace()?; let workspace = self.focused_workspace()?;
let focused_hwnd = WindowsApi::foreground_window()?; let focused_hwnd = WindowsApi::foreground_window()?;
if !workspace.contains_managed_window(focused_hwnd) { if !workspace.contains_managed_window(focused_hwnd) {
+14 -27
View File
@@ -31,62 +31,49 @@ impl Display for WindowManagerEvent {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Manage(window) => { Self::Manage(window) => {
write!(f, "Manage (Window: {})", window) write!(f, "Manage (Window: {window})")
} }
Self::Unmanage(window) => { Self::Unmanage(window) => {
write!(f, "Unmanage (Window: {})", window) write!(f, "Unmanage (Window: {window})")
} }
Self::Destroy(winevent, window) => { Self::Destroy(winevent, window) => {
write!(f, "Destroy (WinEvent: {}, Window: {})", winevent, window) write!(f, "Destroy (WinEvent: {winevent}, Window: {window})")
} }
Self::FocusChange(winevent, window) => { Self::FocusChange(winevent, window) => {
write!( write!(f, "FocusChange (WinEvent: {winevent}, Window: {window})",)
f,
"FocusChange (WinEvent: {}, Window: {})",
winevent, window
)
} }
Self::Hide(winevent, window) => { Self::Hide(winevent, window) => {
write!(f, "Hide (WinEvent: {}, Window: {})", winevent, window) write!(f, "Hide (WinEvent: {winevent}, Window: {window})")
} }
Self::Cloak(winevent, window) => { Self::Cloak(winevent, window) => {
write!(f, "Cloak (WinEvent: {}, Window: {})", winevent, window) write!(f, "Cloak (WinEvent: {winevent}, Window: {window})")
} }
Self::Minimize(winevent, window) => { Self::Minimize(winevent, window) => {
write!(f, "Minimize (WinEvent: {}, Window: {})", winevent, window) write!(f, "Minimize (WinEvent: {winevent}, Window: {window})")
} }
Self::Show(winevent, window) => { Self::Show(winevent, window) => {
write!(f, "Show (WinEvent: {}, Window: {})", winevent, window) write!(f, "Show (WinEvent: {winevent}, Window: {window})")
} }
Self::Uncloak(winevent, window) => { Self::Uncloak(winevent, window) => {
write!(f, "Uncloak (WinEvent: {}, Window: {})", winevent, window) write!(f, "Uncloak (WinEvent: {winevent}, Window: {window})")
} }
Self::MoveResizeStart(winevent, window) => { Self::MoveResizeStart(winevent, window) => {
write!( write!(
f, f,
"MoveResizeStart (WinEvent: {}, Window: {})", "MoveResizeStart (WinEvent: {winevent}, Window: {window})",
winevent, window
) )
} }
Self::MoveResizeEnd(winevent, window) => { Self::MoveResizeEnd(winevent, window) => {
write!( write!(f, "MoveResizeEnd (WinEvent: {winevent}, Window: {window})",)
f,
"MoveResizeEnd (WinEvent: {}, Window: {})",
winevent, window
)
} }
Self::MouseCapture(winevent, window) => { Self::MouseCapture(winevent, window) => {
write!( write!(f, "MouseCapture (WinEvent: {winevent}, Window: {window})",)
f,
"MouseCapture (WinEvent: {}, Window: {})",
winevent, window
)
} }
Self::Raise(window) => { Self::Raise(window) => {
write!(f, "Raise (Window: {})", window) write!(f, "Raise (Window: {window})")
} }
Self::DisplayChange(window) => { Self::DisplayChange(window) => {
write!(f, "DisplayChange (Window: {})", window) write!(f, "DisplayChange (Window: {window})")
} }
} }
} }
+2 -2
View File
@@ -158,7 +158,7 @@ pub extern "system" fn border_window(
lparam: LPARAM, lparam: LPARAM,
) -> LRESULT { ) -> LRESULT {
unsafe { unsafe {
match message as u32 { match message {
WM_PAINT => { WM_PAINT => {
let border_rect = *BORDER_RECT.lock(); let border_rect = *BORDER_RECT.lock();
let mut ps = PAINTSTRUCT::default(); let mut ps = PAINTSTRUCT::default();
@@ -194,7 +194,7 @@ pub extern "system" fn hidden_window(
lparam: LPARAM, lparam: LPARAM,
) -> LRESULT { ) -> LRESULT {
unsafe { unsafe {
match message as u32 { match message {
WM_DISPLAYCHANGE => { WM_DISPLAYCHANGE => {
let event_type = WindowManagerEvent::DisplayChange(Window { hwnd: window.0 }); let event_type = WindowManagerEvent::DisplayChange(Window { hwnd: window.0 });
WINEVENT_CALLBACK_CHANNEL WINEVENT_CALLBACK_CHANNEL
+21 -15
View File
@@ -60,8 +60,7 @@ lazy_static! {
home home
} else { } else {
panic!( panic!(
"$Env:KOMOREBI_CONFIG_HOME is set to '{}', which is not a valid directory", "$Env:KOMOREBI_CONFIG_HOME is set to '{home_path}', which is not a valid directory",
home_path
); );
} }
}, },
@@ -153,6 +152,7 @@ gen_target_subcommand_args! {
SendToWorkspace, SendToWorkspace,
FocusMonitor, FocusMonitor,
FocusWorkspace, FocusWorkspace,
FocusWorkspaces,
MoveWorkspaceToMonitor, MoveWorkspaceToMonitor,
} }
@@ -789,6 +789,9 @@ enum SubCommand {
/// Focus the specified workspace on the focused monitor /// Focus the specified workspace on the focused monitor
#[clap(arg_required_else_help = true)] #[clap(arg_required_else_help = true)]
FocusWorkspace(FocusWorkspace), FocusWorkspace(FocusWorkspace),
/// Focus the specified workspace on all monitors
#[clap(arg_required_else_help = true)]
FocusWorkspaces(FocusWorkspaces),
/// Focus the specified workspace on the target monitor /// Focus the specified workspace on the target monitor
#[clap(arg_required_else_help = true)] #[clap(arg_required_else_help = true)]
FocusMonitorWorkspace(FocusMonitorWorkspace), FocusMonitorWorkspace(FocusMonitorWorkspace),
@@ -1019,7 +1022,7 @@ enum SubCommand {
pub fn send_message(bytes: &[u8]) -> Result<()> { pub fn send_message(bytes: &[u8]) -> Result<()> {
let socket = DATA_DIR.join("komorebi.sock"); let socket = DATA_DIR.join("komorebi.sock");
let mut stream = UnixStream::connect(&socket)?; let mut stream = UnixStream::connect(socket)?;
Ok(stream.write_all(bytes)?) Ok(stream.write_all(bytes)?)
} }
@@ -1103,7 +1106,7 @@ fn main() -> Result<()> {
let locked = file.lock(); let locked = file.lock();
#[allow(clippy::significant_drop_in_scrutinee)] #[allow(clippy::significant_drop_in_scrutinee)]
for line in locked.lines().flatten() { for line in locked.lines().flatten() {
println!("{}", line); println!("{line}");
} }
} }
SubCommand::Focus(arg) => { SubCommand::Focus(arg) => {
@@ -1404,13 +1407,13 @@ fn main() -> Result<()> {
"'--await-configuration'".to_string() "'--await-configuration'".to_string()
}, },
|port| if arg.ffm { |port| if arg.ffm {
format!("'--ffm','--tcp-port={}'", port) format!("'--ffm','--tcp-port={port}'")
} else if arg.await_configuration { } else if arg.await_configuration {
format!("'--await-configuration','--tcp-port={}'", port) format!("'--await-configuration','--tcp-port={port}'")
} else if arg.ffm && arg.await_configuration { } else if arg.ffm && arg.await_configuration {
format!("'--ffm','--await-configuration','--tcp-port={}'", port) format!("'--ffm','--await-configuration','--tcp-port={port}'")
} else { } else {
format!("'--tcp-port={}'", port) format!("'--tcp-port={port}'")
} }
) )
) )
@@ -1432,18 +1435,18 @@ fn main() -> Result<()> {
"'--await-configuration'".to_string() "'--await-configuration'".to_string()
}, },
|port| if arg.ffm { |port| if arg.ffm {
format!("'--ffm','--tcp-port={}'", port) format!("'--ffm','--tcp-port={port}'")
} else if arg.await_configuration { } else if arg.await_configuration {
format!("'--await-configuration','--tcp-port={}'", port) format!("'--await-configuration','--tcp-port={port}'")
} else if arg.ffm && arg.await_configuration { } else if arg.ffm && arg.await_configuration {
format!("'--ffm','--await-configuration','--tcp-port={}'", port) format!("'--ffm','--await-configuration','--tcp-port={port}'")
} else { } else {
format!("'--tcp-port={}'", port) format!("'--tcp-port={port}'")
} }
) )
) )
} else { } else {
format!("Start-Process '{}' -WindowStyle hidden", exec) format!("Start-Process '{exec}' -WindowStyle hidden")
} }
}, },
); );
@@ -1453,10 +1456,10 @@ fn main() -> Result<()> {
while !running { while !running {
match powershell_script::run(&script) { match powershell_script::run(&script) {
Ok(_) => { Ok(_) => {
println!("{}", script); println!("{script}");
} }
Err(error) => { Err(error) => {
println!("Error: {}", error); println!("Error: {error}");
} }
} }
@@ -1538,6 +1541,9 @@ fn main() -> Result<()> {
SubCommand::FocusWorkspace(arg) => { SubCommand::FocusWorkspace(arg) => {
send_message(&SocketMessage::FocusWorkspaceNumber(arg.target).as_bytes()?)?; send_message(&SocketMessage::FocusWorkspaceNumber(arg.target).as_bytes()?)?;
} }
SubCommand::FocusWorkspaces(arg) => {
send_message(&SocketMessage::FocusWorkspaceNumbers(arg.target).as_bytes()?)?;
}
SubCommand::FocusMonitorWorkspace(arg) => { SubCommand::FocusMonitorWorkspace(arg) => {
send_message( send_message(
&SocketMessage::FocusMonitorWorkspaceNumber( &SocketMessage::FocusMonitorWorkspaceNumber(