diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2013-09-13 12:51:20 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-19 20:50:05 +0200 |
commit | d441d6f39bb846989d95bcf5caf387b42414718d (patch) | |
tree | e367e64a75991c554930278175d403c072de6bb8 /Source/WebKit2/UIProcess/API/mac | |
parent | 0060b2994c07842f4c59de64b5e3e430525c4b90 (diff) | |
download | qtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz |
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit.
Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/WebKit2/UIProcess/API/mac')
22 files changed, 877 insertions, 447 deletions
diff --git a/Source/WebKit2/UIProcess/API/mac/FindIndicatorWindow.mm b/Source/WebKit2/UIProcess/API/mac/FindIndicatorWindow.mm index 0e6a6f130..19d696670 100644 --- a/Source/WebKit2/UIProcess/API/mac/FindIndicatorWindow.mm +++ b/Source/WebKit2/UIProcess/API/mac/FindIndicatorWindow.mm @@ -148,7 +148,7 @@ void FindIndicatorWindow::setFindIndicator(PassRefPtr<FindIndicator> findIndicat NSRect windowContentRect = [NSWindow contentRectForFrameRect:windowFrameRect styleMask:NSBorderlessWindowMask]; - m_findIndicatorWindow.adoptNS([[NSWindow alloc] initWithContentRect:windowContentRect + m_findIndicatorWindow = adoptNS([[NSWindow alloc] initWithContentRect:windowContentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]); @@ -157,7 +157,7 @@ void FindIndicatorWindow::setFindIndicator(PassRefPtr<FindIndicator> findIndicat [m_findIndicatorWindow.get() setOpaque:NO]; [m_findIndicatorWindow.get() setIgnoresMouseEvents:YES]; - RetainPtr<WKFindIndicatorView> findIndicatorView(AdoptNS, [[WKFindIndicatorView alloc] _initWithFindIndicator:m_findIndicator]); + RetainPtr<WKFindIndicatorView> findIndicatorView = adoptNS([[WKFindIndicatorView alloc] _initWithFindIndicator:m_findIndicator]); [m_findIndicatorWindow.get() setContentView:findIndicatorView.get()]; [[m_wkView window] addChildWindow:m_findIndicatorWindow.get() ordered:NSWindowAbove]; @@ -166,7 +166,7 @@ void FindIndicatorWindow::setFindIndicator(PassRefPtr<FindIndicator> findIndicat if (animate) { // Start the bounce animation. m_bounceAnimationContext = WKWindowBounceAnimationContextCreate(m_findIndicatorWindow.get()); - m_bounceAnimation.adoptNS([[WKFindIndicatorWindowAnimation alloc] _initWithFindIndicatorWindow:this + m_bounceAnimation = adoptNS([[WKFindIndicatorWindowAnimation alloc] _initWithFindIndicatorWindow:this animationDuration:bounceAnimationDuration animationProgressCallback:&FindIndicatorWindow::bounceAnimationCallback animationDidEndCallback:&FindIndicatorWindow::bounceAnimationDidEnd]); @@ -206,7 +206,7 @@ void FindIndicatorWindow::startFadeOutTimerFired() { ASSERT(!m_fadeOutAnimation); - m_fadeOutAnimation.adoptNS([[WKFindIndicatorWindowAnimation alloc] _initWithFindIndicatorWindow:this + m_fadeOutAnimation = adoptNS([[WKFindIndicatorWindowAnimation alloc] _initWithFindIndicatorWindow:this animationDuration:fadeOutAnimationDuration animationProgressCallback:&FindIndicatorWindow::fadeOutAnimationCallback animationDidEndCallback:&FindIndicatorWindow::fadeOutAnimationDidEnd]); diff --git a/Source/WebKit2/UIProcess/API/mac/PDFViewController.h b/Source/WebKit2/UIProcess/API/mac/PDFViewController.h index 46aaf8458..265d7d692 100644 --- a/Source/WebKit2/UIProcess/API/mac/PDFViewController.h +++ b/Source/WebKit2/UIProcess/API/mac/PDFViewController.h @@ -31,6 +31,7 @@ #include <wtf/Noncopyable.h> #include <wtf/PassOwnPtr.h> #include <wtf/RetainPtr.h> +#include <wtf/text/WTFString.h> @class PDFView; @class WKView; @@ -79,8 +80,6 @@ private: static Class pdfDocumentClass(); static NSBundle* pdfKitBundle(); - NSString *pathToPDFOnDisk(); - WKView* m_wkView; RetainPtr<WKPDFView> m_wkPDFView; @@ -89,8 +88,7 @@ private: RetainPtr<NSString> m_suggestedFilename; RetainPtr<CFDataRef> m_pdfData; - RetainPtr<NSString> m_pathToPDFOnDisk; - bool m_hasWrittenPDFToDisk; + String m_temporaryPDFUUID; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/mac/PDFViewController.mm b/Source/WebKit2/UIProcess/API/mac/PDFViewController.mm index 7b03a5645..8436c5dc8 100644 --- a/Source/WebKit2/UIProcess/API/mac/PDFViewController.mm +++ b/Source/WebKit2/UIProcess/API/mac/PDFViewController.mm @@ -36,6 +36,7 @@ #import "WebPreferences.h" #import <PDFKit/PDFKit.h> #import <WebCore/LocalizedStrings.h> +#import <WebCore/UUID.h> #import <wtf/ObjcRuntimeExtras.h> #import <wtf/text/CString.h> #import <wtf/text/WTFString.h> @@ -45,6 +46,7 @@ #define _webkit_PDFViewScaleChangedNotification @"PDFViewScaleChanged" #define _webkit_PDFViewPageChangedNotification @"PDFViewChangedPage" +using namespace WebCore; using namespace WebKit; @class PDFDocument; @@ -132,7 +134,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec Class previewViewClass = PDFViewController::pdfPreviewViewClass(); ASSERT(previewViewClass); - _pdfPreviewView.adoptNS([[previewViewClass alloc] initWithFrame:frame]); + _pdfPreviewView = adoptNS([[previewViewClass alloc] initWithFrame:frame]); [_pdfPreviewView.get() setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [self addSubview:_pdfPreviewView.get()]; @@ -401,9 +403,8 @@ PassOwnPtr<PDFViewController> PDFViewController::create(WKView *wkView) PDFViewController::PDFViewController(WKView *wkView) : m_wkView(wkView) - , m_wkPDFView(AdoptNS, [[WKPDFView alloc] initWithFrame:[m_wkView bounds] PDFViewController:this]) + , m_wkPDFView(adoptNS([[WKPDFView alloc] initWithFrame:[m_wkView bounds] PDFViewController:this])) , m_pdfView([m_wkPDFView.get() pdfView]) - , m_hasWrittenPDFToDisk(false) { [m_wkView addSubview:m_wkPDFView.get()]; } @@ -431,18 +432,18 @@ static RetainPtr<CFDataRef> convertPostScriptDataSourceToPDF(const CoreIPC::Data // http://developer.apple.com/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_ps_convert/chapter_16_section_1.html CGPSConverterCallbacks callbacks = { 0, 0, 0, 0, 0, 0, 0, 0 }; - RetainPtr<CGPSConverterRef> converter(AdoptCF, CGPSConverterCreate(0, &callbacks, 0)); + RetainPtr<CGPSConverterRef> converter = adoptCF(CGPSConverterCreate(0, &callbacks, 0)); ASSERT(converter); - RetainPtr<NSData> nsData(AdoptNS, [[NSData alloc] initWithBytesNoCopy:const_cast<uint8_t*>(dataReference.data()) length:dataReference.size() freeWhenDone:NO]); + RetainPtr<NSData> nsData = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<uint8_t*>(dataReference.data()) length:dataReference.size() freeWhenDone:NO]); - RetainPtr<CGDataProviderRef> provider(AdoptCF, CGDataProviderCreateWithCFData((CFDataRef)nsData.get())); + RetainPtr<CGDataProviderRef> provider = adoptCF(CGDataProviderCreateWithCFData((CFDataRef)nsData.get())); ASSERT(provider); - RetainPtr<CFMutableDataRef> result(AdoptCF, CFDataCreateMutable(kCFAllocatorDefault, 0)); + RetainPtr<CFMutableDataRef> result = adoptCF(CFDataCreateMutable(kCFAllocatorDefault, 0)); ASSERT(result); - RetainPtr<CGDataConsumerRef> consumer(AdoptCF, CGDataConsumerCreateWithCFData(result.get())); + RetainPtr<CGDataConsumerRef> consumer = adoptCF(CGDataConsumerCreateWithCFData(result.get())); ASSERT(consumer); CGPSConverterConvert(converter.get(), provider.get(), consumer.get(), 0); @@ -462,11 +463,11 @@ void PDFViewController::setPDFDocumentData(const String& mimeType, const String& m_suggestedFilename = String(suggestedFilename + ".pdf"); } else { // Make sure to copy the data. - m_pdfData.adoptCF(CFDataCreate(0, dataReference.data(), dataReference.size())); + m_pdfData = adoptCF(CFDataCreate(0, dataReference.data(), dataReference.size())); m_suggestedFilename = suggestedFilename; } - RetainPtr<PDFDocument> pdfDocument(AdoptNS, [[pdfDocumentClass() alloc] initWithData:(NSData *)m_pdfData.get()]); + RetainPtr<PDFDocument> pdfDocument = adoptNS([[pdfDocumentClass() alloc] initWithData:(NSData *)m_pdfData.get()]); [m_wkPDFView.get() setDocument:pdfDocument.get()]; } @@ -504,7 +505,6 @@ bool PDFViewController::forwardScrollWheelEvent(NSEvent *wheelEvent) return true; } -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 static IMP oldPDFViewScrollView_scrollWheel; static WKPDFView *findEnclosingWKPDFView(NSView *view) @@ -539,7 +539,6 @@ static void PDFViewScrollView_scrollWheel(NSScrollView* self, SEL _cmd, NSEvent wtfCallIMP<void>(oldPDFViewScrollView_scrollWheel, self, _cmd, wheelEvent); } -#endif NSBundle* PDFViewController::pdfKitBundle() { @@ -557,12 +556,10 @@ NSBundle* PDFViewController::pdfKitBundle() if (![pdfKitBundle load]) LOG_ERROR("Couldn't load PDFKit.framework"); -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 if (Class pdfViewScrollViewClass = [pdfKitBundle classNamed:@"PDFViewScrollView"]) { if (Method scrollWheel = class_getInstanceMethod(pdfViewScrollViewClass, @selector(scrollWheel:))) oldPDFViewScrollView_scrollWheel = method_setImplementation(scrollWheel, reinterpret_cast<IMP>(PDFViewScrollView_scrollWheel)); } -#endif return pdfKitBundle; } @@ -580,22 +577,14 @@ void PDFViewController::openPDFInFinder() return; } - NSString *path = pathToPDFOnDisk(); - if (!path) + if (!m_temporaryPDFUUID) { + ASSERT(m_pdfData); + m_temporaryPDFUUID = createCanonicalUUIDString(); + page()->savePDFToTemporaryFolderAndOpenWithNativeApplicationRaw(m_suggestedFilename.get(), page()->mainFrame()->url(), CFDataGetBytePtr(m_pdfData.get()), CFDataGetLength(m_pdfData.get()), m_temporaryPDFUUID); return; - - if (!m_hasWrittenPDFToDisk) { - // Create a PDF file with the minimal permissions (only accessible to the current user, see 4145714). - RetainPtr<NSNumber> permissions(AdoptNS, [[NSNumber alloc] initWithInt:S_IRUSR]); - RetainPtr<NSDictionary> fileAttributes(AdoptNS, [[NSDictionary alloc] initWithObjectsAndKeys:permissions.get(), NSFilePosixPermissions, nil]); - - if (![[NSFileManager defaultManager] createFileAtPath:path contents:(NSData *)m_pdfData.get() attributes:fileAttributes.get()]) - return; - - m_hasWrittenPDFToDisk = true; } - [[NSWorkspace sharedWorkspace] openFile:path]; + page()->openPDFFromTemporaryFolderWithNativeApplication(m_temporaryPDFUUID); } static void releaseCFData(unsigned char*, const void* data) @@ -624,50 +613,6 @@ void PDFViewController::savePDFToDownloadsFolder() page()->saveDataToFileInDownloadsFolder(m_suggestedFilename.get(), page()->mainFrame()->mimeType(), page()->mainFrame()->url(), data.get()); } -static NSString *temporaryPDFDirectoryPath() -{ - static NSString *temporaryPDFDirectoryPath; - - if (!temporaryPDFDirectoryPath) { - NSString *temporaryDirectoryTemplate = [NSTemporaryDirectory() stringByAppendingPathComponent:@"WebKitPDFs-XXXXXX"]; - CString templateRepresentation = [temporaryDirectoryTemplate fileSystemRepresentation]; - - if (mkdtemp(templateRepresentation.mutableData())) - temporaryPDFDirectoryPath = [[[NSFileManager defaultManager] stringWithFileSystemRepresentation:templateRepresentation.data() length:templateRepresentation.length()] copy]; - } - - return temporaryPDFDirectoryPath; -} - -NSString *PDFViewController::pathToPDFOnDisk() -{ - if (m_pathToPDFOnDisk) - return m_pathToPDFOnDisk.get(); - - NSString *pdfDirectoryPath = temporaryPDFDirectoryPath(); - if (!pdfDirectoryPath) - return nil; - - NSString *path = [pdfDirectoryPath stringByAppendingPathComponent:m_suggestedFilename.get()]; - - NSFileManager *fileManager = [NSFileManager defaultManager]; - if ([fileManager fileExistsAtPath:path]) { - NSString *pathTemplatePrefix = [pdfDirectoryPath stringByAppendingPathComponent:@"XXXXXX-"]; - NSString *pathTemplate = [pathTemplatePrefix stringByAppendingString:m_suggestedFilename.get()]; - CString pathTemplateRepresentation = [pathTemplate fileSystemRepresentation]; - - int fd = mkstemps(pathTemplateRepresentation.mutableData(), pathTemplateRepresentation.length() - strlen([pathTemplatePrefix fileSystemRepresentation]) + 1); - if (fd < 0) - return nil; - - close(fd); - path = [fileManager stringWithFileSystemRepresentation:pathTemplateRepresentation.data() length:pathTemplateRepresentation.length()]; - } - - m_pathToPDFOnDisk.adoptNS([path copy]); - return path; -} - void PDFViewController::linkClicked(const String& url) { NSEvent* nsEvent = [NSApp currentEvent]; diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h index 66b23e47c..5f747c0c5 100644 --- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h @@ -40,7 +40,7 @@ class AlternativeTextUIController; namespace WebKit { class FindIndicatorWindow; -class PageClientImpl : public PageClient { +class PageClientImpl FINAL : public PageClient { public: static PassOwnPtr<PageClientImpl> create(WKView*); virtual ~PageClientImpl(); @@ -53,6 +53,7 @@ private: virtual PassOwnPtr<DrawingAreaProxy> createDrawingAreaProxy(); virtual void setViewNeedsDisplay(const WebCore::IntRect&); virtual void displayView(); + virtual bool canScrollView(); virtual void scrollView(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset); virtual WebCore::IntSize viewSize(); @@ -67,6 +68,7 @@ private: virtual void processDidCrash(); virtual void pageClosed(); virtual void didRelaunchProcess(); + virtual void preferencesDidChange() OVERRIDE; virtual void toolTipChanged(const String& oldToolTip, const String& newToolTip); virtual void setCursor(const WebCore::Cursor&); virtual void setCursorHiddenUntilMouseMoves(bool); @@ -81,8 +83,9 @@ private: virtual void setDragImage(const WebCore::IntPoint& clientPosition, PassRefPtr<ShareableBitmap> dragImage, bool isLinkDrag); virtual void setPromisedData(const String& pasteboardName, PassRefPtr<WebCore::SharedBuffer> imageBuffer, const String& filename, const String& extension, const String& title, const String& url, const String& visibleUrl, PassRefPtr<WebCore::SharedBuffer> archiveBuffer); - virtual void updateTextInputState(bool updateSecureInputState); - virtual void resetTextInputState(); + virtual void updateSecureInputState() OVERRIDE; + virtual void resetSecureInputState() OVERRIDE; + virtual void notifyInputContextAboutDiscardedComposition() OVERRIDE; virtual WebCore::FloatRect convertToDeviceSpace(const WebCore::FloatRect&); virtual WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&); @@ -98,7 +101,7 @@ private: virtual PassRefPtr<WebContextMenuProxy> createContextMenuProxy(WebPageProxy*); #if ENABLE(INPUT_TYPE_COLOR) - virtual PassRefPtr<WebColorChooserProxy> createColorChooserProxy(WebPageProxy*, const WebCore::Color& initialColor, const WebCore::IntRect&); + virtual PassRefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& initialColor, const WebCore::IntRect&); #endif void setFindIndicator(PassRefPtr<FindIndicator>, bool fadeOut, bool animate); @@ -116,16 +119,6 @@ private: virtual CGContextRef containingWindowGraphicsContext(); - virtual void didChangeScrollbarsForMainFrame() const; - - virtual void didCommitLoadForMainFrame(bool useCustomRepresentation); - virtual void didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference&); - - virtual double customRepresentationZoomFactor(); - virtual void setCustomRepresentationZoomFactor(double); - virtual void findStringInCustomRepresentation(const String&, FindOptions, unsigned maxMatchCount); - virtual void countStringMatchesInCustomRepresentation(const String&, FindOptions, unsigned maxMatchCount); - virtual void flashBackingStoreUpdates(const Vector<WebCore::IntRect>& updateRects); virtual void didPerformDictionaryLookup(const AttributedString&, const DictionaryPopupInfo&); @@ -145,7 +138,6 @@ private: virtual uint64_t addDictationAlternatives(const RetainPtr<NSTextAlternatives>&); virtual void removeDictationAlternatives(uint64_t dictationContext); virtual void showDictationAlternativeUI(const WebCore::FloatRect& boundingBoxOfDictatedText, uint64_t dictationContext); - virtual void dismissDictationAlternativeUI(); virtual Vector<String> dictationAlternatives(uint64_t dictationContext); #endif diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm index 0172cb077..3d93314e6 100644 --- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm +++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm @@ -127,7 +127,7 @@ PassOwnPtr<PageClientImpl> PageClientImpl::create(WKView* wkView) PageClientImpl::PageClientImpl(WKView* wkView) : m_wkView(wkView) - , m_undoTarget(AdoptNS, [[WKEditorUndoTargetObjC alloc] init]) + , m_undoTarget(adoptNS([[WKEditorUndoTargetObjC alloc] init])) #if USE(DICTATION_ALTERNATIVES) , m_alternativeTextUIController(adoptPtr(new AlternativeTextUIController)) #endif @@ -153,6 +153,12 @@ void PageClientImpl::displayView() [m_wkView displayIfNeeded]; } +bool PageClientImpl::canScrollView() +{ + // -scrollRect:by: does nothing in layer-backed views <rdar://problem/12961719>. + return ![m_wkView layer]; +} + void PageClientImpl::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset) { NSRect clippedScrollRect = NSIntersectionRect(scrollRect, NSOffsetRect(scrollRect, -scrollOffset.width(), -scrollOffset.height())); @@ -191,9 +197,19 @@ bool PageClientImpl::isViewVisible() if (![[m_wkView window] isVisible]) return false; +#if __MAC_OS_X_VERSION_MIN_REQUIRED <= 1080 + // Mountain Lion and previous do not support occlusion notifications, and as such will + // continue to report as "visible" when not on the active space. + if (![[m_wkView window] isOnActiveSpace]) + return false; +#endif + if ([m_wkView isHiddenOrHasHiddenAncestor]) return false; + if ([m_wkView _isWindowOccluded]) + return false; + return true; } @@ -242,6 +258,11 @@ void PageClientImpl::didRelaunchProcess() [m_wkView _didRelaunchProcess]; } +void PageClientImpl::preferencesDidChange() +{ + [m_wkView _preferencesDidChange]; +} + void PageClientImpl::toolTipChanged(const String& oldToolTip, const String& newToolTip) { [m_wkView _toolTipChangedFrom:nsStringFromWebCoreString(oldToolTip) to:nsStringFromWebCoreString(newToolTip)]; @@ -266,7 +287,7 @@ void PageClientImpl::registerEditCommand(PassRefPtr<WebEditCommandProxy> prpComm { RefPtr<WebEditCommandProxy> command = prpCommand; - RetainPtr<WKEditCommandObjC> commandObjC(AdoptNS, [[WKEditCommandObjC alloc] initWithWebEditCommandProxy:command]); + RetainPtr<WKEditCommandObjC> commandObjC = adoptNS([[WKEditCommandObjC alloc] initWithWebEditCommandProxy:command]); String actionName = WebEditCommandProxy::nameForEditAction(command->editAction()); NSUndoManager *undoManager = [m_wkView undoManager]; @@ -298,7 +319,7 @@ bool PageClientImpl::interpretKeyEvent(const NativeWebKeyboardEvent& event, Vect void PageClientImpl::setDragImage(const IntPoint& clientPosition, PassRefPtr<ShareableBitmap> dragImage, bool isLinkDrag) { RetainPtr<CGImageRef> dragCGImage = dragImage->makeCGImage(); - RetainPtr<NSImage> dragNSImage(AdoptNS, [[NSImage alloc] initWithCGImage:dragCGImage.get() size:dragImage->size()]); + RetainPtr<NSImage> dragNSImage = adoptNS([[NSImage alloc] initWithCGImage:dragCGImage.get() size:dragImage->size()]); [m_wkView _setDragImage:dragNSImage.get() at:clientPosition linkDrag:isLinkDrag]; } @@ -310,14 +331,19 @@ void PageClientImpl::setPromisedData(const String& pasteboardName, PassRefPtr<Sh [m_wkView _setPromisedData:image.get() withFileName:filename withExtension:extension withTitle:title withURL:url withVisibleURL:visibleUrl withArchive:archiveBuffer.get() forPasteboard:pasteboardName]; } -void PageClientImpl::updateTextInputState(bool updateSecureInputState) +void PageClientImpl::updateSecureInputState() { - [m_wkView _updateTextInputStateIncludingSecureInputState:updateSecureInputState]; + [m_wkView _updateSecureInputState]; } -void PageClientImpl::resetTextInputState() +void PageClientImpl::resetSecureInputState() { - [m_wkView _resetTextInputState]; + [m_wkView _resetSecureInputState]; +} + +void PageClientImpl::notifyInputContextAboutDiscardedComposition() +{ + [m_wkView _notifyInputContextAboutDiscardedComposition]; } FloatRect PageClientImpl::convertToDeviceSpace(const FloatRect& rect) @@ -367,7 +393,7 @@ PassRefPtr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPagePr } #if ENABLE(INPUT_TYPE_COLOR) -PassRefPtr<WebColorChooserProxy> PageClientImpl::createColorChooserProxy(WebPageProxy*, const WebCore::Color&, const WebCore::IntRect&) +PassRefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy*, const WebCore::Color&, const WebCore::IntRect&) { notImplemented(); return 0; @@ -432,41 +458,6 @@ CGContextRef PageClientImpl::containingWindowGraphicsContext() return static_cast<CGContextRef>([[window graphicsContext] graphicsPort]); } -void PageClientImpl::didChangeScrollbarsForMainFrame() const -{ - [m_wkView _didChangeScrollbarsForMainFrame]; -} - -void PageClientImpl::didCommitLoadForMainFrame(bool useCustomRepresentation) -{ - [m_wkView _setPageHasCustomRepresentation:useCustomRepresentation]; -} - -void PageClientImpl::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference& dataReference) -{ - [m_wkView _didFinishLoadingDataForCustomRepresentationWithSuggestedFilename:suggestedFilename dataReference:dataReference]; -} - -double PageClientImpl::customRepresentationZoomFactor() -{ - return [m_wkView _customRepresentationZoomFactor]; -} - -void PageClientImpl::setCustomRepresentationZoomFactor(double zoomFactor) -{ - [m_wkView _setCustomRepresentationZoomFactor:zoomFactor]; -} - -void PageClientImpl::findStringInCustomRepresentation(const String& string, FindOptions options, unsigned maxMatchCount) -{ - [m_wkView _findStringInCustomRepresentation:string withFindOptions:options maxMatchCount:maxMatchCount]; -} - -void PageClientImpl::countStringMatchesInCustomRepresentation(const String& string, FindOptions options, unsigned maxMatchCount) -{ - [m_wkView _countStringMatchesInCustomRepresentation:string withFindOptions:options maxMatchCount:maxMatchCount]; -} - void PageClientImpl::flashBackingStoreUpdates(const Vector<IntRect>&) { notImplemented(); @@ -477,24 +468,17 @@ void PageClientImpl::didPerformDictionaryLookup(const AttributedString& text, co RetainPtr<NSAttributedString> attributedString = text.string; NSPoint textBaselineOrigin = dictionaryPopupInfo.origin; -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 // Convert to screen coordinates. textBaselineOrigin = [m_wkView convertPoint:textBaselineOrigin toView:nil]; textBaselineOrigin = [m_wkView.window convertRectToScreen:NSMakeRect(textBaselineOrigin.x, textBaselineOrigin.y, 0, 0)].origin; WKShowWordDefinitionWindow(attributedString.get(), textBaselineOrigin, (NSDictionary *)dictionaryPopupInfo.options.get()); -#else - // If the dictionary lookup is being triggered by a hot key, force the overlay style. - NSDictionary *options = (dictionaryPopupInfo.type == DictionaryPopupInfo::HotKey) ? [NSDictionary dictionaryWithObject:NSDefinitionPresentationTypeOverlay forKey:NSDefinitionPresentationTypeKey] : 0; - [m_wkView showDefinitionForAttributedString:attributedString.get() range:NSMakeRange(0, [attributedString.get() length]) options:options baselineOriginProvider:^(NSRange adjustedRange) { return (NSPoint)textBaselineOrigin; }]; -#endif } void PageClientImpl::dismissDictionaryLookupPanel() { -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + // FIXME: We don't know which panel we are dismissing, it may not even be in the current page (see <rdar://problem/13875766>). WKHideWordDefinitionWindow(); -#endif } void PageClientImpl::showCorrectionPanel(AlternativeTextType type, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings) @@ -524,15 +508,12 @@ String PageClientImpl::dismissCorrectionPanelSoon(WebCore::ReasonForDismissingAl void PageClientImpl::recordAutocorrectionResponse(AutocorrectionResponseType responseType, const String& replacedString, const String& replacementString) { -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 NSCorrectionResponse response = responseType == AutocorrectionReverted ? NSCorrectionResponseReverted : NSCorrectionResponseEdited; CorrectionPanel::recordAutocorrectionResponse(m_wkView, response, replacedString, replacementString); -#endif } void PageClientImpl::recommendedScrollbarStyleDidChange(int32_t newStyle) { -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 NSArray *trackingAreas = [m_wkView trackingAreas]; NSUInteger count = [trackingAreas count]; ASSERT(count == 1); @@ -553,9 +534,6 @@ void PageClientImpl::recommendedScrollbarStyleDidChange(int32_t newStyle) userInfo:nil]; [m_wkView addTrackingArea:trackingArea]; [trackingArea release]; -#else - UNUSED_PARAM(newStyle); -#endif } void PageClientImpl::intrinsicContentSizeDidChange(const IntSize& intrinsicContentSize) @@ -592,11 +570,6 @@ Vector<String> PageClientImpl::dictationAlternatives(uint64_t dictationContext) { return m_alternativeTextUIController->alternativesForContext(dictationContext); } - -void PageClientImpl::dismissDictationAlternativeUI() -{ - m_alternativeTextUIController->dismissAlternatives(); -} #endif } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextController.h b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextController.h index 07bb9a8d2..6aa81c438 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextController.h +++ b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextController.h @@ -48,16 +48,23 @@ WK_EXPORT /* Load a request. This is only valid for requests of non-file: URLs. Passing a file: URL will throw an exception. */ - (void)loadRequest:(NSURLRequest *)request; +- (void)loadRequest:(NSURLRequest *)request userData:(id)userData; /* Load a file: URL. Opens the sandbox only for files within allowedDirectory. - - Passing a non-file: URL to either parameter will yeild an exception. + - Passing a non-file: URL to either parameter will yield an exception. - Passing nil as the allowedDirectory will open the entire file-system for - reading. + reading. */ - (void)loadFileURL:(NSURL *)URL restrictToFilesWithin:(NSURL *)allowedDirectory; +- (void)loadFileURL:(NSURL *)URL restrictToFilesWithin:(NSURL *)allowedDirectory userData:(id)userData; /* Load a page using the passed in string as its contents. */ - (void)loadHTMLString:(NSString *)HTMLString baseURL:(NSURL *)baseURL; +- (void)loadHTMLString:(NSString *)HTMLString baseURL:(NSURL *)baseURL userData:(id)userData; + +/* Load a page using the passed in data as its contents. */ +- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL; +- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL userData:(id)userData; /* Stops the load associated with the active URL. */ - (void)stopLoading; diff --git a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextController.mm b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextController.mm index d91019f72..f7120af2e 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextController.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextController.mm @@ -28,6 +28,7 @@ #import "WKBrowsingContextControllerPrivate.h" #import "WKBrowsingContextControllerInternal.h" +#import "ObjCObjectGraph.h" #import "WKErrorCF.h" #import "WKFrame.h" #import "WKPagePrivate.h" @@ -37,11 +38,14 @@ #import "WKURLRequest.h" #import "WKURLRequestNS.h" #import "WebContext.h" +#import "WebData.h" #import "WebPageProxy.h" #import <wtf/RetainPtr.h> #import "WKBrowsingContextLoadDelegate.h" +using namespace WebKit; + static inline NSString *autoreleased(WKStringRef string) { WKRetainPtr<WKStringRef> wkString = adoptWK(string); @@ -99,37 +103,67 @@ static inline NSURL *autoreleased(WKURLRef url) + (void)registerSchemeForCustomProtocol:(NSString *)scheme { + if (!scheme) + return; + NSString *lowercaseScheme = [scheme lowercaseString]; [[WKBrowsingContextController customSchemes] addObject:lowercaseScheme]; - [[NSNotificationCenter defaultCenter] postNotificationName:WebKit::SchemeForCustomProtocolRegisteredNotificationName object:lowercaseScheme]; + [[NSNotificationCenter defaultCenter] postNotificationName:SchemeForCustomProtocolRegisteredNotificationName object:lowercaseScheme]; } + (void)unregisterSchemeForCustomProtocol:(NSString *)scheme { + if (!scheme) + return; + NSString *lowercaseScheme = [scheme lowercaseString]; [[WKBrowsingContextController customSchemes] removeObject:lowercaseScheme]; - [[NSNotificationCenter defaultCenter] postNotificationName:WebKit::SchemeForCustomProtocolUnregisteredNotificationName object:lowercaseScheme]; + [[NSNotificationCenter defaultCenter] postNotificationName:SchemeForCustomProtocolUnregisteredNotificationName object:lowercaseScheme]; } - (void)loadRequest:(NSURLRequest *)request { + [self loadRequest:request userData:nil]; +} + +- (void)loadRequest:(NSURLRequest *)request userData:(id)userData +{ WKRetainPtr<WKURLRequestRef> wkRequest = adoptWK(WKURLRequestCreateWithNSURLRequest(request)); - WKPageLoadURLRequest(self._pageRef, wkRequest.get()); + + RefPtr<ObjCObjectGraph> wkUserData; + if (userData) + wkUserData = ObjCObjectGraph::create(userData); + + WKPageLoadURLRequestWithUserData(self._pageRef, wkRequest.get(), (WKTypeRef)wkUserData.get()); } - (void)loadFileURL:(NSURL *)URL restrictToFilesWithin:(NSURL *)allowedDirectory { - if (![URL isFileURL]) - return; + [self loadFileURL:URL restrictToFilesWithin:allowedDirectory userData:nil]; +} - /* FIXME: Implement restrictions. */ +- (void)loadFileURL:(NSURL *)URL restrictToFilesWithin:(NSURL *)allowedDirectory userData:(id)userData +{ + if (![URL isFileURL] || (allowedDirectory && ![allowedDirectory isFileURL])) + [NSException raise:NSInvalidArgumentException format:@"Attempted to load a non-file URL"]; WKRetainPtr<WKURLRef> wkURL = adoptWK(WKURLCreateWithCFURL((CFURLRef)URL)); - WKPageLoadURL(self._pageRef, wkURL.get()); + WKRetainPtr<WKURLRef> wkAllowedDirectory = adoptWK(WKURLCreateWithCFURL((CFURLRef)allowedDirectory)); + + RefPtr<ObjCObjectGraph> wkUserData; + if (userData) + wkUserData = ObjCObjectGraph::create(userData); + + WKPageLoadFileWithUserData(self._pageRef, wkURL.get(), wkAllowedDirectory.get(), (WKTypeRef)wkUserData.get()); } - (void)loadHTMLString:(NSString *)HTMLString baseURL:(NSURL *)baseURL { + [self loadHTMLString:HTMLString baseURL:baseURL userData:nil]; +} + +- (void)loadHTMLString:(NSString *)HTMLString baseURL:(NSURL *)baseURL userData:(id)userData +{ WKRetainPtr<WKStringRef> wkHTMLString; if (HTMLString) wkHTMLString = adoptWK(WKStringCreateWithCFString((CFStringRef)HTMLString)); @@ -138,7 +172,48 @@ static inline NSURL *autoreleased(WKURLRef url) if (baseURL) wkBaseURL = adoptWK(WKURLCreateWithCFURL((CFURLRef)baseURL)); - WKPageLoadHTMLString(self._pageRef, wkHTMLString.get(), wkBaseURL.get()); + RefPtr<ObjCObjectGraph> wkUserData; + if (userData) + wkUserData = ObjCObjectGraph::create(userData); + + WKPageLoadHTMLStringWithUserData(self._pageRef, wkHTMLString.get(), wkBaseURL.get(), (WKTypeRef)wkUserData.get()); +} + +- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL +{ + [self loadData:data MIMEType:MIMEType textEncodingName:encodingName baseURL:baseURL userData:nil]; +} + +static void releaseNSData(unsigned char*, const void* data) +{ + [(NSData *)data release]; +} + +- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL userData:(id)userData +{ + RefPtr<WebData> wkData; + if (data) { + [data retain]; + wkData = WebData::createWithoutCopying((const unsigned char*)[data bytes], [data length], releaseNSData, data); + } + + WKRetainPtr<WKStringRef> wkMIMEType; + if (MIMEType) + wkMIMEType = adoptWK(WKStringCreateWithCFString((CFStringRef)MIMEType)); + + WKRetainPtr<WKStringRef> wkEncodingName; + if (encodingName) + wkEncodingName = adoptWK(WKStringCreateWithCFString((CFStringRef)encodingName)); + + WKRetainPtr<WKURLRef> wkBaseURL; + if (baseURL) + wkBaseURL = adoptWK(WKURLCreateWithCFURL((CFURLRef)baseURL)); + + RefPtr<ObjCObjectGraph> wkUserData; + if (userData) + wkUserData = ObjCObjectGraph::create(userData); + + WKPageLoadDataWithUserData(self._pageRef, toAPI(wkData.get()), wkMIMEType.get(), wkEncodingName.get(), wkBaseURL.get(), (WKTypeRef)wkUserData.get()); } - (void)stopLoading @@ -340,7 +415,7 @@ static void didFailProvisionalLoadWithErrorForFrame(WKPageRef page, WKFrameRef f WKBrowsingContextController *browsingContext = (WKBrowsingContextController *)clientInfo; if ([browsingContext.loadDelegate respondsToSelector:@selector(browsingContextControllerDidFailProvisionalLoad:withError:)]) { - RetainPtr<CFErrorRef> cfError(AdoptCF, WKErrorCopyCFError(kCFAllocatorDefault, error)); + RetainPtr<CFErrorRef> cfError = adoptCF(WKErrorCopyCFError(kCFAllocatorDefault, error)); [browsingContext.loadDelegate browsingContextControllerDidFailProvisionalLoad:browsingContext withError:(NSError *)cfError.get()]; } } @@ -372,7 +447,7 @@ static void didFailLoadWithErrorForFrame(WKPageRef page, WKFrameRef frame, WKErr WKBrowsingContextController *browsingContext = (WKBrowsingContextController *)clientInfo; if ([browsingContext.loadDelegate respondsToSelector:@selector(browsingContextControllerDidFailLoad:withError:)]) { - RetainPtr<CFErrorRef> cfError(AdoptCF, WKErrorCopyCFError(kCFAllocatorDefault, error)); + RetainPtr<CFErrorRef> cfError = adoptCF(WKErrorCopyCFError(kCFAllocatorDefault, error)); [browsingContext.loadDelegate browsingContextControllerDidFailLoad:browsingContext withError:(NSError *)cfError.get()]; } } diff --git a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextControllerInternal.h b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextControllerInternal.h index fe895c923..1ec4b515c 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextControllerInternal.h +++ b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextControllerInternal.h @@ -33,8 +33,6 @@ /* Returns a WKBrowsingContextController associated with the WKPageRef. */ + (WKBrowsingContextController *)_browsingContextControllerForPageRef:(WKPageRef)pageRef; -@property(readonly) WKPageRef _pageRef; - + (NSMutableSet *)customSchemes; @end diff --git a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextControllerPrivate.h b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextControllerPrivate.h index 48fcb12f0..6c8cb49b2 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextControllerPrivate.h +++ b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextControllerPrivate.h @@ -36,6 +36,8 @@ typedef NSUInteger WKBrowsingContextPaginationMode; @interface WKBrowsingContextController (Private) +@property(readonly) WKPageRef _pageRef; + @property WKBrowsingContextPaginationMode paginationMode; // Whether the column-break-{before,after} properties are respected instead of the // page-break-{before,after} properties. diff --git a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextGroup.mm b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextGroup.mm index 5704dd72a..a24b015c9 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextGroup.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextGroup.mm @@ -25,7 +25,7 @@ #import "config.h" #import "WKBrowsingContextGroup.h" -#import "WKBrowsingContextGroupInternal.h" +#import "WKBrowsingContextGroupPrivate.h" #import "WKArray.h" #import "WKPageGroup.h" @@ -56,6 +56,12 @@ _data = [[WKBrowsingContextGroupData alloc] init]; _data->_pageGroupRef = adoptWK(WKPageGroupCreateWithIdentifier(adoptWK(WKStringCreateWithCFString((CFStringRef)identifier)).get())); + // Give the WKBrowsingContextGroup a identifier-less preferences, so that they + // don't get automatically written to the disk. The automatic writing has proven + // confusing to users of the API. + WKRetainPtr<WKPreferencesRef> preferences = adoptWK(WKPreferencesCreate()); + WKPageGroupSetPreferences(_data->_pageGroupRef.get(), preferences.get()); + return self; } @@ -75,6 +81,16 @@ WKPreferencesSetJavaScriptEnabled(WKPageGroupGetPreferences(self._pageGroupRef), allowsJavaScript); } +- (BOOL)allowsJavaScriptMarkup +{ + return WKPreferencesGetJavaScriptMarkupEnabled(WKPageGroupGetPreferences(self._pageGroupRef)); +} + +- (void)setAllowsJavaScriptMarkup:(BOOL)allowsJavaScriptMarkup +{ + WKPreferencesSetJavaScriptMarkupEnabled(WKPageGroupGetPreferences(self._pageGroupRef), allowsJavaScriptMarkup); +} + - (BOOL)allowsPlugIns { return WKPreferencesGetPluginsEnabled(WKPageGroupGetPreferences(self._pageGroupRef)); @@ -143,7 +159,7 @@ static WKArrayRef createWKArray(NSArray *array) @end -@implementation WKBrowsingContextGroup (Internal) +@implementation WKBrowsingContextGroup (Private) - (WKPageGroupRef)_pageGroupRef { diff --git a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextGroupInternal.h b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextGroupPrivate.h index 957c3b09b..d4f0fc416 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextGroupInternal.h +++ b/Source/WebKit2/UIProcess/API/mac/WKBrowsingContextGroupPrivate.h @@ -25,7 +25,7 @@ #import <WebKit2/WKBrowsingContextGroup.h> -@interface WKBrowsingContextGroup (Internal) +@interface WKBrowsingContextGroup (Private) @property(readonly) WKPageGroupRef _pageGroupRef; diff --git a/Source/WebKit2/UIProcess/API/mac/WKConnection.mm b/Source/WebKit2/UIProcess/API/mac/WKConnection.mm index 50efb79bc..3830e740f 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKConnection.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKConnection.mm @@ -88,10 +88,10 @@ static void didReceiveMessage(WKConnectionRef, WKStringRef messageName, WKTypeRe { WKConnection *connection = (WKConnection *)clientInfo; if ([connection.delegate respondsToSelector:@selector(connection:didReceiveMessageWithName:body:)]) { - RetainPtr<NSString> nsMessageName = adoptNS((NSString *)WKStringCopyCFString(kCFAllocatorDefault, messageName)); + RetainPtr<CFStringRef> nsMessageName = adoptCF(WKStringCopyCFString(kCFAllocatorDefault, messageName)); RetainPtr<id> nsMessageBody = ((ObjCObjectGraph*)messageBody)->rootObject(); - [connection.delegate connection:connection didReceiveMessageWithName:nsMessageName.get() body:nsMessageBody.get()]; + [connection.delegate connection:connection didReceiveMessageWithName:(NSString *)nsMessageName.get() body:nsMessageBody.get()]; } } diff --git a/Source/WebKit2/UIProcess/API/mac/WKPrintingView.h b/Source/WebKit2/UIProcess/API/mac/WKPrintingView.h index 67bd4b1b9..b45f635b3 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKPrintingView.h +++ b/Source/WebKit2/UIProcess/API/mac/WKPrintingView.h @@ -42,7 +42,7 @@ namespace WebKit { RefPtr<WebKit::WebFrameProxy> _webFrame; Vector<WebCore::IntRect> _printingPageRects; double _totalScaleFactorForPrinting; - HashMap<WebCore::IntRect, RefPtr<WebKit::ShareableBitmap> > _pagePreviews; + HashMap<WebCore::IntRect, RefPtr<WebKit::ShareableBitmap>> _pagePreviews; Vector<uint8_t> _printedPagesData; RetainPtr<PDFDocument> _printedPagesPDFDocument; diff --git a/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm b/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm index 0f53f99e9..350ad542e 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm @@ -472,13 +472,15 @@ static void prepareDataForPrintingOnSecondaryThread(void* untypedContext) { ASSERT(isMainThread()); - IntRect rect(nsRect); - rect.scale(1 / _totalScaleFactorForPrinting); - HashMap<WebCore::IntRect, RefPtr<ShareableBitmap> >::iterator pagePreviewIterator = _pagePreviews.find(rect); + IntRect scaledPrintingRect(nsRect); + scaledPrintingRect.scale(1 / _totalScaleFactorForPrinting); + IntSize imageSize(nsRect.size); + imageSize.scale(_webFrame->page()->deviceScaleFactor()); + HashMap<WebCore::IntRect, RefPtr<ShareableBitmap>>::iterator pagePreviewIterator = _pagePreviews.find(scaledPrintingRect); if (pagePreviewIterator == _pagePreviews.end()) { // It's too early to ask for page preview if we don't even know page size and scale. if ([self _hasPageRects]) { - if (uint64_t existingCallback = [self _expectedPreviewCallbackForRect:rect]) { + if (uint64_t existingCallback = [self _expectedPreviewCallbackForRect:scaledPrintingRect]) { // We've already asked for a preview of this page, and are waiting for response. // There is no need to ask again. _latestExpectedPreviewCallback = existingCallback; @@ -493,12 +495,12 @@ static void prepareDataForPrintingOnSecondaryThread(void* untypedContext) IPCCallbackContext* context = new IPCCallbackContext; RefPtr<ImageCallback> callback = ImageCallback::create(context, pageDidDrawToImage); _latestExpectedPreviewCallback = callback->callbackID(); - _expectedPreviewCallbacks.add(_latestExpectedPreviewCallback, rect); + _expectedPreviewCallbacks.add(_latestExpectedPreviewCallback, scaledPrintingRect); context->view = self; context->callbackID = callback->callbackID(); - _webFrame->page()->drawRectToImage(_webFrame.get(), PrintInfo([_printOperation printInfo]), rect, callback.get()); + _webFrame->page()->drawRectToImage(_webFrame.get(), PrintInfo([_printOperation printInfo]), scaledPrintingRect, imageSize, callback.get()); return; } } @@ -513,14 +515,7 @@ static void prepareDataForPrintingOnSecondaryThread(void* untypedContext) GraphicsContext context(cgContext); GraphicsContextStateSaver stateSaver(context); - context.translate(nsRect.origin.x, nsRect.origin.y); - context.scale(FloatSize(_totalScaleFactorForPrinting, _totalScaleFactorForPrinting)); - - // FIXME: Should we get the WebPage's deviceScaleFactor from here instead? - const IntRect& imageBounds = bitmap->bounds(); - float imageScaleFactor = imageBounds.width() / rect.width(); - - bitmap->paint(context, imageScaleFactor, IntPoint(), imageBounds); + bitmap->paint(context, _webFrame->page()->deviceScaleFactor(), IntPoint(nsRect.origin), bitmap->bounds()); } - (void)drawRect:(NSRect)nsRect @@ -541,8 +536,8 @@ static void prepareDataForPrintingOnSecondaryThread(void* untypedContext) ASSERT(!_printedPagesData.isEmpty()); // Prepared by knowsPageRange: if (!_printedPagesPDFDocument) { - RetainPtr<NSData> pdfData(AdoptNS, [[NSData alloc] initWithBytes:_printedPagesData.data() length:_printedPagesData.size()]); - _printedPagesPDFDocument.adoptNS([[pdfDocumentClass() alloc] initWithData:pdfData.get()]); + RetainPtr<NSData> pdfData = adoptNS([[NSData alloc] initWithBytes:_printedPagesData.data() length:_printedPagesData.size()]); + _printedPagesPDFDocument = adoptNS([[pdfDocumentClass() alloc] initWithData:pdfData.get()]); } unsigned printedPageNumber = [self _pageForRect:nsRect] - [self _firstPrintedPageNumber]; diff --git a/Source/WebKit2/UIProcess/API/mac/WKProcessGroup.h b/Source/WebKit2/UIProcess/API/mac/WKProcessGroup.h index d315ad78c..95944814a 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKProcessGroup.h +++ b/Source/WebKit2/UIProcess/API/mac/WKProcessGroup.h @@ -29,6 +29,11 @@ @class WKProcessGroup, WKProcessGroupData, WKConnection; @protocol WKProcessGroupDelegate <NSObject> +@optional + +- (id)processGroupWillCreateConnectionToWebProcessPlugIn:(WKProcessGroup *)processGroup; + +@required - (void)processGroup:(WKProcessGroup *)processGroup didCreateConnectionToWebProcessPlugIn:(WKConnection *)connection; diff --git a/Source/WebKit2/UIProcess/API/mac/WKProcessGroup.mm b/Source/WebKit2/UIProcess/API/mac/WKProcessGroup.mm index 8b4770046..044716b82 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKProcessGroup.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKProcessGroup.mm @@ -25,8 +25,9 @@ #import "config.h" #import "WKProcessGroup.h" -#import "WKProcessGroupInternal.h" +#import "WKProcessGroupPrivate.h" +#import "ObjCObjectGraph.h" #import "WKConnectionInternal.h" #import "WKContext.h" #import "WKRetainPtr.h" @@ -69,6 +70,30 @@ static void setUpConnectionClient(WKProcessGroup *processGroup, WKContextRef con WKContextSetConnectionClient(contextRef, &connectionClient); } +static WKTypeRef getInjectedBundleInitializationUserData(WKContextRef, const void* clientInfo) +{ + WKProcessGroup *processGroup = (WKProcessGroup *)clientInfo; + if ([processGroup.delegate respondsToSelector:@selector(processGroupWillCreateConnectionToWebProcessPlugIn:)]) { + RetainPtr<id> initializationUserData = [processGroup.delegate processGroupWillCreateConnectionToWebProcessPlugIn:processGroup]; + RefPtr<WebKit::ObjCObjectGraph> wkMessageBody = WebKit::ObjCObjectGraph::create(initializationUserData.get()); + return (WKTypeRef)wkMessageBody.release().leakRef(); + } + + return 0; +} + +static void setUpInectedBundleClient(WKProcessGroup *processGroup, WKContextRef contextRef) +{ + WKContextInjectedBundleClient injectedBundleClient; + memset(&injectedBundleClient, 0, sizeof(injectedBundleClient)); + + injectedBundleClient.version = kWKContextInjectedBundleClientCurrentVersion; + injectedBundleClient.clientInfo = processGroup; + injectedBundleClient.getInjectedBundleInitializationUserData = getInjectedBundleInitializationUserData; + + WKContextSetInjectedBundleClient(contextRef, &injectedBundleClient); +} + - (id)init { return [self initWithInjectedBundleURL:nil]; @@ -88,6 +113,7 @@ static void setUpConnectionClient(WKProcessGroup *processGroup, WKContextRef con _data->_contextRef = adoptWK(WKContextCreate()); setUpConnectionClient(self, _data->_contextRef.get()); + setUpInectedBundleClient(self, _data->_contextRef.get()); return self; } @@ -95,6 +121,7 @@ static void setUpConnectionClient(WKProcessGroup *processGroup, WKContextRef con - (void)dealloc { WKContextSetConnectionClient(_data->_contextRef.get(), 0); + WKContextSetInjectedBundleClient(_data->_contextRef.get(), 0); [_data release]; [super dealloc]; @@ -112,7 +139,7 @@ static void setUpConnectionClient(WKProcessGroup *processGroup, WKContextRef con @end -@implementation WKProcessGroup (Internal) +@implementation WKProcessGroup (Private) - (WKContextRef)_contextRef { @@ -120,5 +147,3 @@ static void setUpConnectionClient(WKProcessGroup *processGroup, WKContextRef con } @end - - diff --git a/Source/WebKit2/UIProcess/API/mac/WKProcessGroupInternal.h b/Source/WebKit2/UIProcess/API/mac/WKProcessGroupPrivate.h index 1a8bc2ae2..7a9d2f9c0 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKProcessGroupInternal.h +++ b/Source/WebKit2/UIProcess/API/mac/WKProcessGroupPrivate.h @@ -25,7 +25,7 @@ #import <WebKit2/WKProcessGroup.h> -@interface WKProcessGroup (Internal) +@interface WKProcessGroup (Private) @property(readonly) WKContextRef _contextRef; diff --git a/Source/WebKit2/UIProcess/API/mac/WKTypeRefWrapper.h b/Source/WebKit2/UIProcess/API/mac/WKTypeRefWrapper.h new file mode 100644 index 000000000..7b81e9a98 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/mac/WKTypeRefWrapper.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if defined(__LP64__) && defined(__clang__) + +#import <Foundation/Foundation.h> +#import <WebKit2/WKBase.h> + +WK_EXPORT +@interface WKTypeRefWrapper : NSObject + +- (id)initWithObject:(WKTypeRef)object; + +@property(readonly) WKTypeRef object; + +@end + +#endif diff --git a/Source/WebKit2/UIProcess/API/mac/WKTypeRefWrapper.mm b/Source/WebKit2/UIProcess/API/mac/WKTypeRefWrapper.mm new file mode 100644 index 000000000..fd80ac248 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/mac/WKTypeRefWrapper.mm @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" + +#if defined(__LP64__) && defined(__clang__) + +#import "WKTypeRefWrapper.h" + +#import "WKRetainPtr.h" + +@interface WKTypeRefWrapper () { + // Underlying WKTypeRef. + WKRetainPtr<WKTypeRef> _object; +} +@end + +@implementation WKTypeRefWrapper + +- (id)initWithObject:(WKTypeRef)object +{ + self = [super init]; + if (!self) + return nil; + + _object = object; + + return self; +} + +- (WKTypeRef)object +{ + return _object.get(); +} + +@end + +#endif // defined(__LP64__) && defined(__clang__) diff --git a/Source/WebKit2/UIProcess/API/mac/WKView.mm b/Source/WebKit2/UIProcess/API/mac/WKView.mm index b1470fea9..1d8760988 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKView.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKView.mm @@ -43,7 +43,6 @@ #import "NativeWebKeyboardEvent.h" #import "NativeWebMouseEvent.h" #import "NativeWebWheelEvent.h" -#import "PDFViewController.h" #import "PageClientImpl.h" #import "PasteboardTypes.h" #import "RemoteLayerTreeDrawingAreaProxy.h" @@ -62,10 +61,13 @@ #import "WebEventFactory.h" #import "WebFullScreenManagerProxy.h" #import "WebPage.h" +#import "WebPageGroup.h" #import "WebPageProxy.h" +#import "WebPreferences.h" #import "WebProcessProxy.h" #import "WebSystemInterface.h" #import <QuartzCore/QuartzCore.h> +#import <WebCore/AXObjectCache.h> #import <WebCore/ColorMac.h> #import <WebCore/DragController.h> #import <WebCore/DragData.h> @@ -82,6 +84,8 @@ #import <WebCore/SharedBuffer.h> #import <WebCore/TextAlternativeWithRange.h> #import <WebCore/WebCoreNSStringExtras.h> +#import <WebCore/WebCoreFullScreenPlaceholderView.h> +#import <WebCore/WebCoreFullScreenWindow.h> #import <WebCore/FileSystem.h> #import <WebKitSystemInterface.h> #import <sys/stat.h> @@ -90,9 +94,18 @@ /* API internals. */ #import "WKBrowsingContextControllerInternal.h" -#import "WKBrowsingContextGroupInternal.h" -#import "WKProcessGroupInternal.h" +#import "WKBrowsingContextGroupPrivate.h" +#import "WKProcessGroupPrivate.h" +inline bool isWKContentAnchorRight(WKContentAnchor x) +{ + return x == WKContentAnchorTopRight || x == WKContentAnchorBottomRight; +} + +inline bool isWKContentAnchorBottom(WKContentAnchor x) +{ + return x == WKContentAnchorBottomLeft || x == WKContentAnchorBottomRight; +} @interface NSApplication (WKNSApplicationDetails) - (void)speakString:(NSString *)string; @@ -105,13 +118,6 @@ @end @interface NSWindow (WKNSWindowDetails) -#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1060 -- (NSRect)_growBoxRect; -- (id)_growBoxOwner; -- (void)_setShowOpaqueGrowBoxForOwner:(id)owner; -- (BOOL)_updateGrowBoxForWindowFrameChange; -#endif - - (NSRect)_intersectBottomCornersWithRect:(NSRect)viewRect; - (void)_maskRoundedBottomCorners:(NSRect)clipRect; @end @@ -122,7 +128,7 @@ using namespace WebCore; namespace WebKit { typedef id <NSValidatedUserInterfaceItem> ValidationItem; -typedef Vector<RetainPtr<ValidationItem> > ValidationVector; +typedef Vector<RetainPtr<ValidationItem>> ValidationVector; typedef HashMap<String, ValidationVector> ValidationMap; } @@ -142,6 +148,10 @@ struct WKViewInterpretKeyEventsParameters { - (void)_setDrawingAreaSize:(NSSize)size; - (void)_setPluginComplexTextInputState:(PluginComplexTextInputState)pluginComplexTextInputState; - (BOOL)_shouldUseTiledDrawingArea; + +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 +- (void)_setIsWindowOccluded:(BOOL)isWindowOccluded; +#endif @end @interface WKViewData : NSObject { @@ -164,8 +174,6 @@ struct WKViewInterpretKeyEventsParameters { // For asynchronous validation. ValidationMap _validationMap; - OwnPtr<PDFViewController> _pdfViewController; - OwnPtr<FindIndicatorWindow> _findIndicatorWindow; // We keep here the event when resending it to // the application to distinguish the case of a new event from one @@ -203,6 +211,12 @@ struct WKViewInterpretKeyEventsParameters { NSRect _windowBottomCornerIntersectionRect; unsigned _frameSizeUpdatesDisabledCount; + BOOL _shouldDeferViewInWindowChanges; + + BOOL _viewInWindowChangeWasDeferred; + + BOOL _needsViewFrameInWindowCoordinates; + BOOL _didScheduleWindowAndViewFrameUpdate; // Whether the containing window of the WKView has a valid backing store. // The window server invalidates the backing store whenever the window is resized or minimized. @@ -216,7 +230,22 @@ struct WKViewInterpretKeyEventsParameters { String _promisedFilename; String _promisedURL; + // The frame origin can be seen as a position within the layer of painted page content where the + // top left corner of the frame will be positioned. This is usually 0,0 - but if the content + // anchor is set to a corner other than the top left, the origin will implicitly move as the + // the frame size is modified. + NSPoint _frameOrigin; + WKContentAnchor _contentAnchor; + NSSize _intrinsicContentSize; + BOOL _clipsToVisibleRect; + NSRect _contentPreparationRect; + BOOL _useContentPreparationRectForVisibleRect; + +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 + BOOL _isWindowOccluded; + BOOL _windowOcclusionDetectionEnabled; +#endif } @end @@ -224,7 +253,6 @@ struct WKViewInterpretKeyEventsParameters { @implementation WKViewData @end - @interface WKResponderChainSink : NSResponder { NSResponder *_lastResponderInChain; bool _didReceiveUnhandledCommand; @@ -267,6 +295,9 @@ struct WKViewInterpretKeyEventsParameters { [_data release]; _data = nil; + NSNotificationCenter* workspaceNotificationCenter = [[NSWorkspace sharedWorkspace] notificationCenter]; + [workspaceNotificationCenter removeObserver:self name:NSWorkspaceActiveSpaceDidChangeNotification object:nil]; + WebContext::statistics().wkViewCount--; [super dealloc]; @@ -275,7 +306,7 @@ struct WKViewInterpretKeyEventsParameters { - (WKBrowsingContextController *)browsingContextController { if (!_data->_browsingContextController) - _data->_browsingContextController.adoptNS([[WKBrowsingContextController alloc] _initWithPageRef:[self pageRef]]); + _data->_browsingContextController = adoptNS([[WKBrowsingContextController alloc] _initWithPageRef:[self pageRef]]); return _data->_browsingContextController.get(); } @@ -331,8 +362,11 @@ struct WKViewInterpretKeyEventsParameters { if (_data->_page->editorState().hasComposition && !_data->_page->editorState().shouldIgnoreCompositionSelectionChange) _data->_page->cancelComposition(); - [self _resetTextInputState]; - + + [self _notifyInputContextAboutDiscardedComposition]; + + [self _resetSecureInputState]; + if (!_data->_page->maintainsInactiveSelection()) _data->_page->clearSelection(); @@ -363,27 +397,91 @@ struct WKViewInterpretKeyEventsParameters { return _data->_intrinsicContentSize; } +- (void)prepareContentInRect:(NSRect)rect +{ + _data->_contentPreparationRect = rect; + _data->_useContentPreparationRectForVisibleRect = YES; + + [self _updateViewExposedRect]; +} + +- (void)_updateViewExposedRect +{ + NSRect exposedRect = [self visibleRect]; + + if (_data->_useContentPreparationRectForVisibleRect) + exposedRect = NSUnionRect(_data->_contentPreparationRect, exposedRect); + + _data->_page->viewExposedRectChanged(exposedRect, _data->_clipsToVisibleRect); +} + - (void)setFrameSize:(NSSize)size { if (!NSEqualSizes(size, [self frame].size)) _data->_windowHasValidBackingStore = NO; - [super setFrameSize:size]; + bool frameSizeUpdatesEnabled = ![self frameSizeUpdatesDisabled]; + NSPoint newFrameOrigin; + + // If frame updates are enabled we'll synchronously wait on the repaint, so we can reposition + // the layers back to the origin. If frame updates are disabled then shift the layer position + // so that the currently painted contents remain anchored appropriately. + if (frameSizeUpdatesEnabled) + newFrameOrigin = NSZeroPoint; + else { + newFrameOrigin = _data->_frameOrigin; + if (isWKContentAnchorRight(_data->_contentAnchor)) + newFrameOrigin.x += [self frame].size.width - size.width; + if (isWKContentAnchorBottom(_data->_contentAnchor)) + newFrameOrigin.y += [self frame].size.height - size.height; + } - if (![self frameSizeUpdatesDisabled]) + // If the frame origin has changed then update the layer position. + if (_data->_layerHostingView && !NSEqualPoints(_data->_frameOrigin, newFrameOrigin)) { + _data->_frameOrigin = newFrameOrigin; + CALayer *rootLayer = [[_data->_layerHostingView layer].sublayers objectAtIndex:0]; + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + rootLayer.position = CGPointMake(-newFrameOrigin.x, -newFrameOrigin.y); + [CATransaction commit]; + } + + [super setFrameSize:size]; + + if (frameSizeUpdatesEnabled) { + if (_data->_clipsToVisibleRect) + [self _updateViewExposedRect]; [self _setDrawingAreaSize:size]; + } } - (void)_updateWindowAndViewFrames { - NSWindow *window = [self window]; - ASSERT(window); - - NSRect windowFrameInScreenCoordinates = [window frame]; - NSRect viewFrameInWindowCoordinates = [self convertRect:[self frame] toView:nil]; - NSPoint accessibilityPosition = [[self accessibilityAttributeValue:NSAccessibilityPositionAttribute] pointValue]; - - _data->_page->windowAndViewFramesChanged(enclosingIntRect(windowFrameInScreenCoordinates), enclosingIntRect(viewFrameInWindowCoordinates), IntPoint(accessibilityPosition)); + if (_data->_clipsToVisibleRect) + [self _updateViewExposedRect]; + + if (_data->_didScheduleWindowAndViewFrameUpdate) + return; + + _data->_didScheduleWindowAndViewFrameUpdate = YES; + + dispatch_async(dispatch_get_main_queue(), ^{ + _data->_didScheduleWindowAndViewFrameUpdate = NO; + + if (!_data->_needsViewFrameInWindowCoordinates && !WebCore::AXObjectCache::accessibilityEnabled()) + return; + + NSRect viewFrameInWindowCoordinates = NSZeroRect; + NSPoint accessibilityPosition = NSZeroPoint; + + if (_data->_needsViewFrameInWindowCoordinates) + viewFrameInWindowCoordinates = [self convertRect:self.frame toView:nil]; + + if (WebCore::AXObjectCache::accessibilityEnabled()) + accessibilityPosition = [[self accessibilityAttributeValue:NSAccessibilityPositionAttribute] pointValue]; + + _data->_page->windowAndViewFramesChanged(viewFrameInWindowCoordinates, accessibilityPosition); + }); } - (void)renewGState @@ -581,13 +679,22 @@ WEBCORE_COMMAND(yankAndSelect) - (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType { - BOOL isValidSendType = !sendType || ([PasteboardTypes::forSelection() containsObject:sendType] && !_data->_page->editorState().selectionIsNone); + EditorState editorState = _data->_page->editorState(); + BOOL isValidSendType = NO; + + if (sendType && !editorState.selectionIsNone) { + if (editorState.isInPlugin) + isValidSendType = [sendType isEqualToString:NSStringPboardType]; + else + isValidSendType = [PasteboardTypes::forSelection() containsObject:sendType]; + } + BOOL isValidReturnType = NO; if (!returnType) isValidReturnType = YES; - else if ([PasteboardTypes::forEditing() containsObject:returnType] && _data->_page->editorState().isContentEditable) { + else if ([PasteboardTypes::forEditing() containsObject:returnType] && editorState.isContentEditable) { // We can insert strings in any editable context. We can insert other types, like images, only in rich edit contexts. - isValidReturnType = _data->_page->editorState().isContentRichlyEditable || [returnType isEqualToString:NSStringPboardType]; + isValidReturnType = editorState.isContentRichlyEditable || [returnType isEqualToString:NSStringPboardType]; } if (isValidSendType && isValidReturnType) return self; @@ -970,7 +1077,6 @@ static void speakString(WKStringRef string, WKErrorRef error, void*) - (void)displayIfNeeded { -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 // FIXME: We should remove this code when <rdar://problem/9362085> is resolved. In the meantime, // it is necessary to disable scren updates so we get a chance to redraw the corners before this // display is visible. @@ -978,17 +1084,14 @@ static void speakString(WKStringRef string, WKErrorRef error, void*) BOOL shouldMaskWindow = window && !NSIsEmptyRect(_data->_windowBottomCornerIntersectionRect); if (shouldMaskWindow) NSDisableScreenUpdates(); -#endif [super displayIfNeeded]; -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 if (shouldMaskWindow) { [window _maskRoundedBottomCorners:_data->_windowBottomCornerIntersectionRect]; NSEnableScreenUpdates(); _data->_windowBottomCornerIntersectionRect = NSZeroRect; } -#endif } // Events @@ -1403,18 +1506,6 @@ static const short kIOHIDEventTypeScroll = 6; LOG(TextInput, "...done executing saved keypress commands."); } -- (void)_notifyInputContextAboutDiscardedComposition -{ - // <rdar://problem/9359055>: -discardMarkedText can only be called for active contexts. - // FIXME: We fail to ever notify the input context if something (e.g. a navigation) happens while the window is not key. - // This is not a problem when the window is key, because we discard marked text on resigning first responder. - if (![[self window] isKeyWindow] || self != [[self window] firstResponder]) - return; - - LOG(TextInput, "-> discardMarkedText"); - [[super inputContext] discardMarkedText]; // Inform the input method that we won't have an inline input area despite having been asked to. -} - - (NSTextInputContext *)inputContext { WKViewInterpretKeyEventsParameters* parameters = _data->_interpretKeyEventsParameters; @@ -1692,7 +1783,6 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde _data->_page->dragUpdated(&dragData, [[draggingInfo draggingPasteboard] name]); WebCore::DragSession dragSession = _data->_page->dragSession(); -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 NSInteger numberOfValidItemsForDrop = dragSession.numberOfItemsToBeAccepted; NSDraggingFormation draggingFormation = NSDraggingFormationNone; if (dragSession.mouseIsOverFileInput && numberOfValidItemsForDrop > 0) @@ -1702,7 +1792,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde [draggingInfo setNumberOfValidItemsForDrop:numberOfValidItemsForDrop]; if ([draggingInfo draggingFormation] != draggingFormation) [draggingInfo setDraggingFormation:draggingFormation]; -#endif + return dragSession.operation; } @@ -1804,57 +1894,6 @@ static void createSandboxExtensionsForFileUpload(NSPasteboard *pasteboard, Sandb } -#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1060 -- (BOOL)_ownsWindowGrowBox -{ - NSWindow* window = [self window]; - if (!window) - return NO; - - NSView *superview = [self superview]; - if (!superview) - return NO; - - NSRect growBoxRect = [window _growBoxRect]; - if (NSIsEmptyRect(growBoxRect)) - return NO; - - NSRect visibleRect = [self visibleRect]; - if (NSIsEmptyRect(visibleRect)) - return NO; - - NSRect visibleRectInWindowCoords = [self convertRect:visibleRect toView:nil]; - if (!NSIntersectsRect(growBoxRect, visibleRectInWindowCoords)) - return NO; - - return YES; -} - -- (BOOL)_updateGrowBoxForWindowFrameChange -{ - // Temporarily enable the resize indicator to make a the _ownsWindowGrowBox calculation work. - BOOL wasShowingIndicator = [[self window] showsResizeIndicator]; - if (!wasShowingIndicator) - [[self window] setShowsResizeIndicator:YES]; - - BOOL ownsGrowBox = [self _ownsWindowGrowBox]; - _data->_page->setWindowResizerSize(ownsGrowBox ? enclosingIntRect([[self window] _growBoxRect]).size() : IntSize()); - - if (ownsGrowBox) - [[self window] _setShowOpaqueGrowBoxForOwner:(_data->_page->hasHorizontalScrollbar() || _data->_page->hasVerticalScrollbar() ? self : nil)]; - else - [[self window] _setShowOpaqueGrowBoxForOwner:nil]; - - // Once WebCore can draw the window resizer, this should read: - // if (wasShowingIndicator) - // [[self window] setShowsResizeIndicator:!ownsGrowBox]; - if (!wasShowingIndicator) - [[self window] setShowsResizeIndicator:NO]; - - return ownsGrowBox; -} -#endif - // FIXME: Use AppKit constants for these when they are available. static NSString * const windowDidChangeBackingPropertiesNotification = @"NSWindowDidChangeBackingPropertiesNotification"; static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOldScaleFactorKey"; @@ -1882,6 +1921,10 @@ static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOl name:windowDidChangeBackingPropertiesNotification object:window]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidChangeScreen:) name:NSWindowDidChangeScreenNotification object:window]; +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_windowDidChangeOcclusionState:) + name:NSWindowDidChangeOcclusionStateNotification object:window]; +#endif } } @@ -1897,10 +1940,14 @@ static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOl [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidDeminiaturizeNotification object:window]; [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidMoveNotification object:window]; [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidResizeNotification object:window]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:@"NSWindowWillOrderOffScreenNotification" object:window]; [[NSNotificationCenter defaultCenter] removeObserver:self name:@"NSWindowDidOrderOffScreenNotification" object:window]; [[NSNotificationCenter defaultCenter] removeObserver:self name:@"_NSWindowDidBecomeVisible" object:window]; [[NSNotificationCenter defaultCenter] removeObserver:self name:windowDidChangeBackingPropertiesNotification object:window]; [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidChangeScreenNotification object:window]; +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidChangeOcclusionStateNotification object:window]; +#endif } - (void)viewWillMoveToWindow:(NSWindow *)window @@ -1922,11 +1969,6 @@ static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOl [self removeWindowObservers]; [self addWindowObserversForWindow:window]; - -#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1060 - if ([currentWindow _growBoxOwner] == self) - [currentWindow _setShowOpaqueGrowBoxForOwner:nil]; -#endif } - (void)viewDidMoveToWindow @@ -1935,10 +1977,21 @@ static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOl // update the active state first and then make it visible. If the view is about to be hidden, we hide it first and then // update the active state. if ([self window]) { +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 + if (_data->_windowOcclusionDetectionEnabled) + [self _setIsWindowOccluded:([[self window] occlusionState] & NSWindowOcclusionStateVisible) != NSWindowOcclusionStateVisible]; +#endif _data->_windowHasValidBackingStore = NO; + [self doWindowDidChangeScreen]; [self _updateWindowVisibility]; _data->_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive); - _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible | WebPageProxy::ViewIsInWindow); + + if ([self isDeferringViewInWindowChanges]) { + _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible); + _data->_viewInWindowChangeWasDeferred = YES; + } else + _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible | WebPageProxy::ViewIsInWindow); + [self _updateWindowAndViewFrames]; if (!_data->_flagsChangedEventMonitor) { @@ -1952,7 +2005,12 @@ static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOl } else { [self _updateWindowVisibility]; _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible); - _data->_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive | WebPageProxy::ViewIsInWindow); + + if ([self isDeferringViewInWindowChanges]) { + _data->_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive); + _data->_viewInWindowChangeWasDeferred = YES; + } else + _data->_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive | WebPageProxy::ViewIsInWindow); [NSEvent removeMonitor:_data->_flagsChangedEventMonitor]; _data->_flagsChangedEventMonitor = nil; @@ -1963,9 +2021,7 @@ static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOl _data->_endGestureMonitor = nil; } #endif -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 WKHideWordDefinitionWindow(); -#endif } _data->_page->setIntrinsicDeviceScaleFactor([self _intrinsicDeviceScaleFactor]); @@ -1983,9 +2039,6 @@ static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOl [self _updateSecureInputState]; _data->_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive); } - - // Send a change screen to make sure the initial displayID is set - [self doWindowDidChangeScreen]; } - (void)_windowDidChangeScreen:(NSNotification *)notification @@ -2057,6 +2110,16 @@ static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOl _data->_page->setIntrinsicDeviceScaleFactor(newBackingScaleFactor); } +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 +- (void)_windowDidChangeOcclusionState:(NSNotification *)notification +{ + if (!_data->_windowOcclusionDetectionEnabled) + return; + + [self _setIsWindowOccluded:([self.window occlusionState] & NSWindowOcclusionStateVisible) != NSWindowOcclusionStateVisible]; +} +#endif + static void drawPageBackground(CGContextRef context, WebPageProxy* page, const IntRect& rect) { if (!page->drawsBackground()) @@ -2099,7 +2162,7 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I // If the window doesn't have a valid backing store, we need to fill the parts of the page that we // didn't paint with the background color (white or clear), to avoid garbage in those areas. - if (!_data->_windowHasValidBackingStore) { + if (!_data->_windowHasValidBackingStore || !drawingArea->hasReceivedFirstUpdate()) { Vector<IntRect> unpaintedRects = unpaintedRegion.rects(); for (size_t i = 0; i < unpaintedRects.size(); ++i) drawPageBackground(context, _data->_page.get(), unpaintedRects[i]); @@ -2146,11 +2209,16 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I drawingArea->colorSpaceDidChange(); } +- (void)_activeSpaceDidChange:(NSNotification *)notification +{ + _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible); +} + - (void)_accessibilityRegisterUIProcessTokens { // Initialize remote accessibility when the window connection has been established. NSData *remoteElementToken = WKAXRemoteTokenForElement(self); - NSData *remoteWindowToken = WKAXRemoteTokenForElement([self accessibilityAttributeValue:NSAccessibilityWindowAttribute]); + NSData *remoteWindowToken = WKAXRemoteTokenForElement([self window]); 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); @@ -2172,11 +2240,20 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I WKAXRegisterRemoteProcess(registerProcess, pid); } -- (id)accessibilityFocusedUIElement +- (void)enableAccessibilityIfNecessary { - if (_data->_pdfViewController) - return NSAccessibilityUnignoredDescendant(_data->_pdfViewController->pdfView()); + if (WebCore::AXObjectCache::accessibilityEnabled()) + return; + + // After enabling accessibility update the window frame on the web process so that the + // correct accessibility position is transmitted (when AX is off, that position is not calculated). + WebCore::AXObjectCache::enableAccessibility(); + [self _updateWindowAndViewFrames]; +} +- (id)accessibilityFocusedUIElement +{ + [self enableAccessibilityIfNecessary]; return _data->_remoteAccessibilityChild.get(); } @@ -2187,20 +2264,18 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I - (id)accessibilityHitTest:(NSPoint)point { - if (_data->_pdfViewController) - return [_data->_pdfViewController->pdfView() accessibilityHitTest:point]; - + [self enableAccessibilityIfNecessary]; return _data->_remoteAccessibilityChild.get(); } - (id)accessibilityAttributeValue:(NSString*)attribute { + [self enableAccessibilityIfNecessary]; + if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { id child = nil; - if (_data->_pdfViewController) - child = NSAccessibilityUnignoredDescendant(_data->_pdfViewController->pdfView()); - else if (_data->_remoteAccessibilityChild) + if (_data->_remoteAccessibilityChild) child = _data->_remoteAccessibilityChild.get(); if (!child) @@ -2245,15 +2320,9 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I - (float)_intrinsicDeviceScaleFactor { NSWindow *window = [self window]; -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 if (window) return [window backingScaleFactor]; return [[NSScreen mainScreen] backingScaleFactor]; -#else - if (window) - return [window userSpaceScaleFactor]; - return [[NSScreen mainScreen] userSpaceScaleFactor]; -#endif } - (void)_setDrawingAreaSize:(NSSize)size @@ -2261,7 +2330,13 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I if (!_data->_page->drawingArea()) return; - _data->_page->drawingArea()->setSize(IntSize(size), IntSize(_data->_resizeScrollOffset)); + NSSize layerOffset = NSMakeSize(_data->_frameOrigin.x, _data->_frameOrigin.y); + if (isWKContentAnchorRight(_data->_contentAnchor)) + layerOffset.width += [self frame].size.width - size.width; + if (isWKContentAnchorBottom(_data->_contentAnchor)) + layerOffset.height += [self frame].size.height - size.height; + + _data->_page->drawingArea()->setSize(IntSize(size), IntSize(layerOffset), IntSize(_data->_resizeScrollOffset)); _data->_resizeScrollOffset = NSZeroSize; } @@ -2278,6 +2353,17 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I } #endif +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 +- (void)_setIsWindowOccluded:(BOOL)isWindowOccluded +{ + if (_data->_isWindowOccluded == isWindowOccluded) + return; + + _data->_isWindowOccluded = isWindowOccluded; + _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible); +} +#endif + @end @implementation WKView (Internal) @@ -2338,6 +2424,18 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I [self _accessibilityRegisterUIProcessTokens]; } +- (void)_preferencesDidChange +{ + BOOL needsViewFrameInWindowCoordinates = _data->_page->pageGroup()->preferences()->pluginsEnabled(); + + if (!!needsViewFrameInWindowCoordinates == !!_data->_needsViewFrameInWindowCoordinates) + return; + + _data->_needsViewFrameInWindowCoordinates = needsViewFrameInWindowCoordinates; + if ([self window]) + [self _updateWindowAndViewFrames]; +} + - (void)_setCursor:(NSCursor *)cursor { if ([NSCursor currentCursor] == cursor) @@ -2578,7 +2676,7 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I if (rootLayer) { if (!_data->_layerHostingView) { // Create an NSView that will host our layer tree. - _data->_layerHostingView.adoptNS([[WKFlippedView alloc] initWithFrame:[self bounds]]); + _data->_layerHostingView = adoptNS([[WKFlippedView alloc] initWithFrame:[self bounds]]); [_data->_layerHostingView.get() setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; @@ -2602,6 +2700,7 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I [_data->_layerHostingView setWantsLayer:NO]; _data->_layerHostingView = nullptr; + _data->_frameOrigin = NSZeroPoint; } } @@ -2652,57 +2751,6 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I [self _setPluginComplexTextInputState:pluginComplexTextInputState]; } -- (void)_setPageHasCustomRepresentation:(BOOL)pageHasCustomRepresentation -{ - bool hadPDFView = _data->_pdfViewController; - _data->_pdfViewController = nullptr; - - if (pageHasCustomRepresentation) - _data->_pdfViewController = PDFViewController::create(self); - - if (pageHasCustomRepresentation != hadPDFView) - _data->_page->drawingArea()->pageCustomRepresentationChanged(); -} - -- (void)_didFinishLoadingDataForCustomRepresentationWithSuggestedFilename:(const String&)suggestedFilename dataReference:(const CoreIPC::DataReference&)dataReference -{ - ASSERT(_data->_pdfViewController); - - _data->_pdfViewController->setPDFDocumentData(_data->_page->mainFrame()->mimeType(), suggestedFilename, dataReference); -} - -- (double)_customRepresentationZoomFactor -{ - if (!_data->_pdfViewController) - return 1; - - return _data->_pdfViewController->zoomFactor(); -} - -- (void)_setCustomRepresentationZoomFactor:(double)zoomFactor -{ - if (!_data->_pdfViewController) - return; - - _data->_pdfViewController->setZoomFactor(zoomFactor); -} - -- (void)_findStringInCustomRepresentation:(NSString *)string withFindOptions:(WebKit::FindOptions)options maxMatchCount:(NSUInteger)count -{ - if (!_data->_pdfViewController) - return; - - _data->_pdfViewController->findString(string, options, count); -} - -- (void)_countStringMatchesInCustomRepresentation:(NSString *)string withFindOptions:(WebKit::FindOptions)options maxMatchCount:(NSUInteger)count -{ - if (!_data->_pdfViewController) - return; - - _data->_pdfViewController->countStringMatches(string, options, count); -} - - (void)_setDragImage:(NSImage *)image at:(NSPoint)clientPoint linkDrag:(BOOL)linkDrag { IntSize size([image size]); @@ -2732,7 +2780,7 @@ static bool matchesExtensionOrEquivalent(NSString *filename, NSString *extension { NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:pasteboardName]; - RetainPtr<NSMutableArray> types(AdoptNS, [[NSMutableArray alloc] initWithObjects:NSFilesPromisePboardType, nil]); + RetainPtr<NSMutableArray> types = adoptNS([[NSMutableArray alloc] initWithObjects:NSFilesPromisePboardType, nil]); [types.get() addObjectsFromArray:archiveBuffer ? PasteboardTypes::forImagesWithArchive() : PasteboardTypes::forImages()]; [pasteboard declareTypes:types.get() owner:self]; @@ -2814,8 +2862,8 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) RetainPtr<NSData> data; if (_data->_promisedImage) { - data.adoptNS(_data->_promisedImage->data()->createNSData()); - wrapper.adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:data.get()]); + data = adoptNS(_data->_promisedImage->data()->createNSData()); + wrapper = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:data.get()]); [wrapper.get() setPreferredFilename:_data->_promisedFilename]; } @@ -2864,38 +2912,24 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) _data->_inSecureInputState = isInPasswordField; } -- (void)_updateTextInputStateIncludingSecureInputState:(BOOL)updateSecureInputState +- (void)_resetSecureInputState { - const EditorState& editorState = _data->_page->editorState(); - if (updateSecureInputState) { - // This is a temporary state when editing. Flipping secure input state too quickly can expose race conditions. - if (!editorState.selectionIsNone) - [self _updateSecureInputState]; - } - - if (!editorState.hasComposition || editorState.shouldIgnoreCompositionSelectionChange) - return; - - _data->_page->cancelComposition(); - - [self _notifyInputContextAboutDiscardedComposition]; -} - -- (void)_resetTextInputState -{ - [self _notifyInputContextAboutDiscardedComposition]; - if (_data->_inSecureInputState) { DisableSecureEventInput(); _data->_inSecureInputState = NO; } } -- (void)_didChangeScrollbarsForMainFrame +- (void)_notifyInputContextAboutDiscardedComposition { -#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1060 - [self _updateGrowBoxForWindowFrameChange]; -#endif + // <rdar://problem/9359055>: -discardMarkedText can only be called for active contexts. + // FIXME: We fail to ever notify the input context if something (e.g. a navigation) happens while the window is not key. + // This is not a problem when the window is key, because we discard marked text on resigning first responder. + if (![[self window] isKeyWindow] || self != [[self window] firstResponder]) + return; + + LOG(TextInput, "-> discardMarkedText"); + [[super inputContext] discardMarkedText]; // Inform the input method that we won't have an inline input area despite having been asked to. } #if ENABLE(FULLSCREEN_API) @@ -2907,7 +2941,7 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) - (WKFullScreenWindowController*)fullScreenWindowController { if (!_data->_fullScreenWindowController) { - _data->_fullScreenWindowController.adoptNS([[WKFullScreenWindowController alloc] init]); + _data->_fullScreenWindowController = adoptNS([[WKFullScreenWindowController alloc] initWithWindow:[self createFullScreenWindow]]); [_data->_fullScreenWindowController.get() setWebView:self]; } return _data->_fullScreenWindowController.get(); @@ -2926,7 +2960,7 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) { // The sink does two things: 1) Tells us if the responder went unhandled, and // 2) prevents any NSBeep; we don't ever want to beep here. - RetainPtr<WKResponderChainSink> sink(AdoptNS, [[WKResponderChainSink alloc] initWithResponderChain:self]); + RetainPtr<WKResponderChainSink> sink = adoptNS([[WKResponderChainSink alloc] initWithResponderChain:self]); [super doCommandBySelector:selector]; [sink.get() detach]; return ![sink.get() didReceiveUnhandledCommand]; @@ -2934,14 +2968,21 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) - (void)_setIntrinsicContentSize:(NSSize)intrinsicContentSize { - _data->_intrinsicContentSize = intrinsicContentSize; + // If the intrinsic content size is less than the minimum layout width, the content flowed to fit, + // so we can report that that dimension is flexible. If not, we need to report our intrinsic width + // so that autolayout will know to provide space for us. + + NSSize intrinsicContentSizeAcknowledgingFlexibleWidth = intrinsicContentSize; + if (intrinsicContentSize.width < _data->_page->minimumLayoutSize().width()) + intrinsicContentSizeAcknowledgingFlexibleWidth.width = NSViewNoInstrinsicMetric; + + _data->_intrinsicContentSize = intrinsicContentSizeAcknowledgingFlexibleWidth; [self invalidateIntrinsicContentSize]; } - (void)_cacheWindowBottomCornerRect { -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 - // FIXME: We should remove this code when <rdar://problem/9362085> is resolved. + // FIXME: We should remove this code when <rdar://problem/9362085> is resolved. NSWindow *window = [self window]; if (!window) return; @@ -2949,7 +2990,6 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) _data->_windowBottomCornerIntersectionRect = [window _intersectBottomCornersWithRect:[self convertRect:[self visibleRect] toView:nil]]; if (!NSIsEmptyRect(_data->_windowBottomCornerIntersectionRect)) [self setNeedsDisplayInRect:[self convertRect:_data->_windowBottomCornerIntersectionRect fromView:nil]]; -#endif } - (NSInteger)spellCheckerDocumentTag @@ -2976,6 +3016,15 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) return _data->_page->suppressVisibilityUpdates(); } +- (BOOL)_isWindowOccluded +{ +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 + return _data->_isWindowOccluded; +#else + return NO; +#endif +} + @end @implementation WKView (Private) @@ -3006,14 +3055,10 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) // Legacy style scrollbars have design details that rely on tracking the mouse all the time. NSTrackingAreaOptions options = NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect; -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 if (WKRecommendedScrollerStyle() == NSScrollerStyleLegacy) options |= NSTrackingActiveAlways; else options |= NSTrackingActiveInKeyWindow; -#else - options |= NSTrackingActiveInKeyWindow; -#endif NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:frame options:options @@ -3033,9 +3078,20 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) #endif _data->_mouseDownEvent = nil; _data->_ignoringMouseDraggedEvents = NO; + _data->_clipsToVisibleRect = NO; + _data->_useContentPreparationRectForVisibleRect = NO; _data->_intrinsicContentSize = NSMakeSize(NSViewNoInstrinsicMetric, NSViewNoInstrinsicMetric); +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 + _data->_isWindowOccluded = NO; + _data->_windowOcclusionDetectionEnabled = YES; +#endif + + _data->_needsViewFrameInWindowCoordinates = _data->_page->pageGroup()->preferences()->pluginsEnabled(); + _data->_frameOrigin = NSZeroPoint; + _data->_contentAnchor = WKContentAnchorTopLeft; + [self _registerDraggedTypes]; if ([self _shouldUseTiledDrawingArea]) { @@ -3047,6 +3103,9 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) WebContext::statistics().wkViewCount++; + NSNotificationCenter* workspaceNotificationCenter = [[NSWorkspace sharedWorkspace] notificationCenter]; + [workspaceNotificationCenter addObserver:self selector:@selector(_activeSpaceDidChange:) name:NSWorkspaceActiveSpaceDidChangeNotification object:nil]; + return self; } @@ -3058,7 +3117,16 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) - (void)updateLayer { - self.layer.backgroundColor = CGColorGetConstantColor(kCGColorWhite); + if ([self drawsBackground] && ![self drawsTransparentBackground]) + self.layer.backgroundColor = CGColorGetConstantColor(kCGColorWhite); + else + self.layer.backgroundColor = CGColorGetConstantColor(kCGColorClear); + + // If asynchronous geometry updates have been sent by forceAsyncDrawingAreaSizeUpdate, + // then subsequent calls to setFrameSize should not result in us waiting for the did + // udpate response if setFrameSize is called. + if ([self frameSizeUpdatesDisabled]) + return; if (DrawingAreaProxy* drawingArea = _data->_page->drawingArea()) drawingArea->waitForPossibleGeometryUpdate(); @@ -3080,22 +3148,15 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) { LOG(View, "Creating an NSPrintOperation for frame '%s'", toImpl(frameRef)->url().utf8().data()); - // Only the top frame can currently contain a PDF view. - if (_data->_pdfViewController) { - if (!toImpl(frameRef)->isMainFrame()) - return 0; - return _data->_pdfViewController->makePrintOperation(printInfo); - } else { - // FIXME: If the frame cannot be printed (e.g. if it contains an encrypted PDF that disallows - // printing), this function should return nil. - 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]; - [printOperation setJobTitle:toImpl(frameRef)->title()]; - printingView->_printOperation = printOperation; - return printOperation; - } + // FIXME: If the frame cannot be printed (e.g. if it contains an encrypted PDF that disallows + // printing), this function should return nil. + RetainPtr<WKPrintingView> printingView = adoptNS([[WKPrintingView alloc] initWithFrameProxy:toImpl(frameRef) view:self]); + // NSPrintOperation takes ownership of the view. + NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView:printingView.get() printInfo:printInfo]; + [printOperation setCanSpawnSeparateThread:YES]; + [printOperation setJobTitle:toImpl(frameRef)->title()]; + printingView->_printOperation = printOperation; + return printOperation; } - (void)setFrame:(NSRect)rect andScrollBy:(NSSize)offset @@ -3116,8 +3177,11 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) if (!_data->_frameSizeUpdatesDisabledCount) return; - if (!(--_data->_frameSizeUpdatesDisabledCount)) + if (!(--_data->_frameSizeUpdatesDisabledCount)) { + if (_data->_clipsToVisibleRect) + [self _updateViewExposedRect]; [self _setDrawingAreaSize:[self frame].size]; + } } - (BOOL)frameSizeUpdatesDisabled @@ -3136,19 +3200,232 @@ static NSString *pathWithUniqueFilenameForPath(NSString *path) + (void)hideWordDefinitionWindow { -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 WKHideWordDefinitionWindow(); -#endif } - (CGFloat)minimumLayoutWidth { - return _data->_page->minimumLayoutWidth(); + static BOOL loggedDeprecationWarning = NO; + + if (!loggedDeprecationWarning) { + NSLog(@"Please use minimumSizeForAutoLayout instead of minimumLayoutWidth."); + loggedDeprecationWarning = YES; + } + + return self.minimumSizeForAutoLayout.width; } - (void)setMinimumLayoutWidth:(CGFloat)minimumLayoutWidth { - _data->_page->setMinimumLayoutWidth(minimumLayoutWidth); + static BOOL loggedDeprecationWarning = NO; + + if (!loggedDeprecationWarning) { + NSLog(@"Please use setMinimumSizeForAutoLayout: instead of setMinimumLayoutWidth:."); + loggedDeprecationWarning = YES; + } + + [self setMinimumWidthForAutoLayout:minimumLayoutWidth]; +} + +- (CGFloat)minimumWidthForAutoLayout +{ + static BOOL loggedDeprecationWarning = NO; + + if (!loggedDeprecationWarning) { + NSLog(@"Please use minimumSizeForAutoLayout instead of minimumWidthForAutoLayout."); + loggedDeprecationWarning = YES; + } + + return self.minimumSizeForAutoLayout.width; +} + +- (void)setMinimumWidthForAutoLayout:(CGFloat)minimumLayoutWidth +{ + static BOOL loggedDeprecationWarning = NO; + + if (!loggedDeprecationWarning) { + NSLog(@"Please use setMinimumSizeForAutoLayout: instead of setMinimumWidthForAutoLayout:"); + loggedDeprecationWarning = YES; + } + + self.minimumSizeForAutoLayout = NSMakeSize(minimumLayoutWidth, self.minimumSizeForAutoLayout.height); +} + +- (NSSize)minimumSizeForAutoLayout +{ + return _data->_page->minimumLayoutSize(); +} + +- (void)setMinimumSizeForAutoLayout:(NSSize)minimumSizeForAutoLayout +{ + BOOL expandsToFit = minimumSizeForAutoLayout.width > 0; + + _data->_page->setMinimumLayoutSize(IntSize(minimumSizeForAutoLayout.width, minimumSizeForAutoLayout.height)); + _data->_page->setMainFrameIsScrollable(!expandsToFit); + + [self setShouldClipToVisibleRect:expandsToFit]; +} + +- (BOOL)shouldClipToVisibleRect +{ + return _data->_clipsToVisibleRect; +} + +- (void)setShouldClipToVisibleRect:(BOOL)clipsToVisibleRect +{ + _data->_clipsToVisibleRect = clipsToVisibleRect; + [self _updateViewExposedRect]; +} + +- (NSColor *)underlayColor +{ + Color webColor = _data->_page->underlayColor(); + if (!webColor.isValid()) + return nil; + + return nsColor(webColor); +} + +- (void)setUnderlayColor:(NSColor *)underlayColor +{ + _data->_page->setUnderlayColor(colorFromNSColor(underlayColor)); +} + +- (NSView*)fullScreenPlaceholderView +{ +#if ENABLE(FULLSCREEN_API) + if (_data->_fullScreenWindowController && [_data->_fullScreenWindowController isFullScreen]) + return [_data->_fullScreenWindowController webViewPlaceholder]; +#endif + return nil; +} + +- (void)beginDeferringViewInWindowChanges +{ + if (_data->_shouldDeferViewInWindowChanges) { + NSLog(@"beginDeferringViewInWindowChanges was called while already deferring view-in-window changes!"); + return; + } + + _data->_shouldDeferViewInWindowChanges = YES; +} + +- (void)endDeferringViewInWindowChanges +{ + if (!_data->_shouldDeferViewInWindowChanges) { + NSLog(@"endDeferringViewInWindowChanges was called without beginDeferringViewInWindowChanges!"); + return; + } + + _data->_shouldDeferViewInWindowChanges = NO; + + if (_data->_viewInWindowChangeWasDeferred) { + _data->_page->viewStateDidChange(WebPageProxy::ViewIsInWindow); + _data->_viewInWindowChangeWasDeferred = NO; + } +} + +- (void)endDeferringViewInWindowChangesSync +{ + if (!_data->_shouldDeferViewInWindowChanges) { + NSLog(@"endDeferringViewInWindowChangesSync was called without beginDeferringViewInWindowChanges!"); + return; + } + + PageClient* pageClient = _data->_pageClient.get(); + bool hasPendingViewInWindowChange = _data->_viewInWindowChangeWasDeferred && _data->_page->isInWindow() != pageClient->isViewInWindow(); + + [self endDeferringViewInWindowChanges]; + + if (hasPendingViewInWindowChange) + _data->_page->waitForDidUpdateInWindowState(); +} + +- (BOOL)isDeferringViewInWindowChanges +{ + return _data->_shouldDeferViewInWindowChanges; +} + +- (BOOL)windowOcclusionDetectionEnabled +{ +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 + return _data->_windowOcclusionDetectionEnabled; +#else + return NO; +#endif +} + +- (void)setWindowOcclusionDetectionEnabled:(BOOL)flag +{ +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 + if (_data->_windowOcclusionDetectionEnabled == flag) + return; + + _data->_windowOcclusionDetectionEnabled = flag; + + if (flag) { + // When enabling window occlusion detection, update the view's current occluded state + // immediately, as the notification only fires when it changes. + if (self.window) + [self _setIsWindowOccluded:([self.window occlusionState] & NSWindowOcclusionStateVisible) != NSWindowOcclusionStateVisible]; + } else { + // When disabling window occlusion detection, force the view to think it is not occluded, + // as it may already be occluded at the time of calling. + [self _setIsWindowOccluded:NO]; + } +#endif +} + +- (void)setContentAnchor:(WKContentAnchor)contentAnchor +{ + _data->_contentAnchor = contentAnchor; +} + +- (WKContentAnchor)contentAnchor +{ + return _data->_contentAnchor; +} + +// This method forces a drawing area geometry update, even if frame size updates are disabled. +// The updated is performed asynchronously; we don't wait for the geometry update before returning. +// The area drawn need not match the current frame size - if it differs it will be anchored to the +// frame according to the current contentAnchor. +- (void)forceAsyncDrawingAreaSizeUpdate:(NSSize)size +{ + if (_data->_clipsToVisibleRect) + [self _updateViewExposedRect]; + [self _setDrawingAreaSize:size]; + + // If a geometry update is pending the new update won't be sent. Poll without waiting for any + // pending did-update message now, such that the new update can be sent. We do so after setting + // the drawing area size such that the latest update is sent. + if (DrawingAreaProxy* drawingArea = _data->_page->drawingArea()) + drawingArea->waitForPossibleGeometryUpdate(0); +} + +- (void)waitForAsyncDrawingAreaSizeUpdate +{ + if (DrawingAreaProxy* drawingArea = _data->_page->drawingArea()) { + // If a geometry update is still pending then the action of recieving the + // first geometry update may result in another update being scheduled - + // we should wait for this to complete too. + drawingArea->waitForPossibleGeometryUpdate(DrawingAreaProxy::didUpdateBackingStoreStateTimeout * 0.5); + drawingArea->waitForPossibleGeometryUpdate(DrawingAreaProxy::didUpdateBackingStoreStateTimeout * 0.5); + } +} + +- (NSWindow*)createFullScreenWindow +{ +#if ENABLE(FULLSCREEN_API) +#if __MAC_OS_X_VERSION_MIN_REQUIRED <= 1080 + NSRect contentRect = NSZeroRect; +#else + NSRect contentRect = [[NSScreen mainScreen] frame]; +#endif + return [[[WebCoreFullScreenWindow alloc] initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO] autorelease]; +#else + return nil; +#endif } @end diff --git a/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h b/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h index 9b02947a3..8e62c576a 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h +++ b/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h @@ -55,6 +55,7 @@ namespace WebKit { - (void)_processDidCrash; - (void)_pageClosed; - (void)_didRelaunchProcess; +- (void)_preferencesDidChange; - (void)_toolTipChangedFrom:(NSString *)oldToolTip to:(NSString *)newToolTip; - (void)_setCursor:(NSCursor *)cursor; - (void)_setUserInterfaceItemState:(NSString *)commandName enabled:(BOOL)isEnabled state:(int)newState; @@ -73,19 +74,11 @@ namespace WebKit { - (void)_pluginFocusOrWindowFocusChanged:(BOOL)pluginHasFocusAndWindowHasFocus pluginComplexTextInputIdentifier:(uint64_t)pluginComplexTextInputIdentifier; - (void)_setPluginComplexTextInputState:(WebKit::PluginComplexTextInputState)pluginComplexTextInputState pluginComplexTextInputIdentifier:(uint64_t)pluginComplexTextInputIdentifier; -- (void)_setPageHasCustomRepresentation:(BOOL)pageHasCustomRepresentation; -- (void)_didFinishLoadingDataForCustomRepresentationWithSuggestedFilename:(const String&)suggestedFilename dataReference:(const CoreIPC::DataReference&)dataReference; -- (double)_customRepresentationZoomFactor; -- (void)_setCustomRepresentationZoomFactor:(double)zoomFactor; -- (void)_findStringInCustomRepresentation:(NSString *)string withFindOptions:(WebKit::FindOptions)options maxMatchCount:(NSUInteger)count; -- (void)_countStringMatchesInCustomRepresentation:(NSString *)string withFindOptions:(WebKit::FindOptions)options maxMatchCount:(NSUInteger)count; - (void)_setDragImage:(NSImage *)image at:(NSPoint)clientPoint linkDrag:(BOOL)linkDrag; - (void)_setPromisedData:(WebCore::Image *)image withFileName:(NSString *)filename withExtension:(NSString *)extension withTitle:(NSString *)title withURL:(NSString *)url withVisibleURL:(NSString *)visibleUrl withArchive:(WebCore::SharedBuffer*) archiveBuffer forPasteboard:(NSString *)pasteboardName; - (void)_updateSecureInputState; -- (void)_updateTextInputStateIncludingSecureInputState:(BOOL)updateSecureInputState; -- (void)_resetTextInputState; - -- (void)_didChangeScrollbarsForMainFrame; +- (void)_resetSecureInputState; +- (void)_notifyInputContextAboutDiscardedComposition; - (WebKit::ColorSpaceData)_colorSpace; @@ -103,4 +96,6 @@ namespace WebKit { - (void)_setSuppressVisibilityUpdates:(BOOL)suppressVisibilityUpdates; - (BOOL)_suppressVisibilityUpdates; +- (BOOL)_isWindowOccluded; + @end diff --git a/Source/WebKit2/UIProcess/API/mac/WKViewPrivate.h b/Source/WebKit2/UIProcess/API/mac/WKViewPrivate.h index 2161eb786..a9ff9d30f 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKViewPrivate.h +++ b/Source/WebKit2/UIProcess/API/mac/WKViewPrivate.h @@ -25,11 +25,19 @@ #import <WebKit2/WKView.h> +typedef enum { + WKContentAnchorTopLeft, + WKContentAnchorTopRight, + WKContentAnchorBottomLeft, + WKContentAnchorBottomRight, +} WKContentAnchor; + @interface WKView (Private) /* C SPI support. */ @property(readonly) WKPageRef pageRef; +@property WKContentAnchor contentAnchor; - (id)initWithFrame:(NSRect)frame contextRef:(WKContextRef)contextRef pageGroupRef:(WKPageGroupRef)pageGroupRef; - (id)initWithFrame:(NSRect)frame contextRef:(WKContextRef)contextRef pageGroupRef:(WKPageGroupRef)pageGroupRef relatedToPage:(WKPageRef)relatedPage; @@ -51,5 +59,24 @@ + (void)hideWordDefinitionWindow; @property (readwrite) CGFloat minimumLayoutWidth; +@property (readwrite) CGFloat minimumWidthForAutoLayout; +@property (readwrite) NSSize minimumSizeForAutoLayout; +@property (readwrite) BOOL shouldClipToVisibleRect; + +@property(copy, nonatomic) NSColor *underlayColor; + +- (NSView*)fullScreenPlaceholderView; +- (NSWindow*)createFullScreenWindow; + +- (void)beginDeferringViewInWindowChanges; +- (void)endDeferringViewInWindowChanges; +- (void)endDeferringViewInWindowChangesSync; +- (BOOL)isDeferringViewInWindowChanges; + +- (BOOL)windowOcclusionDetectionEnabled; +- (void)setWindowOcclusionDetectionEnabled:(BOOL)flag; + +- (void)forceAsyncDrawingAreaSizeUpdate:(NSSize)size; +- (void)waitForAsyncDrawingAreaSizeUpdate; @end |