Skip to content

Commit a577202

Browse files
committed
Implement native hud notifications on Linux, enable by default
1 parent b008fcd commit a577202

File tree

7 files changed

+81
-5
lines changed

7 files changed

+81
-5
lines changed

Cargo.lock

Lines changed: 24 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dev_data/config/config.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@
66
#main_window_surface = "xdg_shell"
77
global_shortcuts_api = "legacy_x11_api"
88
#global_shortcuts_api = "none"
9+
10+
[linux]
11+
native_hud = true

rust/server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ url = "2.5"
4444
ureq = "2.10"
4545
dark-light = "1.1.1"
4646
schemars = "0.8"
47+
ashpd = "0.11"
4748

4849
[features]
4950
release = ["gauntlet-common/release", "gauntlet-plugin-runtime/release"]

rust/server/src/plugins/js.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use std::collections::HashMap;
22
use std::fs::File;
33
use std::sync::Arc;
4+
use std::time::Duration;
5+
use std::vec;
46

57
use anyhow::Context;
68
use anyhow::anyhow;
@@ -50,6 +52,7 @@ use serde::Serialize;
5052
use tokio::sync::Mutex;
5153

5254
use crate::model::IntermediateUiEvent;
55+
use crate::plugins::Settings;
5356
use crate::plugins::binary_data_gatherer::BinaryDataGatherer;
5457
use crate::plugins::clipboard::Clipboard;
5558
use crate::plugins::data_db_repository::DataDbRepository;
@@ -78,6 +81,7 @@ pub struct PluginRuntimeData {
7881
pub db_repository: DataDbRepository,
7982
pub search_index: SearchIndex,
8083
pub icon_cache: IconCache,
84+
pub settings: Settings,
8185
pub frontend_api: FrontendApiProxy,
8286
pub dirs: Dirs,
8387
pub clipboard: Clipboard,
@@ -159,6 +163,7 @@ pub async fn start_plugin_runtime(data: PluginRuntimeData, run_status_guard: Run
159163
data.search_index,
160164
data.clipboard,
161165
data.frontend_api,
166+
data.settings,
162167
data.uuid.clone(),
163168
data.id.clone(),
164169
data.name,
@@ -601,6 +606,7 @@ pub struct BackendForPluginRuntimeApiImpl {
601606
search_index: SearchIndex,
602607
clipboard: Clipboard,
603608
frontend_api: FrontendApiProxy,
609+
settings: Settings,
604610
#[allow(unused)]
605611
plugin_uuid: String,
606612
plugin_id: PluginId,
@@ -614,6 +620,7 @@ impl BackendForPluginRuntimeApiImpl {
614620
search_index: SearchIndex,
615621
clipboard: Clipboard,
616622
frontend_api: FrontendApiProxy,
623+
settings: Settings,
617624
plugin_uuid: String,
618625
plugin_id: PluginId,
619626
plugin_name: String,
@@ -624,6 +631,7 @@ impl BackendForPluginRuntimeApiImpl {
624631
search_index,
625632
clipboard,
626633
frontend_api,
634+
settings,
627635
plugin_uuid,
628636
plugin_id,
629637
plugin_name,
@@ -961,7 +969,16 @@ impl BackendForPluginRuntimeApi for BackendForPluginRuntimeApiImpl {
961969
}
962970

963971
async fn ui_show_hud(&self, display: String) -> RequestResult<()> {
964-
self.frontend_api.show_hud(display).await?;
972+
if cfg!(target_os = "linux") {
973+
if self.settings.config().linux_native_hud {
974+
#[cfg(target_os = "linux")]
975+
show_linux_native_hud(display).await?;
976+
} else {
977+
self.frontend_api.show_hud(display).await?;
978+
}
979+
} else {
980+
self.frontend_api.show_hud(display).await?;
981+
}
965982

966983
Ok(())
967984
}
@@ -1201,3 +1218,27 @@ fn any_preferences_missing_value(
12011218

12021219
false
12031220
}
1221+
1222+
#[cfg(target_os = "linux")]
1223+
async fn show_linux_native_hud(display: String) -> anyhow::Result<()> {
1224+
use ashpd::desktop::notification::DisplayHint;
1225+
use ashpd::desktop::notification::Notification;
1226+
use ashpd::desktop::notification::NotificationProxy;
1227+
use ashpd::desktop::notification::Priority;
1228+
1229+
let proxy = NotificationProxy::new().await?;
1230+
1231+
let notification_id = "sh.gauntlet.Hud";
1232+
let notification = Notification::new(&display)
1233+
.priority(Priority::Urgent)
1234+
.display_hint(vec![DisplayHint::Transient, DisplayHint::ShowAsNew]);
1235+
1236+
proxy.add_notification(notification_id, notification).await?;
1237+
1238+
tokio::spawn(async move {
1239+
tokio::time::sleep(Duration::from_secs(2)).await;
1240+
let _ = proxy.remove_notification(notification_id).await;
1241+
});
1242+
1243+
Ok(())
1244+
}

rust/server/src/plugins/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,7 @@ impl ApplicationManager {
919919
search_index: self.search_index.clone(),
920920
icon_cache: self.icon_cache.clone(),
921921
frontend_api: self.frontend_api.clone(),
922+
settings: self.settings.clone(),
922923
dirs: self.dirs.clone(),
923924
clipboard: self.clipboard.clone(),
924925
};

rust/server/src/plugins/settings/config.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use serde::Deserialize;
55
pub struct ApplicationConfig {
66
pub main_window: Option<ApplicationWindowConfig>,
77
pub wayland: Option<WaylandConfig>,
8+
pub linux: Option<LinuxConfig>,
89
}
910

1011
#[derive(Deserialize, Debug, Default)]
@@ -18,6 +19,11 @@ pub struct WaylandConfig {
1819
pub global_shortcuts_api: Option<WaylandGlobalShortcutConfig>,
1920
}
2021

22+
#[derive(Deserialize, Debug, Default)]
23+
pub struct LinuxConfig {
24+
pub native_hud: Option<bool>,
25+
}
26+
2127
#[derive(Deserialize, Debug)]
2228
pub enum WaylandMainWindowConfig {
2329
#[serde(rename = "prefer_wlr_layer_shell")] // default
@@ -40,4 +46,5 @@ pub struct EffectiveConfig {
4046
pub close_on_unfocus: bool,
4147
pub layer_shell: bool,
4248
pub wayland_use_legacy_x11_api: bool,
49+
pub linux_native_hud: bool,
4350
}

rust/server/src/plugins/settings/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,10 @@ impl Settings {
298298
fn effective_config(config: ApplicationConfig, layer_shell_supported: bool) -> EffectiveConfig {
299299
let window_config = config.main_window.unwrap_or_default();
300300
let wayland_config = config.wayland.unwrap_or_default();
301+
let linux_config = config.linux.unwrap_or_default();
301302

302303
let close_on_unfocus = window_config.close_on_unfocus.unwrap_or(true);
304+
let linux_native_hud = linux_config.native_hud.unwrap_or(true);
303305

304306
let main_window_surface = wayland_config
305307
.main_window_surface
@@ -324,5 +326,6 @@ fn effective_config(config: ApplicationConfig, layer_shell_supported: bool) -> E
324326
close_on_unfocus,
325327
layer_shell,
326328
wayland_use_legacy_x11_api,
329+
linux_native_hud,
327330
}
328331
}

0 commit comments

Comments
 (0)