Skip to content

Commit

Permalink
feat: implement set_menu for system tray (#106)
Browse files Browse the repository at this point in the history
Co-authored-by: amrbashir <48618675+amrbashir@users.noreply.github.com>
Co-authored-by: David Lemarier <david@lemarier.ca>
  • Loading branch information
3 people committed Jul 14, 2021
1 parent e7cdb95 commit 578dd23
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 105 deletions.
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

0 comments on commit 578dd23

Please sign in to comment.