Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement set_menu for system tray #106

Merged
merged 11 commits into from
Jul 14, 2021
5 changes: 5 additions & 0 deletions .changes/tray-set-menu.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tao": minor
---

`SystemTray` expose `set_menu` to update the system tray menu once created.
9 changes: 9 additions & 0 deletions examples/system_tray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ fn main() {
let mut focus_all_window =
tray_menu.add_item(MenuItemAttributes::new("Focus window").with_enabled(false));

let change_menu = tray_menu.add_item(MenuItemAttributes::new("Change menu"));

// inject submenu into tray_menu
tray_menu.add_submenu("Sub menu", true, submenu);

Expand Down Expand Up @@ -158,6 +160,13 @@ fn main() {
// tell our app to close at the end of the loop.
*control_flow = ControlFlow::Exit;
}

if menu_id == change_menu.clone().id() {
let mut tray_menu = Menu::new();
tray_menu.add_item(MenuItemAttributes::new("Quit"));
system_tray.set_menu(&tray_menu);
}

println!("Clicked on {:?}", menu_id);
}
_ => (),
Expand Down
43 changes: 27 additions & 16 deletions src/platform_impl/linux/system_tray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ use crate::{
error::OsError, event_loop::EventLoopWindowTarget, system_tray::SystemTray as RootSystemTray,
};

use glib::Sender;
use std::path::PathBuf;

use gtk::{AccelGroup, WidgetExt};
use libappindicator::{AppIndicator, AppIndicatorStatus};

use super::{menu::Menu, WindowId};
use super::{menu::Menu, window::WindowRequest, WindowId};

pub struct SystemTrayBuilder {
pub(crate) system_tray: SystemTray,
tray_menu: Option<Menu>,
app_indicator: AppIndicator,
}

impl SystemTrayBuilder {
Expand All @@ -25,11 +27,10 @@ impl SystemTrayBuilder {
&icon.to_string_lossy(),
&path.to_string_lossy(),
);

Self {
system_tray: SystemTray {
tray_menu,
app_indicator,
},
tray_menu,
app_indicator,
}
}

Expand All @@ -38,27 +39,27 @@ impl SystemTrayBuilder {
mut self,
window_target: &EventLoopWindowTarget<T>,
) -> Result<RootSystemTray, OsError> {
let tx_ = window_target.p.window_requests_tx.clone();
let sender = window_target.p.window_requests_tx.clone();

if let Some(tray_menu) = self.system_tray.tray_menu.clone() {
let menu = &mut tray_menu.into_gtkmenu(&tx_, &AccelGroup::new(), WindowId::dummy());
if let Some(tray_menu) = self.tray_menu.clone() {
let menu = &mut tray_menu.into_gtkmenu(&sender, &AccelGroup::new(), WindowId::dummy());

self.system_tray.app_indicator.set_menu(menu);
self.app_indicator.set_menu(menu);
menu.show_all();
}

self
.system_tray
.app_indicator
.set_status(AppIndicatorStatus::Active);
self.app_indicator.set_status(AppIndicatorStatus::Active);

Ok(RootSystemTray(self.system_tray))
Ok(RootSystemTray(SystemTray {
app_indicator: self.app_indicator,
sender,
}))
}
}

pub struct SystemTray {
tray_menu: Option<Menu>,
app_indicator: AppIndicator,
sender: Sender<(WindowId, WindowRequest)>,
}

impl SystemTray {
Expand All @@ -69,4 +70,14 @@ impl SystemTray {
.set_icon_theme_path(&path.to_string_lossy());
self.app_indicator.set_icon(&icon.to_string_lossy())
}

pub fn set_menu(&mut self, tray_menu: &Menu) {
let mut menu =
tray_menu
.clone()
.into_gtkmenu(&self.sender, &AccelGroup::new(), WindowId::dummy());

self.app_indicator.set_menu(&mut menu);
menu.show_all();
}
}
6 changes: 6 additions & 0 deletions src/platform_impl/macos/system_tray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ impl SystemTray {
self.create_button_with_icon();
}

pub fn set_menu(&mut self, tray_menu: &Menu) {
unsafe {
self.ns_status_bar.setMenu_(tray_menu.menu);
}
}

fn create_button_with_icon(&self) {
const ICON_WIDTH: f64 = 18.0;
const ICON_HEIGHT: f64 = 18.0;
Expand Down
28 changes: 18 additions & 10 deletions src/platform_impl/windows/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,10 @@ impl MenuItemAttributes {

#[derive(Debug, Clone)]
pub struct Menu {
hmenu: windef::HMENU,
pub(crate) hmenu: windef::HMENU,
accels: HashMap<u16, AccelWrapper>,
}

impl Drop for Menu {
fn drop(&mut self) {
unsafe {
winuser::DestroyMenu(self.hmenu);
}
}
}

unsafe impl Send for Menu {}
unsafe impl Sync for Menu {}

Expand All @@ -157,7 +149,7 @@ impl Menu {
}
}

pub fn new_popup_menu() -> Menu {
pub fn new_popup_menu() -> Self {
unsafe {
let hmenu = winuser::CreatePopupMenu();
Menu {
Expand Down Expand Up @@ -319,6 +311,22 @@ impl Menu {
}
}

/*
Disabled as menu's seems to be linked to the app
so they are dropped when the app closes.
see discussion here;

https://github.com/tauri-apps/tao/pull/106#issuecomment-880034210

impl Drop for Menu {
fn drop(&mut self) {
unsafe {
winuser::DestroyMenu(self.hmenu);
}
}
}
*/

pub fn initialize(
menu_builder: Menu,
window_handle: RawWindowHandle,
Expand Down
Loading