add password + enter for worf warden
This commit is contained in:
parent
6632f2f123
commit
ab56048574
3 changed files with 79 additions and 61 deletions
|
@ -44,7 +44,7 @@ impl PasswordProvider {
|
|||
key.clone(),
|
||||
None,
|
||||
None,
|
||||
vec![],
|
||||
vec![].into_iter().collect(),
|
||||
None,
|
||||
0.0,
|
||||
Some(MenuItemMetaData { ids: value.clone() }),
|
||||
|
@ -59,7 +59,7 @@ impl PasswordProvider {
|
|||
format!("Error from rbw: {error}"),
|
||||
None,
|
||||
None,
|
||||
vec![],
|
||||
vec![].into_iter().collect(),
|
||||
None,
|
||||
0.0,
|
||||
None,
|
||||
|
@ -79,11 +79,11 @@ impl PasswordProvider {
|
|||
rbw_get_user(id, false)?,
|
||||
None,
|
||||
None,
|
||||
vec![],
|
||||
vec![].into_iter().collect(),
|
||||
None,
|
||||
0.0,
|
||||
Some(MenuItemMetaData {
|
||||
ids: vec![id.clone()],
|
||||
ids: vec![id.clone()].into_iter().collect(),
|
||||
}),
|
||||
))
|
||||
})
|
||||
|
@ -125,7 +125,16 @@ fn keyboard_type(text: &str) {
|
|||
|
||||
fn keyboard_tab() {
|
||||
Command::new("ydotool")
|
||||
.arg("TAB")
|
||||
.arg("type")
|
||||
.arg("\t")
|
||||
.output()
|
||||
.expect("Failed to execute ydotool");
|
||||
}
|
||||
|
||||
fn keyboard_return() {
|
||||
Command::new("ydotool")
|
||||
.arg("type")
|
||||
.arg("\n")
|
||||
.output()
|
||||
.expect("Failed to execute ydotool");
|
||||
}
|
||||
|
@ -178,7 +187,7 @@ fn rbw_get_totp(id: &str, copy: bool) -> Result<String, String> {
|
|||
fn key_type_all() -> KeyBinding {
|
||||
KeyBinding {
|
||||
key: Key::Num1,
|
||||
modifiers: Modifier::Alt,
|
||||
modifiers: vec![Modifier::Alt].into_iter().collect(),
|
||||
label: "<b>Alt+1</b> Type All".to_string(),
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +195,7 @@ fn key_type_all() -> KeyBinding {
|
|||
fn key_type_user() -> KeyBinding {
|
||||
KeyBinding {
|
||||
key: Key::Num2,
|
||||
modifiers: Modifier::Alt,
|
||||
modifiers: vec![Modifier::Alt].into_iter().collect(),
|
||||
label: "<b>Alt+2</b> Type User".to_string(),
|
||||
}
|
||||
}
|
||||
|
@ -194,15 +203,23 @@ fn key_type_user() -> KeyBinding {
|
|||
fn key_type_password() -> KeyBinding {
|
||||
KeyBinding {
|
||||
key: Key::Num3,
|
||||
modifiers: Modifier::Alt,
|
||||
modifiers: vec![Modifier::Alt].into_iter().collect(),
|
||||
label: "<b>Alt+3</b> Type Password".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn key_type_password_and_enter() -> KeyBinding {
|
||||
KeyBinding {
|
||||
key: Key::Hash,
|
||||
modifiers: vec![Modifier::Alt, Modifier::Shift].into_iter().collect(),
|
||||
label: "<b>Alt+Shift+3</b> Type Password + Enter".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn key_type_totp() -> KeyBinding {
|
||||
KeyBinding {
|
||||
key: Key::Num4,
|
||||
modifiers: Modifier::Alt,
|
||||
modifiers: vec![Modifier::Alt].into_iter().collect(),
|
||||
label: "<b>Alt+4</b> Type Totp".to_string(),
|
||||
}
|
||||
}
|
||||
|
@ -210,7 +227,7 @@ fn key_type_totp() -> KeyBinding {
|
|||
fn key_sync() -> KeyBinding {
|
||||
KeyBinding {
|
||||
key: Key::R,
|
||||
modifiers: Modifier::Alt,
|
||||
modifiers: vec![Modifier::Alt].into_iter().collect(),
|
||||
label: "<b>Alt+r</b> Sync".to_string(),
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +236,7 @@ fn key_sync() -> KeyBinding {
|
|||
fn key_totp() -> KeyBinding {
|
||||
KeyBinding {
|
||||
key: Key::T,
|
||||
modifiers: Modifier::Alt,
|
||||
modifiers: vec![Modifier::Alt].into_iter().collect(),
|
||||
label: "<b>Alt+t</b> Totp".to_string(),
|
||||
}
|
||||
}
|
||||
|
@ -227,7 +244,7 @@ fn key_totp() -> KeyBinding {
|
|||
fn key_lock() -> KeyBinding {
|
||||
KeyBinding {
|
||||
key: Key::L,
|
||||
modifiers: Modifier::Alt,
|
||||
modifiers: vec![Modifier::Alt].into_iter().collect(),
|
||||
label: "<b>Alt+l</b> Lock".to_string(),
|
||||
}
|
||||
}
|
||||
|
@ -242,6 +259,7 @@ fn show(config: Config, provider: PasswordProvider) -> Result<(), String> {
|
|||
key_type_all(),
|
||||
key_type_user(),
|
||||
key_type_password(),
|
||||
key_type_password_and_enter(),
|
||||
key_type_totp(),
|
||||
key_sync(),
|
||||
key_totp(),
|
||||
|
@ -256,7 +274,7 @@ fn show(config: Config, provider: PasswordProvider) -> Result<(), String> {
|
|||
|
||||
let id = meta.ids.first().unwrap_or(&selection.menu.label);
|
||||
|
||||
sleep(Duration::from_millis(250));
|
||||
sleep(Duration::from_millis(500));
|
||||
if let Some(key) = selection.custom_key {
|
||||
if key == key_type_all() {
|
||||
keyboard_type(&rbw_get_user(id, false)?);
|
||||
|
@ -266,6 +284,9 @@ fn show(config: Config, provider: PasswordProvider) -> Result<(), String> {
|
|||
keyboard_type(&rbw_get_user(id, false)?);
|
||||
} else if key == key_type_password() {
|
||||
keyboard_type(&rbw_get_password(id, false)?);
|
||||
} else if key == key_type_password_and_enter() {
|
||||
keyboard_type(&rbw_get_password(id, false)?);
|
||||
keyboard_return();
|
||||
} else if key == key_type_totp() {
|
||||
keyboard_type(&rbw_get_totp(id, false)?);
|
||||
} else if key == key_lock() {
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::time::Instant;
|
||||
|
||||
use crossbeam::channel;
|
||||
use crossbeam::channel::Sender;
|
||||
use crossbeam::channel::internal::SelectHandle;
|
||||
use gdk4::Display;
|
||||
use gdk4::gio::File;
|
||||
use gdk4::glib::{MainContext, Propagation};
|
||||
|
@ -339,24 +338,39 @@ pub enum Modifier {
|
|||
None,
|
||||
}
|
||||
|
||||
impl From<gdk4::ModifierType> for Modifier {
|
||||
fn from(value: gdk4::ModifierType) -> Self {
|
||||
match value {
|
||||
gdk4::ModifierType::SHIFT_MASK => Modifier::Shift,
|
||||
gdk4::ModifierType::CONTROL_MASK => Modifier::Control,
|
||||
gdk4::ModifierType::ALT_MASK => Modifier::Alt,
|
||||
gdk4::ModifierType::SUPER_MASK => Modifier::Super,
|
||||
gdk4::ModifierType::META_MASK => Modifier::Meta,
|
||||
gdk4::ModifierType::LOCK_MASK => Modifier::CapsLock,
|
||||
_ => Modifier::None,
|
||||
fn modifiers_from_mask(mask: gdk4::ModifierType) -> HashSet<Modifier> {
|
||||
let mut modifiers = HashSet::new();
|
||||
|
||||
if mask.contains(gdk4::ModifierType::SHIFT_MASK) {
|
||||
modifiers.insert(Modifier::Shift);
|
||||
}
|
||||
if mask.contains(gdk4::ModifierType::CONTROL_MASK) {
|
||||
modifiers.insert(Modifier::Control);
|
||||
}
|
||||
if mask.contains(gdk4::ModifierType::ALT_MASK) {
|
||||
modifiers.insert(Modifier::Alt);
|
||||
}
|
||||
if mask.contains(gdk4::ModifierType::SUPER_MASK) {
|
||||
modifiers.insert(Modifier::Super);
|
||||
}
|
||||
if mask.contains(gdk4::ModifierType::META_MASK) {
|
||||
modifiers.insert(Modifier::Meta);
|
||||
}
|
||||
if mask.contains(gdk4::ModifierType::LOCK_MASK) {
|
||||
modifiers.insert(Modifier::CapsLock);
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
if modifiers.is_empty() {
|
||||
modifiers.insert(Modifier::None);
|
||||
}
|
||||
|
||||
modifiers
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub struct KeyBinding {
|
||||
pub key: Key,
|
||||
pub modifiers: Modifier, // todo support masks
|
||||
pub modifiers: HashSet<Modifier>,
|
||||
pub label: String,
|
||||
}
|
||||
|
||||
|
@ -566,22 +580,19 @@ fn build_ui<T, P>(
|
|||
let (_changed, provider_elements) = get_provider_elements.join().unwrap();
|
||||
log::debug!("got items after {:?}", wait_for_items.elapsed());
|
||||
|
||||
let animate_cfg = config.clone();
|
||||
let active_cfg = config.clone();
|
||||
let map_cfg = config.clone();
|
||||
let animate_window = ui_elements.window.clone();
|
||||
|
||||
let (sender, receiver) = channel::bounded(1);
|
||||
animate_window.connect_is_active_notify(move |w| {
|
||||
w.set_opacity(1.0);
|
||||
window_show_resize(&animate_cfg.clone(), w);
|
||||
if let Err(e) = sender.send(()) {
|
||||
log::debug!("cannot unblock menu builder {e:?}");
|
||||
}
|
||||
window_show_resize(&active_cfg.clone(), w);
|
||||
});
|
||||
animate_window.connect_map(move |w| {
|
||||
window_show_resize(&map_cfg.clone(), w);
|
||||
});
|
||||
|
||||
build_ui_from_menu_items(&ui_elements, &meta, provider_elements, Some(receiver));
|
||||
build_ui_from_menu_items(&ui_elements, &meta, provider_elements);
|
||||
|
||||
// hide the fact that we are starting with a small window
|
||||
ui_elements.window.set_opacity(0.01);
|
||||
let window_start = Instant::now();
|
||||
ui_elements.window.present();
|
||||
log::debug!("window show took {:?}", window_start.elapsed());
|
||||
|
@ -685,7 +696,6 @@ fn build_ui_from_menu_items<T: Clone + 'static + Send>(
|
|||
ui: &Rc<UiElements<T>>,
|
||||
meta: &Rc<MetaData<T>>,
|
||||
mut items: Vec<MenuItem<T>>,
|
||||
wait_for_signal: Option<channel::Receiver<()>>,
|
||||
) {
|
||||
let start = Instant::now();
|
||||
{
|
||||
|
@ -699,12 +709,6 @@ fn build_ui_from_menu_items<T: Clone + 'static + Send>(
|
|||
let ui_clone = Rc::<UiElements<T>>::clone(ui);
|
||||
|
||||
glib::idle_add_local(move || {
|
||||
if let Some(wait) = &wait_for_signal {
|
||||
if !wait.is_ready() {
|
||||
return ControlFlow::Continue;
|
||||
}
|
||||
}
|
||||
|
||||
ui_clone.main_box.unset_sort_func();
|
||||
let mut done = false;
|
||||
{
|
||||
|
@ -797,15 +801,18 @@ fn handle_key_press<T: Clone + 'static + Send>(
|
|||
let update_view_from_provider = |query: &String| {
|
||||
let (changed, filtered_list) = meta.item_provider.lock().unwrap().get_elements(Some(query));
|
||||
if changed {
|
||||
build_ui_from_menu_items(ui, meta, filtered_list, None);
|
||||
build_ui_from_menu_items(ui, meta, filtered_list);
|
||||
}
|
||||
update_view(query);
|
||||
};
|
||||
|
||||
if let Some(custom_keys) = custom_keys {
|
||||
let mods = modifiers_from_mask(modifier_type);
|
||||
for custom_key in custom_keys {
|
||||
if custom_key.key == keyboard_key.into() && custom_key.modifiers == modifier_type.into()
|
||||
{
|
||||
log::debug!(
|
||||
"comparing custom key {custom_key:?} to mask {mods:?} and key {keyboard_key}"
|
||||
);
|
||||
if custom_key.key == keyboard_key.into() && mods.is_subset(&custom_key.modifiers) {
|
||||
let search_lock = ui.search_text.lock().unwrap();
|
||||
if let Err(e) = handle_selected_item(
|
||||
ui,
|
||||
|
@ -874,7 +881,7 @@ fn handle_key_press<T: Clone + 'static + Send>(
|
|||
if let Some(changed) = opt_changed {
|
||||
let items = changed.0.1.unwrap_or_default();
|
||||
if changed.0.0 {
|
||||
build_ui_from_menu_items(ui, meta, items, None);
|
||||
build_ui_from_menu_items(ui, meta, items);
|
||||
}
|
||||
|
||||
let query = changed.1;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use crate::config::Config;
|
||||
use crate::desktop::{copy_to_clipboard, spawn_fork};
|
||||
use crate::desktop::spawn_fork;
|
||||
use crate::gui::{ItemProvider, MenuItem};
|
||||
use crate::modes::drun::{DRunProvider, update_drun_cache_and_run};
|
||||
use crate::modes::emoji::EmojiProvider;
|
||||
use crate::modes::file::FileItemProvider;
|
||||
use crate::modes::math::MathProvider;
|
||||
use crate::modes::ssh;
|
||||
|
@ -16,7 +15,6 @@ enum AutoRunType {
|
|||
DRun,
|
||||
File,
|
||||
Ssh,
|
||||
Emoji,
|
||||
// WebSearch,
|
||||
}
|
||||
|
||||
|
@ -152,14 +150,6 @@ pub fn show(config: &Config) -> Result<(), Error> {
|
|||
ssh::launch(&selection_result, config)?;
|
||||
break;
|
||||
}
|
||||
AutoRunType::Emoji => {
|
||||
if let Some(action) = selection_result.action {
|
||||
copy_to_clipboard(action, None)?;
|
||||
} else {
|
||||
return Err(Error::MissingAction);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if selection_result.label.starts_with("ssh") {
|
||||
selection_result.label = selection_result.label.chars().skip(4).collect();
|
||||
|
|
Loading…
Add table
Reference in a new issue