summaryrefslogtreecommitdiffstats
path: root/Source/WebKit2/UIProcess/API/mac/WKView.mm
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/UIProcess/API/mac/WKView.mm')
-rw-r--r--Source/WebKit2/UIProcess/API/mac/WKView.mm248
1 files changed, 157 insertions, 91 deletions
diff --git a/Source/WebKit2/UIProcess/API/mac/WKView.mm b/Source/WebKit2/UIProcess/API/mac/WKView.mm
index e432549..05693ef 100644
--- a/Source/WebKit2/UIProcess/API/mac/WKView.mm
+++ b/Source/WebKit2/UIProcess/API/mac/WKView.mm
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,6 +42,7 @@
#import "TextChecker.h"
#import "TextCheckerState.h"
#import "WKAPICast.h"
+#import "WKFullScreenWindowController.h"
#import "WKPrintingView.h"
#import "WKStringCF.h"
#import "WKTextInputWindowController.h"
@@ -49,6 +50,7 @@
#import "WKViewPrivate.h"
#import "WebContext.h"
#import "WebEventFactory.h"
+#import "WebFullScreenManagerProxy.h"
#import "WebPage.h"
#import "WebPageProxy.h"
#import "WebProcessProxy.h"
@@ -57,6 +59,7 @@
#import <WebCore/ColorMac.h>
#import <WebCore/DragController.h>
#import <WebCore/DragData.h>
+#import <WebCore/LocalizedStrings.h>
#import <WebCore/FloatRect.h>
#import <WebCore/IntRect.h>
#import <WebCore/KeyboardEvent.h>
@@ -66,15 +69,14 @@
#import <wtf/RefPtr.h>
#import <wtf/RetainPtr.h>
-// FIXME (WebKit2) <rdar://problem/8728860> WebKit2 needs to be localized
-#define UI_STRING(__str, __desc) [NSString stringWithUTF8String:__str]
-
-@interface NSApplication (Details)
+@interface NSApplication (WebNSApplicationDetails)
- (void)speakString:(NSString *)string;
+- (void)_setCurrentEvent:(NSEvent *)event;
@end
-@interface NSWindow (Details)
+@interface NSWindow (WebNSWindowDetails)
- (NSRect)_growBoxRect;
+- (id)_growBoxOwner;
- (void)_setShowOpaqueGrowBoxForOwner:(id)owner;
- (BOOL)_updateGrowBoxForWindowFrameChange;
@end
@@ -108,11 +110,6 @@ typedef HashMap<String, ValidationVector> ValidationMap;
RetainPtr<NSView> _layerHostingView;
- // FIXME: Remove _oldLayerHostingView.
-#if USE(ACCELERATED_COMPOSITING)
- NSView *_oldLayerHostingView;
-#endif
-
RetainPtr<id> _remoteAccessibilityChild;
// For asynchronous validation.
@@ -124,7 +121,8 @@ typedef HashMap<String, ValidationVector> ValidationMap;
// We keep here the event when resending it to
// the application to distinguish the case of a new event from one
// that has been already sent to WebCore.
- NSEvent *_keyDownEventBeingResent;
+ RetainPtr<NSEvent> _keyDownEventBeingResent;
+ bool _isInInterpretKeyEvents;
Vector<KeypressCommand> _commandsList;
NSSize _resizeScrollOffset;
@@ -145,6 +143,13 @@ typedef HashMap<String, ValidationVector> ValidationMap;
#if ENABLE(GESTURE_EVENTS)
id _endGestureMonitor;
#endif
+
+#if ENABLE(FULLSCREEN_API)
+ RetainPtr<WKFullScreenWindowController> _fullScreenWindowController;
+#endif
+
+ BOOL _hasSpellCheckerDocumentTag;
+ NSInteger _spellCheckerDocumentTag;
}
@end
@@ -158,12 +163,6 @@ typedef HashMap<String, ValidationVector> ValidationMap;
@implementation WKView
-// FIXME: Remove this once we no longer want to be able to go back to the old drawing area.
-static bool useNewDrawingArea()
-{
- return true;
-}
-
- (id)initWithFrame:(NSRect)frame
{
return [self initWithFrame:frame contextRef:toAPI(WebContext::sharedProcessContext())];
@@ -223,6 +222,9 @@ static bool useNewDrawingArea()
_data->_pageClient = PageClientImpl::create(self);
_data->_page = toImpl(contextRef)->createWebPage(_data->_pageClient.get(), toImpl(pageGroupRef));
_data->_page->initializeWebPage();
+#if ENABLE(FULLSCREEN_API)
+ _data->_page->fullScreenManager()->setWebView(self);
+#endif
_data->_mouseDownEvent = nil;
_data->_ignoringMouseDraggedEvents = NO;
@@ -238,6 +240,7 @@ static bool useNewDrawingArea()
_data->_page->close();
[_data release];
+ _data = nil;
WebContext::statistics().wkViewCount--;
@@ -496,6 +499,8 @@ WEBCORE_COMMAND(yankAndSelect)
#undef WEBCORE_COMMAND
+// This method is needed to support Mac OS X services.
+
- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pasteboard types:(NSArray *)types
{
Vector<String> pasteboardTypes;
@@ -505,6 +510,8 @@ WEBCORE_COMMAND(yankAndSelect)
return _data->_page->writeSelectionToPasteboard([pasteboard name], pasteboardTypes);
}
+// This method is needed to support Mac OS X services.
+
- (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType
{
BOOL isValidSendType = !sendType || ([PasteboardTypes::forSelection() containsObject:sendType] && !_data->_page->selectionState().isNone);
@@ -520,6 +527,13 @@ WEBCORE_COMMAND(yankAndSelect)
return [[self nextResponder] validRequestorForSendType:sendType returnType:returnType];
}
+// This method is needed to support Mac OS X services.
+
+- (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pasteboard
+{
+ return _data->_page->readSelectionFromPasteboard([pasteboard name]);
+}
+
/*
When possible, editing-related methods should be implemented in WebCore with the
@@ -589,12 +603,8 @@ static void validateCommandCallback(WKStringRef commandName, bool isEnabled, int
SEL action = [item action];
if (action == @selector(showGuessPanel:)) {
- if (NSMenuItem *menuItem = ::menuItem(item)) {
- BOOL panelShowing = [[[NSSpellChecker sharedSpellChecker] spellingPanel] isVisible];
- [menuItem setTitle:panelShowing
- ? UI_STRING("Hide Spelling and Grammar", "menu item title")
- : UI_STRING("Show Spelling and Grammar", "menu item title")];
- }
+ if (NSMenuItem *menuItem = ::menuItem(item))
+ [menuItem setTitle:contextMenuItemTagShowSpellingPanel([[[NSSpellChecker sharedSpellChecker] spellingPanel] isVisible])];
return _data->_page->selectionState().isContentEditable;
}
@@ -621,12 +631,8 @@ static void validateCommandCallback(WKStringRef commandName, bool isEnabled, int
}
if (action == @selector(orderFrontSubstitutionsPanel:)) {
- if (NSMenuItem *menuItem = ::menuItem(item)) {
- BOOL panelShowing = [[[NSSpellChecker sharedSpellChecker] substitutionsPanel] isVisible];
- [menuItem setTitle:panelShowing
- ? UI_STRING("Hide Substitutions", "menu item title")
- : UI_STRING("Show Substitutions", "menu item title")];
- }
+ if (NSMenuItem *menuItem = ::menuItem(item))
+ [menuItem setTitle:contextMenuItemTagShowSubstitutions([[[NSSpellChecker sharedSpellChecker] substitutionsPanel] isVisible])];
return _data->_page->selectionState().isContentEditable;
}
@@ -1010,6 +1016,12 @@ static const short kIOHIDEventTypeScroll = 6;
- (void)doCommandBySelector:(SEL)selector
{
+ LOG(TextInput, "doCommandBySelector:\"%s\"", sel_getName(selector));
+
+ if (!_data->_isInInterpretKeyEvents) {
+ [super doCommandBySelector:selector];
+ return;
+ }
if (selector != @selector(noop:))
_data->_commandsList.append(KeypressCommand(commandNameForSelector(selector)));
}
@@ -1034,9 +1046,13 @@ static const short kIOHIDEventTypeScroll = 6;
isFromInputMethod = YES;
} else
text = string;
-
+
String eventText = text;
+ // We'd need a different code path here if we wanted to be able to handle this
+ // outside of interpretKeyEvents.
+ ASSERT(_data->_isInInterpretKeyEvents);
+
if (!isFromInputMethod)
_data->_commandsList.append(KeypressCommand("insertText", text));
else {
@@ -1085,9 +1101,6 @@ static const short kIOHIDEventTypeScroll = 6;
// But don't do it if we have already handled the event.
// Pressing Esc results in a fake event being sent - don't pass it to WebCore.
if (!eventWasSentToWebCore && event == [NSApp currentEvent] && self == [[self window] firstResponder]) {
- [_data->_keyDownEventBeingResent release];
- _data->_keyDownEventBeingResent = nil;
-
_data->_page->handleKeyboardEvent(NativeWebKeyboardEvent(event, self));
return YES;
}
@@ -1102,6 +1115,11 @@ static const short kIOHIDEventTypeScroll = 6;
- (void)keyDown:(NSEvent *)theEvent
{
+ // There's a chance that responding to this event will run a nested event loop, and
+ // fetching a new event might release the old one. Retaining and then autoreleasing
+ // the current event prevents that from causing a problem inside WebKit or AppKit code.
+ [[theEvent retain] autorelease];
+
if (_data->_pluginComplexTextInputIdentifier) {
// Try feeding the keyboard event directly to the plug-in.
NSString *string = nil;
@@ -1120,8 +1138,6 @@ static const short kIOHIDEventTypeScroll = 6;
// there is no range selection).
// If this is the case we should ignore the key down.
if (_data->_keyDownEventBeingResent == theEvent) {
- [_data->_keyDownEventBeingResent release];
- _data->_keyDownEventBeingResent = nil;
[super keyDown:theEvent];
return;
}
@@ -1129,7 +1145,7 @@ static const short kIOHIDEventTypeScroll = 6;
}
- (NSTextInputContext *)inputContext {
- if (_data->_pluginComplexTextInputIdentifier)
+ if (_data->_pluginComplexTextInputIdentifier && !_data->_isInInterpretKeyEvents)
return [[WKTextInputWindowController sharedTextInputWindowController] inputContext];
return [super inputContext];
@@ -1153,7 +1169,11 @@ static const short kIOHIDEventTypeScroll = 6;
- (void)unmarkText
{
LOG(TextInput, "unmarkText");
-
+
+ // We'd need a different code path here if we wanted to be able to handle this
+ // outside of interpretKeyEvents.
+ ASSERT(_data->_isInInterpretKeyEvents);
+
_data->_commandsList.append(KeypressCommand("unmarkText"));
}
@@ -1208,6 +1228,10 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
extractUnderlines(string, _data->_underlines);
}
+ // We'd need a different code path here if we wanted to be able to handle this
+ // outside of interpretKeyEvents.
+ ASSERT(_data->_isInInterpretKeyEvents);
+
_data->_commandsList.append(KeypressCommand("setMarkedText", text));
_data->_selectionStart = newSelRange.location;
_data->_selectionEnd = NSMaxRange(newSelRange);
@@ -1418,10 +1442,15 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
- (void)viewWillMoveToWindow:(NSWindow *)window
{
- if (window != [self window]) {
- [self removeWindowObservers];
- [self addWindowObserversForWindow:window];
- }
+ NSWindow *currentWindow = [self window];
+ if (window == currentWindow)
+ return;
+
+ [self removeWindowObservers];
+ [self addWindowObserversForWindow:window];
+
+ if ([currentWindow _growBoxOwner] == self)
+ [currentWindow _setShowOpaqueGrowBoxForOwner:nil];
}
- (void)viewDidMoveToWindow
@@ -1438,7 +1467,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
// Initialize remote accessibility when the window connection has been established.
#if !defined(BUILDING_ON_SNOW_LEOPARD)
NSData *remoteElementToken = WKAXRemoteTokenForElement(self);
- NSData *remoteWindowToken = WKAXRemoteTokenForElement([self window]);
+ NSData *remoteWindowToken = WKAXRemoteTokenForElement([self accessibilityAttributeValue:NSAccessibilityWindowAttribute]);
CoreIPC::DataReference elementToken = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>([remoteElementToken bytes]), [remoteElementToken length]);
CoreIPC::DataReference windowToken = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>([remoteWindowToken bytes]), [remoteWindowToken length]);
_data->_page->registerUIProcessAccessibilityTokens(elementToken, windowToken);
@@ -1454,6 +1483,9 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
_data->_endGestureMonitor = nil;
}
#endif
+#if !defined(BUILDING_ON_SNOW_LEOPARD)
+ WKHideWordDefinitionWindow();
+#endif
}
}
@@ -1510,37 +1542,25 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
{
LOG(View, "drawRect: x:%g, y:%g, width:%g, height:%g", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
_data->_page->endPrinting();
- if (useNewDrawingArea()) {
- CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]);
-
- if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(_data->_page->drawingArea())) {
- const NSRect *rectsBeingDrawn;
- NSInteger numRectsBeingDrawn;
- [self getRectsBeingDrawn:&rectsBeingDrawn count:&numRectsBeingDrawn];
- for (NSInteger i = 0; i < numRectsBeingDrawn; ++i) {
- Region unpaintedRegion;
- IntRect rect = enclosingIntRect(rectsBeingDrawn[i]);
- drawingArea->paint(context, rect, unpaintedRegion);
-
- Vector<IntRect> unpaintedRects = unpaintedRegion.rects();
- for (size_t i = 0; i < unpaintedRects.size(); ++i)
- drawPageBackground(context, _data->_page.get(), unpaintedRects[i]);
- }
- } else
- drawPageBackground(context, _data->_page.get(), enclosingIntRect(rect));
-
- _data->_page->didDraw();
- return;
- }
+ CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]);
+
+ if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(_data->_page->drawingArea())) {
+ const NSRect *rectsBeingDrawn;
+ NSInteger numRectsBeingDrawn;
+ [self getRectsBeingDrawn:&rectsBeingDrawn count:&numRectsBeingDrawn];
+ for (NSInteger i = 0; i < numRectsBeingDrawn; ++i) {
+ Region unpaintedRegion;
+ IntRect rect = enclosingIntRect(rectsBeingDrawn[i]);
+ drawingArea->paint(context, rect, unpaintedRegion);
+
+ Vector<IntRect> unpaintedRects = unpaintedRegion.rects();
+ for (size_t i = 0; i < unpaintedRects.size(); ++i)
+ drawPageBackground(context, _data->_page.get(), unpaintedRects[i]);
+ }
+ } else
+ drawPageBackground(context, _data->_page.get(), enclosingIntRect(rect));
- if (_data->_page->isValid() && _data->_page->drawingArea()) {
- CGContextRef context = static_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]);
- _data->_page->drawingArea()->paint(IntRect(rect), context);
- _data->_page->didDraw();
- } else if (_data->_page->drawsBackground()) {
- [_data->_page->drawsTransparentBackground() ? [NSColor clearColor] : [NSColor whiteColor] set];
- NSRectFill(rect);
- }
+ _data->_page->didDraw();
}
- (BOOL)isOpaque
@@ -1567,6 +1587,9 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
- (id)accessibilityFocusedUIElement
{
+ if (_data->_pdfViewController)
+ return NSAccessibilityUnignoredDescendant(_data->_pdfViewController->pdfView());
+
return _data->_remoteAccessibilityChild.get();
}
@@ -1577,15 +1600,25 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
- (id)accessibilityHitTest:(NSPoint)point
{
+ if (_data->_pdfViewController)
+ return [_data->_pdfViewController->pdfView() accessibilityHitTest:point];
+
return _data->_remoteAccessibilityChild.get();
}
- (id)accessibilityAttributeValue:(NSString*)attribute
{
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
- if (!_data->_remoteAccessibilityChild)
+
+ id child = nil;
+ if (_data->_pdfViewController)
+ child = NSAccessibilityUnignoredDescendant(_data->_pdfViewController->pdfView());
+ else if (_data->_remoteAccessibilityChild)
+ child = _data->_remoteAccessibilityChild.get();
+
+ if (!child)
return nil;
- return [NSArray arrayWithObject:_data->_remoteAccessibilityChild.get()];
+ return [NSArray arrayWithObject:child];
}
if ([attribute isEqualToString:NSAccessibilityRoleAttribute])
return NSAccessibilityGroupRole;
@@ -1605,10 +1638,6 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
if (hitView && _data && hitView == _data->_layerHostingView)
hitView = self;
-#if USE(ACCELERATED_COMPOSITING)
- if (hitView && _data && hitView == _data->_oldLayerHostingView)
- hitView = self;
-#endif
return hitView;
}
@@ -1634,7 +1663,7 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
return 0;
return _data->_pdfViewController->makePrintOperation(printInfo);
} else {
- RetainPtr<WKPrintingView> printingView(AdoptNS, [[WKPrintingView alloc] initWithFrameProxy:toImpl(frameRef)]);
+ RetainPtr<WKPrintingView> printingView(AdoptNS, [[WKPrintingView alloc] initWithFrameProxy:toImpl(frameRef) view:self]);
// NSPrintOperation takes ownership of the view.
NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView:printingView.get()];
[printOperation setCanSpawnSeparateThread:YES];
@@ -1649,10 +1678,7 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
- (PassOwnPtr<WebKit::DrawingAreaProxy>)_createDrawingAreaProxy
{
- if (useNewDrawingArea())
- return DrawingAreaProxyImpl::create(_data->_page.get());
-
- return ChunkedUpdateDrawingAreaProxy::create(self, _data->_page.get());
+ return DrawingAreaProxyImpl::create(_data->_page.get());
}
- (BOOL)_isFocused
@@ -1708,21 +1734,33 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
}
}
-- (void)_setEventBeingResent:(NSEvent *)event
+- (void)_resendKeyDownEvent:(NSEvent *)event
{
- _data->_keyDownEventBeingResent = [event retain];
+ ASSERT(!_data->_keyDownEventBeingResent);
+ _data->_keyDownEventBeingResent = event;
+ [NSApp _setCurrentEvent:event];
+ [NSApp sendEvent:event];
+
+ _data->_keyDownEventBeingResent = nullptr;
}
- (Vector<KeypressCommand>&)_interceptKeyEvent:(NSEvent *)theEvent
{
+ ASSERT(!_data->_isInInterpretKeyEvents);
+
+ _data->_isInInterpretKeyEvents = true;
_data->_commandsList.clear();
- // interpretKeyEvents will trigger one or more calls to doCommandBySelector or setText
+
+ // Calling interpretKeyEvents will trigger one or more calls to doCommandBySelector and insertText
// that will populate the commandsList vector.
[self interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
+
+ _data->_isInInterpretKeyEvents = false;
+
return _data->_commandsList;
}
-- (void)_getTextInputState:(unsigned)start selectionEnd:(unsigned)end underlines:(Vector<WebCore::CompositionUnderline>&)lines
+- (void)_getTextInputState:(unsigned)start selectionEnd:(unsigned)end underlines:(Vector<CompositionUnderline>&)lines
{
start = _data->_selectionStart;
end = _data->_selectionEnd;
@@ -1771,20 +1809,23 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
- (void)removeTrackingRect:(NSTrackingRectTag)tag
{
+ if (!_data)
+ return;
+
if (tag == 0)
return;
- if (_data && (tag == TRACKING_RECT_TAG)) {
+ if (tag == TRACKING_RECT_TAG) {
_data->_trackingRectOwner = nil;
return;
}
- if (_data && (tag == _data->_lastToolTipTag)) {
+ if (tag == _data->_lastToolTipTag) {
[super removeTrackingRect:tag];
_data->_lastToolTipTag = 0;
return;
}
-
+
// If any other tracking rect is being removed, we don't know how it was created
// and it's possible there's a leak involved (see 3500217)
ASSERT_NOT_REACHED();
@@ -2001,6 +2042,17 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
[self _updateGrowBoxForWindowFrameChange];
}
+#if ENABLE(FULLSCREEN_API)
+- (WKFullScreenWindowController*)fullScreenWindowController
+{
+ if (!_data->_fullScreenWindowController) {
+ _data->_fullScreenWindowController.adoptNS([[WKFullScreenWindowController alloc] init]);
+ [_data->_fullScreenWindowController.get() setWebView:self];
+ }
+ return _data->_fullScreenWindowController.get();
+}
+#endif
+
@end
@implementation WKView (Private)
@@ -2033,5 +2085,19 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I
_data->_page->performDictionaryLookupAtLocation(FloatPoint(thePoint.x, thePoint.y));
}
+- (NSInteger)spellCheckerDocumentTag
+{
+ if (!_data->_hasSpellCheckerDocumentTag) {
+ _data->_spellCheckerDocumentTag = [NSSpellChecker uniqueSpellDocumentTag];
+ _data->_hasSpellCheckerDocumentTag = YES;
+ }
+ return _data->_spellCheckerDocumentTag;
+}
+
+- (void)handleCorrectionPanelResult:(NSString*)result
+{
+ _data->_page->handleCorrectionPanelResult(result);
+}
+
@end