Skip to content

feat: add permission handler API for WebView2#1654

Open
F0RLE wants to merge 7 commits intotauri-apps:devfrom
F0RLE:feat/permission-handler
Open

feat: add permission handler API for WebView2#1654
F0RLE wants to merge 7 commits intotauri-apps:devfrom
F0RLE:feat/permission-handler

Conversation

@F0RLE
Copy link

@F0RLE F0RLE commented Jan 9, 2026

This adds a new with_permission_handler method to WebViewBuilder that allows applications to intercept and handle permission requests from the webview.

New types:

  • PermissionKind - enum for permission types (Microphone, Camera, Geolocation, etc.)
  • PermissionResponse - enum for responses (Allow, Deny, Default)

Platform support:

  • Windows: Fully implemented via WebView2's PermissionRequested event
  • macOS / iOS: Fully implemented via WKUIDelegate's requestMediaCapturePermission
  • Linux: Fully implemented via WebKitGTK's permission-request signal
  • Android: Not yet implemented (handler is ignored)

Example usage:

WebViewBuilder::new()
    .with_permission_handler(|kind| {
        match kind {
            PermissionKind::Microphone => PermissionResponse::Allow,
            PermissionKind::Camera => PermissionResponse::Allow,
            _ => PermissionResponse::Default,
        }
    })

This adds a new with_permission_handler method to WebViewBuilder that allows
applications to intercept and handle permission requests from the webview.

New types:
- PermissionKind - enum for permission types (Microphone, Camera, Geolocation, etc.)
- PermissionResponse - enum for responses (Allow, Deny, Default)

Platform support:
- Windows: Fully implemented via WebView2's PermissionRequested event
- Other platforms: Not yet implemented (handler is ignored)

Example usage:
`
ust
WebViewBuilder::new()
    .with_permission_handler(|kind| {
        match kind {
            PermissionKind::Microphone => PermissionResponse::Allow,
            PermissionKind::Camera => PermissionResponse::Allow,
            _ => PermissionResponse::Default,
        }
    })
`

Closes: https://github.com/tauri-apps/wry/issues/XXX
@F0RLE F0RLE requested a review from a team as a code owner January 9, 2026 11:14
This extends the permission handler API to support:
- macOS/iOS: Via WKUIDelegate's requestMediaCapturePermissionForOrigin
- Linux: Via WebKitGTK's permission-request signal with UserMediaPermissionRequest

Changes:
- wkwebview/class/wry_web_view_ui_delegate.rs: Added permission_handler to ivars and updated request_media_capture_permission method
- wkwebview/mod.rs: Pass permission_handler to WryWebViewUIDelegate
- webkitgtk/mod.rs: Added connect_permission_request handler in attach_handlers
- lib.rs: Updated platform-specific documentation
@github-actions
Copy link
Contributor

github-actions bot commented Jan 9, 2026

Package Changes Through 4fa8e94

There are 1 changes which include wry with minor

Planned Package Versions

The following package releases are the planned based on the context of changes in this pull request.

package current next
wry 0.54.1 0.55.0

Add another change file through the GitHub UI by following this link.


Read about change files or the docs at github.com/jbolda/covector

@F0RLE F0RLE force-pushed the feat/permission-handler branch from 56cc0d1 to 755877e Compare January 9, 2026 12:20
@Legend-Master Legend-Master linked an issue Jan 11, 2026 that may be closed by this pull request
2 tasks
@F0RLE F0RLE closed this Jan 20, 2026
This adds DisplayCapture to PermissionKind enum and updates the WebKitGTK permission handler to detect screen capture requests via is_for_display_device().

Changes:

- lib.rs: Added PermissionKind::DisplayCapture variant

- webkitgtk/mod.rs: Added is_for_display_device() check before audio/video checks

This enables apps to programmatically handle getDisplayMedia() permission requests on Linux.
Copy link
Contributor

@pewsheen pewsheen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I currently only have a MacBook, so I'll share some thoughts about the macOS implementation here. For WebView2, maybe @Legend-Master can give some advice?

Personally, I tend not to loosen permission controls, to avoid them being used for malicious purposes.

Comment on lines 148 to 157
let decision = if let Some(handler) = &self.ivars().permission_handler {
match handler(permission_kind) {
PermissionResponse::Allow => WKPermissionDecision::Grant,
PermissionResponse::Deny => WKPermissionDecision::Deny,
PermissionResponse::Default => WKPermissionDecision::Grant, // Default to grant for backwards compatibility
}
} else {
// No handler set, default to grant (backwards compatible behavior)
WKPermissionDecision::Grant
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should align the default action with the OS, giving WKPermissionDecision::Prompt. Granting by default looks dangerous to me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to match the old behavior here? I'm not really aware of the historical context here though

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, you're right. Let's leave it granted then. But I think we might need a discussion for this, maybe in a new issue.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a PermissionResponse::Prompt variant. This keeps the default behavior as Grant (for backward compatibility) but allows apps to explicitly opt-in to the system prompt if they want. I think this covers both use cases.

let permission_kind = match capture_type {
WKMediaCaptureType::Camera => PermissionKind::Camera,
WKMediaCaptureType::Microphone => PermissionKind::Microphone,
WKMediaCaptureType::CameraAndMicrophone => PermissionKind::Microphone, // Treat as microphone for now
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Collapsing CameraAndMicrophone to Microphone also looks dangerous to me.

Maybe we can add some platform-specific type and document it well, or split it into something like vec![Microphone, Camera] and granted if and only if Microphone and Camera are both granted.

Comment on lines +1333 to +1334
/// - **Windows**: Fully supported via WebView2's PermissionRequested event.
/// - **macOS / iOS / Linux / Android**: Not yet implemented, handler is ignored.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you have implemented most of them!

Copy link
Contributor

@Legend-Master Legend-Master left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good for the webview2 implementation at least at a glance, awesome work!

Could you also add a change file?

https://github.com/tauri-apps/wry/blob/dev/.changes/readme.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for web APIs that require permissions

3 participants