feat: remove menu feature flag (#2415)

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
Ngo Iok Ui (Wu Yu Wei)
2021-08-13 21:23:32 +08:00
committed by GitHub
parent f665d001ed
commit f81ebddfcc
29 changed files with 338 additions and 457 deletions

View File

@@ -8,7 +8,7 @@
"getPublishedVersion": "cargo search ${ pkgFile.pkg.package.name } --limit 1 | sed -nE \"s/^[^\\\"]*\\\"//; s/\\\".*//1p\"",
"prepublish": [
"sudo apt-get update",
"sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev",
"sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev",
"cargo install cargo-audit --features=fix",
{
"command": "cargo generate-lockfile",

View File

@@ -0,0 +1,7 @@
---
"tauri": minor
"tauri-runtime": minor
"tauri-runtime-wry": minor
---
Remove menu feature flag since there's no package dependency need to be installed on any platform anymore.

View File

@@ -35,7 +35,7 @@ jobs:
if: matrix.platform == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
- name: Get current date
run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV

View File

@@ -37,7 +37,7 @@ jobs:
run: |
python -m pip install --upgrade pip
sudo apt-get update
sudo apt-get install -y webkit2gtk-4.0 libgtksourceview-3.0-dev libappindicator3-dev xvfb
sudo apt-get install -y webkit2gtk-4.0 libappindicator3-dev xvfb
wget https://github.com/sharkdp/hyperfine/releases/download/v1.11.0/hyperfine_1.11.0_amd64.deb
sudo dpkg -i hyperfine_1.11.0_amd64.deb
pip install memory_profiler

View File

@@ -69,7 +69,7 @@ jobs:
if: matrix.platform == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
- name: yarn install for cli
working-directory: tauri/tooling/cli.js
run: yarn

View File

@@ -24,7 +24,7 @@ jobs:
- name: install webkit2gtk
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
- uses: actions-rs/toolchain@v1
with:
@@ -151,7 +151,7 @@ jobs:
- name: install webkit2gtk
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
- uses: actions-rs/toolchain@v1
with:

View File

@@ -76,7 +76,7 @@ jobs:
- name: install webkit2gtk
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
# Rust
- name: generate rust docs

View File

@@ -37,7 +37,7 @@ jobs:
if: matrix.platform == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
- name: cache rust bin
id: cache_rust_bin
uses: actions/cache@v1

View File

@@ -35,7 +35,7 @@ jobs:
if: matrix.platform == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
- name: Get current date
run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV
@@ -100,7 +100,7 @@ jobs:
if: matrix.platform == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
- name: clippy check
uses: actions-rs/clippy-check@v1
with:

View File

@@ -37,7 +37,7 @@ jobs:
if: matrix.platform == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
- name: Get current date
run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV
@@ -161,7 +161,7 @@ jobs:
if: matrix.platform == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
- name: Get current date
run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV

View File

@@ -45,7 +45,7 @@ jobs:
if: (github.event.inputs.platform || 'ubuntu') == 'ubuntu'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
- run: yarn
working-directory: tooling/cli.js
- run: yarn build
@@ -86,7 +86,7 @@ jobs:
# if: (github.event.inputs.platform || 'ubuntu') == 'ubuntu'
# run: |
# sudo apt-get update
# sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
# sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
# - run: yarn
# working-directory: tooling/create-tauri-app
# - run: yarn build

View File

@@ -90,7 +90,7 @@ jobs:
- name: Install required packages
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
- uses: actions-rs/cargo@v1
with:

View File

@@ -43,7 +43,7 @@ jobs:
- name: install webkit2gtk
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libgtksourceview-3.0-dev webkit2gtk-4.0 libappindicator3-dev
sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev
# Rust
- name: generate rust docs

View File

@@ -29,5 +29,4 @@ gtk = { version = "0.14", features = [ "v3_20" ] }
[features]
dox = [ "wry/dox" ]
menu = [ "tauri-runtime/menu"]
system-tray = [ "wry/tray", "tauri-runtime/system-tray" ]

View File

@@ -5,6 +5,7 @@
//! The [`wry`] Tauri [`Runtime`].
use tauri_runtime::{
menu::{CustomMenuItem, Menu, MenuEntry, MenuHash, MenuItem, MenuUpdate, Submenu},
monitor::Monitor,
webview::{
FileDropEvent, FileDropHandler, RpcRequest, WebviewRpcHandler, WindowBuilder, WindowBuilderBase,
@@ -17,7 +18,6 @@ use tauri_runtime::{
RunEvent, RunIteration, Runtime, RuntimeHandle, UserAttentionType,
};
#[cfg(feature = "menu")]
use tauri_runtime::window::MenuEvent;
#[cfg(feature = "system-tray")]
use tauri_runtime::{SystemTray, SystemTrayEvent};
@@ -49,6 +49,10 @@ use wry::{
event::{Event, WindowEvent as WryWindowEvent},
event_loop::{ControlFlow, EventLoop, EventLoopProxy, EventLoopWindowTarget},
global_shortcut::{GlobalShortcut, ShortcutManager as WryShortcutManager},
menu::{
CustomMenuItem as WryCustomMenuItem, MenuBar, MenuId as WryMenuId, MenuItem as WryMenuItem,
MenuItemAttributes as WryMenuItemAttributes, MenuType,
},
monitor::MonitorHandle,
window::{Fullscreen, Icon as WindowIcon, UserAttentionType as WryUserAttentionType},
},
@@ -63,6 +67,13 @@ pub use wry::application::window::{Window, WindowBuilder as WryWindowBuilder, Wi
#[cfg(target_os = "windows")]
use wry::webview::WebviewExtWindows;
#[cfg(target_os = "macos")]
use tauri_runtime::menu::NativeImage;
#[cfg(target_os = "macos")]
pub use wry::application::platform::macos::{
CustomMenuItemExtMacOS, NativeImage as WryNativeImage,
};
use std::{
collections::{
hash_map::Entry::{Occupied, Vacant},
@@ -80,19 +91,25 @@ use std::{
thread::{current as current_thread, ThreadId},
};
#[cfg(any(feature = "menu", feature = "system-tray"))]
mod menu;
#[cfg(any(feature = "menu", feature = "system-tray"))]
use menu::*;
#[cfg(feature = "system-tray")]
mod system_tray;
#[cfg(feature = "system-tray")]
use system_tray::*;
mod mime_type;
use mime_type::MimeType;
type WebContextStore = Mutex<HashMap<Option<PathBuf>, WebContext>>;
// window
type WindowEventHandler = Box<dyn Fn(&WindowEvent) + Send>;
type WindowEventListenersMap = Arc<Mutex<HashMap<Uuid, WindowEventHandler>>>;
type WindowEventListeners = Arc<Mutex<HashMap<WindowId, WindowEventListenersMap>>>;
// global shortcut
type GlobalShortcutListeners = Arc<Mutex<HashMap<AcceleratorId, Box<dyn Fn() + Send>>>>;
// menu
pub type MenuEventHandler = Box<dyn Fn(&MenuEvent) + Send>;
pub type MenuEventListeners = Arc<Mutex<HashMap<WindowId, WindowMenuEventListeners>>>;
pub type WindowMenuEventListeners = Arc<Mutex<HashMap<Uuid, MenuEventHandler>>>;
macro_rules! dispatcher_getter {
($self: ident, $message: expr) => {{
@@ -134,6 +151,124 @@ struct EventLoopContext {
proxy: EventLoopProxy<Message>,
}
pub struct MenuItemAttributesWrapper<'a>(pub WryMenuItemAttributes<'a>);
impl<'a> From<&'a CustomMenuItem> for MenuItemAttributesWrapper<'a> {
fn from(item: &'a CustomMenuItem) -> Self {
let mut attributes = WryMenuItemAttributes::new(&item.title)
.with_enabled(item.enabled)
.with_selected(item.selected)
.with_id(WryMenuId(item.id));
if let Some(accelerator) = item.keyboard_accelerator.as_ref() {
attributes = attributes.with_accelerators(&accelerator.parse().expect("invalid accelerator"));
}
Self(attributes)
}
}
pub struct MenuItemWrapper(pub WryMenuItem);
impl From<MenuItem> for MenuItemWrapper {
fn from(item: MenuItem) -> Self {
match item {
MenuItem::About(v) => Self(WryMenuItem::About(v)),
MenuItem::Hide => Self(WryMenuItem::Hide),
MenuItem::Services => Self(WryMenuItem::Services),
MenuItem::HideOthers => Self(WryMenuItem::HideOthers),
MenuItem::ShowAll => Self(WryMenuItem::ShowAll),
MenuItem::CloseWindow => Self(WryMenuItem::CloseWindow),
MenuItem::Quit => Self(WryMenuItem::Quit),
MenuItem::Copy => Self(WryMenuItem::Copy),
MenuItem::Cut => Self(WryMenuItem::Cut),
MenuItem::Undo => Self(WryMenuItem::Undo),
MenuItem::Redo => Self(WryMenuItem::Redo),
MenuItem::SelectAll => Self(WryMenuItem::SelectAll),
MenuItem::Paste => Self(WryMenuItem::Paste),
MenuItem::EnterFullScreen => Self(WryMenuItem::EnterFullScreen),
MenuItem::Minimize => Self(WryMenuItem::Minimize),
MenuItem::Zoom => Self(WryMenuItem::Zoom),
MenuItem::Separator => Self(WryMenuItem::Separator),
_ => unimplemented!(),
}
}
}
#[cfg(target_os = "macos")]
pub struct NativeImageWrapper(pub WryNativeImage);
#[cfg(target_os = "macos")]
impl std::fmt::Debug for NativeImageWrapper {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("NativeImageWrapper").finish()
}
}
#[cfg(target_os = "macos")]
impl From<NativeImage> for NativeImageWrapper {
fn from(image: NativeImage) -> NativeImageWrapper {
let wry_image = match image {
NativeImage::Add => WryNativeImage::Add,
NativeImage::Advanced => WryNativeImage::Advanced,
NativeImage::Bluetooth => WryNativeImage::Bluetooth,
NativeImage::Bookmarks => WryNativeImage::Bookmarks,
NativeImage::Caution => WryNativeImage::Caution,
NativeImage::ColorPanel => WryNativeImage::ColorPanel,
NativeImage::ColumnView => WryNativeImage::ColumnView,
NativeImage::Computer => WryNativeImage::Computer,
NativeImage::EnterFullScreen => WryNativeImage::EnterFullScreen,
NativeImage::Everyone => WryNativeImage::Everyone,
NativeImage::ExitFullScreen => WryNativeImage::ExitFullScreen,
NativeImage::FlowView => WryNativeImage::FlowView,
NativeImage::Folder => WryNativeImage::Folder,
NativeImage::FolderBurnable => WryNativeImage::FolderBurnable,
NativeImage::FolderSmart => WryNativeImage::FolderSmart,
NativeImage::FollowLinkFreestanding => WryNativeImage::FollowLinkFreestanding,
NativeImage::FontPanel => WryNativeImage::FontPanel,
NativeImage::GoLeft => WryNativeImage::GoLeft,
NativeImage::GoRight => WryNativeImage::GoRight,
NativeImage::Home => WryNativeImage::Home,
NativeImage::IChatTheater => WryNativeImage::IChatTheater,
NativeImage::IconView => WryNativeImage::IconView,
NativeImage::Info => WryNativeImage::Info,
NativeImage::InvalidDataFreestanding => WryNativeImage::InvalidDataFreestanding,
NativeImage::LeftFacingTriangle => WryNativeImage::LeftFacingTriangle,
NativeImage::ListView => WryNativeImage::ListView,
NativeImage::LockLocked => WryNativeImage::LockLocked,
NativeImage::LockUnlocked => WryNativeImage::LockUnlocked,
NativeImage::MenuMixedState => WryNativeImage::MenuMixedState,
NativeImage::MenuOnState => WryNativeImage::MenuOnState,
NativeImage::MobileMe => WryNativeImage::MobileMe,
NativeImage::MultipleDocuments => WryNativeImage::MultipleDocuments,
NativeImage::Network => WryNativeImage::Network,
NativeImage::Path => WryNativeImage::Path,
NativeImage::PreferencesGeneral => WryNativeImage::PreferencesGeneral,
NativeImage::QuickLook => WryNativeImage::QuickLook,
NativeImage::RefreshFreestanding => WryNativeImage::RefreshFreestanding,
NativeImage::Refresh => WryNativeImage::Refresh,
NativeImage::Remove => WryNativeImage::Remove,
NativeImage::RevealFreestanding => WryNativeImage::RevealFreestanding,
NativeImage::RightFacingTriangle => WryNativeImage::RightFacingTriangle,
NativeImage::Share => WryNativeImage::Share,
NativeImage::Slideshow => WryNativeImage::Slideshow,
NativeImage::SmartBadge => WryNativeImage::SmartBadge,
NativeImage::StatusAvailable => WryNativeImage::StatusAvailable,
NativeImage::StatusNone => WryNativeImage::StatusNone,
NativeImage::StatusPartiallyAvailable => WryNativeImage::StatusPartiallyAvailable,
NativeImage::StatusUnavailable => WryNativeImage::StatusUnavailable,
NativeImage::StopProgressFreestanding => WryNativeImage::StopProgressFreestanding,
NativeImage::StopProgress => WryNativeImage::StopProgress,
NativeImage::TrashEmpty => WryNativeImage::TrashEmpty,
NativeImage::TrashFull => WryNativeImage::TrashFull,
NativeImage::User => WryNativeImage::User,
NativeImage::UserAccounts => WryNativeImage::UserAccounts,
NativeImage::UserGroup => WryNativeImage::UserGroup,
NativeImage::UserGuest => WryNativeImage::UserGuest,
};
Self(wry_image)
}
}
#[derive(Debug, Clone)]
pub struct GlobalShortcutWrapper(GlobalShortcut);
@@ -438,7 +573,6 @@ impl From<UserAttentionType> for UserAttentionTypeWrapper {
pub struct WindowBuilderWrapper {
inner: WryWindowBuilder,
center: bool,
#[cfg(feature = "menu")]
menu: Menu,
}
@@ -481,7 +615,6 @@ impl WindowBuilder for WindowBuilderWrapper {
window
}
#[cfg(feature = "menu")]
fn menu(mut self, menu: Menu) -> Self {
self.menu = convert_menu_id(Menu::new(), menu);
self
@@ -604,7 +737,6 @@ impl WindowBuilder for WindowBuilderWrapper {
self.inner.window.window_icon.is_some()
}
#[cfg(feature = "menu")]
fn has_menu(&self) -> bool {
self.inner.window.window_menu.is_some()
}
@@ -675,7 +807,6 @@ pub enum WindowMessage {
IsDecorated(Sender<bool>),
IsResizable(Sender<bool>),
IsVisible(Sender<bool>),
#[cfg(feature = "menu")]
IsMenuVisible(Sender<bool>),
CurrentMonitor(Sender<Option<MonitorHandle>>),
PrimaryMonitor(Sender<Option<MonitorHandle>>),
@@ -701,9 +832,7 @@ pub enum WindowMessage {
Unmaximize,
Minimize,
Unminimize,
#[cfg(feature = "menu")]
ShowMenu,
#[cfg(feature = "menu")]
HideMenu,
Show,
Hide,
@@ -719,8 +848,7 @@ pub enum WindowMessage {
SetIcon(WindowIcon),
SetSkipTaskbar(bool),
DragWindow,
#[cfg(feature = "menu")]
UpdateMenuItem(u16, menu::MenuUpdate),
UpdateMenuItem(u16, MenuUpdate),
}
#[derive(Debug, Clone)]
@@ -740,7 +868,7 @@ pub enum WebviewEvent {
#[cfg(feature = "system-tray")]
#[derive(Debug, Clone)]
pub enum TrayMessage {
UpdateItem(u16, menu::MenuUpdate),
UpdateItem(u16, MenuUpdate),
UpdateIcon(Icon),
#[cfg(target_os = "macos")]
UpdateIconAsTemplate(bool),
@@ -786,7 +914,6 @@ struct DispatcherContext {
is_event_loop_running: Arc<AtomicBool>,
proxy: EventLoopProxy<Message>,
window_event_listeners: WindowEventListeners,
#[cfg(feature = "menu")]
menu_event_listeners: MenuEventListeners,
}
@@ -834,7 +961,6 @@ impl Dispatch for WryDispatcher {
id
}
#[cfg(feature = "menu")]
fn on_menu_event<F: Fn(&MenuEvent) + Send + 'static>(&self, f: F) -> Uuid {
let id = Uuid::new_v4();
self
@@ -894,7 +1020,6 @@ impl Dispatch for WryDispatcher {
Ok(dispatcher_getter!(self, WindowMessage::IsVisible))
}
#[cfg(feature = "menu")]
fn is_menu_visible(&self) -> Result<bool> {
Ok(dispatcher_getter!(self, WindowMessage::IsMenuVisible))
}
@@ -1052,7 +1177,6 @@ impl Dispatch for WryDispatcher {
.map_err(|_| Error::FailedToSendMessage)
}
#[cfg(feature = "menu")]
fn show_menu(&self) -> Result<()> {
self
.context
@@ -1061,7 +1185,6 @@ impl Dispatch for WryDispatcher {
.map_err(|_| Error::FailedToSendMessage)
}
#[cfg(feature = "menu")]
fn hide_menu(&self) -> Result<()> {
self
.context
@@ -1220,8 +1343,7 @@ impl Dispatch for WryDispatcher {
.map_err(|_| Error::FailedToSendMessage)
}
#[cfg(feature = "menu")]
fn update_menu_item(&self, id: u16, update: menu::MenuUpdate) -> Result<()> {
fn update_menu_item(&self, id: u16, update: MenuUpdate) -> Result<()> {
self
.context
.proxy
@@ -1258,7 +1380,6 @@ impl WindowHandle {
pub struct WindowWrapper {
label: String,
inner: WindowHandle,
#[cfg(feature = "menu")]
menu_items: HashMap<u16, WryCustomMenuItem>,
}
@@ -1274,7 +1395,6 @@ pub struct Wry {
windows: Arc<Mutex<HashMap<WindowId, WindowWrapper>>>,
web_context: WebContextStore,
window_event_listeners: WindowEventListeners,
#[cfg(feature = "menu")]
menu_event_listeners: MenuEventListeners,
#[cfg(feature = "system-tray")]
tray_context: TrayContext,
@@ -1392,7 +1512,6 @@ impl Runtime for Wry {
windows: Default::default(),
web_context: Default::default(),
window_event_listeners: Default::default(),
#[cfg(feature = "menu")]
menu_event_listeners: Default::default(),
#[cfg(feature = "system-tray")]
tray_context: Default::default(),
@@ -1406,7 +1525,6 @@ impl Runtime for Wry {
is_event_loop_running: self.is_event_loop_running.clone(),
proxy: self.event_loop.create_proxy(),
window_event_listeners: self.window_event_listeners.clone(),
#[cfg(feature = "menu")]
menu_event_listeners: self.menu_event_listeners.clone(),
},
}
@@ -1431,7 +1549,6 @@ impl Runtime for Wry {
is_event_loop_running: self.is_event_loop_running.clone(),
proxy: proxy.clone(),
window_event_listeners: self.window_event_listeners.clone(),
#[cfg(feature = "menu")]
menu_event_listeners: self.menu_event_listeners.clone(),
},
pending,
@@ -1473,7 +1590,6 @@ impl Runtime for Wry {
is_event_loop_running: self.is_event_loop_running.clone(),
proxy,
window_event_listeners: self.window_event_listeners.clone(),
#[cfg(feature = "menu")]
menu_event_listeners: self.menu_event_listeners.clone(),
},
};
@@ -1543,7 +1659,6 @@ impl Runtime for Wry {
let windows = self.windows.clone();
let web_context = &self.web_context;
let window_event_listeners = self.window_event_listeners.clone();
#[cfg(feature = "menu")]
let menu_event_listeners = self.menu_event_listeners.clone();
#[cfg(feature = "system-tray")]
let tray_context = self.tray_context.clone();
@@ -1571,7 +1686,6 @@ impl Runtime for Wry {
global_shortcut_manager: global_shortcut_manager.clone(),
global_shortcut_manager_handle: &global_shortcut_manager_handle,
clipboard_manager: clipboard_manager.clone(),
#[cfg(feature = "menu")]
menu_event_listeners: &menu_event_listeners,
#[cfg(feature = "system-tray")]
tray_context: &tray_context,
@@ -1589,7 +1703,6 @@ impl Runtime for Wry {
let windows = self.windows.clone();
let web_context = self.web_context;
let window_event_listeners = self.window_event_listeners.clone();
#[cfg(feature = "menu")]
let menu_event_listeners = self.menu_event_listeners.clone();
#[cfg(feature = "system-tray")]
let tray_context = self.tray_context;
@@ -1609,7 +1722,6 @@ impl Runtime for Wry {
global_shortcut_manager: global_shortcut_manager.clone(),
global_shortcut_manager_handle: &global_shortcut_manager_handle,
clipboard_manager: clipboard_manager.clone(),
#[cfg(feature = "menu")]
menu_event_listeners: &menu_event_listeners,
#[cfg(feature = "system-tray")]
tray_context: &tray_context,
@@ -1627,7 +1739,6 @@ struct EventLoopIterationContext<'a> {
global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
global_shortcut_manager_handle: &'a GlobalShortcutManagerHandle,
clipboard_manager: Arc<Mutex<Clipboard>>,
#[cfg(feature = "menu")]
menu_event_listeners: &'a MenuEventListeners,
#[cfg(feature = "system-tray")]
tray_context: &'a TrayContext,
@@ -1647,7 +1758,6 @@ fn handle_event_loop(
global_shortcut_manager,
global_shortcut_manager_handle,
clipboard_manager,
#[cfg(feature = "menu")]
menu_event_listeners,
#[cfg(feature = "system-tray")]
tray_context,
@@ -1667,7 +1777,6 @@ fn handle_event_loop(
}
}
}
#[cfg(feature = "menu")]
Event::MenuEvent {
window_id,
menu_id,
@@ -1756,7 +1865,6 @@ fn handle_event_loop(
control_flow,
#[cfg(target_os = "linux")]
window_event_listeners,
#[cfg(feature = "menu")]
menu_event_listeners.clone(),
);
}
@@ -1807,7 +1915,6 @@ fn handle_event_loop(
WindowMessage::IsDecorated(tx) => tx.send(window.is_decorated()).unwrap(),
WindowMessage::IsResizable(tx) => tx.send(window.is_resizable()).unwrap(),
WindowMessage::IsVisible(tx) => tx.send(window.is_visible()).unwrap(),
#[cfg(feature = "menu")]
WindowMessage::IsMenuVisible(tx) => tx.send(window.is_menu_visible()).unwrap(),
WindowMessage::CurrentMonitor(tx) => tx.send(window.current_monitor()).unwrap(),
WindowMessage::PrimaryMonitor(tx) => tx.send(window.primary_monitor()).unwrap(),
@@ -1841,9 +1948,7 @@ fn handle_event_loop(
WindowMessage::Unmaximize => window.set_maximized(false),
WindowMessage::Minimize => window.set_minimized(true),
WindowMessage::Unminimize => window.set_minimized(false),
#[cfg(feature = "menu")]
WindowMessage::ShowMenu => window.show_menu(),
#[cfg(feature = "menu")]
WindowMessage::HideMenu => window.hide_menu(),
WindowMessage::Show => window.set_visible(true),
WindowMessage::Hide => window.set_visible(false),
@@ -1855,7 +1960,6 @@ fn handle_event_loop(
control_flow,
#[cfg(target_os = "linux")]
window_event_listeners,
#[cfg(feature = "menu")]
menu_event_listeners.clone(),
);
}
@@ -1893,7 +1997,6 @@ fn handle_event_loop(
WindowMessage::DragWindow => {
let _ = window.drag_window();
}
#[cfg(feature = "menu")]
WindowMessage::UpdateMenuItem(id, update) => {
let item = webview
.menu_items
@@ -1962,7 +2065,6 @@ fn handle_event_loop(
.unwrap()
.insert(window.id(), WindowEventListenersMap::default());
#[cfg(feature = "menu")]
context
.menu_event_listeners
.lock()
@@ -1976,7 +2078,6 @@ fn handle_event_loop(
WindowWrapper {
label,
inner: WindowHandle::Window(w.clone()),
#[cfg(feature = "menu")]
menu_items: Default::default(),
},
);
@@ -2075,10 +2176,9 @@ fn on_window_close<'a>(
windows: &mut MutexGuard<'a, HashMap<WindowId, WindowWrapper>>,
control_flow: &mut ControlFlow,
#[cfg(target_os = "linux")] window_event_listeners: &WindowEventListeners,
#[cfg(feature = "menu")] menu_event_listeners: MenuEventListeners,
menu_event_listeners: MenuEventListeners,
) {
if let Some(webview) = windows.remove(&window_id) {
#[cfg(feature = "menu")]
menu_event_listeners.lock().unwrap().remove(&window_id);
callback(RunEvent::WindowClose(webview.label.clone()));
@@ -2128,6 +2228,71 @@ fn center_window(window: &Window) -> Result<()> {
}
}
fn convert_menu_id(mut new_menu: Menu, menu: Menu) -> Menu {
for item in menu.items {
match item {
MenuEntry::CustomItem(c) => {
let mut item = CustomMenuItem::new(c.id_str, c.title);
#[cfg(target_os = "macos")]
if let Some(native_image) = c.native_image {
item = item.native_image(native_image);
}
if let Some(accelerator) = c.keyboard_accelerator {
item = item.accelerator(accelerator);
}
if !c.enabled {
item = item.disabled();
}
if c.selected {
item = item.selected();
}
new_menu = new_menu.add_item(item);
}
MenuEntry::NativeItem(i) => {
new_menu = new_menu.add_native_item(i);
}
MenuEntry::Submenu(submenu) => {
let new_submenu = convert_menu_id(Menu::new(), submenu.inner);
new_menu = new_menu.add_submenu(Submenu::new(submenu.title, new_submenu));
}
}
}
new_menu
}
fn to_wry_menu(
custom_menu_items: &mut HashMap<MenuHash, WryCustomMenuItem>,
menu: Menu,
) -> MenuBar {
let mut wry_menu = MenuBar::new();
for item in menu.items {
match item {
MenuEntry::CustomItem(c) => {
let mut attributes = MenuItemAttributesWrapper::from(&c).0;
attributes = attributes.with_id(WryMenuId(c.id));
#[allow(unused_mut)]
let mut item = wry_menu.add_item(attributes);
#[cfg(target_os = "macos")]
if let Some(native_image) = c.native_image {
item.set_native_image(NativeImageWrapper::from(native_image).0);
}
custom_menu_items.insert(c.id, item);
}
MenuEntry::NativeItem(i) => {
wry_menu.add_native_item(MenuItemWrapper::from(i).0);
}
MenuEntry::Submenu(submenu) => {
wry_menu.add_submenu(
&submenu.title,
submenu.enabled,
to_wry_menu(custom_menu_items, submenu.inner),
);
}
}
}
wry_menu
}
fn create_webview(
event_loop: &EventLoopWindowTarget<Message>,
web_context: &WebContextStore,
@@ -2146,7 +2311,6 @@ fn create_webview(
} = pending;
let is_window_transparent = window_builder.inner.window.transparent;
#[cfg(feature = "menu")]
let menu_items = {
let mut menu_items = HashMap::new();
let menu = to_wry_menu(&mut menu_items, window_builder.menu);
@@ -2161,7 +2325,6 @@ fn create_webview(
.unwrap()
.insert(window.id(), WindowEventListenersMap::default());
#[cfg(feature = "menu")]
context
.menu_event_listeners
.lock()
@@ -2224,7 +2387,6 @@ fn create_webview(
Ok(WindowWrapper {
label,
inner: WindowHandle::Webview(webview),
#[cfg(feature = "menu")]
menu_items,
})
}

View File

@@ -1,313 +0,0 @@
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
pub use tauri_runtime::{
menu::{
CustomMenuItem, Menu, MenuEntry, MenuItem, MenuUpdate, Submenu, SystemTrayMenu,
SystemTrayMenuEntry, SystemTrayMenuItem, TrayHandle,
},
window::MenuEvent,
Icon, SystemTrayEvent,
};
pub use wry::application::{
event::TrayEvent,
event_loop::EventLoopProxy,
menu::{
ContextMenu as WryContextMenu, CustomMenuItem as WryCustomMenuItem, MenuBar,
MenuId as WryMenuId, MenuItem as WryMenuItem, MenuItemAttributes as WryMenuItemAttributes,
MenuType,
},
window::WindowId,
};
#[cfg(target_os = "macos")]
use tauri_runtime::menu::NativeImage;
#[cfg(target_os = "macos")]
pub use wry::application::platform::macos::{
CustomMenuItemExtMacOS, NativeImage as WryNativeImage,
};
#[cfg(feature = "system-tray")]
use crate::{Error, Message, Result, TrayMessage};
#[cfg(any(feature = "menu", feature = "system-tray"))]
use tauri_runtime::menu::MenuHash;
use uuid::Uuid;
use std::{
collections::HashMap,
sync::{Arc, Mutex},
};
#[cfg(feature = "menu")]
pub type MenuEventHandler = Box<dyn Fn(&MenuEvent) + Send>;
#[cfg(feature = "menu")]
pub type MenuEventListeners = Arc<Mutex<HashMap<WindowId, WindowMenuEventListeners>>>;
#[cfg(feature = "menu")]
pub type WindowMenuEventListeners = Arc<Mutex<HashMap<Uuid, MenuEventHandler>>>;
#[cfg(feature = "system-tray")]
pub type SystemTrayEventHandler = Box<dyn Fn(&SystemTrayEvent) + Send>;
#[cfg(feature = "system-tray")]
pub type SystemTrayEventListeners = Arc<Mutex<HashMap<Uuid, SystemTrayEventHandler>>>;
#[cfg(feature = "system-tray")]
pub type SystemTrayItems = Arc<Mutex<HashMap<u16, WryCustomMenuItem>>>;
#[cfg(feature = "system-tray")]
#[derive(Debug, Clone)]
pub struct SystemTrayHandle {
pub(crate) proxy: EventLoopProxy<super::Message>,
}
#[cfg(feature = "system-tray")]
impl TrayHandle for SystemTrayHandle {
fn set_icon(&self, icon: Icon) -> Result<()> {
self
.proxy
.send_event(Message::Tray(TrayMessage::UpdateIcon(icon)))
.map_err(|_| Error::FailedToSendMessage)
}
fn update_item(&self, id: u16, update: MenuUpdate) -> Result<()> {
self
.proxy
.send_event(Message::Tray(TrayMessage::UpdateItem(id, update)))
.map_err(|_| Error::FailedToSendMessage)
}
#[cfg(target_os = "macos")]
fn set_icon_as_template(&self, is_template: bool) -> tauri_runtime::Result<()> {
self
.proxy
.send_event(Message::Tray(TrayMessage::UpdateIconAsTemplate(
is_template,
)))
.map_err(|_| Error::FailedToSendMessage)
}
}
#[cfg(target_os = "macos")]
pub struct NativeImageWrapper(pub WryNativeImage);
#[cfg(target_os = "macos")]
impl std::fmt::Debug for NativeImageWrapper {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("NativeImageWrapper").finish()
}
}
#[cfg(target_os = "macos")]
impl From<NativeImage> for NativeImageWrapper {
fn from(image: NativeImage) -> NativeImageWrapper {
let wry_image = match image {
NativeImage::Add => WryNativeImage::Add,
NativeImage::Advanced => WryNativeImage::Advanced,
NativeImage::Bluetooth => WryNativeImage::Bluetooth,
NativeImage::Bookmarks => WryNativeImage::Bookmarks,
NativeImage::Caution => WryNativeImage::Caution,
NativeImage::ColorPanel => WryNativeImage::ColorPanel,
NativeImage::ColumnView => WryNativeImage::ColumnView,
NativeImage::Computer => WryNativeImage::Computer,
NativeImage::EnterFullScreen => WryNativeImage::EnterFullScreen,
NativeImage::Everyone => WryNativeImage::Everyone,
NativeImage::ExitFullScreen => WryNativeImage::ExitFullScreen,
NativeImage::FlowView => WryNativeImage::FlowView,
NativeImage::Folder => WryNativeImage::Folder,
NativeImage::FolderBurnable => WryNativeImage::FolderBurnable,
NativeImage::FolderSmart => WryNativeImage::FolderSmart,
NativeImage::FollowLinkFreestanding => WryNativeImage::FollowLinkFreestanding,
NativeImage::FontPanel => WryNativeImage::FontPanel,
NativeImage::GoLeft => WryNativeImage::GoLeft,
NativeImage::GoRight => WryNativeImage::GoRight,
NativeImage::Home => WryNativeImage::Home,
NativeImage::IChatTheater => WryNativeImage::IChatTheater,
NativeImage::IconView => WryNativeImage::IconView,
NativeImage::Info => WryNativeImage::Info,
NativeImage::InvalidDataFreestanding => WryNativeImage::InvalidDataFreestanding,
NativeImage::LeftFacingTriangle => WryNativeImage::LeftFacingTriangle,
NativeImage::ListView => WryNativeImage::ListView,
NativeImage::LockLocked => WryNativeImage::LockLocked,
NativeImage::LockUnlocked => WryNativeImage::LockUnlocked,
NativeImage::MenuMixedState => WryNativeImage::MenuMixedState,
NativeImage::MenuOnState => WryNativeImage::MenuOnState,
NativeImage::MobileMe => WryNativeImage::MobileMe,
NativeImage::MultipleDocuments => WryNativeImage::MultipleDocuments,
NativeImage::Network => WryNativeImage::Network,
NativeImage::Path => WryNativeImage::Path,
NativeImage::PreferencesGeneral => WryNativeImage::PreferencesGeneral,
NativeImage::QuickLook => WryNativeImage::QuickLook,
NativeImage::RefreshFreestanding => WryNativeImage::RefreshFreestanding,
NativeImage::Refresh => WryNativeImage::Refresh,
NativeImage::Remove => WryNativeImage::Remove,
NativeImage::RevealFreestanding => WryNativeImage::RevealFreestanding,
NativeImage::RightFacingTriangle => WryNativeImage::RightFacingTriangle,
NativeImage::Share => WryNativeImage::Share,
NativeImage::Slideshow => WryNativeImage::Slideshow,
NativeImage::SmartBadge => WryNativeImage::SmartBadge,
NativeImage::StatusAvailable => WryNativeImage::StatusAvailable,
NativeImage::StatusNone => WryNativeImage::StatusNone,
NativeImage::StatusPartiallyAvailable => WryNativeImage::StatusPartiallyAvailable,
NativeImage::StatusUnavailable => WryNativeImage::StatusUnavailable,
NativeImage::StopProgressFreestanding => WryNativeImage::StopProgressFreestanding,
NativeImage::StopProgress => WryNativeImage::StopProgress,
NativeImage::TrashEmpty => WryNativeImage::TrashEmpty,
NativeImage::TrashFull => WryNativeImage::TrashFull,
NativeImage::User => WryNativeImage::User,
NativeImage::UserAccounts => WryNativeImage::UserAccounts,
NativeImage::UserGroup => WryNativeImage::UserGroup,
NativeImage::UserGuest => WryNativeImage::UserGuest,
};
Self(wry_image)
}
}
pub struct MenuItemAttributesWrapper<'a>(pub WryMenuItemAttributes<'a>);
impl<'a> From<&'a CustomMenuItem> for MenuItemAttributesWrapper<'a> {
fn from(item: &'a CustomMenuItem) -> Self {
let mut attributes = WryMenuItemAttributes::new(&item.title)
.with_enabled(item.enabled)
.with_selected(item.selected)
.with_id(WryMenuId(item.id));
if let Some(accelerator) = item.keyboard_accelerator.as_ref() {
attributes = attributes.with_accelerators(&accelerator.parse().expect("invalid accelerator"));
}
Self(attributes)
}
}
pub struct MenuItemWrapper(pub WryMenuItem);
impl From<MenuItem> for MenuItemWrapper {
fn from(item: MenuItem) -> Self {
match item {
MenuItem::About(v) => Self(WryMenuItem::About(v)),
MenuItem::Hide => Self(WryMenuItem::Hide),
MenuItem::Services => Self(WryMenuItem::Services),
MenuItem::HideOthers => Self(WryMenuItem::HideOthers),
MenuItem::ShowAll => Self(WryMenuItem::ShowAll),
MenuItem::CloseWindow => Self(WryMenuItem::CloseWindow),
MenuItem::Quit => Self(WryMenuItem::Quit),
MenuItem::Copy => Self(WryMenuItem::Copy),
MenuItem::Cut => Self(WryMenuItem::Cut),
MenuItem::Undo => Self(WryMenuItem::Undo),
MenuItem::Redo => Self(WryMenuItem::Redo),
MenuItem::SelectAll => Self(WryMenuItem::SelectAll),
MenuItem::Paste => Self(WryMenuItem::Paste),
MenuItem::EnterFullScreen => Self(WryMenuItem::EnterFullScreen),
MenuItem::Minimize => Self(WryMenuItem::Minimize),
MenuItem::Zoom => Self(WryMenuItem::Zoom),
MenuItem::Separator => Self(WryMenuItem::Separator),
_ => unimplemented!(),
}
}
}
impl From<SystemTrayMenuItem> for MenuItemWrapper {
fn from(item: SystemTrayMenuItem) -> Self {
match item {
SystemTrayMenuItem::Separator => Self(WryMenuItem::Separator),
_ => unimplemented!(),
}
}
}
#[cfg(feature = "menu")]
pub fn convert_menu_id(mut new_menu: Menu, menu: Menu) -> Menu {
for item in menu.items {
match item {
MenuEntry::CustomItem(c) => {
let mut item = CustomMenuItem::new(c.id_str, c.title);
#[cfg(target_os = "macos")]
if let Some(native_image) = c.native_image {
item = item.native_image(native_image);
}
if let Some(accelerator) = c.keyboard_accelerator {
item = item.accelerator(accelerator);
}
if !c.enabled {
item = item.disabled();
}
if c.selected {
item = item.selected();
}
new_menu = new_menu.add_item(item);
}
MenuEntry::NativeItem(i) => {
new_menu = new_menu.add_native_item(i);
}
MenuEntry::Submenu(submenu) => {
let new_submenu = convert_menu_id(Menu::new(), submenu.inner);
new_menu = new_menu.add_submenu(Submenu::new(submenu.title, new_submenu));
}
}
}
new_menu
}
#[cfg(feature = "menu")]
pub fn to_wry_menu(
custom_menu_items: &mut HashMap<MenuHash, WryCustomMenuItem>,
menu: Menu,
) -> MenuBar {
let mut wry_menu = MenuBar::new();
for item in menu.items {
match item {
MenuEntry::CustomItem(c) => {
let mut attributes = MenuItemAttributesWrapper::from(&c).0;
attributes = attributes.with_id(WryMenuId(c.id));
#[allow(unused_mut)]
let mut item = wry_menu.add_item(attributes);
#[cfg(target_os = "macos")]
if let Some(native_image) = c.native_image {
item.set_native_image(NativeImageWrapper::from(native_image).0);
}
custom_menu_items.insert(c.id, item);
}
MenuEntry::NativeItem(i) => {
wry_menu.add_native_item(MenuItemWrapper::from(i).0);
}
MenuEntry::Submenu(submenu) => {
wry_menu.add_submenu(
&submenu.title,
submenu.enabled,
to_wry_menu(custom_menu_items, submenu.inner),
);
}
}
}
wry_menu
}
#[cfg(feature = "system-tray")]
pub fn to_wry_context_menu(
custom_menu_items: &mut HashMap<MenuHash, WryCustomMenuItem>,
menu: SystemTrayMenu,
) -> WryContextMenu {
let mut tray_menu = WryContextMenu::new();
for item in menu.items {
match item {
SystemTrayMenuEntry::CustomItem(c) => {
#[allow(unused_mut)]
let mut item = tray_menu.add_item(MenuItemAttributesWrapper::from(&c).0);
#[cfg(target_os = "macos")]
if let Some(native_image) = c.native_image {
item.set_native_image(NativeImageWrapper::from(native_image).0);
}
custom_menu_items.insert(c.id, item);
}
SystemTrayMenuEntry::NativeItem(i) => {
tray_menu.add_native_item(MenuItemWrapper::from(i).0);
}
SystemTrayMenuEntry::Submenu(submenu) => {
tray_menu.add_submenu(
&submenu.title,
submenu.enabled,
to_wry_context_menu(custom_menu_items, submenu.inner),
);
}
}
}
tray_menu
}

View File

@@ -0,0 +1,102 @@
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
pub use tauri_runtime::{
menu::{
Menu, MenuEntry, MenuItem, MenuUpdate, Submenu, SystemTrayMenu, SystemTrayMenuEntry,
SystemTrayMenuItem, TrayHandle,
},
Icon, SystemTrayEvent,
};
pub use wry::application::{
event::TrayEvent,
event_loop::EventLoopProxy,
menu::{
ContextMenu as WryContextMenu, CustomMenuItem as WryCustomMenuItem, MenuItem as WryMenuItem,
},
};
use crate::{Error, Message, Result, TrayMessage};
use tauri_runtime::menu::MenuHash;
use uuid::Uuid;
use std::{
collections::HashMap,
sync::{Arc, Mutex},
};
pub type SystemTrayEventHandler = Box<dyn Fn(&SystemTrayEvent) + Send>;
pub type SystemTrayEventListeners = Arc<Mutex<HashMap<Uuid, SystemTrayEventHandler>>>;
pub type SystemTrayItems = Arc<Mutex<HashMap<u16, WryCustomMenuItem>>>;
#[derive(Debug, Clone)]
pub struct SystemTrayHandle {
pub(crate) proxy: EventLoopProxy<super::Message>,
}
impl TrayHandle for SystemTrayHandle {
fn set_icon(&self, icon: Icon) -> Result<()> {
self
.proxy
.send_event(Message::Tray(TrayMessage::UpdateIcon(icon)))
.map_err(|_| Error::FailedToSendMessage)
}
fn update_item(&self, id: u16, update: MenuUpdate) -> Result<()> {
self
.proxy
.send_event(Message::Tray(TrayMessage::UpdateItem(id, update)))
.map_err(|_| Error::FailedToSendMessage)
}
#[cfg(target_os = "macos")]
fn set_icon_as_template(&self, is_template: bool) -> tauri_runtime::Result<()> {
self
.proxy
.send_event(Message::Tray(TrayMessage::UpdateIconAsTemplate(
is_template,
)))
.map_err(|_| Error::FailedToSendMessage)
}
}
impl From<SystemTrayMenuItem> for crate::MenuItemWrapper {
fn from(item: SystemTrayMenuItem) -> Self {
match item {
SystemTrayMenuItem::Separator => Self(WryMenuItem::Separator),
_ => unimplemented!(),
}
}
}
pub fn to_wry_context_menu(
custom_menu_items: &mut HashMap<MenuHash, WryCustomMenuItem>,
menu: SystemTrayMenu,
) -> WryContextMenu {
let mut tray_menu = WryContextMenu::new();
for item in menu.items {
match item {
SystemTrayMenuEntry::CustomItem(c) => {
#[allow(unused_mut)]
let mut item = tray_menu.add_item(crate::MenuItemAttributesWrapper::from(&c).0);
#[cfg(target_os = "macos")]
if let Some(native_image) = c.native_image {
item.set_native_image(crate::NativeImageWrapper::from(native_image).0);
}
custom_menu_items.insert(c.id, item);
}
SystemTrayMenuEntry::NativeItem(i) => {
tray_menu.add_native_item(crate::MenuItemWrapper::from(i).0);
}
SystemTrayMenuEntry::Submenu(submenu) => {
tray_menu.add_submenu(
&submenu.title,
submenu.enabled,
to_wry_context_menu(custom_menu_items, submenu.inner),
);
}
}
}
tray_menu
}

View File

@@ -35,5 +35,4 @@ winapi = "0.3"
gtk = { version = "0.14", features = [ "v3_20" ] }
[features]
menu = [ ]
system-tray = [ ]

View File

@@ -14,8 +14,6 @@ use uuid::Uuid;
use winapi::shared::windef::HWND;
/// Create window and system tray menus.
#[cfg(any(feature = "menu", feature = "system-tray"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "menu", feature = "system-tray"))))]
pub mod menu;
/// Types useful for interacting with a user's monitors.
pub mod monitor;
@@ -353,8 +351,6 @@ pub trait Dispatch: Debug + Clone + Send + Sized + 'static {
fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) -> Uuid;
/// Registers a window event handler.
#[cfg(feature = "menu")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
fn on_menu_event<F: Fn(&window::MenuEvent) + Send + 'static>(&self, f: F) -> Uuid;
// GETTERS
@@ -394,7 +390,6 @@ pub trait Dispatch: Debug + Clone + Send + Sized + 'static {
fn is_visible(&self) -> crate::Result<bool>;
/// Gets the window menu current visibility state.
#[cfg(feature = "menu")]
fn is_menu_visible(&self) -> crate::Result<bool>;
/// Returns the monitor on which the window currently resides.
@@ -466,11 +461,9 @@ pub trait Dispatch: Debug + Clone + Send + Sized + 'static {
fn unminimize(&self) -> crate::Result<()>;
/// Shows the window menu.
#[cfg(feature = "menu")]
fn show_menu(&self) -> crate::Result<()>;
/// Hides the window menu.
#[cfg(feature = "menu")]
fn hide_menu(&self) -> crate::Result<()>;
/// Shows the window.
@@ -519,6 +512,5 @@ pub trait Dispatch: Debug + Clone + Send + Sized + 'static {
fn eval_script<S: Into<String>>(&self, script: S) -> crate::Result<()>;
/// Applies the specified `update` to the menu item associated with the given `id`.
#[cfg(feature = "menu")]
fn update_menu_item(&self, id: u16, update: menu::MenuUpdate) -> crate::Result<()>;
}

View File

@@ -6,7 +6,6 @@
use crate::{window::DetachedWindow, Icon};
#[cfg(feature = "menu")]
use crate::menu::Menu;
use serde::Deserialize;
@@ -118,8 +117,6 @@ pub trait WindowBuilder: WindowBuilderBase {
fn with_config(config: WindowConfig) -> Self;
/// Sets the menu for the window.
#[cfg(feature = "menu")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
fn menu(self, menu: Menu) -> Self;
/// Show window in the center of the screen.
@@ -194,8 +191,6 @@ pub trait WindowBuilder: WindowBuilderBase {
fn has_icon(&self) -> bool;
/// Whether the menu was set or not.
#[cfg(feature = "menu")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
fn has_menu(&self) -> bool;
}

View File

@@ -106,7 +106,6 @@ api-all = [
"path-all"
]
updater = [ "minisign-verify", "base64" ]
menu = [ "tauri-runtime/menu", "tauri-runtime-wry/menu" ]
system-tray = [ "tauri-runtime/system-tray", "tauri-runtime-wry/system-tray" ]
reqwest-client = [ "reqwest", "bytes" ]
fs-all = [ "fs-write-binary-file" ]

View File

@@ -30,7 +30,6 @@ use std::{
sync::{mpsc::Sender, Arc},
};
#[cfg(feature = "menu")]
use crate::runtime::menu::{Menu, MenuId, MenuIdRef};
#[cfg(all(windows, feature = "system-tray"))]
@@ -41,7 +40,6 @@ use crate::runtime::{Icon, SystemTrayEvent as RuntimeSystemTrayEvent};
#[cfg(feature = "updater")]
use crate::updater;
#[cfg(feature = "menu")]
pub(crate) type GlobalMenuEventListener<R> = Box<dyn Fn(WindowMenuEvent<R>) + Send + Sync>;
pub(crate) type GlobalWindowEventListener<R> = Box<dyn Fn(GlobalWindowEvent<R>) + Send + Sync>;
#[cfg(feature = "system-tray")]
@@ -97,8 +95,6 @@ pub enum Event {
}
/// A menu event that was triggered on a window.
#[cfg(feature = "menu")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
#[default_runtime(crate::Wry, wry)]
#[derive(Debug)]
pub struct WindowMenuEvent<R: Runtime> {
@@ -106,7 +102,6 @@ pub struct WindowMenuEvent<R: Runtime> {
pub(crate) window: Window<R>,
}
#[cfg(feature = "menu")]
impl<R: Runtime> WindowMenuEvent<R> {
/// The menu item id.
pub fn menu_item_id(&self) -> MenuIdRef<'_> {
@@ -543,11 +538,9 @@ pub struct Builder<R: Runtime> {
state: StateManager,
/// The menu set to all windows.
#[cfg(feature = "menu")]
menu: Option<Menu>,
/// Menu event handlers that listens to all windows.
#[cfg(feature = "menu")]
menu_event_listeners: Vec<GlobalMenuEventListener<R>>,
/// Window event handlers that listens to all windows.
@@ -573,9 +566,7 @@ impl<R: Runtime> Builder<R> {
plugins: PluginStore::default(),
uri_scheme_protocols: Default::default(),
state: StateManager::new(),
#[cfg(feature = "menu")]
menu: None,
#[cfg(feature = "menu")]
menu_event_listeners: Vec::new(),
window_event_listeners: Vec::new(),
#[cfg(feature = "system-tray")]
@@ -737,16 +728,12 @@ impl<R: Runtime> Builder<R> {
}
/// Sets the menu to use on all windows.
#[cfg(feature = "menu")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
pub fn menu(mut self, menu: Menu) -> Self {
self.menu.replace(menu);
self
}
/// Registers a menu event handler for all windows.
#[cfg(feature = "menu")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
pub fn on_menu_event<F: Fn(WindowMenuEvent<R>) + Send + Sync + 'static>(
mut self,
handler: F,
@@ -850,7 +837,6 @@ impl<R: Runtime> Builder<R> {
self.uri_scheme_protocols,
self.state,
self.window_event_listeners,
#[cfg(feature = "menu")]
(self.menu, self.menu_event_listeners),
);

View File

@@ -66,15 +66,10 @@ use serde::Serialize;
use std::{collections::HashMap, sync::Arc};
// Export types likely to be used by the application.
#[cfg(any(feature = "menu", feature = "system-tray"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "menu", feature = "system-tray"))))]
pub use runtime::menu::CustomMenuItem;
#[cfg(all(target_os = "macos", any(feature = "menu", feature = "system-tray")))]
#[cfg_attr(
doc_cfg,
doc(cfg(all(target_os = "macos", any(feature = "menu", feature = "system-tray"))))
)]
#[cfg(target_os = "macos")]
#[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))]
pub use runtime::menu::NativeImage;
pub use {
@@ -108,8 +103,6 @@ pub use {
SystemTray,
},
};
#[cfg(feature = "menu")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
pub use {
self::app::WindowMenuEvent,
self::runtime::menu::{Menu, MenuItem, Submenu},

View File

@@ -26,10 +26,8 @@ use crate::{
#[cfg(target_os = "windows")]
use crate::api::path::{resolve_path, BaseDirectory};
#[cfg(feature = "menu")]
use crate::app::{GlobalMenuEventListener, WindowMenuEvent};
#[cfg(feature = "menu")]
use crate::{
runtime::menu::{Menu, MenuEntry, MenuHash, MenuId},
MenuEvent,
@@ -55,7 +53,6 @@ const WINDOW_DESTROYED_EVENT: &str = "tauri://destroyed";
const WINDOW_FOCUS_EVENT: &str = "tauri://focus";
const WINDOW_BLUR_EVENT: &str = "tauri://blur";
const WINDOW_SCALE_FACTOR_CHANGED_EVENT: &str = "tauri://scale-change";
#[cfg(feature = "menu")]
const MENU_EVENT: &str = "tauri://menu";
#[default_runtime(crate::Wry, wry)]
@@ -81,13 +78,10 @@ pub struct InnerWindowManager<R: Runtime> {
/// The webview protocols protocols available to all windows.
uri_scheme_protocols: HashMap<String, Arc<CustomProtocol>>,
/// The menu set to all windows.
#[cfg(feature = "menu")]
menu: Option<Menu>,
/// Maps runtime id to a strongly typed menu id.
#[cfg(feature = "menu")]
menu_ids: HashMap<MenuHash, MenuId>,
/// Menu event listeners to all windows.
#[cfg(feature = "menu")]
menu_event_listeners: Arc<Vec<GlobalMenuEventListener<R>>>,
/// Window event listeners to all windows.
window_event_listeners: Arc<Vec<GlobalWindowEventListener<R>>>,
@@ -104,7 +98,6 @@ impl<R: Runtime> fmt::Debug for InnerWindowManager<R> {
.field("default_window_icon", &self.default_window_icon)
.field("salts", &self.salts)
.field("package_info", &self.package_info);
#[cfg(feature = "menu")]
{
w = w
.field("menu", &self.menu)
@@ -130,7 +123,6 @@ impl<R: Runtime> Clone for WindowManager<R> {
}
}
#[cfg(feature = "menu")]
fn get_menu_ids(map: &mut HashMap<MenuHash, MenuId>, menu: &Menu) {
for item in &menu.items {
match item {
@@ -153,10 +145,7 @@ impl<R: Runtime> WindowManager<R> {
uri_scheme_protocols: HashMap<String, Arc<CustomProtocol>>,
state: StateManager,
window_event_listeners: Vec<GlobalWindowEventListener<R>>,
#[cfg(feature = "menu")] (menu, menu_event_listeners): (
Option<Menu>,
Vec<GlobalMenuEventListener<R>>,
),
(menu, menu_event_listeners): (Option<Menu>, Vec<GlobalMenuEventListener<R>>),
) -> Self {
Self {
inner: Arc::new(InnerWindowManager {
@@ -172,7 +161,6 @@ impl<R: Runtime> WindowManager<R> {
salts: Mutex::default(),
package_info: context.package_info,
uri_scheme_protocols,
#[cfg(feature = "menu")]
menu_ids: {
let mut map = HashMap::new();
if let Some(menu) = &menu {
@@ -180,9 +168,7 @@ impl<R: Runtime> WindowManager<R> {
}
map
},
#[cfg(feature = "menu")]
menu,
#[cfg(feature = "menu")]
menu_event_listeners: Arc::new(menu_event_listeners),
window_event_listeners: Arc::new(window_event_listeners),
}),
@@ -201,7 +187,6 @@ impl<R: Runtime> WindowManager<R> {
}
/// Get the menu ids mapper.
#[cfg(feature = "menu")]
pub(crate) fn menu_ids(&self) -> HashMap<MenuHash, MenuId> {
self.inner.menu_ids.clone()
}
@@ -284,7 +269,6 @@ impl<R: Runtime> WindowManager<R> {
}
}
#[cfg(feature = "menu")]
if !pending.window_builder.has_menu() {
if let Some(menu) = &self.inner.menu {
pending.window_builder = pending.window_builder.menu(menu.clone());
@@ -513,7 +497,6 @@ mod test {
Default::default(),
StateManager::new(),
Default::default(),
#[cfg(feature = "menu")]
Default::default(),
);
@@ -639,7 +622,6 @@ impl<R: Runtime> WindowManager<R> {
});
}
});
#[cfg(feature = "menu")]
{
let window_ = window.clone();
let menu_event_listeners = self.inner.menu_event_listeners.clone();
@@ -819,7 +801,6 @@ struct ScaleFactorChanged {
size: PhysicalSize<u32>,
}
#[cfg(feature = "menu")]
fn on_menu_event<R: Runtime>(window: &Window<R>, event: &MenuEvent) -> crate::Result<()> {
window.emit(MENU_EVENT, Some(event.menu_item_id.clone()))
}

View File

@@ -2,12 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
#[cfg(feature = "menu")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
pub(crate) mod menu;
#[cfg(feature = "menu")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
pub use menu::{MenuEvent, MenuHandle};
use crate::{
@@ -293,8 +289,6 @@ impl<R: Runtime> Window<R> {
}
/// Registers a menu event listener.
#[cfg(feature = "menu")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
pub fn on_menu_event<F: Fn(MenuEvent) + Send + 'static>(&self, f: F) -> uuid::Uuid {
let menu_ids = self.manager.menu_ids();
self.window.dispatcher.on_menu_event(move |event| {
@@ -307,7 +301,6 @@ impl<R: Runtime> Window<R> {
// Getters
/// Gets a handle to the window menu.
#[cfg(feature = "menu")]
pub fn menu_handle(&self) -> MenuHandle<R> {
MenuHandle {
ids: self.manager.menu_ids(),

View File

@@ -12,13 +12,11 @@ use tauri_macros::default_runtime;
use std::collections::HashMap;
/// The window menu event.
#[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
#[derive(Debug, Clone)]
pub struct MenuEvent {
pub(crate) menu_item_id: MenuId,
}
#[cfg(feature = "menu")]
impl MenuEvent {
/// The menu item id.
pub fn menu_item_id(&self) -> MenuIdRef<'_> {

View File

@@ -4,15 +4,6 @@ title: Window Menu
Native application menus can be attached to a window.
### Setup
Enable the `menu` feature flag on `src-tauri/Cargo.toml`:
```toml
[dependencies]
tauri = { version = "1.0.0-beta.0", features = ["menu"] }
```
### Creating a menu
To create a native window menu, import the `Menu`, `Submenu`, `MenuItem` and `CustomMenuItem` types.

View File

@@ -11,7 +11,7 @@ tauri-build = { path = "../../../core/tauri-build" }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = [ "derive" ] }
tauri = { path = "../../../core/tauri", features = ["api-all", "cli", "menu", "system-tray", "updater"] }
tauri = { path = "../../../core/tauri", features = ["api-all", "cli", "system-tray", "updater"] }
[features]
default = [ "custom-protocol" ]

View File

@@ -388,9 +388,6 @@ fn tauri_config_to_bundle_settings(
// provides `libwebkit2gtk-4.0.so.37` and all `4.0` versions have the -37 package name
depends.push("libwebkit2gtk-4.0-37".to_string());
depends.push("libgtk-3-0".to_string());
if manifest.features.contains("menu") || system_tray_config.is_some() {
depends.push("libgtksourceview-3.0-1".to_string());
}
}
let signing_identity = match std::env::var_os("APPLE_SIGNING_IDENTITY") {