Skip to content

feat(linux): implement custom user data path #188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 22, 2021
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
5 changes: 5 additions & 0 deletions .changes/linux-user-data-path.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wry": patch
---

The `data_directory` field now affects the IndexedDB and LocalStorage directories on Linux.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ tauri-winit = "0.24"
[target."cfg(target_os = \"linux\")".dependencies]
bitflags = "1.2"
cairo-rs = "0.9"
webkit2gtk = { version = "0.11", features = [ "v2_8" ] }
webkit2gtk = { version = "0.11", features = [ "v2_10" ] }
gio = "0.9"
glib = "0.10"
gtk = "0.9"
Expand Down
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ Run the `cargo run --example <file_name>` to see how each example works.
- `multi_window`: create the window dynamically even after the application is running.
- `dragndrop`: example for file drop handler.
- `custom_titlebar`: A frameless window with custom title-bar to show `drag-region` class in action.
- `custom_user_data`: uses a custom data directory (Windows only).
- `custom_data_directory`: uses a custom data directory (Windows and Linux only).
- `custom_protocol`: uses a custom protocol to load files from bytes.
- `detect_js_ecma`: detects which versions of ECMAScript is supported by the webview.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn main() -> wry::Result<()> {
let _webview = WebViewBuilder::new(window)
.unwrap()
.with_url("https://tauri.studio")?
.user_data_path(Some(test_path))
.with_data_directory(test_path)
.build()?;

event_loop.run(move |event, _, control_flow| {
Expand Down
29 changes: 25 additions & 4 deletions src/webview/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ use gtk::{ContainerExt, WidgetExt};
use url::Url;
use webkit2gtk::{
SecurityManagerExt, SettingsExt, URISchemeRequestExt, UserContentInjectedFrames,
UserContentManager, UserContentManagerExt, UserScript, UserScriptInjectionTime, WebContext,
WebContextExt, WebView, WebViewExt, WebViewExtManual,
UserContentManager, UserContentManagerExt, UserScript, UserScriptInjectionTime,
WebContextBuilder, WebContextExt, WebView, WebViewExt, WebViewExtManual,
WebsiteDataManagerBuilder,
};

use crate::{
Expand All @@ -39,13 +40,33 @@ impl InnerWebView {
)>,
rpc_handler: Option<Box<dyn Fn(&Window, RpcRequest) -> Option<RpcResponse>>>,
file_drop_handler: Option<Box<dyn Fn(&Window, FileDropEvent) -> bool>>,
_user_data_path: Option<PathBuf>,
data_directory: Option<PathBuf>,
) -> Result<Self> {
let window_rc = Rc::clone(&window);
let window = &window.window;
// Webview widget
let manager = UserContentManager::new();
let context = WebContext::new();
let mut context_builder = WebContextBuilder::new();
if let Some(data_directory) = data_directory {
let data_manager = WebsiteDataManagerBuilder::new()
.local_storage_directory(
&data_directory
.join("localstorage")
.to_string_lossy()
.into_owned(),
)
.indexeddb_directory(
&data_directory
.join("databases")
.join("indexeddb")
.to_string_lossy()
.into_owned(),
)
.build();
context_builder = context_builder.website_data_manager(&data_manager);
}
let context = context_builder.build();

let webview = Rc::new(WebView::new_with_context_and_user_content_manager(
&context, &manager,
));
Expand Down
2 changes: 1 addition & 1 deletion src/webview/macos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl InnerWebView {
)>,
rpc_handler: Option<Box<dyn Fn(&Window, RpcRequest) -> Option<RpcResponse>>>,
file_drop_handler: Option<Box<dyn Fn(&Window, FileDropEvent) -> bool>>,
_user_data_path: Option<PathBuf>,
_data_directory: Option<PathBuf>,
) -> Result<Self> {
// Function for rpc handler
extern "C" fn did_receive(this: &Object, _: Sel, _: id, msg: id) {
Expand Down
10 changes: 5 additions & 5 deletions src/webview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub struct WebViewBuilder {
custom_protocols: Vec<(String, Box<dyn Fn(&Window, &str) -> Result<Vec<u8>>>)>,
rpc_handler: Option<Box<dyn Fn(&Window, RpcRequest) -> Option<RpcResponse>>>,
file_drop_handler: Option<Box<dyn Fn(&Window, FileDropEvent) -> bool>>,
user_data_path: Option<PathBuf>,
data_directory: Option<PathBuf>,
}

impl WebViewBuilder {
Expand All @@ -116,7 +116,7 @@ impl WebViewBuilder {
custom_protocols: vec![],
rpc_handler: None,
file_drop_handler: None,
user_data_path: None,
data_directory: None,
})
}

Expand All @@ -137,8 +137,8 @@ impl WebViewBuilder {

/// Whether the WebView window should have a custom user data path. This is usefull in Windows
/// when a bundled application can't have the webview data inside `Program Files`.
pub fn user_data_path(mut self, user_data_path: Option<PathBuf>) -> Self {
self.user_data_path = user_data_path;
pub fn with_data_directory(mut self, data_directory: PathBuf) -> Self {
self.data_directory.replace(data_directory);
self
}

Expand Down Expand Up @@ -261,7 +261,7 @@ impl WebViewBuilder {
self.custom_protocols,
self.rpc_handler,
self.file_drop_handler,
self.user_data_path,
self.data_directory,
)?;
Ok(WebView {
window,
Expand Down
11 changes: 5 additions & 6 deletions src/webview/win32/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl InnerWebView {
)>,
rpc_handler: Option<Box<dyn Fn(&Window, RpcRequest) -> Option<RpcResponse>>>,
file_drop_handler: Option<Box<dyn Fn(&Window, FileDropEvent) -> bool>>,
user_data_path: Option<PathBuf>,
data_directory: Option<PathBuf>,
) -> Result<Self> {
let hwnd = window.hwnd() as HWND;

Expand All @@ -54,13 +54,12 @@ impl InnerWebView {
let file_drop_controller_clone = file_drop_controller.clone();

let webview_builder: webview2::EnvironmentBuilder;
let user_data_path_provided: PathBuf;
let data_directory_provided: PathBuf;

if user_data_path.is_some() {
// Safe to unwrap since this is already checked.
user_data_path_provided = user_data_path.unwrap();
if let Some(data_directory) = data_directory {
data_directory_provided = data_directory;
webview_builder =
webview2::EnvironmentBuilder::new().with_user_data_folder(&user_data_path_provided);
webview2::EnvironmentBuilder::new().with_user_data_folder(&data_directory_provided);
} else {
webview_builder = webview2::EnvironmentBuilder::new();
}
Expand Down
8 changes: 4 additions & 4 deletions src/webview/winrt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,18 @@ impl InnerWebView {
)>,
rpc_handler: Option<Box<dyn Fn(&Window, RpcRequest) -> Option<RpcResponse>>>,
file_drop_handler: Option<Box<dyn Fn(&Window, FileDropEvent) -> bool>>,
user_data_path: Option<PathBuf>,
data_directory: Option<PathBuf>,
) -> Result<Self> {
let hwnd = HWND(window.hwnd() as _);

let controller_rc: Rc<OnceCell<webview2::CoreWebView2Controller>> = Rc::new(OnceCell::new());
let webview_rc: Rc<OnceCell<webview2::CoreWebView2>> = Rc::new(OnceCell::new());
let file_drop_controller_rc: Rc<OnceCell<FileDropController>> = Rc::new(OnceCell::new());

let env = wait_for_async_operation(match user_data_path {
Some(user_data_path_provided) => webview2::CoreWebView2Environment::CreateWithOptionsAsync(
let env = wait_for_async_operation(match data_directory {
Some(data_directory_provided) => webview2::CoreWebView2Environment::CreateWithOptionsAsync(
"",
user_data_path_provided.to_str().unwrap_or(""),
data_directory_provided.to_str().unwrap_or(""),
webview2::CoreWebView2EnvironmentOptions::new()?,
)?,
None => webview2::CoreWebView2Environment::CreateAsync()?,
Expand Down