mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-14 12:59:48 +02:00
feat(cli): add last focused workspace cmd
This commit adds a new komorebic command, focus-last-workspace, which switches to the last focused workspace on the focused monitor (if there is one).
This commit is contained in:
@@ -99,6 +99,7 @@ pub enum SocketMessage {
|
||||
CycleFocusMonitor(CycleDirection),
|
||||
CycleFocusWorkspace(CycleDirection),
|
||||
FocusMonitorNumber(usize),
|
||||
FocusLastWorkspace,
|
||||
FocusWorkspaceNumber(usize),
|
||||
FocusWorkspaceNumbers(usize),
|
||||
FocusMonitorWorkspaceNumber(usize, usize),
|
||||
|
||||
@@ -35,6 +35,9 @@ pub struct Monitor {
|
||||
work_area_offset: Option<Rect>,
|
||||
workspaces: Ring<Workspace>,
|
||||
#[serde(skip_serializing)]
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
last_focused_workspace: Option<usize>,
|
||||
#[serde(skip_serializing)]
|
||||
#[getset(get_mut = "pub")]
|
||||
workspace_names: HashMap<usize, String>,
|
||||
}
|
||||
@@ -54,6 +57,7 @@ pub fn new(id: isize, size: Rect, work_area_size: Rect, name: String) -> Monitor
|
||||
work_area_size,
|
||||
work_area_offset: None,
|
||||
workspaces,
|
||||
last_focused_workspace: None,
|
||||
workspace_names: HashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +172,23 @@ impl WindowManager {
|
||||
_ => {}
|
||||
};
|
||||
|
||||
match message {
|
||||
SocketMessage::CycleFocusWorkspace(_) | SocketMessage::FocusWorkspaceNumber(_) => {
|
||||
if let Some(monitor) = self.focused_monitor_mut() {
|
||||
let idx = monitor.focused_workspace_idx();
|
||||
monitor.set_last_focused_workspace(Option::from(idx));
|
||||
}
|
||||
}
|
||||
SocketMessage::FocusMonitorWorkspaceNumber(target_monitor_idx, _) => {
|
||||
let idx = self.focused_workspace_idx_for_monitor_idx(target_monitor_idx)?;
|
||||
if let Some(monitor) = self.monitors_mut().get_mut(target_monitor_idx) {
|
||||
monitor.set_last_focused_workspace(Option::from(idx));
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
};
|
||||
|
||||
match message {
|
||||
SocketMessage::Promote => self.promote_container_to_front()?,
|
||||
SocketMessage::PromoteFocus => self.promote_focus_to_front()?,
|
||||
@@ -598,6 +615,33 @@ impl WindowManager {
|
||||
self.show_border()?;
|
||||
};
|
||||
}
|
||||
SocketMessage::FocusLastWorkspace => {
|
||||
// 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 idx = self
|
||||
.focused_monitor()
|
||||
.ok_or_else(|| anyhow!("there is no monitor"))?
|
||||
.focused_workspace_idx();
|
||||
|
||||
if let Some(monitor) = self.focused_monitor_mut() {
|
||||
if let Some(last_focused_workspace) = monitor.last_focused_workspace() {
|
||||
self.focus_workspace(last_focused_workspace)?;
|
||||
}
|
||||
}
|
||||
|
||||
self.focused_monitor_mut()
|
||||
.ok_or_else(|| anyhow!("there is no monitor"))?
|
||||
.set_last_focused_workspace(Option::from(idx));
|
||||
|
||||
if BORDER_ENABLED.load(Ordering::SeqCst) {
|
||||
self.show_border()?;
|
||||
};
|
||||
}
|
||||
SocketMessage::FocusWorkspaceNumber(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
|
||||
@@ -1338,21 +1382,17 @@ impl WindowManager {
|
||||
rect.bottom += self.invisible_borders.bottom;
|
||||
|
||||
let monocle = BORDER_COLOUR_MONOCLE.load(Ordering::SeqCst);
|
||||
if monocle != 0 {
|
||||
if self.focused_workspace()?.monocle_container().is_some() {
|
||||
BORDER_COLOUR_CURRENT.store(
|
||||
monocle,
|
||||
Ordering::SeqCst,
|
||||
);
|
||||
}
|
||||
if monocle != 0 && self.focused_workspace()?.monocle_container().is_some() {
|
||||
BORDER_COLOUR_CURRENT.store(
|
||||
monocle,
|
||||
Ordering::SeqCst,
|
||||
);
|
||||
}
|
||||
|
||||
let stack = BORDER_COLOUR_STACK.load(Ordering::SeqCst);
|
||||
if stack != 0 {
|
||||
if self.focused_container()?.windows().len() > 1 {
|
||||
BORDER_COLOUR_CURRENT
|
||||
.store(stack, Ordering::SeqCst);
|
||||
}
|
||||
if stack != 0 && self.focused_container()?.windows().len() > 1 {
|
||||
BORDER_COLOUR_CURRENT
|
||||
.store(stack, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
let border = Border::from(BORDER_HWND.load(Ordering::SeqCst));
|
||||
|
||||
@@ -2198,6 +2198,14 @@ impl WindowManager {
|
||||
.ok_or_else(|| anyhow!("there is no workspace"))
|
||||
}
|
||||
|
||||
pub fn focused_workspace_idx_for_monitor_idx(&self, idx: usize) -> Result<usize> {
|
||||
Ok(self
|
||||
.monitors()
|
||||
.get(idx)
|
||||
.ok_or_else(|| anyhow!("there is no monitor at this index"))?
|
||||
.focused_workspace_idx())
|
||||
}
|
||||
|
||||
pub fn focused_workspace_for_monitor_idx(&self, idx: usize) -> Result<&Workspace> {
|
||||
self.monitors()
|
||||
.get(idx)
|
||||
|
||||
@@ -868,6 +868,8 @@ enum SubCommand {
|
||||
/// Focus the specified monitor
|
||||
#[clap(arg_required_else_help = true)]
|
||||
FocusMonitor(FocusMonitor),
|
||||
/// Focus the last focused workspace on the focused monitor
|
||||
FocusLastWorkspace,
|
||||
/// Focus the specified workspace on the focused monitor
|
||||
#[clap(arg_required_else_help = true)]
|
||||
FocusWorkspace(FocusWorkspace),
|
||||
@@ -1857,6 +1859,9 @@ Stop-Process -Name:whkd -ErrorAction SilentlyContinue
|
||||
SubCommand::FocusMonitor(arg) => {
|
||||
send_message(&SocketMessage::FocusMonitorNumber(arg.target).as_bytes()?)?;
|
||||
}
|
||||
SubCommand::FocusLastWorkspace => {
|
||||
send_message(&SocketMessage::FocusLastWorkspace.as_bytes()?)?;
|
||||
}
|
||||
SubCommand::FocusWorkspace(arg) => {
|
||||
send_message(&SocketMessage::FocusWorkspaceNumber(arg.target).as_bytes()?)?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user