Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changes/disable-input-accessory-view-ios.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@tauri-apps/api": minor:feat
"tauri-utils": minor:feat
---

Added `disableInputAccessoryView: bool` config for iOS.

6 changes: 6 additions & 0 deletions .changes/input-accessory-view-builder-runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri-runtime": minor:feat
"tauri-runtime-wry": minor:feat
---

Added `WebviewAttributes::input_accessory_view_builder` on iOS.
5 changes: 5 additions & 0 deletions .changes/input-accessory-view-builder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri": minor:feat
---

Added `WebviewWindowBuilder::with_input_accessory_view_builder` and `WebviewBuilder::with_input_accessory_view_builder` on iOS.
21 changes: 12 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions crates/tauri-cli/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,11 @@
"description": "on macOS and iOS there is a link preview on long pressing links, this is enabled by default.\n see https://docs.rs/objc2-web-kit/latest/objc2_web_kit/struct.WKWebView.html#method.allowsLinkPreview",
"default": true,
"type": "boolean"
},
"disableInputAccessoryView": {
"description": "Allows disabling the input accessory view on iOS.\n\n The accessory view is the view that appears above the keyboard when a text input element is focused.\n It usually displays a view with \"Done\", \"Next\" buttons.",
"default": false,
"type": "boolean"
}
},
"additionalProperties": false
Expand Down
2 changes: 1 addition & 1 deletion crates/tauri-runtime-wry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ rustc-args = ["--cfg", "docsrs"]
rustdoc-args = ["--cfg", "docsrs"]

