Improve Windows notification

This commit is contained in:
Federico Terzi 2019-09-08 13:37:58 +02:00
parent 4e98e4801d
commit db902ab425
8 changed files with 73 additions and 37 deletions

View File

@ -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) { int32_t initialize_notification(wchar_t * icon_path) {
if (nw != NULL) {
SetWindowText(hwnd_st_u, L" ");
SetWindowText(hwnd_st_u, message);
}
g_espanso_icon = (HBITMAP)LoadImage(NULL, icon_path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); g_espanso_icon = (HBITMAP)LoadImage(NULL, icon_path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); 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; y = 40; h = 30;
x = 100; w = 180; x = 100; w = 180;
hwnd_st_u = CreateWindowEx(0, L"static", L"ST_U", hwnd_st_u = CreateWindowEx(0, L"static", L"ST_U",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | SS_CENTER, WS_CHILD | WS_VISIBLE | WS_TABSTOP | SS_CENTER,
x, y, w, h, x, y, w, h,
nw, (HMENU)(501), nw, (HMENU)(501),
(HINSTANCE)GetWindowLong(nw, GWLP_HINSTANCE), NULL); (HINSTANCE)GetWindowLong(nw, GWLP_HINSTANCE), NULL);
SetWindowText(hwnd_st_u, message); SetWindowText(hwnd_st_u, L"Loading...");
int posX = GetSystemMetrics(SM_CXSCREEN) - 350; int posX = GetSystemMetrics(SM_CXSCREEN) - 350;
int posY = GetSystemMetrics(SM_CYSCREEN) - 200; 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); SetWindowPos(nw, HWND_TOP, posX, posY, 0, 0, SWP_NOSIZE);
// Hide the window // Hide the window
ShowWindow(nw, SW_SHOW); ShowWindow(nw, SW_HIDE);
// Enter the Event loop // Enter the Event loop
MSG msg; MSG msg;
@ -403,13 +398,26 @@ int32_t show_notification(wchar_t * message, wchar_t * icon_path) {
} }
else { else {
// Something went wrong, error. // Something went wrong, error.
return -1; return GetLastError();
} }
return 1; return 1;
} }
void close_notification() { int32_t show_notification(wchar_t * message) {
SendMessage(nw, WM_CLOSE, 0, 0); if (nw != NULL) {
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() {
// Hide the window
ShowWindow(nw, SW_HIDE);
} }

View File

@ -56,10 +56,15 @@ extern "C" int32_t get_active_window_executable(wchar_t * buffer, int32_t size);
// UI // UI
/*
* Initialize the notification window.
*/
extern "C" int32_t initialize_notification(wchar_t * icon_path);
/* /*
* Show a window containing the notification. * 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 * Close the notification if present

View File

@ -8,7 +8,8 @@ extern {
pub fn get_active_window_executable(buffer: *mut u16, size: i32) -> i32; pub fn get_active_window_executable(buffer: *mut u16, size: i32) -> i32;
// UI // 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(); pub fn close_notification();
// KEYBOARD // KEYBOARD

View File

@ -3,20 +3,27 @@ use crate::keyboard::KeyboardSender;
use crate::config::ConfigManager; use crate::config::ConfigManager;
use crate::config::BackendType; use crate::config::BackendType;
use crate::clipboard::ClipboardManager; 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, sender: S,
clipboard_manager: &'a C, clipboard_manager: &'a C,
config_manager: &'a M, config_manager: &'a M,
ui_manager: &'a U,
} }
impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager> Engine<'a, S, C, M> { impl <'a, S: KeyboardSender, C: ClipboardManager, M: ConfigManager, U: UIManager>
pub fn new<'b>(sender: S, clipboard_manager: &'b C, config_manager: &'b M) -> Engine<'b, S, C, M> { Engine<'a, S, C, M, U> {
Engine{sender, clipboard_manager, config_manager } 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) { fn on_match(&self, m: &Match) {
let config = self.config_manager.default_config(); 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);
}
} }

View File

@ -95,9 +95,6 @@ fn espanso_background(rxc: Receiver<KeyEvent>, config_set: ConfigSet) {
let config_manager = RuntimeConfigManager::new(config_set, system_manager); let config_manager = RuntimeConfigManager::new(config_set, system_manager);
let ui_manager = ui::get_uimanager(); 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(); let clipboard_manager = clipboard::get_manager();
@ -105,7 +102,9 @@ fn espanso_background(rxc: Receiver<KeyEvent>, config_set: ConfigSet) {
let engine = Engine::new(sender, let engine = Engine::new(sender,
&clipboard_manager, &clipboard_manager,
&config_manager); &config_manager,
&ui_manager
);
let matcher = ScrollingMatcher::new(&config_manager, engine); let matcher = ScrollingMatcher::new(&config_manager, engine);
matcher.watch(rxc); matcher.watch(rxc);

View File

@ -12,6 +12,7 @@ pub struct Match {
pub trait MatchReceiver { pub trait MatchReceiver {
fn on_match(&self, m: &Match); fn on_match(&self, m: &Match);
fn on_toggle(&self, status: bool);
} }
pub trait Matcher { pub trait Matcher {

View File

@ -86,7 +86,7 @@ impl <'a, R: MatchReceiver, M: ConfigManager> super::Matcher for ScrollingMatche
self.current_set_queue.borrow_mut().clear(); self.current_set_queue.borrow_mut().clear();
} }
println!("Enabled {}", *is_enabled); self.receiver.on_toggle(*is_enabled);
} }
} }

View File

@ -1,5 +1,5 @@
use std::process::Command; 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 widestring::U16CString;
use std::{fs, thread, time}; use std::{fs, thread, time};
use log::{info, debug}; use log::{info, debug};
@ -41,15 +41,10 @@ impl super::UIManager for WindowsUIManager {
}); });
// Create and show a window notification // Create and show a window notification
let message = message.to_owned(); unsafe {
let icon_file = self.icon_file.clone(); let message = U16CString::from_str(message).unwrap();
thread::spawn( move || { show_notification(message.as_ptr());
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());
}
});
} }
} }
@ -70,6 +65,14 @@ impl WindowsUIManager {
info!("Extracted cached icon to: {}", icon_file); info!("Extracted cached icon to: {}", icon_file);
let id = Arc::new(Mutex::new(0)); 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 { WindowsUIManager {
icon_file, icon_file,
id id