| Index: ui/views/cocoa/bridged_content_view.mm
|
| diff --git a/ui/views/cocoa/bridged_content_view.mm b/ui/views/cocoa/bridged_content_view.mm
|
| index b5ddb05057f64ac07965453a335f8ab73e090259..cc98f89457b87cff82e6ccdcbf968dc32a2f6672 100644
|
| --- a/ui/views/cocoa/bridged_content_view.mm
|
| +++ b/ui/views/cocoa/bridged_content_view.mm
|
| @@ -65,6 +65,14 @@ gfx::Point MovePointToWindow(const NSPoint& point,
|
| domCode:(ui::DomCode)domCode
|
| eventFlags:(int)eventFlags;
|
|
|
| +// Menu action handlers.
|
| +- (void)undo:(id)sender;
|
| +- (void)redo:(id)sender;
|
| +- (void)cut:(id)sender;
|
| +- (void)copy:(id)sender;
|
| +- (void)paste:(id)sender;
|
| +- (void)selectAll:(id)sender;
|
| +
|
| @end
|
|
|
| @implementation BridgedContentView
|
| @@ -147,8 +155,13 @@ gfx::Point MovePointToWindow(const NSPoint& point,
|
| return;
|
| }
|
|
|
| + ui::KeyEvent event(ui::ET_KEY_PRESSED, keyCode, domCode, eventFlags);
|
| + // If the text input's controller soaks up the event, bail.
|
| + if (textInputClient_ && textInputClient_->HandleAsKeyEventOnly(event))
|
| + return;
|
| +
|
| // If there's an active TextInputClient, it ignores the key and processes the
|
| - // logical editing action.
|
| + // logical editing action. Ignores |event|.
|
| if (commandId && textInputClient_ &&
|
| textInputClient_->IsEditingCommandEnabled(commandId)) {
|
| textInputClient_->ExecuteEditingCommand(commandId);
|
| @@ -156,10 +169,62 @@ gfx::Point MovePointToWindow(const NSPoint& point,
|
| }
|
|
|
| // Otherwise, process the action as a regular key event.
|
| - ui::KeyEvent event(ui::ET_KEY_PRESSED, keyCode, domCode, eventFlags);
|
| hostedView_->GetWidget()->OnKeyEvent(&event);
|
| }
|
|
|
| +- (void)undo:(id)sender {
|
| + // This DCHECK is more strict than a similar check in handleAction:. It can be
|
| + // done here because the actors sending these actions should be calling
|
| + // validateUserInterfaceItem: before enabling UI that allows these messages to
|
| + // be sent. Checking it here would be too late to provide correct UI feedback
|
| + // (e.g. there will be no "beep").
|
| + DCHECK(textInputClient_->IsEditingCommandEnabled(IDS_APP_UNDO));
|
| + [self handleAction:IDS_APP_UNDO
|
| + keyCode:ui::VKEY_Z
|
| + domCode:ui::DomCode::KEY_Z
|
| + eventFlags:ui::EF_CONTROL_DOWN];
|
| +}
|
| +
|
| +- (void)redo:(id)sender {
|
| + DCHECK(textInputClient_->IsEditingCommandEnabled(IDS_APP_REDO));
|
| + [self handleAction:IDS_APP_REDO
|
| + keyCode:ui::VKEY_Y
|
| + domCode:ui::DomCode::KEY_Y
|
| + eventFlags:ui::EF_CONTROL_DOWN];
|
| +}
|
| +
|
| +- (void)cut:(id)sender {
|
| + DCHECK(textInputClient_->IsEditingCommandEnabled(IDS_APP_CUT));
|
| + [self handleAction:IDS_APP_CUT
|
| + keyCode:ui::VKEY_X
|
| + domCode:ui::DomCode::KEY_X
|
| + eventFlags:ui::EF_CONTROL_DOWN];
|
| +}
|
| +
|
| +- (void)copy:(id)sender {
|
| + DCHECK(textInputClient_->IsEditingCommandEnabled(IDS_APP_COPY));
|
| + [self handleAction:IDS_APP_COPY
|
| + keyCode:ui::VKEY_C
|
| + domCode:ui::DomCode::KEY_C
|
| + eventFlags:ui::EF_CONTROL_DOWN];
|
| +}
|
| +
|
| +- (void)paste:(id)sender {
|
| + DCHECK(textInputClient_->IsEditingCommandEnabled(IDS_APP_PASTE));
|
| + [self handleAction:IDS_APP_PASTE
|
| + keyCode:ui::VKEY_V
|
| + domCode:ui::DomCode::KEY_V
|
| + eventFlags:ui::EF_CONTROL_DOWN];
|
| +}
|
| +
|
| +- (void)selectAll:(id)sender {
|
| + DCHECK(textInputClient_->IsEditingCommandEnabled(IDS_APP_SELECT_ALL));
|
| + [self handleAction:IDS_APP_SELECT_ALL
|
| + keyCode:ui::VKEY_A
|
| + domCode:ui::DomCode::KEY_A
|
| + eventFlags:ui::EF_CONTROL_DOWN];
|
| +}
|
| +
|
| // NSView implementation.
|
|
|
| - (BOOL)acceptsFirstResponder {
|
| @@ -206,7 +271,9 @@ gfx::Point MovePointToWindow(const NSPoint& point,
|
|
|
| - (void)keyDown:(NSEvent*)theEvent {
|
| // Convert the event into an action message, according to OSX key mappings.
|
| + inKeyDown_ = YES;
|
| [self interpretKeyEvents:@[ theEvent ]];
|
| + inKeyDown_= NO;
|
| }
|
|
|
| - (void)mouseDown:(NSEvent*)theEvent {
|
| @@ -485,8 +552,10 @@ gfx::Point MovePointToWindow(const NSPoint& point,
|
| - (void)doCommandBySelector:(SEL)selector {
|
| if ([self respondsToSelector:selector])
|
| [self performSelector:selector withObject:nil];
|
| - else
|
| + else {
|
| + NSLog(@"Unhandled: %@\n", NSStringFromSelector(selector));
|
| [[self nextResponder] doCommandBySelector:selector];
|
| + }
|
| }
|
|
|
| - (NSRect)firstRectForCharacterRange:(NSRange)range
|
| @@ -531,7 +600,16 @@ gfx::Point MovePointToWindow(const NSPoint& point,
|
| return;
|
|
|
| textInputClient_->DeleteRange(gfx::Range(replacementRange));
|
| - textInputClient_->InsertText(base::SysNSStringToUTF16(text));
|
| +
|
| + // If a single character is inserted by keyDown's call to interpretKeyEvents:
|
| + // then use InsertChar() to allow editing events to be merged. Never send the
|
| + // key modifier flags to InsertChar since interpretKeyEvents: will filter out
|
| + // things that are actually commands, and 'Alt' on Mac actually inserts
|
| + // alternate characters (e.g. Alt+S is ß), so shouldn't be ignored.
|
| + if (inKeyDown_ && [text length] == 1)
|
| + textInputClient_->InsertChar([text characterAtIndex:0], 0);
|
| + else
|
| + textInputClient_->InsertText(base::SysNSStringToUTF16(text));
|
| }
|
|
|
| - (NSRange)markedRange {
|
| @@ -575,6 +653,33 @@ gfx::Point MovePointToWindow(const NSPoint& point,
|
| return @[];
|
| }
|
|
|
| +// NSUserInterfaceValidations protocol implementation.
|
| +
|
| +- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item {
|
| + // TODO(tapted): A read-only views::Textfield currently returns null from
|
| + // GetTextInputClient(), which means this incorrectly (in)validates menus for
|
| + // read-only textfields (e.g. Copy gets disabled).
|
| + if (!textInputClient_)
|
| + return NO;
|
| +
|
| + SEL action = [item action];
|
| +
|
| + if (action == @selector(undo:))
|
| + return textInputClient_->IsEditingCommandEnabled(IDS_APP_UNDO);
|
| + if (action == @selector(redo:))
|
| + return textInputClient_->IsEditingCommandEnabled(IDS_APP_REDO);
|
| + if (action == @selector(cut:))
|
| + return textInputClient_->IsEditingCommandEnabled(IDS_APP_CUT);
|
| + if (action == @selector(copy:))
|
| + return textInputClient_->IsEditingCommandEnabled(IDS_APP_COPY);
|
| + if (action == @selector(paste:))
|
| + return textInputClient_->IsEditingCommandEnabled(IDS_APP_PASTE);
|
| + if (action == @selector(selectAll:))
|
| + return textInputClient_->IsEditingCommandEnabled(IDS_APP_SELECT_ALL);
|
| +
|
| + return NO;
|
| +}
|
| +
|
| // NSAccessibility informal protocol implementation.
|
|
|
| - (id)accessibilityAttributeValue:(NSString*)attribute {
|
|
|