The Problem
I am working on a game with a copy and paste shortcut. I can support Windows users with Control + V, which works fine. However, for Mac users, the canonical keyboard shortcut is Cmd ⌘ + v. As far as I can tell, there is absolutely no way to recognize when Cmd ⌘ + v is passed in the Mac Roblox client.
This is a duplicate of a bug report that was filed 3 years ago but closed without resolution. @crypto_mancer responded on that post as well as a related remapping post, so tagging them here.
It works in Studio, but Cmd is remapped to Ctrl
In Roblox Studio, presses of left Cmd (which Roblox maps to Enum.KeyCode.LeftMeta) are remapped to Enum.ModifierKey.Ctrl or Enum.KeyCode.LeftControl. Therefore, a LocalScript like this works to recognize paste (though you’ll notice that cmd + v actually always shows as ctrl + v from the keycodes in the prints)
local ContextActionService = game:GetService("ContextActionService")
ContextActionService:BindAction("test", function(_, inputState: Enum.UserInputState, obj: InputObject)
if obj:IsModifierKeyDown(Enum.ModifierKey.Ctrl) then
print("ctrl + v", obj.KeyCode)
elseif obj:IsModifierKeyDown(Enum.ModifierKey.Meta) then
print("meta + v", obj.KeyCode)
end
end,
false,
Enum.KeyCode.V)
No way of recognizing this in the Mac Roblox client
However, in the Mac Roblox app, something always sinks the input when Cmd ⌘ + v is pressed. Control + v still works. In fact, there is no way that I’ve found to receive input when Cmd ⌘ and v are pressed. I’ve tried listening to the keys individually with ContextActionService. I’ve also tried to use UserInputService to detect this. For example, if you run this code and then press LeftMeta, that first keypress will show up, but if you hold it down and press V, the V will never show up.
local UserInputService = game:GetService("UserInputService")
local function onInputBegan(input: InputObject, _gameProcessed)
print(input.KeyCode)
end
UserInputService.InputBegan:Connect(onInputBegan)
Here is a baseplate which has a LocalScript with some of the code above. To use it, observe the printed output in Studio versus the output in the Developer Console after publishing it.
cmdplusv.rbxl (46.3 KB)
Hypothesizing about a root cause
Cmd ⌘ + v registers fine for the CoreScripts to handle things like pasting things into chat and textboxes. One potential root cause is if the paste handler for Mac inadvertently doesn’t return anything, resulting in a ContextActionResult.Sink being passed by default. My guess is that some part of the Roblox CoreScripts to handle UI input has a part like:
ContextActionService:BindAction("Copy", function(_, inputState: Enum.UserInputState, obj: InputObject)
if obj:IsModifierKeyDown(Enum.ModifierKey.Ctrl) then
local handled = handlePaste()
if not handled then
return Enum.ContextActionResult.Pass
end
-- Enum.ContextActionResult.Sink is passed by default
end
end,
false,
Enum.KeyCode.V)
...........
ContextActionService:BindAction("CopyMac", function(_, inputState: Enum.UserInputState, obj: InputObject)
if obj:IsModifierKeyDown(Enum.ModifierKey.Meta) then
handlePaste()
-- Enum.ContextActionResult.Sink is implicitly returned here!!
end
end,
false,
Enum.KeyCode.V)
Thank you for your help looking into this to provide a great experience for users who are used to Mac keyboard shortcuts.
Expected behavior
There should be a way to recognize Cmd ⌘ + v