Make tray icon red on Windows when disabled. Fix #293
This commit is contained in:
parent
411078a503
commit
b9fad30878
|
@ -62,6 +62,7 @@ HWND nw = NULL;
|
||||||
HWND hwnd_st_u = NULL;
|
HWND hwnd_st_u = NULL;
|
||||||
HBITMAP g_espanso_bmp = NULL;
|
HBITMAP g_espanso_bmp = NULL;
|
||||||
HICON g_espanso_ico = NULL;
|
HICON g_espanso_ico = NULL;
|
||||||
|
HICON g_espanso_red_ico = NULL;
|
||||||
NOTIFYICONDATA nid = {};
|
NOTIFYICONDATA nid = {};
|
||||||
|
|
||||||
UINT WM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated");
|
UINT WM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated");
|
||||||
|
@ -309,13 +310,14 @@ LRESULT CALLBACK window_procedure(HWND window, unsigned int msg, WPARAM wp, LPAR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t initialize(void * self, wchar_t * ico_path, wchar_t * bmp_path, int32_t _show_icon) {
|
int32_t initialize(void * self, wchar_t * ico_path, wchar_t * red_ico_path, wchar_t * bmp_path, int32_t _show_icon) {
|
||||||
manager_instance = self;
|
manager_instance = self;
|
||||||
show_icon = _show_icon;
|
show_icon = _show_icon;
|
||||||
|
|
||||||
// Load the images
|
// Load the images
|
||||||
g_espanso_bmp = (HBITMAP)LoadImage(NULL, bmp_path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
g_espanso_bmp = (HBITMAP)LoadImage(NULL, bmp_path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
||||||
g_espanso_ico = (HICON)LoadImage(NULL, ico_path, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_SHARED | LR_DEFAULTSIZE | LR_LOADFROMFILE);
|
g_espanso_ico = (HICON)LoadImage(NULL, ico_path, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_SHARED | LR_DEFAULTSIZE | LR_LOADFROMFILE);
|
||||||
|
g_espanso_red_ico = (HICON)LoadImage(NULL, red_ico_path, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_SHARED | LR_DEFAULTSIZE | LR_LOADFROMFILE);
|
||||||
|
|
||||||
// Make the notification capable of handling different screen definitions
|
// Make the notification capable of handling different screen definitions
|
||||||
SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
|
SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
|
||||||
|
@ -472,6 +474,19 @@ void eventloop() {
|
||||||
// Something went wrong, this should have been an infinite loop.
|
// Something went wrong, this should have been an infinite loop.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update_tray_icon(int32_t enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
nid.hIcon = g_espanso_ico;
|
||||||
|
}else{
|
||||||
|
nid.hIcon = g_espanso_red_ico;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the icon
|
||||||
|
if (show_icon) {
|
||||||
|
Shell_NotifyIcon(NIM_MODIFY, &nid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Type the given string simulating keyboard presses.
|
* Type the given string simulating keyboard presses.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -33,7 +33,7 @@ extern void * manager_instance;
|
||||||
* Initialize the Windows parameters
|
* Initialize the Windows parameters
|
||||||
* return: 1 if OK, -1 otherwise.
|
* return: 1 if OK, -1 otherwise.
|
||||||
*/
|
*/
|
||||||
extern "C" int32_t initialize(void * self, wchar_t * ico_path, wchar_t * bmp_path, int32_t show_icon);
|
extern "C" int32_t initialize(void * self, wchar_t * ico_path, wchar_t * red_ico_path, wchar_t * bmp_path, int32_t show_icon);
|
||||||
|
|
||||||
#define LEFT_VARIANT 1
|
#define LEFT_VARIANT 1
|
||||||
#define RIGHT_VARIANT 2
|
#define RIGHT_VARIANT 2
|
||||||
|
@ -152,6 +152,11 @@ extern "C" int32_t show_notification(wchar_t * message);
|
||||||
*/
|
*/
|
||||||
extern "C" void close_notification();
|
extern "C" void close_notification();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update the tray icon status
|
||||||
|
*/
|
||||||
|
extern "C" void update_tray_icon(int32_t enabled);
|
||||||
|
|
||||||
// CLIPBOARD
|
// CLIPBOARD
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -33,6 +33,7 @@ extern "C" {
|
||||||
pub fn initialize(
|
pub fn initialize(
|
||||||
s: *const c_void,
|
s: *const c_void,
|
||||||
ico_path: *const u16,
|
ico_path: *const u16,
|
||||||
|
red_ico_path: *const u16,
|
||||||
bmp_path: *const u16,
|
bmp_path: *const u16,
|
||||||
show_icon: i32,
|
show_icon: i32,
|
||||||
) -> i32;
|
) -> i32;
|
||||||
|
@ -48,6 +49,7 @@ extern "C" {
|
||||||
pub fn register_icon_click_callback(cb: extern "C" fn(_self: *mut c_void));
|
pub fn register_icon_click_callback(cb: extern "C" fn(_self: *mut c_void));
|
||||||
pub fn register_context_menu_click_callback(cb: extern "C" fn(_self: *mut c_void, id: i32));
|
pub fn register_context_menu_click_callback(cb: extern "C" fn(_self: *mut c_void, id: i32));
|
||||||
pub fn cleanup_ui();
|
pub fn cleanup_ui();
|
||||||
|
pub fn update_tray_icon(enabled: i32);
|
||||||
|
|
||||||
// CLIPBOARD
|
// CLIPBOARD
|
||||||
pub fn get_clipboard(buffer: *mut u16, size: i32) -> i32;
|
pub fn get_clipboard(buffer: *mut u16, size: i32) -> i32;
|
||||||
|
|
|
@ -48,6 +48,11 @@ pub fn new(
|
||||||
macos::MacContext::new(config, send_channel, is_injecting)
|
macos::MacContext::new(config, send_channel, is_injecting)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
pub fn update_icon(enabled: bool) {
|
||||||
|
// TODO: add update icon on macOS
|
||||||
|
}
|
||||||
|
|
||||||
// LINUX IMPLEMENTATION
|
// LINUX IMPLEMENTATION
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
@ -58,6 +63,11 @@ pub fn new(
|
||||||
linux::LinuxContext::new(config, send_channel, is_injecting)
|
linux::LinuxContext::new(config, send_channel, is_injecting)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub fn update_icon(enabled: bool) {
|
||||||
|
// No icon on Linux
|
||||||
|
}
|
||||||
|
|
||||||
// WINDOWS IMPLEMENTATION
|
// WINDOWS IMPLEMENTATION
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
@ -68,6 +78,11 @@ pub fn new(
|
||||||
windows::WindowsContext::new(config, send_channel, is_injecting)
|
windows::WindowsContext::new(config, send_channel, is_injecting)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn update_icon(enabled: bool) {
|
||||||
|
windows::update_icon(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
// espanso directories
|
// espanso directories
|
||||||
|
|
||||||
static WARING_INIT: Once = Once::new();
|
static WARING_INIT: Once = Once::new();
|
||||||
|
|
|
@ -32,6 +32,7 @@ use widestring::{U16CStr, U16CString};
|
||||||
|
|
||||||
const BMP_BINARY: &[u8] = include_bytes!("../res/win/espanso.bmp");
|
const BMP_BINARY: &[u8] = include_bytes!("../res/win/espanso.bmp");
|
||||||
const ICO_BINARY: &[u8] = include_bytes!("../res/win/espanso.ico");
|
const ICO_BINARY: &[u8] = include_bytes!("../res/win/espanso.ico");
|
||||||
|
const RED_ICO_BINARY: &[u8] = include_bytes!("../res/win/espansored.ico");
|
||||||
|
|
||||||
pub struct WindowsContext {
|
pub struct WindowsContext {
|
||||||
send_channel: Sender<Event>,
|
send_channel: Sender<Event>,
|
||||||
|
@ -77,8 +78,22 @@ impl WindowsContext {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let espanso_red_ico_image = espanso_dir.join("espansored.ico");
|
||||||
|
if espanso_red_ico_image.exists() {
|
||||||
|
info!("red ICO already initialized, skipping.");
|
||||||
|
} else {
|
||||||
|
fs::write(&espanso_red_ico_image, RED_ICO_BINARY)
|
||||||
|
.expect("Unable to write windows ico file");
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"Extracted 'red ico' icon to: {}",
|
||||||
|
espanso_red_ico_image.to_str().unwrap_or("error")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let bmp_icon = espanso_bmp_image.to_str().unwrap_or_default();
|
let bmp_icon = espanso_bmp_image.to_str().unwrap_or_default();
|
||||||
let ico_icon = espanso_ico_image.to_str().unwrap_or_default();
|
let ico_icon = espanso_ico_image.to_str().unwrap_or_default();
|
||||||
|
let red_ico_icon = espanso_red_ico_image.to_str().unwrap_or_default();
|
||||||
|
|
||||||
let send_channel = send_channel;
|
let send_channel = send_channel;
|
||||||
|
|
||||||
|
@ -96,6 +111,7 @@ impl WindowsContext {
|
||||||
register_context_menu_click_callback(context_menu_click_callback);
|
register_context_menu_click_callback(context_menu_click_callback);
|
||||||
|
|
||||||
let ico_file_c = U16CString::from_str(ico_icon).unwrap();
|
let ico_file_c = U16CString::from_str(ico_icon).unwrap();
|
||||||
|
let red_ico_file_c = U16CString::from_str(red_ico_icon).unwrap();
|
||||||
let bmp_file_c = U16CString::from_str(bmp_icon).unwrap();
|
let bmp_file_c = U16CString::from_str(bmp_icon).unwrap();
|
||||||
|
|
||||||
let show_icon = if config.show_icon { 1 } else { 0 };
|
let show_icon = if config.show_icon { 1 } else { 0 };
|
||||||
|
@ -104,6 +120,7 @@ impl WindowsContext {
|
||||||
let res = initialize(
|
let res = initialize(
|
||||||
context_ptr,
|
context_ptr,
|
||||||
ico_file_c.as_ptr(),
|
ico_file_c.as_ptr(),
|
||||||
|
red_ico_file_c.as_ptr(),
|
||||||
bmp_file_c.as_ptr(),
|
bmp_file_c.as_ptr(),
|
||||||
show_icon,
|
show_icon,
|
||||||
);
|
);
|
||||||
|
@ -126,6 +143,12 @@ impl super::Context for WindowsContext {
|
||||||
|
|
||||||
// Native bridge code
|
// Native bridge code
|
||||||
|
|
||||||
|
pub fn update_icon(enabled: bool) {
|
||||||
|
unsafe {
|
||||||
|
crate::bridge::windows::update_tray_icon(if enabled { 1 } else { 0 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" fn keypress_callback(
|
extern "C" fn keypress_callback(
|
||||||
_self: *mut c_void,
|
_self: *mut c_void,
|
||||||
raw_buffer: *const u16,
|
raw_buffer: *const u16,
|
||||||
|
|
|
@ -377,6 +377,9 @@ impl<
|
||||||
if config.show_notifications {
|
if config.show_notifications {
|
||||||
self.ui_manager.notify(message);
|
self.ui_manager.notify(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the icon on supported OSes.
|
||||||
|
crate::context::update_icon(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_passive(&self) {
|
fn on_passive(&self) {
|
||||||
|
|
BIN
src/res/win/espansored.ico
Normal file
BIN
src/res/win/espansored.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
Loading…
Reference in New Issue
Block a user