Add focus history and Alt-Tab window switching
This commit is contained in:
1 parent
a3431cab5b
commit
0162870cca
18 files changed
+571
-8
No files matched your search
@@ -0,0 +1,100 @@
|
||||
use super::*;
|
||||
|
||||
impl Ferese {
|
||||
pub(super) fn focus_candidates(&self) -> Vec<WindowId> {
|
||||
self.window_ids
|
||||
.iter()
|
||||
.filter_map(|(window, id)| {
|
||||
self.workspaces.workspace_for_window(*id)?;
|
||||
(window.toplevel().is_some()
|
||||
&& self.window_content_ready(window)
|
||||
&& self.window_geometry.contains_key(id)
|
||||
&& self.output_workspaces.focused_output().is_some()
|
||||
&& !self.closing_windows.contains_key(id))
|
||||
.then_some(*id)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn focus_preview_output(&self, id: WindowId) -> Option<OutputId> {
|
||||
if self.closing_windows.contains_key(&id) {
|
||||
return None;
|
||||
}
|
||||
self.workspaces
|
||||
.workspace_for_window(id)
|
||||
.and_then(|workspace| self.output_workspaces.output_for_workspace(workspace))
|
||||
.or_else(|| self.output_workspaces.focused_output())
|
||||
}
|
||||
|
||||
pub(crate) fn focus_last_window(&mut self) {
|
||||
if self.session_lock.active || self.input_capture.captures(1) {
|
||||
return;
|
||||
}
|
||||
self.cancel_focus_cycle();
|
||||
let target = self
|
||||
.focus_history
|
||||
.candidates(self.focused_window, self.focus_candidates())
|
||||
.into_iter()
|
||||
.find(|id| Some(*id) != self.focused_window);
|
||||
if let Some(id) = target {
|
||||
self.activate_managed_window(id);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn cycle_focus(&mut self, reverse: bool, preview: bool) {
|
||||
if self.session_lock.active || self.input_capture.captures(1) {
|
||||
return;
|
||||
}
|
||||
let available = self.focus_candidates();
|
||||
if !preview {
|
||||
self.cancel_focus_cycle();
|
||||
let order = self.focus_history.candidates(self.focused_window, available.clone());
|
||||
let mut cycle = ferese_core::FocusCycle::new(order, self.focused_window);
|
||||
if let Some(id) = cycle.advance(reverse, &available) {
|
||||
self.activate_managed_window(id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if self.focus_cycle.is_none() {
|
||||
let order = self.focus_history.candidates(self.focused_window, available.clone());
|
||||
if order.len() < 2 {
|
||||
return;
|
||||
}
|
||||
self.focus_cycle = Some(ferese_core::FocusCycle::new(order, self.focused_window));
|
||||
if self.overview.is_active() {
|
||||
self.retarget_overview();
|
||||
} else {
|
||||
self.set_overview_active(true);
|
||||
}
|
||||
}
|
||||
if let Some(id) = self
|
||||
.focus_cycle
|
||||
.as_mut()
|
||||
.and_then(|cycle| cycle.advance(reverse, &available))
|
||||
{
|
||||
self.overview.select_window(id);
|
||||
crate::backends::direct::render_all(self);
|
||||
} else {
|
||||
self.cancel_focus_cycle();
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn finish_focus_cycle(&mut self) {
|
||||
let Some(mut cycle) = self.focus_cycle.take() else {
|
||||
return;
|
||||
};
|
||||
if !self.session_lock.active
|
||||
&& !self.input_capture.captures(1)
|
||||
&& let Some(id) = cycle.reconcile(&self.focus_candidates())
|
||||
{
|
||||
self.activate_managed_window(id);
|
||||
}
|
||||
self.set_overview_active(false);
|
||||
}
|
||||
|
||||
pub(crate) fn cancel_focus_cycle(&mut self) {
|
||||
if self.focus_cycle.take().is_some() {
|
||||
self.set_overview_active(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,6 +184,9 @@ impl Ferese {
|
||||
let Some(output_id) = self.output_id(output) else {
|
||||
return false;
|
||||
};
|
||||
if self.focus_cycle.is_some() && self.overview.is_active() {
|
||||
return self.overview.has_window_preview(window) && self.focus_preview_output(window) == Some(output_id);
|
||||
}
|
||||
let workspace = self.workspaces.workspace_for_window(window);
|
||||
workspace == self.output_workspaces.active_workspace(output_id)
|
||||
|| self
|
||||
|
||||
@@ -388,6 +388,7 @@ impl Ferese {
|
||||
let Some(id) = self.window_ids.remove(window) else {
|
||||
return;
|
||||
};
|
||||
self.focus_history.remove(id);
|
||||
self.window_geometry.remove(&id);
|
||||
self.resize_transactions.remove(&id);
|
||||
self.resize_snapshots.remove(&id);
|
||||
|
||||
Reference in new issue
Block a user