Use arbitrary actions, to be defined by source

This commit is contained in:
Armin Friedl 2021-11-09 23:48:36 +01:00
parent 0aee80e52e
commit e7a6dc2237
6 changed files with 34 additions and 33 deletions

View file

@ -112,7 +112,7 @@ impl RoftlLoop {
// quick switch if only one result // quick switch if only one result
if results.len() == 1 { if results.len() == 1 {
self.roftl.do_action(0, roftl::Action::Primary); self.roftl.exec_default(0);
*flow = ControlFlow::Exit; *flow = ControlFlow::Exit;
return; return;
} }
@ -185,7 +185,7 @@ impl RoftlLoop {
// Enter // Enter
c if c == char::from(0x0d) => { c if c == char::from(0x0d) => {
trace!{"Retrieved enter. Trigger primary action"} trace!{"Retrieved enter. Trigger primary action"}
self.roftl.do_action(self.selection, roftl::Action::Primary); self.roftl.exec_action(self.selection, 0);
ControlFlow::Exit ControlFlow::Exit
} }
@ -235,22 +235,22 @@ impl RoftlLoop {
match character { match character {
'1' => { '1' => {
trace!{"Retrieved action selection 1. Trigger primary action"} trace!{"Retrieved action selection 1. Trigger primary action"}
self.roftl.do_action(self.selection, roftl::Action::Primary); self.roftl.exec_action(self.selection, 0);
ControlFlow::Exit ControlFlow::Exit
}, },
'2' => { '2' => {
trace!{"Retrieved action selection 2. Trigger secondary action"} trace!{"Retrieved action selection 2. Trigger secondary action"}
self.roftl.do_action(self.selection, roftl::Action::Secondary); self.roftl.exec_action(self.selection, 1);
ControlFlow::Exit ControlFlow::Exit
}, },
'3' => { '3' => {
trace!{"Retrieved action selection 3. Trigger tertiary action"} trace!{"Retrieved action selection 3. Trigger tertiary action"}
self.roftl.do_action(self.selection, roftl::Action::Tertiary); self.roftl.exec_action(self.selection, 2);
ControlFlow::Exit ControlFlow::Exit
}, },
'4' => { '4' => {
trace!{"Retrieved action selection 4. Trigger quaternary action"} trace!{"Retrieved action selection 4. Trigger quaternary action"}
self.roftl.do_action(self.selection, roftl::Action::Quaternary); self.roftl.exec_action(self.selection, 3);
ControlFlow::Exit ControlFlow::Exit
}, },

View file

@ -14,20 +14,16 @@ pub struct Entry {
pub identifier: u64, pub identifier: u64,
} }
#[derive(Debug)]
pub enum Action {
Primary,
Secondary,
Tertiary,
Quaternary
}
pub trait Source: Send + Sync { pub trait Source: Send + Sync {
fn name(&self) -> &'static str; fn name(&self) -> &'static str;
fn entries(&mut self) -> Vec<Entry>; fn entries(&mut self) -> Vec<Entry>;
fn action(&self, entry: &Entry, action: Action);
fn actions(&self, _entry: &Entry) -> Vec<String> fn actions(&self, _entry: &Entry) -> Vec<String>
{ vec![] } { vec![] }
fn exec_default(&self, entry: &Entry)
{ self.exec_action(entry, 0) }
fn exec_action(&self, entry: &Entry, action: u8);
} }
pub trait Matcher: Send + Sync { pub trait Matcher: Send + Sync {
@ -82,7 +78,7 @@ impl Roftl {
.flat_map(|s| s.entries()) .flat_map(|s| s.entries())
.collect(); .collect();
debug!("Entries {:?}", self.entries); debug!("Sourced {} entries from {} sources", self.entries.len(), self.sources.len());
} }
pub fn narrow(&mut self, input: &str) -> Vec<(&Entry, Vec<usize>)> { pub fn narrow(&mut self, input: &str) -> Vec<(&Entry, Vec<usize>)> {
@ -133,16 +129,21 @@ impl Roftl {
.collect() .collect()
} }
pub fn do_action(&self, selection_id: usize, action: Action) {
let (entry, source) = self.find_selection(selection_id);
source.action(entry, action);
}
pub fn actions(&self, selection_id: usize) -> Vec<String> { pub fn actions(&self, selection_id: usize) -> Vec<String> {
let (entry, source) = self.find_selection(selection_id); let (entry, source) = self.find_selection(selection_id);
source.actions(entry) source.actions(entry)
} }
pub fn exec_default(&self, selection_id: usize) {
let (entry, source) = self.find_selection(selection_id);
source.exec_default(entry);
}
pub fn exec_action(&self, selection_id: usize, action: u8) {
let (entry, source) = self.find_selection(selection_id);
source.exec_action(entry, action);
}
fn find_selection(&self, selection_id: usize) -> (&Entry, &Box<dyn Source>) fn find_selection(&self, selection_id: usize) -> (&Entry, &Box<dyn Source>)
{ {
let entry_id = self.narrow_map[selection_id]; let entry_id = self.narrow_map[selection_id];

View file

@ -5,7 +5,7 @@ use log::{debug, error, trace};
use walkdir::WalkDir; use walkdir::WalkDir;
use nix::unistd::{getpid, setpgid}; use nix::unistd::{getpid, setpgid};
use crate::roftl::{Action, Entry, Source}; use crate::roftl::{Entry, Source};
#[derive(Debug)] #[derive(Debug)]
struct App { struct App {
@ -176,7 +176,7 @@ impl Source for Apps {
entries entries
} }
fn action(&self, entry: &Entry, action: Action) { fn exec_action(&self, entry: &Entry, action: u8) {
debug!{"Got desktop entry {:?} for action", entry} debug!{"Got desktop entry {:?} for action", entry}
debug!{"Desktop entry has id {}", entry.identifier} debug!{"Desktop entry has id {}", entry.identifier}
trace!{"Apps has entries {:?}", self.entries} trace!{"Apps has entries {:?}", self.entries}

View file

@ -3,7 +3,7 @@ use log::{debug, error};
use nix::unistd::{getpid, setpgid}; use nix::unistd::{getpid, setpgid};
use walkdir::WalkDir; use walkdir::WalkDir;
use crate::roftl::{Entry, Source, Action}; use crate::roftl::{Entry, Source};
pub struct ShellHost { pub struct ShellHost {
scripts: Vec<PathBuf>, scripts: Vec<PathBuf>,
@ -43,7 +43,7 @@ impl Source for ShellHost {
entries entries
} }
fn action(&self, entry: &Entry, action: Action) { fn exec_action(&self, entry: &Entry, action: u8) {
let script: &PathBuf = self.scripts.get(entry.identifier as usize).unwrap(); let script: &PathBuf = self.scripts.get(entry.identifier as usize).unwrap();
debug!{"Got script {:?}", script}; debug!{"Got script {:?}", script};

View file

@ -1,4 +1,4 @@
use crate::roftl::{Entry, Source, Action}; use crate::roftl::{Entry, Source};
pub struct TestSource { pub struct TestSource {
entries: Vec<Entry>, entries: Vec<Entry>,
@ -38,7 +38,7 @@ impl Source for TestSource {
self.entries.clone() self.entries.clone()
} }
fn action(&self, entry: &Entry, action: Action) { fn exec_action(&self, entry: &Entry, action: u8) {
println!("Doing action {:?} for entry {}", action, entry.name) println!("Doing action {:?} for entry {}", action, entry.name)
} }

View file

@ -1,7 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::ptr; use std::ptr;
use crate::roftl::{Entry, Source, Action}; use crate::roftl::{Entry, Source};
use log::debug; use log::debug;
use xcb::ffi::XCB_CURRENT_TIME; use xcb::ffi::XCB_CURRENT_TIME;
use xcb_util::ewmh; use xcb_util::ewmh;
@ -111,31 +111,31 @@ impl Source for Window {
entries entries
} }
fn action(&self, entry: &Entry, action: Action) { fn exec_action(&self, entry: &Entry, action: u8) {
debug!("Doing action {:?} for entry {}", action, entry.name); debug!("Doing action {:?} for entry {}", action, entry.name);
match action { match action {
Action::Primary => { 0 => {
let (window, screen) = *self.action_data.get(&entry.identifier).unwrap(); let (window, screen) = *self.action_data.get(&entry.identifier).unwrap();
let (xcb_conn, _screen_num) = xcb::base::Connection::connect(None).expect("Could not connect to X server"); let (xcb_conn, _screen_num) = xcb::base::Connection::connect(None).expect("Could not connect to X server");
let ewmh_conn = ewmh::Connection::connect(xcb_conn).map_err(|(e,_)| e).unwrap(); let ewmh_conn = ewmh::Connection::connect(xcb_conn).map_err(|(e,_)| e).unwrap();
self.switch_window(&ewmh_conn, window, screen).unwrap() self.switch_window(&ewmh_conn, window, screen).unwrap()
}, },
Action::Secondary => { 1 => {
let (window, screen) = *self.action_data.get(&entry.identifier).unwrap(); let (window, screen) = *self.action_data.get(&entry.identifier).unwrap();
let (xcb_conn, _screen_num) = xcb::base::Connection::connect(None).expect("Could not connect to X server"); let (xcb_conn, _screen_num) = xcb::base::Connection::connect(None).expect("Could not connect to X server");
let ewmh_conn = ewmh::Connection::connect(xcb_conn).map_err(|(e,_)| e).unwrap(); let ewmh_conn = ewmh::Connection::connect(xcb_conn).map_err(|(e,_)| e).unwrap();
self.toggle_maximize_window(&ewmh_conn, window, screen).unwrap(); self.toggle_maximize_window(&ewmh_conn, window, screen).unwrap();
self.switch_window(&ewmh_conn, window, screen).unwrap() self.switch_window(&ewmh_conn, window, screen).unwrap()
}, },
Action::Tertiary => { 2 => {
let (window, screen) = *self.action_data.get(&entry.identifier).unwrap(); let (window, screen) = *self.action_data.get(&entry.identifier).unwrap();
let (xcb_conn, _screen_num) = xcb::base::Connection::connect(None).expect("Could not connect to X server"); let (xcb_conn, _screen_num) = xcb::base::Connection::connect(None).expect("Could not connect to X server");
let ewmh_conn = ewmh::Connection::connect(xcb_conn).map_err(|(e,_)| e).unwrap(); let ewmh_conn = ewmh::Connection::connect(xcb_conn).map_err(|(e,_)| e).unwrap();
self.toggle_hide_window(&ewmh_conn, window, screen).unwrap(); self.toggle_hide_window(&ewmh_conn, window, screen).unwrap();
}, },
Action::Quaternary => { 3 => {
let (window, screen) = *self.action_data.get(&entry.identifier).unwrap(); let (window, screen) = *self.action_data.get(&entry.identifier).unwrap();
let (xcb_conn, _screen_num) = xcb::base::Connection::connect(None).expect("Could not connect to X server"); let (xcb_conn, _screen_num) = xcb::base::Connection::connect(None).expect("Could not connect to X server");
let ewmh_conn = ewmh::Connection::connect(xcb_conn).map_err(|(e,_)| e).unwrap(); let ewmh_conn = ewmh::Connection::connect(xcb_conn).map_err(|(e,_)| e).unwrap();