Skip to content

Commit 6ac21b3

Browse files
committed
feat: add private api feature flag (#7)
1 parent cf54dcf commit 6ac21b3

File tree

17 files changed

+366
-157
lines changed

17 files changed

+366
-157
lines changed

.changes/private-api.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri": patch
3+
"tauri-runtime-wry": patch
4+
"cli.rs": patch
5+
---
6+
7+
Add `macos-private-api` feature flag, enabled via `tauri.conf.json > tauri > macOSPrivateApi`.

core/tauri-runtime-wry/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ readme = "README.md"
1414

1515
[dependencies]
1616
#wry = { version = "0.12", default-features = false, features = [ "file-drop", "protocol" ] }
17-
wry = { git = "https://github.com/tauri-apps/wry", rev = "3284f8d442978269f7654edbdfc9bc51022eaa40", default-features = false, features = [ "file-drop", "protocol", "transparent", "fullscreen" ] }
17+
wry = { git = "https://github.com/tauri-sec/wry", branch = "next", default-features = false, features = [ "file-drop", "protocol" ] }
1818
tauri-runtime = { version = "0.2.1", path = "../tauri-runtime" }
1919
tauri-utils = { version = "1.0.0-beta.3", path = "../tauri-utils" }
2020
uuid = { version = "0.8.2", features = [ "v4" ] }
@@ -45,3 +45,4 @@ gtk = { version = "0.14", features = [ "v3_20" ] }
4545
dox = [ "wry/dox" ]
4646
system-tray = [ "wry/tray", "tauri-runtime/system-tray" ]
4747
egui = ["epi", "egui-tao", "egui_glow", "tao-glutin", "glow", "once_cell"]
48+
macos-private-api = [ "wry/fullscreen", "wry/transparent", "tauri-runtime/macos-private-api" ]

core/tauri-runtime-wry/src/lib.rs

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ use tauri_runtime::{
1111
},
1212
menu::{CustomMenuItem, Menu, MenuEntry, MenuHash, MenuId, MenuItem, MenuUpdate},
1313
monitor::Monitor,
14-
webview::{
15-
FileDropEvent, FileDropHandler, RpcRequest, WebviewRpcHandler, WindowBuilder, WindowBuilderBase,
16-
},
14+
webview::{FileDropEvent, FileDropHandler, WebviewIpcHandler, WindowBuilder, WindowBuilderBase},
1715
window::{
1816
dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size},
1917
DetachedWindow, PendingWindow, WindowEvent,
@@ -68,10 +66,7 @@ use wry::{
6866
Request as WryHttpRequest, RequestParts as WryRequestParts, Response as WryHttpResponse,
6967
ResponseParts as WryResponseParts,
7068
},
71-
webview::{
72-
FileDropEvent as WryFileDropEvent, RpcRequest as WryRpcRequest, RpcResponse, WebContext,
73-
WebView, WebViewBuilder,
74-
},
69+
webview::{FileDropEvent as WryFileDropEvent, WebContext, WebView, WebViewBuilder},
7570
};
7671

