0

[Mac keyboard shortcuts] Fix behavior of Fn e (emoji palette)

Fn/World e corresponds to Edit -> Emoji & Symbols. With the insertion
point in a web content textfield pressing Fn/World e would invoke
the character palette but also insert the character "e" into the
content. With this cl the palette appears but the character "e"
gets consumed.

Bug: 1294834

Change-Id: I1f6e596680a97b6458a080ae908e097cf7a4727b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3496322
Reviewed-by: Avi Drissman <avi@chromium.org>
Commit-Queue: Jayson Adams <shrike@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1028883}
This commit is contained in:
Jayson Adams
2022-07-27 20:19:49 +00:00
committed by Chromium LUCI CQ
parent 1e1a852a1c
commit f2283d8b80

@ -32,6 +32,8 @@
#import "ui/base/clipboard/clipboard_util_mac.h"
#import "ui/base/cocoa/appkit_utils.h"
#include "ui/base/cocoa/cocoa_base_utils.h"
#import "ui/base/cocoa/nsmenu_additions.h"
#import "ui/base/cocoa/nsmenuitem_additions.h"
#include "ui/base/cocoa/remote_accessibility_api.h"
#import "ui/base/cocoa/touch_bar_util.h"
#include "ui/base/ui_base_features.h"
@ -1053,9 +1055,48 @@ void ExtractUnderlines(NSAttributedString* string,
withObject:theEvent];
}
} else {
// Sends key down events to input method first, then we can decide what
// should be done according to input method's feedback.
[self interpretKeyEvents:@[ theEvent ]];
// Previously, we would just send the event, shortcut or no, to
// -interpretKeyEvents: below. The problem is that certain keyboard
// shortcuts now use the Function/World key and in those cases the
// corresponding shortcut fires but the shortcut event also gets processed
// as if it were a key press. As a result, with the insertion point
// in a web text box, after typing something like "Function e" to invoke
// the Emoji palette, we would wind up in -insertText:replacementRange:.
// The logic there (_handlingKeyDown && replacementRange.location ==
// NSNotFound) would create an invisible placeholder for the character. This
// invisible placeholder would cause macOS to position the palette at the
// upper-left corner of the webcontents instead of at the insertion point.
//
// For these Function/World events, we want the AppKit to process them
// as it usually would (i.e. via performKeyEquivalent:). It would be simpler
// if we could pass all of these keyboard shortcut events along to
// performKeyEquivalent:, however web pages are allowed to hijack keyboard
// shortcuts and apparently that's done through interpretKeyEvents:.
// Applications are not allowed to create these system events (you get a
// warning if you try and the Function event modifier flag doesn't stick)
// so it's OK not to allow web pages to do so either.
//
// If the event's not a shortcut, send it along to the input method first.
// We can then decide what should be done according to the input method's
// feedback.
bool is_a_system_shortcut_event = false;
if (equiv) {
bool is_a_keyboard_shortcut_event =
[[NSApp mainMenu] cr_menuItemForKeyEquivalentEvent:theEvent] != nil;
const NSEventModifierFlags kSystemShortcutModifierFlag =
NSEventModifierFlagFunction;
is_a_system_shortcut_event =
is_a_keyboard_shortcut_event &&
(ui::cocoa::ModifierMaskForKeyEvent(theEvent) &
kSystemShortcutModifierFlag) != 0;
}
if (is_a_system_shortcut_event) {
[[NSApp mainMenu] performKeyEquivalent:theEvent];
} else {
[self interpretKeyEvents:@[ theEvent ]];
}
}
_handlingKeyDown = NO;