Skip to content

Commit

Permalink
feat(wm): add focus-workspaces cmd
Browse files Browse the repository at this point in the history
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 #451 #426
  • Loading branch information
LGUG2Z committed Jun 4, 2023
1 parent 7ba7067 commit 4bab46e
Show file tree
Hide file tree
Showing 13 changed files with 130 additions and 89 deletions.
3 changes: 3 additions & 0 deletions .czrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"path": "cz-conventional-changelog"
}
30 changes: 9 additions & 21 deletions komorebi-core/src/config_generation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,19 @@ impl ApplicationOptions {
pub fn raw_cfgen(&self, kind: &ApplicationIdentifier, id: &str) -> String {
match self {
ApplicationOptions::ObjectNameChange => {
format!(
"komorebic.exe identify-object-name-change-application {} \"{}\"",
kind, id
)
format!("komorebic.exe identify-object-name-change-application {kind} \"{id}\"",)
}
ApplicationOptions::Layered => {
format!(
"komorebic.exe identify-layered-application {} \"{}\"",
kind, id
)
format!("komorebic.exe identify-layered-application {kind} \"{id}\"",)
}
ApplicationOptions::BorderOverflow => {
format!(
"komorebic.exe identify-border-overflow-application {} \"{}\"",
kind, id
)
format!("komorebic.exe identify-border-overflow-application {kind} \"{id}\"",)
}
ApplicationOptions::TrayAndMultiWindow => {
format!(
"komorebic.exe identify-tray-application {} \"{}\"",
kind, id
)
format!("komorebic.exe identify-tray-application {kind} \"{id}\"",)
}
ApplicationOptions::Force => {
format!("komorebic.exe manage-rule {} \"{}\"", kind, id)
format!("komorebic.exe manage-rule {kind} \"{id}\"")
}
}
}
Expand Down Expand Up @@ -143,7 +131,7 @@ impl ApplicationConfigurationGenerator {
lines.push(format!("# {}", app.name));
if let Some(options) = app.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"));
}

Expand All @@ -161,7 +149,7 @@ impl ApplicationConfigurationGenerator {
float_rules.push(float_rule.clone());

if let Some(comment) = float.comment {
lines.push(format!("# {}", comment));
lines.push(format!("# {comment}"));
};

lines.push(float_rule);
Expand Down Expand Up @@ -192,7 +180,7 @@ impl ApplicationConfigurationGenerator {
lines.push(format!("; {}", app.name));
if let Some(options) = app.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"));
}

Expand All @@ -212,7 +200,7 @@ impl ApplicationConfigurationGenerator {
float_rules.push(float_rule.clone());

if let Some(comment) = float.comment {
lines.push(format!("; {}", comment));
lines.push(format!("; {comment}"));
};

lines.push(float_rule);
Expand Down
1 change: 1 addition & 0 deletions komorebi-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ pub enum SocketMessage {
CycleFocusWorkspace(CycleDirection),
FocusMonitorNumber(usize),
FocusWorkspaceNumber(usize),
FocusWorkspaceNumbers(usize),
FocusMonitorWorkspaceNumber(usize, usize),
FocusNamedWorkspace(String),
ContainerPadding(usize, usize, i32),
Expand Down
15 changes: 15 additions & 0 deletions komorebi.generated.ahk
Original file line number Diff line number Diff line change
Expand Up @@ -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
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
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
Expand Down Expand Up @@ -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 manage-rule exe "Obsidian.exe"', , "Hide")

; OneDrive
RunWait('komorebic.exe float-rule class "OneDriveReactNativeWin32WindowClass"', , "Hide")

; OpenRGB
; 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")
Expand All @@ -289,6 +295,8 @@ RunWait('komorebic.exe identify-border-overflow-application exe "Plexamp.exe"',
RunWait('komorebic.exe float-rule exe "PowerToys.ColorPickerUI.exe"', , "Hide")
; Target image resizer dialog
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
; If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
Expand Down Expand Up @@ -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
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
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
Expand All @@ -435,6 +447,9 @@ RunWait('komorebic.exe identify-object-name-change-application exe "devenv.exe"'
; Visual Studio Code
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
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
Expand Down
15 changes: 15 additions & 0 deletions komorebi.generated.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
komorebic.exe identify-tray-application exe "Akiflow.exe"

# Android Studio
komorebic.exe identify-object-name-change-application exe "studio64.exe"

# ArmCord
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
Expand Down Expand Up @@ -274,6 +277,9 @@ komorebic.exe identify-tray-application class "DocEditorsWindowClass"
komorebic.exe identify-border-overflow-application exe "Obsidian.exe"
komorebic.exe manage-rule exe "Obsidian.exe"

# OneDrive
komorebic.exe float-rule class "OneDriveReactNativeWin32WindowClass"

# OpenRGB
# 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"
Expand All @@ -289,6 +295,8 @@ komorebic.exe identify-border-overflow-application exe "Plexamp.exe"
komorebic.exe float-rule exe "PowerToys.ColorPickerUI.exe"
# Target image resizer dialog
komorebic.exe float-rule exe "PowerToys.ImageResizer.exe"
# Target Peek popup
komorebic.exe float-rule exe "PowerToys.Peek.UI.exe"

# Process Hacker
# If you have disabled minimize/close to tray for this application, you can delete/comment out the next line
Expand Down Expand Up @@ -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
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
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
Expand All @@ -435,6 +447,9 @@ komorebic.exe identify-object-name-change-application exe "devenv.exe"
# Visual Studio Code
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
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
Expand Down
5 changes: 2 additions & 3 deletions komorebi/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,7 @@ lazy_static! {
home
} else {
panic!(
"$Env:KOMOREBI_CONFIG_HOME is set to '{}', which is not a valid directory",
home_path
"$Env:KOMOREBI_CONFIG_HOME is set to '{home_path}', which is not a valid directory",
);
}
})
Expand Down Expand Up @@ -344,7 +343,7 @@ pub fn notify_subscribers(notification: &str) -> Result<()> {
let mut stale_subscriptions = vec![];
let mut subscriptions = SUBSCRIPTION_PIPES.lock();
for (subscriber, pipe) in subscriptions.iter_mut() {
match writeln!(pipe, "{}", notification) {
match writeln!(pipe, "{notification}") {
Ok(_) => {
tracing::debug!("pushed notification to subscriber: {}", subscriber);
}
Expand Down
51 changes: 36 additions & 15 deletions komorebi/src/process_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ pub fn listen_for_commands(wm: Arc<Mutex<WindowManager>>) {
#[tracing::instrument]
pub fn listen_for_commands_tcp(wm: Arc<Mutex<WindowManager>>, port: usize) {
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 || {
tracing::info!("listening on 0.0.0.0:43663");
Expand Down Expand Up @@ -557,6 +557,29 @@ impl WindowManager {
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) => {
self.focus_monitor(monitor_idx)?;
self.focus_workspace(workspace_idx)?;
Expand Down Expand Up @@ -688,8 +711,8 @@ impl WindowManager {
}
}
}
// Otherwise proceed with the resizing logic for individual window containers in the
// assumed BSP layout
// Otherwise proceed with the resizing logic for individual window containers in the
// assumed BSP layout
} else {
match axis {
Axis::Horizontal => {
Expand Down Expand Up @@ -773,9 +796,10 @@ impl WindowManager {
}
}
FocusFollowsMouseImplementation::Windows => {
if let Some(FocusFollowsMouseImplementation::Komorebi) =
self.focus_follows_mouse
{
if matches!(
self.focus_follows_mouse,
Some(FocusFollowsMouseImplementation::Komorebi)
) {
tracing::warn!(
"the windows implementation of focus follows mouse cannot be enabled while the komorebi implementation is enabled"
);
Expand Down Expand Up @@ -820,9 +844,10 @@ impl WindowManager {
}
}
FocusFollowsMouseImplementation::Windows => {
if let Some(FocusFollowsMouseImplementation::Komorebi) =
self.focus_follows_mouse
{
if matches!(
self.focus_follows_mouse,
Some(FocusFollowsMouseImplementation::Komorebi)
) {
tracing::warn!(
"the windows implementation of focus follows mouse cannot be toggled while the komorebi implementation is enabled"
);
Expand Down Expand Up @@ -958,7 +983,7 @@ impl WindowManager {
}
SocketMessage::AddSubscriber(ref subscriber) => {
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(|_| {
anyhow!("the named pipe '{}' has not yet been created; please create it before running this command", pipe_path)
})?;
Expand Down Expand Up @@ -1286,11 +1311,7 @@ pub fn read_commands_tcp(
break;
}
Ok(size) => {
let message = if let Ok(message) =
SocketMessage::from_str(&String::from_utf8_lossy(&buf[..size]))
{
message
} else {
let Ok(message) = SocketMessage::from_str(&String::from_utf8_lossy(&buf[..size])) else {
tracing::warn!("client sent an invalid message, disconnecting: {addr}");
let mut connections = TCP_CONNECTIONS.lock();
connections.remove(addr);
Expand Down
5 changes: 4 additions & 1 deletion komorebi/src/process_movement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ pub fn listen_for_movements(wm: Arc<Mutex<WindowManager>>) {

loop {
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() {
// Don't want to send any raise events while we are dragging or resizing
Event::MouseButton { action, .. } => match action {
Expand Down
8 changes: 4 additions & 4 deletions komorebi/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,20 @@ impl Display for Window {
let mut display = format!("(hwnd: {}", self.hwnd);

if let Ok(title) = self.title() {
write!(display, ", title: {}", title)?;
write!(display, ", title: {title}")?;
}

if let Ok(exe) = self.exe() {
write!(display, ", exe: {}", exe)?;
write!(display, ", exe: {exe}")?;
}

if let Ok(class) = self.class() {
write!(display, ", class: {}", class)?;
write!(display, ", class: {class}")?;
}

write!(display, ")")?;

write!(f, "{}", display)
write!(f, "{display}")
}
}

Expand Down
5 changes: 4 additions & 1 deletion komorebi/src/window_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,10 @@ impl WindowManager {

#[tracing::instrument(skip(self))]
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 focused_hwnd = WindowsApi::foreground_window()?;
if !workspace.contains_managed_window(focused_hwnd) {
Expand Down
Loading

0 comments on commit 4bab46e

Please sign in to comment.