Bug 1833923: Start detecting when the Fn key is pressed on macOS, which allows for built-in macOS shortcuts (such as Fn+e for the emoji picker) to start working. r=masayuki

Depends on D195016

Differential Revision: https://phabricator.services.mozilla.com/D223630
This commit is contained in:
Stephen A Pohl 2024-11-02 02:13:06 +00:00
parent 4cc92336df
commit 7132f773ba
4 changed files with 27 additions and 9 deletions

View File

@ -133,13 +133,11 @@ class KeyEventHandler final {
static const int32_t cAlt; static const int32_t cAlt;
static const int32_t cControl; static const int32_t cControl;
static const int32_t cMeta; static const int32_t cMeta;
static const int32_t cOS;
static const int32_t cShiftMask; static const int32_t cShiftMask;
static const int32_t cAltMask; static const int32_t cAltMask;
static const int32_t cControlMask; static const int32_t cControlMask;
static const int32_t cMetaMask; static const int32_t cMetaMask;
static const int32_t cOSMask;
static const int32_t cAllModifiers; static const int32_t cAllModifiers;

View File

@ -238,7 +238,7 @@ class WidgetKeyboardEvent final : public WidgetInputEvent {
// we don't have any bug reports that user cannot input proper // we don't have any bug reports that user cannot input proper
// character with Alt and/or Ctrl key. // character with Alt and/or Ctrl key.
// -- On macOS, IMEInputHandler::WillDispatchKeyboardEvent() clears // -- On macOS, IMEInputHandler::WillDispatchKeyboardEvent() clears
// MODIFIER_ALT and MDOFIEIR_CONTROL of eKeyPress event only when // MODIFIER_ALT and MODIFIER_CONTROL of eKeyPress event only when
// TextInputHandler::InsertText() has been called for the event. // TextInputHandler::InsertText() has been called for the event.
// I.e., they are cleared only when an editor has focus (even if IME // I.e., they are cleared only when an editor has focus (even if IME
// is disabled in password field or by |ime-mode: disabled;|) because // is disabled in password field or by |ime-mode: disabled;|) because

View File

@ -545,9 +545,11 @@ bool TISInputSourceWrapper::IsDeadKey(NSEvent* aNativeKeyEvent) {
return false; return false;
} }
// Assmue that if control key or command key is pressed, it's not a dead key. // Assume that if the control key, command key or Fn key is pressed, it's not
// a dead key.
NSUInteger cocoaState = [aNativeKeyEvent modifierFlags]; NSUInteger cocoaState = [aNativeKeyEvent modifierFlags];
if (cocoaState & (NSEventModifierFlagControl | NSEventModifierFlagCommand)) { if (cocoaState & (NSEventModifierFlagControl | NSEventModifierFlagCommand |
NSEventModifierFlagFunction)) {
return false; return false;
} }
@ -1849,6 +1851,14 @@ bool TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent,
return false; return false;
} }
// macOS supports shortcut keys using the `Fn` key. Check first if this key
// event is such a shortcut key.
if (nsCocoaUtils::ModifiersForEvent(aNativeEvent) & MODIFIER_FN) {
if (mWidget->SendEventToNativeMenuSystem(aNativeEvent)) {
return true;
}
}
// Let Cocoa interpret the key events, caching IsIMEComposing first. // Let Cocoa interpret the key events, caching IsIMEComposing first.
bool wasComposing = IsIMEComposing(); bool wasComposing = IsIMEComposing();
bool interpretKeyEventsCalled = false; bool interpretKeyEventsCalled = false;

View File

@ -701,7 +701,8 @@ NSEvent* nsCocoaUtils::MakeNewCococaEventFromWidgetEvent(
{MODIFIER_ALTGRAPH, NSEventModifierFlagOption}, {MODIFIER_ALTGRAPH, NSEventModifierFlagOption},
{MODIFIER_META, NSEventModifierFlagCommand}, {MODIFIER_META, NSEventModifierFlagCommand},
{MODIFIER_CAPSLOCK, NSEventModifierFlagCapsLock}, {MODIFIER_CAPSLOCK, NSEventModifierFlagCapsLock},
{MODIFIER_NUMLOCK, NSEventModifierFlagNumericPad}}; {MODIFIER_NUMLOCK, NSEventModifierFlagNumericPad},
{MODIFIER_FN, NSEventModifierFlagFunction}};
NSUInteger modifierFlags = 0; NSUInteger modifierFlags = 0;
for (uint32_t i = 0; i < std::size(sModifierFlagMap); ++i) { for (uint32_t i = 0; i < std::size(sModifierFlagMap); ++i) {
@ -786,9 +787,18 @@ Modifiers nsCocoaUtils::ModifiersForEvent(NSEvent* aNativeEvent) {
result |= MODIFIER_NUMLOCK; result |= MODIFIER_NUMLOCK;
} }
// Be aware, NSEventModifierFlagFunction is included when arrow keys, home key // Be aware, NSEventModifierFlagFunction is also set on the native event when
// or some other keys are pressed. We cannot check whether 'fn' key is pressed // arrow keys, the home key or some other keys are pressed. We cannot check
// or not by the flag. // whether the 'fn' key is pressed or not by the flag alone. We need to check
// that the event's keyCode falls outside the range of keys that will also set
// the function modifier.
if (!!(modifiers & NSEventModifierFlagFunction) &&
(aNativeEvent.type == NSKeyDown || aNativeEvent.type == NSKeyUp ||
aNativeEvent.type == NSFlagsChanged) &&
!(kVK_Return <= aNativeEvent.keyCode &&
aNativeEvent.keyCode <= NSModeSwitchFunctionKey)) {
result |= MODIFIER_FN;
}
return result; return result;
} }