107 lines
3.7 KiB
Text
107 lines
3.7 KiB
Text
|
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
// found in the LICENSE file.
|
||
|
|
||
|
#import "browser/atom_event_processing_window.h"
|
||
|
|
||
|
#include "base/logging.h"
|
||
|
#import "content/public/browser/render_widget_host_view_mac_base.h"
|
||
|
|
||
|
@interface AtomEventProcessingWindow ()
|
||
|
// Duplicate the given key event, but changing the associated window.
|
||
|
- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event;
|
||
|
@end
|
||
|
|
||
|
@implementation AtomEventProcessingWindow
|
||
|
|
||
|
- (BOOL)redispatchKeyEvent:(NSEvent*)event {
|
||
|
DCHECK(event);
|
||
|
NSEventType eventType = [event type];
|
||
|
if (eventType != NSKeyDown &&
|
||
|
eventType != NSKeyUp &&
|
||
|
eventType != NSFlagsChanged) {
|
||
|
NOTREACHED();
|
||
|
return YES; // Pretend it's been handled in an effort to limit damage.
|
||
|
}
|
||
|
|
||
|
// Ordinarily, the event's window should be this window. However, when
|
||
|
// switching between normal and fullscreen mode, we switch out the window, and
|
||
|
// the event's window might be the previous window (or even an earlier one if
|
||
|
// the renderer is running slowly and several mode switches occur). In this
|
||
|
// rare case, we synthesize a new key event so that its associate window
|
||
|
// (number) is our own.
|
||
|
if ([event window] != self)
|
||
|
event = [self keyEventForWindow:self fromKeyEvent:event];
|
||
|
|
||
|
// Redispatch the event.
|
||
|
eventHandled_ = YES;
|
||
|
redispatchingEvent_ = YES;
|
||
|
[NSApp sendEvent:event];
|
||
|
redispatchingEvent_ = NO;
|
||
|
|
||
|
// If the event was not handled by [NSApp sendEvent:], the sendEvent:
|
||
|
// method below will be called, and because |redispatchingEvent_| is YES,
|
||
|
// |eventHandled_| will be set to NO.
|
||
|
return eventHandled_;
|
||
|
}
|
||
|
|
||
|
- (void)sendEvent:(NSEvent*)event {
|
||
|
if (!redispatchingEvent_)
|
||
|
[super sendEvent:event];
|
||
|
else
|
||
|
eventHandled_ = NO;
|
||
|
}
|
||
|
|
||
|
- (NSEvent*)keyEventForWindow:(NSWindow*)window fromKeyEvent:(NSEvent*)event {
|
||
|
NSEventType eventType = [event type];
|
||
|
|
||
|
// Convert the event's location from the original window's coordinates into
|
||
|
// our own.
|
||
|
NSPoint eventLoc = [event locationInWindow];
|
||
|
eventLoc = [[event window] convertBaseToScreen:eventLoc];
|
||
|
eventLoc = [self convertScreenToBase:eventLoc];
|
||
|
|
||
|
// Various things *only* apply to key down/up.
|
||
|
BOOL eventIsARepeat = NO;
|
||
|
NSString* eventCharacters = nil;
|
||
|
NSString* eventUnmodCharacters = nil;
|
||
|
if (eventType == NSKeyDown || eventType == NSKeyUp) {
|
||
|
eventIsARepeat = [event isARepeat];
|
||
|
eventCharacters = [event characters];
|
||
|
eventUnmodCharacters = [event charactersIgnoringModifiers];
|
||
|
}
|
||
|
|
||
|
// This synthesis may be slightly imperfect: we provide nil for the context,
|
||
|
// since I (viettrungluu) am sceptical that putting in the original context
|
||
|
// (if one is given) is valid.
|
||
|
return [NSEvent keyEventWithType:eventType
|
||
|
location:eventLoc
|
||
|
modifierFlags:[event modifierFlags]
|
||
|
timestamp:[event timestamp]
|
||
|
windowNumber:[window windowNumber]
|
||
|
context:nil
|
||
|
characters:eventCharacters
|
||
|
charactersIgnoringModifiers:eventUnmodCharacters
|
||
|
isARepeat:eventIsARepeat
|
||
|
keyCode:[event keyCode]];
|
||
|
}
|
||
|
|
||
|
|
||
|
- (BOOL)performKeyEquivalent:(NSEvent*)event {
|
||
|
if (redispatchingEvent_)
|
||
|
return NO;
|
||
|
|
||
|
// Give the web site a chance to handle the event. If it doesn't want to
|
||
|
// handle it, it will call us back with one of the |handle*| methods above.
|
||
|
NSResponder* r = [self firstResponder];
|
||
|
if ([r conformsToProtocol:@protocol(RenderWidgetHostViewMacBase)])
|
||
|
return [r performKeyEquivalent:event];
|
||
|
|
||
|
if ([super performKeyEquivalent:event])
|
||
|
return YES;
|
||
|
|
||
|
return NO;
|
||
|
}
|
||
|
|
||
|
@end // AtomEventProcessingWindow
|