[dependencies]
wry = { version = "0.51", default-features = false, features = [
wry = { version = "0.51.2", default-features = false, features = [
"drag-drop",
"protocol",
"os-webview",
Expand Down
17 changes: 13 additions & 4 deletions crates/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use tauri_runtime::{
UserAttentionType, UserEvent, WebviewDispatch, WebviewEventId, WindowDispatch, WindowEventId,
};

#[cfg(any(target_os = "macos", target_os = "ios"))]
#[cfg(target_vendor = "apple")]
use objc2::rc::Retained;
#[cfg(target_os = "macos")]
use tao::platform::macos::{EventLoopWindowTargetExtMacOS, WindowBuilderExtMacOS};
Expand All @@ -42,9 +42,11 @@ use tao::platform::windows::{WindowBuilderExtWindows, WindowExtWindows};
use webview2_com::FocusChangedEventHandler;
#[cfg(windows)]
use windows::Win32::Foundation::HWND;
#[cfg(target_os = "ios")]
use wry::WebViewBuilderExtIos;
#[cfg(windows)]
use wry::WebViewBuilderExtWindows;
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[cfg(target_vendor = "apple")]
use wry::{WebViewBuilderExtDarwin, WebViewExtDarwin};

use tao::{
Expand Down Expand Up @@ -2987,7 +2989,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
}

#[cfg(target_os = "ios")]
fn run_return<F: FnMut(RunEvent<T>) + 'static>(mut self, callback: F) -> i32 {
fn run_return<F: FnMut(RunEvent<T>) + 'static>(self, callback: F) -> i32 {
self.run(callback);
0
}
Expand Down Expand Up @@ -4627,9 +4629,16 @@ fn create_webview<T: UserEvent>(
webview_builder.with_allow_link_preview(webview_attributes.allow_link_preview);
}

#[cfg(target_os = "ios")]
{
if let Some(input_accessory_view_builder) = webview_attributes.input_accessory_view_builder {
webview_builder = webview_builder
.with_input_accessory_view_builder(move |webview| input_accessory_view_builder.0(webview));
}
}

#[cfg(target_os = "macos")]
{
use wry::WebViewBuilderExtDarwin;
if let Some(position) = &webview_attributes.traffic_light_position {
webview_builder = webview_builder.with_traffic_light_inset(*position);
}
Expand Down
7 changes: 7 additions & 0 deletions crates/tauri-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ gtk = { version = "0.18", features = ["v3_24"] }
[target."cfg(target_os = \"android\")".dependencies]
jni = "0.21"

[target.'cfg(all(target_vendor = "apple", not(target_os = "macos")))'.dependencies]
objc2 = "0.6"
objc2-ui-kit = { version = "0.3.0", default-features = false, features = [
"UIView",
"UIResponder",
] }

[target."cfg(target_os = \"macos\")".dependencies]
url = "2"

Expand Down
47 changes: 46 additions & 1 deletion crates/tauri-runtime/src/webview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ type OnPageLoadHandler = dyn Fn(Url, PageLoadEvent) + Send;

type DownloadHandler = dyn Fn(DownloadEvent) -> bool + Send + Sync;

#[cfg(target_os = "ios")]
type InputAccessoryViewBuilderFn = dyn Fn(&objc2_ui_kit::UIView) -> Option<objc2::rc::Retained<objc2_ui_kit::UIView>>
+ Send
+ Sync
+ 'static;

/// Download event.
pub enum DownloadEvent<'a> {
/// Download requested.
Expand Down Expand Up @@ -193,7 +199,7 @@ impl<T: UserEvent, R: Runtime<T>> PartialEq for DetachedWebview<T, R> {
}

/// The attributes used to create an webview.
#[derive(Debug, Clone)]
#[derive(Debug)]
pub struct WebviewAttributes {
pub url: WebviewUrl,
pub user_agent: Option<String>,
Expand Down Expand Up @@ -236,6 +242,37 @@ pub struct WebviewAttributes {
/// on macOS and iOS there is a link preview on long pressing links, this is enabled by default.
/// see https://docs.rs/objc2-web-kit/latest/objc2_web_kit/struct.WKWebView.html#method.allowsLinkPreview
pub allow_link_preview: bool,
/// Allows overriding the the keyboard accessory view on iOS.
/// Returning `None` effectively removes the view.
///
/// The closure parameter is the webview instance.
///
/// The accessory view is the view that appears above the keyboard when a text input element is focused.
/// It usually displays a view with "Done", "Next" buttons.
///
/// # Stability
///
/// This relies on [`objc2_ui_kit`] which does not provide a stable API yet, so it can receive breaking changes in minor releases.
#[cfg(target_os = "ios")]
pub input_accessory_view_builder: Option<InputAccessoryViewBuilder>,
}

#[cfg(target_os = "ios")]
#[non_exhaustive]
pub struct InputAccessoryViewBuilder(pub Box<InputAccessoryViewBuilderFn>);

#[cfg(target_os = "ios")]
impl std::fmt::Debug for InputAccessoryViewBuilder {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
f.debug_struct("InputAccessoryViewBuilder").finish()
}
}

#[cfg(target_os = "ios")]
impl InputAccessoryViewBuilder {
pub fn new(builder: Box<InputAccessoryViewBuilderFn>) -> Self {
Self(builder)
}
}

impl From<&WindowConfig> for WebviewAttributes {
Expand Down Expand Up @@ -281,6 +318,12 @@ impl From<&WindowConfig> for WebviewAttributes {
}
builder.javascript_disabled = config.javascript_disabled;
builder.allow_link_preview = config.allow_link_preview;
#[cfg(target_os = "ios")]
if config.disable_input_accessory_view {
builder
.input_accessory_view_builder
.replace(InputAccessoryViewBuilder::new(Box::new(|_webview| None)));
}
builder
}
}
Expand Down Expand Up @@ -315,6 +358,8 @@ impl WebviewAttributes {
background_throttling: None,
javascript_disabled: false,
allow_link_preview: true,
#[cfg(target_os = "ios")]
input_accessory_view_builder: None,
}
}

Expand Down
5 changes: 5 additions & 0 deletions crates/tauri-schema-generator/schemas/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,11 @@
"description": "on macOS and iOS there is a link preview on long pressing links, this is enabled by default.\n see https://docs.rs/objc2-web-kit/latest/objc2_web_kit/struct.WKWebView.html#method.allowsLinkPreview",
"default": true,
"type": "boolean"
},
"disableInputAccessoryView": {
"description": "Allows disabling the input accessory view on iOS.\n\n The accessory view is the view that appears above the keyboard when a text input element is focused.\n It usually displays a view with \"Done\", \"Next\" buttons.",
"default": false,
"type": "boolean"
}
},
"additionalProperties": false
Expand Down
15 changes: 14 additions & 1 deletion crates/tauri-utils/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1777,6 +1777,16 @@ pub struct WindowConfig {
/// see https://docs.rs/objc2-web-kit/latest/objc2_web_kit/struct.WKWebView.html#method.allowsLinkPreview
#[serde(default = "default_true", alias = "allow-link-preview")]
pub allow_link_preview: bool,
/// Allows disabling the input accessory view on iOS.
///
/// The accessory view is the view that appears above the keyboard when a text input element is focused.
/// It usually displays a view with "Done", "Next" buttons.
#[serde(
default,
alias = "disable-input-accessory-view",
alias = "disable_input_accessory_view"
)]
pub disable_input_accessory_view: bool,
}

