hotkey.rs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. use crate::{data::*, feat, log_if_err};
  2. use anyhow::{bail, Result};
  3. use std::collections::HashMap;
  4. use tauri_hotkey::{parse_hotkey, HotkeyManager};
  5. pub struct Hotkey {
  6. current: Vec<String>, // 保存当前的热键设置
  7. manager: HotkeyManager,
  8. }
  9. impl Hotkey {
  10. pub fn new() -> Hotkey {
  11. Hotkey {
  12. current: Vec::new(),
  13. manager: HotkeyManager::new(),
  14. }
  15. }
  16. pub fn init(&mut self) -> Result<()> {
  17. let data = Data::global();
  18. let verge = data.verge.lock();
  19. if let Some(hotkeys) = verge.hotkeys.as_ref() {
  20. for hotkey in hotkeys.iter() {
  21. let mut iter = hotkey.split(',');
  22. let func = iter.next();
  23. let key = iter.next();
  24. if func.is_some() && key.is_some() {
  25. log_if_err!(self.register(func.unwrap(), key.unwrap()));
  26. } else {
  27. log::error!(target: "app", "invalid hotkey \"{}\":\"{}\"", func.unwrap_or("None"), key.unwrap_or("None"));
  28. }
  29. }
  30. self.current = hotkeys.clone();
  31. }
  32. Ok(())
  33. }
  34. fn register(&mut self, func: &str, key: &str) -> Result<()> {
  35. let hotkey = parse_hotkey(key.trim())?;
  36. if self.manager.is_registered(&hotkey) {
  37. self.manager.unregister(&hotkey)?;
  38. }
  39. let f = match func.trim() {
  40. "clash_mode_rule" => || feat::change_clash_mode("rule"),
  41. "clash_mode_direct" => || feat::change_clash_mode("direct"),
  42. "clash_mode_global" => || feat::change_clash_mode("global"),
  43. "clash_moda_script" => || feat::change_clash_mode("script"),
  44. "toggle_system_proxy" => || feat::toggle_system_proxy(),
  45. "enable_system_proxy" => || feat::enable_system_proxy(),
  46. "disable_system_proxy" => || feat::disable_system_proxy(),
  47. "toggle_tun_mode" => || feat::toggle_tun_mode(),
  48. "enable_tun_mode" => || feat::enable_tun_mode(),
  49. "disable_tun_mode" => || feat::disable_tun_mode(),
  50. _ => bail!("invalid function \"{func}\""),
  51. };
  52. self.manager.register(hotkey, f)?;
  53. log::info!(target: "app", "register hotkey {func} {key}");
  54. Ok(())
  55. }
  56. fn unregister(&mut self, key: &str) -> Result<()> {
  57. let hotkey = parse_hotkey(key.trim())?;
  58. self.manager.unregister(&hotkey)?;
  59. log::info!(target: "app", "unregister hotkey {key}");
  60. Ok(())
  61. }
  62. pub fn update(&mut self, new_hotkeys: Vec<String>) -> Result<()> {
  63. let current = self.current.to_owned();
  64. let old_map = Self::get_map_from_vec(&current);
  65. let new_map = Self::get_map_from_vec(&new_hotkeys);
  66. for diff in Self::get_diff(old_map, new_map).iter() {
  67. match diff {
  68. Diff::Del(key) => {
  69. let _ = self.unregister(key);
  70. }
  71. Diff::Mod(key, func) => {
  72. let _ = self.unregister(key);
  73. log_if_err!(self.register(func, key));
  74. }
  75. Diff::Add(key, func) => {
  76. log_if_err!(self.register(func, key));
  77. }
  78. }
  79. }
  80. self.current = new_hotkeys;
  81. Ok(())
  82. }
  83. fn get_map_from_vec<'a>(hotkeys: &'a Vec<String>) -> HashMap<&'a str, &'a str> {
  84. let mut map = HashMap::new();
  85. hotkeys.iter().for_each(|hotkey| {
  86. let mut iter = hotkey.split(',');
  87. let func = iter.next();
  88. let key = iter.next();
  89. if func.is_some() && key.is_some() {
  90. let func = func.unwrap().trim();
  91. let key = key.unwrap().trim();
  92. map.insert(key, func);
  93. }
  94. });
  95. map
  96. }
  97. fn get_diff<'a>(
  98. old_map: HashMap<&'a str, &'a str>,
  99. new_map: HashMap<&'a str, &'a str>,
  100. ) -> Vec<Diff<'a>> {
  101. let mut list = vec![];
  102. old_map
  103. .iter()
  104. .for_each(|(key, func)| match new_map.get(key) {
  105. Some(new_func) => {
  106. if new_func != func {
  107. list.push(Diff::Mod(key, new_func));
  108. }
  109. }
  110. None => list.push(Diff::Del(key)),
  111. });
  112. new_map.iter().for_each(|(key, func)| {
  113. if old_map.get(key).is_none() {
  114. list.push(Diff::Add(key, func));
  115. }
  116. });
  117. list
  118. }
  119. }
  120. impl Drop for Hotkey {
  121. fn drop(&mut self) {
  122. let _ = self.manager.unregister_all();
  123. }
  124. }
  125. enum Diff<'a> {
  126. Del(&'a str), // key
  127. Add(&'a str, &'a str), // key, func
  128. Mod(&'a str, &'a str), // key, func
  129. }