From da13c36e9b2d19a30ef54dcf117e31bcfb94c2b2 Mon Sep 17 00:00:00 2001 From: Darksome Date: Sun, 26 Mar 2023 14:48:26 +0400 Subject: [PATCH 1/4] Fix focus issue --- rustfmt.toml | 0 src/input/mod.rs | 11 ++++------- src/shell/mod.rs | 13 +++++++++++++ 3 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 rustfmt.toml diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000..e69de29b diff --git a/src/input/mod.rs b/src/input/mod.rs index cc171df1..b6b6b6c2 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -676,10 +676,7 @@ impl State { 0 => 9, x => x - 1, }; - let _ = self - .common - .shell - .activate(¤t_output, workspace as usize); + Shell::activate_and_focus(self, seat, ¤t_output, workspace as usize) } Action::NextWorkspace => { let current_output = seat.active_output(); @@ -690,7 +687,7 @@ impl State { .active_num(¤t_output) .saturating_add(1); // TODO: Possibly move to next output, if idx to large - let _ = self.common.shell.activate(¤t_output, workspace); + Shell::activate_and_focus(self, seat, ¤t_output, workspace) } Action::PreviousWorkspace => { let current_output = seat.active_output(); @@ -701,7 +698,7 @@ impl State { .active_num(¤t_output) .saturating_sub(1); // TODO: Possibly move to prev output, if idx < 0 - let _ = self.common.shell.activate(¤t_output, workspace); + Shell::activate_and_focus(self, seat, ¤t_output, workspace) } Action::LastWorkspace => { let current_output = seat.active_output(); @@ -711,7 +708,7 @@ impl State { .workspaces .len(¤t_output) .saturating_sub(1); - let _ = self.common.shell.activate(¤t_output, workspace); + Shell::activate_and_focus(self, seat, ¤t_output, workspace) } x @ Action::MoveToWorkspace(_) | x @ Action::SendToWorkspace(_) => { let current_output = seat.active_output(); diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 0ff4b8e6..eb12a3d6 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1176,6 +1176,19 @@ impl Shell { } } + pub fn activate_and_focus(state: &mut State, seat: &Seat, output: &Output, idx: usize) { + let _ = state.common.shell.activate(output, idx); + + // without this the last window of the target workspace may not receive focus when switching + // from a workspace having focused fullscreen window (there may be other cases). + let workspace = state.common.shell.active_space(output); + if let Some(mapped) = workspace.focus_stack.get(seat).last() { + // TODO: There should probably be a `KeyboardFocusTargetRef<'a>` to avoid unnecessary + // cloning. + Common::set_focus(state, Some(&(mapped.clone().into())), seat, None); + } + } + pub fn move_current_window( state: &mut State, seat: &Seat, From 32805d8ee034077ea68fa94ffec5e9712226c85c Mon Sep 17 00:00:00 2001 From: Darksome Date: Sat, 1 Apr 2023 20:35:29 +0400 Subject: [PATCH 2/4] Revert "Fix focus issue" This reverts commit da13c36e9b2d19a30ef54dcf117e31bcfb94c2b2. --- rustfmt.toml | 0 src/input/mod.rs | 11 +++++++---- src/shell/mod.rs | 13 ------------- 3 files changed, 7 insertions(+), 17 deletions(-) delete mode 100644 rustfmt.toml diff --git a/rustfmt.toml b/rustfmt.toml deleted file mode 100644 index e69de29b..00000000 diff --git a/src/input/mod.rs b/src/input/mod.rs index b6b6b6c2..cc171df1 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -676,7 +676,10 @@ impl State { 0 => 9, x => x - 1, }; - Shell::activate_and_focus(self, seat, ¤t_output, workspace as usize) + let _ = self + .common + .shell + .activate(¤t_output, workspace as usize); } Action::NextWorkspace => { let current_output = seat.active_output(); @@ -687,7 +690,7 @@ impl State { .active_num(¤t_output) .saturating_add(1); // TODO: Possibly move to next output, if idx to large - Shell::activate_and_focus(self, seat, ¤t_output, workspace) + let _ = self.common.shell.activate(¤t_output, workspace); } Action::PreviousWorkspace => { let current_output = seat.active_output(); @@ -698,7 +701,7 @@ impl State { .active_num(¤t_output) .saturating_sub(1); // TODO: Possibly move to prev output, if idx < 0 - Shell::activate_and_focus(self, seat, ¤t_output, workspace) + let _ = self.common.shell.activate(¤t_output, workspace); } Action::LastWorkspace => { let current_output = seat.active_output(); @@ -708,7 +711,7 @@ impl State { .workspaces .len(¤t_output) .saturating_sub(1); - Shell::activate_and_focus(self, seat, ¤t_output, workspace) + let _ = self.common.shell.activate(¤t_output, workspace); } x @ Action::MoveToWorkspace(_) | x @ Action::SendToWorkspace(_) => { let current_output = seat.active_output(); diff --git a/src/shell/mod.rs b/src/shell/mod.rs index eb12a3d6..0ff4b8e6 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1176,19 +1176,6 @@ impl Shell { } } - pub fn activate_and_focus(state: &mut State, seat: &Seat, output: &Output, idx: usize) { - let _ = state.common.shell.activate(output, idx); - - // without this the last window of the target workspace may not receive focus when switching - // from a workspace having focused fullscreen window (there may be other cases). - let workspace = state.common.shell.active_space(output); - if let Some(mapped) = workspace.focus_stack.get(seat).last() { - // TODO: There should probably be a `KeyboardFocusTargetRef<'a>` to avoid unnecessary - // cloning. - Common::set_focus(state, Some(&(mapped.clone().into())), seat, None); - } - } - pub fn move_current_window( state: &mut State, seat: &Seat, From a11c3e8f67da8902c86b93e15ac076597d06e7e9 Mon Sep 17 00:00:00 2001 From: Darksome Date: Sat, 1 Apr 2023 20:35:58 +0400 Subject: [PATCH 3/4] Fix refresh_focus --- rustfmt.toml | 0 src/shell/element/mod.rs | 8 ++++++++ src/shell/element/stack.rs | 5 +++++ src/shell/element/window.rs | 4 ++++ src/shell/focus/mod.rs | 21 ++++++++++++++++++--- 5 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 rustfmt.toml diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000..e69de29b diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 702281d3..8e2d04c9 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -132,6 +132,14 @@ impl CosmicMapped { } } + pub fn has_active_window(&self, window: &CosmicSurface) -> bool { + match &self.element { + CosmicMappedInternal::Stack(stack) => stack.has_active(window), + CosmicMappedInternal::Window(win) => win.contains_surface(window), + _ => unreachable!(), + } + } + pub fn active_window_offset(&self) -> Point { match &self.element { CosmicMappedInternal::Stack(stack) => stack.offset(), diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 724f88ef..1d7ecb5e 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -124,6 +124,11 @@ impl CosmicStack { .with_program(|p| p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)].clone()) } + pub fn has_active(&self, window: &CosmicSurface) -> bool { + self.0 + .with_program(|p| &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)] == window) + } + pub fn set_active(&self, window: &CosmicSurface) { self.0.with_program(|p| { if let Some(val) = p.windows.lock().unwrap().iter().position(|w| w == window) { diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 06ff52d5..b85139e4 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -149,6 +149,10 @@ impl CosmicWindow { self.0.with_program(|p| p.window.clone()) } + pub fn contains_surface(&self, window: &CosmicSurface) -> bool { + self.0.with_program(|p| &p.window == window) + } + pub fn offset(&self) -> Point { let has_ssd = self.0.with_program(|p| p.has_ssd()); if has_ssd { diff --git a/src/shell/focus/mod.rs b/src/shell/focus/mod.rs index d4b30a03..cc5a0c1f 100644 --- a/src/shell/focus/mod.rs +++ b/src/shell/focus/mod.rs @@ -216,9 +216,24 @@ impl Common { continue; // Focus is valid, } } - KeyboardFocusTarget::Popup(_) | KeyboardFocusTarget::Fullscreen(_) => { - continue; - } // Focus is valid + KeyboardFocusTarget::Fullscreen(surface) => { + let workspace = state.common.shell.active_space(&output); + let focus_stack = workspace.focus_stack.get(&seat); + + if focus_stack + .last() + .map(|m| m.has_active_window(&surface)) + .unwrap_or(false) + && workspace.get_fullscreen(&output).is_some() + { + continue; // Focus is valid + } else { + trace!("Wrong Window, focus fixup"); + } + } + KeyboardFocusTarget::Popup(_) => { + continue; // Focus is valid + } }; } else { trace!("Surface dead, focus fixup"); From e3a718dab5714eabf4d01211a25fd8dea45a64e1 Mon Sep 17 00:00:00 2001 From: Darksome Date: Sat, 1 Apr 2023 21:01:00 +0400 Subject: [PATCH 4/4] Fix focus when switching from empty workspace --- src/shell/focus/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/shell/focus/mod.rs b/src/shell/focus/mod.rs index cc5a0c1f..bd53c4fa 100644 --- a/src/shell/focus/mod.rs +++ b/src/shell/focus/mod.rs @@ -239,7 +239,14 @@ impl Common { trace!("Surface dead, focus fixup"); } } else { - continue; + let workspace = state.common.shell.active_space(&output); + let focus_stack = workspace.focus_stack.get(&seat); + + if focus_stack.last().is_none() { + continue; // Focus is valid + } else { + trace!("No previous window, focus fixup"); + } } // fixup focus