Function activationKey cannot reliably support Ctrl+C on macOS
Summary
I am trying to configure React Grab so either Cmd+C or Ctrl+C can trigger the copy/grab shortcut on macOS.
Using a function activationKey lets the keydown path recognize both shortcuts, but Ctrl+C still does not reliably activate/copy. It looks like the keyup/release path derives required modifiers from the platform default when activationKey is a function, so on macOS it still treats Meta as the required modifier even when the custom matcher matched Ctrl+C.
Example configuration
import { getGlobalApi } from "react-grab";
const reactGrab = getGlobalApi();
reactGrab?.setOptions({
activationKey: (event) => {
const key = event.key.toLowerCase();
const isCopyKey = key === "c" || event.code === "KeyC";
return isCopyKey && (event.metaKey || event.ctrlKey) && !event.shiftKey && !event.altKey;
},
keyHoldDuration: 0,
});Expected behavior
When activationKey is a function and returns true for Ctrl+C, React Grab should use that matched shortcut consistently for the full hold/copy lifecycle.
In this case, both Cmd+C and Ctrl+C should be viable on macOS.
Actual behavior
Cmd+C behaves as expected on macOS, but Ctrl+C does not reliably trigger/copy, even when activationKey returns true and keyHoldDuration is set to 0.
Source-level notes
From reading the current source:
packages/react-grab/src/utils/is-target-key-combination.tshonors a functionactivationKeyin the keydown path.packages/react-grab/src/utils/parse-activation-key.tshasgetModifiersFromActivationKey(), but for a function activation key it returns platform defaults:- macOS:
metaKey: true - non-macOS:
ctrlKey: true
- macOS:
packages/react-grab/src/core/index.tsxusesgetRequiredModifiers()in the keyup path to computeisReleasingModifier.
That means a function matcher can say "this Ctrl+C keydown is valid", but the later release logic still appears to evaluate macOS Meta as the required modifier. For an OR-style shortcut like Cmd+C or Ctrl+C, there does not seem to be a way for the function matcher to also tell React Grab which modifier/key combination was actually matched.
There is also a MIN_HOLD_FOR_ACTIVATION_AFTER_COPY_MS gate in the keyup path, so setting keyHoldDuration: 0 is not enough to make a normal Ctrl+C press work reliably.
Why this matters
The string form can represent one shortcut such as "ctrl+c", but it cannot represent an OR shortcut like "use Cmd+C or Ctrl+C". The function form is the natural API for that, but today it loses release/modifier semantics.
Possible fixes
A few possible directions:
- Let
activationKeyaccept an array of strings/functions, e.g.["cmd+c", "ctrl+c"], so modifier metadata remains parseable. - Add an optional way for function matchers to declare required modifiers.
- Track the shortcut/modifiers that actually matched on keydown and use that for keyup/release handling instead of falling back to platform defaults for function activation keys.
Related but not the same as #398, which is about copy behavior while the toolbar is minimized. This issue is specifically about function activationKey release semantics on macOS.
Source: aidenybai/react-grab