feat: add Linux permission handling for media access and configure main window in tauri.conf.json
All checks were successful
Build / check-version (push) Successful in 5s
Build / build-linux (push) Successful in 8m58s
Build / build-windows (push) Successful in 9m17s
Build / build-android (push) Successful in 12m35s
Build / create-release (push) Has been skipped

- Implemented automatic permission handling for microphone and camera access on Linux using webkit2gtk.
- Updated tauri.conf.json to define the main application window with specific dimensions and properties.
This commit is contained in:
2026-02-05 04:57:45 +11:00
parent 4b185556f8
commit 89b0da0854
6 changed files with 72 additions and 2 deletions

2
src-tauri/Cargo.lock generated
View File

@@ -2681,6 +2681,7 @@ version = "4.10.2"
dependencies = [ dependencies = [
"arboard", "arboard",
"base64 0.22.1", "base64 0.22.1",
"gtk",
"open", "open",
"png 0.17.16", "png 0.17.16",
"ppv-lite86", "ppv-lite86",
@@ -2696,6 +2697,7 @@ dependencies = [
"tauri-plugin-single-instance", "tauri-plugin-single-instance",
"tauri-plugin-updater", "tauri-plugin-updater",
"tauri-plugin-window-state", "tauri-plugin-window-state",
"webkit2gtk",
] ]
[[package]] [[package]]

View File

@@ -29,6 +29,8 @@ tauri-plugin-notification = "2"
arboard = { version = "3", features = ["wayland-data-control"] } arboard = { version = "3", features = ["wayland-data-control"] }
png = "0.17" png = "0.17"
base64 = "0.22" base64 = "0.22"
webkit2gtk = "2.0"
gtk = "0.18"
[target."cfg(any(target_os = \"android\", target_os = \"ios\"))".dependencies] [target."cfg(any(target_os = \"android\", target_os = \"ios\"))".dependencies]
tauri-plugin-deep-link = "2" tauri-plugin-deep-link = "2"

View File

@@ -10,6 +10,16 @@
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" android:maxSdkVersion="32" /> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.USE_EXACT_ALARM" /> <uses-permission android:name="android.permission.USE_EXACT_ALARM" />
<!-- Audio/Video call permissions -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.CAMERA" />
<!-- Hardware features for calls (optional) -->
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.microphone" android:required="false" />
<!-- AndroidTV support --> <!-- AndroidTV support -->
<uses-feature android:name="android.software.leanback" android:required="false" /> <uses-feature android:name="android.software.leanback" android:required="false" />

File diff suppressed because one or more lines are too long

View File

@@ -13,6 +13,12 @@ use tauri::{
WindowEvent, WindowEvent,
}; };
// Linux: Import for permission handling
#[cfg(target_os = "linux")]
use webkit2gtk::{PermissionRequestExt, WebViewExt};
#[cfg(target_os = "linux")]
use gtk::prelude::*;
/// Read image from clipboard on Linux using arboard with Wayland support /// Read image from clipboard on Linux using arboard with Wayland support
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
#[tauri::command] #[tauri::command]
@@ -116,6 +122,35 @@ pub fn run() {
}) })
.build()?; .build()?;
// Linux: Set up permission handler to auto-allow microphone/camera access
#[cfg(target_os = "linux")]
{
if let Some(webview_window) = app.get_webview_window("main") {
let _ = webview_window.with_webview(|webview| {
use webkit2gtk::UserMediaPermissionRequestExt;
let wv = webview.inner();
wv.connect_permission_request(|_webview, permission_request| {
// Check if this is a user media (microphone/camera) permission request
if let Some(user_media_request) = permission_request.downcast_ref::<webkit2gtk::UserMediaPermissionRequest>() {
// Log what's being requested
let is_audio = user_media_request.is_for_audio_device();
let is_video = user_media_request.is_for_video_device();
eprintln!("Paarrot: Media permission request - audio: {}, video: {}", is_audio, is_video);
// Allow the request
permission_request.allow();
return true;
}
// For other permission types, allow by default
permission_request.allow();
true
});
});
}
}
// Create system tray // Create system tray
let show_item = MenuItem::with_id(app, "show", "Show Paarrot", true, None::<&str>)?; let show_item = MenuItem::with_id(app, "show", "Show Paarrot", true, None::<&str>)?;
let quit_item = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?; let quit_item = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
@@ -171,10 +206,19 @@ pub fn run() {
#[cfg(any(target_os = "android", target_os = "ios"))] #[cfg(any(target_os = "android", target_os = "ios"))]
{ {
use tauri::{WebviewUrl, webview::WebviewWindowBuilder};
tauri::Builder::default() tauri::Builder::default()
.plugin(tauri_plugin_opener::init()) .plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_notification::init()) .plugin(tauri_plugin_notification::init())
.plugin(tauri_plugin_deep_link::init()) .plugin(tauri_plugin_deep_link::init())
.setup(|app| {
// Create the main window for mobile
// Mobile uses the bundled assets directly, not localhost
WebviewWindowBuilder::new(app, "main", WebviewUrl::default())
.build()?;
Ok(())
})
.invoke_handler(tauri::generate_handler![read_clipboard_image]) .invoke_handler(tauri::generate_handler![read_clipboard_image])
.run(tauri::generate_context!()) .run(tauri::generate_context!())
.expect("error while building tauri application"); .expect("error while building tauri application");

View File

@@ -11,7 +11,19 @@
}, },
"app": { "app": {
"withGlobalTauri": true, "withGlobalTauri": true,
"windows": [], "windows": [
{
"label": "main",
"title": "Paarrot",
"width": 1200,
"height": 800,
"minWidth": 480,
"minHeight": 480,
"resizable": true,
"fullscreen": false,
"create": false
}
],
"security": { "security": {
"csp": "script-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'; img-src 'self' https: http: data: blob:" "csp": "script-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'; img-src 'self' https: http: data: blob:"
} }