fix(windows): use webview2_com built-in handler instead of #[implement]
The previous approach used windows::core::implement to manually implement ICoreWebView2PermissionRequestedEventHandler_Impl, but the sealed IUnknownImpl constraint in webview2-com prevents external #[implement] usage — you must use the crate's own pre-built handler types. Replace with PermissionRequestedEventHandler::create() which wraps the closure and handles COM ref-counting internally. Also removes the now- unused windows = "0.61" direct dependency. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -44,7 +44,6 @@ tauri-plugin-updater = "2"
|
|||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
webview2-com = "0.38"
|
webview2-com = "0.38"
|
||||||
windows = { version = "0.61", features = [] }
|
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "app_lib"
|
name = "app_lib"
|
||||||
|
|||||||
+27
-44
@@ -3,46 +3,9 @@
|
|||||||
windows_subsystem = "windows"
|
windows_subsystem = "windows"
|
||||||
)]
|
)]
|
||||||
|
|
||||||
// mod menu;
|
|
||||||
|
|
||||||
use tauri::{webview::{NewWindowResponse, WebviewWindowBuilder}, WebviewUrl};
|
use tauri::{webview::{NewWindowResponse, WebviewWindowBuilder}, WebviewUrl};
|
||||||
use tauri_plugin_opener::OpenerExt;
|
use tauri_plugin_opener::OpenerExt;
|
||||||
|
|
||||||
// Automatically grant camera and microphone permissions in WebView2 (Windows).
|
|
||||||
// macOS handles this via Info.plist; Windows requires an explicit PermissionRequested handler.
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
mod win_permissions {
|
|
||||||
use webview2_com::Microsoft::Web::WebView2::Win32::{
|
|
||||||
ICoreWebView2, ICoreWebView2PermissionRequestedEventArgs,
|
|
||||||
ICoreWebView2PermissionRequestedEventHandler,
|
|
||||||
ICoreWebView2PermissionRequestedEventHandler_Impl,
|
|
||||||
COREWEBVIEW2_PERMISSION_KIND_CAMERA, COREWEBVIEW2_PERMISSION_KIND_MICROPHONE,
|
|
||||||
COREWEBVIEW2_PERMISSION_STATE_ALLOW,
|
|
||||||
};
|
|
||||||
use windows::core::implement;
|
|
||||||
|
|
||||||
#[implement(ICoreWebView2PermissionRequestedEventHandler)]
|
|
||||||
pub struct PermissionHandler;
|
|
||||||
|
|
||||||
impl ICoreWebView2PermissionRequestedEventHandler_Impl for PermissionHandler {
|
|
||||||
fn Invoke(
|
|
||||||
&self,
|
|
||||||
_sender: Option<&ICoreWebView2>,
|
|
||||||
args: Option<&ICoreWebView2PermissionRequestedEventArgs>,
|
|
||||||
) -> windows::core::Result<()> {
|
|
||||||
if let Some(args) = args {
|
|
||||||
let kind = unsafe { args.PermissionKind() }?;
|
|
||||||
if kind == COREWEBVIEW2_PERMISSION_KIND_MICROPHONE
|
|
||||||
|| kind == COREWEBVIEW2_PERMISSION_KIND_CAMERA
|
|
||||||
{
|
|
||||||
unsafe { args.SetState(COREWEBVIEW2_PERMISSION_STATE_ALLOW) }?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
let port: u16 = 44548;
|
let port: u16 = 44548;
|
||||||
let context = tauri::generate_context!();
|
let context = tauri::generate_context!();
|
||||||
@@ -71,19 +34,39 @@ pub fn run() {
|
|||||||
NewWindowResponse::Deny
|
NewWindowResponse::Deny
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Grant camera and microphone to WebView2 automatically.
|
||||||
|
// Windows requires an explicit PermissionRequested COM event handler;
|
||||||
|
// macOS uses Info.plist.
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let builder = builder.with_webview(|webview| {
|
let builder = builder.with_webview(|webview| {
|
||||||
use webview2_com::Microsoft::Web::WebView2::Win32::ICoreWebView2PermissionRequestedEventHandler;
|
use webview2_com::{
|
||||||
use windows::core::EventRegistrationToken;
|
Microsoft::Web::WebView2::Win32::{
|
||||||
use win_permissions::PermissionHandler;
|
COREWEBVIEW2_PERMISSION_KIND_CAMERA,
|
||||||
|
COREWEBVIEW2_PERMISSION_KIND_MICROPHONE,
|
||||||
|
COREWEBVIEW2_PERMISSION_STATE_ALLOW,
|
||||||
|
},
|
||||||
|
PermissionRequestedEventHandler,
|
||||||
|
};
|
||||||
|
|
||||||
let controller = webview.controller();
|
let controller = webview.controller();
|
||||||
if let Ok(core) = unsafe { controller.CoreWebView2() } {
|
if let Ok(core) = unsafe { controller.CoreWebView2() } {
|
||||||
let handler: ICoreWebView2PermissionRequestedEventHandler =
|
let handler = PermissionRequestedEventHandler::create(Box::new(
|
||||||
PermissionHandler.into();
|
|_sender, args| {
|
||||||
let mut token = EventRegistrationToken(0);
|
if let Some(args) = args {
|
||||||
|
let kind = unsafe { args.PermissionKind() }?;
|
||||||
|
if kind == COREWEBVIEW2_PERMISSION_KIND_MICROPHONE
|
||||||
|
|| kind == COREWEBVIEW2_PERMISSION_KIND_CAMERA
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
args.SetState(COREWEBVIEW2_PERMISSION_STATE_ALLOW)
|
||||||
|
}?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
));
|
||||||
|
let mut token = Default::default();
|
||||||
let _ = unsafe { core.add_PermissionRequested(&handler, &mut token) };
|
let _ = unsafe { core.add_PermissionRequested(&handler, &mut token) };
|
||||||
std::mem::forget(handler);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user