impl Default for WindowConfig {
Expand Down Expand Up @@ -1834,6 +1844,7 @@ impl Default for WindowConfig {
background_throttling: None,
javascript_disabled: false,
allow_link_preview: true,
disable_input_accessory_view: false,
}
}
}
Expand Down Expand Up @@ -3163,6 +3174,7 @@ mod build {
let background_throttling = opt_lit(self.background_throttling.as_ref());
let javascript_disabled = self.javascript_disabled;
let allow_link_preview = self.allow_link_preview;
let disable_input_accessory_view = self.disable_input_accessory_view;

literal_struct!(
tokens,
Expand Down Expand Up @@ -3218,7 +3230,8 @@ mod build {
background_color,
background_throttling,
javascript_disabled,
allow_link_preview
allow_link_preview,
disable_input_accessory_view
);
}
}
Expand Down
8 changes: 7 additions & 1 deletion crates/tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,14 @@ tray-icon = { version = "0.20", default-features = false, features = [
gtk = { version = "0.18", features = ["v3_24"] }
webkit2gtk = { version = "=2.0.1", features = ["v2_40"], optional = true }

# darwin
[target.'cfg(target_vendor = "apple")'.dependencies]
objc2 = "0.6"

# macOS
[target.'cfg(target_os = "macos")'.dependencies]
embed_plist = "1.2"
plist = "1"
objc2 = "0.6"
objc2-foundation = { version = "0.3", default-features = false, features = [
"std",
"NSData",
Expand Down Expand Up @@ -145,6 +148,9 @@ jni = "0.21"
[target.'cfg(all(target_vendor = "apple", not(target_os = "macos")))'.dependencies]
libc = "0.2"
swift-rs = "1"
objc2-ui-kit = { version = "0.3.0", default-features = false, features = [
"UIView",
] }

[build-dependencies]
glob = "0.3"
Expand Down
4 changes: 0 additions & 4 deletions crates/tauri/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,6 @@ impl<R: Runtime> AppHandle<R> {
///
/// Needs to be called from Main Thread
pub async fn fetch_data_store_identifiers(&self) -> crate::Result<Vec<[u8; 16]>> {
use std::sync::Mutex;

let (tx, rx) = tokio::sync::oneshot::channel::<Result<Vec<[u8; 16]>, tauri_runtime::Error>>();
let lock: Arc<Mutex<Option<_>>> = Arc::new(Mutex::new(Some(tx)));
let runtime_handle = self.runtime_handle.clone();
Expand All @@ -415,8 +413,6 @@ impl<R: Runtime> AppHandle<R> {
///
/// Needs to be called from Main Thread
pub async fn remove_data_store(&self, uuid: [u8; 16]) -> crate::Result<()> {
use std::sync::Mutex;

let (tx, rx) = tokio::sync::oneshot::channel::<Result<(), tauri_runtime::Error>>();
let lock: Arc<Mutex<Option<_>>> = Arc::new(Mutex::new(Some(tx)));
let runtime_handle = self.runtime_handle.clone();
Expand Down
Loading