Use arbitrary actions, to be defined by source
This commit is contained in:
parent
0aee80e52e
commit
e7a6dc2237
6 changed files with 34 additions and 33 deletions
12
src/main.rs
12
src/main.rs
|
@ -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
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
31
src/roftl.rs
31
src/roftl.rs
|
@ -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];
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue