🐛 Toggle display-guides via physical key code so the shortcut works on non-US layouts (#9209)

* 🐛 Toggle display-guides via physical key code so the shortcut works on non-US layouts

Signed-off-by: RenzoMXD <170978465+RenzoMXD@users.noreply.github.com>

* 🐛 Add tests for display-guides shortcut on non-US layout

---------

Signed-off-by: RenzoMXD <170978465+RenzoMXD@users.noreply.github.com>
Signed-off-by: Renzo <170978465+RenzoMXD@users.noreply.github.com>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
This commit is contained in:
Renzo 2026-05-08 17:36:52 +02:00 committed by GitHub
parent 6aeccb1208
commit ea24445c2c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 127 additions and 0 deletions

View File

@ -75,6 +75,7 @@
### :bug: Bugs fixed
- Fix `Ctrl+'` "Show guides" shortcut on non-US keyboard layouts by matching the physical key location so it no longer collides with the snap-guides shortcut (by @RenzoMXD) [Github #8423](https://github.com/penpot/penpot/issues/8423)
- Fix lost-update race on `team.features` during concurrent file creation: two simultaneous create-file requests on the same team could both read the same features snapshot, compute different unions, and have the second `UPDATE` silently overwrite the first; the write is now preceded by a `SELECT … FOR UPDATE` inside the same transaction so every update sees the latest committed state [Github #9197](https://github.com/penpot/penpot/issues/9197)
- Fix Alt/Option to draw shapes from center point (by @offreal) [Github #8361](https://github.com/penpot/penpot/pull/8361)
- Add token name on broken token pill on sidebar [Taiga #13527](https://tree.taiga.io/project/penpot/issue/13527)

View File

@ -6,6 +6,7 @@
(ns app.main.data.workspace.shortcuts
(:require
[app.config :as cf]
[app.main.data.common :as dcm]
[app.main.data.event :as ev]
[app.main.data.exports.assets :as de]
@ -41,6 +42,19 @@
(-> (dw/toggle-layout-flag flag)
(vary-meta assoc ::ev/origin "workspace-shortcuts")))
(defn on-display-guides-keydown
[^js event]
(let [mod? (if (cf/check-platform? :macos)
(.-metaKey event)
(.-ctrlKey event))
shift? (.-shiftKey event)
code (.-code event)]
(when (and mod?
(or (and (not shift?) (= "Quote" code))
(and shift? (= "Backslash" code))))
(.preventDefault event)
(st/emit! (toggle-layout-flag :display-guides)))))
(defn- emit-when-no-readonly
[& events]
(let [can-edit? (:can-edit (deref refs/permissions))

View File

@ -461,6 +461,11 @@
[path-editing? drawing-path? text-editing? grid-editing?]
(hooks/use-shortcuts ::workspace wsc/shortcuts)
(mf/with-effect []
(.addEventListener js/window "keydown" wsc/on-display-guides-keydown)
(fn []
(.removeEventListener js/window "keydown" wsc/on-display-guides-keydown)))
(mf/with-effect [path-editing? drawing-path? grid-editing?]
(cond
grid-editing?

View File

@ -0,0 +1,105 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns frontend-tests.data.workspace-shortcuts-test
(:require
[app.config :as cf]
[app.main.data.workspace.shortcuts :as shortcuts]
[app.main.store :as st]
[cljs.test :as t :include-macros true]))
(defn- keyboard-event
[{:keys [ctrl? meta? shift? code prevented?]}]
#js {:ctrlKey (boolean ctrl?)
:metaKey (boolean meta?)
:shiftKey (boolean shift?)
:code code
:preventDefault #(reset! prevented? true)})
(t/deftest display-guides-handler-detects-physical-keys
(t/testing "US layout uses Ctrl+Quote"
(let [prevented? (atom false)
emitted (atom [])]
(with-redefs [cf/check-platform? (constantly false)
st/emit! #(swap! emitted conj %)]
(shortcuts/on-display-guides-keydown
(keyboard-event {:ctrl? true :code "Quote" :prevented? prevented?})))
(t/is (true? @prevented?))
(t/is (= 1 (count @emitted)))))
(t/testing "German layout uses Ctrl+Shift+Backslash"
(let [prevented? (atom false)
emitted (atom [])]
(with-redefs [cf/check-platform? (constantly false)
st/emit! #(swap! emitted conj %)]
(shortcuts/on-display-guides-keydown
(keyboard-event {:ctrl? true :shift? true :code "Backslash" :prevented? prevented?})))
(t/is (true? @prevented?))
(t/is (= 1 (count @emitted)))))
(t/testing "macOS uses Meta+Quote"
(let [prevented? (atom false)
emitted (atom [])]
(with-redefs [cf/check-platform? (constantly true)
st/emit! #(swap! emitted conj %)]
(shortcuts/on-display-guides-keydown
(keyboard-event {:meta? true :code "Quote" :prevented? prevented?})))
(t/is (true? @prevented?))
(t/is (= 1 (count @emitted)))))
(t/testing "macOS German layout uses Meta+Shift+Backslash"
(let [prevented? (atom false)
emitted (atom [])]
(with-redefs [cf/check-platform? (constantly true)
st/emit! #(swap! emitted conj %)]
(shortcuts/on-display-guides-keydown
(keyboard-event {:meta? true :shift? true :code "Backslash" :prevented? prevented?})))
(t/is (true? @prevented?))
(t/is (= 1 (count @emitted)))))
(t/testing "macOS ignores Ctrl+Quote"
(let [prevented? (atom false)
emitted (atom [])]
(with-redefs [cf/check-platform? (constantly true)
st/emit! #(swap! emitted conj %)]
(shortcuts/on-display-guides-keydown
(keyboard-event {:ctrl? true :code "Quote" :prevented? prevented?})))
(t/is (false? @prevented?))
(t/is (empty? @emitted))))
(t/testing "macOS snap-guides shortcut stays out of this handler"
(let [prevented? (atom false)
emitted (atom [])]
(with-redefs [cf/check-platform? (constantly true)
st/emit! #(swap! emitted conj %)]
(shortcuts/on-display-guides-keydown
(keyboard-event {:meta? true :shift? true :code "Quote" :prevented? prevented?})))
(t/is (false? @prevented?))
(t/is (empty? @emitted))))
(t/testing "matching physical keys without the platform modifier are ignored"
(let [prevented? (atom false)
emitted (atom [])]
(with-redefs [cf/check-platform? (constantly false)
st/emit! #(swap! emitted conj %)]
(shortcuts/on-display-guides-keydown
(keyboard-event {:code "Quote" :prevented? prevented?}))
(shortcuts/on-display-guides-keydown
(keyboard-event {:shift? true :code "Backslash" :prevented? prevented?})))
(t/is (false? @prevented?))
(t/is (empty? @emitted))))
(t/testing "snap-guides and alignment shortcuts stay out of this handler"
(let [prevented? (atom false)
emitted (atom [])]
(with-redefs [cf/check-platform? (constantly false)
st/emit! #(swap! emitted conj %)]
(shortcuts/on-display-guides-keydown
(keyboard-event {:ctrl? true :shift? true :code "Quote" :prevented? prevented?}))
(shortcuts/on-display-guides-keydown
(keyboard-event {:ctrl? true :code "Backslash" :prevented? prevented?})))
(t/is (false? @prevented?))
(t/is (empty? @emitted)))))

View File

@ -9,6 +9,7 @@
[frontend-tests.data.viewer-test]
[frontend-tests.data.workspace-colors-test]
[frontend-tests.data.workspace-media-test]
[frontend-tests.data.workspace-shortcuts-test]
[frontend-tests.data.workspace-texts-test]
[frontend-tests.data.workspace-thumbnails-test]
[frontend-tests.errors-test]
@ -58,6 +59,7 @@
'frontend-tests.data.viewer-test
'frontend-tests.data.workspace-colors-test
'frontend-tests.data.workspace-media-test
'frontend-tests.data.workspace-shortcuts-test
'frontend-tests.data.workspace-texts-test
'frontend-tests.data.workspace-thumbnails-test
'frontend-tests.helpers-shapes-test