7772
pub use wry::application::window::{Window, WindowBuilder as WryWindowBuilder, WindowId};
@@ -738,13 +733,17 @@ impl WindowBuilder for WindowBuilderWrapper {
738733
.inner_size(config.width, config.height)
739734
.visible(config.visible)
740735
.resizable(config.resizable)
736+
.fullscreen(config.fullscreen)
741737
.decorations(config.decorations)
742738
.maximized(config.maximized)
743-
.fullscreen(config.fullscreen)
744-
.transparent(config.transparent)
745739
.always_on_top(config.always_on_top)
746740
.skip_taskbar(config.skip_taskbar);
747741

742+
#[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))]
743+
{
744+
window = window.transparent(config.transparent);
745+
}
746+
748747
if let (Some(min_width), Some(min_height)) = (config.min_width, config.min_height) {
749748
window = window.min_inner_size(min_width, min_height);
750749
}
@@ -835,6 +834,7 @@ impl WindowBuilder for WindowBuilderWrapper {
835834
self
836835
}
837836

837+
#[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))]
838838
fn transparent(mut self, transparent: bool) -> Self {
839839
self.inner = self.inner.with_transparent(transparent);
840840
self
@@ -889,17 +889,6 @@ impl WindowBuilder for WindowBuilderWrapper {
889889
}
890890
}
891891

892-
pub struct RpcRequestWrapper(WryRpcRequest);
893-
894-
impl From<RpcRequestWrapper> for RpcRequest {
895-
fn from(request: RpcRequestWrapper) -> Self {
896-
Self {
897-
command: request.0.method,
898-
params: request.0.params,
899-
}
900-
}
901-
}
902-
903892
pub struct FileDropEventWrapper(WryFileDropEvent);
904893

905894
impl From<FileDropEventWrapper> for FileDropEvent {
@@ -3066,7 +3055,7 @@ fn create_webview(
30663055
webview_attributes,
30673056
uri_scheme_protocols,
30683057
mut window_builder,
3069-
rpc_handler,
3058+
ipc_handler,
30703059
file_drop_handler,
30713060
label,
30723061
url,
@@ -3106,8 +3095,8 @@ fn create_webview(
31063095
.with_url(&url)
31073096
.unwrap() // safe to unwrap because we validate the URL beforehand
31083097
.with_transparent(is_window_transparent);
3109-
if let Some(handler) = rpc_handler {
3110-
webview_builder = webview_builder.with_rpc_handler(create_rpc_handler(
3098+
if let Some(handler) = ipc_handler {
3099+
webview_builder = webview_builder.with_ipc_handler(create_ipc_handler(
31113100
context.clone(),
31123101
label.clone(),
31133102
menu_ids.clone(),
@@ -3172,14 +3161,14 @@ fn create_webview(
31723161
})
31733162
}
31743163

3175-
/// Create a wry rpc handler from a tauri rpc handler.
3176-
fn create_rpc_handler(
3164+
/// Create a wry ipc handler from a tauri ipc handler.
3165+
fn create_ipc_handler(
31773166
context: Context,
31783167
label: String,
31793168
menu_ids: Arc<Mutex<HashMap<MenuHash, MenuId>>>,
31803169
js_event_listeners: Arc<Mutex<HashMap<String, HashSet<u64>>>>,
3181-
handler: WebviewRpcHandler<Wry>,
3182-
) -> Box<dyn Fn(&Window, WryRpcRequest) -> Option<RpcResponse> + 'static> {
3170+
handler: WebviewIpcHandler<Wry>,
3171+
) -> Box<dyn Fn(&Window, String) + 'static> {
31833172
Box::new(move |window, request| {
31843173
handler(
31853174
DetachedWindow {
@@ -3191,9 +3180,8 @@ fn create_rpc_handler(
31913180
menu_ids: menu_ids.clone(),
31923181
js_event_listeners: js_event_listeners.clone(),
31933182
},
3194-
RpcRequestWrapper(request).into(),
3183+
request,
31953184
);
3196-
None
31973185
})
31983186
}
31993187

core/tauri-runtime/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,4 @@ gtk = { version = "0.14", features = [ "v3_20" ] }
4646

4747
[features]
4848
system-tray = [ ]
49+
macos-private-api = [ ]

core/tauri-runtime/src/webview.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ pub trait WindowBuilder: WindowBuilderBase {
120120

121121
/// Whether the the window should be transparent. If this is true, writing colors
122122
/// with alpha values different than `1.0` will produce a transparent window.
123+
#[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))]
124+
#[cfg_attr(
125+
doc_cfg,
126+
doc(cfg(any(not(target_os = "macos"), feature = "macos-private-api")))
127+
)]
123128
fn transparent(self, transparent: bool) -> Self;
124129

125130
/// Whether the window should have borders and bars.
@@ -160,15 +165,6 @@ pub trait WindowBuilder: WindowBuilderBase {
160165
fn get_menu(&self) -> Option<&Menu>;
161166
}
162167

163-
/// Rpc request.
164-
#[derive(Debug)]
165-
pub struct RpcRequest {
166-
/// RPC command.
167-
pub command: String,
168-
/// Params.
169-
pub params: Option<JsonValue>,
170-
}
171-
172168
/// The file drop event payload.
173169
#[derive(Debug, Clone)]
174170
#[non_exhaustive]
@@ -181,15 +177,16 @@ pub enum FileDropEvent {
181177
Cancelled,
182178
}
183179

184-
/// Rpc handler.
185-
pub type WebviewRpcHandler<R> = Box<dyn Fn(DetachedWindow<R>, RpcRequest) + Send>;
180+
/// IPC handler.
181+
pub type WebviewIpcHandler<R> = Box<dyn Fn(DetachedWindow<R>, String) + Send>;
186182

187183
/// File drop handler callback
188184
/// Return `true` in the callback to block the OS' default behavior of handling a file drop.
189185
pub type FileDropHandler<R> = Box<dyn Fn(FileDropEvent, DetachedWindow<R>) -> bool + Send>;
190186

191187
#[derive(Debug, Deserialize)]
192188
pub struct InvokePayload {
189+
pub command: String,
193190
#[serde(rename = "__tauriModule")]
194191
pub tauri_module: Option<String>,
195192
pub callback: String,

core/tauri-runtime/src/window.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use crate::{
88
http::{Request as HttpRequest, Response as HttpResponse},
99
menu::{Menu, MenuEntry, MenuHash, MenuId},
10-
webview::{FileDropHandler, WebviewAttributes, WebviewRpcHandler},
10+
webview::{FileDropHandler, WebviewAttributes, WebviewIpcHandler},
1111
Dispatch, Runtime, WindowBuilder,
1212
};
1313
use serde::Serialize;
@@ -93,8 +93,8 @@ pub struct PendingWindow<R: Runtime> {
9393

9494
pub uri_scheme_protocols: HashMap<String, Box<UriSchemeProtocol>>,
9595

96-
/// How to handle RPC calls on the webview window.
97-
pub rpc_handler: Option<WebviewRpcHandler<R>>,
96+
/// How to handle IPC calls on the webview window.
97+
pub ipc_handler: Option<WebviewIpcHandler<R>>,
9898

9999
/// How to handle a file dropping onto the webview window.
100100
pub file_drop_handler: Option<FileDropHandler<R>>,
@@ -125,7 +125,7 @@ impl<R: Runtime> PendingWindow<R> {
125125
webview_attributes,
126126
uri_scheme_protocols: Default::default(),
127127
label: label.into(),
128-
rpc_handler: None,
128+
ipc_handler: None,
129129
file_drop_handler: None,
130130
url: "tauri://localhost".to_string(),
131131
menu_ids: Arc::new(Mutex::new(menu_ids)),
@@ -149,7 +149,7 @@ impl<R: Runtime> PendingWindow<R> {
149149
webview_attributes,
150150
uri_scheme_protocols: Default::default(),
151151
label: label.into(),
152-
rpc_handler: None,
152+
ipc_handler: None,
153153
file_drop_handler: None,
154154
url: "tauri://localhost".to_string(),
155155
menu_ids: Arc::new(Mutex::new(menu_ids)),

core/tauri-utils/src/config.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,9 @@ pub struct WindowConfig {
448448
#[serde(default = "default_focus")]
449449
pub focus: bool,
450450
/// Whether the window is transparent or not.
451+
///
452+
/// Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri.conf.json > tauri > macosPrivateApi`.
453+
/// WARNING: Using private APIs on `macOS` prevents your application from being accepted for the `App Store`.
451454
#[serde(default)]
452455
pub transparent: bool,
453456
/// Whether the window is maximized or not.
@@ -900,6 +903,9 @@ pub struct TauriConfig {
900903
pub updater: UpdaterConfig,
901904
/// Configuration for app system tray.
902905
pub system_tray: Option<SystemTrayConfig>,
906+
/// MacOS private API configuration. Enables the transparent background API and sets the `fullScreenEnabled` preference to `true`.
907+
#[serde(rename = "macOSPrivateApi", default)]
908+
pub macos_private_api: bool,
903909
}
904910

905911
impl Default for TauriConfig {
@@ -912,6 +918,7 @@ impl Default for TauriConfig {
912918
security: SecurityConfig::default(),
913919
updater: UpdaterConfig::default(),
914920
system_tray: None,
921+
macos_private_api: false,
915922
}
916923
}
917924
}
@@ -930,6 +937,9 @@ impl TauriConfig {
930937
if self.system_tray.is_some() {
931938
features.push("system-tray");
932939
}
940+
if self.macos_private_api {
941+
features.push("macos-private-api");
942+
}
933943
features.sort_unstable();
934944
features
935945
}
@@ -1615,6 +1625,7 @@ mod build {
16151625
let security = &self.security;
16161626
let system_tray = opt_lit(self.system_tray.as_ref());
16171627
let allowlist = quote!(Default::default());
1628+
let macos_private_api = self.macos_private_api;
16181629

16191630
literal_struct!(
16201631
tokens,
@@ -1625,7 +1636,8 @@ mod build {
16251636
updater,
16261637
security,
16271638
system_tray,
1628-
allowlist
1639+
allowlist,
1640+
macos_private_api
16291641
);
16301642
}
16311643
}
@@ -1741,6 +1753,7 @@ mod test {
17411753
},
17421754
allowlist: AllowlistConfig::default(),
17431755
system_tray: None,
1756+
macos_private_api: false,
17441757
};
17451758

17461759
// create a build config

core/tauri/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ api-all = [
115115
]
116116
updater = [ "minisign-verify", "base64" ]
117117
system-tray = [ "tauri-runtime/system-tray", "tauri-runtime-wry/system-tray" ]
118+
macos-private-api = [ "tauri-runtime/macos-private-api", "tauri-runtime-wry/macos-private-api" ]
118119
reqwest-client = [ "reqwest", "bytes" ]
119120
fs-all = [ "fs-write-binary-file" ]
120121
fs-read-text-file = [ ]

core/tauri/src/app.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ impl<R: Runtime> Builder<R> {
657657
invoke_handler: Box::new(|_| ()),
658658
invoke_responder: Arc::new(window_invoke_responder),
659659
invoke_initialization_script:
660-
"Object.defineProperty(window, '__TAURI_POST_MESSAGE__', { value: (cmd, args) => window.rpc.notify(cmd, args) })".into(),
660+
"Object.defineProperty(window, '__TAURI_POST_MESSAGE__', { value: (command, args) => window.ipc.notify(JSON.stringify({{ ...args, command }})) })".into(),
661661
on_page_load: Box::new(|_, _| ()),
662662
pending_windows: Default::default(),
663663
plugins: PluginStore::default(),

core/tauri/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
//! - **reqwest-client**: Uses `reqwest` as HTTP client on the `http` APIs. Improves performance, but increases the bundle size.
1515
//! - **cli**: Enables usage of `clap` for CLI argument parsing. Enabled by default if the `cli` config is defined on the `tauri.conf.json` file.
1616
//! - **system-tray**: Enables application system tray API. Enabled by default if the `systemTray` config is defined on the `tauri.conf.json` file.
17+
//! - **macos-private-api**: Enables features only available in **macOS**'s private APIs, currently the `transparent` window functionality and the `fullScreenEnabled` preference setting to `true`. Enabled by default if the `tauri > macosPrivateApi` config flag is set to `true` on the `tauri.conf.json` file.
1718
//! - **updater**: Enables the application auto updater. Enabled by default if the `updater` config is defined on the `tauri.conf.json` file.
1819
//! - **egui**: Enables method to create a native egui window. This can be used for creating native
1920
//! OpenGL contexts or [egui](https://github.com/emilk/egui) widgets.

0 commit comments

Comments
 (0)