feat(core): MenuHandle show, hide, is_visible and toggle APIs (#1958)

This commit is contained in:
Lucas Fernandes Nogueira 2021-06-15 22:04:44 -03:00 committed by GitHub
parent cca8115d9c
commit 954460c520
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 138 additions and 9 deletions

View File

@ -0,0 +1,5 @@
---
"tauri": patch
---
Adds `show`, `hide`, `is_visible` and `toggle` APIs to the `MenuHandle`.

View File

@ -0,0 +1,6 @@
---
"tauri-runtime": patch
"tauri-runtime-wry": patch
---
Adds `show_menu`, `hide_menu` and `is_menu_visible` APIs to the `Dispatcher` trait.

View File

@ -23,7 +23,7 @@ members = [
]
[patch.crates-io]
tao = { git = "https://github.com/tauri-apps/tao", rev = "5be88eb9488e3ad27194b5eff2ea31a473128f9c" }
tao = { git = "https://github.com/tauri-apps/tao", rev = "66360eea4ec6af8a52afcebb7700f486a0092168" }
# default to small, optimized workspace release binaries
[profile.release]

View File

@ -57,6 +57,9 @@ use std::{
},
};
#[cfg(feature = "menu")]
use std::sync::atomic::{AtomicBool, Ordering};
#[cfg(any(feature = "menu", feature = "system-tray"))]
mod menu;
#[cfg(any(feature = "menu", feature = "system-tray"))]
@ -456,6 +459,8 @@ 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>>),
AvailableMonitors(Sender<Vec<MonitorHandle>>),
@ -469,6 +474,10 @@ enum WindowMessage {
Unmaximize,
Minimize,
Unminimize,
#[cfg(feature = "menu")]
ShowMenu,
#[cfg(feature = "menu")]
HideMenu,
Show,
Hide,
Close,
@ -618,6 +627,11 @@ 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))
}
fn current_monitor(&self) -> Result<Option<Monitor>> {
Ok(
dispatcher_getter!(self, WindowMessage::CurrentMonitor)
@ -741,6 +755,24 @@ impl Dispatch for WryDispatcher {
.map_err(|_| Error::FailedToSendMessage)
}
#[cfg(feature = "menu")]
fn show_menu(&self) -> Result<()> {
self
.context
.proxy
.send_event(Message::Window(self.window_id, WindowMessage::ShowMenu))
.map_err(|_| Error::FailedToSendMessage)
}
#[cfg(feature = "menu")]
fn hide_menu(&self) -> Result<()> {
self
.context
.proxy
.send_event(Message::Window(self.window_id, WindowMessage::HideMenu))
.map_err(|_| Error::FailedToSendMessage)
}
fn show(&self) -> Result<()> {
self
.context
@ -916,6 +948,8 @@ struct WebviewWrapper {
inner: WebView,
#[cfg(feature = "menu")]
menu_items: HashMap<u32, WryCustomMenuItem>,
#[cfg(feature = "menu")]
is_menu_visible: AtomicBool,
}
/// A Tauri [`Runtime`] wrapper around wry.
@ -1275,6 +1309,10 @@ 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(webview.is_menu_visible.load(Ordering::Relaxed))
.unwrap(),
WindowMessage::CurrentMonitor(tx) => tx.send(window.current_monitor()).unwrap(),
WindowMessage::PrimaryMonitor(tx) => tx.send(window.primary_monitor()).unwrap(),
WindowMessage::AvailableMonitors(tx) => {
@ -1295,6 +1333,16 @@ 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();
webview.is_menu_visible.store(true, Ordering::Relaxed);
}
#[cfg(feature = "menu")]
WindowMessage::HideMenu => {
window.hide_menu();
webview.is_menu_visible.store(false, Ordering::Relaxed);
}
WindowMessage::Show => window.set_visible(true),
WindowMessage::Hide => window.set_visible(false),
WindowMessage::Close => {
@ -1494,6 +1542,8 @@ fn create_webview<P: Params<Runtime = Wry>>(
inner: webview,
#[cfg(feature = "menu")]
menu_items,
#[cfg(feature = "menu")]
is_menu_visible: AtomicBool::new(true),
})
}

View File

@ -301,6 +301,10 @@ pub trait Dispatch: Clone + Send + Sized + 'static {
/// Gets the window's current vibility state.
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.
///
/// Returns None if current monitor can't be detected.
@ -350,6 +354,14 @@ pub trait Dispatch: Clone + Send + Sized + 'static {
/// Unminimizes the window.
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.
fn show(&self) -> crate::Result<()>;

View File

@ -70,6 +70,30 @@ impl<P: Params> MenuHandle<P> {
}
panic!("item id not found")
}
/// Shows the menu.
pub fn show(&self) -> crate::Result<()> {
self.dispatcher.show_menu().map_err(Into::into)
}
/// Hides the menu.
pub fn hide(&self) -> crate::Result<()> {
self.dispatcher.hide_menu().map_err(Into::into)
}
/// Whether the menu is visible or not.
pub fn is_visible(&self) -> crate::Result<bool> {
self.dispatcher.is_menu_visible().map_err(Into::into)
}
/// Toggles the menu visibility.
pub fn toggle(&self) -> crate::Result<()> {
if self.is_visible()? {
self.hide()
} else {
self.show()
}
}
}
impl<P: Params> MenuItemHandle<P> {

View File

@ -18,6 +18,7 @@
},
"dependencies": {
"@tauri-apps/api": "link:../../tooling/api/dist",
"hotkeys-js": "^3.8.5",
"sirv-cli": "1.0.11"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -20,6 +20,11 @@ struct Reply {
data: String,
}
#[tauri::command]
async fn menu_toggle(window: tauri::Window) {
window.menu_handle().toggle().unwrap();
}
fn main() {
tauri::Builder::default()
.on_page_load(|window, _| {
@ -86,7 +91,8 @@ fn main() {
})
.invoke_handler(tauri::generate_handler![
cmd::log_operation,
cmd::perform_request
cmd::perform_request,
menu_toggle,
])
.run(tauri::generate_context!())
.expect("error while running tauri application");

View File

@ -1,6 +1,8 @@
<script>
import { onMount } from "svelte";
import hotkeys from "hotkeys-js";
import { open } from "@tauri-apps/api/shell";
import { invoke } from "@tauri-apps/api/tauri";
import Welcome from "./components/Welcome.svelte";
import Cli from "./components/Cli.svelte";
@ -14,6 +16,14 @@
import Shell from "./components/Shell.svelte";
import Updater from "./components/Updater.svelte";
const MENU_TOGGLE_HOTKEY = 'ctrl+b';
onMount(() => {
hotkeys(MENU_TOGGLE_HOTKEY, () => {
invoke('menu_toggle');
});
});
const views = [
{
label: "Welcome",

View File

@ -1,13 +1,14 @@
<script>
import { getName, getVersion, getTauriVersion } from "@tauri-apps/api/app";
import { relaunch, exit } from "@tauri-apps/api/process";
let version = 0.0;
let tauriVersion = 0.0;
let appName = 'Unknown';
getName().then(n => {appName = n});
getVersion().then(v => {version = v});
getTauriVersion().then(v => {tauriVersion = v});
getName().then(n => { appName = n });
getVersion().then(v => { version = v });
getTauriVersion().then(v => { tauriVersion = v });
async function closeApp() {
await exit();

View File

@ -287,6 +287,11 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"
hotkeys-js@^3.8.5:
version "3.8.5"
resolved "https://registry.yarnpkg.com/hotkeys-js/-/hotkeys-js-3.8.5.tgz#a66030c48b75ceb2f3fc48fd39e7a0b3473a4b19"
integrity sha512-beJJ2Y4J6XkSlXlLPOG29BRKxZx3bV0gVi3eUpYdjrecN1i25iqndM/+X1eIDPSeG0XdqSv7Ksek43j5tQrmPQ==
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"

View File

@ -27,7 +27,7 @@ describe('[CLI] cli.js template', () => {
const manifestFile = readFileSync(manifestPath).toString()
writeFileSync(
manifestPath,
`workspace = { }\n[patch.crates-io]\ntao = { git = "https://github.com/tauri-apps/tao", rev = "5be88eb9488e3ad27194b5eff2ea31a473128f9c" }\n\n${manifestFile}`
`workspace = { }\n[patch.crates-io]\ntao = { git = "https://github.com/tauri-apps/tao", rev = "66360eea4ec6af8a52afcebb7700f486a0092168" }\n\n${manifestFile}`
)
const { promise: buildPromise } = await build()