From db902ab4259c295b984102a978c4eba7eb3b2e44 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Sun, 8 Sep 2019 13:37:58 +0200 Subject: [PATCH] Improve Windows notification --- native/libwinbridge/bridge.cpp | 38 ++++++++++++++++++++-------------- native/libwinbridge/bridge.h | 7 ++++++- src/bridge/windows.rs | 3 ++- src/engine.rs | 29 +++++++++++++++++++++----- src/main.rs | 7 +++---- src/matcher/mod.rs | 1 + src/matcher/scrolling.rs | 2 +- src/ui/windows.rs | 23 +++++++++++--------- 8 files changed, 73 insertions(+), 37 deletions(-) diff --git a/native/libwinbridge/bridge.cpp b/native/libwinbridge/bridge.cpp index 0f6bf53..f459755 100644 --- a/native/libwinbridge/bridge.cpp +++ b/native/libwinbridge/bridge.cpp @@ -331,12 +331,7 @@ LRESULT CALLBACK notification_worker_procedure(HWND window, unsigned int msg, WP } } -int32_t show_notification(wchar_t * message, wchar_t * icon_path) { - if (nw != NULL) { - SetWindowText(hwnd_st_u, L" "); - SetWindowText(hwnd_st_u, message); - } - +int32_t initialize_notification(wchar_t * icon_path) { g_espanso_icon = (HBITMAP)LoadImage(NULL, icon_path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); @@ -381,12 +376,12 @@ int32_t show_notification(wchar_t * message, wchar_t * icon_path) { y = 40; h = 30; x = 100; w = 180; hwnd_st_u = CreateWindowEx(0, L"static", L"ST_U", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | SS_CENTER, - x, y, w, h, - nw, (HMENU)(501), - (HINSTANCE)GetWindowLong(nw, GWLP_HINSTANCE), NULL); + WS_CHILD | WS_VISIBLE | WS_TABSTOP | SS_CENTER, + x, y, w, h, + nw, (HMENU)(501), + (HINSTANCE)GetWindowLong(nw, GWLP_HINSTANCE), NULL); - SetWindowText(hwnd_st_u, message); + SetWindowText(hwnd_st_u, L"Loading..."); int posX = GetSystemMetrics(SM_CXSCREEN) - 350; int posY = GetSystemMetrics(SM_CYSCREEN) - 200; @@ -394,7 +389,7 @@ int32_t show_notification(wchar_t * message, wchar_t * icon_path) { SetWindowPos(nw, HWND_TOP, posX, posY, 0, 0, SWP_NOSIZE); // Hide the window - ShowWindow(nw, SW_SHOW); + ShowWindow(nw, SW_HIDE); // Enter the Event loop MSG msg; @@ -403,13 +398,26 @@ int32_t show_notification(wchar_t * message, wchar_t * icon_path) { } else { // Something went wrong, error. - return -1; + return GetLastError(); } return 1; } +int32_t show_notification(wchar_t * message) { + if (nw != NULL) { + SetWindowText(hwnd_st_u, L" "); + SetWindowText(hwnd_st_u, message); + + // Show the window + ShowWindow(nw, SW_SHOW); + return 1; + } + + return -1; +} + void close_notification() { - SendMessage(nw, WM_CLOSE, 0, 0); - nw = NULL; + // Hide the window + ShowWindow(nw, SW_HIDE); } \ No newline at end of file diff --git a/native/libwinbridge/bridge.h b/native/libwinbridge/bridge.h index d7bfd6e..0676032 100644 --- a/native/libwinbridge/bridge.h +++ b/native/libwinbridge/bridge.h @@ -56,10 +56,15 @@ extern "C" int32_t get_active_window_executable(wchar_t * buffer, int32_t size); // UI +/* + * Initialize the notification window. + */ +extern "C" int32_t initialize_notification(wchar_t * icon_path); + /* * Show a window containing the notification. */ -extern "C" int32_t show_notification(wchar_t * message, wchar_t * icon_path); +extern "C" int32_t show_notification(wchar_t * message); /* * Close the notification if present diff --git a/src/bridge/windows.rs b/src/bridge/windows.rs index 50f114b..8814e96 100644 --- a/src/bridge/windows.rs +++ b/src/bridge/windows.rs @@ -8,7 +8,8 @@ extern { pub fn get_active_window_executable(buffer: *mut u16, size: i32) -> i32; // UI - pub fn show_notification(message: *const u16, icon_path: *const u16) -> i32; + pub fn initialize_notification(icon_path: *const u16) -> i32; + pub fn show_notification(message: *const u16) -> i32; pub fn close_notification(); // KEYBOARD diff --git a/src/engine.rs b/src/engine.rs index 82ebfe4..6f59732 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -3,20 +3,27 @@ use crate::keyboard::KeyboardSender; use crate::config::ConfigManager; use crate::config::BackendType; use crate::clipboard::ClipboardManager; +use log::{info}; +use crate::ui::UIManager; -pub struct Engine<'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager> { +pub struct Engine<'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager, + U: UIManager> { sender: S, clipboard_manager: &'a C, config_manager: &'a M, + ui_manager: &'a U, } -impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager> Engine<'a, S, C, M> { - pub fn new<'b>(sender: S, clipboard_manager: &'b C, config_manager: &'b M) -> Engine<'b, S, C, M> { - Engine{sender, clipboard_manager, config_manager } +impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager, U: UIManager> + Engine<'a, S, C, M, U> { + pub fn new<'b>(sender: S, clipboard_manager: &'b C, config_manager: &'b M, ui_manager: &'b U) -> Engine<'b, S, C, M, U> { + Engine{sender, clipboard_manager, config_manager, ui_manager } } } -impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager> MatchReceiver for Engine<'a, S, C, M>{ +impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager, U: UIManager> + MatchReceiver for Engine<'a, S, C, M, U>{ + fn on_match(&self, m: &Match) { let config = self.config_manager.default_config(); @@ -48,4 +55,16 @@ impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager> MatchReceive }, } } + + fn on_toggle(&self, status: bool) { + let message = if status { + "espanso enabled" + }else{ + "espanso disabled" + }; + + info!("Toggled: {}", message); + + self.ui_manager.notify(message); + } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 21e31a6..248bab1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -95,9 +95,6 @@ fn espanso_background(rxc: Receiver, config_set: ConfigSet) { let config_manager = RuntimeConfigManager::new(config_set, system_manager); let ui_manager = ui::get_uimanager(); - ui_manager.notify("Hello guys"); - thread::sleep(time::Duration::from_millis(600)); - ui_manager.notify("There"); let clipboard_manager = clipboard::get_manager(); @@ -105,7 +102,9 @@ fn espanso_background(rxc: Receiver, config_set: ConfigSet) { let engine = Engine::new(sender, &clipboard_manager, - &config_manager); + &config_manager, + &ui_manager + ); let matcher = ScrollingMatcher::new(&config_manager, engine); matcher.watch(rxc); diff --git a/src/matcher/mod.rs b/src/matcher/mod.rs index 46b9236..55a1c04 100644 --- a/src/matcher/mod.rs +++ b/src/matcher/mod.rs @@ -12,6 +12,7 @@ pub struct Match { pub trait MatchReceiver { fn on_match(&self, m: &Match); + fn on_toggle(&self, status: bool); } pub trait Matcher { diff --git a/src/matcher/scrolling.rs b/src/matcher/scrolling.rs index 7b630ae..2dbd6ea 100644 --- a/src/matcher/scrolling.rs +++ b/src/matcher/scrolling.rs @@ -86,7 +86,7 @@ impl <'a, R: MatchReceiver, M: ConfigManager> super::Matcher for ScrollingMatche self.current_set_queue.borrow_mut().clear(); } - println!("Enabled {}", *is_enabled); + self.receiver.on_toggle(*is_enabled); } } diff --git a/src/ui/windows.rs b/src/ui/windows.rs index c03a188..520c9ed 100644 --- a/src/ui/windows.rs +++ b/src/ui/windows.rs @@ -1,5 +1,5 @@ use std::process::Command; -use crate::bridge::windows::{show_notification, close_notification}; +use crate::bridge::windows::{show_notification, close_notification, initialize_notification}; use widestring::U16CString; use std::{fs, thread, time}; use log::{info, debug}; @@ -41,15 +41,10 @@ impl super::UIManager for WindowsUIManager { }); // Create and show a window notification - let message = message.to_owned(); - let icon_file = self.icon_file.clone(); - thread::spawn( move || { - unsafe { - let message = U16CString::from_str(message).unwrap(); - let icon_file = U16CString::from_str(&icon_file).unwrap(); - show_notification(message.as_ptr(), icon_file.as_ptr()); - } - }); + unsafe { + let message = U16CString::from_str(message).unwrap(); + show_notification(message.as_ptr()); + } } } @@ -70,6 +65,14 @@ impl WindowsUIManager { info!("Extracted cached icon to: {}", icon_file); let id = Arc::new(Mutex::new(0)); + let icon_file_c = U16CString::from_str(&icon_file).unwrap(); + + thread::spawn(move || { + unsafe { + initialize_notification(icon_file_c.as_ptr()); + } + }); + WindowsUIManager { icon_file, id