Fix next/prev-window commands

The prev-window commands never worked.  They only switched between the last two
recently used windows ignoring all others.
timeout_old
Tassilo Horn 3 years ago
parent 637cbff935
commit d83acacea0
  1. 51
      src/cmds.rs
  2. 7
      src/con.rs
  3. 1
      src/demon.rs

@ -26,6 +26,7 @@ use rand;
use rand::prelude::SliceRandom; use rand::prelude::SliceRandom;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::atomic;
use std::sync::Arc; use std::sync::Arc;
use std::sync::RwLock; use std::sync::RwLock;
use swayipc as s; use swayipc as s;
@ -140,6 +141,24 @@ pub enum SwayrCommand {
ExecuteSwayrCommand, ExecuteSwayrCommand,
} }
impl SwayrCommand {
fn is_prev_next_window_variant(&self) -> bool {
matches!(
self,
SwayrCommand::NextWindow { .. }
| SwayrCommand::PrevWindow { .. }
| SwayrCommand::NextTiledWindow { .. }
| SwayrCommand::PrevTiledWindow { .. }
| SwayrCommand::NextTabbedOrStackedWindow { .. }
| SwayrCommand::PrevTabbedOrStackedWindow { .. }
| SwayrCommand::NextFloatingWindow { .. }
| SwayrCommand::PrevFloatingWindow { .. }
| SwayrCommand::NextSimilarWindow { .. }
| SwayrCommand::PrevSimilarWindow { .. }
)
}
}
pub struct ExecSwayrCmdArgs<'a> { pub struct ExecSwayrCmdArgs<'a> {
pub cmd: &'a SwayrCommand, pub cmd: &'a SwayrCommand,
pub extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>, pub extra_props: Arc<RwLock<HashMap<i64, con::ExtraProps>>>,
@ -156,8 +175,25 @@ fn always_true(_x: &con::Window) -> bool {
true true
} }
static IN_NEXT_PREV_WINDOW_SEQ: atomic::AtomicBool =
atomic::AtomicBool::new(false);
pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) { pub fn exec_swayr_cmd(args: ExecSwayrCmdArgs) {
let props = args.extra_props; let props = args.extra_props;
if args.cmd.is_prev_next_window_variant() {
let before =
IN_NEXT_PREV_WINDOW_SEQ.swap(true, atomic::Ordering::SeqCst);
if !before {
let mut map = props.write().unwrap();
for val in map.values_mut() {
val.last_focus_time_for_next_prev_seq = val.last_focus_time;
}
}
} else {
IN_NEXT_PREV_WINDOW_SEQ.store(false, atomic::Ordering::SeqCst);
}
match args.cmd { match args.cmd {
SwayrCommand::SwitchToUrgentOrLRUWindow => { SwayrCommand::SwitchToUrgentOrLRUWindow => {
switch_to_urgent_or_lru_window(Some(&*props.read().unwrap())) switch_to_urgent_or_lru_window(Some(&*props.read().unwrap()))
@ -393,15 +429,22 @@ pub fn focus_window_in_direction(
} }
}; };
let windows: Vec<con::Window> = con::get_windows(root, false, extra_props) let mut windows: Vec<con::Window> =
.into_iter() con::get_windows(root, false, extra_props)
.filter(|w| pred(w)) .into_iter()
.collect(); .filter(|w| pred(w))
.collect();
if windows.len() < 2 { if windows.len() < 2 {
return; return;
} }
windows.sort_by(|a, b| {
let lru_a = a.last_focus_time_for_next_prev_seq();
let lru_b = b.last_focus_time_for_next_prev_seq();
lru_a.cmp(&lru_b).reverse()
});
let is_focused_window: Box<dyn Fn(&con::Window) -> bool> = let is_focused_window: Box<dyn Fn(&con::Window) -> bool> =
if !windows.iter().any(|w| w.is_focused()) { if !windows.iter().any(|w| w.is_focused()) {
let last_focused_win_id = windows.get(0).unwrap().get_id(); let last_focused_win_id = windows.get(0).unwrap().get_id();

@ -113,6 +113,7 @@ impl NodeMethods for s::Node {
pub struct ExtraProps { pub struct ExtraProps {
/// Milliseconds since UNIX epoch. /// Milliseconds since UNIX epoch.
pub last_focus_time: u128, pub last_focus_time: u128,
pub last_focus_time_for_next_prev_seq: u128,
} }
#[derive(Debug)] #[derive(Debug)]
@ -176,6 +177,12 @@ impl Window<'_> {
let layout = &self.get_parent().layout; let layout = &self.get_parent().layout;
layout == &s::NodeLayout::Tabbed || layout == &s::NodeLayout::Stacked layout == &s::NodeLayout::Tabbed || layout == &s::NodeLayout::Stacked
} }
pub fn last_focus_time_for_next_prev_seq(&self) -> u128 {
self.extra_props
.as_ref()
.map_or(0, |wp| wp.last_focus_time_for_next_prev_seq)
}
} }
impl PartialEq for Window<'_> { impl PartialEq for Window<'_> {

@ -186,6 +186,7 @@ fn update_last_focus_time(
id, id,
con::ExtraProps { con::ExtraProps {
last_focus_time: get_epoch_time_as_millis(), last_focus_time: get_epoch_time_as_millis(),
last_focus_time_for_next_prev_seq: 0,
}, },
); );
} }

Loading…
Cancel
Save