From 8c2e45b8f82b04ad2f1037490256dc770ff0e322 Mon Sep 17 00:00:00 2001 From: Lucas Rodrigues Date: Tue, 10 Mar 2026 00:45:17 +0000 Subject: [PATCH] app,io: [js] change Shortcut key on macOS/iOS Previously, the Shortcut key was hardcoded as ModCtrl. That patches tries to identify the OS and change the key. Fixes: https://todo.sr.ht/~eliasnaur/gio/624 Signed-off-by: Lucas Rodrigues Signed-off-by: Elias Naur --- app/os_js.go | 47 +++++++++++++++++++---------------------------- io/key/mod.go | 3 +-- io/key/mod_js.go | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 30 deletions(-) create mode 100644 io/key/mod_js.go diff --git a/app/os_js.go b/app/os_js.go index 45cdff7e..28dc7a77 100644 --- a/app/os_js.go +++ b/app/os_js.go @@ -406,27 +406,12 @@ func (w *window) keyEvent(e js.Value, ks key.State) { k := e.Get("key").String() if n, ok := translateKey(k); ok { - isJSHandledEdit := false - switch n { - case key.NameDeleteBackward: - if w.tarea.Get("selectionStart").Int() > 0 { - isJSHandledEdit = true - } - case key.NameDeleteForward: - if w.tarea.Get("selectionStart").Int() < w.tarea.Get("value").Length() { - isJSHandledEdit = true - } - } - if ks == key.Press { - isMod := n == key.NameAlt || n == key.NameCommand || n == key.NameCtrl || n == key.NameShift + isMod := n == key.NameAlt || n == key.NameCommand || n == key.NameCtrl || n == key.NameShift || n == key.NameSuper isFunc := n == key.NameUpArrow || n == key.NameDownArrow || n == key.NameLeftArrow || n == key.NameRightArrow || n == key.NamePageUp || n == key.NamePageDown || n == key.NameHome || n == key.NameEnd || - n == key.NameEscape || n == key.NameReturn || n == key.NameEnter || n == key.NameTab - - if !isJSHandledEdit && (n == key.NameDeleteBackward || n == key.NameDeleteForward) { - isFunc = true - } + n == key.NameEscape || n == key.NameReturn || n == key.NameEnter || n == key.NameTab || + n == key.NameDeleteBackward || n == key.NameDeleteForward if isMod || isFunc { // Gio will request the browser to change the selection/carret position natively. @@ -434,14 +419,12 @@ func (w *window) keyEvent(e js.Value, ks key.State) { } } - if !isJSHandledEdit { - cmd := key.Event{ - Name: n, - Modifiers: modifiersFor(e), - State: ks, - } - w.processEvent(cmd) + cmd := key.Event{ + Name: n, + Modifiers: modifiersFor(e), + State: ks, } + w.processEvent(cmd) } } @@ -502,6 +485,12 @@ func modifiersFor(e js.Value) key.Modifiers { if e.Call("getModifierState", "Shift").Bool() { mods |= key.ModShift } + if e.Call("getModifierState", "Meta").Bool() { + mods |= key.ModCommand + } + if e.Call("getModifierState", "OS").Bool() { + mods |= key.ModSuper + } return mods } @@ -522,6 +511,9 @@ func (w *window) touchEvent(kind pointer.Kind, e js.Value) { if e.Get("ctrlKey").Bool() { mods |= key.ModCtrl } + if e.Get("metaKey").Bool() { + mods |= key.ModCommand + } for i := 0; i < n; i++ { touch := changedTouches.Index(i) pid := w.touchIDFor(touch) @@ -668,10 +660,9 @@ func (w *window) ReadClipboard() { if w.clipboard.IsUndefined() { return } - if w.clipboard.Get("readText").IsUndefined() { - return + if w.clipboard.Get("readText").Truthy() { + w.clipboard.Call("readText").Call("then", w.clipboardCallback) } - w.clipboard.Call("readText", w.clipboard).Call("then", w.clipboardCallback) } func (w *window) WriteClipboard(mime string, s []byte) { diff --git a/io/key/mod.go b/io/key/mod.go index d9bb836f..f52b8b18 100644 --- a/io/key/mod.go +++ b/io/key/mod.go @@ -1,7 +1,6 @@ // SPDX-License-Identifier: Unlicense OR MIT -//go:build !darwin - +//go:build !darwin && !js package key // ModShortcut is the platform's shortcut modifier, usually the ctrl diff --git a/io/key/mod_js.go b/io/key/mod_js.go new file mode 100644 index 00000000..07e8b1e7 --- /dev/null +++ b/io/key/mod_js.go @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: Unlicense OR MIT + +package key + +import ( + "strings" + "syscall/js" +) + +// ModShortcut is the platform's shortcut modifier, usually the ctrl +// modifier. On Apple platforms it is the cmd key. +var ModShortcut = ModCtrl + +// ModShortcut is the platform's alternative shortcut modifier, +// usually the ctrl modifier. On Apple platforms it is the alt modifier. +var ModShortcutAlt = ModCtrl + +func init() { + nav := js.Global().Get("navigator") + if !nav.Truthy() { + return // Almost impossible to happen + } + + platform := "" + if p := nav.Get("platform"); p.Truthy() { + platform = p.String() + } + platform = strings.ToLower(platform) + + // Based on https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform#examples + for _, darwinPlatform := range []string{"mac", "iphone", "ipad", "ipod"} { + if strings.HasPrefix(platform, darwinPlatform) { + ModShortcut = ModCommand + ModShortcutAlt = ModAlt + return + } + } +}