Skip to content

Commit e4f6fb8

Browse files
authored
fix: toggle extension should register/unregister hotkey (#691)
1 parent ee182b2 commit e4f6fb8

9 files changed

Lines changed: 502 additions & 357 deletions

File tree

docs/content.en/docs/release-notes/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Information about release notes of Coco Server is provided here.
1616
### 🐛 Bug fix
1717

1818
- fix: quick ai state synchronous #693
19+
- fix: toggle extension should register/unregister hotkey #691
1920

2021
### ✈️ Improvements
2122

src-tauri/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ function_name = "0.3.0"
100100
regex = "1.11.1"
101101
borrowme = "0.0.15"
102102
tauri-plugin-opener = "2"
103+
async-recursion = "1.1.1"
103104

104105
[target."cfg(target_os = \"macos\")".dependencies]
105106
tauri-nspanel = { git = "https://github.com/ahkohd/tauri-nspanel", branch = "v2" }

src-tauri/src/extension/built_in/application/with_feature.rs

Lines changed: 76 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,9 @@ impl Task for IndexNewApplicationsTask {
428428
pub struct ApplicationSearchSource;
429429

430430
impl ApplicationSearchSource {
431-
pub async fn init<R: Runtime>(app_handle: AppHandle<R>) -> Result<(), String> {
431+
pub async fn prepare_index_and_store<R: Runtime>(
432+
app_handle: AppHandle<R>,
433+
) -> Result<(), String> {
432434
let (tx, rx) = tokio::sync::oneshot::channel();
433435
let index_applications_task = IndexAllApplicationsTask {
434436
tauri_app_handle: app_handle.clone(),
@@ -472,8 +474,6 @@ impl ApplicationSearchSource {
472474
.set(TAURI_STORE_KEY_SEARCH_PATH, default_search_path);
473475
}
474476

475-
register_app_hotkey_upon_start(app_handle.clone())?;
476-
477477
Ok(())
478478
}
479479
}
@@ -638,28 +638,69 @@ fn app_hotkey_handler<R: Runtime>(
638638
}
639639
}
640640

641-
fn register_app_hotkey_upon_start<R: Runtime>(
642-
tauri_app_handle: AppHandle<R>,
643-
) -> Result<(), String> {
641+
/// For all the applications, if it is enabled & has hotkey set, then set it up.
642+
pub(crate) fn set_apps_hotkey<R: Runtime>(tauri_app_handle: &AppHandle<R>) -> Result<(), String> {
644643
let app_hotkey_store = tauri_app_handle
645644
.store(TAURI_STORE_APP_HOTKEY)
646645
.unwrap_or_else(|_| panic!("store [{}] not found/loaded", TAURI_STORE_APP_HOTKEY));
647646

647+
let disabled_app_list = get_disabled_app_list(&tauri_app_handle);
648+
648649
for (app_path, hotkey) in app_hotkey_store.entries() {
650+
if disabled_app_list.contains(&app_path) {
651+
continue;
652+
}
653+
654+
let hotkey = match hotkey {
655+
Json::String(str) => str,
656+
_ => unreachable!("hotkey should be stored in a string"),
657+
};
658+
659+
set_app_hotkey(&tauri_app_handle, &app_path, &hotkey)?;
660+
}
661+
662+
Ok(())
663+
}
664+
665+
/// For all the applications, if it is enabled & has hotkey set, then unset it.
666+
pub(crate) fn unset_apps_hotkey<R: Runtime>(tauri_app_handle: &AppHandle<R>) -> Result<(), String> {
667+
let app_hotkey_store = tauri_app_handle
668+
.store(TAURI_STORE_APP_HOTKEY)
669+
.unwrap_or_else(|_| panic!("store [{}] not found/loaded", TAURI_STORE_APP_HOTKEY));
670+
671+
let disabled_app_list = get_disabled_app_list(&tauri_app_handle);
672+
673+
for (app_path, hotkey) in app_hotkey_store.entries() {
674+
if disabled_app_list.contains(&app_path) {
675+
continue;
676+
}
677+
649678
let hotkey = match hotkey {
650679
Json::String(str) => str,
651680
_ => unreachable!("hotkey should be stored in a string"),
652681
};
653682

654683
tauri_app_handle
655684
.global_shortcut()
656-
.on_shortcut(hotkey.as_str(), app_hotkey_handler(app_path))
685+
.unregister(hotkey.as_str())
657686
.map_err(|e| e.to_string())?;
658687
}
659688

660689
Ok(())
661690
}
662691

692+
/// Set the hotkey but won't persist this settings change.
693+
pub(crate) fn set_app_hotkey<R: Runtime>(
694+
tauri_app_handle: &AppHandle<R>,
695+
app_path: &str,
696+
hotkey: &str,
697+
) -> Result<(), String> {
698+
tauri_app_handle
699+
.global_shortcut()
700+
.on_shortcut(hotkey, app_hotkey_handler(app_path.into()))
701+
.map_err(|e| e.to_string())
702+
}
703+
663704
pub fn register_app_hotkey<R: Runtime>(
664705
tauri_app_handle: &AppHandle<R>,
665706
app_path: &str,
@@ -671,13 +712,9 @@ pub fn register_app_hotkey<R: Runtime>(
671712
let app_hotkey_store = tauri_app_handle
672713
.store(TAURI_STORE_APP_HOTKEY)
673714
.unwrap_or_else(|_| panic!("store [{}] not found/loaded", TAURI_STORE_APP_HOTKEY));
674-
675715
app_hotkey_store.set(app_path, hotkey);
676716

677-
tauri_app_handle
678-
.global_shortcut()
679-
.on_shortcut(hotkey, app_hotkey_handler(app_path.into()))
680-
.map_err(|e| e.to_string())?;
717+
set_app_hotkey(tauri_app_handle, app_path, hotkey)?;
681718

682719
Ok(())
683720
}
@@ -789,6 +826,21 @@ pub fn disable_app_search<R: Runtime>(
789826

790827
store.set(TAURI_STORE_KEY_DISABLED_APP_LIST, disabled_app_list);
791828

829+
let app_hotkey_store = tauri_app_handle
830+
.store(TAURI_STORE_APP_HOTKEY)
831+
.unwrap_or_else(|_| panic!("store [{}] not found/loaded", TAURI_STORE_APP_HOTKEY));
832+
let opt_hokey = app_hotkey_store.get(app_path).map(|json| match json {
833+
Json::String(s) => s,
834+
_ => panic!("hotkey should be stored in a string"),
835+
});
836+
837+
if let Some(hotkey) = opt_hokey {
838+
tauri_app_handle
839+
.global_shortcut()
840+
.unregister(hotkey.as_str())
841+
.map_err(|e| e.to_string())?;
842+
}
843+
792844
Ok(())
793845
}
794846

@@ -815,6 +867,18 @@ pub fn enable_app_search<R: Runtime>(
815867
disabled_app_list.remove(index);
816868
store.set(TAURI_STORE_KEY_DISABLED_APP_LIST, disabled_app_list);
817869

870+
let app_hotkey_store = tauri_app_handle
871+
.store(TAURI_STORE_APP_HOTKEY)
872+
.unwrap_or_else(|_| panic!("store [{}] not found/loaded", TAURI_STORE_APP_HOTKEY));
873+
let opt_hokey = app_hotkey_store.get(app_path).map(|json| match json {
874+
Json::String(s) => s,
875+
_ => panic!("hotkey should be stored in a string"),
876+
});
877+
878+
if let Some(hotkey) = opt_hokey {
879+
set_app_hotkey(tauri_app_handle, app_path, &hotkey)?;
880+
}
881+
818882
Ok(())
819883
}
820884
None => Err(format!(

src-tauri/src/extension/built_in/application/without_feature.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub(crate) const QUERYSOURCE_ID_DATASOURCE_ID_DATASOURCE_NAME: &str = "Applicati
1212
pub struct ApplicationSearchSource;
1313

1414
impl ApplicationSearchSource {
15-
pub async fn init<R: Runtime>(_app_handle: AppHandle<R>) -> Result<(), String> {
15+
pub async fn prepare_index_and_store<R: Runtime>(_app_handle: AppHandle<R>) -> Result<(), String> {
1616
Ok(())
1717
}
1818
}
@@ -117,3 +117,14 @@ pub async fn get_app_metadata<R: Runtime>(
117117
) -> Result<AppMetadata, String> {
118118
unreachable!("app list should be empty, there is no way this can be invoked")
119119
}
120+
121+
122+
pub(crate) fn set_apps_hotkey<R: Runtime>(_tauri_app_handle: &AppHandle<R>) -> Result<(), String> {
123+
// no-op
124+
Ok(())
125+
}
126+
127+
pub(crate) fn unset_apps_hotkey<R: Runtime>(_tauri_app_handle: &AppHandle<R>) -> Result<(), String> {
128+
// no-op
129+
Ok(())
130+
}

src-tauri/src/extension/built_in/mod.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ pub mod file_system;
77
pub mod pizza_engine_runtime;
88
pub mod quick_ai_access;
99

10-
use anyhow::Context;
1110
use super::Extension;
11+
use crate::extension::built_in::application::{set_apps_hotkey, unset_apps_hotkey};
1212
use crate::extension::{
13-
alter_extension_json_file, ExtensionBundleIdBorrowed,
14-
PLUGIN_JSON_FILE_NAME,
13+
alter_extension_json_file, ExtensionBundleIdBorrowed, PLUGIN_JSON_FILE_NAME,
1514
};
1615
use crate::{SearchSourceRegistry, GLOBAL_TAURI_APP_HANDLE};
16+
use anyhow::Context;
1717
use std::path::{Path, PathBuf};
1818
use std::sync::LazyLock;
19-
use tauri::Manager;
19+
use tauri::{AppHandle, Manager, Runtime};
2020

2121
pub(crate) static BUILT_IN_EXTENSION_DIRECTORY: LazyLock<PathBuf> = LazyLock::new(|| {
2222
let mut resource_dir = GLOBAL_TAURI_APP_HANDLE
@@ -176,16 +176,18 @@ pub(crate) async fn list_built_in_extensions() -> Result<Vec<Extension>, String>
176176
Ok(built_in_extensions)
177177
}
178178

179-
pub(super) async fn init_built_in_extension(
179+
pub(super) async fn init_built_in_extension<R: Runtime>(
180+
tauri_app_handle: &AppHandle<R>,
180181
extension: &Extension,
181182
search_source_registry: &SearchSourceRegistry,
182-
) {
183+
) -> Result<(), String> {
183184
log::trace!("initializing built-in extensions");
184185

185186
if extension.id == application::QUERYSOURCE_ID_DATASOURCE_ID_DATASOURCE_NAME {
186187
search_source_registry
187188
.register_source(application::ApplicationSearchSource)
188189
.await;
190+
set_apps_hotkey(&tauri_app_handle)?;
189191
log::debug!("built-in extension [{}] initialized", extension.id);
190192
}
191193

@@ -196,6 +198,8 @@ pub(super) async fn init_built_in_extension(
196198
.await;
197199
log::debug!("built-in extension [{}] initialized", extension.id);
198200
}
201+
202+
Ok(())
199203
}
200204

201205
pub(crate) fn is_extension_built_in(bundle_id: &ExtensionBundleIdBorrowed<'_>) -> bool {
@@ -221,6 +225,8 @@ pub(crate) async fn enable_built_in_extension(
221225
search_source_registry_tauri_state
222226
.register_source(application::ApplicationSearchSource)
223227
.await;
228+
set_apps_hotkey(tauri_app_handle)?;
229+
224230
alter_extension_json_file(
225231
&BUILT_IN_EXTENSION_DIRECTORY.as_path(),
226232
bundle_id,
@@ -292,6 +298,8 @@ pub(crate) async fn disable_built_in_extension(
292298
search_source_registry_tauri_state
293299
.remove_source(bundle_id.extension_id)
294300
.await;
301+
unset_apps_hotkey(tauri_app_handle)?;
302+
295303
alter_extension_json_file(
296304
&BUILT_IN_EXTENSION_DIRECTORY.as_path(),
297305
bundle_id,

0 commit comments

Comments
 (0)