fix(wm): fix focus changes with stackbar enabled

Notify all stackbars on focus change, and they now respond to changes,
but do not create focus changes themselves just from an update.
This commit is contained in:
James Tucker
2024-04-13 18:10:43 -07:00
committed by LGUG2Z
parent 86b07f28dd
commit b476bee1d8
5 changed files with 111 additions and 63 deletions
+7 -7
View File
@@ -499,11 +499,11 @@ impl WindowManager {
);
self.focus_monitor(monitor_idx)?;
self.update_focused_workspace(self.mouse_follows_focus)?;
self.update_focused_workspace(self.mouse_follows_focus, true)?;
}
SocketMessage::FocusMonitorNumber(monitor_idx) => {
self.focus_monitor(monitor_idx)?;
self.update_focused_workspace(self.mouse_follows_focus)?;
self.update_focused_workspace(self.mouse_follows_focus, true)?;
}
SocketMessage::Retile => self.retile_all(false)?,
SocketMessage::FlipLayout(layout_flip) => self.flip_layout(layout_flip)?,
@@ -914,7 +914,7 @@ impl WindowManager {
}
}
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
}
SocketMessage::FocusFollowsMouse(mut implementation, enable) => {
if !CUSTOM_FFM.load(Ordering::SeqCst) {
@@ -1020,7 +1020,7 @@ impl WindowManager {
SocketMessage::CompleteConfiguration => {
if !INITIAL_CONFIGURATION_LOADED.load(Ordering::SeqCst) {
INITIAL_CONFIGURATION_LOADED.store(true, Ordering::SeqCst);
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
}
}
SocketMessage::WatchConfiguration(enable) => {
@@ -1127,7 +1127,7 @@ impl WindowManager {
let resize: Vec<Option<Rect>> = serde_json::from_reader(file)?;
workspace.set_resize_dimensions(resize);
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
}
SocketMessage::Save(ref path) => {
let workspace = self.focused_workspace_mut()?;
@@ -1150,7 +1150,7 @@ impl WindowManager {
let resize: Vec<Option<Rect>> = serde_json::from_reader(file)?;
workspace.set_resize_dimensions(resize);
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
}
SocketMessage::AddSubscriberSocket(ref socket) => {
let mut sockets = SUBSCRIPTION_SOCKETS.lock();
@@ -1295,7 +1295,7 @@ impl WindowManager {
SocketMessage::ToggleTitleBars => {
let current = REMOVE_TITLEBARS.load(Ordering::SeqCst);
REMOVE_TITLEBARS.store(!current, Ordering::SeqCst);
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
}
// Deprecated commands
SocketMessage::AltFocusHack(_)
+20 -13
View File
@@ -153,6 +153,10 @@ impl WindowManager {
};
for (j, workspace) in monitor.workspaces_mut().iter_mut().enumerate() {
if let WindowManagerEvent::FocusChange(_, window) = event {
let _ = workspace.focus_changed(window.hwnd);
}
let reaped_orphans = workspace.reap_orphans()?;
if reaped_orphans.0 > 0 || reaped_orphans.1 > 0 {
workspace.update(&work_area, offset)?;
@@ -177,13 +181,12 @@ impl WindowManager {
}
match event {
WindowManagerEvent::Raise(window) => {
window.focus(false)?;
WindowManagerEvent::Raise(_window) => {
self.has_pending_raise_op = false;
}
WindowManagerEvent::Destroy(_, window) | WindowManagerEvent::Unmanage(window) => {
self.focused_workspace_mut()?.remove_window(window.hwnd)?;
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
let mut already_moved_window_handles = self.already_moved_window_handles.lock();
@@ -201,7 +204,7 @@ impl WindowManager {
if hide {
self.focused_workspace_mut()?.remove_window(window.hwnd)?;
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
}
}
WindowManagerEvent::Hide(_, window) => {
@@ -242,7 +245,7 @@ impl WindowManager {
if hide {
self.focused_workspace_mut()?.remove_window(window.hwnd)?;
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
}
let mut already_moved_window_handles = self.already_moved_window_handles.lock();
@@ -250,6 +253,8 @@ impl WindowManager {
already_moved_window_handles.remove(&window.hwnd);
}
WindowManagerEvent::FocusChange(_, window) => {
self.update_focused_workspace(true, false)?;
let workspace = self.focused_workspace_mut()?;
if !workspace
.floating_windows()
@@ -324,14 +329,14 @@ impl WindowManager {
match behaviour {
WindowContainerBehaviour::Create => {
workspace.new_container_for_window(window);
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
}
WindowContainerBehaviour::Append => {
workspace
.focused_container_mut()
.ok_or_else(|| anyhow!("there is no focused container"))?
.add_window(window);
self.update_focused_workspace(true)?;
self.update_focused_workspace(true, false)?;
}
}
}
@@ -481,11 +486,11 @@ impl WindowManager {
// the origin monitor's focused workspace
self.focus_monitor(origin_monitor_idx)?;
self.focus_workspace(origin_workspace_idx)?;
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
self.focus_monitor(target_monitor_idx)?;
self.focus_workspace(target_workspace_idx)?;
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
}
// Here we handle a simple move on the same monitor which is treated as
// a container swap
@@ -496,11 +501,12 @@ impl WindowManager {
Some(target_idx) => {
workspace
.swap_containers(focused_container_idx, target_idx);
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
}
None => {
self.update_focused_workspace(
self.mouse_follows_focus,
false,
)?;
}
}
@@ -509,11 +515,12 @@ impl WindowManager {
match workspace.container_idx_from_current_point() {
Some(target_idx) => {
workspace.move_window_to_container(target_idx)?;
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
}
None => {
self.update_focused_workspace(
self.mouse_follows_focus,
false,
)?;
}
}
@@ -560,12 +567,12 @@ impl WindowManager {
self.resize_window(edge, sizing, delta, true)?;
}
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
}
}
}
WindowManagerEvent::ForceUpdate(_) => {
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, true)?;
}
WindowManagerEvent::DisplayChange(..)
| WindowManagerEvent::MouseCapture(..)
+2 -2
View File
@@ -55,6 +55,8 @@ use komorebi_core::Rect;
use crate::window::Window;
use crate::windows_api::WindowsApi;
use crate::winevent_listener::event_tx;
use crate::WindowManagerEvent;
use crate::DEFAULT_CONTAINER_PADDING;
use crate::STACKBAR_FOCUSED_TEXT_COLOUR;
use crate::STACKBAR_TAB_BACKGROUND_COLOUR;
@@ -234,8 +236,6 @@ impl Stackbar {
for (i, window) in windows.iter().enumerate() {
if window.hwnd == focused_hwnd {
SetTextColor(hdc, COLORREF(focused_text_colour));
window.focus(false)?;
} else {
SetTextColor(hdc, COLORREF(unfocused_text_colour));
}
+55 -41
View File
@@ -617,7 +617,7 @@ impl WindowManager {
// Only re-tile the focused workspace if we need to
if should_update_focused_workspace {
self.update_focused_workspace(false)?;
self.update_focused_workspace(false, false)?;
}
Ok(())
@@ -796,7 +796,11 @@ impl WindowManager {
}
#[tracing::instrument(skip(self))]
pub fn update_focused_workspace(&mut self, follow_focus: bool) -> Result<()> {
pub fn update_focused_workspace(
&mut self,
follow_focus: bool,
trigger_focus: bool,
) -> Result<()> {
tracing::info!("updating");
let offset = self.work_area_offset;
@@ -807,13 +811,19 @@ impl WindowManager {
if follow_focus {
if let Some(window) = self.focused_workspace()?.maximized_window() {
window.focus(self.mouse_follows_focus)?;
} else if let Some(container) = self.focused_workspace()?.monocle_container() {
if let Some(window) = container.focused_window() {
if trigger_focus {
window.focus(self.mouse_follows_focus)?;
}
} else if let Some(container) = self.focused_workspace()?.monocle_container() {
if let Some(window) = container.focused_window() {
if trigger_focus {
window.focus(self.mouse_follows_focus)?;
}
}
} else if let Ok(window) = self.focused_window_mut() {
window.focus(self.mouse_follows_focus)?;
if trigger_focus {
window.focus(self.mouse_follows_focus)?;
}
} else {
let desktop_window = Window {
hwnd: WindowsApi::desktop_window()?,
@@ -841,7 +851,9 @@ impl WindowManager {
&& self.focused_workspace()?.monocle_container().is_none()
{
if let Ok(window) = self.focused_window_mut() {
window.focus(self.mouse_follows_focus)?;
if trigger_focus {
window.focus(self.mouse_follows_focus)?;
}
}
}
}
@@ -851,7 +863,9 @@ impl WindowManager {
if !follow_focus {
if let Some(window) = self.focused_workspace()?.maximized_window() {
window.restore();
window.focus(self.mouse_follows_focus)?;
if trigger_focus {
window.focus(self.mouse_follows_focus)?;
}
}
}
@@ -934,7 +948,7 @@ impl WindowManager {
workspace.resize_dimensions_mut()[focused_idx] = resize;
return if update {
self.update_focused_workspace(false)
self.update_focused_workspace(false, false)
} else {
Ok(())
};
@@ -1070,7 +1084,7 @@ impl WindowManager {
self.swap_monitor_workspaces(focused_monitor_idx, idx)?;
self.update_focused_workspace(mouse_follows_focus)
self.update_focused_workspace(mouse_follows_focus, true)
}
#[tracing::instrument(skip(self))]
@@ -1117,7 +1131,7 @@ impl WindowManager {
self.focus_monitor(monitor_idx)?;
}
self.update_focused_workspace(self.mouse_follows_focus)
self.update_focused_workspace(self.mouse_follows_focus, true)
}
#[tracing::instrument(skip(self))]
@@ -1134,7 +1148,7 @@ impl WindowManager {
monitor.move_container_to_workspace(idx, follow)?;
monitor.load_focused_workspace(mouse_follows_focus)?;
self.update_focused_workspace(mouse_follows_focus)
self.update_focused_workspace(mouse_follows_focus, true)
}
pub fn remove_focused_workspace(&mut self) -> Option<Workspace> {
@@ -1163,7 +1177,7 @@ impl WindowManager {
}
self.focus_monitor(idx)?;
self.update_focused_workspace(mouse_follows_focus)
self.update_focused_workspace(mouse_follows_focus, true)
}
#[tracing::instrument(skip(self))]
@@ -1324,7 +1338,7 @@ impl WindowManager {
.id();
if !WindowsApi::monitors_have_same_dpi(a, b)? {
self.update_focused_workspace(self.mouse_follows_focus)?;
self.update_focused_workspace(self.mouse_follows_focus, true)?;
}
}
Some(new_idx) => {
@@ -1334,7 +1348,7 @@ impl WindowManager {
}
}
self.update_focused_workspace(self.mouse_follows_focus)
self.update_focused_workspace(self.mouse_follows_focus, true)
}
#[tracing::instrument(skip(self))]
@@ -1392,7 +1406,7 @@ impl WindowManager {
workspace.swap_containers(current_idx, new_idx);
workspace.focus_container(new_idx);
self.update_focused_workspace(self.mouse_follows_focus)
self.update_focused_workspace(self.mouse_follows_focus, true)
}
#[tracing::instrument(skip(self))]
@@ -1416,7 +1430,7 @@ impl WindowManager {
container.focus_window(next_idx);
container.load_focused_window();
self.update_focused_workspace(self.mouse_follows_focus)
self.update_focused_workspace(self.mouse_follows_focus, true)
}
#[tracing::instrument(skip(self))]
@@ -1453,7 +1467,7 @@ impl WindowManager {
};
workspace.move_window_to_container(adjusted_new_index)?;
self.update_focused_workspace(self.mouse_follows_focus)?;
self.update_focused_workspace(self.mouse_follows_focus, false)?;
}
Ok(())
@@ -1473,7 +1487,7 @@ impl WindowManager {
tracing::info!("promoting container");
workspace.promote_container()?;
self.update_focused_workspace(self.mouse_follows_focus)
self.update_focused_workspace(self.mouse_follows_focus, true)
}
#[tracing::instrument(skip(self))]
@@ -1496,7 +1510,7 @@ impl WindowManager {
};
workspace.focus_container(target_idx);
self.update_focused_workspace(self.mouse_follows_focus)
self.update_focused_workspace(self.mouse_follows_focus, true)
}
#[tracing::instrument(skip(self))]
@@ -1512,14 +1526,14 @@ impl WindowManager {
let workspace = self.focused_workspace_mut()?;
workspace.new_container_for_focused_window()?;
self.update_focused_workspace(self.mouse_follows_focus)
self.update_focused_workspace(self.mouse_follows_focus, false)
}
#[tracing::instrument(skip(self))]
pub fn toggle_tiling(&mut self) -> Result<()> {
let workspace = self.focused_workspace_mut()?;
workspace.set_tile(!*workspace.tile());
self.update_focused_workspace(false)
self.update_focused_workspace(false, false)
}
#[tracing::instrument(skip(self))]
@@ -1541,7 +1555,7 @@ impl WindowManager {
self.float_window()?;
}
self.update_focused_workspace(is_floating_window)
self.update_focused_workspace(is_floating_window, true)
}
#[tracing::instrument(skip(self))]
@@ -1583,7 +1597,7 @@ impl WindowManager {
Some(_) => self.monocle_off()?,
}
self.update_focused_workspace(true)
self.update_focused_workspace(true, true)
}
#[tracing::instrument(skip(self))]
@@ -1613,7 +1627,7 @@ impl WindowManager {
Some(_) => self.unmaximize_window()?,
}
self.update_focused_workspace(true)
self.update_focused_workspace(true, false)
}
#[tracing::instrument(skip(self))]
@@ -1672,7 +1686,7 @@ impl WindowManager {
}
}
self.update_focused_workspace(false)
self.update_focused_workspace(false, false)
}
#[tracing::instrument(skip(self))]
@@ -1697,7 +1711,7 @@ impl WindowManager {
}
workspace.set_layout(Layout::Default(layout));
self.update_focused_workspace(self.mouse_follows_focus)
self.update_focused_workspace(self.mouse_follows_focus, false)
}
#[tracing::instrument(skip(self))]
@@ -1720,7 +1734,7 @@ impl WindowManager {
Layout::Custom(_) => {}
}
self.update_focused_workspace(self.mouse_follows_focus)
self.update_focused_workspace(self.mouse_follows_focus, false)
}
#[tracing::instrument(skip(self))]
@@ -1750,7 +1764,7 @@ impl WindowManager {
workspace.set_layout(Layout::Custom(layout));
workspace.set_layout_flip(None);
self.update_focused_workspace(self.mouse_follows_focus)
self.update_focused_workspace(self.mouse_follows_focus, false)
}
#[tracing::instrument(skip(self))]
@@ -1765,7 +1779,7 @@ impl WindowManager {
workspace.set_workspace_padding(Option::from(sizing.adjust_by(padding, adjustment)));
self.update_focused_workspace(false)
self.update_focused_workspace(false, false)
}
#[tracing::instrument(skip(self))]
@@ -1780,7 +1794,7 @@ impl WindowManager {
workspace.set_container_padding(Option::from(sizing.adjust_by(padding, adjustment)));
self.update_focused_workspace(false)
self.update_focused_workspace(false, false)
}
#[tracing::instrument(skip(self))]
@@ -1802,7 +1816,7 @@ impl WindowManager {
workspace.set_tile(tile);
self.update_focused_workspace(false)
self.update_focused_workspace(false, false)
}
#[tracing::instrument(skip(self))]
@@ -1846,7 +1860,7 @@ impl WindowManager {
workspace.update(&work_area, offset)?;
Ok(())
} else {
Ok(self.update_focused_workspace(false)?)
Ok(self.update_focused_workspace(false, false)?)
}
}
@@ -1896,7 +1910,7 @@ impl WindowManager {
workspace.update(&work_area, offset)?;
Ok(())
} else {
Ok(self.update_focused_workspace(false)?)
Ok(self.update_focused_workspace(false, false)?)
}
}
@@ -1937,7 +1951,7 @@ impl WindowManager {
workspace.update(&work_area, offset)?;
Ok(())
} else {
Ok(self.update_focused_workspace(false)?)
Ok(self.update_focused_workspace(false, false)?)
}
}
@@ -1978,7 +1992,7 @@ impl WindowManager {
workspace.update(&work_area, offset)?;
Ok(())
} else {
Ok(self.update_focused_workspace(false)?)
Ok(self.update_focused_workspace(false, false)?)
}
}
@@ -2023,7 +2037,7 @@ impl WindowManager {
workspace.update(&work_area, offset)?;
Ok(())
} else {
Ok(self.update_focused_workspace(false)?)
Ok(self.update_focused_workspace(false, false)?)
}
}
@@ -2090,7 +2104,7 @@ impl WindowManager {
workspace.set_workspace_padding(Option::from(size));
self.update_focused_workspace(false)
self.update_focused_workspace(false, false)
}
#[tracing::instrument(skip(self))]
@@ -2139,7 +2153,7 @@ impl WindowManager {
workspace.set_container_padding(Option::from(size));
self.update_focused_workspace(false)
self.update_focused_workspace(false, false)
}
pub fn focused_monitor_size(&self) -> Result<Rect> {
@@ -2243,7 +2257,7 @@ impl WindowManager {
monitor.focus_workspace(idx)?;
monitor.load_focused_workspace(mouse_follows_focus)?;
self.update_focused_workspace(false)
self.update_focused_workspace(false, true)
}
#[tracing::instrument(skip(self))]
@@ -2275,7 +2289,7 @@ impl WindowManager {
monitor.focus_workspace(monitor.new_workspace_idx())?;
monitor.load_focused_workspace(mouse_follows_focus)?;
self.update_focused_workspace(self.mouse_follows_focus)
self.update_focused_workspace(self.mouse_follows_focus, false)
}
pub fn focused_container(&self) -> Result<&Container> {
+27
View File
@@ -357,6 +357,33 @@ impl Workspace {
Ok(())
}
// focus_changed performs updates in response to the fact that a focus
// change event has occurred. The focus change is assumed to be valid, and
// should not result in a new focus change - the intent here is to update
// focus-reactive elements, such as the stackbar.
pub fn focus_changed(&mut self, hwnd: isize) -> Result<()> {
if !self.tile() {
return Ok(());
}
let containers = self.containers_mut();
for container in containers.iter_mut() {
let container_windows = container.windows().clone();
let container_topbar = container.stackbar().clone();
if let Some(idx) = container.idx_for_window(hwnd) {
container.focus_window(idx);
container.restore();
}
if let Some(stackbar) = container_topbar {
stackbar.update(&container_windows, hwnd)?;
}
}
Ok(())
}
pub fn reap_orphans(&mut self) -> Result<(usize, usize)> {
let mut hwnds = vec![];
let mut floating_hwnds = vec![];