diff options
Diffstat (limited to 'Source/WebKit2/WebProcess')
96 files changed, 2743 insertions, 668 deletions
diff --git a/Source/WebKit2/WebProcess/ApplicationCache/WebApplicationCacheManager.cpp b/Source/WebKit2/WebProcess/ApplicationCache/WebApplicationCacheManager.cpp index 4f91e3d..5f9a724 100644 --- a/Source/WebKit2/WebProcess/ApplicationCache/WebApplicationCacheManager.cpp +++ b/Source/WebKit2/WebProcess/ApplicationCache/WebApplicationCacheManager.cpp @@ -56,6 +56,8 @@ void WebApplicationCacheManager::didReceiveMessage(CoreIPC::Connection* connecti void WebApplicationCacheManager::getApplicationCacheOrigins(uint64_t callbackID) { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + HashSet<RefPtr<SecurityOrigin>, SecurityOriginHash> origins; #if ENABLE(OFFLINE_WEB_APPLICATIONS) @@ -79,11 +81,12 @@ void WebApplicationCacheManager::getApplicationCacheOrigins(uint64_t callbackID) } WebProcess::shared().connection()->send(Messages::WebApplicationCacheManagerProxy::DidGetApplicationCacheOrigins(identifiers, callbackID), 0); - WebProcess::shared().terminateIfPossible(); } void WebApplicationCacheManager::deleteEntriesForOrigin(const SecurityOriginData& originData) { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + #if ENABLE(OFFLINE_WEB_APPLICATIONS) RefPtr<SecurityOrigin> origin = SecurityOrigin::create(originData.protocol, originData.host, originData.port); if (!origin) @@ -91,15 +94,15 @@ void WebApplicationCacheManager::deleteEntriesForOrigin(const SecurityOriginData ApplicationCache::deleteCacheForOrigin(origin.get()); #endif - WebProcess::shared().terminateIfPossible(); } void WebApplicationCacheManager::deleteAllEntries() { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + #if ENABLE(OFFLINE_WEB_APPLICATIONS) cacheStorage().deleteAllEntries(); #endif - WebProcess::shared().terminateIfPossible(); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Cookies/WebCookieManager.cpp b/Source/WebKit2/WebProcess/Cookies/WebCookieManager.cpp index 4181e14..e8254cc 100644 --- a/Source/WebKit2/WebProcess/Cookies/WebCookieManager.cpp +++ b/Source/WebKit2/WebProcess/Cookies/WebCookieManager.cpp @@ -54,6 +54,8 @@ void WebCookieManager::didReceiveMessage(CoreIPC::Connection* connection, CoreIP void WebCookieManager::getHostnamesWithCookies(uint64_t callbackID) { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + HashSet<String> hostnames; WebCore::getHostnamesWithCookies(hostnames); @@ -62,25 +64,27 @@ void WebCookieManager::getHostnamesWithCookies(uint64_t callbackID) copyToVector(hostnames, hostnameList); WebProcess::shared().connection()->send(Messages::WebCookieManagerProxy::DidGetHostnamesWithCookies(hostnameList, callbackID), 0); - WebProcess::shared().terminateIfPossible(); } void WebCookieManager::deleteCookiesForHostname(const String& hostname) { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + WebCore::deleteCookiesForHostname(hostname); - WebProcess::shared().terminateIfPossible(); } void WebCookieManager::deleteAllCookies() { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + WebCore::deleteAllCookies(); - WebProcess::shared().terminateIfPossible(); } void WebCookieManager::startObservingCookieChanges() { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + WebCore::startObservingCookieChanges(); - WebProcess::shared().terminateIfPossible(); } void WebCookieManager::stopObservingCookieChanges() @@ -95,14 +99,14 @@ void WebCookieManager::dispatchCookiesDidChange() void WebCookieManager::setHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); platformSetHTTPCookieAcceptPolicy(policy); - WebProcess::shared().terminateIfPossible(); } void WebCookieManager::getHTTPCookieAcceptPolicy(uint64_t callbackID) { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); WebProcess::shared().connection()->send(Messages::WebCookieManagerProxy::DidGetHTTPCookieAcceptPolicy(platformGetHTTPCookieAcceptPolicy(), callbackID), 0); - WebProcess::shared().terminateIfPossible(); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Downloads/Download.cpp b/Source/WebKit2/WebProcess/Downloads/Download.cpp index 3fc87d9..ff0482b 100644 --- a/Source/WebKit2/WebProcess/Downloads/Download.cpp +++ b/Source/WebKit2/WebProcess/Downloads/Download.cpp @@ -52,11 +52,15 @@ Download::Download(uint64_t downloadID, const ResourceRequest& request) #endif { ASSERT(m_downloadID); + + WebProcess::shared().disableTermination(); } Download::~Download() { platformInvalidate(); + + WebProcess::shared().enableTermination(); } CoreIPC::Connection* Download::connection() const diff --git a/Source/WebKit2/WebProcess/Downloads/DownloadManager.cpp b/Source/WebKit2/WebProcess/Downloads/DownloadManager.cpp index 4a96b11..a624891 100644 --- a/Source/WebKit2/WebProcess/Downloads/DownloadManager.cpp +++ b/Source/WebKit2/WebProcess/Downloads/DownloadManager.cpp @@ -77,8 +77,6 @@ void DownloadManager::downloadFinished(Download* download) m_downloads.remove(download->downloadID()); delete download; - - WebProcess::shared().terminateIfPossible(); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Downloads/mac/DownloadMac.mm b/Source/WebKit2/WebProcess/Downloads/mac/DownloadMac.mm index 2d09612..aacdf0b 100644 --- a/Source/WebKit2/WebProcess/Downloads/mac/DownloadMac.mm +++ b/Source/WebKit2/WebProcess/Downloads/mac/DownloadMac.mm @@ -45,7 +45,7 @@ - (void)_setOriginatingURL:(NSURL *)originatingURL; @end -@interface WKDownloadAsDelegate : NSObject <NSURLConnectionDelegate> { +@interface WKDownloadAsDelegate : NSObject <NSURLDownloadDelegate> { WebKit::Download* _download; } - (id)initWithDownload:(WebKit::Download*)download; diff --git a/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.cpp b/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.cpp index e856876..47f1d42 100644 --- a/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.cpp +++ b/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.cpp @@ -66,9 +66,8 @@ bool WebFullScreenManager::supportsFullScreen(bool withKeyboard) if (!m_page->corePage()->settings()->fullScreenEnabled()) return false; - bool supports = true; - m_page->sendSync(Messages::WebFullScreenManagerProxy::SupportsFullScreen(withKeyboard), supports); - return supports; + return m_page->injectedBundleFullScreenClient().supportsFullScreen(m_page.get(), withKeyboard); + } void WebFullScreenManager::enterFullScreenForElement(WebCore::Element* element) @@ -76,14 +75,14 @@ void WebFullScreenManager::enterFullScreenForElement(WebCore::Element* element) ASSERT(element); m_element = element; m_initialFrame = m_element->screenRect(); - m_page->send(Messages::WebFullScreenManagerProxy::EnterFullScreen()); + m_page->injectedBundleFullScreenClient().enterFullScreenForElement(m_page.get(), element); } void WebFullScreenManager::exitFullScreenForElement(WebCore::Element* element) { ASSERT(element); ASSERT(m_element == element); - m_page->send(Messages::WebFullScreenManagerProxy::ExitFullScreen()); + m_page->injectedBundleFullScreenClient().exitFullScreenForElement(m_page.get(), element); } void WebFullScreenManager::beganEnterFullScreenAnimation() diff --git a/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.h b/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.h index d4ec15d..d6ccb15 100644 --- a/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.h +++ b/Source/WebKit2/WebProcess/FullScreen/WebFullScreenManager.h @@ -63,15 +63,16 @@ public: void finishedExitFullScreenAnimation(bool completed); virtual void setRootFullScreenLayer(WebCore::GraphicsLayer*) = 0; + void willEnterFullScreen(); + void didEnterFullScreen(); + void willExitFullScreen(); + void didExitFullScreen(); + WebCore::Element* element(); protected: WebFullScreenManager(WebPage*); - void willEnterFullScreen(); - void didEnterFullScreen(); - void willExitFullScreen(); - void didExitFullScreen(); virtual void beginEnterFullScreenAnimation(float duration) = 0; virtual void beginExitFullScreenAnimation(float duration) = 0; WebCore::IntRect getFullScreenRect(); diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.cpp index 587968c..d73070d 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.cpp +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundle.cpp @@ -133,7 +133,42 @@ void WKBundleOverrideAllowUniversalAccessFromFileURLsForTestRunner(WKBundleRef b toImpl(bundleRef)->overrideAllowUniversalAccessFromFileURLsForTestRunner(toImpl(pageGroupRef), enabled); } +void WKBundleSetAllowFileAccessFromFileURLs(WKBundleRef bundleRef, WKBundlePageGroupRef pageGroupRef, bool enabled) +{ + toImpl(bundleRef)->setAllowFileAccessFromFileURLs(toImpl(pageGroupRef), enabled); +} + void WKBundleReportException(JSContextRef context, JSValueRef exception) { InjectedBundle::reportException(context, exception); } + +void WKBundleClearAllDatabases(WKBundleRef bundleRef) +{ + toImpl(bundleRef)->clearAllDatabases(); +} + +void WKBundleSetDatabaseQuota(WKBundleRef bundleRef, uint64_t quota) +{ + toImpl(bundleRef)->setDatabaseQuota(quota); +} + +int WKBundleNumberOfPages(WKBundleRef bundleRef, WKBundleFrameRef frameRef, double pageWidthInPixels, double pageHeightInPixels) +{ + return toImpl(bundleRef)->numberOfPages(toImpl(frameRef), pageWidthInPixels, pageHeightInPixels); +} + +int WKBundlePageNumberForElementById(WKBundleRef bundleRef, WKBundleFrameRef frameRef, WKStringRef idRef, double pageWidthInPixels, double pageHeightInPixels) +{ + return toImpl(bundleRef)->pageNumberForElementById(toImpl(frameRef), toImpl(idRef)->string(), pageWidthInPixels, pageHeightInPixels); +} + +WKStringRef WKBundlePageSizeAndMarginsInPixels(WKBundleRef bundleRef, WKBundleFrameRef frameRef, int pageIndex, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) +{ + return toCopiedAPI(toImpl(bundleRef)->pageSizeAndMarginsInPixels(toImpl(frameRef), pageIndex, width, height, marginTop, marginRight, marginBottom, marginLeft)); +} + +WK_EXPORT bool WKBundleIsPageBoxVisible(WKBundleRef bundleRef, WKBundleFrameRef frameRef, int pageIndex) +{ + return toImpl(bundleRef)->isPageBoxVisible(toImpl(frameRef), pageIndex); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.cpp index dd44e93..5528dfe 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.cpp +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.cpp @@ -201,6 +201,16 @@ WKSize WKBundleFrameGetScrollOffset(WKBundleFrameRef frameRef) return toAPI(toImpl(frameRef)->scrollOffset()); } +bool WKBundleFrameHasHorizontalScrollbar(WKBundleFrameRef frameRef) +{ + return toImpl(frameRef)->hasHorizontalScrollbar(); +} + +bool WKBundleFrameHasVerticalScrollbar(WKBundleFrameRef frameRef) +{ + return toImpl(frameRef)->hasVerticalScrollbar(); +} + bool WKBundleFrameGetDocumentBackgroundColor(WKBundleFrameRef frameRef, double* red, double* green, double* blue, double* alpha) { return toImpl(frameRef)->getDocumentBackgroundColor(red, green, blue, alpha); diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.h index 3c7c52d..727ea53 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.h +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleFrame.h @@ -63,6 +63,9 @@ WK_EXPORT WKRect WKBundleFrameGetVisibleContentBounds(WKBundleFrameRef frame); WK_EXPORT WKRect WKBundleFrameGetVisibleContentBoundsExcludingScrollbars(WKBundleFrameRef frame); WK_EXPORT WKSize WKBundleFrameGetScrollOffset(WKBundleFrameRef frame); +WK_EXPORT bool WKBundleFrameHasHorizontalScrollbar(WKBundleFrameRef frame); +WK_EXPORT bool WKBundleFrameHasVerticalScrollbar(WKBundleFrameRef frame); + WK_EXPORT bool WKBundleFrameGetDocumentBackgroundColor(WKBundleFrameRef frame, double* red, double* green, double* blue, double* alpha); WK_EXPORT WKStringRef WKBundleFrameCopySuggestedFilenameForResourceWithURL(WKBundleFrameRef frame, WKURLRef url); diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandle.cpp index 6bed7a4..292b022 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandle.cpp +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandle.cpp @@ -51,14 +51,20 @@ WKBundleNodeHandleRef WKBundleNodeHandleCopyDocument(WKBundleNodeHandleRef nodeH return toAPI(nodeHandle.release().releaseRef()); } -WKRect WKBundleNodeHandleGetElementBounds(WKBundleNodeHandleRef nodeHandleRef) +WKRect WKBundleNodeHandleGetRenderRect(WKBundleNodeHandleRef nodeHandleRef, bool* isReplaced) { - return toAPI(toImpl(nodeHandleRef)->elementBounds()); + return toAPI(toImpl(nodeHandleRef)->renderRect(isReplaced)); } -WKRect WKBundleNodeHandleGetRenderRect(WKBundleNodeHandleRef nodeHandleRef, bool* isReplaced) +WKRect WKBundleNodeHandleGetElementBounds(WKBundleNodeHandleRef elementHandleRef) { - return toAPI(toImpl(nodeHandleRef)->renderRect(isReplaced)); + return toAPI(toImpl(elementHandleRef)->elementBounds()); +} + +WKBundleNodeHandleRef WKBundleNodeHandleCopyElementShadowRoot(WKBundleNodeHandleRef elementHandleRef) +{ + RefPtr<InjectedBundleNodeHandle> nodeHandle = toImpl(elementHandleRef)->elementShadowRoot(); + return toAPI(nodeHandle.release().releaseRef()); } void WKBundleNodeHandleSetHTMLInputElementValueForUser(WKBundleNodeHandleRef htmlInputElementHandleRef, WKStringRef valueRef) diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandlePrivate.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandlePrivate.h index 6006596..3655194 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandlePrivate.h +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundleNodeHandlePrivate.h @@ -42,9 +42,11 @@ WK_EXPORT WKBundleNodeHandleRef WKBundleNodeHandleCopyDocument(WKBundleNodeHandl /* Additional DOM Operations */ -WK_EXPORT WKRect WKBundleNodeHandleGetElementBounds(WKBundleNodeHandleRef nodeHandle); WK_EXPORT WKRect WKBundleNodeHandleGetRenderRect(WKBundleNodeHandleRef nodeHandle, bool* isReplaced); +/* Element Specific Operations */ +WK_EXPORT WKRect WKBundleNodeHandleGetElementBounds(WKBundleNodeHandleRef elementHandle); +WK_EXPORT WKBundleNodeHandleRef WKBundleNodeHandleCopyElementShadowRoot(WKBundleNodeHandleRef elementHandle); /* HTMLInputElement Specific Operations */ WK_EXPORT void WKBundleNodeHandleSetHTMLInputElementValueForUser(WKBundleNodeHandleRef htmlInputElementHandle, WKStringRef value); diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp index 58052c5..e57b420 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,8 +28,10 @@ #include "WKBundlePagePrivate.h" #include "InjectedBundleBackForwardList.h" +#include "InjectedBundleNodeHandle.h" #include "WKAPICast.h" #include "WKBundleAPICast.h" +#include "WebFullScreenManager.h" #include "WebImage.h" #include "WebPage.h" #include "WebURL.h" @@ -93,6 +95,43 @@ void WKBundlePageSetUIClient(WKBundlePageRef pageRef, WKBundlePageUIClient* wkCl toImpl(pageRef)->initializeInjectedBundleUIClient(wkClient); } +void WKBundlePageSetFullScreenClient(WKBundlePageRef pageRef, WKBundlePageFullScreenClient* wkClient) +{ +#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API + if (wkClient && wkClient->version) + return; + toImpl(pageRef)->initializeInjectedBundleFullScreenClient(wkClient); +#endif +} + +void WKBundlePageWillEnterFullScreen(WKBundlePageRef pageRef) +{ +#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API + toImpl(pageRef)->fullScreenManager()->willEnterFullScreen(); +#endif +} + +void WKBundlePageDidEnterFullScreen(WKBundlePageRef pageRef) +{ +#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API + toImpl(pageRef)->fullScreenManager()->didEnterFullScreen(); +#endif +} + +void WKBundlePageWillExitFullScreen(WKBundlePageRef pageRef) +{ +#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API + toImpl(pageRef)->fullScreenManager()->willExitFullScreen(); +#endif +} + +void WKBundlePageDidExitFullScreen(WKBundlePageRef pageRef) +{ +#if defined(ENABLE_FULLSCREEN_API) && ENABLE_FULLSCREEN_API + toImpl(pageRef)->fullScreenManager()->didExitFullScreen(); +#endif +} + WKBundlePageGroupRef WKBundlePageGetPageGroup(WKBundlePageRef pageRef) { return toAPI(toImpl(pageRef)->pageGroup()); @@ -158,6 +197,11 @@ void WKBundlePageSetPageZoomFactor(WKBundlePageRef pageRef, double zoomFactor) toImpl(pageRef)->setPageZoomFactor(zoomFactor); } +void WKBundlePageSetScaleAtOrigin(WKBundlePageRef pageRef, double scale, WKPoint origin) +{ + toImpl(pageRef)->scaleWebView(scale, toIntPoint(origin)); +} + WKBundleBackForwardListRef WKBundlePageGetBackForwardList(WKBundlePageRef pageRef) { return toAPI(toImpl(pageRef)->backForwardList()); @@ -170,7 +214,7 @@ void WKBundlePageInstallPageOverlay(WKBundlePageRef pageRef, WKBundlePageOverlay void WKBundlePageUninstallPageOverlay(WKBundlePageRef pageRef, WKBundlePageOverlayRef pageOverlayRef) { - toImpl(pageRef)->uninstallPageOverlay(toImpl(pageOverlayRef)); + toImpl(pageRef)->uninstallPageOverlay(toImpl(pageOverlayRef), false); } bool WKBundlePageHasLocalDataForURL(WKBundlePageRef pageRef, WKURLRef urlRef) @@ -217,3 +261,18 @@ void WKBundlePageForceRepaint(WKBundlePageRef page) { toImpl(page)->forceRepaintWithoutCallback(); } + +void WKBundlePageSimulateMouseDown(WKBundlePageRef page, int button, WKPoint position, int clickCount, WKEventModifiers modifiers, double time) +{ + toImpl(page)->simulateMouseDown(button, toIntPoint(position), clickCount, modifiers, time); +} + +void WKBundlePageSimulateMouseUp(WKBundlePageRef page, int button, WKPoint position, int clickCount, WKEventModifiers modifiers, double time) +{ + toImpl(page)->simulateMouseUp(button, toIntPoint(position), clickCount, modifiers, time); +} + +void WKBundlePageSimulateMouseMotion(WKBundlePageRef page, WKPoint position, double time) +{ + toImpl(page)->simulateMouseMotion(toIntPoint(position), time); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h index e01f51f..74d899e 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePage.h @@ -66,6 +66,12 @@ enum { }; typedef uint32_t WKInputFieldActionType; +enum { + WKFullScreenNoKeyboard, + WKFullScreenKeyboard, +}; +typedef uint32_t WKFullScreenKeyboardRequestType; + // Loader Client typedef void (*WKBundlePageDidStartProvisionalLoadForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); typedef void (*WKBundlePageDidReceiveServerRedirectForProvisionalLoadForFrameCallback)(WKBundlePageRef page, WKBundleFrameRef frame, WKTypeRef* userData, const void *clientInfo); @@ -243,8 +249,27 @@ struct WKBundlePageContextMenuClient { }; typedef struct WKBundlePageContextMenuClient WKBundlePageContextMenuClient; +// Full Screen client +typedef bool (*WKBundlePageSupportsFullScreen)(WKBundlePageRef page, WKFullScreenKeyboardRequestType requestType); +typedef void (*WKBundlePageEnterFullScreenForElement)(WKBundlePageRef page, WKBundleNodeHandleRef element); +typedef void (*WKBundlePageExitFullScreenForElement)(WKBundlePageRef page, WKBundleNodeHandleRef element); + +struct WKBundlePageFullScreenClient { + int version; + const void * clientInfo; + WKBundlePageSupportsFullScreen supportsFullScreen; + WKBundlePageEnterFullScreenForElement enterFullScreenForElement; + WKBundlePageExitFullScreenForElement exitFullScreenForElement; +}; +typedef struct WKBundlePageFullScreenClient WKBundlePageFullScreenClient; + +WK_EXPORT void WKBundlePageWillEnterFullScreen(WKBundlePageRef page); +WK_EXPORT void WKBundlePageDidEnterFullScreen(WKBundlePageRef page); +WK_EXPORT void WKBundlePageWillExitFullScreen(WKBundlePageRef page); +WK_EXPORT void WKBundlePageDidExitFullScreen(WKBundlePageRef page); + WK_EXPORT WKTypeID WKBundlePageGetTypeID(); - + WK_EXPORT void WKBundlePageSetContextMenuClient(WKBundlePageRef page, WKBundlePageContextMenuClient* client); WK_EXPORT void WKBundlePageSetEditorClient(WKBundlePageRef page, WKBundlePageEditorClient* client); WK_EXPORT void WKBundlePageSetFormClient(WKBundlePageRef page, WKBundlePageFormClient* client); @@ -252,6 +277,8 @@ WK_EXPORT void WKBundlePageSetPageLoaderClient(WKBundlePageRef page, WKBundlePag WK_EXPORT void WKBundlePageSetResourceLoadClient(WKBundlePageRef page, WKBundlePageResourceLoadClient* client); WK_EXPORT void WKBundlePageSetPolicyClient(WKBundlePageRef page, WKBundlePagePolicyClient* client); WK_EXPORT void WKBundlePageSetUIClient(WKBundlePageRef page, WKBundlePageUIClient* client); + +WK_EXPORT void WKBundlePageSetFullScreenClient(WKBundlePageRef page, WKBundlePageFullScreenClient* client); WK_EXPORT WKBundlePageGroupRef WKBundlePageGetPageGroup(WKBundlePageRef page); WK_EXPORT WKBundleFrameRef WKBundlePageGetMainFrame(WKBundlePageRef page); diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.cpp index d86c2e0..4364ce9 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.cpp +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.cpp @@ -137,3 +137,8 @@ void WKBundlePageOverlaySetNeedsDisplay(WKBundlePageOverlayRef bundlePageOverlay { toImpl(bundlePageOverlayRef)->setNeedsDisplay(enclosingIntRect(toFloatRect(rect))); } + +float WKBundlePageOverlayFractionFadedIn(WKBundlePageOverlayRef bundlePageOverlayRef) +{ + return toImpl(bundlePageOverlayRef)->fractionFadedIn(); +} diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.h index 3b4f950..e78b350 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.h +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePageOverlay.h @@ -66,6 +66,7 @@ WK_EXPORT WKTypeID WKBundlePageOverlayGetTypeID(); WK_EXPORT WKBundlePageOverlayRef WKBundlePageOverlayCreate(WKBundlePageOverlayClient* client); WK_EXPORT void WKBundlePageOverlaySetNeedsDisplay(WKBundlePageOverlayRef bundlePageOverlay, WKRect rect); +WK_EXPORT float WKBundlePageOverlayFractionFadedIn(WKBundlePageOverlayRef bundlePageOverlay); #ifdef __cplusplus } diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h index b9dce68..5e902d9 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePagePrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -45,8 +45,14 @@ WK_EXPORT void WKBundlePageSetTextZoomFactor(WKBundlePageRef page, double zoomFa WK_EXPORT double WKBundlePageGetPageZoomFactor(WKBundlePageRef page); WK_EXPORT void WKBundlePageSetPageZoomFactor(WKBundlePageRef page, double zoomFactor); +WK_EXPORT void WKBundlePageSetScaleAtOrigin(WKBundlePageRef page, double scale, WKPoint origin); + WK_EXPORT void WKBundlePageForceRepaint(WKBundlePageRef page); +WK_EXPORT void WKBundlePageSimulateMouseDown(WKBundlePageRef page, int button, WKPoint position, int clickCount, WKEventModifiers modifiers, double time); +WK_EXPORT void WKBundlePageSimulateMouseUp(WKBundlePageRef page, int button, WKPoint position, int clickCount, WKEventModifiers modifiers, double time); +WK_EXPORT void WKBundlePageSimulateMouseMotion(WKBundlePageRef page, WKPoint position, double time); + #ifdef __cplusplus } #endif diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePrivate.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePrivate.h index 79c796a..03e17a2 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePrivate.h +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/WKBundlePrivate.h @@ -66,6 +66,13 @@ WK_EXPORT void WKBundleRemoveAllUserContent(WKBundleRef bundle, WKBundlePageGrou // Will make WebProcess ignore this preference until a preferences change notification, only for WebKitTestRunner use. WK_EXPORT void WKBundleOverrideXSSAuditorEnabledForTestRunner(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, bool enabled); WK_EXPORT void WKBundleOverrideAllowUniversalAccessFromFileURLsForTestRunner(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, bool enabled); +WK_EXPORT void WKBundleSetAllowFileAccessFromFileURLs(WKBundleRef bundle, WKBundlePageGroupRef pageGroup, bool enabled); +WK_EXPORT void WKBundleClearAllDatabases(WKBundleRef bundle); +WK_EXPORT void WKBundleSetDatabaseQuota(WKBundleRef bundle, uint64_t); +WK_EXPORT int WKBundleNumberOfPages(WKBundleRef bundle, WKBundleFrameRef frameRef, double pageWidthInPixels, double pageHeightInPixels); +WK_EXPORT int WKBundlePageNumberForElementById(WKBundleRef bundle, WKBundleFrameRef frameRef, WKStringRef idRef, double pageWidthInPixels, double pageHeightInPixels); +WK_EXPORT WKStringRef WKBundlePageSizeAndMarginsInPixels(WKBundleRef bundle, WKBundleFrameRef frameRef, int, int, int, int, int, int, int); +WK_EXPORT bool WKBundleIsPageBoxVisible(WKBundleRef bundle, WKBundleFrameRef frameRef, int); #ifdef __cplusplus } diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.cpp b/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.cpp index d97784e..463a211 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.cpp +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.cpp @@ -37,7 +37,7 @@ void WKBundleSetHostAllowsAnyHTTPSCertificate(WKBundleRef bundleRef, WKStringRef toImpl(bundleRef)->setHostAllowsAnyHTTPSCertificate(toWTFString(host)); } -void WKBundleSetClientCertificate(WKBundleRef bundleRef, WKStringRef host, WKCertificateInfoRef certificateInfoRef) +void WKBundleSetClientCertificate(WKBundleRef bundleRef, WKStringRef host, WKStringRef certificateSystemStoreName, WKCertificateInfoRef certificateInfoRef) { - toImpl(bundleRef)->setClientCertificate(toWTFString(host), toImpl(certificateInfoRef)); + toImpl(bundleRef)->setClientCertificate(toWTFString(host), toWTFString(certificateSystemStoreName), toImpl(certificateInfoRef)); } diff --git a/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.h b/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.h index e404ec8..03006dc 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.h +++ b/Source/WebKit2/WebProcess/InjectedBundle/API/c/win/WKBundlePrivateWin.h @@ -33,7 +33,7 @@ extern "C" { #endif WK_EXPORT void WKBundleSetHostAllowsAnyHTTPSCertificate(WKBundleRef bundle, WKStringRef host); -WK_EXPORT void WKBundleSetClientCertificate(WKBundleRef bundle, WKStringRef host, WKCertificateInfoRef certificateInfo); +WK_EXPORT void WKBundleSetClientCertificate(WKBundleRef bundle, WKStringRef host, WKStringRef certificateSystemStoreName, WKCertificateInfoRef certificateInfo); #ifdef __cplusplus } diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp index 5e15872..bef3f90 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp @@ -165,6 +165,14 @@ PassRefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::htmlTableCellElem return getOrCreate(static_cast<HTMLTableCellElement*>(m_node.get())->cellAbove()); } +PassRefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::elementShadowRoot() +{ + if (!m_node->isElementNode()) + return 0; + + return getOrCreate(static_cast<Element*>(m_node.get())->shadowRoot()); +} + PassRefPtr<WebFrame> InjectedBundleNodeHandle::documentFrame() { if (!m_node->isDocumentNode()) diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.h b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.h index e4a5ab9..e1003e8 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.h +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.h @@ -68,6 +68,8 @@ public: PassRefPtr<InjectedBundleNodeHandle> htmlTableCellElementCellAbove(); + PassRefPtr<InjectedBundleNodeHandle> elementShadowRoot(); + PassRefPtr<WebFrame> documentFrame(); PassRefPtr<WebFrame> htmlFrameElementContentFrame(); PassRefPtr<WebFrame> htmlIFrameElementContentFrame(); diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp index 24dc7f9..baee7c9 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.cpp @@ -35,15 +35,20 @@ #include "WKBundleAPICast.h" #include "WebContextMessageKinds.h" #include "WebCoreArgumentCoders.h" +#include "WebDatabaseManager.h" +#include "WebFrame.h" #include "WebPage.h" #include "WebPreferencesStore.h" #include "WebProcess.h" #include <JavaScriptCore/APICast.h> #include <JavaScriptCore/JSLock.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameView.h> #include <WebCore/GCController.h> #include <WebCore/JSDOMWindow.h> #include <WebCore/Page.h> #include <WebCore/PageGroup.h> +#include <WebCore/PrintContext.h> #include <WebCore/Settings.h> #include <wtf/OwnArrayPtr.h> #include <wtf/PassOwnArrayPtr.h> @@ -119,6 +124,76 @@ void InjectedBundle::overrideAllowUniversalAccessFromFileURLsForTestRunner(WebPa (*iter)->settings()->setAllowUniversalAccessFromFileURLs(enabled); } +void InjectedBundle::setAllowFileAccessFromFileURLs(WebPageGroupProxy* pageGroup, bool enabled) +{ + // Override the preference for all future pages. + WebPreferencesStore::overrideAllowFileAccessFromFileURLsForTestRunner(enabled); + + // Change the setting for existing ones. + const HashSet<Page*>& pages = PageGroup::pageGroup(pageGroup->identifier())->pages(); + for (HashSet<Page*>::iterator iter = pages.begin(); iter != pages.end(); ++iter) + (*iter)->settings()->setAllowFileAccessFromFileURLs(enabled); +} + +void InjectedBundle::clearAllDatabases() +{ + WebDatabaseManager::shared().deleteAllDatabases(); +} + +void InjectedBundle::setDatabaseQuota(uint64_t quota) +{ + WebDatabaseManager::shared().setQuotaForOrigin("file:///", quota); +} + +int InjectedBundle::numberOfPages(WebFrame* frame, double pageWidthInPixels, double pageHeightInPixels) +{ + Frame* coreFrame = frame ? frame->coreFrame() : 0; + if (!coreFrame) + return -1; + if (!pageWidthInPixels) + pageWidthInPixels = coreFrame->view()->width(); + if (!pageHeightInPixels) + pageHeightInPixels = coreFrame->view()->height(); + + return PrintContext::numberOfPages(coreFrame, FloatSize(pageWidthInPixels, pageHeightInPixels)); +} + +int InjectedBundle::pageNumberForElementById(WebFrame* frame, const String& id, double pageWidthInPixels, double pageHeightInPixels) +{ + Frame* coreFrame = frame ? frame->coreFrame() : 0; + if (!coreFrame) + return -1; + + Element* element = coreFrame->document()->getElementById(AtomicString(id)); + if (!element) + return -1; + + if (!pageWidthInPixels) + pageWidthInPixels = coreFrame->view()->width(); + if (!pageHeightInPixels) + pageHeightInPixels = coreFrame->view()->height(); + + return PrintContext::pageNumberForElement(element, FloatSize(pageWidthInPixels, pageHeightInPixels)); +} + +String InjectedBundle::pageSizeAndMarginsInPixels(WebFrame* frame, int pageIndex, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) +{ + Frame* coreFrame = frame ? frame->coreFrame() : 0; + if (!coreFrame) + return String(); + + return PrintContext::pageSizeAndMarginsInPixels(coreFrame, pageIndex, width, height, marginTop, marginRight, marginBottom, marginLeft); +} + +bool InjectedBundle::isPageBoxVisible(WebFrame* frame, int pageIndex) +{ + Frame* coreFrame = frame ? frame->coreFrame() : 0; + if (!coreFrame) + return false; + + return PrintContext::isPageBoxVisible(coreFrame, pageIndex); +} + static PassOwnPtr<Vector<String> > toStringVector(ImmutableArray* patterns) { if (!patterns) diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.h index 6896669..6755a39 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.h +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundle.h @@ -60,6 +60,7 @@ typedef void* PlatformBundle; class ImmutableArray; class InjectedBundleScriptWorld; class WebCertificateInfo; +class WebFrame; class WebPage; class WebPageGroupProxy; @@ -82,7 +83,7 @@ public: void postSynchronousMessage(const String&, APIObject*, RefPtr<APIObject>& returnData); #if PLATFORM(WIN) void setHostAllowsAnyHTTPSCertificate(const String&); - void setClientCertificate(const String&, const WebCertificateInfo*); + void setClientCertificate(const String& host, const String& certificateSystemStoreName, const WebCertificateInfo*); #endif // TestRunner only SPI @@ -91,6 +92,11 @@ public: void activateMacFontAscentHack(); void overrideXSSAuditorEnabledForTestRunner(WebPageGroupProxy* pageGroup, bool enabled); void overrideAllowUniversalAccessFromFileURLsForTestRunner(WebPageGroupProxy*, bool); + void setAllowFileAccessFromFileURLs(WebPageGroupProxy*, bool); + int numberOfPages(WebFrame*, double, double); + int pageNumberForElementById(WebFrame*, const String&, double, double); + String pageSizeAndMarginsInPixels(WebFrame*, int, int, int, int, int, int, int); + bool isPageBoxVisible(WebFrame*, int); // UserContent API void addUserScript(WebPageGroupProxy*, InjectedBundleScriptWorld*, const String& source, const String& url, ImmutableArray* whitelist, ImmutableArray* blacklist, WebCore::UserScriptInjectionTime, WebCore::UserContentInjectedFrames); @@ -101,6 +107,10 @@ public: void removeUserStyleSheets(WebPageGroupProxy*, InjectedBundleScriptWorld*); void removeAllUserContent(WebPageGroupProxy*); + // Local storage API + void clearAllDatabases(); + void setDatabaseQuota(uint64_t); + // Garbage collection API void garbageCollectJavaScriptObjects(); void garbageCollectJavaScriptObjectsOnAlternateThreadForDebugging(bool waitUntilDone); diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFullScreenClient.cpp b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFullScreenClient.cpp new file mode 100644 index 0000000..0f81a1c --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFullScreenClient.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2010 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. + */ + +#include "config.h" + +#if ENABLE(FULLSCREEN_API) + +#include "InjectedBundlePageFullScreenClient.h" + +#include "InjectedBundleNodeHandle.h" +#include "WKAPICast.h" +#include "WKBundleAPICast.h" +#include "WebFullScreenManagerProxyMessages.h" +#include "WebPage.h" +#include <WebCore/Element.h> + +using namespace WebCore; + +namespace WebKit { + +bool InjectedBundlePageFullScreenClient::supportsFullScreen(WebPage *page, bool withKeyboard) +{ + if (m_client.supportsFullScreen) + return m_client.supportsFullScreen(toAPI(page), withKeyboard); + + bool supports = true; + page->sendSync(Messages::WebFullScreenManagerProxy::SupportsFullScreen(withKeyboard), supports); + return supports; +} + +void InjectedBundlePageFullScreenClient::enterFullScreenForElement(WebPage *page, WebCore::Element *element) +{ + if (m_client.enterFullScreenForElement) { + RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::getOrCreate(element); + m_client.enterFullScreenForElement(toAPI(page), toAPI(nodeHandle.get())); + } else + page->send(Messages::WebFullScreenManagerProxy::EnterFullScreen()); +} + +void InjectedBundlePageFullScreenClient::exitFullScreenForElement(WebPage *page, WebCore::Element *element) +{ + if (m_client.enterFullScreenForElement) { + RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::getOrCreate(element); + m_client.enterFullScreenForElement(toAPI(page), toAPI(nodeHandle.get())); + } else + page->send(Messages::WebFullScreenManagerProxy::ExitFullScreen()); +} + +} // namespace WebKit + +#endif // ENABLE(FULLSCREEN_API) diff --git a/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFullScreenClient.h b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFullScreenClient.h new file mode 100644 index 0000000..eebc4b4 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/InjectedBundlePageFullScreenClient.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * 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. + */ + +#ifndef InjectedBundlePageFullScreenClient_h +#define InjectedBundlePageFullScreenClient_h + +#if ENABLE(FULLSCREEN_API) + +#include "APIClient.h" +#include "WKBundlePage.h" +#include "WebEvent.h" +#include <wtf/Forward.h> + +namespace WebCore { +class Element; +} + +namespace WebKit { + +class WebPage; + +class InjectedBundlePageFullScreenClient : public APIClient<WKBundlePageFullScreenClient> { +public: + bool supportsFullScreen(WebPage*, bool withKeyboard); + void enterFullScreenForElement(WebPage*, WebCore::Element*); + void exitFullScreenForElement(WebPage*, WebCore::Element*); +}; + +} // namespace WebKit + +#endif // ENABLE(FULLSCREEN_API) + +#endif // InjectedBundlePageFullScreenClient_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/win/InjectedBundleWin.cpp b/Source/WebKit2/WebProcess/InjectedBundle/win/InjectedBundleWin.cpp index 4b415a4..08c9a93 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/win/InjectedBundleWin.cpp +++ b/Source/WebKit2/WebProcess/InjectedBundle/win/InjectedBundleWin.cpp @@ -31,6 +31,7 @@ #include "WebCertificateInfo.h" #include <WebCore/ResourceHandle.h> #include <WebCore/SimpleFontData.h> +#include <wtf/text/CString.h> #include <windows.h> #include <winbase.h> @@ -99,10 +100,10 @@ void InjectedBundle::setHostAllowsAnyHTTPSCertificate(const String& host) #endif } -void InjectedBundle::setClientCertificate(const String& host, const WebCertificateInfo* certificateInfo) +void InjectedBundle::setClientCertificate(const String& host, const String& certificateSystemStoreName, const WebCertificateInfo* certificateInfo) { #if USE(CFNETWORK) - ASSERT(certificateInfo); + ASSERT_ARG(certificateInfo, certificateInfo); if (!certificateInfo) return; @@ -111,7 +112,29 @@ void InjectedBundle::setClientCertificate(const String& host, const WebCertifica if (certificateChain.size() != 1) return; - ResourceHandle::setClientCertificate(host, WebCore::copyCertificateToData(certificateChain.first()).get()); + ASSERT_ARG(certificateSystemStoreName, !certificateSystemStoreName.isEmpty()); + if (certificateSystemStoreName.isEmpty()) + return; + + // The PCCERT_CONTEXT in the WebCertificateInfo we created using the message from the UI process doesn't contain enough information + // to actually use it in a request, we need to get the real certificate from the certificate store (which is typically the "MY" store). + String mutableCertificateSystemStoreName = certificateSystemStoreName; + HCERTSTORE certStore = ::CertOpenSystemStore(0, mutableCertificateSystemStoreName.charactersWithNullTermination()); + if (!certStore) { + LOG_ERROR("Could not open system certificate store %s", certificateSystemStoreName.ascii().data()); + return; + } + + PCCERT_CONTEXT realCert = ::CertFindCertificateInStore(certStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_EXISTING, certificateChain.first(), 0); + if (!realCert) { + LOG_ERROR("Could not find certificate in system certificate store"); + return; + } + + ResourceHandle::setClientCertificate(host, WebCore::copyCertificateToData(realCert).get()); + CertFreeCertificateContext(realCert); + + // We can't close certStore here, since the certificate is still in use. #endif } diff --git a/Source/WebKit2/WebProcess/KeyValueStorage/WebKeyValueStorageManager.cpp b/Source/WebKit2/WebProcess/KeyValueStorage/WebKeyValueStorageManager.cpp index 45431c3..6b41204 100644 --- a/Source/WebKit2/WebProcess/KeyValueStorage/WebKeyValueStorageManager.cpp +++ b/Source/WebKit2/WebProcess/KeyValueStorage/WebKeyValueStorageManager.cpp @@ -57,6 +57,8 @@ void WebKeyValueStorageManager::didReceiveMessage(CoreIPC::Connection* connectio void WebKeyValueStorageManager::getKeyValueStorageOrigins(uint64_t callbackID) { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + Vector<RefPtr<SecurityOrigin> > coreOrigins; StorageTracker::tracker().origins(coreOrigins); @@ -76,23 +78,23 @@ void WebKeyValueStorageManager::getKeyValueStorageOrigins(uint64_t callbackID) } WebProcess::shared().connection()->send(Messages::WebKeyValueStorageManagerProxy::DidGetKeyValueStorageOrigins(identifiers, callbackID), 0); - WebProcess::shared().terminateIfPossible(); } void WebKeyValueStorageManager::deleteEntriesForOrigin(const SecurityOriginData& originData) { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + RefPtr<SecurityOrigin> origin = SecurityOrigin::create(originData.protocol, originData.host, originData.port); if (!origin) return; StorageTracker::tracker().deleteOrigin(origin.get()); - WebProcess::shared().terminateIfPossible(); } void WebKeyValueStorageManager::deleteAllEntries() { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); StorageTracker::tracker().deleteAllOrigins(); - WebProcess::shared().terminateIfPossible(); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/MediaCache/WebMediaCacheManager.cpp b/Source/WebKit2/WebProcess/MediaCache/WebMediaCacheManager.cpp index 6baf6d9..4a5d7f9 100644 --- a/Source/WebKit2/WebProcess/MediaCache/WebMediaCacheManager.cpp +++ b/Source/WebKit2/WebProcess/MediaCache/WebMediaCacheManager.cpp @@ -53,6 +53,8 @@ void WebMediaCacheManager::didReceiveMessage(CoreIPC::Connection* connection, Co void WebMediaCacheManager::getHostnamesWithMediaCache(uint64_t callbackID) { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + Vector<String> mediaCacheHostnames; #if ENABLE(VIDEO) @@ -60,23 +62,24 @@ void WebMediaCacheManager::getHostnamesWithMediaCache(uint64_t callbackID) #endif WebProcess::shared().connection()->send(Messages::WebMediaCacheManagerProxy::DidGetHostnamesWithMediaCache(mediaCacheHostnames, callbackID), 0); - WebProcess::shared().terminateIfPossible(); } void WebMediaCacheManager::clearCacheForHostname(const String& hostname) { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + #if ENABLE(VIDEO) HTMLMediaElement::clearMediaCacheForSite(hostname); #endif - WebProcess::shared().terminateIfPossible(); } void WebMediaCacheManager::clearCacheForAllHostnames() { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + #if ENABLE(VIDEO) HTMLMediaElement::clearMediaCache(); #endif - WebProcess::shared().terminateIfPossible(); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.h b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.h index f0c2424..0fd01ea 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.h @@ -42,7 +42,7 @@ public: NPIdentifier npIdentifier() const { return m_npIdentifier; } private: - static PassRefPtr<JSC::Structure> createStructure(JSC::JSGlobalData& globalData, JSC::JSValue prototype) + static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSValue prototype) { return JSC::Structure::create(globalData, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info); } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h index e8a08da..ed124b9 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.h @@ -55,7 +55,7 @@ public: private: static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::OverridesGetPropertyNames | JSObject::StructureFlags; - static PassRefPtr<JSC::Structure> createStructure(JSC::JSGlobalData& globalData, JSC::JSValue prototype) + static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSValue prototype) { return JSC::Structure::create(globalData, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), AnonymousSlotCount, &s_info); } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp index 4c687f4..7720e88 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp @@ -55,7 +55,6 @@ NPJSObject* NPJSObject::create(JSGlobalData& globalData, NPRuntimeObjectMap* obj NPJSObject::NPJSObject() : m_objectMap(0) - , m_jsObject(Global<JSObject>::EmptyValue) { } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.h index 796f1c3..f0ee07a 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.h @@ -26,7 +26,7 @@ #ifndef NPJSObject_h #define NPJSObject_h -#include <JavaScriptCore/Global.h> +#include <JavaScriptCore/Strong.h> #include <WebCore/npruntime_internal.h> #include <wtf/Noncopyable.h> @@ -90,7 +90,7 @@ private: static bool NP_Construct(NPObject*, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result); NPRuntimeObjectMap* m_objectMap; - JSC::Global<JSC::JSObject> m_jsObject; + JSC::Strong<JSC::JSObject> m_jsObject; }; } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp index f6c0057..1cf60d2 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NPRuntimeObjectMap.cpp @@ -33,6 +33,7 @@ #include <JavaScriptCore/Error.h> #include <JavaScriptCore/JSLock.h> #include <JavaScriptCore/SourceCode.h> +#include <JavaScriptCore/Strong.h> #include <WebCore/Frame.h> #include <WebCore/NotImplemented.h> @@ -182,7 +183,7 @@ void NPRuntimeObjectMap::convertJSValueToNPVariant(ExecState* exec, JSValue valu bool NPRuntimeObjectMap::evaluate(NPObject* npObject, const String&scriptString, NPVariant* result) { - Global<JSGlobalObject> globalObject(this->globalObject()->globalData(), this->globalObject()); + Strong<JSGlobalObject> globalObject(this->globalObject()->globalData(), this->globalObject()); if (!globalObject) return false; diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp index 7d00219..574df0d 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp @@ -491,6 +491,11 @@ void NetscapePlugin::destroy() // Stop all streams. stopAllStreams(); +#if !PLUGIN_ARCHITECTURE(MAC) + m_npWindow.window = 0; + callSetWindow(); +#endif + NPP_Destroy(0); m_isStarted = false; diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp new file mode 100644 index 0000000..d4b2043 --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginNone.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + * + * 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. + */ + +#include "config.h" +#if PLUGIN_ARCHITECTURE(UNSUPPORTED) + +#include "NetscapePlugin.h" + +using namespace WebCore; + +namespace WebKit { + +bool NetscapePlugin::platformPostInitialize() +{ + return false; +} + +void NetscapePlugin::platformDestroy() +{ +} + +bool NetscapePlugin::platformInvalidate(const IntRect&) +{ + return false; +} + +void NetscapePlugin::platformGeometryDidChange() +{ +} + +void NetscapePlugin::platformPaint(GraphicsContext*, const IntRect&, bool) +{ +} + +bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent&) +{ + return false; +} + +bool NetscapePlugin::platformHandleWheelEvent(const WebWheelEvent&) +{ + return false; +} + +void NetscapePlugin::platformSetFocus(bool) +{ +} + +bool NetscapePlugin::platformHandleMouseEnterEvent(const WebMouseEvent&) +{ + return false; +} + +bool NetscapePlugin::platformHandleMouseLeaveEvent(const WebMouseEvent&) +{ + return false; +} + +bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent& event) +{ + return false; +} + +} // namespace WebKit + +#endif // PLUGIN_ARCHITECTURE(UNSUPPORTED) diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp index cf5affc..c5beb5f 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePluginStream.cpp @@ -221,6 +221,7 @@ void NetscapePluginStream::deliverDataToPlugin() int32_t numBytesWritten = m_plugin->NPP_Write(&m_npStream, m_offset, dataLength, data); if (numBytesWritten < 0) { + cancel(); stop(NPRES_NETWORK_ERR); return; } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm index 14ac070..e1c193f 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm @@ -124,6 +124,7 @@ NPBool NetscapePlugin::convertPoint(double sourceX, double sourceY, NPCoordinate case NPCoordinateSpaceFlippedScreen: sourceXInScreenSpace = sourceX; sourceYInScreenSpace = flipScreenYCoordinate(sourceY); + break; default: return false; } @@ -231,17 +232,7 @@ bool NetscapePlugin::platformPostInitialize() // Get the Core Animation layer. if (NPP_GetValue(NPPVpluginCoreAnimationLayer, &value) == NPERR_NO_ERROR && value) { ASSERT(!m_pluginLayer); - - CALayer *realPluginLayer = reinterpret_cast<CALayer *>(value); - - // Create a layer with flipped geometry and add the real plug-in layer as a sublayer - // so the coordinate system will match the event coordinate system. - m_pluginLayer.adoptNS([[CALayer alloc] init]); - [m_pluginLayer.get() setBounds:[realPluginLayer bounds]]; - [m_pluginLayer.get() setGeometryFlipped:YES]; - - [realPluginLayer setAutoresizingMask:kCALayerWidthSizable | kCALayerHeightSizable]; - [m_pluginLayer.get() addSublayer:realPluginLayer]; + m_pluginLayer = reinterpret_cast<CALayer *>(value); } } @@ -517,11 +508,14 @@ bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& mouseEvent) // access m_currentMouseEvent afterwards. RefPtr<NetscapePlugin> protect(this); - bool returnValue = NPP_HandleEvent(&event); + NPP_HandleEvent(&event); m_currentMouseEvent = previousMouseEvent; - return returnValue; + // Some plug-ins return false even if the mouse event has been handled. + // This leads to bugs such as <rdar://problem/9167611>. Work around this + // by always returning true. + return true; } #ifndef NP_NO_CARBON @@ -549,7 +543,12 @@ bool NetscapePlugin::platformHandleMouseEvent(const WebMouseEvent& mouseEvent) event.where.h = mouseEvent.globalPosition().x(); event.where.v = mouseEvent.globalPosition().y(); - return NPP_HandleEvent(&event); + NPP_HandleEvent(&event); + + // Some plug-ins return false even if the mouse event has been handled. + // This leads to bugs such as <rdar://problem/9167611>. Work around this + // by always returning true. + return true; } #endif @@ -646,6 +645,8 @@ static unsigned modifierFlags(const WebKeyboardEvent& keyboardEvent) { unsigned modifierFlags = 0; + if (keyboardEvent.capsLockKey()) + modifierFlags |= NSAlphaShiftKeyMask; if (keyboardEvent.shiftKey()) modifierFlags |= NSShiftKeyMask; if (keyboardEvent.controlKey()) @@ -658,20 +659,46 @@ static unsigned modifierFlags(const WebKeyboardEvent& keyboardEvent) return modifierFlags; } +static bool isFlagsChangedEvent(const WebKeyboardEvent& keyboardEvent) +{ + switch (keyboardEvent.nativeVirtualKeyCode()) { + case 54: // Right Command + case 55: // Left Command + + case 57: // Capslock + + case 56: // Left Shift + case 60: // Right Shift + + case 58: // Left Alt + case 61: // Right Alt + + case 59: // Left Ctrl + case 62: // Right Ctrl + return true; + } + + return false; +} + static NPCocoaEvent initializeKeyboardEvent(const WebKeyboardEvent& keyboardEvent) { NPCocoaEventType eventType; - - switch (keyboardEvent.type()) { - case WebEvent::KeyDown: - eventType = NPCocoaEventKeyDown; - break; - case WebEvent::KeyUp: - eventType = NPCocoaEventKeyUp; - break; - default: - ASSERT_NOT_REACHED(); - return NPCocoaEvent(); + + if (isFlagsChangedEvent(keyboardEvent)) + eventType = NPCocoaEventFlagsChanged; + else { + switch (keyboardEvent.type()) { + case WebEvent::KeyDown: + eventType = NPCocoaEventKeyDown; + break; + case WebEvent::KeyUp: + eventType = NPCocoaEventKeyUp; + break; + default: + ASSERT_NOT_REACHED(); + return NPCocoaEvent(); + } } NPCocoaEvent event = initializeEvent(eventType); diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/mac/PluginProxyMac.mm b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/PluginProxyMac.mm index d331506..0b2917f 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/mac/PluginProxyMac.mm +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/PluginProxyMac.mm @@ -34,8 +34,17 @@ namespace WebKit { PlatformLayer* PluginProxy::pluginLayer() { - if (!m_pluginLayer && m_remoteLayerClientID) - m_pluginLayer = WKMakeRenderLayer(m_remoteLayerClientID); + if (!m_pluginLayer && m_remoteLayerClientID) { + CALayer *renderLayer = WKMakeRenderLayer(m_remoteLayerClientID); + + // Create a layer with flipped geometry and add the real plug-in layer as a sublayer + // so the coordinate system will match the event coordinate system. + m_pluginLayer.adoptNS([[CALayer alloc] init]); + [m_pluginLayer.get() setGeometryFlipped:YES]; + + [renderLayer setAutoresizingMask:kCALayerWidthSizable | kCALayerHeightSizable]; + [m_pluginLayer.get() addSublayer:renderLayer]; + } return m_pluginLayer.get(); } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp index 27e694b..b8c8f2a 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp @@ -25,6 +25,8 @@ */ #include "config.h" +#if PLUGIN_ARCHITECTURE(X11) + #include "NetscapePlugin.h" #include "WebEvent.h" @@ -38,6 +40,7 @@ #include <QX11Info> #elif PLATFORM(GTK) #include <gdk/gdkx.h> +#include <WebCore/GtkVersioning.h> #endif using namespace WebCore; @@ -423,3 +426,5 @@ bool NetscapePlugin::platformHandleKeyboardEvent(const WebKeyboardEvent& event) } } // namespace WebKit + +#endif // PLUGIN_ARCHITECTURE(X11) diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp index 3d007a6..31e377f 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp @@ -32,14 +32,33 @@ #include "PluginProcessConnectionManager.h" #include "PluginProxy.h" #include "WebProcess.h" +#include "WebProcessProxyMessages.h" +#include <WebCore/FileSystem.h> + +using namespace WebCore; namespace WebKit { +// The timeout, in seconds, when sending sync messages to the plug-in. +static const double syncMessageTimeout = 45; + +static double defaultSyncMessageTimeout(const String& pluginPath) +{ + // We don't want a message timeout for the AppleConnect plug-in. + // FIXME: We should key this off something other than the path. + if (pathGetFileName(pluginPath) == "AppleConnect.plugin") + return CoreIPC::Connection::NoTimeout; + + return syncMessageTimeout; +} + PluginProcessConnection::PluginProcessConnection(PluginProcessConnectionManager* pluginProcessConnectionManager, const String& pluginPath, CoreIPC::Connection::Identifier connectionIdentifier) : m_pluginProcessConnectionManager(pluginProcessConnectionManager) , m_pluginPath(pluginPath) { m_connection = CoreIPC::Connection::createClientConnection(connectionIdentifier, this, WebProcess::shared().runLoop()); + + m_connection->setDefaultSyncMessageTimeout(defaultSyncMessageTimeout(m_pluginPath)); m_npRemoteObjectMap = NPRemoteObjectMap::create(m_connection.get()); m_connection->open(); @@ -116,6 +135,11 @@ void PluginProcessConnection::didReceiveInvalidMessage(CoreIPC::Connection*, Cor { } +void PluginProcessConnection::syncMessageSendTimedOut(CoreIPC::Connection*) +{ + WebProcess::shared().connection()->send(Messages::WebProcessProxy::PluginSyncMessageSendTimedOut(m_pluginPath), 0); +} + } // namespace WebKit #endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h index 76e2315..589baf4 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h @@ -66,7 +66,8 @@ private: virtual CoreIPC::SyncReplyMode didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder*); virtual void didClose(CoreIPC::Connection*); virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID); - + virtual void syncMessageSendTimedOut(CoreIPC::Connection*); + PluginProcessConnectionManager* m_pluginProcessConnectionManager; String m_pluginPath; diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp index 1290391..d2f3686 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp @@ -30,13 +30,16 @@ #include "ArgumentDecoder.h" #include "ArgumentEncoder.h" -#include "MachPort.h" #include "PluginProcessConnection.h" #include "WebCoreArgumentCoders.h" #include "WebProcess.h" -#include "WebProcessProxyMessageKinds.h" +#include "WebProcessProxyMessages.h" #include <wtf/StdLibExtras.h> +#if PLATFORM(MAC) +#include "MachPort.h" +#endif + namespace WebKit { PluginProcessConnectionManager& PluginProcessConnectionManager::shared() @@ -61,11 +64,18 @@ PluginProcessConnection* PluginProcessConnectionManager::getPluginProcessConnect } CoreIPC::Connection::Identifier connectionIdentifier; +#if PLATFORM(MAC) CoreIPC::MachPort connectionMachPort; - if (!WebProcess::shared().connection()->deprecatedSendSync(WebProcessProxyLegacyMessage::GetPluginProcessConnection, 0, CoreIPC::In(pluginPath), CoreIPC::Out(connectionMachPort))) + + if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::GetPluginProcessConnection(pluginPath), Messages::WebProcessProxy::GetPluginProcessConnection::Reply(connectionMachPort), 0)) return 0; connectionIdentifier = connectionMachPort.port(); +#else + // FIXME: Implement. + connectionIdentifier = 0; + ASSERT_NOT_REACHED(); +#endif if (!connectionIdentifier) return 0; diff --git a/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.cpp b/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.cpp index 1596319..febf61b 100644 --- a/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.cpp +++ b/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.cpp @@ -28,6 +28,7 @@ #include "Connection.h" #include "MessageID.h" +#include "ResourceCachesToClear.h" #include "SecurityOriginData.h" #include "WebCoreArgumentCoders.h" #include "WebResourceCacheManagerProxyMessages.h" @@ -62,6 +63,8 @@ void WebResourceCacheManager::didReceiveMessage(CoreIPC::Connection* connection, void WebResourceCacheManager::getCacheOrigins(uint64_t callbackID) const { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + MemoryCache::SecurityOriginSet origins; memoryCache()->getOriginsWithCache(origins); @@ -93,11 +96,18 @@ void WebResourceCacheManager::getCacheOrigins(uint64_t callbackID) const } WebProcess::shared().connection()->send(Messages::WebResourceCacheManagerProxy::DidGetCacheOrigins(identifiers, callbackID), 0); - WebProcess::shared().terminateIfPossible(); } -void WebResourceCacheManager::clearCacheForOrigin(SecurityOriginData originData) const +void WebResourceCacheManager::clearCacheForOrigin(SecurityOriginData originData, uint32_t cachesToClear) const { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + +#if USE(CFURLCACHE) + ResourceCachesToClear resourceCachesToClear = static_cast<ResourceCachesToClear>(cachesToClear); +#else + UNUSED_PARAM(cachesToClear); +#endif + RefPtr<SecurityOrigin> origin = SecurityOrigin::create(originData.protocol, originData.host, originData.port); if (!origin) return; @@ -105,19 +115,23 @@ void WebResourceCacheManager::clearCacheForOrigin(SecurityOriginData originData) memoryCache()->removeResourcesWithOrigin(origin.get()); #if USE(CFURLCACHE) - RetainPtr<CFMutableArrayRef> hostArray(AdoptCF, CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks)); - RetainPtr<CFStringRef> host(AdoptCF, origin->host().createCFString()); - CFArrayAppendValue(hostArray.get(), host.get()); + if (resourceCachesToClear != InMemoryResourceCachesOnly) { + RetainPtr<CFMutableArrayRef> hostArray(AdoptCF, CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks)); + RetainPtr<CFStringRef> host(AdoptCF, origin->host().createCFString()); + CFArrayAppendValue(hostArray.get(), host.get()); - clearCFURLCacheForHostNames(hostArray.get()); + clearCFURLCacheForHostNames(hostArray.get()); + } #endif - WebProcess::shared().terminateIfPossible(); } -void WebResourceCacheManager::clearCacheForAllOrigins() const +void WebResourceCacheManager::clearCacheForAllOrigins(uint32_t cachesToClear) const { - WebProcess::shared().clearResourceCaches(); - WebProcess::shared().terminateIfPossible(); + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + + ResourceCachesToClear resourceCachesToClear = static_cast<ResourceCachesToClear>(cachesToClear); + + WebProcess::shared().clearResourceCaches(resourceCachesToClear); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.h b/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.h index 3a29a4b..0172389 100644 --- a/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.h +++ b/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.h @@ -27,6 +27,7 @@ #define WebResourceCacheManager_h #include "Arguments.h" +#include "ResourceCachesToClear.h" #include <wtf/Noncopyable.h> #include <wtf/RetainPtr.h> #include <wtf/text/WTFString.h> @@ -56,8 +57,8 @@ private: void didReceiveWebResourceCacheManagerMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); void getCacheOrigins(uint64_t callbackID) const; - void clearCacheForOrigin(SecurityOriginData origin) const; - void clearCacheForAllOrigins() const; + void clearCacheForOrigin(SecurityOriginData, uint32_t cachesToClear) const; + void clearCacheForAllOrigins(uint32_t cachesToClear) const; #if USE(CFURLCACHE) static RetainPtr<CFArrayRef> cfURLCacheHostNames(); diff --git a/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.messages.in b/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.messages.in index b6d5900..336b253 100644 --- a/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.messages.in +++ b/Source/WebKit2/WebProcess/ResourceCache/WebResourceCacheManager.messages.in @@ -22,6 +22,6 @@ messages -> WebResourceCacheManager { void GetCacheOrigins(uint64_t callbackID) - void ClearCacheForOrigin(WebKit::SecurityOriginData originIdentifier) - void ClearCacheForAllOrigins() + void ClearCacheForOrigin(WebKit::SecurityOriginData originIdentifier, uint32_t cachesToClear) + void ClearCacheForAllOrigins(uint32_t cachesToClear) } diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp index becf48f..2a81851 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebChromeClient.cpp @@ -43,7 +43,6 @@ #include "WebPopupMenu.h" #include "WebPreferencesStore.h" #include "WebProcess.h" -#include "WebProcessProxyMessageKinds.h" #include "WebSearchPopupMenu.h" #include <WebCore/DatabaseTracker.h> #include <WebCore/FileChooser.h> @@ -138,7 +137,7 @@ bool WebChromeClient::canTakeFocus(FocusDirection) void WebChromeClient::takeFocus(FocusDirection direction) { - m_page->send(Messages::WebPageProxy::TakeFocus(direction == FocusDirectionForward ? true : false)); + m_page->send(Messages::WebPageProxy::TakeFocus(direction)); } void WebChromeClient::focusedNodeChanged(Node*) diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.cpp index 825a448..6104a50 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.cpp +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.cpp @@ -67,6 +67,8 @@ void WebDatabaseManager::didReceiveMessage(CoreIPC::Connection* connection, Core void WebDatabaseManager::getDatabasesByOrigin(uint64_t callbackID) const { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + // FIXME: This could be made more efficient by adding a function to DatabaseTracker // to get both the origins and the Vector of DatabaseDetails for each origin in one // shot. That would avoid taking the numerous locks this requires. @@ -105,11 +107,12 @@ void WebDatabaseManager::getDatabasesByOrigin(uint64_t callbackID) const } WebProcess::shared().connection()->send(Messages::WebDatabaseManagerProxy::DidGetDatabasesByOrigin(originAndDatabasesVector, callbackID), 0); - WebProcess::shared().terminateIfPossible(); } void WebDatabaseManager::getDatabaseOrigins(uint64_t callbackID) const { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + Vector<RefPtr<SecurityOrigin> > origins; DatabaseTracker::tracker().origins(origins); @@ -119,37 +122,41 @@ void WebDatabaseManager::getDatabaseOrigins(uint64_t callbackID) const for (size_t i = 0; i < numOrigins; ++i) identifiers[i] = origins[i]->databaseIdentifier(); WebProcess::shared().connection()->send(Messages::WebDatabaseManagerProxy::DidGetDatabaseOrigins(identifiers, callbackID), 0); - WebProcess::shared().terminateIfPossible(); } void WebDatabaseManager::deleteDatabaseWithNameForOrigin(const String& databaseIdentifier, const String& originIdentifier) const { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromDatabaseIdentifier(originIdentifier); if (!origin) return; DatabaseTracker::tracker().deleteDatabase(origin.get(), databaseIdentifier); - WebProcess::shared().terminateIfPossible(); } void WebDatabaseManager::deleteDatabasesForOrigin(const String& originIdentifier) const { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromDatabaseIdentifier(originIdentifier); if (!origin) return; DatabaseTracker::tracker().deleteOrigin(origin.get()); - WebProcess::shared().terminateIfPossible(); } void WebDatabaseManager::deleteAllDatabases() const { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + DatabaseTracker::tracker().deleteAllDatabases(); - WebProcess::shared().terminateIfPossible(); } void WebDatabaseManager::setQuotaForOrigin(const String& originIdentifier, unsigned long long quota) const { + WebProcess::LocalTerminationDisabler terminationDisabler(WebProcess::shared()); + // If the quota is set to a value lower than the current usage, that quota will // "stick" but no data will be purged to meet the new quota. This will simply // prevent new data from being added to databases in that origin. @@ -159,7 +166,6 @@ void WebDatabaseManager::setQuotaForOrigin(const String& originIdentifier, unsig return; DatabaseTracker::tracker().setQuota(origin.get(), quota); - WebProcess::shared().terminateIfPossible(); } void WebDatabaseManager::dispatchDidModifyOrigin(SecurityOrigin* origin) diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.h index 96ed83e..ad91493 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.h +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebDatabaseManager.h @@ -46,6 +46,10 @@ public: static void initialize(const String& databaseDirectory); void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + void setQuotaForOrigin(const String& originIdentifier, unsigned long long quota) const; + +public: + void deleteAllDatabases() const; private: WebDatabaseManager(); @@ -58,8 +62,6 @@ private: void getDatabaseOrigins(uint64_t callbackID) const; void deleteDatabaseWithNameForOrigin(const String& databaseIdentifier, const String& originIdentifier) const; void deleteDatabasesForOrigin(const String& originIdentifier) const; - void deleteAllDatabases() const; - void setQuotaForOrigin(const String& originIdentifier, unsigned long long quota) const; // WebCore::DatabaseTrackerClient virtual void dispatchDidModifyOrigin(WebCore::SecurityOrigin*); diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.cpp index dfb1542..204810e 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.cpp +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.cpp @@ -26,14 +26,16 @@ #include "config.h" #include "WebDragClient.h" -#include <WebCore/NotImplemented.h> +#include "WebPage.h" using namespace WebCore; namespace WebKit { -void WebDragClient::willPerformDragDestinationAction(DragDestinationAction, DragData*) +void WebDragClient::willPerformDragDestinationAction(DragDestinationAction action, DragData*) { + if (action == DragDestinationActionLoad) + m_page->willPerformLoadDragDestinationAction(); } void WebDragClient::willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard*) diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp index b954283..197a0ab 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp @@ -26,10 +26,11 @@ #include "config.h" #include "WebEditorClient.h" -#include "SelectionState.h" +#include "EditorState.h" #include "WebCoreArgumentCoders.h" #include "WebFrameLoaderClient.h" #include "WebPage.h" +#include "WebPageProxy.h" #include "WebPageProxyMessages.h" #include "WebProcess.h" #include <WebCore/ArchiveResource.h> @@ -189,16 +190,7 @@ void WebEditorClient::respondToChangedSelection() if (!frame) return; - SelectionState selectionState; - selectionState.isNone = frame->selection()->isNone(); - selectionState.isContentEditable = frame->selection()->isContentEditable(); - selectionState.isContentRichlyEditable = frame->selection()->isContentRichlyEditable(); - selectionState.isInPasswordField = frame->selection()->isInPasswordField(); - selectionState.hasComposition = frame->editor()->hasComposition(); - - WebPage::getLocationAndLengthFromRange(frame->selection()->toNormalizedRange().get(), selectionState.selectedRangeStart, selectionState.selectedRangeLength); - - m_page->send(Messages::WebPageProxy::SelectionStateChanged(selectionState)); + m_page->send(Messages::WebPageProxy::EditorStateChanged(m_page->editorState())); #if PLATFORM(WIN) // FIXME: This should also go into the selection state. @@ -263,27 +255,31 @@ bool WebEditorClient::canPaste(bool defaultValue) const bool WebEditorClient::canUndo() const { - notImplemented(); - return false; + bool result = false; + m_page->sendSync(Messages::WebPageProxy::CanUndoRedo(static_cast<uint32_t>(WebPageProxy::Undo)), Messages::WebPageProxy::CanUndoRedo::Reply(result)); + return result; } bool WebEditorClient::canRedo() const { - notImplemented(); - return false; + bool result = false; + m_page->sendSync(Messages::WebPageProxy::CanUndoRedo(static_cast<uint32_t>(WebPageProxy::Redo)), Messages::WebPageProxy::CanUndoRedo::Reply(result)); + return result; } void WebEditorClient::undo() { - notImplemented(); + bool result = false; + m_page->sendSync(Messages::WebPageProxy::ExecuteUndoRedo(static_cast<uint32_t>(WebPageProxy::Undo)), Messages::WebPageProxy::ExecuteUndoRedo::Reply(result)); } void WebEditorClient::redo() { - notImplemented(); + bool result = false; + m_page->sendSync(Messages::WebPageProxy::ExecuteUndoRedo(static_cast<uint32_t>(WebPageProxy::Redo)), Messages::WebPageProxy::ExecuteUndoRedo::Reply(result)); } -#if !PLATFORM(MAC) +#if !PLATFORM(GTK) && !PLATFORM(MAC) void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event) { if (m_page->handleEditingKeyboardEvent(event)) @@ -389,9 +385,15 @@ void WebEditorClient::learnWord(const String& word) m_page->send(Messages::WebPageProxy::LearnWord(word)); } -void WebEditorClient::checkSpellingOfString(const UChar*, int, int*, int*) +void WebEditorClient::checkSpellingOfString(const UChar* text, int length, int* misspellingLocation, int* misspellingLength) { - notImplemented(); + int32_t resultLocation = -1; + int32_t resultLength = 0; + // FIXME: It would be nice if we wouldn't have to copy the text here. + m_page->sendSync(Messages::WebPageProxy::CheckSpellingOfString(String(text, length)), + Messages::WebPageProxy::CheckSpellingOfString::Reply(resultLocation, resultLength)); + *misspellingLocation = resultLocation; + *misspellingLength = resultLength; } String WebEditorClient::getAutoCorrectSuggestionForMisspelledWord(const String&) @@ -400,9 +402,15 @@ String WebEditorClient::getAutoCorrectSuggestionForMisspelledWord(const String&) return String(); } -void WebEditorClient::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*) +void WebEditorClient::checkGrammarOfString(const UChar* text, int length, Vector<WebCore::GrammarDetail>& grammarDetails, int* badGrammarLocation, int* badGrammarLength) { - notImplemented(); + int32_t resultLocation = -1; + int32_t resultLength = 0; + // FIXME: It would be nice if we wouldn't have to copy the text here. + m_page->sendSync(Messages::WebPageProxy::CheckGrammarOfString(String(text, length)), + Messages::WebPageProxy::CheckGrammarOfString::Reply(grammarDetails, resultLocation, resultLength)); + *badGrammarLocation = resultLocation; + *badGrammarLength = resultLength; } void WebEditorClient::updateSpellingUIWithGrammarString(const String& badGrammarPhrase, const GrammarDetail& grammarDetail) @@ -422,8 +430,9 @@ void WebEditorClient::showSpellingUI(bool) bool WebEditorClient::spellingUIIsShowing() { - notImplemented(); - return false; + bool isShowing = false; + m_page->sendSync(Messages::WebPageProxy::SpellingUIIsShowing(), Messages::WebPageProxy::SpellingUIIsShowing::Reply(isShowing)); + return isShowing; } void WebEditorClient::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses) @@ -441,7 +450,7 @@ void WebEditorClient::setInputMethodState(bool) notImplemented(); } -void WebEditorClient::requestCheckingOfString(WebCore::SpellChecker*, int, const WTF::String&) +void WebEditorClient::requestCheckingOfString(WebCore::SpellChecker*, int, WebCore::TextCheckingTypeMask, const WTF::String&) { notImplemented(); } diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h index 9200af0..633090f 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h @@ -123,6 +123,11 @@ private: virtual void toggleAutomaticSpellingCorrection(); #endif +#if PLATFORM(GTK) + bool executePendingEditorCommands(WebCore::Frame*, Vector<WTF::String>, bool); + void getEditorCommandsForKeyEvent(const WebCore::KeyboardEvent*, Vector<WTF::String>&); +#endif + TextCheckerClient* textChecker() { return this; } virtual void ignoreWordInSpellDocument(const String&); @@ -131,7 +136,7 @@ private: virtual String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord); virtual void checkGrammarOfString(const UChar*, int length, Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength); #if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) - virtual void checkTextOfParagraph(const UChar* text, int length, uint64_t checkingTypes, Vector<WebCore::TextCheckingResult>& results); + virtual void checkTextOfParagraph(const UChar* text, int length, WebCore::TextCheckingTypeMask checkingTypes, Vector<WebCore::TextCheckingResult>& results); #endif virtual void updateSpellingUIWithGrammarString(const String&, const WebCore::GrammarDetail& detail); virtual void updateSpellingUIWithMisspelledWord(const String&); @@ -140,7 +145,7 @@ private: virtual void getGuessesForWord(const String& word, const String& context, Vector<String>& guesses); virtual void willSetInputMethodState(); virtual void setInputMethodState(bool enabled); - virtual void requestCheckingOfString(WebCore::SpellChecker*, int, const WTF::String&); + virtual void requestCheckingOfString(WebCore::SpellChecker*, int, WebCore::TextCheckingTypeMask, const WTF::String&); #if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD) virtual void showCorrectionPanel(WebCore::CorrectionPanelInfo::PanelType, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings); virtual void dismissCorrectionPanel(WebCore::ReasonForDismissingCorrectionPanel); diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp index fa3cdce..c3f72b0 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp @@ -44,7 +44,6 @@ #include "WebPage.h" #include "WebPageProxyMessages.h" #include "WebProcess.h" -#include "WebProcessProxyMessageKinds.h" #include "WebProcessProxyMessages.h" #include <JavaScriptCore/APICast.h> #include <JavaScriptCore/JSObject.h> @@ -223,14 +222,14 @@ void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned webPage->send(Messages::WebPageProxy::DidReceiveResponseForResource(m_frame->frameID(), identifier, response)); } -void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int lengthReceived) +void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int dataLength) { WebPage* webPage = m_frame->page(); if (!webPage) return; - webPage->injectedBundleResourceLoadClient().didReceiveContentLengthForResource(webPage, m_frame, identifier, lengthReceived); - webPage->send(Messages::WebPageProxy::DidReceiveContentLengthForResource(m_frame->frameID(), identifier, lengthReceived)); + webPage->injectedBundleResourceLoadClient().didReceiveContentLengthForResource(webPage, m_frame, identifier, dataLength); + webPage->send(Messages::WebPageProxy::DidReceiveContentLengthForResource(m_frame->frameID(), identifier, dataLength)); } void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier) @@ -403,7 +402,7 @@ void WebFrameLoaderClient::dispatchDidStartProvisionalLoad() webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), url, unreachableURL, InjectedBundleUserMessageEncoder(userData.get()))); } -void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title) +void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title) { WebPage* webPage = m_frame->page(); if (!webPage) @@ -412,10 +411,11 @@ void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title) RefPtr<APIObject> userData; // Notify the bundle client. - webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(webPage, title, m_frame, userData); + // FIXME: use direction of title. + webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(webPage, title.string(), m_frame, userData); // Notify the UIProcess. - webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), title, InjectedBundleUserMessageEncoder(userData.get()))); + webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), title.string(), InjectedBundleUserMessageEncoder(userData.get()))); } void WebFrameLoaderClient::dispatchDidChangeIcons() @@ -839,14 +839,15 @@ void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader) void WebFrameLoaderClient::updateGlobalHistory() { WebPage* webPage = m_frame->page(); - if (!webPage) + if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient()) return; DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader(); WebNavigationDataStore data; data.url = loader->urlForHistory().string(); - data.title = loader->title(); + // FIXME: use direction of title. + data.title = loader->title().string(); WebProcess::shared().connection()->send(Messages::WebContext::DidNavigateWithNavigationData(webPage->pageID(), data, m_frame->frameID()), 0); } @@ -854,7 +855,7 @@ void WebFrameLoaderClient::updateGlobalHistory() void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks() { WebPage* webPage = m_frame->page(); - if (!webPage) + if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient()) return; DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader(); @@ -1061,14 +1062,15 @@ PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const Reso return DocumentLoader::create(request, data); } -void WebFrameLoaderClient::setTitle(const String& title, const KURL& url) +void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url) { WebPage* webPage = m_frame->page(); - if (!webPage) + if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient()) return; + // FIXME: use direction of title. WebProcess::shared().connection()->send(Messages::WebContext::DidUpdateHistoryTitle(webPage->pageID(), - title, url.string(), m_frame->frameID()), 0); + title.string(), url.string(), m_frame->frameID()), 0); } String WebFrameLoaderClient::userAgent(const KURL&) diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h index 1948541..6ab6691 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.h @@ -67,7 +67,7 @@ private: virtual bool canAuthenticateAgainstProtectionSpace(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ProtectionSpace&); #endif virtual void dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse&); - virtual void dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long identifier, int lengthReceived); + virtual void dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long identifier, int dataLength); virtual void dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier); virtual void dispatchDidFailLoading(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceError&); virtual bool dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int length); @@ -84,7 +84,7 @@ private: virtual void dispatchWillClose(); virtual void dispatchDidReceiveIcon(); virtual void dispatchDidStartProvisionalLoad(); - virtual void dispatchDidReceiveTitle(const String& title); + virtual void dispatchDidReceiveTitle(const WebCore::StringWithDirection&); virtual void dispatchDidChangeIcons(); virtual void dispatchDidCommitLoad(); virtual void dispatchDidFailProvisionalLoad(const WebCore::ResourceError&); @@ -165,7 +165,7 @@ private: virtual void prepareForDataSourceReplacement(); virtual PassRefPtr<WebCore::DocumentLoader> createDocumentLoader(const WebCore::ResourceRequest&, const WebCore::SubstituteData&); - virtual void setTitle(const String& title, const WebCore::KURL&); + virtual void setTitle(const WebCore::StringWithDirection&, const WebCore::KURL&); virtual String userAgent(const WebCore::KURL&); diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.cpp index 7242d4f..940cb95 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.cpp +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.cpp @@ -81,7 +81,7 @@ Vector<WebPopupItem> WebPopupMenu::populateItems() for (size_t i = 0; i < size; ++i) { if (m_popupClient->itemIsSeparator(i)) - items.append(WebPopupItem(WebPopupItem::Seperator)); + items.append(WebPopupItem(WebPopupItem::Separator)); else { // FIXME: Add support for styling the font. // FIXME: Add support for styling the foreground and background colors. @@ -126,6 +126,13 @@ void WebPopupMenu::hide() void WebPopupMenu::updateFromElement() { +#if PLATFORM(WIN) + if (!m_page || !m_popupClient) + return; + + int selectedIndex = m_popupClient->selectedIndex(); + WebProcess::shared().connection()->send(Messages::WebPageProxy::SetPopupMenuSelectedIndex(selectedIndex), m_page->pageID()); +#endif } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.h b/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.h index 3083c94..1e6e09a 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.h +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebPopupMenu.h @@ -43,6 +43,8 @@ public: static PassRefPtr<WebPopupMenu> create(WebPage*, WebCore::PopupMenuClient*); ~WebPopupMenu(); + WebPage* page() { return m_page; } + void disconnectFromPage() { m_page = 0; } void didChangeSelectedIndex(int newIndex); void setTextForIndex(int newIndex); diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/WebSearchPopupMenu.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/WebSearchPopupMenu.cpp index b875f32..39a7f32 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/WebSearchPopupMenu.cpp +++ b/Source/WebKit2/WebProcess/WebCoreSupport/WebSearchPopupMenu.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -23,6 +23,11 @@ #include "config.h" #include "WebSearchPopupMenu.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <wtf/text/AtomicString.h> + using namespace WebCore; namespace WebKit { @@ -42,17 +47,33 @@ PopupMenu* WebSearchPopupMenu::popupMenu() return m_popup.get(); } -void WebSearchPopupMenu::saveRecentSearches(const AtomicString&, const Vector<String>&) +void WebSearchPopupMenu::saveRecentSearches(const AtomicString& name, const Vector<String>& searchItems) { + if (name.isEmpty()) + return; + + WebPage* page = m_popup->page(); + if (!page) + return; + + WebProcess::shared().connection()->send(Messages::WebPageProxy::SaveRecentSearches(name, searchItems), page->pageID()); } -void WebSearchPopupMenu::loadRecentSearches(const AtomicString&, Vector<String>&) +void WebSearchPopupMenu::loadRecentSearches(const AtomicString& name, Vector<String>& resultItems) { + if (name.isEmpty()) + return; + + WebPage* page = m_popup->page(); + if (!page) + return; + + WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::LoadRecentSearches(name), Messages::WebPageProxy::LoadRecentSearches::Reply(resultItems), page->pageID()); } bool WebSearchPopupMenu::enabled() { - return false; + return true; } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebEditorClientGtk.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebEditorClientGtk.cpp new file mode 100644 index 0000000..c05589b --- /dev/null +++ b/Source/WebKit2/WebProcess/WebCoreSupport/gtk/WebEditorClientGtk.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "WebEditorClient.h" + +#include "Frame.h" +#include "PlatformKeyboardEvent.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include "WebProcess.h" +#include <WebCore/KeyboardEvent.h> +#include <WebCore/NotImplemented.h> + +using namespace WebCore; + +namespace WebKit { + +void WebEditorClient::getEditorCommandsForKeyEvent(const KeyboardEvent* event, Vector<WTF::String>& pendingEditorCommands) +{ + ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent); + + // First try to interpret the command in the UI and get the commands. + WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::GetEditorCommandsForKeyEvent(), + Messages::WebPageProxy::GetEditorCommandsForKeyEvent::Reply(pendingEditorCommands), + m_page->pageID(), CoreIPC::Connection::NoTimeout); +} + +bool WebEditorClient::executePendingEditorCommands(Frame* frame, Vector<WTF::String> pendingEditorCommands, bool allowTextInsertion) +{ + Vector<Editor::Command> commands; + for (size_t i = 0; i < pendingEditorCommands.size(); i++) { + Editor::Command command = frame->editor()->command(pendingEditorCommands.at(i).utf8().data()); + if (command.isTextInsertion() && !allowTextInsertion) + return false; + + commands.append(command); + } + + for (size_t i = 0; i < commands.size(); i++) { + if (!commands.at(i).execute()) + return false; + } + + return true; +} + +void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event) +{ + Node* node = event->target()->toNode(); + ASSERT(node); + Frame* frame = node->document()->frame(); + ASSERT(frame); + + const PlatformKeyboardEvent* platformEvent = event->keyEvent(); + if (!platformEvent) + return; + + Vector<WTF::String> pendingEditorCommands; + getEditorCommandsForKeyEvent(event, pendingEditorCommands); + if (!pendingEditorCommands.isEmpty()) { + + // During RawKeyDown events if an editor command will insert text, defer + // the insertion until the keypress event. We want keydown to bubble up + // through the DOM first. + if (platformEvent->type() == PlatformKeyboardEvent::RawKeyDown) { + if (executePendingEditorCommands(frame, pendingEditorCommands, false)) + event->setDefaultHandled(); + + return; + } + + // Only allow text insertion commands if the current node is editable. + if (executePendingEditorCommands(frame, pendingEditorCommands, frame->editor()->canEdit())) { + event->setDefaultHandled(); + return; + } + } + + // Don't allow text insertion for nodes that cannot edit. + if (!frame->editor()->canEdit()) + return; + + // This is just a normal text insertion, so wait to execute the insertion + // until a keypress event happens. This will ensure that the insertion will not + // be reflected in the contents of the field until the keyup DOM event. + if (event->type() == eventNames().keypressEvent) { + + // FIXME: Add IM support + // https://bugs.webkit.org/show_bug.cgi?id=55946 + frame->editor()->insertText(platformEvent->text(), event); + event->setDefaultHandled(); + + } else { + // Don't insert null or control characters as they can result in unexpected behaviour + if (event->charCode() < ' ') + return; + + // Don't insert anything if a modifier is pressed + if (platformEvent->ctrlKey() || platformEvent->altKey()) + return; + + if (frame->editor()->insertText(platformEvent->text(), event)) + event->setDefaultHandled(); + } +} + +void WebEditorClient::handleInputMethodKeydown(KeyboardEvent*) +{ + notImplemented(); +} + +} diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebContextMenuClientMac.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebContextMenuClientMac.mm index 6aa83f8..84b7d50 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebContextMenuClientMac.mm +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebContextMenuClientMac.mm @@ -80,9 +80,7 @@ void WebContextMenuClient::searchWithSpotlight() if (selectedString.isEmpty()) return; - NSString *convertedSelectedString = selectedString; - - [[NSWorkspace sharedWorkspace] showSearchResultsForQueryString:convertedSelectedString]; + m_page->send(Messages::WebPageProxy::SearchWithSpotlight(selectedString)); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm index 75d92e2..b9806f4 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm @@ -152,7 +152,7 @@ void WebDragClient::declareAndWriteDragImage(NSPasteboard *pasteboard, DOMElemen RetainPtr<WKPasteboardFilePromiseOwner> filePromiseOwner(AdoptNS, [(WKPasteboardFilePromiseOwner *)[WKPasteboardFilePromiseOwner alloc] initWithSource:pasteboardOwner.get()]); m_page->setDragSource(filePromiseOwner.get()); - [pasteboard declareTypes:types.get() owner:pasteboardOwner.get()]; + [pasteboard declareTypes:types.get() owner:pasteboardOwner.leakRef()]; [pasteboard setPropertyList:[NSArray arrayWithObject:extension] forType:NSFilesPromisePboardType]; @@ -252,6 +252,7 @@ static CachedResourceClient* promisedDataClient() - (void)pasteboardChangedOwner:(NSPasteboard *)pasteboard { [self clearImage]; + CFRelease(self); // Balanced by the leakRef that WebDragClient::declareAndWriteDragImage does when making this pasteboard owner. } static bool matchesExtensionOrEquivalent(NSString *filename, NSString *extension) diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebEditorClientMac.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebEditorClientMac.mm index 7a95a72..17fd5fe 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebEditorClientMac.mm +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebEditorClientMac.mm @@ -46,9 +46,6 @@ #import <WebCore/Page.h> #import <WebKit/WebResource.h> #import <WebKit/WebNSURLExtras.h> -#if !defined(BUILDING_ON_SNOW_LEOPARD) -#import <AppKit/NSTextChecker.h> -#endif using namespace WebCore; @@ -64,13 +61,13 @@ namespace WebKit { void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event) { - if (m_page->interceptEditingKeyboardEvent(event, false)) + if (m_page->handleEditingKeyboardEvent(event, false)) event->setDefaultHandled(); } void WebEditorClient::handleInputMethodKeydown(KeyboardEvent* event) { - if (m_page->interceptEditingKeyboardEvent(event, true)) + if (m_page->handleEditingKeyboardEvent(event, true)) event->setDefaultHandled(); } @@ -176,8 +173,9 @@ void WebEditorClient::showSubstitutionsPanel(bool) bool WebEditorClient::substitutionsPanelIsShowing() { - notImplemented(); - return false; + bool isShowing; + m_page->sendSync(Messages::WebPageProxy::SubstitutionsPanelIsShowing(), Messages::WebPageProxy::SubstitutionsPanelIsShowing::Reply(isShowing)); + return isShowing; } void WebEditorClient::toggleSmartInsertDelete() @@ -240,7 +238,7 @@ void WebEditorClient::toggleAutomaticSpellingCorrection() notImplemented(); } -void WebEditorClient::checkTextOfParagraph(const UChar* text, int length, uint64_t checkingTypes, Vector<TextCheckingResult>& results) +void WebEditorClient::checkTextOfParagraph(const UChar* text, int length, WebCore::TextCheckingTypeMask checkingTypes, Vector<TextCheckingResult>& results) { // FIXME: It would be nice if we wouldn't have to copy the text here. m_page->sendSync(Messages::WebPageProxy::CheckTextOfParagraph(String(text, length), checkingTypes), Messages::WebPageProxy::CheckTextOfParagraph::Reply(results)); diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebErrorsMac.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebErrorsMac.mm index 70e7607..3ae02a9 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebErrorsMac.mm +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebErrorsMac.mm @@ -43,17 +43,17 @@ static NSString * const WebKitErrorPlugInNameKey = @"WebKitErrorPlug static NSString * const WebKitErrorPlugInPageURLStringKey = @"WebKitErrorPlugInPageURLStringKey"; // Policy errors -#define WebKitErrorDescriptionCannotShowMIMEType UI_STRING("Content with specified MIME type can’t be shown", "WebKitErrorCannotShowMIMEType description") -#define WebKitErrorDescriptionCannotShowURL UI_STRING("The URL can’t be shown", "WebKitErrorCannotShowURL description") -#define WebKitErrorDescriptionFrameLoadInterruptedByPolicyChange UI_STRING("Frame load interrupted", "WebKitErrorFrameLoadInterruptedByPolicyChange description") -#define WebKitErrorDescriptionCannotUseRestrictedPort UI_STRING("Not allowed to use restricted network port", "WebKitErrorCannotUseRestrictedPort description") +#define WebKitErrorDescriptionCannotShowMIMEType WEB_UI_STRING("Content with specified MIME type can’t be shown", "WebKitErrorCannotShowMIMEType description") +#define WebKitErrorDescriptionCannotShowURL WEB_UI_STRING("The URL can’t be shown", "WebKitErrorCannotShowURL description") +#define WebKitErrorDescriptionFrameLoadInterruptedByPolicyChange WEB_UI_STRING("Frame load interrupted", "WebKitErrorFrameLoadInterruptedByPolicyChange description") +#define WebKitErrorDescriptionCannotUseRestrictedPort WEB_UI_STRING("Not allowed to use restricted network port", "WebKitErrorCannotUseRestrictedPort description") // Plug-in and java errors -#define WebKitErrorDescriptionCannotFindPlugin UI_STRING("The plug-in can’t be found", "WebKitErrorCannotFindPlugin description") -#define WebKitErrorDescriptionCannotLoadPlugin UI_STRING("The plug-in can’t be loaded", "WebKitErrorCannotLoadPlugin description") -#define WebKitErrorDescriptionJavaUnavailable UI_STRING("Java is unavailable", "WebKitErrorJavaUnavailable description") -#define WebKitErrorDescriptionPlugInCancelledConnection UI_STRING("Plug-in cancelled", "WebKitErrorPlugInCancelledConnection description") -#define WebKitErrorDescriptionPlugInWillHandleLoad UI_STRING("Plug-in handled load", "WebKitErrorPlugInWillHandleLoad description") +#define WebKitErrorDescriptionCannotFindPlugin WEB_UI_STRING("The plug-in can’t be found", "WebKitErrorCannotFindPlugin description") +#define WebKitErrorDescriptionCannotLoadPlugin WEB_UI_STRING("The plug-in can’t be loaded", "WebKitErrorCannotLoadPlugin description") +#define WebKitErrorDescriptionJavaUnavailable WEB_UI_STRING("Java is unavailable", "WebKitErrorJavaUnavailable description") +#define WebKitErrorDescriptionPlugInCancelledConnection WEB_UI_STRING("Plug-in cancelled", "WebKitErrorPlugInCancelledConnection description") +#define WebKitErrorDescriptionPlugInWillHandleLoad WEB_UI_STRING("Plug-in handled load", "WebKitErrorPlugInWillHandleLoad description") static pthread_once_t registerErrorsControl = PTHREAD_ONCE_INIT; static void registerErrors(void); diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebPopupMenuMac.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebPopupMenuMac.mm index e36f438..b9bc48f 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebPopupMenuMac.mm +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebPopupMenuMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -46,6 +46,7 @@ void WebPopupMenu::setUpPlatformData(const IntRect&, PlatformPopupMenuData& data return; data.fontInfo.fontAttributeDictionary = fontDescriptorAttributes; + data.shouldPopOver = m_popupClient->shouldPopOver(); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.mm b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.mm index 06faa2f..a4fbc09 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.mm +++ b/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebSystemInterface.mm @@ -65,7 +65,6 @@ void InitWebCoreSystemInterface(void) INIT(GetWheelEventDeltas); INIT(HitTestMediaUIPart); INIT(InitializeMaximumHTTPConnectionCountPerHost); - INIT(IsLatchingWheelEvent); INIT(MeasureMediaUIPart); INIT(MediaControllerThemeAvailable); INIT(PopupMenu); @@ -85,7 +84,9 @@ void InitWebCoreSystemInterface(void) INIT(SetCONNECTProxyForStream); INIT(SetCookieStoragePrivateBrowsingEnabled); INIT(SetDragImage); + INIT(SetHTTPPipeliningMaximumPriority); INIT(SetHTTPPipeliningPriority); + INIT(SetHTTPPipeliningMinimumFastLanePriority); INIT(SetNSURLConnectionDefersCallbacks); INIT(SetNSURLRequestShouldContentSniff); INIT(SetPatternBaseCTM); @@ -135,9 +136,12 @@ void InitWebCoreSystemInterface(void) INIT(WillEndLiveResize); INIT(ContentAreaDidShow); INIT(ContentAreaDidHide); + INIT(DidBeginScrollGesture); + INIT(DidEndScrollGesture); INIT(ScrollbarPainterUsesOverlayScrollers); #else INIT(GetHyphenationLocationBeforeIndex); + INIT(GetNSEventMomentumPhase); #endif INIT(GetAXTextMarkerTypeID); diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.cpp index 5fcaa84..0248f70 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.cpp +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.cpp @@ -29,6 +29,7 @@ namespace WebCore { WebFrameNetworkingContext::WebFrameNetworkingContext(Frame* frame) : FrameNetworkingContext(frame) , m_originatingObject(0) + , m_mimeSniffingEnabled(true) { } @@ -47,4 +48,9 @@ QNetworkAccessManager* WebFrameNetworkingContext::networkAccessManager() const return WebKit::WebProcess::shared().networkAccessManager(); } +bool WebFrameNetworkingContext::mimeSniffingEnabled() const +{ + return m_mimeSniffingEnabled; +} + } diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.h b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.h index 9c87785..f2cf248 100644 --- a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.h +++ b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.h @@ -33,8 +33,10 @@ private: virtual QObject* originatingObject() const; virtual QNetworkAccessManager* networkAccessManager() const; + virtual bool mimeSniffingEnabled() const; QObject* m_originatingObject; + bool m_mimeSniffingEnabled; }; } diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp index 47acc7a..6272fb5 100644 --- a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp +++ b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp @@ -42,6 +42,7 @@ #endif using namespace WebCore; +using namespace std; namespace WebKit { @@ -159,7 +160,8 @@ void DrawingAreaImpl::forceRepaint() if (m_layerTreeHost) { m_layerTreeHost->forceRepaint(); - return; + if (!m_layerTreeHost->participatesInDisplay()) + return; } m_isWaitingForDidUpdate = false; @@ -190,6 +192,13 @@ void DrawingAreaImpl::setPageOverlayNeedsDisplay(const IntRect& rect) setNeedsDisplay(rect); } +void DrawingAreaImpl::setLayerHostNeedsDisplay() +{ + ASSERT(m_layerTreeHost); + ASSERT(m_layerTreeHost->participatesInDisplay()); + scheduleDisplay(); +} + void DrawingAreaImpl::layerHostDidFlushLayers() { ASSERT(m_layerTreeHost); @@ -201,8 +210,12 @@ void DrawingAreaImpl::layerHostDidFlushLayers() return; } - if (!m_layerTreeHost) + if (!m_layerTreeHost || m_layerTreeHost->participatesInDisplay()) { + // When the layer tree host participates in display, we never tell the UI process about + // accelerated compositing. From the UI process's point of view, we're still just sending + // it a series of bitmaps in Update messages. return; + } #if USE(ACCELERATED_COMPOSITING) m_webPage->send(Messages::DrawingAreaProxy::EnterAcceleratedCompositingMode(m_backingStoreStateID, m_layerTreeHost->layerTreeContext())); @@ -301,13 +314,13 @@ void DrawingAreaImpl::sendDidUpdateBackingStoreState() UpdateInfo updateInfo; - if (!m_isPaintingSuspended && !m_layerTreeHost) + if (!m_isPaintingSuspended && (!m_layerTreeHost || m_layerTreeHost->participatesInDisplay())) display(updateInfo); #if USE(ACCELERATED_COMPOSITING) LayerTreeContext layerTreeContext; - if (m_isPaintingSuspended || m_layerTreeHost) { + if (m_isPaintingSuspended || (m_layerTreeHost && !m_layerTreeHost->participatesInDisplay())) { updateInfo.viewSize = m_webPage->size(); if (m_layerTreeHost) { @@ -318,6 +331,7 @@ void DrawingAreaImpl::sendDidUpdateBackingStoreState() // message back to the UI process, but the updated layer tree context // will be sent back in the DidUpdateBackingStoreState message. m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(false); + m_layerTreeHost->forceRepaint(); } } @@ -329,7 +343,7 @@ void DrawingAreaImpl::didUpdate() { // We might get didUpdate messages from the UI process even after we've // entered accelerated compositing mode. Ignore them. - if (m_layerTreeHost) + if (m_layerTreeHost && !m_layerTreeHost->participatesInDisplay()) return; m_isWaitingForDidUpdate = false; @@ -342,14 +356,24 @@ void DrawingAreaImpl::suspendPainting() { ASSERT(!m_isPaintingSuspended); + if (m_layerTreeHost) + m_layerTreeHost->pauseRendering(); + m_isPaintingSuspended = true; m_displayTimer.stop(); } void DrawingAreaImpl::resumePainting() { - ASSERT(m_isPaintingSuspended); - + if (!m_isPaintingSuspended) { + // FIXME: We can get a call to resumePainting when painting is not suspended. + // This happens when sending a synchronous message to create a new page. See <rdar://problem/8976531>. + return; + } + + if (m_layerTreeHost) + m_layerTreeHost->resumeRendering(); + m_isPaintingSuspended = false; // FIXME: We shouldn't always repaint everything here. @@ -372,8 +396,11 @@ void DrawingAreaImpl::enterAcceleratedCompositingMode(GraphicsLayer* graphicsLay m_dirtyRegion = Region(); m_scrollRect = IntRect(); m_scrollOffset = IntSize(); - m_displayTimer.stop(); - m_isWaitingForDidUpdate = false; + + if (!m_layerTreeHost->participatesInDisplay()) { + m_displayTimer.stop(); + m_isWaitingForDidUpdate = false; + } } void DrawingAreaImpl::exitAcceleratedCompositingMode() @@ -385,6 +412,8 @@ void DrawingAreaImpl::exitAcceleratedCompositingMode() ASSERT(m_layerTreeHost); + bool wasParticipatingInDisplay = m_layerTreeHost->participatesInDisplay(); + m_layerTreeHost->invalidate(); m_layerTreeHost = nullptr; m_dirtyRegion = m_webPage->bounds(); @@ -404,9 +433,16 @@ void DrawingAreaImpl::exitAcceleratedCompositingMode() display(updateInfo); #if USE(ACCELERATED_COMPOSITING) - // Send along a complete update of the page so we can paint the contents right after we exit the - // accelerated compositing mode, eliminiating flicker. - m_webPage->send(Messages::DrawingAreaProxy::ExitAcceleratedCompositingMode(m_backingStoreStateID, updateInfo)); + if (wasParticipatingInDisplay) { + // When the layer tree host participates in display, we never tell the UI process about + // accelerated compositing. From the UI process's point of view, we're still just sending + // it a series of bitmaps in Update messages. + m_webPage->send(Messages::DrawingAreaProxy::Update(m_backingStoreStateID, updateInfo)); + } else { + // Send along a complete update of the page so we can paint the contents right after we exit the + // accelerated compositing mode, eliminiating flicker. + m_webPage->send(Messages::DrawingAreaProxy::ExitAcceleratedCompositingMode(m_backingStoreStateID, updateInfo)); + } #endif } @@ -420,14 +456,19 @@ void DrawingAreaImpl::exitAcceleratedCompositingModeSoon() void DrawingAreaImpl::scheduleDisplay() { + ASSERT(!m_layerTreeHost || m_layerTreeHost->participatesInDisplay()); + if (m_isWaitingForDidUpdate) return; if (m_isPaintingSuspended) return; - if (m_dirtyRegion.isEmpty()) - return; + if (m_layerTreeHost) { + if (!m_layerTreeHost->needsDisplay()) + return; + } else if (m_dirtyRegion.isEmpty()) + return; if (m_displayTimer.isActive()) return; @@ -440,7 +481,8 @@ void DrawingAreaImpl::displayTimerFired() static const double minimumFrameInterval = 1.0 / 60.0; double timeSinceLastDisplay = currentTime() - m_lastDisplayTime; - double timeUntilNextDisplay = minimumFrameInterval - timeSinceLastDisplay; + double timeUntilLayerTreeHostNeedsDisplay = m_layerTreeHost && m_layerTreeHost->participatesInDisplay() ? m_layerTreeHost->timeUntilNextDisplay() : 0; + double timeUntilNextDisplay = max(minimumFrameInterval - timeSinceLastDisplay, timeUntilLayerTreeHostNeedsDisplay); if (timeUntilNextDisplay > 0) { m_displayTimer.startOneShot(timeUntilNextDisplay); @@ -452,14 +494,17 @@ void DrawingAreaImpl::displayTimerFired() void DrawingAreaImpl::display() { - ASSERT(!m_layerTreeHost); + ASSERT(!m_layerTreeHost || m_layerTreeHost->participatesInDisplay()); ASSERT(!m_isWaitingForDidUpdate); ASSERT(!m_inUpdateBackingStoreState); if (m_isPaintingSuspended) return; - if (m_dirtyRegion.isEmpty()) + if (m_layerTreeHost) { + if (!m_layerTreeHost->needsDisplay()) + return; + } else if (m_dirtyRegion.isEmpty()) return; if (m_shouldSendDidUpdateBackingStoreState) { @@ -470,7 +515,7 @@ void DrawingAreaImpl::display() UpdateInfo updateInfo; display(updateInfo); - if (m_layerTreeHost) { + if (m_layerTreeHost && !m_layerTreeHost->participatesInDisplay()) { // The call to update caused layout which turned on accelerated compositing. // Don't send an Update message in this case. return; @@ -504,7 +549,7 @@ static bool shouldPaintBoundsRect(const IntRect& bounds, const Vector<IntRect>& void DrawingAreaImpl::display(UpdateInfo& updateInfo) { ASSERT(!m_isPaintingSuspended); - ASSERT(!m_layerTreeHost); + ASSERT(!m_layerTreeHost || m_layerTreeHost->participatesInDisplay()); ASSERT(!m_webPage->size().isEmpty()); // FIXME: It would be better if we could avoid painting altogether when there is a custom representation. @@ -516,44 +561,49 @@ void DrawingAreaImpl::display(UpdateInfo& updateInfo) m_webPage->layoutIfNeeded(); - // The layout may have put the page into accelerated compositing mode, in which case the - // LayerTreeHost is now in charge of displaying. - if (m_layerTreeHost) + // The layout may have put the page into accelerated compositing mode. If the LayerTreeHost is + // in charge of displaying, we have nothing more to do. + if (m_layerTreeHost && !m_layerTreeHost->participatesInDisplay()) return; - IntRect bounds = m_dirtyRegion.bounds(); - ASSERT(m_webPage->bounds().contains(bounds)); + updateInfo.viewSize = m_webPage->size(); + + if (m_layerTreeHost) + m_layerTreeHost->display(updateInfo); + else { + IntRect bounds = m_dirtyRegion.bounds(); + ASSERT(m_webPage->bounds().contains(bounds)); - RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(bounds.size(), ShareableBitmap::SupportsAlpha); - if (!bitmap->createHandle(updateInfo.bitmapHandle)) - return; + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(bounds.size(), ShareableBitmap::SupportsAlpha); + if (!bitmap->createHandle(updateInfo.bitmapHandle)) + return; - Vector<IntRect> rects = m_dirtyRegion.rects(); + Vector<IntRect> rects = m_dirtyRegion.rects(); - if (shouldPaintBoundsRect(bounds, rects)) { - rects.clear(); - rects.append(bounds); - } + if (shouldPaintBoundsRect(bounds, rects)) { + rects.clear(); + rects.append(bounds); + } - updateInfo.scrollRect = m_scrollRect; - updateInfo.scrollOffset = m_scrollOffset; + updateInfo.scrollRect = m_scrollRect; + updateInfo.scrollOffset = m_scrollOffset; - m_dirtyRegion = Region(); - m_scrollRect = IntRect(); - m_scrollOffset = IntSize(); + m_dirtyRegion = Region(); + m_scrollRect = IntRect(); + m_scrollOffset = IntSize(); - OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext(); - - updateInfo.viewSize = m_webPage->size(); - updateInfo.updateRectBounds = bounds; + OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext(); + + updateInfo.updateRectBounds = bounds; - graphicsContext->translate(-bounds.x(), -bounds.y()); + graphicsContext->translate(-bounds.x(), -bounds.y()); - for (size_t i = 0; i < rects.size(); ++i) { - m_webPage->drawRect(*graphicsContext, rects[i]); - if (m_webPage->hasPageOverlay()) - m_webPage->drawPageOverlay(*graphicsContext, rects[i]); - updateInfo.updateRects.append(rects[i]); + for (size_t i = 0; i < rects.size(); ++i) { + m_webPage->drawRect(*graphicsContext, rects[i]); + if (m_webPage->hasPageOverlay()) + m_webPage->drawPageOverlay(*graphicsContext, rects[i]); + updateInfo.updateRects.append(rects[i]); + } } // Layout can trigger more calls to setNeedsDisplay and we don't want to process them diff --git a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h index 9e93869..471ba56 100644 --- a/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h +++ b/Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h @@ -40,6 +40,7 @@ public: static PassOwnPtr<DrawingAreaImpl> create(WebPage*, const WebPageCreationParameters&); virtual ~DrawingAreaImpl(); + void setLayerHostNeedsDisplay(); void layerHostDidFlushLayers(); private: diff --git a/Source/WebKit2/WebProcess/WebPage/FindController.cpp b/Source/WebKit2/WebProcess/WebPage/FindController.cpp index 3e7b268..49f5786 100644 --- a/Source/WebKit2/WebProcess/WebPage/FindController.cpp +++ b/Source/WebKit2/WebProcess/WebPage/FindController.cpp @@ -38,6 +38,7 @@ #include <WebCore/GraphicsContext.h> #include <WebCore/Page.h> +using namespace std; using namespace WebCore; namespace WebKit { @@ -64,9 +65,16 @@ FindController::~FindController() void FindController::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount) { - unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount); + if (maxMatchCount == numeric_limits<unsigned>::max()) + --maxMatchCount; + + unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount + 1); m_webPage->corePage()->unmarkAllTextMatches(); + // Check if we have more matches than allowed. + if (matchCount > maxMatchCount) + matchCount = static_cast<unsigned>(kWKMoreThanMaximumMatchCount); + m_webPage->send(Messages::WebPageProxy::DidCountStringMatches(string, matchCount)); } @@ -102,6 +110,9 @@ void FindController::findString(const String& string, FindOptions options, unsig shouldShowOverlay = options & FindOptionsShowOverlay; if (shouldShowOverlay) { + if (maxMatchCount == numeric_limits<unsigned>::max()) + --maxMatchCount; + unsigned matchCount = m_webPage->corePage()->markAllMatchesForText(string, core(options), false, maxMatchCount + 1); // Check if we have more matches than allowed. @@ -122,7 +133,7 @@ void FindController::findString(const String& string, FindOptions options, unsig if (!shouldShowOverlay) { if (m_findPageOverlay) { // Get rid of the overlay. - m_webPage->uninstallPageOverlay(m_findPageOverlay); + m_webPage->uninstallPageOverlay(m_findPageOverlay, false); } ASSERT(!m_findPageOverlay); @@ -142,7 +153,7 @@ void FindController::findString(const String& string, FindOptions options, unsig void FindController::hideFindUI() { if (m_findPageOverlay) - m_webPage->uninstallPageOverlay(m_findPageOverlay); + m_webPage->uninstallPageOverlay(m_findPageOverlay, true); hideFindIndicator(); } @@ -259,27 +270,39 @@ static const float shadowOffsetY = 1.0; static const float shadowBlurRadius = 2.0; static const float whiteFrameThickness = 1.0; -static const int overlayBackgroundRed = 25; -static const int overlayBackgroundGreen = 25; -static const int overlayBackgroundBlue = 25; -static const int overlayBackgroundAlpha = 63; +static const float overlayBackgroundRed = 0.1; +static const float overlayBackgroundGreen = 0.1; +static const float overlayBackgroundBlue = 0.1; +static const float overlayBackgroundAlpha = 0.25; + +static Color overlayBackgroundColor(float fractionFadedIn) +{ + return Color(overlayBackgroundRed, overlayBackgroundGreen, overlayBackgroundBlue, overlayBackgroundAlpha * fractionFadedIn); +} -static Color overlayBackgroundColor() +static Color holeShadowColor(float fractionFadedIn) { - return Color(overlayBackgroundRed, overlayBackgroundGreen, overlayBackgroundBlue, overlayBackgroundAlpha); + return Color(0.0f, 0.0f, 0.0f, fractionFadedIn); } -void FindController::drawRect(PageOverlay*, GraphicsContext& graphicsContext, const IntRect& dirtyRect) +static Color holeFillColor(float fractionFadedIn) { + return Color(1.0f, 1.0f, 1.0f, fractionFadedIn); +} + +void FindController::drawRect(PageOverlay* pageOverlay, GraphicsContext& graphicsContext, const IntRect& dirtyRect) +{ + float fractionFadedIn = pageOverlay->fractionFadedIn(); + Vector<IntRect> rects = rectsForTextMatches(); // Draw the background. - graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(), ColorSpaceSRGB); + graphicsContext.fillRect(dirtyRect, overlayBackgroundColor(fractionFadedIn), ColorSpaceSRGB); graphicsContext.save(); - graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, Color::black, ColorSpaceSRGB); + graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, holeShadowColor(fractionFadedIn), ColorSpaceSRGB); - graphicsContext.setFillColor(Color::white, ColorSpaceSRGB); + graphicsContext.setFillColor(holeFillColor(fractionFadedIn), ColorSpaceSRGB); // Draw white frames around the holes. for (size_t i = 0; i < rects.size(); ++i) { diff --git a/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp index 737e195..24cbcc6 100644 --- a/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp +++ b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.cpp @@ -26,8 +26,12 @@ #include "config.h" #include "LayerTreeHost.h" +#if USE(CA) #if PLATFORM(MAC) -#include "LayerTreeHostCA.h" +#include "LayerTreeHostCAMac.h" +#elif PLATFORM(WIN) +#include "LayerTreeHostCAWin.h" +#endif #endif #if !PLATFORM(MAC) && !PLATFORM(WIN) @@ -41,10 +45,12 @@ namespace WebKit { PassRefPtr<LayerTreeHost> LayerTreeHost::create(WebPage* webPage) { #if PLATFORM(MAC) - return LayerTreeHostCA::create(webPage); -#endif - + return LayerTreeHostCAMac::create(webPage); +#elif PLATFORM(WIN) && HAVE(WKQCA) + return LayerTreeHostCAWin::create(webPage); +#else return 0; +#endif } LayerTreeHost::LayerTreeHost(WebPage* webPage) diff --git a/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h index bbb94e8..004bdb7 100644 --- a/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h +++ b/Source/WebKit2/WebProcess/WebPage/LayerTreeHost.h @@ -38,6 +38,7 @@ namespace WebCore { namespace WebKit { class LayerTreeContext; +class UpdateInfo; class WebPage; class LayerTreeHost : public RefCounted<LayerTreeHost> { @@ -45,6 +46,8 @@ public: static PassRefPtr<LayerTreeHost> create(WebPage*); virtual ~LayerTreeHost(); + static bool supportsAcceleratedCompositing(); + virtual const LayerTreeContext& layerTreeContext() = 0; virtual void scheduleLayerFlush() = 0; virtual void setShouldNotifyAfterNextScheduledLayerFlush(bool) = 0; @@ -60,12 +63,29 @@ public: virtual void didUninstallPageOverlay() = 0; virtual void setPageOverlayNeedsDisplay(const WebCore::IntRect&) = 0; + virtual void pauseRendering() { } + virtual void resumeRendering() { } + + // If a derived class overrides this function to return true, the derived class must also + // override the functions beneath it. + virtual bool participatesInDisplay() { return false; } + virtual bool needsDisplay() { ASSERT_NOT_REACHED(); return false; } + virtual double timeUntilNextDisplay() { ASSERT_NOT_REACHED(); return 0; } + virtual void display(UpdateInfo&) { ASSERT_NOT_REACHED(); } + protected: explicit LayerTreeHost(WebPage*); WebPage* m_webPage; }; +#if !PLATFORM(WIN) +inline bool LayerTreeHost::supportsAcceleratedCompositing() +{ + return true; +} +#endif + } // namespace WebKit #endif // LayerTreeHost_h diff --git a/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp b/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp index 67c1165..d4b1b41 100644 --- a/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp +++ b/Source/WebKit2/WebProcess/WebPage/PageOverlay.cpp @@ -27,6 +27,7 @@ #include "PageOverlay.h" #include "WebPage.h" +#include "WebProcess.h" #include <WebCore/Frame.h> #include <WebCore/FrameView.h> #include <WebCore/GraphicsContext.h> @@ -37,6 +38,9 @@ using namespace WebCore; namespace WebKit { +static const double fadeAnimationDuration = 0.2; +static const double fadeAnimationFrameRate = 30; + PassRefPtr<PageOverlay> PageOverlay::create(Client* client) { return adoptRef(new PageOverlay(client)); @@ -45,6 +49,11 @@ PassRefPtr<PageOverlay> PageOverlay::create(Client* client) PageOverlay::PageOverlay(Client* client) : m_client(client) , m_webPage(0) + , m_fadeAnimationTimer(WebProcess::shared().runLoop(), this, &PageOverlay::fadeAnimationTimerFired) + , m_fadeAnimationStartTime(0.0) + , m_fadeAnimationDuration(fadeAnimationDuration) + , m_fadeAnimationType(NoAnimation) + , m_fractionFadedIn(1.0) { } @@ -54,7 +63,7 @@ PageOverlay::~PageOverlay() IntRect PageOverlay::bounds() const { - FrameView* frameView = webPage()->corePage()->mainFrame()->view(); + FrameView* frameView = m_webPage->corePage()->mainFrame()->view(); int width = frameView->width(); int height = frameView->height(); @@ -73,6 +82,8 @@ void PageOverlay::setPage(WebPage* webPage) m_client->willMoveToWebPage(this, webPage); m_webPage = webPage; m_client->didMoveToWebPage(this, webPage); + + m_fadeAnimationTimer.stop(); } void PageOverlay::setNeedsDisplay(const IntRect& dirtyRect) @@ -112,4 +123,54 @@ bool PageOverlay::mouseEvent(const WebMouseEvent& mouseEvent) return m_client->mouseEvent(this, mouseEvent); } +void PageOverlay::startFadeInAnimation() +{ + m_fractionFadedIn = 0.0; + m_fadeAnimationType = FadeInAnimation; + + startFadeAnimation(); +} + +void PageOverlay::startFadeOutAnimation() +{ + m_fractionFadedIn = 1.0; + m_fadeAnimationType = FadeOutAnimation; + + startFadeAnimation(); +} + +void PageOverlay::startFadeAnimation() +{ + m_fadeAnimationStartTime = currentTime(); + + // Start the timer + m_fadeAnimationTimer.startRepeating(1 / fadeAnimationFrameRate); +} + +void PageOverlay::fadeAnimationTimerFired() +{ + float animationProgress = (currentTime() - m_fadeAnimationStartTime) / m_fadeAnimationDuration; + + if (animationProgress >= 1.0) + animationProgress = 1.0; + + double sine = sin(piOverTwoFloat * animationProgress); + float fadeAnimationValue = sine * sine; + + m_fractionFadedIn = (m_fadeAnimationType == FadeInAnimation) ? fadeAnimationValue : 1 - fadeAnimationValue; + setNeedsDisplay(); + + if (animationProgress == 1.0) { + m_fadeAnimationTimer.stop(); + + bool wasFadingOut = m_fadeAnimationType == FadeOutAnimation; + m_fadeAnimationType = NoAnimation; + + if (wasFadingOut) { + // If this was a fade out, go ahead and uninstall the page overlay. + m_webPage->uninstallPageOverlay(this, false); + } + } +} + } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/PageOverlay.h b/Source/WebKit2/WebProcess/WebPage/PageOverlay.h index 6f1f70f..1f61ceb 100644 --- a/Source/WebKit2/WebProcess/WebPage/PageOverlay.h +++ b/Source/WebKit2/WebProcess/WebPage/PageOverlay.h @@ -27,6 +27,7 @@ #define PageOverlay_h #include "APIObject.h" +#include "RunLoop.h" #include <wtf/PassRefPtr.h> namespace WebCore { @@ -65,20 +66,38 @@ public: void drawRect(WebCore::GraphicsContext&, const WebCore::IntRect& dirtyRect); bool mouseEvent(const WebMouseEvent&); + void startFadeInAnimation(); + void startFadeOutAnimation(); + + float fractionFadedIn() const { return m_fractionFadedIn; } + protected: explicit PageOverlay(Client*); - WebPage* webPage() const { return m_webPage; } - private: // APIObject virtual Type type() const { return APIType; } WebCore::IntRect bounds() const; - Client* m_client; + void startFadeAnimation(); + void fadeAnimationTimerFired(); + Client* m_client; WebPage* m_webPage; + + RunLoop::Timer<PageOverlay> m_fadeAnimationTimer; + double m_fadeAnimationStartTime; + double m_fadeAnimationDuration; + + enum FadeAnimationType { + NoAnimation, + FadeInAnimation, + FadeOutAnimation, + }; + + FadeAnimationType m_fadeAnimationType; + float m_fractionFadedIn; }; } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp index 35058de..cbed180 100644 --- a/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp +++ b/Source/WebKit2/WebProcess/WebPage/WebContextMenu.cpp @@ -82,7 +82,8 @@ void WebContextMenu::show() contextMenuState.absoluteImageURLString = controller->hitTestResult().absoluteImageURL().string(); contextMenuState.absoluteLinkURLString = controller->hitTestResult().absoluteLinkURL().string(); - // Notify the UIProcess. + // Mark the WebPage has having a shown context menu then notify the UIProcess. + m_page->contextMenuShowing(); m_page->send(Messages::WebPageProxy::ShowContextMenu(view->contentsToWindow(controller->hitTestResult().point()), contextMenuState, proposedMenu, InjectedBundleUserMessageEncoder(userData.get()))); } diff --git a/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp b/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp index 574634f..0d550c9 100644 --- a/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp +++ b/Source/WebKit2/WebProcess/WebPage/WebFrame.cpp @@ -512,6 +512,30 @@ IntSize WebFrame::scrollOffset() const return view->scrollOffset(); } +bool WebFrame::hasHorizontalScrollbar() const +{ + if (!m_coreFrame) + return false; + + FrameView* view = m_coreFrame->view(); + if (!view) + return false; + + return view->horizontalScrollbar(); +} + +bool WebFrame::hasVerticalScrollbar() const +{ + if (!m_coreFrame) + return false; + + FrameView* view = m_coreFrame->view(); + if (!view) + return false; + + return view->verticalScrollbar(); +} + bool WebFrame::getDocumentBackgroundColor(double* red, double* green, double* blue, double* alpha) { if (!m_coreFrame) @@ -550,6 +574,9 @@ WebFrame* WebFrame::frameForContext(JSContextRef context) JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleNodeHandle* nodeHandle, InjectedBundleScriptWorld* world) { + if (!m_coreFrame) + return 0; + JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(world->coreWorld()); ExecState* exec = globalObject->globalExec(); @@ -559,6 +586,9 @@ JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleNodeHandle* nodeHandle, Inj JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleRangeHandle* rangeHandle, InjectedBundleScriptWorld* world) { + if (!m_coreFrame) + return 0; + JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(world->coreWorld()); ExecState* exec = globalObject->globalExec(); diff --git a/Source/WebKit2/WebProcess/WebPage/WebFrame.h b/Source/WebKit2/WebProcess/WebPage/WebFrame.h index 3c63cf3..b6e1e13 100644 --- a/Source/WebKit2/WebProcess/WebPage/WebFrame.h +++ b/Source/WebKit2/WebProcess/WebPage/WebFrame.h @@ -93,6 +93,8 @@ public: WebCore::IntRect visibleContentBounds() const; WebCore::IntRect visibleContentBoundsExcludingScrollbars() const; WebCore::IntSize scrollOffset() const; + bool hasHorizontalScrollbar() const; + bool hasVerticalScrollbar() const; bool getDocumentBackgroundColor(double* red, double* green, double* blue, double* alpha); static WebFrame* frameForContext(JSContextRef); diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp index d5f3724..7707965 100644 --- a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp @@ -32,6 +32,7 @@ #include "DrawingArea.h" #include "InjectedBundle.h" #include "InjectedBundleBackForwardList.h" +#include "LayerTreeHost.h" #include "MessageID.h" #include "NetscapePlugin.h" #include "PageOverlay.h" @@ -66,8 +67,8 @@ #include "WebPopupMenu.h" #include "WebPreferencesStore.h" #include "WebProcess.h" -#include "WebProcessProxyMessageKinds.h" #include "WebProcessProxyMessages.h" +#include <JavaScriptCore/APICast.h> #include <WebCore/AbstractDatabase.h> #include <WebCore/ArchiveResource.h> #include <WebCore/Chrome.h> @@ -77,18 +78,23 @@ #include <WebCore/DocumentMarkerController.h> #include <WebCore/DragController.h> #include <WebCore/DragData.h> +#include <WebCore/EditingBehavior.h> #include <WebCore/EventHandler.h> #include <WebCore/FocusController.h> +#include <WebCore/FormState.h> #include <WebCore/Frame.h> +#include <WebCore/FrameLoadRequest.h> #include <WebCore/FrameLoaderTypes.h> #include <WebCore/FrameView.h> +#include <WebCore/HTMLFormElement.h> #include <WebCore/HistoryItem.h> #include <WebCore/KeyboardEvent.h> +#include <WebCore/MouseEvent.h> #include <WebCore/Page.h> #include <WebCore/PlatformKeyboardEvent.h> #include <WebCore/PrintContext.h> -#include <WebCore/RenderTreeAsText.h> #include <WebCore/RenderLayer.h> +#include <WebCore/RenderTreeAsText.h> #include <WebCore/RenderView.h> #include <WebCore/ReplaceSelectionCommand.h> #include <WebCore/ResourceRequest.h> @@ -110,9 +116,10 @@ #endif #if ENABLE(PLUGIN_PROCESS) -// FIXME: This is currently Mac-specific! +#if PLATFORM(MAC) #include "MachPort.h" #endif +#endif #if PLATFORM(QT) #include "HitTestResult.h" @@ -151,6 +158,7 @@ WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters) #if PLATFORM(MAC) , m_windowIsVisible(false) , m_isSmartInsertDeleteEnabled(parameters.isSmartInsertDeleteEnabled) + , m_keyboardEventBeingInterpreted(0) #elif PLATFORM(WIN) , m_nativeWindow(parameters.nativeWindow) #endif @@ -163,6 +171,10 @@ WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters) , m_userSpaceScaleFactor(parameters.userSpaceScaleFactor) , m_cachedMainFrameIsPinnedToLeftSide(false) , m_cachedMainFrameIsPinnedToRightSide(false) + , m_isShowingContextMenu(false) +#if PLATFORM(WIN) + , m_gestureReachedScrollingLimit(false) +#endif { ASSERT(m_pageID); @@ -282,6 +294,13 @@ void WebPage::initializeInjectedBundleUIClient(WKBundlePageUIClient* client) m_uiClient.initialize(client); } +#if ENABLE(FULLSCREEN_API) +void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClient* client) +{ + m_fullScreenClient.initialize(client); +} +#endif + PassRefPtr<Plugin> WebPage::createPlugin(const Plugin::Parameters& parameters) { String pluginPath; @@ -302,6 +321,22 @@ PassRefPtr<Plugin> WebPage::createPlugin(const Plugin::Parameters& parameters) #endif } +EditorState WebPage::editorState() const +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + ASSERT(frame); + + EditorState result; + result.selectionIsNone = frame->selection()->isNone(); + result.selectionIsRange = frame->selection()->isRange(); + result.isContentEditable = frame->selection()->isContentEditable(); + result.isContentRichlyEditable = frame->selection()->isContentRichlyEditable(); + result.isInPasswordField = frame->selection()->isInPasswordField(); + result.hasComposition = frame->editor()->hasComposition(); + + return result; +} + String WebPage::renderTreeExternalRepresentation() const { return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal); @@ -440,6 +475,20 @@ void WebPage::loadPlainTextString(const String& string) loadData(sharedBuffer, "text/plain", "utf-16", blankURL(), KURL()); } +void WebPage::linkClicked(const String& url, const WebMouseEvent& event) +{ + Frame* frame = m_page->mainFrame(); + if (!frame) + return; + + RefPtr<Event> coreEvent; + if (event.type() != WebEvent::NoType) + coreEvent = MouseEvent::create(eventNames().clickEvent, frame->document()->defaultView(), platform(event), 0, 0); + + frame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(url)), + false, false, coreEvent.get(), 0, SendReferrer); +} + void WebPage::stopLoadingFrame(uint64_t frameID) { WebFrame* frame = WebProcess::shared().webFrame(frameID); @@ -697,22 +746,38 @@ void WebPage::setFixedLayoutSize(const IntSize& size) void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay) { - if (m_pageOverlay) - pageOverlay->setPage(0); + bool shouldFadeIn = true; + + if (m_pageOverlay) { + m_pageOverlay->setPage(0); + + if (pageOverlay) { + // We're installing a page overlay when a page overlay is already active. + // In this case we don't want to fade in the new overlay. + shouldFadeIn = false; + } + } m_pageOverlay = pageOverlay; m_pageOverlay->setPage(this); - m_drawingArea->didInstallPageOverlay(); + if (shouldFadeIn) + m_pageOverlay->startFadeInAnimation(); + m_drawingArea->didInstallPageOverlay(); m_pageOverlay->setNeedsDisplay(); } -void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay) +void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay, bool fadeOut) { if (pageOverlay != m_pageOverlay) return; + if (fadeOut) { + m_pageOverlay->startFadeOutAnimation(); + return; + } + m_pageOverlay->setPage(0); m_pageOverlay = nullptr; @@ -804,35 +869,6 @@ WebContextMenu* WebPage::contextMenu() return m_contextMenu.get(); } -void WebPage::getLocationAndLengthFromRange(Range* range, uint64_t& location, uint64_t& length) -{ - location = notFound; - length = 0; - - if (!range || !range->startContainer()) - return; - - Element* selectionRoot = range->ownerDocument()->frame()->selection()->rootEditableElement(); - Element* scope = selectionRoot ? selectionRoot : range->ownerDocument()->documentElement(); - - // Mouse events may cause TSM to attempt to create an NSRange for a portion of the view - // that is not inside the current editable region. These checks ensure we don't produce - // potentially invalid data when responding to such requests. - if (range->startContainer() != scope && !range->startContainer()->isDescendantOf(scope)) - return; - if (range->endContainer() != scope && !range->endContainer()->isDescendantOf(scope)) - return; - - RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset()); - ASSERT(testRange->startContainer() == scope); - location = TextIterator::rangeLength(testRange.get()); - - ExceptionCode ec; - testRange->setEnd(range->endContainer(), range->endOffset(), ec); - ASSERT(testRange->startContainer() == scope); - length = TextIterator::rangeLength(testRange.get()) - location; -} - // Events static const WebEvent* g_currentEvent = 0; @@ -913,6 +949,12 @@ static bool handleMouseEvent(const WebMouseEvent& mouseEvent, Page* page) void WebPage::mouseEvent(const WebMouseEvent& mouseEvent) { + // Don't try to handle any pending mouse events if a context menu is showing. + if (m_isShowingContextMenu) { + send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false)); + return; + } + bool handled = false; if (m_pageOverlay) { @@ -962,6 +1004,7 @@ void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent) CurrentEvent currentEvent(keyboardEvent); bool handled = handleKeyEvent(keyboardEvent, m_page.get()); + // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler). if (!handled) handled = performDefaultBehaviorForKeyEvent(keyboardEvent); @@ -1142,8 +1185,9 @@ void WebPage::viewWillEndLiveResize() void WebPage::setFocused(bool isFocused) { - if (!isFocused) + if (!isFocused && m_page->focusController()->focusedOrMainFrame()->editor()->behavior().shouldClearSelectionWhenLosingWebPageFocus()) m_page->focusController()->focusedOrMainFrame()->selection()->clear(); + m_page->focusController()->setFocused(isFocused); } @@ -1240,7 +1284,8 @@ void WebPage::runJavaScriptInMainFrame(const String& script, uint64_t callbackID JSLock lock(SilenceAssertionsOnly); if (JSValue resultValue = m_mainFrame->coreFrame()->script()->executeScript(script, true).jsValue()) { - if ((serializedResultValue = SerializedScriptValue::create(m_mainFrame->coreFrame()->script()->globalObject(mainThreadNormalWorld())->globalExec(), resultValue))) + if ((serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContext(), + toRef(m_mainFrame->coreFrame()->script()->globalObject(mainThreadNormalWorld())->globalExec(), resultValue), 0))) dataReference = CoreIPC::DataReference(serializedResultValue->data().data(), serializedResultValue->data().size()); } @@ -1360,6 +1405,7 @@ void WebPage::updatePreferences(const WebPreferencesStore& store) settings->setJavaScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey())); settings->setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey())); + settings->setLoadsSiteIconsIgnoringImageLoadingSetting(store.getBoolValueForKey(WebPreferencesKey::loadsSiteIconsIgnoringImageLoadingPreferenceKey())); settings->setPluginsEnabled(store.getBoolValueForKey(WebPreferencesKey::pluginsEnabledKey())); settings->setJavaEnabled(store.getBoolValueForKey(WebPreferencesKey::javaEnabledKey())); settings->setOfflineWebApplicationCacheEnabled(store.getBoolValueForKey(WebPreferencesKey::offlineWebApplicationCacheEnabledKey())); @@ -1391,17 +1437,11 @@ void WebPage::updatePreferences(const WebPreferencesStore& store) settings->setMinimumLogicalFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey())); settings->setDefaultFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFontSizeKey())); settings->setDefaultFixedFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFixedFontSizeKey())); + settings->setEditableLinkBehavior(static_cast<WebCore::EditableLinkBehavior>(store.getUInt32ValueForKey(WebPreferencesKey::editableLinkBehaviorKey()))); -#if PLATFORM(WIN) - // Temporarily turn off accelerated compositing until we have a good solution for rendering it. - settings->setAcceleratedCompositingEnabled(false); - settings->setAcceleratedDrawingEnabled(false); - settings->setCanvasUsesAcceleratedDrawing(false); -#else - settings->setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey())); - settings->setAcceleratedDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedDrawingEnabledKey())); - settings->setCanvasUsesAcceleratedDrawing(store.getBoolValueForKey(WebPreferencesKey::canvasUsesAcceleratedDrawingKey())); -#endif + settings->setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing()); + settings->setAcceleratedDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedDrawingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing()); + settings->setCanvasUsesAcceleratedDrawing(store.getBoolValueForKey(WebPreferencesKey::canvasUsesAcceleratedDrawingKey()) && LayerTreeHost::supportsAcceleratedCompositing()); settings->setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey())); settings->setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey())); settings->setWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::webGLEnabledKey())); @@ -1441,7 +1481,7 @@ WebFullScreenManager* WebPage::fullScreenManager() } #endif -#if !PLATFORM(MAC) +#if !PLATFORM(GTK) && !PLATFORM(MAC) bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt) { Node* node = evt->target()->toNode(); @@ -1504,7 +1544,7 @@ void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint cli } } #else -void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags) +void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags, const SandboxExtension::Handle& sandboxExtensionHandle) { if (!m_page) { send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone)); @@ -1525,10 +1565,23 @@ void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint cli m_page->dragController()->dragExited(&dragData); break; - case DragControllerActionPerformDrag: + case DragControllerActionPerformDrag: { + ASSERT(!m_pendingDropSandboxExtension); + + m_pendingDropSandboxExtension = SandboxExtension::create(sandboxExtensionHandle); + m_page->dragController()->performDrag(&dragData); + + // If we started loading a local file, the sandbox extension tracker would have adopted this + // pending drop sandbox extension. If not, we'll play it safe and invalidate it. + if (m_pendingDropSandboxExtension) { + m_pendingDropSandboxExtension->invalidate(); + m_pendingDropSandboxExtension = nullptr; + } + break; - + } + default: ASSERT_NOT_REACHED(); } @@ -1550,6 +1603,11 @@ void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint glob m_page->mainFrame()->eventHandler()->dragSourceEndedAt(event, (DragOperation)operation); } +void WebPage::willPerformLoadDragDestinationAction() +{ + m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(m_pendingDropSandboxExtension.release()); +} + WebEditCommand* WebPage::webEditCommand(uint64_t commandID) { return m_editCommandMap.get(commandID).get(); @@ -1734,8 +1792,9 @@ void WebPage::didChangeScrollOffsetForMainFrame() Frame* frame = m_page->mainFrame(); IntPoint scrollPosition = frame->view()->scrollPosition(); IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition(); + IntPoint minimumScrollPosition = frame->view()->minimumScrollPosition(); - bool isPinnedToLeftSide = (scrollPosition.x() <= 0); + bool isPinnedToLeftSide = (scrollPosition.x() <= minimumScrollPosition.x()); bool isPinnedToRightSide = (scrollPosition.x() >= maximumScrollPosition.x()); if (isPinnedToLeftSide != m_cachedMainFrameIsPinnedToLeftSide || isPinnedToRightSide != m_cachedMainFrameIsPinnedToRightSide) { @@ -1877,18 +1936,28 @@ void WebPage::SandboxExtensionTracker::invalidate() } } +void WebPage::SandboxExtensionTracker::willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension) +{ + setPendingProvisionalSandboxExtension(pendingDropSandboxExtension); +} + void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle) { ASSERT(frame->isMainFrame()); + setPendingProvisionalSandboxExtension(SandboxExtension::create(handle)); +} + +void WebPage::SandboxExtensionTracker::setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension> pendingProvisionalSandboxExtension) +{ // If we get two beginLoad calls in succession, without a provisional load starting, then // m_pendingProvisionalSandboxExtension will be non-null. Invalidate and null out the extension if that is the case. if (m_pendingProvisionalSandboxExtension) { m_pendingProvisionalSandboxExtension->invalidate(); m_pendingProvisionalSandboxExtension = nullptr; } - - m_pendingProvisionalSandboxExtension = SandboxExtension::create(handle); + + m_pendingProvisionalSandboxExtension = pendingProvisionalSandboxExtension; } static bool shouldReuseCommittedSandboxExtension(WebFrame* frame) @@ -1907,8 +1976,7 @@ static bool shouldReuseCommittedSandboxExtension(WebFrame* frame) if (!documentLoader || !provisionalDocumentLoader) return false; - if (documentLoader->url().isLocalFile() && provisionalDocumentLoader->url().isLocalFile() - && provisionalDocumentLoader->triggeringAction().type() == NavigationTypeLinkClicked) + if (documentLoader->url().isLocalFile() && provisionalDocumentLoader->url().isLocalFile()) return true; return false; @@ -1953,7 +2021,6 @@ void WebPage::SandboxExtensionTracker::didFailProvisionalLoad(WebFrame* frame) if (!frame->isMainFrame()) return; - ASSERT(!m_pendingProvisionalSandboxExtension); if (!m_provisionalSandboxExtension) return; @@ -2058,7 +2125,7 @@ void WebPage::drawRectToPDF(uint64_t frameID, const WebCore::IntRect& rect, uint if (coreFrame) { ASSERT(coreFrame->document()->printing()); -#if PLATFORM(CG) +#if USE(CG) // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data. RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get())); @@ -2090,7 +2157,7 @@ void WebPage::drawPagesToPDF(uint64_t frameID, uint32_t first, uint32_t count, u if (coreFrame) { ASSERT(coreFrame->document()->printing()); -#if PLATFORM(CG) +#if USE(CG) // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data. RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get())); @@ -2159,4 +2226,19 @@ void WebPage::handleCorrectionPanelResult(const String& result) } #endif +void WebPage::simulateMouseDown(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time) +{ + mouseEvent(WebMouseEvent(WebMouseEvent::MouseDown, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time)); +} + +void WebPage::simulateMouseUp(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time) +{ + mouseEvent(WebMouseEvent(WebMouseEvent::MouseUp, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time)); +} + +void WebPage::simulateMouseMotion(WebCore::IntPoint position, double time) +{ + mouseEvent(WebMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::NoButton, position, position, 0, 0, 0, 0, WebMouseEvent::Modifiers(), time)); +} + } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.h b/Source/WebKit2/WebProcess/WebPage/WebPage.h index 8e4e71c..7828b45 100644 --- a/Source/WebKit2/WebProcess/WebPage/WebPage.h +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.h @@ -34,6 +34,7 @@ #include "InjectedBundlePageContextMenuClient.h" #include "InjectedBundlePageEditorClient.h" #include "InjectedBundlePageFormClient.h" +#include "InjectedBundlePageFullScreenClient.h" #include "InjectedBundlePageLoaderClient.h" #include "InjectedBundlePagePolicyClient.h" #include "InjectedBundlePageResourceLoadClient.h" @@ -81,6 +82,7 @@ namespace WebCore { class ResourceRequest; class SharedBuffer; class VisibleSelection; + struct KeypressCommand; } namespace WebKit { @@ -103,6 +105,8 @@ class WebOpenPanelResultListener; class WebPageGroupProxy; class WebPopupMenu; class WebWheelEvent; +struct AttributedString; +struct EditorState; struct PrintInfo; struct WebPageCreationParameters; struct WebPreferencesStore; @@ -159,9 +163,12 @@ public: void layoutIfNeeded(); // -- Called from WebCore clients. -#if !PLATFORM(MAC) +#if PLATFORM(MAC) + bool handleEditingKeyboardEvent(WebCore::KeyboardEvent*, bool saveCommands); +#elif !PLATFORM(GTK) bool handleEditingKeyboardEvent(WebCore::KeyboardEvent*); #endif + void show(); String userAgent() const { return m_userAgent; } WebCore::IntRect windowResizerRect() const; @@ -189,6 +196,9 @@ public: void initializeInjectedBundlePolicyClient(WKBundlePagePolicyClient*); void initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClient*); void initializeInjectedBundleUIClient(WKBundlePageUIClient*); +#if ENABLE(FULLSCREEN_API) + void initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClient*); +#endif InjectedBundlePageContextMenuClient& injectedBundleContextMenuClient() { return m_contextMenuClient; } InjectedBundlePageEditorClient& injectedBundleEditorClient() { return m_editorClient; } @@ -197,12 +207,17 @@ public: InjectedBundlePagePolicyClient& injectedBundlePolicyClient() { return m_policyClient; } InjectedBundlePageResourceLoadClient& injectedBundleResourceLoadClient() { return m_resourceLoadClient; } InjectedBundlePageUIClient& injectedBundleUIClient() { return m_uiClient; } +#if ENABLE(FULLSCREEN_API) + InjectedBundlePageFullScreenClient& injectedBundleFullScreenClient() { return m_fullScreenClient; } +#endif bool findStringFromInjectedBundle(const String&, FindOptions); WebFrame* mainFrame() const { return m_mainFrame.get(); } PassRefPtr<Plugin> createPlugin(const Plugin::Parameters&); + EditorState editorState() const; + String renderTreeExternalRepresentation() const; void executeEditingCommand(const String& commandName, const String& argument); bool isEditingCommandEnabled(const String& commandName); @@ -240,14 +255,13 @@ public: bool windowIsVisible() const { return m_windowIsVisible; } const WebCore::IntRect& windowFrameInScreenCoordinates() const { return m_windowFrameInScreenCoordinates; } const WebCore::IntRect& viewFrameInWindowCoordinates() const { return m_viewFrameInWindowCoordinates; } - bool interceptEditingKeyboardEvent(WebCore::KeyboardEvent*, bool); #elif PLATFORM(WIN) HWND nativeWindow() const { return m_nativeWindow; } #endif bool windowIsFocused() const; void installPageOverlay(PassRefPtr<PageOverlay>); - void uninstallPageOverlay(PageOverlay*); + void uninstallPageOverlay(PageOverlay*, bool fadeOut); bool hasPageOverlay() const { return m_pageOverlay; } WebCore::IntRect windowToScreen(const WebCore::IntRect&); @@ -285,10 +299,14 @@ public: void invalidate(); void beginLoad(WebFrame*, const SandboxExtension::Handle& handle); + void willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension); void didStartProvisionalLoad(WebFrame*); void didCommitProvisionalLoad(WebFrame*); void didFailProvisionalLoad(WebFrame*); + private: + void setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension>); + RefPtr<SandboxExtension> m_pendingProvisionalSandboxExtension; RefPtr<SandboxExtension> m_provisionalSandboxExtension; RefPtr<SandboxExtension> m_committedSandboxExtension; @@ -296,8 +314,6 @@ public: SandboxExtensionTracker& sandboxExtensionTracker() { return m_sandboxExtensionTracker; } - static void getLocationAndLengthFromRange(WebCore::Range*, uint64_t& location, uint64_t& length); - #if PLATFORM(MAC) void registerUIProcessAccessibilityTokens(const CoreIPC::DataReference& elemenToken, const CoreIPC::DataReference& windowToken); AccessibilityWebPageObject* accessibilityRemoteObject(); @@ -305,16 +321,29 @@ public: void sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput); + void setComposition(const String& text, Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, EditorState& newState); + void confirmComposition(EditorState& newState); + void insertText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, bool& handled, EditorState& newState); void getMarkedRange(uint64_t& location, uint64_t& length); + void getSelectedRange(uint64_t& location, uint64_t& length); + void getAttributedSubstringFromRange(uint64_t location, uint64_t length, AttributedString&); void characterIndexForPoint(const WebCore::IntPoint point, uint64_t& result); void firstRectForCharacterRange(uint64_t location, uint64_t length, WebCore::IntRect& resultRect); + void executeKeypressCommands(const Vector<WebCore::KeypressCommand>&, bool& handled, EditorState& newState); void writeSelectionToPasteboard(const WTF::String& pasteboardName, const WTF::Vector<WTF::String>& pasteboardTypes, bool& result); void readSelectionFromPasteboard(const WTF::String& pasteboardName, bool& result); + void shouldDelayWindowOrderingEvent(const WebKit::WebMouseEvent&, bool& result); + void acceptsFirstMouse(int eventNumber, const WebKit::WebMouseEvent&, bool& result); + bool performNonEditingBehaviorForSelector(const String&); #elif PLATFORM(WIN) void confirmComposition(const String& compositionString); void setComposition(const WTF::String& compositionString, const WTF::Vector<WebCore::CompositionUnderline>& underlines, uint64_t cursorPosition); void firstRectForCharacterInSelectedRange(const uint64_t characterPosition, WebCore::IntRect& resultRect); void getSelectedText(WTF::String&); + + void gestureWillBegin(const WebCore::IntPoint&, bool& canBeginPanning); + void gestureDidScroll(const WebCore::IntSize&); + void gestureDidEnd(); #endif // FIXME: This a dummy message, to avoid breaking the build for platforms that don't require @@ -335,10 +364,12 @@ public: #if PLATFORM(WIN) void performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WebCore::DragDataMap&, uint32_t flags); #else - void performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WTF::String& dragStorageName, uint32_t flags); + void performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WTF::String& dragStorageName, uint32_t flags, const SandboxExtension::Handle&); #endif void dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation); + void willPerformLoadDragDestinationAction(); + void beginPrinting(uint64_t frameID, const PrintInfo&); void endPrinting(); void computePagesForPrinting(uint64_t frameID, const PrintInfo&, uint64_t callbackID); @@ -365,6 +396,9 @@ public: void forceRepaintWithoutCallback(); + void unmarkAllMisspellings(); + void unmarkAllBadGrammar(); + #if PLATFORM(MAC) void setDragSource(NSObject *); #endif @@ -373,6 +407,12 @@ public: void handleCorrectionPanelResult(const String&); #endif + void simulateMouseDown(int button, WebCore::IntPoint, int clickCount, WKEventModifiers, double time); + void simulateMouseUp(int button, WebCore::IntPoint, int clickCount, WKEventModifiers, double time); + void simulateMouseMotion(WebCore::IntPoint, double time); + + void contextMenuShowing() { m_isShowingContextMenu = true; } + private: WebPage(uint64_t pageID, const WebPageCreationParameters&); @@ -383,9 +423,15 @@ private: void didReceiveWebPageMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); CoreIPC::SyncReplyMode didReceiveSyncWebPageMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder*); +#if !PLATFORM(MAC) static const char* interpretKeyEvent(const WebCore::KeyboardEvent*); +#endif bool performDefaultBehaviorForKeyEvent(const WebKeyboardEvent&); +#if PLATFORM(MAC) + bool executeKeypressCommandsInternal(const Vector<WebCore::KeypressCommand>&, WebCore::KeyboardEvent*); +#endif + String sourceForFrame(WebFrame*); void loadData(PassRefPtr<WebCore::SharedBuffer>, const String& MIMEType, const String& encodingName, const WebCore::KURL& baseURL, const WebCore::KURL& failingURL); @@ -399,6 +445,7 @@ private: void loadHTMLString(const String& htmlString, const String& baseURL); void loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL); void loadPlainTextString(const String&); + void linkClicked(const String& url, const WebMouseEvent&); void reload(bool reloadFromOrigin); void goForward(uint64_t, const SandboxExtension::Handle&); void goBack(uint64_t, const SandboxExtension::Handle&); @@ -420,6 +467,7 @@ private: #if ENABLE(TOUCH_EVENTS) void touchEvent(const WebTouchEvent&); #endif + void contextMenuHidden() { m_isShowingContextMenu = false; } static void scroll(WebCore::Page*, WebCore::ScrollDirection, WebCore::ScrollGranularity); static void logicalScroll(WebCore::Page*, WebCore::ScrollLogicalDirection, WebCore::ScrollGranularity); @@ -486,8 +534,6 @@ private: void advanceToNextMisspelling(bool startBeforeSelection); void changeSpellingToWord(const String& word); - void unmarkAllMisspellings(); - void unmarkAllBadGrammar(); #if PLATFORM(MAC) void uppercaseWord(); void lowercaseWord(); @@ -545,9 +591,14 @@ private: RetainPtr<AccessibilityWebPageObject> m_mockAccessibilityElement; RetainPtr<NSObject> m_dragSource; + + WebCore::KeyboardEvent* m_keyboardEventBeingInterpreted; + #elif PLATFORM(WIN) // Our view's window (in the UI process). HWND m_nativeWindow; + + RefPtr<WebCore::Node> m_gestureTargetNode; #endif HashMap<uint64_t, RefPtr<WebEditCommand> > m_editCommandMap; @@ -561,6 +612,9 @@ private: InjectedBundlePagePolicyClient m_policyClient; InjectedBundlePageResourceLoadClient m_resourceLoadClient; InjectedBundlePageUIClient m_uiClient; +#if ENABLE(FULLSCREEN_API) + InjectedBundlePageFullScreenClient m_fullScreenClient; +#endif #if ENABLE(TILED_BACKING_STORE) WebCore::IntSize m_resizesToContentsLayoutSize; @@ -585,6 +639,8 @@ private: SandboxExtensionTracker m_sandboxExtensionTracker; uint64_t m_pageID; + RefPtr<SandboxExtension> m_pendingDropSandboxExtension; + bool m_canRunBeforeUnloadConfirmPanel; bool m_canRunModal; @@ -594,6 +650,12 @@ private: bool m_cachedMainFrameIsPinnedToLeftSide; bool m_cachedMainFrameIsPinnedToRightSide; + + bool m_isShowingContextMenu; + +#if PLATFORM(WIN) + bool m_gestureReachedScrollingLimit; +#endif }; } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in index 69bd54d..673e8d6 100644 --- a/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in +++ b/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in @@ -42,6 +42,8 @@ messages -> WebPage { TouchEvent(WebKit::WebTouchEvent event) #endif + ContextMenuHidden() + ScrollBy(uint32_t scrollDirection, uint32_t scrollGranularity) GoBack(uint64_t backForwardItemID, WebKit::SandboxExtension::Handle sandboxExtensionHandle) @@ -52,6 +54,7 @@ messages -> WebPage { LoadPlainTextString(WTF::String string) LoadURL(WTF::String url, WebKit::SandboxExtension::Handle sandboxExtensionHandle) LoadURLRequest(WebCore::ResourceRequest request, WebKit::SandboxExtension::Handle sandboxExtensionHandle) + LinkClicked(WTF::String url, WebKit::WebMouseEvent event) Reload(bool reloadFromOrigin) StopLoading() @@ -119,7 +122,7 @@ messages -> WebPage { PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, HashMap<UINT,Vector<String>> dataMap, uint32_t flags) #endif #if !PLATFORM(WIN) - PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, WTF::String dragStorageName, uint32_t flags) + PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, WTF::String dragStorageName, uint32_t flags, WebKit::SandboxExtension::Handle sandboxExtensionHandle) #endif DragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation) @@ -140,8 +143,6 @@ messages -> WebPage { # Spelling and grammar. AdvanceToNextMisspelling(bool startBeforeSelection) ChangeSpellingToWord(WTF::String word) - UnmarkAllMisspellings() - UnmarkAllBadGrammar() #if PLATFORM(MAC) UppercaseWord(); LowercaseWord(); @@ -179,18 +180,33 @@ messages -> WebPage { SetWindowIsVisible(bool windowIsVisible) WindowAndViewFramesChanged(WebCore::IntRect windowFrameInScreenCoordinates, WebCore::IntRect viewFrameInWindowCoordinates, WebCore::IntPoint accessibilityViewCoordinates) - GetMarkedRange() -> (uint64_t location, uint64_t length) - CharacterIndexForPoint(WebCore::IntPoint point) -> (uint64_t result) - FirstRectForCharacterRange(uint64_t location, uint64_t length) -> (WebCore::IntRect resultRect) RegisterUIProcessAccessibilityTokens(CoreIPC::DataReference elemenToken, CoreIPC::DataReference windowToken) WriteSelectionToPasteboard(WTF::String pasteboardName, WTF::Vector<WTF::String> pasteboardTypes) -> (bool result) ReadSelectionFromPasteboard(WTF::String pasteboardName) -> (bool result) + + # Text input. + SetComposition(WTF::String text, WTF::Vector<WebCore::CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd) -> (WebKit::EditorState newState) + ConfirmComposition() -> (WebKit::EditorState newState) + InsertText(WTF::String text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd) -> (bool handled, WebKit::EditorState newState) + GetMarkedRange() -> (uint64_t location, uint64_t length) + GetSelectedRange() -> (uint64_t location, uint64_t length) + GetAttributedSubstringFromRange(uint64_t location, uint64_t length) -> (WebKit::AttributedString result) + CharacterIndexForPoint(WebCore::IntPoint point) -> (uint64_t result) + FirstRectForCharacterRange(uint64_t location, uint64_t length) -> (WebCore::IntRect resultRect) + ExecuteKeypressCommands(Vector<WebCore::KeypressCommand> savedCommands) -> (bool handled, WebKit::EditorState newState) + ShouldDelayWindowOrderingEvent(WebKit::WebMouseEvent event) -> (bool result) + AcceptsFirstMouse(int eventNumber, WebKit::WebMouseEvent event) -> (bool result) #endif #if PLATFORM(WIN) + // FIXME: Unify with Mac counterparts. ConfirmComposition(WTF::String compositionString) SetComposition(WTF::String compositionString, WTF::Vector<WebCore::CompositionUnderline> underlines, uint64_t cursorPosition) FirstRectForCharacterInSelectedRange(uint64_t characterPosition) -> (WebCore::IntRect resultRect) GetSelectedText() -> (WTF::String text) + + GestureWillBegin(WebCore::IntPoint point) -> (bool canBeginPanning) + GestureDidScroll(WebCore::IntSize size) + GestureDidEnd() #endif #if PLATFORM(QT) FindZoomableAreaForPoint(WebCore::IntPoint point) diff --git a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h index 55cf629..91e6c5c 100644 --- a/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h +++ b/Source/WebKit2/WebProcess/WebPage/WebPageGroupProxy.h @@ -42,6 +42,7 @@ public: const String& identifier() const { return m_data.identifer; } uint64_t pageGroupID() const { return m_data.pageGroupID; } bool isVisibleToInjectedBundle() const { return m_data.visibleToInjectedBundle; } + bool isVisibleToHistoryClient() const { return m_data.visibleToHistoryClient; } private: WebPageGroupProxy(const WebPageGroupData& data) diff --git a/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp index 2460607..42a2dc9 100644 --- a/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp +++ b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.cpp @@ -31,39 +31,41 @@ #include "WebProcess.h" #include <WebCore/Frame.h> #include <WebCore/FrameView.h> +#include <WebCore/GraphicsLayerCA.h> #include <WebCore/Page.h> +#include <WebCore/PlatformCALayer.h> #include <WebCore/Settings.h> using namespace WebCore; namespace WebKit { -PassRefPtr<LayerTreeHostCA> LayerTreeHostCA::create(WebPage* webPage) -{ - return adoptRef(new LayerTreeHostCA(webPage)); -} - LayerTreeHostCA::LayerTreeHostCA(WebPage* webPage) : LayerTreeHost(webPage) , m_isValid(true) , m_notifyAfterScheduledLayerFlush(false) { +} +void LayerTreeHostCA::initialize() +{ // Create a root layer. m_rootLayer = GraphicsLayer::create(this); #ifndef NDEBUG m_rootLayer->setName("LayerTreeHost root layer"); #endif m_rootLayer->setDrawsContent(false); - m_rootLayer->setSize(webPage->size()); + m_rootLayer->setSize(m_webPage->size()); + static_cast<GraphicsLayerCA*>(m_rootLayer.get())->platformCALayer()->setGeometryFlipped(true); m_nonCompositedContentLayer = GraphicsLayer::create(this); + static_cast<GraphicsLayerCA*>(m_nonCompositedContentLayer.get())->setAllowTiledLayer(false); #ifndef NDEBUG m_nonCompositedContentLayer->setName("LayerTreeHost non-composited content"); #endif m_nonCompositedContentLayer->setDrawsContent(true); m_nonCompositedContentLayer->setContentsOpaque(m_webPage->drawsBackground() && !m_webPage->drawsTransparentBackground()); - m_nonCompositedContentLayer->setSize(webPage->size()); + m_nonCompositedContentLayer->setSize(m_webPage->size()); if (m_webPage->corePage()->settings()->acceleratedDrawingEnabled()) m_nonCompositedContentLayer->setAcceleratesDrawing(true); @@ -72,7 +74,7 @@ LayerTreeHostCA::LayerTreeHostCA(WebPage* webPage) if (m_webPage->hasPageOverlay()) createPageOverlayLayer(); - platformInitialize(); + platformInitialize(m_layerTreeContext); scheduleLayerFlush(); } @@ -81,10 +83,6 @@ LayerTreeHostCA::~LayerTreeHostCA() { ASSERT(!m_isValid); ASSERT(!m_rootLayer); -#if PLATFORM(MAC) - ASSERT(!m_flushPendingLayerChangesRunLoopObserver); - ASSERT(!m_remoteLayerClient); -#endif } const LayerTreeContext& LayerTreeHostCA::layerTreeContext() @@ -109,7 +107,6 @@ void LayerTreeHostCA::setRootCompositingLayer(GraphicsLayer* graphicsLayer) void LayerTreeHostCA::invalidate() { ASSERT(m_isValid); - platformInvalidate(); m_rootLayer = nullptr; m_isValid = false; } @@ -138,16 +135,12 @@ void LayerTreeHostCA::sizeDidChange(const IntSize& newSize) scheduleLayerFlush(); flushPendingLayerChanges(); - - platformSizeDidChange(); } void LayerTreeHostCA::forceRepaint() { scheduleLayerFlush(); flushPendingLayerChanges(); - - platformForceRepaint(); } void LayerTreeHostCA::didInstallPageOverlay() @@ -218,8 +211,6 @@ void LayerTreeHostCA::performScheduledLayerFlush() void LayerTreeHostCA::didPerformScheduledLayerFlush() { - platformDidPerformScheduledLayerFlush(); - if (m_notifyAfterScheduledLayerFlush) { // Let the drawing area know that we've done a flush of the layer changes. static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->layerHostDidFlushLayers(); diff --git a/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h index ba4e33a..3a62d15 100644 --- a/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h +++ b/Source/WebKit2/WebProcess/WebPage/ca/LayerTreeHostCA.h @@ -31,35 +31,36 @@ #include <WebCore/GraphicsLayerClient.h> #include <wtf/OwnPtr.h> -#if PLATFORM(MAC) -#include <wtf/RetainPtr.h> -#endif - -#if PLATFORM(MAC) -typedef struct __WKCARemoteLayerClientRef* WKCARemoteLayerClientRef; -#endif - namespace WebKit { class LayerTreeHostCA : public LayerTreeHost, WebCore::GraphicsLayerClient { public: - static PassRefPtr<LayerTreeHostCA> create(WebPage*); - ~LayerTreeHostCA(); + virtual ~LayerTreeHostCA(); -private: +protected: explicit LayerTreeHostCA(WebPage*); + WebCore::GraphicsLayer* rootLayer() const { return m_rootLayer.get(); } + + void initialize(); + void performScheduledLayerFlush(); + + // LayerTreeHost. + virtual void invalidate(); + virtual void sizeDidChange(const WebCore::IntSize& newSize); + virtual void forceRepaint(); + + // LayerTreeHostCA + virtual void didPerformScheduledLayerFlush(); + +private: // LayerTreeHost. virtual const LayerTreeContext& layerTreeContext(); - virtual void scheduleLayerFlush(); virtual void setShouldNotifyAfterNextScheduledLayerFlush(bool); virtual void setRootCompositingLayer(WebCore::GraphicsLayer*); - virtual void invalidate(); virtual void setNonCompositedContentsNeedDisplay(const WebCore::IntRect&); virtual void scrollNonCompositedContents(const WebCore::IntRect& scrollRect, const WebCore::IntSize& scrollOffset); - virtual void sizeDidChange(const WebCore::IntSize& newSize); - virtual void forceRepaint(); virtual void didInstallPageOverlay(); virtual void didUninstallPageOverlay(); @@ -72,23 +73,14 @@ private: virtual bool showDebugBorders() const; virtual bool showRepaintCounter() const; - void platformInitialize(); - void platformInvalidate(); - void platformSizeDidChange(); - void platformForceRepaint(); + // LayerTreeHostCA + virtual void platformInitialize(LayerTreeContext&) = 0; - void performScheduledLayerFlush(); - void didPerformScheduledLayerFlush(); - void platformDidPerformScheduledLayerFlush(); bool flushPendingLayerChanges(); void createPageOverlayLayer(); void destroyPageOverlayLayer(); -#if PLATFORM(MAC) - static void flushPendingLayerChangesRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void*); -#endif - // The context for this layer tree. LayerTreeContext m_layerTreeContext; @@ -107,11 +99,6 @@ private: // The page overlay layer. Will be null if there's no page overlay. OwnPtr<WebCore::GraphicsLayer> m_pageOverlayLayer; - -#if PLATFORM(MAC) - RetainPtr<WKCARemoteLayerClientRef> m_remoteLayerClient; - RetainPtr<CFRunLoopObserverRef> m_flushPendingLayerChangesRunLoopObserver; -#endif }; } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h new file mode 100644 index 0000000..e3a0160 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * 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. + */ + +#ifndef LayerTreeHostCAMac_h +#define LayerTreeHostCAMac_h + +#include "LayerTreeHostCA.h" +#include <wtf/RetainPtr.h> + +typedef struct __WKCARemoteLayerClientRef* WKCARemoteLayerClientRef; + +namespace WebKit { + +class LayerTreeHostCAMac : public LayerTreeHostCA { +public: + static PassRefPtr<LayerTreeHostCAMac> create(WebPage*); + virtual ~LayerTreeHostCAMac(); + +private: + explicit LayerTreeHostCAMac(WebPage*); + + // LayerTreeHost. + virtual void scheduleLayerFlush(); + virtual void invalidate(); + virtual void sizeDidChange(const WebCore::IntSize& newSize); + virtual void forceRepaint(); + virtual void pauseRendering(); + virtual void resumeRendering(); + + // LayerTreeHostCA + virtual void platformInitialize(LayerTreeContext&); + virtual void didPerformScheduledLayerFlush(); + + static void flushPendingLayerChangesRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void*); + + RetainPtr<WKCARemoteLayerClientRef> m_remoteLayerClient; + RetainPtr<CFRunLoopObserverRef> m_flushPendingLayerChangesRunLoopObserver; +}; + +} // namespace WebKit + +#endif // LayerTreeHostCAMac_h diff --git a/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm index 50776d7..69cfa44 100644 --- a/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm +++ b/Source/WebKit2/WebProcess/WebPage/ca/mac/LayerTreeHostCAMac.mm @@ -24,32 +24,50 @@ */ #import "config.h" -#import "LayerTreeHostCA.h" +#import "LayerTreeHostCAMac.h" #import "WebProcess.h" #import <QuartzCore/CATransaction.h> #import <WebCore/GraphicsLayer.h> #import <WebKitSystemInterface.h> +using namespace WebCore; + @interface CATransaction (Details) + (void)synchronize; @end namespace WebKit { -void LayerTreeHostCA::platformInitialize() +PassRefPtr<LayerTreeHostCAMac> LayerTreeHostCAMac::create(WebPage* webPage) +{ + RefPtr<LayerTreeHostCAMac> host = adoptRef(new LayerTreeHostCAMac(webPage)); + host->initialize(); + return host.release(); +} + +LayerTreeHostCAMac::LayerTreeHostCAMac(WebPage* webPage) + : LayerTreeHostCA(webPage) +{ +} + +LayerTreeHostCAMac::~LayerTreeHostCAMac() +{ + ASSERT(!m_flushPendingLayerChangesRunLoopObserver); + ASSERT(!m_remoteLayerClient); +} + +void LayerTreeHostCAMac::platformInitialize(LayerTreeContext& layerTreeContext) { mach_port_t serverPort = WebProcess::shared().compositingRenderServerPort(); m_remoteLayerClient = WKCARemoteLayerClientMakeWithServerPort(serverPort); - [m_rootLayer->platformLayer() setGeometryFlipped:YES]; + WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), rootLayer()->platformLayer()); - WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), m_rootLayer->platformLayer()); - - m_layerTreeContext.contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerClient.get()); + layerTreeContext.contextID = WKCARemoteLayerClientGetClientId(m_remoteLayerClient.get()); } -void LayerTreeHostCA::scheduleLayerFlush() +void LayerTreeHostCAMac::scheduleLayerFlush() { CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent(); @@ -67,7 +85,7 @@ void LayerTreeHostCA::scheduleLayerFlush() CFRunLoopAddObserver(currentRunLoop, m_flushPendingLayerChangesRunLoopObserver.get(), kCFRunLoopCommonModes); } -void LayerTreeHostCA::platformInvalidate() +void LayerTreeHostCAMac::invalidate() { if (m_flushPendingLayerChangesRunLoopObserver) { CFRunLoopObserverInvalidate(m_flushPendingLayerChangesRunLoopObserver.get()); @@ -76,34 +94,54 @@ void LayerTreeHostCA::platformInvalidate() WKCARemoteLayerClientInvalidate(m_remoteLayerClient.get()); m_remoteLayerClient = nullptr; + + LayerTreeHostCA::invalidate(); } -void LayerTreeHostCA::platformSizeDidChange() +void LayerTreeHostCAMac::sizeDidChange(const IntSize& newSize) { + LayerTreeHostCA::sizeDidChange(newSize); [CATransaction flush]; [CATransaction synchronize]; } -void LayerTreeHostCA::platformForceRepaint() +void LayerTreeHostCAMac::forceRepaint() { + LayerTreeHostCA::forceRepaint(); [CATransaction flush]; [CATransaction synchronize]; -} +} + +void LayerTreeHostCAMac::pauseRendering() +{ + CALayer* root = rootLayer()->platformLayer(); + [root setValue:(id)kCFBooleanTrue forKey:@"NSCAViewRenderPaused"]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"NSCAViewRenderDidPauseNotification" object:nil userInfo:[NSDictionary dictionaryWithObject:root forKey:@"layer"]]; +} -void LayerTreeHostCA::flushPendingLayerChangesRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void* context) +void LayerTreeHostCAMac::resumeRendering() +{ + CALayer* root = rootLayer()->platformLayer(); + [root setValue:(id)kCFBooleanFalse forKey:@"NSCAViewRenderPaused"]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"NSCAViewRenderDidResumeNotification" object:nil userInfo:[NSDictionary dictionaryWithObject:root forKey:@"layer"]]; +} + +void LayerTreeHostCAMac::flushPendingLayerChangesRunLoopObserverCallback(CFRunLoopObserverRef, CFRunLoopActivity, void* context) { // This gets called outside of the normal event loop so wrap in an autorelease pool NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - static_cast<LayerTreeHostCA*>(context)->performScheduledLayerFlush(); + static_cast<LayerTreeHostCAMac*>(context)->performScheduledLayerFlush(); [pool drain]; } -void LayerTreeHostCA::platformDidPerformScheduledLayerFlush() +void LayerTreeHostCAMac::didPerformScheduledLayerFlush() { // We successfully flushed the pending layer changes, remove the run loop observer. ASSERT(m_flushPendingLayerChangesRunLoopObserver); CFRunLoopObserverInvalidate(m_flushPendingLayerChangesRunLoopObserver.get()); m_flushPendingLayerChangesRunLoopObserver = 0; + + LayerTreeHostCA::didPerformScheduledLayerFlush(); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp index 81db03e..699a1fe 100644 --- a/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp +++ b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.cpp @@ -24,46 +24,276 @@ */ #include "config.h" -#include "LayerTreeHostCA.h" +#include "LayerTreeHostCAWin.h" -#include <WebCore/NotImplemented.h> +#if HAVE(WKQCA) + +#include "DrawingAreaImpl.h" +#include "ShareableBitmap.h" +#include "UpdateInfo.h" +#include "WebPage.h" +#include <WebCore/GraphicsLayerCA.h> +#include <WebCore/LayerChangesFlusher.h> +#include <WebCore/PlatformCALayer.h> +#include <WebCore/WebCoreInstanceHandle.h> +#include <WebKitQuartzCoreAdditions/WKCACFImage.h> +#include <WebKitQuartzCoreAdditions/WKCACFView.h> +#include <wtf/CurrentTime.h> +#include <wtf/Threading.h> + +#ifdef DEBUG_ALL +#pragma comment(lib, "WebKitQuartzCoreAdditions_debug") +#else +#pragma comment(lib, "WebKitQuartzCoreAdditions") +#endif + +using namespace WebCore; namespace WebKit { -void LayerTreeHostCA::platformInitialize() +static HWND dummyWindow; +static LPCWSTR dummyWindowClass = L"LayerTreeHostCAWindowClass"; +static size_t validLayerTreeHostCount; + +static void registerDummyWindowClass() +{ + static bool didRegister; + if (didRegister) + return; + didRegister = true; + + WNDCLASSW wndClass = {0}; + wndClass.lpszClassName = dummyWindowClass; + wndClass.lpfnWndProc = ::DefWindowProcW; + wndClass.hInstance = instanceHandle(); + + ::RegisterClassW(&wndClass); +} + +// This window is never shown. It is only needed so that D3D can determine the display mode, etc. +static HWND createDummyWindow() { - // FIXME: <http://webkit.org/b/45567> Implement this! - notImplemented(); + registerDummyWindowClass(); + return ::CreateWindowW(dummyWindowClass, 0, WS_POPUP, 0, 0, 10, 10, 0, 0, instanceHandle(), 0); } -void LayerTreeHostCA::scheduleLayerFlush() +bool LayerTreeHostCAWin::supportsAcceleratedCompositing() { - // FIXME: <http://webkit.org/b/45567> Implement this! - notImplemented(); + static bool initialized; + static bool supportsAcceleratedCompositing; + if (initialized) + return supportsAcceleratedCompositing; + initialized = true; + + ASSERT(!dummyWindow); + dummyWindow = createDummyWindow(); + RetainPtr<WKCACFViewRef> view(AdoptCF, WKCACFViewCreate(kWKCACFViewDrawingDestinationImage)); + CGRect fakeBounds = CGRectMake(0, 0, 10, 10); + WKCACFViewUpdate(view.get(), dummyWindow, &fakeBounds); + + supportsAcceleratedCompositing = WKCACFViewCanDraw(view.get()); + + WKCACFViewUpdate(view.get(), 0, 0); + ::DestroyWindow(dummyWindow); + dummyWindow = 0; + + return supportsAcceleratedCompositing; } -void LayerTreeHostCA::platformInvalidate() +PassRefPtr<LayerTreeHostCAWin> LayerTreeHostCAWin::create(WebPage* webPage) { - // FIXME: <http://webkit.org/b/45567> Implement this! - notImplemented(); + RefPtr<LayerTreeHostCAWin> host = adoptRef(new LayerTreeHostCAWin(webPage)); + host->initialize(); + return host.release(); } -void LayerTreeHostCA::platformSizeDidChange() +LayerTreeHostCAWin::LayerTreeHostCAWin(WebPage* webPage) + : LayerTreeHostCA(webPage) + , m_isFlushingLayerChanges(false) + , m_nextDisplayTime(0) { - // FIXME: <http://webkit.org/b/45567> Implement this! - notImplemented(); } -void LayerTreeHostCA::platformForceRepaint() +LayerTreeHostCAWin::~LayerTreeHostCAWin() { - // FIXME: <http://webkit.org/b/45567> Implement this! - notImplemented(); } -void LayerTreeHostCA::platformDidPerformScheduledLayerFlush() +void LayerTreeHostCAWin::platformInitialize(LayerTreeContext&) { - // FIXME: <http://webkit.org/b/45567> Implement this! - notImplemented(); + ++validLayerTreeHostCount; + if (!dummyWindow) + dummyWindow = createDummyWindow(); + + m_view.adoptCF(WKCACFViewCreate(kWKCACFViewDrawingDestinationImage)); + WKCACFViewSetContextUserData(m_view.get(), static_cast<AbstractCACFLayerTreeHost*>(this)); + WKCACFViewSetLayer(m_view.get(), rootLayer()->platformLayer()); + WKCACFViewSetContextDidChangeCallback(m_view.get(), contextDidChangeCallback, this); + + CGRect bounds = m_webPage->bounds(); + WKCACFViewUpdate(m_view.get(), dummyWindow, &bounds); +} + +void LayerTreeHostCAWin::invalidate() +{ + LayerChangesFlusher::shared().cancelPendingFlush(this); + + WKCACFViewUpdate(m_view.get(), 0, 0); + WKCACFViewSetContextUserData(m_view.get(), 0); + WKCACFViewSetLayer(m_view.get(), 0); + WKCACFViewSetContextDidChangeCallback(m_view.get(), 0, 0); + + LayerTreeHostCA::invalidate(); + + if (--validLayerTreeHostCount) + return; + ::DestroyWindow(dummyWindow); + dummyWindow = 0; +} + +void LayerTreeHostCAWin::scheduleLayerFlush() +{ + LayerChangesFlusher::shared().flushPendingLayerChangesSoon(this); +} + +bool LayerTreeHostCAWin::participatesInDisplay() +{ + return true; +} + +bool LayerTreeHostCAWin::needsDisplay() +{ + return timeUntilNextDisplay() <= 0; +} + +double LayerTreeHostCAWin::timeUntilNextDisplay() +{ + return m_nextDisplayTime - currentTime(); +} + +static IntSize size(WKCACFImageRef image) +{ + return IntSize(WKCACFImageGetWidth(image), WKCACFImageGetHeight(image)); +} + +static PassRefPtr<ShareableBitmap> toShareableBitmap(WKCACFImageRef image) +{ + size_t fileMappingSize; + HANDLE mapping = WKCACFImageCopyFileMapping(image, &fileMappingSize); + if (!mapping) + return 0; + + RefPtr<SharedMemory> sharedMemory = SharedMemory::adopt(mapping, fileMappingSize, SharedMemory::ReadWrite); + if (!sharedMemory) { + ::CloseHandle(mapping); + return 0; + } + + // WKCACFImage never has an alpha channel. + return ShareableBitmap::create(size(image), 0, sharedMemory.release()); +} + +void LayerTreeHostCAWin::display(UpdateInfo& updateInfo) +{ + CGPoint imageOrigin; + CFTimeInterval nextDrawTime; + RetainPtr<WKCACFImageRef> image(AdoptCF, WKCACFViewCopyDrawnImage(m_view.get(), &imageOrigin, &nextDrawTime)); + m_nextDisplayTime = nextDrawTime - CACurrentMediaTime() + currentTime(); + if (!image) + return; + RefPtr<ShareableBitmap> bitmap = toShareableBitmap(image.get()); + if (!bitmap) + return; + if (!bitmap->createHandle(updateInfo.bitmapHandle)) + return; + updateInfo.updateRectBounds = IntRect(IntPoint(imageOrigin.x, m_webPage->size().height() - imageOrigin.y - bitmap->size().height()), bitmap->size()); + updateInfo.updateRects.append(updateInfo.updateRectBounds); +} + +void LayerTreeHostCAWin::sizeDidChange(const IntSize& newSize) +{ + LayerTreeHostCA::sizeDidChange(newSize); + CGRect bounds = CGRectMake(0, 0, newSize.width(), newSize.height()); + WKCACFViewUpdate(m_view.get(), dummyWindow, &bounds); + WKCACFViewFlushContext(m_view.get()); +} + +void LayerTreeHostCAWin::forceRepaint() +{ + LayerTreeHostCA::forceRepaint(); + WKCACFViewFlushContext(m_view.get()); +} + +void LayerTreeHostCAWin::contextDidChangeCallback(WKCACFViewRef view, void* info) +{ + // This should only be called on a background thread when no changes have actually + // been committed to the context, eg. when a video frame has been added to an image + // queue, so return without triggering animations etc. + if (!isMainThread()) + return; + + LayerTreeHostCAWin* host = static_cast<LayerTreeHostCAWin*>(info); + ASSERT_ARG(view, view == host->m_view); + host->contextDidChange(); +} + +void LayerTreeHostCAWin::contextDidChange() +{ + // Send currentTime to the pending animations. This function is called by CACF in a callback + // which occurs after the drawInContext calls. So currentTime is very close to the time + // the animations actually start + double currentTime = WTF::currentTime(); + + HashSet<RefPtr<PlatformCALayer> >::iterator end = m_pendingAnimatedLayers.end(); + for (HashSet<RefPtr<PlatformCALayer> >::iterator it = m_pendingAnimatedLayers.begin(); it != end; ++it) + (*it)->animationStarted(currentTime); + + m_pendingAnimatedLayers.clear(); + + m_nextDisplayTime = 0; + static_cast<DrawingAreaImpl*>(m_webPage->drawingArea())->setLayerHostNeedsDisplay(); +} + +PlatformCALayer* LayerTreeHostCAWin::rootLayer() const +{ + return static_cast<GraphicsLayerCA*>(LayerTreeHostCA::rootLayer())->platformCALayer(); +} + +void LayerTreeHostCAWin::addPendingAnimatedLayer(PassRefPtr<PlatformCALayer> layer) +{ + m_pendingAnimatedLayers.add(layer); +} + +void LayerTreeHostCAWin::layerTreeDidChange() +{ + if (m_isFlushingLayerChanges) { + // The layer tree is changing as a result of flushing GraphicsLayer changes to their + // underlying PlatformCALayers. We'll flush those changes to the context as part of that + // process, so there's no need to schedule another flush here. + return; + } + + // The layer tree is changing as a result of someone modifying a PlatformCALayer that doesn't + // have a corresponding GraphicsLayer. Schedule a flush since we won't schedule one through the + // normal GraphicsLayer mechanisms. + LayerChangesFlusher::shared().flushPendingLayerChangesSoon(this); +} + +void LayerTreeHostCAWin::flushPendingLayerChangesNow() +{ + RefPtr<LayerTreeHostCA> protector(this); + + m_isFlushingLayerChanges = true; + + // Flush changes stored up in GraphicsLayers to their underlying PlatformCALayers, if + // requested. + performScheduledLayerFlush(); + + // Flush changes stored up in PlatformCALayers to the context so they will be rendered. + WKCACFViewFlushContext(m_view.get()); + + m_isFlushingLayerChanges = false; } } // namespace WebKit + +#endif // HAVE(WKQCA) diff --git a/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h new file mode 100644 index 0000000..2232b08 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/ca/win/LayerTreeHostCAWin.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * 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. + */ + +#ifndef LayerTreeHostCAWin_h +#define LayerTreeHostCAWin_h + +#include "HeaderDetection.h" + +#if HAVE(WKQCA) + +#include "LayerTreeHostCA.h" +#include <WebCore/AbstractCACFLayerTreeHost.h> +#include <wtf/HashSet.h> +#include <wtf/RetainPtr.h> + +typedef struct _WKCACFView* WKCACFViewRef; + +namespace WebKit { + +class LayerTreeHostCAWin : public LayerTreeHostCA, private WebCore::AbstractCACFLayerTreeHost { +public: + static bool supportsAcceleratedCompositing(); + + static PassRefPtr<LayerTreeHostCAWin> create(WebPage*); + virtual ~LayerTreeHostCAWin(); + +private: + explicit LayerTreeHostCAWin(WebPage*); + + static void contextDidChangeCallback(WKCACFViewRef, void* info); + void contextDidChange(); + + // LayerTreeHost + virtual void invalidate(); + virtual void forceRepaint(); + virtual void sizeDidChange(const WebCore::IntSize& newSize); + virtual void scheduleLayerFlush(); + virtual bool participatesInDisplay(); + virtual bool needsDisplay(); + virtual double timeUntilNextDisplay(); + virtual void display(UpdateInfo&); + + // LayerTreeHostCA + virtual void platformInitialize(LayerTreeContext&); + + // AbstractCACFLayerTreeHost + virtual WebCore::PlatformCALayer* rootLayer() const; + virtual void addPendingAnimatedLayer(PassRefPtr<WebCore::PlatformCALayer>); + virtual void layerTreeDidChange(); + virtual void flushPendingLayerChangesNow(); + + RetainPtr<WKCACFViewRef> m_view; + HashSet<RefPtr<WebCore::PlatformCALayer> > m_pendingAnimatedLayers; + bool m_isFlushingLayerChanges; + double m_nextDisplayTime; +}; + +} // namespace WebKit + +#endif // HAVE(WKQCA) + +#endif // LayerTreeHostCAWin_h diff --git a/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp b/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp new file mode 100644 index 0000000..57c9977 --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/gtk/WebPageGtk.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. + * Copyright (C) 2011 Igalia S.L. + * + * 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. + */ + +#include "config.h" +#include "WebPage.h" + +#include "NotImplemented.h" +#include "WebEvent.h" +#include "WindowsKeyboardCodes.h" +#include <WebCore/FocusController.h> +#include <WebCore/Frame.h> +#include <WebCore/KeyboardEvent.h> +#include <WebCore/Page.h> +#include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/Settings.h> + +using namespace WebCore; + +namespace WebKit { + +void WebPage::platformInitialize() +{ + notImplemented(); +} + +void WebPage::platformPreferencesDidChange(const WebPreferencesStore&) +{ + notImplemented(); +} + +static inline void scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity) +{ + page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity); +} + +bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent) +{ + if (keyboardEvent.type() != WebEvent::KeyDown && keyboardEvent.type() != WebEvent::RawKeyDown) + return false; + + switch (keyboardEvent.windowsVirtualKeyCode()) { + case VK_BACK: + if (keyboardEvent.shiftKey()) + m_page->goForward(); + else + m_page->goBack(); + break; + case VK_SPACE: + scroll(m_page.get(), keyboardEvent.shiftKey() ? ScrollUp : ScrollDown, ScrollByPage); + break; + case VK_LEFT: + scroll(m_page.get(), ScrollLeft, ScrollByLine); + break; + case VK_RIGHT: + scroll(m_page.get(), ScrollRight, ScrollByLine); + break; + case VK_UP: + scroll(m_page.get(), ScrollUp, ScrollByLine); + break; + case VK_DOWN: + scroll(m_page.get(), ScrollDown, ScrollByLine); + break; + case VK_HOME: + scroll(m_page.get(), ScrollUp, ScrollByDocument); + break; + case VK_END: + scroll(m_page.get(), ScrollDown, ScrollByDocument); + break; + case VK_PRIOR: + scroll(m_page.get(), ScrollUp, ScrollByPage); + break; + case VK_NEXT: + scroll(m_page.get(), ScrollDown, ScrollByPage); + break; + default: + return false; + } + + return true; +} + +bool WebPage::platformHasLocalDataForURL(const WebCore::KURL&) +{ + // FIXME: Implement + notImplemented(); + return false; +} + +String WebPage::cachedResponseMIMETypeForURL(const WebCore::KURL&) +{ + // FIXME: Implement + return String(); +} + +bool WebPage::platformCanHandleRequest(const WebCore::ResourceRequest&) +{ + // FIXME: Implement + return true; +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm b/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm index 8d81889..d7b352c 100644 --- a/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm +++ b/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm @@ -27,10 +27,13 @@ #import "WebPage.h" #import "AccessibilityWebPageObject.h" +#import "AttributedString.h" #import "DataReference.h" +#import "EditorState.h" #import "PluginView.h" #import "WebCoreArgumentCoders.h" #import "WebEvent.h" +#import "WebEventConversion.h" #import "WebFrame.h" #import "WebPageProxyMessages.h" #import "WebProcess.h" @@ -39,6 +42,7 @@ #import <WebCore/Frame.h> #import <WebCore/FrameView.h> #import <WebCore/HitTestResult.h> +#import <WebCore/HTMLConverter.h> #import <WebCore/KeyboardEvent.h> #import <WebCore/Page.h> #import <WebCore/PlatformKeyboardEvent.h> @@ -53,6 +57,8 @@ using namespace WebCore; namespace WebKit { +static PassRefPtr<Range> convertToRange(Frame*, NSRange); + void WebPage::platformInitialize() { m_page->addSchedulePair(SchedulePair::create([NSRunLoop currentRunLoop], kCFRunLoopCommonModes)); @@ -77,68 +83,131 @@ void WebPage::platformPreferencesDidChange(const WebPreferencesStore&) { } -bool WebPage::interceptEditingKeyboardEvent(KeyboardEvent* evt, bool shouldSaveCommand) +typedef HashMap<String, String> SelectorNameMap; + +// Map selectors into Editor command names. +// This is not needed for any selectors that have the same name as the Editor command. +static const SelectorNameMap* createSelectorExceptionMap() +{ + SelectorNameMap* map = new HashMap<String, String>; + + map->add("insertNewlineIgnoringFieldEditor:", "InsertNewline"); + map->add("insertParagraphSeparator:", "InsertNewline"); + map->add("insertTabIgnoringFieldEditor:", "InsertTab"); + map->add("pageDown:", "MovePageDown"); + map->add("pageDownAndModifySelection:", "MovePageDownAndModifySelection"); + map->add("pageUp:", "MovePageUp"); + map->add("pageUpAndModifySelection:", "MovePageUpAndModifySelection"); + + return map; +} + +static String commandNameForSelectorName(const String& selectorName) +{ + // Check the exception map first. + static const SelectorNameMap* exceptionMap = createSelectorExceptionMap(); + SelectorNameMap::const_iterator it = exceptionMap->find(selectorName); + if (it != exceptionMap->end()) + return it->second; + + // Remove the trailing colon. + // No need to capitalize the command name since Editor command names are not case sensitive. + size_t selectorNameLength = selectorName.length(); + if (selectorNameLength < 2 || selectorName[selectorNameLength - 1] != ':') + return String(); + return selectorName.left(selectorNameLength - 1); +} + +static Frame* frameForEvent(KeyboardEvent* event) { - Node* node = evt->target()->toNode(); + Node* node = event->target()->toNode(); ASSERT(node); Frame* frame = node->document()->frame(); ASSERT(frame); + return frame; +} + +bool WebPage::executeKeypressCommandsInternal(const Vector<WebCore::KeypressCommand>& commands, KeyboardEvent* event) +{ + Frame* frame = frameForEvent(event); + ASSERT(frame->page() == corePage()); + + bool eventWasHandled = false; + for (size_t i = 0; i < commands.size(); ++i) { + if (commands[i].commandName == "insertText:") { + ASSERT(!frame->editor()->hasComposition()); + + if (!frame->editor()->canEdit()) + continue; + + // An insertText: might be handled by other responders in the chain if we don't handle it. + // One example is space bar that results in scrolling down the page. + eventWasHandled |= frame->editor()->insertText(commands[i].text, event); + } else { + Editor::Command command = frame->editor()->command(commandNameForSelectorName(commands[i].commandName)); + if (command.isSupported()) { + bool commandExecutedByEditor = command.execute(event); + eventWasHandled |= commandExecutedByEditor; + if (!commandExecutedByEditor) { + bool performedNonEditingBehavior = event->keyEvent()->type() == PlatformKeyboardEvent::RawKeyDown && performNonEditingBehaviorForSelector(commands[i].commandName); + eventWasHandled |= performedNonEditingBehavior; + } + } else { + bool commandWasHandledByUIProcess = false; + WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::ExecuteSavedCommandBySelector(commands[i].commandName), + Messages::WebPageProxy::ExecuteSavedCommandBySelector::Reply(commandWasHandledByUIProcess), m_pageID); + eventWasHandled |= commandWasHandledByUIProcess; + } + } + } + return eventWasHandled; +} + +bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* event, bool saveCommands) +{ + ASSERT(!saveCommands || event->keypressCommands().isEmpty()); // Save commands once for each event. + + Frame* frame = frameForEvent(event); - const PlatformKeyboardEvent* keyEvent = evt->keyEvent(); - if (!keyEvent) + const PlatformKeyboardEvent* platformEvent = event->keyEvent(); + if (!platformEvent) return false; - const Vector<KeypressCommand>& commands = evt->keypressCommands(); - bool hasKeypressCommand = !commands.isEmpty(); - + Vector<KeypressCommand>& commands = event->keypressCommands(); + + if ([platformEvent->macEvent() type] == NSFlagsChanged) + return false; + bool eventWasHandled = false; - if (shouldSaveCommand || !hasKeypressCommand) { - Vector<KeypressCommand> commandsList; - Vector<CompositionUnderline> underlines; - unsigned start; - unsigned end; - if (!WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::InterpretKeyEvent(keyEvent->type()), - Messages::WebPageProxy::InterpretKeyEvent::Reply(commandsList, start, end, underlines), - m_pageID, CoreIPC::Connection::NoTimeout)) + if (saveCommands) { + KeyboardEvent* oldEvent = m_keyboardEventBeingInterpreted; + m_keyboardEventBeingInterpreted = event; + bool sendResult = WebProcess::shared().connection()->sendSync(Messages::WebPageProxy::InterpretQueuedKeyEvent(editorState()), + Messages::WebPageProxy::InterpretQueuedKeyEvent::Reply(eventWasHandled, commands), m_pageID); + m_keyboardEventBeingInterpreted = oldEvent; + if (!sendResult) + return false; + + // An input method may make several actions per keypress. For example, pressing Return with Korean IM both confirms it and sends a newline. + // IM-like actions are handled immediately (so the return value from UI process is true), but there are saved commands that + // should be handled like normal text input after DOM event dispatch. + if (!event->keypressCommands().isEmpty()) return false; - if (commandsList.isEmpty()) - return eventWasHandled; - - if (commandsList[0].commandName == "setMarkedText") { - frame->editor()->setComposition(commandsList[0].text, underlines, start, end); - eventWasHandled = true; - } else if (commandsList[0].commandName == "insertText" && frame->editor()->hasComposition()) { - frame->editor()->confirmComposition(commandsList[0].text); - eventWasHandled = true; - } else if (commandsList[0].commandName == "unmarkText") { - frame->editor()->confirmComposition(); - eventWasHandled = true; - } else { - for (size_t i = 0; i < commandsList.size(); i++) - evt->keypressCommands().append(commandsList[i]); - } } else { - size_t size = commands.size(); - // Are there commands that would just cause text insertion if executed via Editor? + // Are there commands that could just cause text insertion if executed via Editor? // WebKit doesn't have enough information about mode to decide how they should be treated, so we leave it upon WebCore // to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated // (e.g. Tab that inserts a Tab character, or Enter). bool haveTextInsertionCommands = false; - for (size_t i = 0; i < size; ++i) { - if (frame->editor()->command(commands[i].commandName).isTextInsertion()) + for (size_t i = 0; i < commands.size(); ++i) { + if (frame->editor()->command(commandNameForSelectorName(commands[i].commandName)).isTextInsertion()) haveTextInsertionCommands = true; } - if (!haveTextInsertionCommands || keyEvent->type() == PlatformKeyboardEvent::Char) { - for (size_t i = 0; i < size; ++i) { - if (commands[i].commandName == "insertText") { - // Don't insert null or control characters as they can result in unexpected behaviour - if (evt->charCode() < ' ') - return false; - eventWasHandled = frame->editor()->insertText(commands[i].text, evt); - } else - if (frame->editor()->command(commands[i].commandName).isSupported()) - eventWasHandled = frame->editor()->command(commands[i].commandName).execute(evt); - } + // If there are no text insertion commands, default keydown handler is the right time to execute the commands. + // Keypress (Char event) handler is the latest opportunity to execute. + if (!haveTextInsertionCommands || platformEvent->type() == PlatformKeyboardEvent::Char) { + eventWasHandled = executeKeypressCommandsInternal(event->keypressCommands(), event); + event->keypressCommands().clear(); } } return eventWasHandled; @@ -152,6 +221,54 @@ void WebPage::sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdenti } } +void WebPage::setComposition(const String& text, Vector<CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, EditorState& newState) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + + if (frame->selection()->isContentEditable()) { + RefPtr<Range> replacementRange; + if (replacementRangeStart != NSNotFound) { + replacementRange = convertToRange(frame, NSMakeRange(replacementRangeStart, replacementRangeEnd - replacementRangeStart)); + frame->selection()->setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY)); + } + + frame->editor()->setComposition(text, underlines, selectionStart, selectionEnd); + } + + newState = editorState(); +} + +void WebPage::confirmComposition(EditorState& newState) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + + frame->editor()->confirmComposition(); + + newState = editorState(); +} + +void WebPage::insertText(const String& text, uint64_t replacementRangeStart, uint64_t replacementRangeEnd, bool& handled, EditorState& newState) +{ + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + + RefPtr<Range> replacementRange; + if (replacementRangeStart != NSNotFound) { + replacementRange = convertToRange(frame, NSMakeRange(replacementRangeStart, replacementRangeEnd - replacementRangeStart)); + frame->selection()->setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY)); + } + + if (!frame->editor()->hasComposition()) { + // An insertText: might be handled by other responders in the chain if we don't handle it. + // One example is space bar that results in scrolling down the page. + handled = frame->editor()->insertText(text, m_keyboardEventBeingInterpreted); + } else { + handled = true; + frame->editor()->confirmComposition(text); + } + + newState = editorState(); +} + void WebPage::getMarkedRange(uint64_t& location, uint64_t& length) { location = NSNotFound; @@ -159,38 +276,59 @@ void WebPage::getMarkedRange(uint64_t& location, uint64_t& length) Frame* frame = m_page->focusController()->focusedOrMainFrame(); if (!frame) return; - - getLocationAndLengthFromRange(frame->editor()->compositionRange().get(), location, length); -} + RefPtr<Range> range = frame->editor()->compositionRange(); + size_t locationSize; + size_t lengthSize; + if (range && TextIterator::locationAndLengthFromRange(range.get(), locationSize, lengthSize)) { + location = static_cast<uint64_t>(locationSize); + length = static_cast<uint64_t>(lengthSize); + } +} -static PassRefPtr<Range> characterRangeAtPositionForPoint(Frame* frame, const VisiblePosition& position, const IntPoint& point) +void WebPage::getSelectedRange(uint64_t& location, uint64_t& length) { - if (position.isNull()) - return 0; + location = NSNotFound; + length = 0; + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; - VisiblePosition previous = position.previous(); - if (previous.isNotNull()) { - RefPtr<Range> previousCharacterRange = makeRange(previous, position); - IntRect rect = frame->editor()->firstRectForRange(previousCharacterRange.get()); - if (rect.contains(point)) - return previousCharacterRange.release(); - } - - VisiblePosition next = position.next(); - if (next.isNotNull()) { - RefPtr<Range> nextCharacterRange = makeRange(position, next); - IntRect rect = frame->editor()->firstRectForRange(nextCharacterRange.get()); - if (rect.contains(point)) - return nextCharacterRange.release(); + size_t locationSize; + size_t lengthSize; + RefPtr<Range> range = frame->selection()->toNormalizedRange(); + if (range && TextIterator::locationAndLengthFromRange(range.get(), locationSize, lengthSize)) { + location = static_cast<uint64_t>(locationSize); + length = static_cast<uint64_t>(lengthSize); } - - return 0; } -static PassRefPtr<Range> characterRangeAtPoint(Frame* frame, const IntPoint& point) +void WebPage::getAttributedSubstringFromRange(uint64_t location, uint64_t length, AttributedString& result) { - return characterRangeAtPositionForPoint(frame, frame->visiblePositionForPoint(point), point); + NSRange nsRange = NSMakeRange(location, length - location); + + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; + + if (frame->selection()->isNone() || !frame->selection()->isContentEditable() || frame->selection()->isInPasswordField()) + return; + + RefPtr<Range> range = convertToRange(frame, nsRange); + if (!range) + return; + + result.string = [WebHTMLConverter editingAttributedStringFromRange:range.get()]; + NSAttributedString* attributedString = result.string.get(); + + // [WebHTMLConverter editingAttributedStringFromRange:] insists on inserting a trailing + // whitespace at the end of the string which breaks the ATOK input method. <rdar://problem/5400551> + // To work around this we truncate the resultant string to the correct length. + if ([attributedString length] > nsRange.length) { + ASSERT([attributedString length] == nsRange.length + 1); + ASSERT([[attributedString string] characterAtIndex:nsRange.length] == '\n' || [[attributedString string] characterAtIndex:nsRange.length] == ' '); + result.string = [attributedString attributedSubstringFromRange:NSMakeRange(0, nsRange.length)]; + } } void WebPage::characterIndexForPoint(IntPoint point, uint64_t& index) @@ -203,15 +341,17 @@ void WebPage::characterIndexForPoint(IntPoint point, uint64_t& index) HitTestResult result = frame->eventHandler()->hitTestResultAtPoint(point, false); frame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document()->frame() : m_page->focusController()->focusedOrMainFrame(); - RefPtr<Range> range = characterRangeAtPoint(frame, result.point()); + RefPtr<Range> range = frame->rangeForPoint(result.point()); if (!range) return; - uint64_t length; - getLocationAndLengthFromRange(range.get(), index, length); + size_t location; + size_t length; + if (TextIterator::locationAndLengthFromRange(range.get(), location, length)) + index = static_cast<uint64_t>(location); } -static PassRefPtr<Range> convertToRange(Frame* frame, NSRange nsrange) +PassRefPtr<Range> convertToRange(Frame* frame, NSRange nsrange) { if (nsrange.location > INT_MAX) return 0; @@ -246,6 +386,12 @@ void WebPage::firstRectForCharacterRange(uint64_t location, uint64_t length, Web resultRect = frame->view()->contentsToWindow(rect); } +void WebPage::executeKeypressCommands(const Vector<WebCore::KeypressCommand>& commands, bool& handled, EditorState& newState) +{ + handled = executeKeypressCommandsInternal(commands, m_keyboardEventBeingInterpreted); + newState = editorState(); +} + static bool isPositionInRange(const VisiblePosition& position, Range* range) { RefPtr<Range> positionRange = makeRange(position, position); @@ -284,12 +430,12 @@ void WebPage::performDictionaryLookupAtLocation(const FloatPoint& floatPoint) frame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document()->frame() : m_page->focusController()->focusedOrMainFrame(); IntPoint translatedPoint = frame->view()->windowToContents(point); - VisiblePosition position = frame->visiblePositionForPoint(translatedPoint); // Don't do anything if there is no character at the point. - if (!characterRangeAtPositionForPoint(frame, position, translatedPoint)) + if (!frame->rangeForPoint(translatedPoint)) return; + VisiblePosition position = frame->visiblePositionForPoint(translatedPoint); VisibleSelection selection = m_page->focusController()->focusedOrMainFrame()->selection()->selection(); if (shouldUseSelection(position, selection)) { performDictionaryLookupForSelection(DictionaryPopupInfo::HotKey, frame, selection); @@ -378,96 +524,54 @@ void WebPage::performDictionaryLookupForRange(DictionaryPopupInfo::Type type, Fr dictionaryPopupInfo.type = type; dictionaryPopupInfo.origin = FloatPoint(rangeRect.x(), rangeRect.y()); dictionaryPopupInfo.fontInfo.fontAttributeDictionary = fontDescriptorAttributes; +#if !defined(BUILDING_ON_SNOW_LEOPARD) dictionaryPopupInfo.options = (CFDictionaryRef)options; +#endif send(Messages::WebPageProxy::DidPerformDictionaryLookup(rangeText, dictionaryPopupInfo)); } -bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent) +bool WebPage::performNonEditingBehaviorForSelector(const String& selector) { - if (keyboardEvent.type() != WebEvent::KeyDown) - return false; - - // FIXME: This should be in WebCore. - - switch (keyboardEvent.windowsVirtualKeyCode()) { - case VK_BACK: - if (keyboardEvent.shiftKey()) - m_page->goForward(); - else - m_page->goBack(); - break; - case VK_SPACE: - if (keyboardEvent.shiftKey()) - logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage); - else - logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage); - break; - case VK_PRIOR: - logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByPage); - break; - case VK_NEXT: - logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByPage); - break; - case VK_HOME: - logicalScroll(m_page.get(), ScrollBlockDirectionBackward, ScrollByDocument); - break; - case VK_END: - logicalScroll(m_page.get(), ScrollBlockDirectionForward, ScrollByDocument); - break; - case VK_UP: - if (keyboardEvent.shiftKey()) - return false; - if (keyboardEvent.metaKey()) { - scroll(m_page.get(), ScrollUp, ScrollByDocument); - scroll(m_page.get(), ScrollLeft, ScrollByDocument); - } else if (keyboardEvent.altKey() || keyboardEvent.controlKey()) - scroll(m_page.get(), ScrollUp, ScrollByPage); - else - scroll(m_page.get(), ScrollUp, ScrollByLine); - break; - case VK_DOWN: - if (keyboardEvent.shiftKey()) - return false; - if (keyboardEvent.metaKey()) { - scroll(m_page.get(), ScrollDown, ScrollByDocument); - scroll(m_page.get(), ScrollLeft, ScrollByDocument); - } else if (keyboardEvent.altKey() || keyboardEvent.controlKey()) - scroll(m_page.get(), ScrollDown, ScrollByPage); - else - scroll(m_page.get(), ScrollDown, ScrollByLine); - break; - case VK_LEFT: - if (keyboardEvent.shiftKey()) - return false; - if (keyboardEvent.metaKey()) - m_page->goBack(); - else { - if (keyboardEvent.altKey() || keyboardEvent.controlKey()) - scroll(m_page.get(), ScrollLeft, ScrollByPage); - else - scroll(m_page.get(), ScrollLeft, ScrollByLine); - } - break; - case VK_RIGHT: - if (keyboardEvent.shiftKey()) - return false; - if (keyboardEvent.metaKey()) - m_page->goForward(); - else { - if (keyboardEvent.altKey() || keyboardEvent.controlKey()) - scroll(m_page.get(), ScrollRight, ScrollByPage); - else - scroll(m_page.get(), ScrollRight, ScrollByLine); - } - break; - default: + // FIXME: All these selectors have corresponding Editor commands, but the commands only work in editable content. + // Should such non-editing behaviors be implemented in Editor or EventHandler::defaultArrowEventHandler() perhaps? + if (selector == "moveUp:") + scroll(m_page.get(), ScrollUp, ScrollByLine); + else if (selector == "moveToBeginningOfParagraph:") + scroll(m_page.get(), ScrollUp, ScrollByPage); + else if (selector == "moveToBeginningOfDocument:") { + scroll(m_page.get(), ScrollUp, ScrollByDocument); + scroll(m_page.get(), ScrollLeft, ScrollByDocument); + } else if (selector == "moveDown:") + scroll(m_page.get(), ScrollDown, ScrollByLine); + else if (selector == "moveToEndOfParagraph:") + scroll(m_page.get(), ScrollDown, ScrollByPage); + else if (selector == "moveToEndOfDocument:") { + scroll(m_page.get(), ScrollDown, ScrollByDocument); + scroll(m_page.get(), ScrollLeft, ScrollByDocument); + } else if (selector == "moveLeft:") + scroll(m_page.get(), ScrollLeft, ScrollByLine); + else if (selector == "moveWordLeft:") + scroll(m_page.get(), ScrollLeft, ScrollByPage); + else if (selector == "moveToLeftEndOfLine:") + m_page->goBack(); + else if (selector == "moveRight:") + scroll(m_page.get(), ScrollRight, ScrollByLine); + else if (selector == "moveWordRight:") + scroll(m_page.get(), ScrollRight, ScrollByPage); + else if (selector == "moveToRightEndOfLine:") + m_page->goForward(); + else return false; - } return true; } +bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent&) +{ + return false; +} + void WebPage::registerUIProcessAccessibilityTokens(const CoreIPC::DataReference& elementToken, const CoreIPC::DataReference& windowToken) { #if !defined(BUILDING_ON_SNOW_LEOPARD) @@ -484,6 +588,10 @@ void WebPage::registerUIProcessAccessibilityTokens(const CoreIPC::DataReference& void WebPage::writeSelectionToPasteboard(const String& pasteboardName, const Vector<String>& pasteboardTypes, bool& result) { Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame || frame->selection()->isNone()) { + result = false; + return; + } frame->editor()->writeSelectionToPasteboard(pasteboardName, pasteboardTypes); result = true; } @@ -491,6 +599,10 @@ void WebPage::writeSelectionToPasteboard(const String& pasteboardName, const Vec void WebPage::readSelectionFromPasteboard(const String& pasteboardName, bool& result) { Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame || frame->selection()->isNone()) { + result = false; + return; + } frame->editor()->readSelectionFromPasteboard(pasteboardName); result = true; } @@ -548,10 +660,39 @@ void WebPage::setDragSource(NSObject *dragSource) void WebPage::platformDragEnded() { + // The draggedImage method releases its responder; we retain here to balance that. + [m_dragSource.get() retain]; // The drag source we care about here is NSFilePromiseDragSource, which doesn't look at // the arguments. It's OK to just pass arbitrary constant values, so we just pass all zeroes. [m_dragSource.get() draggedImage:nil endedAt:NSZeroPoint operation:NSDragOperationNone]; m_dragSource = nullptr; } +void WebPage::shouldDelayWindowOrderingEvent(const WebKit::WebMouseEvent& event, bool& result) +{ + result = false; + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; + + HitTestResult hitResult = frame->eventHandler()->hitTestResultAtPoint(event.position(), true); + if (hitResult.isSelected()) + result = frame->eventHandler()->eventMayStartDrag(platform(event)); +} + +void WebPage::acceptsFirstMouse(int eventNumber, const WebKit::WebMouseEvent& event, bool& result) +{ + result = false; + Frame* frame = m_page->focusController()->focusedOrMainFrame(); + if (!frame) + return; + + HitTestResult hitResult = frame->eventHandler()->hitTestResultAtPoint(event.position(), true); + frame->eventHandler()->setActivationEventNumber(eventNumber); + if (hitResult.isSelected()) + result = frame->eventHandler()->eventMayStartDrag(platform(event)); + else + result = !!hitResult.scrollbar(); +} + } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/win/LayerTreeHostWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/LayerTreeHostWin.cpp new file mode 100644 index 0000000..57c04bb --- /dev/null +++ b/Source/WebKit2/WebProcess/WebPage/win/LayerTreeHostWin.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * 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. + */ + +#include "config.h" +#include "LayerTreeHost.h" + +#if USE(CA) +#include "LayerTreeHostCAWin.h" +#endif + +namespace WebKit { + +bool LayerTreeHost::supportsAcceleratedCompositing() +{ +#if USE(CA) && HAVE(WKQCA) + return LayerTreeHostCAWin::supportsAcceleratedCompositing(); +#else + return false; +#endif +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp b/Source/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp index 41bb219..9c7206a 100644 --- a/Source/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp +++ b/Source/WebKit2/WebProcess/WebPage/win/WebPageWin.cpp @@ -28,17 +28,22 @@ #include "FontSmoothingLevel.h" #include "WebEvent.h" +#include "WebPageProxyMessages.h" #include "WebPreferencesStore.h" #include <WebCore/FocusController.h> #include <WebCore/FontRenderingMode.h> #include <WebCore/Frame.h> #include <WebCore/FrameView.h> +#include <WebCore/HitTestRequest.h> +#include <WebCore/HitTestResult.h> #include <WebCore/KeyboardEvent.h> #include <WebCore/Page.h> #include <WebCore/PlatformKeyboardEvent.h> +#include <WebCore/RenderLayer.h> +#include <WebCore/RenderView.h> #include <WebCore/ResourceHandle.h> #include <WebCore/Settings.h> -#if PLATFORM(CG) +#if USE(CG) #include <WebKitSystemInterface/WebKitSystemInterface.h> #endif #include <WinUser.h> @@ -62,7 +67,7 @@ void WebPage::platformPreferencesDidChange(const WebPreferencesStore& store) { FontSmoothingLevel fontSmoothingLevel = static_cast<FontSmoothingLevel>(store.getUInt32ValueForKey(WebPreferencesKey::fontSmoothingLevelKey())); -#if PLATFORM(CG) +#if USE(CG) FontSmoothingLevel adjustedLevel = fontSmoothingLevel; if (adjustedLevel == FontSmoothingLevelWindows) adjustedLevel = FontSmoothingLevelMedium; @@ -351,4 +356,89 @@ void WebPage::getSelectedText(String& text) text = selectedRange->text(); } +void WebPage::gestureWillBegin(const WebCore::IntPoint& point, bool& canBeginPanning) +{ + m_gestureReachedScrollingLimit = false; + + bool hitScrollbar = false; + + HitTestRequest request(HitTestRequest::ReadOnly); + for (Frame* childFrame = m_page->mainFrame(); childFrame; childFrame = EventHandler::subframeForTargetNode(m_gestureTargetNode.get())) { + ScrollView* scollView = childFrame->view(); + if (!scollView) + break; + + RenderView* renderView = childFrame->document()->renderView(); + if (!renderView) + break; + + RenderLayer* layer = renderView->layer(); + if (!layer) + break; + + HitTestResult result = scollView->windowToContents(point); + layer->hitTest(request, result); + m_gestureTargetNode = result.innerNode(); + + if (!hitScrollbar) + hitScrollbar = result.scrollbar(); + } + + if (hitScrollbar) { + canBeginPanning = false; + return; + } + + if (!m_gestureTargetNode) { + canBeginPanning = false; + return; + } + + for (RenderObject* renderer = m_gestureTargetNode->renderer(); renderer; renderer = renderer->parent()) { + if (renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()) { + canBeginPanning = true; + return; + } + } + + canBeginPanning = false; +} + +static bool scrollbarAtTopOrBottomOfDocument(Scrollbar* scrollbar) +{ + ASSERT_ARG(scrollbar, scrollbar); + return !scrollbar->currentPos() || scrollbar->currentPos() >= scrollbar->maximum(); +} + +void WebPage::gestureDidScroll(const IntSize& size) +{ + ASSERT_ARG(size, !size.isZero()); + + if (!m_gestureTargetNode || !m_gestureTargetNode->renderer() || !m_gestureTargetNode->renderer()->enclosingLayer()) + return; + + Scrollbar* verticalScrollbar = 0; + if (Frame* frame = m_page->mainFrame()) { + if (ScrollView* view = frame->view()) + verticalScrollbar = view->verticalScrollbar(); + } + + m_gestureTargetNode->renderer()->enclosingLayer()->scrollByRecursively(size.width(), size.height()); + bool gestureReachedScrollingLimit = verticalScrollbar && scrollbarAtTopOrBottomOfDocument(verticalScrollbar); + + // FIXME: We really only want to update this state if the state was updated via scrolling the main frame, + // not scrolling something in a main frame when the main frame had already reached its scrolling limit. + + if (gestureReachedScrollingLimit == m_gestureReachedScrollingLimit) + return; + + send(Messages::WebPageProxy::SetGestureReachedScrollingLimit(gestureReachedScrollingLimit)); + m_gestureReachedScrollingLimit = gestureReachedScrollingLimit; +} + +void WebPage::gestureDidEnd() +{ + m_gestureTargetNode = nullptr; +} + } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebProcess.cpp b/Source/WebKit2/WebProcess/WebProcess.cpp index ba3290b..20bd6e3 100644 --- a/Source/WebKit2/WebProcess/WebProcess.cpp +++ b/Source/WebKit2/WebProcess/WebProcess.cpp @@ -59,6 +59,7 @@ #include <WebCore/Logging.h> #include <WebCore/MemoryCache.h> #include <WebCore/Page.h> +#include <WebCore/PageCache.h> #include <WebCore/PageGroup.h> #include <WebCore/ResourceHandle.h> #include <WebCore/SchemeRegistry.h> @@ -69,7 +70,6 @@ #include <wtf/RandomNumber.h> #ifndef NDEBUG -#include <WebCore/MemoryCache.h> #include <WebCore/GCController.h> #endif @@ -117,8 +117,11 @@ WebProcess& WebProcess::shared() return process; } +static const double shutdownTimeout = 60; + WebProcess::WebProcess() - : m_inDidClose(false) + : ChildProcess(shutdownTimeout) + , m_inDidClose(false) , m_hasSetCacheModel(false) , m_cacheModel(CacheModelDocumentViewer) #if USE(ACCELERATED_COMPOSITING) && PLATFORM(MAC) @@ -145,6 +148,7 @@ void WebProcess::initialize(CoreIPC::Connection::Identifier serverIdentifier, Ru m_connection = CoreIPC::Connection::createClientConnection(serverIdentifier, this, runLoop); m_connection->setDidCloseOnConnectionWorkQueueCallback(didCloseOnConnectionWorkQueue); + m_connection->setShouldExitOnSyncMessageSendFailure(true); m_connection->open(); @@ -214,11 +218,6 @@ void WebProcess::initializeWebProcess(const WebProcessCreationParameters& parame for (size_t i = 0; i < parameters.mimeTypesWithCustomRepresentation.size(); ++i) m_mimeTypesWithCustomRepresentations.add(parameters.mimeTypesWithCustomRepresentation[i]); - - if (parameters.clearResourceCaches) - clearResourceCaches(); - if (parameters.clearApplicationCache) - clearApplicationCache(); #if PLATFORM(MAC) m_presenterApplicationPid = parameters.presenterApplicationPid; @@ -276,20 +275,28 @@ void WebProcess::setVisitedLinkTable(const SharedMemory::Handle& handle) m_visitedLinkTable.setSharedMemory(sharedMemory.release()); } -PageGroup* WebProcess::sharedPageGroup() -{ - return PageGroup::pageGroup("WebKit2Group"); -} - void WebProcess::visitedLinkStateChanged(const Vector<WebCore::LinkHash>& linkHashes) { - for (size_t i = 0; i < linkHashes.size(); ++i) - Page::visitedStateChanged(sharedPageGroup(), linkHashes[i]); + // FIXME: We may want to track visited links per WebPageGroup rather than per WebContext. + for (size_t i = 0; i < linkHashes.size(); ++i) { + HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator it = m_pageGroupMap.begin(); + HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator end = m_pageGroupMap.end(); + for (; it != end; ++it) + Page::visitedStateChanged(PageGroup::pageGroup(it->second->identifier()), linkHashes[i]); + } + + pageCache()->markPagesForVistedLinkStyleRecalc(); } void WebProcess::allVisitedLinkStateChanged() { - Page::allVisitedStateChanged(sharedPageGroup()); + // FIXME: We may want to track visited links per WebPageGroup rather than per WebContext. + HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator it = m_pageGroupMap.begin(); + HashMap<uint64_t, RefPtr<WebPageGroupProxy> >::const_iterator end = m_pageGroupMap.end(); + for (; it != end; ++it) + Page::allVisitedStateChanged(PageGroup::pageGroup(it->second->identifier())); + + pageCache()->markPagesForVistedLinkStyleRecalc(); } bool WebProcess::isLinkVisited(LinkHash linkHash) const @@ -490,6 +497,9 @@ void WebProcess::createWebPage(uint64_t pageID, const WebPageCreationParameters& if (result.second) { ASSERT(!result.first->second); result.first->second = WebPage::create(pageID, parameters); + + // Balanced by an enableTermination in removeWebPage. + disableTermination(); } ASSERT(result.first->second); @@ -497,8 +507,11 @@ void WebProcess::createWebPage(uint64_t pageID, const WebPageCreationParameters& void WebProcess::removeWebPage(uint64_t pageID) { + ASSERT(m_pageMap.contains(pageID)); + m_pageMap.remove(pageID); - terminateIfPossible(); + + enableTermination(); } bool WebProcess::isSeparateProcess() const @@ -507,29 +520,26 @@ bool WebProcess::isSeparateProcess() const return m_runLoop == RunLoop::main(); } -void WebProcess::terminateIfPossible() +bool WebProcess::shouldTerminate() { - if (!m_pageMap.isEmpty()) - return; - - if (m_inDidClose) - return; - - if (DownloadManager::shared().isDownloading()) - return; - // Keep running forever if we're running in the same process. if (!isSeparateProcess()) - return; + return false; + + ASSERT(m_pageMap.isEmpty()); + ASSERT(!DownloadManager::shared().isDownloading()); // FIXME: the ShouldTerminate message should also send termination parameters, such as any session cookies that need to be preserved. bool shouldTerminate = false; if (m_connection->sendSync(Messages::WebProcessProxy::ShouldTerminate(), Messages::WebProcessProxy::ShouldTerminate::Reply(shouldTerminate), 0) && !shouldTerminate) - return; + return false; - // Actually terminate the process. + return true; +} +void WebProcess::terminate() +{ #ifndef NDEBUG gcController().garbageCollectNow(); memoryCache()->setDisabled(true); @@ -656,11 +666,8 @@ void WebProcess::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::Message // we'll let it slide. } -NO_RETURN void WebProcess::didFailToSendSyncMessage(CoreIPC::Connection*) +void WebProcess::syncMessageSendTimedOut(CoreIPC::Connection*) { - // We were making a synchronous call to a UI process that doesn't exist any more. - // Callers are unlikely to be prepared for an error like this, so it's best to exit immediately. - exit(0); } WebFrame* WebProcess::webFrame(uint64_t frameID) const @@ -702,10 +709,8 @@ WebPageGroupProxy* WebProcess::webPageGroup(const WebPageGroupData& pageGroupDat return result.first->second.get(); } -void WebProcess::clearResourceCaches(uint32_t cachesToClear) +void WebProcess::clearResourceCaches(ResourceCachesToClear resourceCachesToClear) { - ResourceCachesToClear resourceCachesToClear = static_cast<ResourceCachesToClear>(cachesToClear); - platformClearResourceCaches(resourceCachesToClear); // Toggling the cache model like this forces the cache to evict all its in-memory resources. @@ -731,6 +736,8 @@ void WebProcess::clearApplicationCache() #if !ENABLE(PLUGIN_PROCESS) void WebProcess::getSitesWithPluginData(const Vector<String>& pluginPaths, uint64_t callbackID) { + LocalTerminationDisabler terminationDisabler(*this); + HashSet<String> sitesSet; for (size_t i = 0; i < pluginPaths.size(); ++i) { @@ -747,11 +754,12 @@ void WebProcess::getSitesWithPluginData(const Vector<String>& pluginPaths, uint6 copyToVector(sitesSet, sites); m_connection->send(Messages::WebContext::DidGetSitesWithPluginData(sites, callbackID), 0); - terminateIfPossible(); } void WebProcess::clearPluginSiteData(const Vector<String>& pluginPaths, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) { + LocalTerminationDisabler terminationDisabler(*this); + for (size_t i = 0; i < pluginPaths.size(); ++i) { RefPtr<NetscapePluginModule> netscapePluginModule = NetscapePluginModule::getOrCreate(pluginPaths[i]); if (!netscapePluginModule) @@ -768,7 +776,6 @@ void WebProcess::clearPluginSiteData(const Vector<String>& pluginPaths, const Ve } m_connection->send(Messages::WebContext::DidClearPluginSiteData(callbackID), 0); - terminateIfPossible(); } #endif @@ -805,7 +812,22 @@ void WebProcess::stopMemorySampler() void WebProcess::setTextCheckerState(const TextCheckerState& textCheckerState) { + bool continuousSpellCheckingTurnedOff = !textCheckerState.isContinuousSpellCheckingEnabled && m_textCheckerState.isContinuousSpellCheckingEnabled; + bool grammarCheckingTurnedOff = !textCheckerState.isGrammarCheckingEnabled && m_textCheckerState.isGrammarCheckingEnabled; + m_textCheckerState = textCheckerState; + + if (!continuousSpellCheckingTurnedOff && !grammarCheckingTurnedOff) + return; + + HashMap<uint64_t, RefPtr<WebPage> >::iterator end = m_pageMap.end(); + for (HashMap<uint64_t, RefPtr<WebPage> >::iterator it = m_pageMap.begin(); it != end; ++it) { + WebPage* page = (*it).second.get(); + if (continuousSpellCheckingTurnedOff) + page->unmarkAllMisspellings(); + if (grammarCheckingTurnedOff) + page->unmarkAllBadGrammar(); + } } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/WebProcess.h b/Source/WebKit2/WebProcess/WebProcess.h index d666910..e57fb3f 100644 --- a/Source/WebKit2/WebProcess/WebProcess.h +++ b/Source/WebKit2/WebProcess/WebProcess.h @@ -66,7 +66,7 @@ struct WebPageGroupData; struct WebPreferencesStore; struct WebProcessCreationParameters; -class WebProcess : ChildProcess { +class WebProcess : public ChildProcess { public: static WebProcess& shared(); @@ -99,7 +99,6 @@ public: WebPageGroupProxy* webPageGroup(uint64_t pageGroupID); WebPageGroupProxy* webPageGroup(const WebPageGroupData&); - static WebCore::PageGroup* sharedPageGroup(); #if PLATFORM(MAC) pid_t presenterApplicationPid() const { return m_presenterApplicationPid; } #endif @@ -108,9 +107,6 @@ public: QNetworkAccessManager* networkAccessManager() { return m_networkAccessManager; } #endif - // Will terminate the web process if there are no live pages or downloads. - void terminateIfPossible(); - bool shouldUseCustomRepresentationForMIMEType(const String& mimeType) const { return m_mimeTypesWithCustomRepresentations.contains(mimeType); } // Text Checking @@ -119,7 +115,7 @@ public: // Geolocation WebGeolocationManager& geolocationManager() { return m_geolocationManager; } - void clearResourceCaches(uint32_t cachesToClear = AllResourceCaches); + void clearResourceCaches(ResourceCachesToClear = AllResourceCaches); const String& localStorageDirectory() const { return m_localStorageDirectory; } @@ -167,12 +163,20 @@ private: void setTextCheckerState(const TextCheckerState&); + // ChildProcess + virtual bool shouldTerminate(); + virtual void terminate(); + // CoreIPC::Connection::Client - void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); - CoreIPC::SyncReplyMode didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder*); - void didClose(CoreIPC::Connection*); - void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID); - NO_RETURN void didFailToSendSyncMessage(CoreIPC::Connection*); + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + virtual CoreIPC::SyncReplyMode didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, CoreIPC::ArgumentEncoder*); + virtual void didClose(CoreIPC::Connection*); + virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID); + virtual void syncMessageSendTimedOut(CoreIPC::Connection*); + +#if PLATFORM(WIN) + Vector<HWND> windowsToReceiveSentMessagesWhileWaitingForSyncReply(); +#endif // Implemented in generated WebProcessMessageReceiver.cpp void didReceiveWebProcessMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); diff --git a/Source/WebKit2/WebProcess/WebProcess.messages.in b/Source/WebKit2/WebProcess/WebProcess.messages.in index 36155a7..f50c979 100644 --- a/Source/WebKit2/WebProcess/WebProcess.messages.in +++ b/Source/WebKit2/WebProcess/WebProcess.messages.in @@ -50,16 +50,13 @@ messages -> WebProcess { GetSitesWithPluginData(Vector<WTF::String> pluginPaths, uint64_t callbackID) ClearPluginSiteData(Vector<WTF::String> pluginPaths, Vector<WTF::String> sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) #endif - - ClearResourceCaches(uint32_t cachesToClear); - ClearApplicationCache(); void StartMemorySampler(WebKit::SandboxExtension::Handle sampleLogFileHandle, WTF::String sampleLogFilePath, double interval); void StopMemorySampler(); # Downloads. This should really be in a Download.messages.in, but it seemed unnecessary to create a new file just for # two messages. - void DownloadRequest(uint64_t downloadID, uint64_t initiatingPageID, WebCore::ResourceRequest request) + DownloadRequest(uint64_t downloadID, uint64_t initiatingPageID, WebCore::ResourceRequest request) CancelDownload(uint64_t downloadID) SetTextCheckerState(WebKit::TextCheckerState textCheckerState) diff --git a/Source/WebKit2/WebProcess/com.apple.WebProcess.sb b/Source/WebKit2/WebProcess/com.apple.WebProcess.sb index fa81666..f4958d5 100644 --- a/Source/WebKit2/WebProcess/com.apple.WebProcess.sb +++ b/Source/WebKit2/WebProcess/com.apple.WebProcess.sb @@ -11,6 +11,7 @@ ;; Read-only preferences and data (allow file-read* ;; Basic system paths + (subpath "/Library/Dictionaries") (subpath "/Library/Fonts") (subpath "/Library/Frameworks") (subpath "/Library/Keychains") @@ -46,6 +47,28 @@ ;; FIXME: This should be removed when <rdar://problem/8957845> is fixed. (subpath (string-append (param "HOME_DIR") "/Library/Fonts")) + ;; FIXME: These should be removed when <rdar://problem/9217757> is fixed. + (subpath (string-append (param "HOME_DIR") "/Library/Audio/Plug-Ins/Components")) + (subpath (string-append (param "HOME_DIR") "/Library/Preferences/QuickTime Preferences")) + (subpath "/Library/Audio/Plug-Ins/Components") + (subpath "/Library/Audio/Plug-Ins/HAL") + (subpath "/Library/Video/Plug-Ins") + (subpath "/Library/QuickTime") + + ;; FIXME: This should be removed when <rdar://problem/9237619> is fixed. + (literal (string-append (param "HOME_DIR") "/Library/Preferences/com.apple.universalaccess.plist")) + + ;; FIXME: This should be removed when <rdar://problem/9276253> is fixed. + (subpath (string-append (param "HOME_DIR") "/Library/Keyboard Layouts")) + + ;; FIXME: This should be removed when <rdar://problem/9276268> is fixed. + (subpath (string-append (param "HOME_DIR") "/Library/Input Methods")) + + ;; FIXME: This should be removed when <rdar://problem/9276430> is fixed. + (literal (string-append (param "HOME_DIR") "/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV2")) + + (subpath (string-append (param "HOME_DIR") "/Library/Dictionaries")) + ;; Extensions from UIProcess (extension) ) @@ -61,6 +84,9 @@ (regex (string-append "^" (param "HOME_DIR") "/Library/Preferences/ByHost/com\.apple\.HIToolbox\.")) (regex (string-append "^" (param "HOME_DIR") "/Library/Preferences/com\.apple\.WebProcess\.")) (subpath (string-append (param "HOME_DIR") "/Library/Keychains")) + + ;; FIXME: This should be removed when <rdar://problem/9217757> is fixed. + (literal (string-append (param "HOME_DIR") "/Library/Caches/com.apple.coreaudio.components.plist")) ) ;; Darwin temporary files and caches, if present @@ -94,57 +120,45 @@ ;; Various services required by AppKit and other frameworks (allow mach-lookup - (global-name "com.apple.CoreServices.coreservicesd") - (global-name "com.apple.DiskArbitration.diskarbitrationd") - (global-name "com.apple.FileCoordination") - (global-name "com.apple.FontObjectsServer") - (global-name "com.apple.FontServer") - (global-name "com.apple.SecurityServer") - (global-name "com.apple.SystemConfiguration.configd") - (global-name "com.apple.audio.VDCAssistant") - (global-name "com.apple.audio.audiohald") - (global-name "com.apple.audio.coreaudiod") - (global-name "com.apple.cookied") - (global-name "com.apple.cvmsServ") - (global-name "com.apple.dock.server") - (global-name "com.apple.ocspd") - (global-name "com.apple.pasteboard.1") - (global-name "com.apple.system.opendirectoryd.api") - (global-name "com.apple.window_proxies") - (global-name "com.apple.windowserver.active") - (global-name-regex #"^com\.apple\.WebKit\.WebProcess-") - (global-name-regex #"^com\.apple\.qtkitserver\.") + (global-name "com.apple.CoreServices.coreservicesd") + (global-name "com.apple.DiskArbitration.diskarbitrationd") + (global-name "com.apple.FileCoordination") + (global-name "com.apple.FontObjectsServer") + (global-name "com.apple.FontServer") + (global-name "com.apple.SecurityServer") + (global-name "com.apple.SystemConfiguration.configd") + (global-name "com.apple.audio.VDCAssistant") + (global-name "com.apple.audio.audiohald") + (global-name "com.apple.audio.coreaudiod") + (global-name "com.apple.cookied") + (global-name "com.apple.cvmsServ") + (global-name "com.apple.networkd") + (global-name "com.apple.dock.server") + (global-name "com.apple.ocspd") + (global-name "com.apple.pasteboard.1") + (global-name "com.apple.system.opendirectoryd.api") + (global-name "com.apple.window_proxies") + (global-name "com.apple.windowserver.active") + (global-name-regex #"^com\.apple\.WebKit\.WebProcess-") + (global-name-regex #"^com\.apple\.qtkitserver\.") + + ;; FIXME: This should be removed when <rdar://problem/9276393> is fixed. + (global-name "com.apple.metadata.mds") ) -;; FIXME: These rules are required until <rdar://problem/8448410> is addressed. See <rdar://problem/8349882> for discussion. +;; FIXME: <rdar://problem/9263428> These rules are required to avoid +;; sandbox violation spam, but some narrower rule should be +;; sufficient. (allow network-outbound) (deny network-outbound (regex "")) (deny network-outbound (local ip)) + (allow network-outbound ;; Local mDNSResponder for DNS, arbitrary outbound TCP (literal "/private/var/run/mDNSResponder") (remote tcp) ) -;; FIXME: These rules are required until plug-ins are moved out of the web process. -(allow file-read* - (regex (string-append "^" (param "HOME_DIR") "/Library/Preferences/ByHost/com\.apple\.ist\.")) - (literal (string-append (param "HOME_DIR") "/Library/Preferences/edu.mit.Kerberos")) - (literal "/Library/Preferences/edu.mit.Kerberos") -) - -(allow mach-lookup - (global-name "org.h5l.kcm") - (global-name "com.apple.tsm.uiserver") - (global-name-regex #"^com\.apple\.ist") -) - -(allow network-outbound (remote ip)) - -;; These rules are required while QTKitServer is being launched directly via posix_spawn (<rdar://problem/6912494>). -(allow process-fork) -(allow process-exec (literal "/System/Library/Frameworks/QTKit.framework/Versions/A/Resources/QTKitServer") (with no-sandbox)) - ;; FIXME: Once <rdar://problem/8900275> has been fixed, these rules can be removed. (allow mach-lookup (global-name "com.apple.pubsub.ipc")) (allow network-outbound (regex #"^/private/tmp/launch-[^/]+/Render")) diff --git a/Source/WebKit2/WebProcess/mac/WebProcessMac.mm b/Source/WebKit2/WebProcess/mac/WebProcessMac.mm index 88ef834..4c23daf 100644 --- a/Source/WebKit2/WebProcess/mac/WebProcessMac.mm +++ b/Source/WebKit2/WebProcess/mac/WebProcessMac.mm @@ -30,6 +30,7 @@ #import "SandboxExtension.h" #import "WebPage.h" #import "WebProcessCreationParameters.h" +#import <WebCore/FileSystem.h> #import <WebCore/MemoryCache.h> #import <WebCore/PageCache.h> #import <WebKitSystemInterface.h> @@ -122,7 +123,7 @@ bool WebProcess::fullKeyboardAccessEnabled() } #if ENABLE(WEB_PROCESS_SANDBOX) -static void appendSandboxParameterPath(Vector<const char*>& vector, const char* name, const char* path) +static void appendSandboxParameterPathInternal(Vector<const char*>& vector, const char* name, const char* path) { char normalizedPath[PATH_MAX]; if (!realpath(path, normalizedPath)) @@ -132,14 +133,31 @@ static void appendSandboxParameterPath(Vector<const char*>& vector, const char* vector.append(fastStrDup(normalizedPath)); } -static void appendSandboxParameterConfPath(Vector<const char*>& vector, const char* name, int confID) +static void appendReadwriteConfDirectory(Vector<const char*>& vector, const char* name, int confID) { char path[PATH_MAX]; if (confstr(confID, path, PATH_MAX) <= 0) path[0] = '\0'; - appendSandboxParameterPath(vector, name, path); + appendSandboxParameterPathInternal(vector, name, path); } + +static void appendReadonlySandboxDirectory(Vector<const char*>& vector, const char* name, NSString *path) +{ + appendSandboxParameterPathInternal(vector, name, [(NSString *)path fileSystemRepresentation]); +} + +static void appendReadwriteSandboxDirectory(Vector<const char*>& vector, const char* name, NSString *path) +{ + NSError *error = nil; + + // This is very unlikely to fail, but in case it actually happens, we'd like some sort of output in the console. + if (![[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]) + NSLog(@"could not create \"%@\", error %@", path, error); + + appendSandboxParameterPathInternal(vector, name, [(NSString *)path fileSystemRepresentation]); +} + #endif static void initializeSandbox(const WebProcessCreationParameters& parameters) @@ -152,14 +170,20 @@ static void initializeSandbox(const WebProcessCreationParameters& parameters) Vector<const char*> sandboxParameters; - appendSandboxParameterPath(sandboxParameters, "HOME_DIR", [NSHomeDirectory() fileSystemRepresentation]); - appendSandboxParameterPath(sandboxParameters, "WEBKIT2_FRAMEWORK_DIR", [[[[NSBundle bundleForClass:NSClassFromString(@"WKView")] bundlePath] stringByDeletingLastPathComponent] fileSystemRepresentation]); - appendSandboxParameterConfPath(sandboxParameters, "DARWIN_USER_TEMP_DIR", _CS_DARWIN_USER_TEMP_DIR); - appendSandboxParameterConfPath(sandboxParameters, "DARWIN_USER_CACHE_DIR", _CS_DARWIN_USER_CACHE_DIR); - appendSandboxParameterPath(sandboxParameters, "WEBKIT_DATABASE_DIR", [(NSString *)parameters.databaseDirectory fileSystemRepresentation]); - appendSandboxParameterPath(sandboxParameters, "WEBKIT_LOCALSTORAGE_DIR", [(NSString *)parameters.localStorageDirectory fileSystemRepresentation]); - appendSandboxParameterPath(sandboxParameters, "NSURL_CACHE_DIR", parameters.nsURLCachePath.data()); - appendSandboxParameterPath(sandboxParameters, "UI_PROCESS_BUNDLE_RESOURCE_DIR", parameters.uiProcessBundleResourcePath.data()); + // These are read-only. + appendReadonlySandboxDirectory(sandboxParameters, "WEBKIT2_FRAMEWORK_DIR", [[[NSBundle bundleForClass:NSClassFromString(@"WKView")] bundlePath] stringByDeletingLastPathComponent]); + appendReadonlySandboxDirectory(sandboxParameters, "UI_PROCESS_BUNDLE_RESOURCE_DIR", parameters.uiProcessBundleResourcePath); + + // These are read-write getconf paths. + appendReadwriteConfDirectory(sandboxParameters, "DARWIN_USER_TEMP_DIR", _CS_DARWIN_USER_TEMP_DIR); + appendReadwriteConfDirectory(sandboxParameters, "DARWIN_USER_CACHE_DIR", _CS_DARWIN_USER_CACHE_DIR); + + // These are read-write paths. + appendReadwriteSandboxDirectory(sandboxParameters, "HOME_DIR", NSHomeDirectory()); + appendReadwriteSandboxDirectory(sandboxParameters, "WEBKIT_DATABASE_DIR", parameters.databaseDirectory); + appendReadwriteSandboxDirectory(sandboxParameters, "WEBKIT_LOCALSTORAGE_DIR", parameters.localStorageDirectory); + appendReadwriteSandboxDirectory(sandboxParameters, "NSURL_CACHE_DIR", parameters.nsURLCachePath); + sandboxParameters.append(static_cast<const char*>(0)); const char* profilePath = [[[NSBundle mainBundle] pathForResource:@"com.apple.WebProcess" ofType:@"sb"] fileSystemRepresentation]; @@ -193,7 +217,7 @@ void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters initializeSandbox(parameters); if (!parameters.parentProcessName.isNull()) { - NSString *applicationName = [NSString stringWithFormat:UI_STRING("%@ Web Content", "Visible name of the web process. The argument is the application name."), (NSString *)parameters.parentProcessName]; + NSString *applicationName = [NSString stringWithFormat:WEB_UI_STRING("%@ Web Content", "Visible name of the web process. The argument is the application name."), (NSString *)parameters.parentProcessName]; WKSetVisibleApplicationName((CFStringRef)applicationName); } @@ -201,8 +225,7 @@ void WebProcess::platformInitializeWebProcess(const WebProcessCreationParameters NSUInteger cacheMemoryCapacity = parameters.nsURLCacheMemoryCapacity; NSUInteger cacheDiskCapacity = parameters.nsURLCacheDiskCapacity; - NSString *nsCachePath = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:parameters.nsURLCachePath.data() length:strlen(parameters.nsURLCachePath.data())]; - RetainPtr<NSURLCache> parentProcessURLCache(AdoptNS, [[NSURLCache alloc] initWithMemoryCapacity:cacheMemoryCapacity diskCapacity:cacheDiskCapacity diskPath:nsCachePath]); + RetainPtr<NSURLCache> parentProcessURLCache(AdoptNS, [[NSURLCache alloc] initWithMemoryCapacity:cacheMemoryCapacity diskCapacity:cacheDiskCapacity diskPath:parameters.nsURLCachePath]); [NSURLCache setSharedURLCache:parentProcessURLCache.get()]; } diff --git a/Source/WebKit2/WebProcess/win/WebProcessWin.cpp b/Source/WebKit2/WebProcess/win/WebProcessWin.cpp index d56fef6..d9a4af5 100644 --- a/Source/WebKit2/WebProcess/win/WebProcessWin.cpp +++ b/Source/WebKit2/WebProcess/win/WebProcessWin.cpp @@ -27,6 +27,7 @@ #include "WebProcess.h" #include "WebCookieManager.h" +#include "WebPage.h" #include "WebProcessCreationParameters.h" #include <WebCore/FileSystem.h> #include <WebCore/MemoryCache.h> @@ -137,4 +138,49 @@ void WebProcess::setShouldPaintNativeControls(bool shouldPaintNativeControls) #endif } +struct EnumWindowsContext { + DWORD currentThreadID; + Vector<HWND>* windows; +}; + +static BOOL CALLBACK addWindowToVectorIfOwnedByCurrentThread(HWND window, LPARAM lParam) +{ + EnumWindowsContext* context = reinterpret_cast<EnumWindowsContext*>(lParam); + + if (::GetWindowThreadProcessId(window, 0) != context->currentThreadID) + return TRUE; + + context->windows->append(window); + return TRUE; +} + +Vector<HWND> WebProcess::windowsToReceiveSentMessagesWhileWaitingForSyncReply() +{ + Vector<HWND> windows; + + // Any non-message-only window created by this thread needs to receive sent messages while we + // wait for a sync reply. Otherwise we could deadlock with the UI process if, e.g., the focus + // window changes. See <http://webkit.org/b/58239>. + + EnumWindowsContext context; + context.currentThreadID = ::GetCurrentThreadId(); + context.windows = &windows; + + // Start out with top-level windows created by this thread (like Flash's hidden + // SWFlash_PlaceholderX top-level windows). + ::EnumThreadWindows(context.currentThreadID, addWindowToVectorIfOwnedByCurrentThread, reinterpret_cast<LPARAM>(&context)); + + // Also include any descendants of those top-level windows. + size_t topLevelWindowCount = windows.size(); + for (size_t i = 0; i < topLevelWindowCount; ++i) + ::EnumChildWindows(windows[i], addWindowToVectorIfOwnedByCurrentThread, reinterpret_cast<LPARAM>(&context)); + + // Also include any descendants of the WebPages' windows which we've created (e.g., for windowed plugins). + HashMap<uint64_t, RefPtr<WebPage> >::const_iterator::Values end = m_pageMap.end(); + for (HashMap<uint64_t, RefPtr<WebPage> >::const_iterator::Values it = m_pageMap.begin(); it != end; ++it) + ::EnumChildWindows((*it)->nativeWindow(), addWindowToVectorIfOwnedByCurrentThread, reinterpret_cast<LPARAM>(&context)); + + return windows; +} + } // namespace WebKit |