Skip to content
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

fix(macos): global keys shortcuts #1156

Merged
merged 3 commits into from
Jan 31, 2024

Conversation

thewh1teagle
Copy link
Contributor

Since WkWebview implementation used webview::new_as_child, global keyboard shortcuts didn't worked in MacOS even when there's a menu with global shortcuts.
for instnace, command + h (for hiding the window) didn't worked, and any other menu shortcut in MacOS

Resolve
tauri-apps/tauri#8676

Context
https://discord.com/channels/616186924390023171/1199750637240459327

@thewh1teagle thewh1teagle requested a review from a team as a code owner January 28, 2024 19:36
@wusyong
Copy link
Member

wusyong commented Jan 29, 2024

I think I need an example to test that menu item accelerator works on both new and new_as_child.
And also test that it only work on new before this PR.

pewsheen
pewsheen previously approved these changes Jan 30, 2024
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.

Thanks for the contribution!
I've tested it on Tauri examples with single and multiple webviews, and it works after this patch.

Before we merge this commit, the CI requires you to add a change file in the .changes folder, and also needs you to sign your commits.

For the change file, you can reference the README.md or existing change file under .changes folder.
Signing commit: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits

@wusyong
Copy link
Member

wusyong commented Jan 30, 2024

@thewh1teagle You will need to sign your commits and then I could merge the PR.

@thewh1teagle thewh1teagle force-pushed the fix/wkwebview-shortcuts branch from 1ddd267 to a0fcc42 Compare January 30, 2024 10:02
@thewh1teagle
Copy link
Contributor Author

@wusyong

Signed and added a file to .changes

@wusyong wusyong merged commit c033bd2 into tauri-apps:dev Jan 31, 2024
11 checks passed
yydcnjjw pushed a commit to yydcnjjw/wry that referenced this pull request Feb 5, 2024
* fix: send key equivalent to menu

* Create wkwebview.md

* Update wkwebview.md
@lucasfernog
Copy link
Member

@wusyong @pewsheen this is breaking client-side shortcut handling. For instance this code:

;(function () {
  function toggleDevtoolsHotkey() {
    const osName = __TEMPLATE_os_name__

    const isHotkey =
      osName === 'macos'
        ? (event) => event.metaKey && event.altKey && event.key === 'I'
        : (event) => event.ctrlKey && event.shiftKey && event.key === 'I'

    document.addEventListener('keydown', (event) => {
      if (isHotkey(event)) {
        window.__TAURI_INTERNALS__.invoke(
          'plugin:webview|internal_toggle_devtools'
        )
      }
    })
  }

  if (
    document.readyState === 'complete' ||
    document.readyState === 'interactive'
  ) {
    toggleDevtoolsHotkey()
  } else {
    window.addEventListener('DOMContentLoaded', toggleDevtoolsHotkey, true)
  }
})()

I won't get the third event because the menu consumed it (I think).

@pewsheen
Copy link
Contributor

pewsheen commented Feb 8, 2024

@lucasfernog @thewh1teagle
Oops... I just tested the code. If the return value of performKeyEquivalent is NO, it will pass the event to the next responder (default behavior), and everything looks normal as before, but it will introduce another issue to multi-webviews. For example, if we have two child webviews, it will call the performKeyEquivalent twice. If we copy & paste a word in the sub-webview, it will paste twice...

For now, I'll revert the MR first and see if we have a better way to deal with it.

Btw, the toggle devtool shortcut on Mac seems to have another issue telling it is the hotkey... event.key === 'I' will be different if we hit command + I -> event.key = "^" or Alt + I -> event.key = Dead. I think we should use event.code === 'KeyI' instead. I'll open an issue on tauri for that

pewsheen added a commit that referenced this pull request Feb 8, 2024
wusyong pushed a commit that referenced this pull request Feb 8, 2024
* Revert "fix(macos): global keys shortcuts (#1156)"

This reverts commit c033bd2.

* chore: add changlog file
@lucasfernog
Copy link
Member

Yeah I noticed the key code issue working on another project. Thanks for investigating it!

@thewh1teagle
Copy link
Contributor Author

@pewsheen

Oops... I just tested the code. If the return value of performKeyEquivalent is NO, it will pass the event to the next responder (default behavior), and everything looks normal as before, but it will introduce another issue to multi-webviews. For example, if we have two child webviews, it will call the performKeyEquivalent twice. If we copy & paste a word in the sub-webview, it will paste twice...

For now, I'll revert the MR first and see if we have a better way to deal with it.

Btw, the toggle devtool shortcut on Mac seems to have another issue telling it is the hotkey... event.key === 'I' will be different if we hit command + I -> event.key = "^" or Alt + I -> event.key = Dead. I think we should use event.code === 'KeyI' instead. I'll open an issue on tauri for that

I found that if we return NO (meaning it won't be the responder) without send anything to the menu, it fix the global keyboard shortcuts without introduce the bugs you mentioned.

Also checked command + option + i and it does open the devtools.

menu_shortcuts.patch
# wry - patch which fix global menu keyboard shortcuts on multiwebview window in wry library - by github.com/thewh1teagle

diff --git a/src/wkwebview/mod.rs b/src/wkwebview/mod.rs
index d6a9ef4..7538f1c 100644
--- a/src/wkwebview/mod.rs
+++ b/src/wkwebview/mod.rs
@@ -339,6 +339,14 @@ impl InnerWebView {
               sel!(acceptsFirstMouse:),
               accept_first_mouse as extern "C" fn(&Object, Sel, id) -> BOOL,
             );
+            decl.add_method(
+              sel!(performKeyEquivalent:),
+              key_equivalent as extern "C" fn(&mut Object, Sel, id) -> BOOL,
+            );
+
+            extern "C" fn key_equivalent(_this: &mut Object, _sel: Sel, _event: id) -> BOOL {
+              NO
+            }
 
             extern "C" fn accept_first_mouse(this: &Object, _sel: Sel, _event: id) -> BOOL {
               unsafe {

@pewsheen
Copy link
Contributor

pewsheen commented Apr 1, 2024

@pewsheen

Oops... I just tested the code. If the return value of performKeyEquivalent is NO, it will pass the event to the next responder (default behavior), and everything looks normal as before, but it will introduce another issue to multi-webviews. For example, if we have two child webviews, it will call the performKeyEquivalent twice. If we copy & paste a word in the sub-webview, it will paste twice...
For now, I'll revert the MR first and see if we have a better way to deal with it.
Btw, the toggle devtool shortcut on Mac seems to have another issue telling it is the hotkey... event.key === 'I' will be different if we hit command + I -> event.key = "^" or Alt + I -> event.key = Dead. I think we should use event.code === 'KeyI' instead. I'll open an issue on tauri for that

I found that if we return NO (meaning it won't be the responder) without send anything to the menu, it fix the global keyboard shortcuts without introduce the bugs you mentioned.

Also checked command + option + i and it does open the devtools.

menu_shortcuts.patch

Cool! It looks good on my side. Would you mind opening another PR for this?

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.

4 participants