mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-07-08 05:55:09 +02:00
feat(wm): cycle through monitors and workspaces
This commit adds commands to navigate monitors and workspaces using cycle directions. resolve #47
This commit is contained in:
@@ -226,6 +226,8 @@ save Save the current resize layout dimensions to a fil
|
|||||||
load Load the resize layout dimensions from a file
|
load Load the resize layout dimensions from a file
|
||||||
focus Change focus to the window in the specified direction
|
focus Change focus to the window in the specified direction
|
||||||
move Move the focused window in the specified direction
|
move Move the focused window in the specified direction
|
||||||
|
cycle-focus Change focus to the window in the specified cycle direction
|
||||||
|
cycle-move Move the focused window in the specified cycle direction
|
||||||
stack Stack the focused window in the specified direction
|
stack Stack the focused window in the specified direction
|
||||||
resize Resize the focused window in the specified direction
|
resize Resize the focused window in the specified direction
|
||||||
unstack Unstack the focused window
|
unstack Unstack the focused window
|
||||||
@@ -236,6 +238,8 @@ send-to-monitor Send the focused window to the specified monitor
|
|||||||
send-to-workspace Send the focused window to the specified workspace
|
send-to-workspace Send the focused window to the specified workspace
|
||||||
focus-monitor Focus the specified monitor
|
focus-monitor Focus the specified monitor
|
||||||
focus-workspace Focus the specified workspace on the focused monitor
|
focus-workspace Focus the specified workspace on the focused monitor
|
||||||
|
cycle-monitor Focus the monitor in the given cycle direction
|
||||||
|
cycle-workspace Focus the workspace in the given cycle direction
|
||||||
new-workspace Create and append a new workspace on the focused monitor
|
new-workspace Create and append a new workspace on the focused monitor
|
||||||
invisible-borders Set the invisible border dimensions around each window
|
invisible-borders Set the invisible border dimensions around each window
|
||||||
adjust-container-padding Adjust container padding on the focused workspace
|
adjust-container-padding Adjust container padding on the focused workspace
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
use std::num::NonZeroUsize;
|
||||||
|
|
||||||
use clap::ArgEnum;
|
use clap::ArgEnum;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::num::NonZeroUsize;
|
|
||||||
use strum::Display;
|
use strum::Display;
|
||||||
use strum::EnumString;
|
use strum::EnumString;
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ pub enum SocketMessage {
|
|||||||
QuickLoad,
|
QuickLoad,
|
||||||
Save(PathBuf),
|
Save(PathBuf),
|
||||||
Load(PathBuf),
|
Load(PathBuf),
|
||||||
|
CycleFocusMonitor(CycleDirection),
|
||||||
|
CycleFocusWorkspace(CycleDirection),
|
||||||
FocusMonitorNumber(usize),
|
FocusMonitorNumber(usize),
|
||||||
FocusWorkspaceNumber(usize),
|
FocusWorkspaceNumber(usize),
|
||||||
ContainerPadding(usize, usize, i32),
|
ContainerPadding(usize, usize, i32),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::fs::OpenOptions;
|
|||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::num::NonZeroUsize;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -136,6 +137,16 @@ impl WindowManager {
|
|||||||
SocketMessage::ToggleTiling => {
|
SocketMessage::ToggleTiling => {
|
||||||
self.toggle_tiling()?;
|
self.toggle_tiling()?;
|
||||||
}
|
}
|
||||||
|
SocketMessage::CycleFocusMonitor(direction) => {
|
||||||
|
let monitor_idx = direction.next_idx(
|
||||||
|
self.focused_monitor_idx(),
|
||||||
|
NonZeroUsize::new(self.monitors().len())
|
||||||
|
.ok_or_else(|| anyhow!("there must be at least one monitor"))?,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.focus_monitor(monitor_idx)?;
|
||||||
|
self.update_focused_workspace(true)?;
|
||||||
|
}
|
||||||
SocketMessage::FocusMonitorNumber(monitor_idx) => {
|
SocketMessage::FocusMonitorNumber(monitor_idx) => {
|
||||||
self.focus_monitor(monitor_idx)?;
|
self.focus_monitor(monitor_idx)?;
|
||||||
self.update_focused_workspace(true)?;
|
self.update_focused_workspace(true)?;
|
||||||
@@ -149,6 +160,31 @@ impl WindowManager {
|
|||||||
SocketMessage::WorkspaceLayout(monitor_idx, workspace_idx, layout) => {
|
SocketMessage::WorkspaceLayout(monitor_idx, workspace_idx, layout) => {
|
||||||
self.set_workspace_layout(monitor_idx, workspace_idx, layout)?;
|
self.set_workspace_layout(monitor_idx, workspace_idx, layout)?;
|
||||||
}
|
}
|
||||||
|
SocketMessage::CycleFocusWorkspace(direction) => {
|
||||||
|
// 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
|
||||||
|
let monitor_idx = self.monitor_idx_from_current_pos().ok_or_else(|| {
|
||||||
|
anyhow!("there is no monitor associated with the current cursor position")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.focus_monitor(monitor_idx)?;
|
||||||
|
|
||||||
|
let focused_monitor = self
|
||||||
|
.focused_monitor()
|
||||||
|
.ok_or_else(|| anyhow!("there is no monitor"))?;
|
||||||
|
|
||||||
|
let focused_workspace_idx = focused_monitor.focused_workspace_idx();
|
||||||
|
let workspaces = focused_monitor.workspaces().len();
|
||||||
|
|
||||||
|
let workspace_idx = direction.next_idx(
|
||||||
|
focused_workspace_idx,
|
||||||
|
NonZeroUsize::new(workspaces)
|
||||||
|
.ok_or_else(|| anyhow!("there must be at least one workspace"))?,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.focus_workspace(workspace_idx)?;
|
||||||
|
}
|
||||||
SocketMessage::FocusWorkspaceNumber(workspace_idx) => {
|
SocketMessage::FocusWorkspaceNumber(workspace_idx) => {
|
||||||
// This is to ensure that even on an empty workspace on a secondary monitor, the
|
// 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
|
// secondary monitor where the cursor is focused will be used as the target for
|
||||||
|
|||||||
@@ -44,6 +44,14 @@ Move(operation_direction) {
|
|||||||
Run, komorebic.exe move %operation_direction%, , Hide
|
Run, komorebic.exe move %operation_direction%, , Hide
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CycleFocus(cycle_direction) {
|
||||||
|
Run, komorebic.exe cycle-focus %cycle_direction%, , Hide
|
||||||
|
}
|
||||||
|
|
||||||
|
CycleMove(cycle_direction) {
|
||||||
|
Run, komorebic.exe cycle-move %cycle_direction%, , Hide
|
||||||
|
}
|
||||||
|
|
||||||
Stack(operation_direction) {
|
Stack(operation_direction) {
|
||||||
Run, komorebic.exe stack %operation_direction%, , Hide
|
Run, komorebic.exe stack %operation_direction%, , Hide
|
||||||
}
|
}
|
||||||
@@ -84,6 +92,14 @@ FocusWorkspace(target) {
|
|||||||
Run, komorebic.exe focus-workspace %target%, , Hide
|
Run, komorebic.exe focus-workspace %target%, , Hide
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CycleMonitor(cycle_direction) {
|
||||||
|
Run, komorebic.exe cycle-monitor %cycle_direction%, , Hide
|
||||||
|
}
|
||||||
|
|
||||||
|
CycleWorkspace(cycle_direction) {
|
||||||
|
Run, komorebic.exe cycle-workspace %cycle_direction%, , Hide
|
||||||
|
}
|
||||||
|
|
||||||
NewWorkspace() {
|
NewWorkspace() {
|
||||||
Run, komorebic.exe new-workspace, , Hide
|
Run, komorebic.exe new-workspace, , Hide
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ gen_enum_subcommand_args! {
|
|||||||
Move: OperationDirection,
|
Move: OperationDirection,
|
||||||
CycleFocus: CycleDirection,
|
CycleFocus: CycleDirection,
|
||||||
CycleMove: CycleDirection,
|
CycleMove: CycleDirection,
|
||||||
|
CycleMonitor: CycleDirection,
|
||||||
|
CycleWorkspace: CycleDirection,
|
||||||
Stack: OperationDirection,
|
Stack: OperationDirection,
|
||||||
CycleStack: CycleDirection,
|
CycleStack: CycleDirection,
|
||||||
FlipLayout: Flip,
|
FlipLayout: Flip,
|
||||||
@@ -353,6 +355,12 @@ enum SubCommand {
|
|||||||
/// Focus the specified workspace on the focused monitor
|
/// Focus the specified workspace on the focused monitor
|
||||||
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
|
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
|
||||||
FocusWorkspace(FocusWorkspace),
|
FocusWorkspace(FocusWorkspace),
|
||||||
|
/// Focus the monitor in the given cycle direction
|
||||||
|
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
|
||||||
|
CycleMonitor(CycleMonitor),
|
||||||
|
/// Focus the workspace in the given cycle direction
|
||||||
|
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
|
||||||
|
CycleWorkspace(CycleWorkspace),
|
||||||
/// Create and append a new workspace on the focused monitor
|
/// Create and append a new workspace on the focused monitor
|
||||||
NewWorkspace,
|
NewWorkspace,
|
||||||
/// Set the invisible border dimensions around each window
|
/// Set the invisible border dimensions around each window
|
||||||
@@ -668,6 +676,12 @@ 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::CycleMonitor(arg) => {
|
||||||
|
send_message(&*SocketMessage::CycleFocusMonitor(arg.cycle_direction).as_bytes()?)?;
|
||||||
|
}
|
||||||
|
SubCommand::CycleWorkspace(arg) => {
|
||||||
|
send_message(&*SocketMessage::CycleFocusWorkspace(arg.cycle_direction).as_bytes()?)?;
|
||||||
|
}
|
||||||
SubCommand::NewWorkspace => {
|
SubCommand::NewWorkspace => {
|
||||||
send_message(&*SocketMessage::NewWorkspace.as_bytes()?)?;
|
send_message(&*SocketMessage::NewWorkspace.as_bytes()?)?;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user