Skip to content

Commit

Permalink
Make tray icon red on Windows when disabled. Fix #293
Browse files Browse the repository at this point in the history
  • Loading branch information
federico-terzi committed Aug 15, 2020
1 parent 411078a commit b9fad30
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 2 deletions.
17 changes: 16 additions & 1 deletion native/libwinbridge/bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ HWND nw = NULL;
HWND hwnd_st_u = NULL;
HBITMAP g_espanso_bmp = NULL;
HICON g_espanso_ico = NULL;
HICON g_espanso_red_ico = NULL;
NOTIFYICONDATA nid = {};

UINT WM_TASKBARCREATED = RegisterWindowMessage(L"TaskbarCreated");
Expand Down Expand Up @@ -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;
show_icon = _show_icon;

// Load the images
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_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
SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
Expand Down Expand Up @@ -472,6 +474,19 @@ void eventloop() {
// 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.
*/
Expand Down
7 changes: 6 additions & 1 deletion native/libwinbridge/bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ extern void * manager_instance;
* Initialize the Windows parameters
* 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 RIGHT_VARIANT 2
Expand Down Expand Up @@ -152,6 +152,11 @@ extern "C" int32_t show_notification(wchar_t * message);
*/
extern "C" void close_notification();

/*
* Update the tray icon status
*/
extern "C" void update_tray_icon(int32_t enabled);

// CLIPBOARD

/*
Expand Down
2 changes: 2 additions & 0 deletions src/bridge/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ extern "C" {
pub fn initialize(
s: *const c_void,
ico_path: *const u16,
red_ico_path: *const u16,
bmp_path: *const u16,
show_icon: i32,
) -> i32;
Expand All @@ -48,6 +49,7 @@ extern "C" {
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 cleanup_ui();
pub fn update_tray_icon(enabled: i32);

// CLIPBOARD
pub fn get_clipboard(buffer: *mut u16, size: i32) -> i32;
Expand Down
15 changes: 15 additions & 0 deletions src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ pub fn new(
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
#[cfg(target_os = "linux")]
pub fn new(
Expand All @@ -58,6 +63,11 @@ pub fn new(
linux::LinuxContext::new(config, send_channel, is_injecting)
}

#[cfg(target_os = "linux")]
pub fn update_icon(enabled: bool) {
// No icon on Linux
}

// WINDOWS IMPLEMENTATION
#[cfg(target_os = "windows")]
pub fn new(
Expand All @@ -68,6 +78,11 @@ pub fn new(
windows::WindowsContext::new(config, send_channel, is_injecting)
}

#[cfg(target_os = "windows")]
pub fn update_icon(enabled: bool) {
windows::update_icon(enabled);
}

// espanso directories

static WARING_INIT: Once = Once::new();
Expand Down
23 changes: 23 additions & 0 deletions src/context/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use widestring::{U16CStr, U16CString};

const BMP_BINARY: &[u8] = include_bytes!("../res/win/espanso.bmp");
const ICO_BINARY: &[u8] = include_bytes!("../res/win/espanso.ico");
const RED_ICO_BINARY: &[u8] = include_bytes!("../res/win/espansored.ico");

pub struct WindowsContext {
send_channel: Sender<Event>,
Expand Down Expand Up @@ -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 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;

Expand All @@ -96,6 +111,7 @@ impl WindowsContext {
register_context_menu_click_callback(context_menu_click_callback);

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 show_icon = if config.show_icon { 1 } else { 0 };
Expand All @@ -104,6 +120,7 @@ impl WindowsContext {
let res = initialize(
context_ptr,
ico_file_c.as_ptr(),
red_ico_file_c.as_ptr(),
bmp_file_c.as_ptr(),
show_icon,
);
Expand All @@ -126,6 +143,12 @@ impl super::Context for WindowsContext {

// 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(
_self: *mut c_void,
raw_buffer: *const u16,
Expand Down
3 changes: 3 additions & 0 deletions src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,9 @@ impl<
if config.show_notifications {
self.ui_manager.notify(message);
}

// Update the icon on supported OSes.
crate::context::update_icon(status);
}

fn on_passive(&self) {
Expand Down
Binary file added src/res/win/espansored.ico
Binary file not shown.

0 comments on commit b9fad30

Please sign in to comment.