diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-03-12 14:11:15 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-03-12 14:11:15 +0100 |
commit | dd91e772430dc294e3bf478c119ef8d43c0a3358 (patch) | |
tree | 6f33ce4d5872a5691e0291eb45bf6ab373a5f567 /Source/WebKit2/UIProcess | |
parent | ad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (diff) | |
download | qtwebkit-dd91e772430dc294e3bf478c119ef8d43c0a3358.tar.gz |
Imported WebKit commit 3db4eb1820ac8fb03065d7ea73a4d9db1e8fea1a (http://svn.webkit.org/repository/webkit/trunk@110422)
This includes build fixes for the latest qtbase/qtdeclarative as well as the final QML2 API.
Diffstat (limited to 'Source/WebKit2/UIProcess')
157 files changed, 3990 insertions, 2303 deletions
diff --git a/Source/WebKit2/UIProcess/API/C/WKAPICast.h b/Source/WebKit2/UIProcess/API/C/WKAPICast.h index 0e7175a42..bd3fa2d74 100644 --- a/Source/WebKit2/UIProcess/API/C/WKAPICast.h +++ b/Source/WebKit2/UIProcess/API/C/WKAPICast.h @@ -83,6 +83,8 @@ class WebPageProxy; class WebPluginSiteDataManager; class WebPreferences; class WebProtectionSpace; +class WebRenderLayer; +class WebRenderObject; class WebTextChecker; WK_ADD_API_MAPPING(WKApplicationCacheManagerRef, WebApplicationCacheManagerProxy) @@ -119,6 +121,8 @@ WK_ADD_API_MAPPING(WKPageRef, WebPageProxy) WK_ADD_API_MAPPING(WKPluginSiteDataManagerRef, WebPluginSiteDataManager) WK_ADD_API_MAPPING(WKPreferencesRef, WebPreferences) WK_ADD_API_MAPPING(WKProtectionSpaceRef, WebProtectionSpace) +WK_ADD_API_MAPPING(WKRenderLayerRef, WebRenderLayer) +WK_ADD_API_MAPPING(WKRenderObjectRef, WebRenderObject) WK_ADD_API_MAPPING(WKTextCheckerRef, WebTextChecker) #if ENABLE(INSPECTOR) diff --git a/Source/WebKit2/UIProcess/API/C/WKInspector.cpp b/Source/WebKit2/UIProcess/API/C/WKInspector.cpp index 1a4ecc7c9..7e2187dda 100644 --- a/Source/WebKit2/UIProcess/API/C/WKInspector.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKInspector.cpp @@ -48,6 +48,11 @@ bool WKInspectorIsVisible(WKInspectorRef inspectorRef) return toImpl(inspectorRef)->isVisible(); } +bool WKInspectorIsFront(WKInspectorRef inspectorRef) +{ + return toImpl(inspectorRef)->isFront(); +} + void WKInspectorShow(WKInspectorRef inspectorRef) { toImpl(inspectorRef)->show(); diff --git a/Source/WebKit2/UIProcess/API/C/WKInspector.h b/Source/WebKit2/UIProcess/API/C/WKInspector.h index 2e85688d0..a00d103de 100644 --- a/Source/WebKit2/UIProcess/API/C/WKInspector.h +++ b/Source/WebKit2/UIProcess/API/C/WKInspector.h @@ -43,6 +43,7 @@ WK_EXPORT WKTypeID WKInspectorGetTypeID(); WK_EXPORT WKPageRef WKInspectorGetPage(WKInspectorRef inspector); WK_EXPORT bool WKInspectorIsVisible(WKInspectorRef inspector); +WK_EXPORT bool WKInspectorIsFront(WKInspectorRef inspector); WK_EXPORT void WKInspectorShow(WKInspectorRef inspector); WK_EXPORT void WKInspectorClose(WKInspectorRef inspector); diff --git a/Source/WebKit2/UIProcess/API/C/WKNotification.cpp b/Source/WebKit2/UIProcess/API/C/WKNotification.cpp index 634aa9824..5dfcbba29 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNotification.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKNotification.cpp @@ -52,6 +52,11 @@ WKStringRef WKNotificationCopyIconURL(WKNotificationRef notification) return toCopiedAPI(toImpl(notification)->iconURL()); } +WKStringRef WKNotificationCopyReplaceID(WKNotificationRef notification) +{ + return toCopiedAPI(toImpl(notification)->replaceID()); +} + WKSecurityOriginRef WKNotificationGetSecurityOrigin(WKNotificationRef notification) { return toAPI(toImpl(notification)->origin()); diff --git a/Source/WebKit2/UIProcess/API/C/WKNotification.h b/Source/WebKit2/UIProcess/API/C/WKNotification.h index 7c2723896..11ea97275 100644 --- a/Source/WebKit2/UIProcess/API/C/WKNotification.h +++ b/Source/WebKit2/UIProcess/API/C/WKNotification.h @@ -37,6 +37,7 @@ WK_EXPORT WKTypeID WKNotificationGetTypeID(); WK_EXPORT WKStringRef WKNotificationCopyTitle(WKNotificationRef notification); WK_EXPORT WKStringRef WKNotificationCopyBody(WKNotificationRef notification); WK_EXPORT WKStringRef WKNotificationCopyIconURL(WKNotificationRef notification); +WK_EXPORT WKStringRef WKNotificationCopyReplaceID(WKNotificationRef notification); WK_EXPORT WKSecurityOriginRef WKNotificationGetSecurityOrigin(WKNotificationRef notification); WK_EXPORT uint64_t WKNotificationGetID(WKNotificationRef notification); diff --git a/Source/WebKit2/UIProcess/API/C/WKPage.cpp b/Source/WebKit2/UIProcess/API/C/WKPage.cpp index 3010016c3..130dd0e45 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPage.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKPage.cpp @@ -660,6 +660,11 @@ void WKPageDrawPagesToPDF(WKPageRef page, WKFrameRef frame, WKPrintInfo printInf { toImpl(page)->drawPagesToPDF(toImpl(frame), printInfoFromWKPrintInfo(printInfo), first, count, DataCallback::create(context, callback)); } + +void WKPageEndPrinting(WKPageRef page) +{ + toImpl(page)->endPrinting(); +} #endif WKImageRef WKPageCreateSnapshotOfVisibleContent(WKPageRef) diff --git a/Source/WebKit2/UIProcess/API/C/WKPage.h b/Source/WebKit2/UIProcess/API/C/WKPage.h index 96d097c60..05b7aff0c 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPage.h +++ b/Source/WebKit2/UIProcess/API/C/WKPage.h @@ -285,24 +285,29 @@ enum { }; // ContextMenu client -typedef void (*WKPageGetContextMenuFromProposedContextMenuCallback)(WKPageRef page, WKArrayRef proposedMenu, WKArrayRef* newMenu, WKTypeRef userData, const void* clientInfo); +typedef void (*WKPageGetContextMenuFromProposedContextMenuCallback)(WKPageRef page, WKArrayRef proposedMenu, WKArrayRef* newMenu, WKHitTestResultRef hitTestResult, WKTypeRef userData, const void* clientInfo); typedef void (*WKPageCustomContextMenuItemSelectedCallback)(WKPageRef page, WKContextMenuItemRef contextMenuItem, const void* clientInfo); typedef void (*WKPageContextMenuDismissedCallback)(WKPageRef page, const void* clientInfo); +// Deprecated +typedef void (*WKPageGetContextMenuFromProposedContextMenuCallback_deprecatedForUseWithV0)(WKPageRef page, WKArrayRef proposedMenu, WKArrayRef* newMenu, WKTypeRef userData, const void* clientInfo); struct WKPageContextMenuClient { - int version; - const void * clientInfo; - + int version; + const void * clientInfo; + // Version 0 - WKPageGetContextMenuFromProposedContextMenuCallback getContextMenuFromProposedMenu; - WKPageCustomContextMenuItemSelectedCallback customContextMenuItemSelected; - + WKPageGetContextMenuFromProposedContextMenuCallback_deprecatedForUseWithV0 getContextMenuFromProposedMenu_deprecatedForUseWithV0; + WKPageCustomContextMenuItemSelectedCallback customContextMenuItemSelected; + // Version 1 - WKPageContextMenuDismissedCallback contextMenuDismissed; + WKPageContextMenuDismissedCallback contextMenuDismissed; + + // Version 2 + WKPageGetContextMenuFromProposedContextMenuCallback getContextMenuFromProposedMenu; }; typedef struct WKPageContextMenuClient WKPageContextMenuClient; -enum { kWKPageContextMenuClientCurrentVersion = 1 }; +enum { kWKPageContextMenuClientCurrentVersion = 2 }; WK_EXPORT WKTypeID WKPageGetTypeID(); diff --git a/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h b/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h index 097aabfe1..18860fd74 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h +++ b/Source/WebKit2/UIProcess/API/C/WKPagePrivate.h @@ -83,6 +83,7 @@ WK_EXPORT void WKPageComputePagesForPrinting(WKPageRef page, WKFrameRef frame, W typedef void (*WKPageDrawToPDFFunction)(WKDataRef data, WKErrorRef error, void* functionContext); WK_EXPORT void WKPageBeginPrinting(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo); WK_EXPORT void WKPageDrawPagesToPDF(WKPageRef page, WKFrameRef frame, WKPrintInfo printInfo, uint32_t first, uint32_t count, WKPageDrawToPDFFunction callback, void* context); +WK_EXPORT void WKPageEndPrinting(WKPageRef page); // FIXME https://bugs.webkit.org/show_bug.cgi?id=66979: Remove this sync call. WK_EXPORT WKImageRef WKPageCreateSnapshotOfVisibleContent(WKPageRef page); diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp b/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp index 87d32ed2f..39903bcb5 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp +++ b/Source/WebKit2/UIProcess/API/C/WKPreferences.cpp @@ -688,6 +688,16 @@ bool WKPreferencesGetSuppressesIncrementalRendering(WKPreferencesRef preferences return toImpl(preferencesRef)->suppressesIncrementalRendering(); } +void WKPreferencesSetSuppressIncrementalRendering(WKPreferencesRef preferencesRef, bool enabled) +{ + WKPreferencesSetSuppressesIncrementalRendering(preferencesRef, enabled); +} + +bool WKPreferencesGetSuppressIncrementalRendering(WKPreferencesRef preferencesRef) +{ + return WKPreferencesGetSuppressesIncrementalRendering(preferencesRef); +} + void WKPreferencesSetBackspaceKeyNavigationEnabled(WKPreferencesRef preferencesRef, bool enabled) { toImpl(preferencesRef)->setBackspaceKeyNavigationEnabled(enabled); diff --git a/Source/WebKit2/UIProcess/API/C/WKPreferences.h b/Source/WebKit2/UIProcess/API/C/WKPreferences.h index 8054e00f3..501c5a5d6 100644 --- a/Source/WebKit2/UIProcess/API/C/WKPreferences.h +++ b/Source/WebKit2/UIProcess/API/C/WKPreferences.h @@ -172,6 +172,11 @@ WK_EXPORT bool WKPreferencesGetWebAudioEnabled(WKPreferencesRef preferencesRef); // Defaults to false WK_EXPORT void WKPreferencesSetSuppressesIncrementalRendering(WKPreferencesRef preferencesRef, bool enabled); WK_EXPORT bool WKPreferencesGetSuppressesIncrementalRendering(WKPreferencesRef preferencesRef); + +// Defaults to false +// These functions are deprecated. See <rdar://problem/10929617> Remove WKPreferences[Get|Set]SuppressIncrementalRendering from WKPreferences.h. +WK_EXPORT void WKPreferencesSetSuppressIncrementalRendering(WKPreferencesRef preferencesRef, bool enabled); +WK_EXPORT bool WKPreferencesGetSuppressIncrementalRendering(WKPreferencesRef preferencesRef); // Defaults to true WK_EXPORT void WKPreferencesSetBackspaceKeyNavigationEnabled(WKPreferencesRef preferencesRef, bool enabled); diff --git a/Source/WebKit2/UIProcess/API/C/mac/WKInspectorMac.h b/Source/WebKit2/UIProcess/API/C/mac/WKInspectorPrivateMac.h index ec5a35afb..aef86a5d9 100644 --- a/Source/WebKit2/UIProcess/API/C/mac/WKInspectorMac.h +++ b/Source/WebKit2/UIProcess/API/C/mac/WKInspectorPrivateMac.h @@ -23,8 +23,8 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef WKInspectorMac_h -#define WKInspectorMac_h +#ifndef WKInspectorPrivateMac_h +#define WKInspectorPrivateMac_h #ifdef __cplusplus extern "C" { @@ -32,8 +32,18 @@ extern "C" { const NSInteger WKInspectorViewTag = 1000; +// This class is the Web Inspector window delegate. It can be used to add interface +// actions that need to work when the Web Inspector window is key. +WK_EXPORT @interface WKWebInspectorProxyObjCAdapter : NSObject <NSWindowDelegate> { + void* _inspectorProxy; +} + +@property (readonly) WKInspectorRef inspectorRef; + +@end + #ifdef __cplusplus } #endif -#endif // WKInspectorMac_h +#endif // WKInspectorPrivateMac_h diff --git a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp index a56265adb..c21162903 100644 --- a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp +++ b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.cpp @@ -213,6 +213,11 @@ void PageClientImpl::exitAcceleratedCompositingMode() { notImplemented(); } + +void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext&) +{ + notImplemented(); +} #endif // USE(ACCELERATED_COMPOSITING) void PageClientImpl::didChangeScrollbarsForMainFrame() const diff --git a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h index 2522153d4..40af3b23f 100644 --- a/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/efl/PageClientImpl.h @@ -85,6 +85,7 @@ private: #if USE(ACCELERATED_COMPOSITING) virtual void enterAcceleratedCompositingMode(const LayerTreeContext&); virtual void exitAcceleratedCompositingMode(); + virtual void updateAcceleratedCompositingMode(const LayerTreeContext&); #endif virtual void didChangeScrollbarsForMainFrame() const; diff --git a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp index c3ad3f764..9fadbeab5 100644 --- a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp @@ -242,6 +242,11 @@ void PageClientImpl::exitAcceleratedCompositingMode() { notImplemented(); } + +void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext&) +{ + notImplemented(); +} #endif // USE(ACCELERATED_COMPOSITING) void PageClientImpl::didCommitLoadForMainFrame(bool useCustomRepresentation) diff --git a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h index 291ba212b..6a1cb2459 100644 --- a/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h @@ -92,6 +92,7 @@ private: #if USE(ACCELERATED_COMPOSITING) virtual void enterAcceleratedCompositingMode(const LayerTreeContext&); virtual void exitAcceleratedCompositingMode(); + virtual void updateAcceleratedCompositingMode(const LayerTreeContext&); #endif virtual void didCommitLoadForMainFrame(bool useCustomRepresentation); diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h b/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h index 8c3eec2a4..96bcb4ea2 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDefines.h @@ -33,6 +33,8 @@ #include <glib.h> typedef struct _WebKitPrintOperation WebKitPrintOperation; +typedef struct _WebKitFindController WebKitFindController; +typedef struct _WebKitWebView WebKitWebView; #ifdef G_OS_WIN32 # ifdef BUILDING_WEBKIT diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp index 4d4eba18d..018f08d3d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.cpp @@ -169,18 +169,14 @@ static void webkit_download_class_init(WebKitDownloadClass* downloadClass) * This signal is emitted after response is received, * every time new data has been written to the destination. It's * useful to know the progress of the download operation. - * - * Returns: %TRUE to stop other handlers from being invoked for the event. - * %FALSE to propagate the event further. */ signals[RECEIVED_DATA] = g_signal_new("received-data", G_TYPE_FROM_CLASS(objectClass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitDownloadClass, received_data), - g_signal_accumulator_true_handled, NULL, - webkit_marshal_BOOLEAN__UINT64, - G_TYPE_BOOLEAN, 1, + 0, 0, 0, + webkit_marshal_VOID__UINT64, + G_TYPE_NONE, 1, G_TYPE_UINT64); /** @@ -189,18 +185,14 @@ static void webkit_download_class_init(WebKitDownloadClass* downloadClass) * * This signal is emitted when download finishes successfully or due to an error. * In case of errors #WebKitDownload::failed signal is emitted before this one. - * - * Returns: %TRUE to stop other handlers from being invoked for the event. - * %FALSE to propagate the event further. */ signals[FINISHED] = g_signal_new("finished", G_TYPE_FROM_CLASS(objectClass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitDownloadClass, finished), - g_signal_accumulator_true_handled, NULL, - webkit_marshal_BOOLEAN__VOID, - G_TYPE_BOOLEAN, 0); + 0, 0, 0, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); /** * WebKitDownload::failed: @@ -213,18 +205,14 @@ static void webkit_download_class_init(WebKitDownloadClass* downloadClass) * with webkit_download_cancel(), this signal is emitted with error * %WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER. The download operation finishes * after an error and #WebKitDownload::finished signal is emitted after this one. - * - * Returns: %TRUE to stop other handlers from being invoked for the event. - * %FALSE to propagate the event further. */ signals[FAILED] = g_signal_new("failed", G_TYPE_FROM_CLASS(objectClass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitDownloadClass, failed), - g_signal_accumulator_true_handled, NULL, - webkit_marshal_BOOLEAN__POINTER, - G_TYPE_BOOLEAN, 1, + 0, 0, 0, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); /** @@ -258,17 +246,13 @@ static void webkit_download_class_init(WebKitDownloadClass* downloadClass) * This signal is emitted after #WebKitDownload::decide-destination and before * #WebKitDownload::received-data to notify that destination file has been * created successfully at @destination. - * - * Returns: %TRUE to stop other handlers from being invoked for the event. - * %FALSE to propagate the event further. */ signals[CREATED_DESTINATION] = g_signal_new("created-destination", G_TYPE_FROM_CLASS(objectClass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitDownloadClass, created_destination), - g_signal_accumulator_true_handled, NULL, - webkit_marshal_BOOLEAN__STRING, + 0, 0, 0, + g_cclosure_marshal_VOID__STRING, G_TYPE_BOOLEAN, 1, G_TYPE_STRING); @@ -304,8 +288,7 @@ void webkitDownloadNotifyProgress(WebKitDownload* download, guint64 bytesReceive download->priv->timer.set(g_timer_new()); priv->currentSize += bytesReceived; - gboolean returnValue; - g_signal_emit(download, signals[RECEIVED_DATA], 0, bytesReceived, &returnValue); + g_signal_emit(download, signals[RECEIVED_DATA], 0, bytesReceived); // Throttle progress notification to not consume high amounts of // CPU on fast links, except when the last notification occured @@ -333,9 +316,9 @@ void webkitDownloadFailed(WebKitDownload* download, const ResourceError& resourc resourceError.localizedDescription().utf8().data())); if (download->priv->timer) g_timer_stop(download->priv->timer.get()); - gboolean returnValue; - g_signal_emit(download, signals[FAILED], 0, webError.get(), &returnValue); - g_signal_emit(download, signals[FINISHED], 0, &returnValue); + + g_signal_emit(download, signals[FAILED], 0, webError.get()); + g_signal_emit(download, signals[FINISHED], 0, NULL); } void webkitDownloadCancelled(WebKitDownload* download) @@ -356,8 +339,7 @@ void webkitDownloadFinished(WebKitDownload* download) } if (download->priv->timer) g_timer_stop(download->priv->timer.get()); - gboolean returnValue; - g_signal_emit(download, signals[FINISHED], 0, &returnValue); + g_signal_emit(download, signals[FINISHED], 0, NULL); } CString webkitDownloadDecideDestinationWithSuggestedFilename(WebKitDownload* download, const CString& suggestedFilename) diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h index e200fec53..b6c51fea5 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitDownload.h @@ -50,15 +50,8 @@ struct _WebKitDownload { struct _WebKitDownloadClass { GObjectClass parent_class; - gboolean (* received_data) (WebKitDownload *download, - guint64 data_length); - gboolean (* finished) (WebKitDownload *download); - gboolean (* failed) (WebKitDownload *download, - GError *error); gboolean (* decide_destination) (WebKitDownload *download, const gchar *suggested_filename); - gboolean (* created_destination) (WebKitDownload *download, - const gchar *destination); }; WEBKIT_API GType diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp new file mode 100644 index 000000000..360137e16 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.cpp @@ -0,0 +1,475 @@ +/* + * Copyright (C) 2012 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,1 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitFindController.h" + +#include "WebKitEnumTypes.h" +#include "WebKitPrivate.h" +#include "WebKitWebViewBasePrivate.h" +#include <glib/gi18n-lib.h> +#include <wtf/gobject/GRefPtr.h> +#include <wtf/text/CString.h> + +using namespace WebCore; + +enum { + FOUND_TEXT, + FAILED_TO_FIND_TEXT, + COUNTED_MATCHES, + + LAST_SIGNAL +}; + +enum { + PROP_0, + + PROP_TEXT, + PROP_OPTIONS, + PROP_MAX_MATCH_COUNT, + PROP_WEB_VIEW +}; + +typedef enum { + FindOperation, + CountOperation +} WebKitFindControllerOperation; + +struct _WebKitFindControllerPrivate { + CString searchText; + uint32_t findOptions; + unsigned maxMatchCount; + WebKitWebView* webView; +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +G_DEFINE_TYPE(WebKitFindController, webkit_find_controller, G_TYPE_OBJECT) + +COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE, kWKFindOptionsCaseInsensitive); +COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_AT_WORD_STARTS, kWKFindOptionsAtWordStarts); +COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START, kWKFindOptionsTreatMedialCapitalAsWordStart); +COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_BACKWARDS, kWKFindOptionsBackwards); +COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_FIND_OPTIONS_WRAP_AROUND, kWKFindOptionsWrapAround); + +static void didFindString(WKPageRef page, WKStringRef string, unsigned matchCount, const void* clientInfo) +{ + g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[FOUND_TEXT], 0, matchCount); +} + +static void didFailToFindString(WKPageRef page, WKStringRef string, const void* clientInfo) +{ + g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[FAILED_TO_FIND_TEXT], 0); +} + +static void didCountStringMatches(WKPageRef page, WKStringRef string, unsigned matchCount, const void* clientInfo) +{ + g_signal_emit(WEBKIT_FIND_CONTROLLER(clientInfo), signals[COUNTED_MATCHES], 0, matchCount); +} + +static void webkit_find_controller_init(WebKitFindController* findController) +{ + WebKitFindControllerPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(findController, WEBKIT_TYPE_FIND_CONTROLLER, WebKitFindControllerPrivate); + findController->priv = priv; + new (priv) WebKitFindControllerPrivate(); +} + +static WKPageRef inline getWKPageFromWebKitWebView(WebKitWebView* webView) +{ + return toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); +} + +static void webkitFindControllerConstructed(GObject* object) +{ + WebKitFindController* findController = WEBKIT_FIND_CONTROLLER(object); + WKPageFindClient wkFindClient = { + kWKPageFindClientCurrentVersion, + findController, // clientInfo + didFindString, + didFailToFindString, + didCountStringMatches + }; + + WKPageSetPageFindClient(getWKPageFromWebKitWebView(findController->priv->webView), &wkFindClient); +} + +static void webkitFindControllerGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) +{ + WebKitFindController* findController = WEBKIT_FIND_CONTROLLER(object); + + switch (propId) { + case PROP_TEXT: + g_value_set_string(value, webkit_find_controller_get_search_text(findController)); + break; + case PROP_OPTIONS: + g_value_set_uint(value, webkit_find_controller_get_options(findController)); + break; + case PROP_MAX_MATCH_COUNT: + g_value_set_uint(value, webkit_find_controller_get_max_match_count(findController)); + break; + case PROP_WEB_VIEW: + g_value_set_object(value, webkit_find_controller_get_web_view(findController)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkitFindControllerSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) +{ + WebKitFindController* findController = WEBKIT_FIND_CONTROLLER(object); + + switch (propId) { + case PROP_WEB_VIEW: + findController->priv->webView = WEBKIT_WEB_VIEW(g_value_get_object(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkitFindControllerFinalize(GObject* object) +{ + WEBKIT_FIND_CONTROLLER(object)->priv->~WebKitFindControllerPrivate(); + G_OBJECT_CLASS(webkit_find_controller_parent_class)->finalize(object); +} + +static void webkit_find_controller_class_init(WebKitFindControllerClass* findClass) +{ + GObjectClass* gObjectClass = G_OBJECT_CLASS(findClass); + + gObjectClass->constructed = webkitFindControllerConstructed; + gObjectClass->get_property = webkitFindControllerGetProperty; + gObjectClass->set_property = webkitFindControllerSetProperty; + gObjectClass->finalize = webkitFindControllerFinalize; + + g_type_class_add_private(findClass, sizeof(WebKitFindControllerPrivate)); + + /** + * WebKitFindController:text: + * + * The current search text for this #WebKitFindController. + */ + g_object_class_install_property(gObjectClass, + PROP_TEXT, + g_param_spec_string("text", + _("Search text"), + _("Text to search for in the view"), + 0, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitFindController:options: + * + * The options to be used in the search operation. + */ + g_object_class_install_property(gObjectClass, + PROP_OPTIONS, + g_param_spec_flags("options", + _("Search Options"), + _("Search options to be used in the search operation"), + WEBKIT_TYPE_FIND_OPTIONS, + WEBKIT_FIND_OPTIONS_NONE, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitFindController:max-match-count: + * + * The maximum number of matches to report for a given search. + */ + g_object_class_install_property(gObjectClass, + PROP_MAX_MATCH_COUNT, + g_param_spec_uint("max-match-count", + _("Maximum matches count"), + _("The maximum number of matches in a given text to report"), + 0, G_MAXUINT, 0, + WEBKIT_PARAM_READABLE)); + + /** + * WebKitFindController:web-view: + * + * The #WebKitWebView this controller is associated to. + */ + g_object_class_install_property(gObjectClass, + PROP_WEB_VIEW, + g_param_spec_object("web-view", + _("WebView"), + _("The WebView associated with this find controller"), + WEBKIT_TYPE_WEB_VIEW, + static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitFindController::found-text: + * @find_controller: the #WebKitFindController + * @match_count: the number of matches found of the search text + * + * This signal is emitted when a given text is found in the web + * page text. It will be issued if the text is found + * asynchronously after a call to webkit_find_controller_search(), + * webkit_find_controller_search_next() or + * webkit_find_controller_search_previous(). + */ + signals[FOUND_TEXT] = + g_signal_new("found-text", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + 0, 0, 0, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + + /** + * WebKitFindController::failed-to-find-text: + * @find_controller: the #WebKitFindController + * + * This signal is emitted when a search operation does not find + * any result for the given text. It will be issued if the text + * is not found asynchronously after a call to + * webkit_find_controller_search(), webkit_find_controller_search_next() + * or webkit_find_controller_search_previous(). + */ + signals[FAILED_TO_FIND_TEXT] = + g_signal_new("failed-to-find-text", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + 0, 0, 0, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * WebKitFindController::counted-matches: + * @find_controller: the #WebKitFindController + * @match_count: the number of matches of the search text + * + * This signal is emitted when the #WebKitFindController has + * counted the number of matches for a given text after a call + * to webkit_find_controller_count_matches(). + */ + signals[COUNTED_MATCHES] = + g_signal_new("counted-matches", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + 0, 0, 0, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); +} + +/** + * webkit_find_controller_get_search_text: + * @find_controller: the #WebKitFindController + * + * Gets the text that @find_controller is currently searching + * for. This text is passed to either + * webkit_find_controller_search() or + * webkit_find_controller_count_matches(). + * + * Returns: the text to look for in the #WebKitWebView. + */ +const char* webkit_find_controller_get_search_text(WebKitFindController* findController) +{ + g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), 0); + + return findController->priv->searchText.data(); +} + +/** + * webkit_find_controller_get_options: + * @find_controller: the #WebKitFindController + * + * Gets a bitmask containing the #WebKitFindOptions associated with + * the current search. + * + * Returns: a bitmask containing the #WebKitFindOptions associated + * with the current search. + */ +guint32 webkit_find_controller_get_options(WebKitFindController* findController) +{ + g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), WEBKIT_FIND_OPTIONS_NONE); + + return findController->priv->findOptions; +} + +/** + * webkit_find_controller_get_max_match_count: + * @find_controller: the #WebKitFindController + * + * Gets the maximum number of matches to report during a text + * lookup. This number is passed as the last argument of + * webkit_find_controller_search() or + * webkit_find_controller_count_matches(). + * + * Returns: the maximum number of matches to report. + */ +guint webkit_find_controller_get_max_match_count(WebKitFindController* findController) +{ + g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), 0); + + return findController->priv->maxMatchCount; +} + +/** + * webkit_find_controller_get_web_view: + * @find_controller: the #WebKitFindController + * + * Gets the #WebKitWebView this find controller is associated to. Do + * not unref the returned instance as it belongs to the + * #WebKitFindController. + * + * Returns: (transfer none): the #WebKitWebView. + */ +WebKitWebView* webkit_find_controller_get_web_view(WebKitFindController* findController) +{ + g_return_val_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController), 0); + + return findController->priv->webView; +} + +static void webKitFindControllerPerform(WebKitFindController* findController, WebKitFindControllerOperation operation) +{ + WKFindOptions wkFindOptions = static_cast<WKFindOptions>(findController->priv->findOptions); + WKRetainPtr<WKStringRef> wkSearchText(AdoptWK, WKStringCreateWithUTF8CString(findController->priv->searchText.data())); + WKPageRef wkPage = getWKPageFromWebKitWebView(findController->priv->webView); + + if (operation == FindOperation) { + // Unconditionally highlight text matches. WK1 API was forcing + // clients to enable/disable highlighting. Since most of them + // (all?) where using highlighting we decided to simplify the + // WK2 API and unconditionally show highlights. + wkFindOptions = static_cast<WKFindOptions>(findController->priv->findOptions | kWKFindOptionsShowHighlight); + WKPageFindString(wkPage, wkSearchText.get(), wkFindOptions, findController->priv->maxMatchCount); + return; + } + + WKPageCountStringMatches(wkPage, wkSearchText.get(), wkFindOptions, findController->priv->maxMatchCount); +} + +static inline void webKitFindControllerSetSearchData(WebKitFindController* findController, const gchar* searchText, guint32 findOptions, guint maxMatchCount) +{ + findController->priv->searchText = searchText; + findController->priv->findOptions = findOptions; + findController->priv->maxMatchCount = maxMatchCount; +} + +/** + * webkit_find_controller_search: + * @find_controller: the #WebKitFindController + * @search_text: the text to look for + * @find_options: a bitmask with the #WebKitFindOptions used in the search + * @max_match_count: the maximum number of matches allowed in the search + * + * Looks for @search_text in the #WebKitWebView associated with + * @find_controller since the beginning of the document highlighting + * up to @max_match_count matches. The outcome of the search will be + * asynchronously provided by the #WebKitFindController::found-text + * and #WebKitFindController::failed-to-find-text signals. + * + * To look for the next or previous occurrences of the same text + * with the same find options use webkit_find_controller_search_next() + * and/or webkit_find_controller_search_previous(). The + * #WebKitFindController will use the same text and options for the + * following searches unless they are modified by another call to this + * method. + * + * Note that if the number of matches is higher than @max_match_count + * then #WebKitFindController::found-text will report %G_MAXUINT matches + * instead of the actual number. + * + * Callers should call webkit_find_controller_search_finish() to + * finish the current search operation. + */ +void webkit_find_controller_search(WebKitFindController* findController, const gchar* searchText, guint findOptions, guint maxMatchCount) +{ + g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); + g_return_if_fail(searchText); + + webKitFindControllerSetSearchData(findController, searchText, findOptions, maxMatchCount); + webKitFindControllerPerform(findController, FindOperation); +} + +/** + * webkit_find_controller_search_next: + * @find_controller: the #WebKitFindController + * + * Looks for the next occurrence of the search text. + * + * Calling this method before webkit_find_controller_search() or + * webkit_find_controller_count_matches() is a programming error. + */ +void webkit_find_controller_search_next(WebKitFindController* findController) +{ + g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); + + findController->priv->findOptions = findController->priv->findOptions & ~WEBKIT_FIND_OPTIONS_BACKWARDS; + webKitFindControllerPerform(findController, FindOperation); +} + +/** + * webkit_find_controller_search_previous: + * @find_controller: the #WebKitFindController + * + * Looks for the previous occurrence of the search text. + * + * Calling this method before webkit_find_controller_search() or + * webkit_find_controller_count_matches() is a programming error. + */ +void webkit_find_controller_search_previous(WebKitFindController* findController) +{ + g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); + + findController->priv->findOptions = findController->priv->findOptions | WEBKIT_FIND_OPTIONS_BACKWARDS; + webKitFindControllerPerform(findController, FindOperation); +} + +/** + * webkit_find_controller_count_matches: + * @find_controller: the #WebKitFindController + * @search_text: the text to look for + * @find_options: a bitmask with the #WebKitFindOptions used in the search + * @max_match_count: the maximum number of matches allowed in the search + * + * Counts the number of matches for @search_text found in the + * #WebKitWebView with the provided @find_options. The number of + * matches will be provided by the + * #WebKitFindController::counted-matches signal. + */ +void webkit_find_controller_count_matches(WebKitFindController* findController, const gchar* searchText, guint32 findOptions, guint maxMatchCount) +{ + g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); + g_return_if_fail(searchText); + + webKitFindControllerSetSearchData(findController, searchText, findOptions, maxMatchCount); + webKitFindControllerPerform(findController, CountOperation); +} + +/** + * webkit_find_controller_search_finish: + * @find_controller: a #WebKitFindController + * + * Finishes a find operation started by + * webkit_find_controller_search(). It will basically unhighlight + * every text match found. + * + * This method will be typically called when the search UI is + * closed/hidden by the client application. + */ +void webkit_find_controller_search_finish(WebKitFindController* findController) +{ + g_return_if_fail(WEBKIT_IS_FIND_CONTROLLER(findController)); + + WKPageHideFindUI(getWKPageFromWebKitWebView(findController->priv->webView)); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h new file mode 100644 index 000000000..3a47f99d4 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitFindController.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2012 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,1 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitFindController_h +#define WebKitFindController_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_FIND_CONTROLLER (webkit_find_controller_get_type()) +#define WEBKIT_FIND_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_FIND_CONTROLLER, WebKitFindController)) +#define WEBKIT_FIND_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), WEBKIT_TYPE_FIND_CONTROLLER, WebKitFindControllerClass)) +#define WEBKIT_IS_FIND_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_FIND_CONTROLLER)) +#define WEBKIT_IS_FIND_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_FIND_CONTROLLER)) +#define WEBKIT_FIND_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_FIND_CONTROLLER, WebKitFindControllerClass)) + +typedef struct _WebKitFindControllerPrivate WebKitFindControllerPrivate; +typedef struct _WebKitFindControllerClass WebKitFindControllerClass; + +/** + * WebKitFindOptions: + * @WEBKIT_FIND_OPTIONS_NONE: no search flags, this means a case + * sensitive, no wrap, forward only search. + * @WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE: case insensitive search. + * @WEBKIT_FIND_OPTIONS_AT_WORD_STARTS: search text only at the + * begining of the words. + * @WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START: treat + * capital letters in the middle of words as word start. + * @WEBKIT_FIND_OPTIONS_BACKWARDS: search backwards. + * @WEBKIT_FIND_OPTIONS_WRAP_AROUND: if not present search will stop + * at the end of the document. + * + * Enum values used to specify search options. + */ +typedef enum { + WEBKIT_FIND_OPTIONS_NONE, + + WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE = 1 << 0, + WEBKIT_FIND_OPTIONS_AT_WORD_STARTS = 1 << 1, + WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START = 1 << 2, + WEBKIT_FIND_OPTIONS_BACKWARDS = 1 << 3, + WEBKIT_FIND_OPTIONS_WRAP_AROUND = 1 << 4, +} WebKitFindOptions; + +struct _WebKitFindController { + GObject parent; + + /*< private >*/ + WebKitFindControllerPrivate *priv; +}; + +struct _WebKitFindControllerClass { + GObjectClass parent_class; +}; + +WEBKIT_API GType +webkit_find_controller_get_type (void); + +WEBKIT_API void +webkit_find_controller_search (WebKitFindController *find_controller, + const gchar *search_text, + guint32 find_options, + guint max_match_count); + +WEBKIT_API void +webkit_find_controller_search_finish (WebKitFindController *find_controller); + +WEBKIT_API void +webkit_find_controller_search_next (WebKitFindController *find_controller); + +WEBKIT_API void +webkit_find_controller_search_previous (WebKitFindController *find_controller); + +WEBKIT_API void +webkit_find_controller_count_matches (WebKitFindController *find_controller, + const gchar *search_text, + guint32 find_options, + guint max_match_count); + +WEBKIT_API const gchar * +webkit_find_controller_get_search_text (WebKitFindController *find_controller); + +WEBKIT_API guint32 +webkit_find_controller_get_options (WebKitFindController *find_controller); + +WEBKIT_API guint +webkit_find_controller_get_max_match_count (WebKitFindController *find_controller); + +WEBKIT_API WebKitWebView * +webkit_find_controller_get_web_view (WebKitFindController *find_controller); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp index 94d13eab2..e40fde76e 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitNavigationPolicyDecision.cpp @@ -38,7 +38,7 @@ using namespace WebKit; * @See_also: #WebKitPolicyDecision, #WebKitWebView * * WebKitNavigationPolicyDecision represents a policy decision for events associated with - * navigations. If the value of WebKitNavigationPolicyDecision:mouse-button is not 0, then + * navigations. If the value of #WebKitNavigationPolicyDecision:mouse-button is not 0, then * the navigation was triggered by a mouse event. */ @@ -143,7 +143,7 @@ static void webkit_navigation_policy_decision_class_init(WebKitNavigationPolicyD * * If the navigation associated with this policy decision was originally * triggered by a mouse event, this property contains a bitmask of various - * GdkModifierType values describing the modifiers used for that click. + * #GdkModifierType values describing the modifiers used for that click. * If the navigation was not triggered by a mouse event or no modifiers * were active, the value of this property will be zero. */ @@ -248,7 +248,7 @@ WebKitURIRequest* webkit_navigation_policy_decision_get_request(WebKitNavigation * * Gets the value of the #WebKitNavigationPolicyDecision:frame-name property. * - * Returns: The name of the new frame this navigation action targets or %NULL + * Returns: The name of the new frame this navigation action targets or %NULL */ const char* webkit_navigation_policy_decision_get_frame_name(WebKitNavigationPolicyDecision* decision) { diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp index a20ccb2a6..d79d40149 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp @@ -367,7 +367,7 @@ void webkit_print_operation_set_page_setup(WebKitPrintOperation* printOperation, * the user. This method returns when the print dialog is closed. * If the print dialog is cancelled %WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL * is returned. If the user clicks on the print button, %WEBKIT_PRINT_OPERATION_RESPONSE_PRINT - * is returned and the print operation starts. In this case, the WebKitPrintOperation::finished + * is returned and the print operation starts. In this case, the #WebKitPrintOperation::finished * signal is emitted when the operation finishes. * If the print dialog is not cancelled current print settings and page setup of @print_operation * are updated with options selected by the user when Print button is pressed in print dialog. @@ -394,7 +394,7 @@ WebKitPrintOperationResponse webkit_print_operation_run_dialog(WebKitPrintOperat * are not set with webkit_print_operation_set_print_settings() and * webkit_print_operation_set_page_setup(), the default options will be used * and the print job will be sent to the default printer. - * The WebKitPrintOperation::finished signal is emitted when the printing + * The #WebKitPrintOperation::finished signal is emitted when the printing * operation finishes. */ void webkit_print_operation_print(WebKitPrintOperation* printOperation) diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h index 43d26cc85..e785c3638 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrivate.h @@ -28,7 +28,9 @@ #include <WebKit2/WKAPICast.h> #include <WebKit2/WKDownload.h> +#include <WebKit2/WKFindOptions.h> #include <WebKit2/WKRetainPtr.h> +#include <WebKit2/WKString.h> #include <WebKit2/WebKit2.h> #include <glib.h> #include <wtf/Assertions.h> diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp new file mode 100644 index 000000000..863665d71 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "WebKitScriptDialog.h" + +#include "WebKitScriptDialogPrivate.h" + +static WebKitScriptDialog* webkitScriptDialogCopy(WebKitScriptDialog* dialog) +{ + WebKitScriptDialog* copy = g_slice_new0(WebKitScriptDialog); + new (copy) WebKitScriptDialog(dialog); + return copy; +} + +static void webkitScriptDialogFree(WebKitScriptDialog* dialog) +{ + dialog->~WebKitScriptDialog(); + g_slice_free(WebKitScriptDialog, dialog); +} + +G_DEFINE_BOXED_TYPE(WebKitScriptDialog, webkit_script_dialog, webkitScriptDialogCopy, webkitScriptDialogFree) + +/** + * webkit_script_dialog_get_dialog_type: + * @dialog: a #WebKitScriptDialog + * + * Get the dialog type of a #WebKitScriptDialog. + * + * Returns: the #WebKitScriptDialogType of @dialog + */ +WebKitScriptDialogType webkit_script_dialog_get_dialog_type(WebKitScriptDialog* dialog) +{ + g_return_val_if_fail(dialog, WEBKIT_SCRIPT_DIALOG_ALERT); + + return static_cast<WebKitScriptDialogType>(dialog->type); +} + +/** + * webkit_script_dialog_get_message: + * @dialog: a #WebKitScriptDialog + * + * Get the message of a #WebKitScriptDialog. + * + * Returns: the message of @dialog. + */ +const char* webkit_script_dialog_get_message(WebKitScriptDialog* dialog) +{ + g_return_val_if_fail(dialog, 0); + + return dialog->message.data(); +} + +/** + * webkit_script_dialog_confirm_set_confirmed: + * @dialog: a #WebKitScriptDialog + * @confirmed: whether user confirmed the dialog + * + * This method is used for %WEBKIT_SCRIPT_DIALOG_CONFIRM dialogs when + * #WebKitWebView::script-dialog signal is emitted to set whether the user + * confirmed the dialog or not. The default implementation of #WebKitWebView::script-dialog + * signal sets %TRUE when the OK button is clicked and %FALSE otherwise. + * It's an error to use this method with a #WebKitScriptDialog that is not of type + * %WEBKIT_SCRIPT_DIALOG_CONFIRM. + */ +void webkit_script_dialog_confirm_set_confirmed(WebKitScriptDialog* dialog, gboolean confirmed) +{ + g_return_if_fail(dialog); + g_return_if_fail(dialog->type == WEBKIT_SCRIPT_DIALOG_CONFIRM); + + dialog->confirmed = confirmed; +} + +/** + * webkit_script_dialog_prompt_get_default_text: + * @dialog: a #WebKitScriptDialog + * + * Get the default text of a #WebKitScriptDialog of type %WEBKIT_SCRIPT_DIALOG_PROMPT. + * It's an error to use this method with a #WebKitScriptDialog that is not of type + * %WEBKIT_SCRIPT_DIALOG_PROMPT. + * + * Returns: the default text of @dialog + */ +const char* webkit_script_dialog_prompt_get_default_text(WebKitScriptDialog* dialog) +{ + g_return_val_if_fail(dialog, 0); + g_return_val_if_fail(dialog->type == WEBKIT_SCRIPT_DIALOG_PROMPT, 0); + + return dialog->defaultText.data(); +} + +/** + * webkit_script_dialog_prompt_set_text: + * @dialog: a #WebKitScriptDialog + * @text: the text to set + * + * This method is used for %WEBKIT_SCRIPT_DIALOG_PROMPT dialogs when + * #WebKitWebView::script-dialog signal is emitted to set the text + * entered by the user. The default implementation of #WebKitWebView::script-dialog + * signal sets the text of the entry form when OK button is clicked, otherwise %NULL is set. + * It's an error to use this method with a #WebKitScriptDialog that is not of type + * %WEBKIT_SCRIPT_DIALOG_PROMPT. + */ +void webkit_script_dialog_prompt_set_text(WebKitScriptDialog* dialog, const char* text) +{ + g_return_if_fail(dialog); + g_return_if_fail(dialog->type == WEBKIT_SCRIPT_DIALOG_PROMPT); + + dialog->text = text; +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h new file mode 100644 index 000000000..cf88535ad --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialog.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) +#error "Only <webkit2/webkit2.h> can be included directly." +#endif + +#ifndef WebKitScriptDialog_h +#define WebKitScriptDialog_h + +#include <glib-object.h> +#include <webkit2/WebKitDefines.h> + +G_BEGIN_DECLS + +#define WEBKIT_TYPE_SCRIPT_DIALOG (webkit_script_dialog_get_type()) + +typedef struct _WebKitScriptDialog WebKitScriptDialog; + +/** + * WebKitScriptDialogType: + * @WEBKIT_SCRIPT_DIALOG_ALERT: Alert script dialog, used to show a + * message to the user. + * @WEBKIT_SCRIPT_DIALOG_CONFIRM: Confirm script dialog, used to ask + * confirmation to the user. + * @WEBKIT_SCRIPT_DIALOG_PROMPT: Prompt script dialog, used to ask + * information to the user. + * + * Enum values used for determining the type of #WebKitScriptDialog + */ +typedef enum { + WEBKIT_SCRIPT_DIALOG_ALERT, + WEBKIT_SCRIPT_DIALOG_CONFIRM, + WEBKIT_SCRIPT_DIALOG_PROMPT +} WebKitScriptDialogType; + +WEBKIT_API GType +webkit_script_dialog_get_type (void); + +WEBKIT_API WebKitScriptDialogType +webkit_script_dialog_get_dialog_type (WebKitScriptDialog *dialog); + +WEBKIT_API const gchar * +webkit_script_dialog_get_message (WebKitScriptDialog *dialog); + +WEBKIT_API void +webkit_script_dialog_confirm_set_confirmed (WebKitScriptDialog *dialog, + gboolean confirmed); + +WEBKIT_API const gchar * +webkit_script_dialog_prompt_get_default_text (WebKitScriptDialog *dialog); + +WEBKIT_API void +webkit_script_dialog_prompt_set_text (WebKitScriptDialog *dialog, + const gchar *text); + +G_END_DECLS + +#endif diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialogPrivate.h b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialogPrivate.h new file mode 100644 index 000000000..5f1a43d94 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitScriptDialogPrivate.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2012 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef WebKitScriptDialogPrivate_h +#define WebKitScriptDialogPrivate_h + +#include "WebKitScriptDialog.h" +#include <wtf/text/CString.h> + +struct _WebKitScriptDialog { + _WebKitScriptDialog(unsigned type, const CString& message) + : type(type) + , message(message) + , confirmed(false) + { + } + + _WebKitScriptDialog(unsigned type, const CString& message, const CString& defaultText) + : type(type) + , message(message) + , defaultText(defaultText) + , confirmed(false) + { + ASSERT(type == WEBKIT_SCRIPT_DIALOG_PROMPT); + } + + _WebKitScriptDialog(WebKitScriptDialog* dialog) + : type(dialog->type) + , message(dialog->message) + , defaultText(dialog->defaultText) + , confirmed(dialog->confirmed) + , text(dialog->text) + { + } + + unsigned type; + CString message; + CString defaultText; + + bool confirmed; + CString text; +}; + +#endif // WebKitScriptDialogPrivate_h diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp index c1c4a970b..b4b267d1b 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.cpp @@ -46,6 +46,7 @@ struct _WebKitSettingsPrivate { CString fantasyFontFamily; CString pictographFontFamily; CString defaultCharset; + bool zoomTextOnly; }; /** @@ -103,7 +104,8 @@ enum { PROP_ENABLE_FULLSCREEN, PROP_PRINT_BACKGROUNDS, PROP_ENABLE_WEBAUDIO, - PROP_ENABLE_WEBGL + PROP_ENABLE_WEBGL, + PROP_ZOOM_TEXT_ONLY }; static void webKitSettingsSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) @@ -210,6 +212,9 @@ static void webKitSettingsSetProperty(GObject* object, guint propId, const GValu case PROP_ENABLE_WEBGL: webkit_settings_set_enable_webgl(settings, g_value_get_boolean(value)); break; + case PROP_ZOOM_TEXT_ONLY: + webkit_settings_set_zoom_text_only(settings, g_value_get_boolean(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); break; @@ -320,6 +325,9 @@ static void webKitSettingsGetProperty(GObject* object, guint propId, GValue* val case PROP_ENABLE_WEBGL: g_value_set_boolean(value, webkit_settings_get_enable_webgl(settings)); break; + case PROP_ZOOM_TEXT_ONLY: + g_value_set_boolean(value, webkit_settings_get_zoom_text_only(settings)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); break; @@ -816,6 +824,22 @@ static void webkit_settings_class_init(WebKitSettingsClass* klass) FALSE, readWriteConstructParamFlags)); + /** + * WebKitSettings:zoom-text-only: + * + * Whether #WebKitWebView:zoom-level affects only the + * text of the page or all the contents. Other contents containing text + * like form controls will be also affected by zoom factor when + * this property is enabled. + */ + g_object_class_install_property(gObjectClass, + PROP_ZOOM_TEXT_ONLY, + g_param_spec_boolean("zoom-text-only", + _("Zoom Text Only"), + _("Whether zoom level of web view changes only the text size"), + FALSE, + readWriteConstructParamFlags)); + g_type_class_add_private(klass, sizeof(WebKitSettingsPrivate)); } @@ -2073,3 +2097,39 @@ void webkit_settings_set_enable_webgl(WebKitSettings* settings, gboolean enabled WKPreferencesSetWebGLEnabled(priv->preferences.get(), enabled); g_object_notify(G_OBJECT(settings), "enable-webgl"); } + +/** + * webkit_settings_set_zoom_text_only: + * @settings: a #WebKitSettings + * @zoom_text_only: Value to be set + * + * Set the #WebKitSettings:zoom-text-only property. + */ +void webkit_settings_set_zoom_text_only(WebKitSettings* settings, gboolean zoomTextOnly) +{ + g_return_if_fail(WEBKIT_IS_SETTINGS(settings)); + + WebKitSettingsPrivate* priv = settings->priv; + if (priv->zoomTextOnly == zoomTextOnly) + return; + + priv->zoomTextOnly = zoomTextOnly; + g_object_notify(G_OBJECT(settings), "zoom-text-only"); +} + +/** + * webkit_settings_get_zoom_text_only: + * @settings: a #WebKitSettings + * + * Get the #WebKitSettings:zoom-text-only property. + * + * Returns: %TRUE If zoom level of the view should only affect the text + * or %FALSE if all view contents should be scaled. + */ +gboolean webkit_settings_get_zoom_text_only(WebKitSettings* settings) +{ + g_return_val_if_fail(WEBKIT_IS_SETTINGS(settings), FALSE); + + return settings->priv->zoomTextOnly; +} + diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h index b22ba00ff..25a78aca3 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitSettings.h @@ -307,6 +307,13 @@ WEBKIT_API void webkit_settings_set_enable_webgl (WebKitSettings *settings, gboolean enabled); +WEBKIT_API void +webkit_settings_set_zoom_text_only (WebKitSettings *settings, + gboolean zoom_text_only); + +WEBKIT_API gboolean +webkit_settings_get_zoom_text_only (WebKitSettings *settings); + G_END_DECLS #endif /* WebKitSettings_h */ diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp index be590ff33..4f17d4669 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.cpp @@ -30,6 +30,7 @@ #include "WebKitPolicyClient.h" #include "WebKitPrintOperationPrivate.h" #include "WebKitPrivate.h" +#include "WebKitScriptDialogPrivate.h" #include "WebKitSettingsPrivate.h" #include "WebKitUIClient.h" #include "WebKitWebContextPrivate.h" @@ -55,9 +56,7 @@ enum { READY_TO_SHOW, CLOSE, - SCRIPT_ALERT, - SCRIPT_CONFIRM, - SCRIPT_PROMPT, + SCRIPT_DIALOG, DECIDE_POLICY, @@ -78,13 +77,20 @@ enum { PROP_ZOOM_LEVEL }; +typedef enum { + NotReplacingContent, + WillReplaceContent, + ReplacingContent, + DidReplaceContent +} ReplaceContentStatus; + struct _WebKitWebViewPrivate { WebKitWebContext* context; CString title; CString customTextEncoding; double estimatedLoadProgress; CString activeURI; - bool replacingContent; + ReplaceContentStatus replaceContentStatus; GRefPtr<WebKitBackForwardList> backForwardList; GRefPtr<WebKitSettings> settings; @@ -92,6 +98,8 @@ struct _WebKitWebViewPrivate { GRefPtr<WebKitHitTestResult> mouseTargetHitTestResult; unsigned mouseTargetModifiers; + + GRefPtr<WebKitFindController> findController; }; static guint signals[LAST_SIGNAL] = { 0, }; @@ -128,39 +136,56 @@ static GtkWidget* webkitWebViewCreateJavaScriptDialog(WebKitWebView* webView, Gt return dialog; } -static gboolean webkitWebViewScriptAlert(WebKitWebView* webView, const char* message) +static gboolean webkitWebViewScriptDialog(WebKitWebView* webView, WebKitScriptDialog* scriptDialog) { - GtkWidget* dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, GTK_RESPONSE_CLOSE, message); - gtk_dialog_run(GTK_DIALOG(dialog)); + GtkWidget* dialog = 0; + + switch (scriptDialog->type) { + case WEBKIT_SCRIPT_DIALOG_ALERT: + dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, GTK_RESPONSE_CLOSE, scriptDialog->message.data()); + gtk_dialog_run(GTK_DIALOG(dialog)); + break; + case WEBKIT_SCRIPT_DIALOG_CONFIRM: + dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, scriptDialog->message.data()); + scriptDialog->confirmed = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK; + break; + case WEBKIT_SCRIPT_DIALOG_PROMPT: + dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, scriptDialog->message.data()); + GtkWidget* entry = gtk_entry_new(); + gtk_entry_set_text(GTK_ENTRY(entry), scriptDialog->defaultText.data()); + gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), entry); + gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); + gtk_widget_show(entry); + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) + scriptDialog->text = gtk_entry_get_text(GTK_ENTRY(entry)); + break; + } + gtk_widget_destroy(dialog); + return TRUE; } -static gboolean webkitWebViewScriptConfirm(WebKitWebView* webView, const char* message, gboolean* confirmed) +static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision* decision, WebKitPolicyDecisionType) { - GtkWidget* dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, message); - *confirmed = gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK; - gtk_widget_destroy(dialog); + webkit_policy_decision_use(decision); return TRUE; } -static gboolean webkitWebViewScriptPrompt(WebKitWebView* webView, const char* message, const char* defaultText, char** text) +static void zoomTextOnlyChanged(WebKitSettings* settings, GParamSpec*, WebKitWebView* webView) { - GtkWidget* dialog = webkitWebViewCreateJavaScriptDialog(webView, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, message); - GtkWidget* entry = gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(entry), defaultText); - gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), entry); - gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); - gtk_widget_show(entry); - - *text = (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) ? g_strdup(gtk_entry_get_text(GTK_ENTRY(entry))) : 0; - return TRUE; + WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); + gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(settings); + gdouble pageZoomLevel = zoomTextOnly ? 1 : WKPageGetTextZoomFactor(wkPage); + gdouble textZoomLevel = zoomTextOnly ? WKPageGetPageZoomFactor(wkPage) : 1; + WKPageSetPageAndTextZoomFactors(wkPage, pageZoomLevel, textZoomLevel); } -static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision* decision, WebKitPolicyDecisionType) +static void webkitWebViewSetSettings(WebKitWebView* webView, WebKitSettings* settings, WKPageRef wkPage) { - webkit_policy_decision_use(decision); - return TRUE; + webView->priv->settings = settings; + webkitSettingsAttachSettingsToPage(webView->priv->settings.get(), wkPage); + g_signal_connect(settings, "notify::zoom-text-only", G_CALLBACK(zoomTextOnlyChanged), webView); } static void webkitWebViewConstructed(GObject* object) @@ -180,8 +205,9 @@ static void webkitWebViewConstructed(GObject* object) WebPageProxy* page = webkitWebViewBaseGetPage(webViewBase); priv->backForwardList = adoptGRef(webkitBackForwardListCreate(WKPageGetBackForwardList(toAPI(page)))); - priv->settings = adoptGRef(webkit_settings_new()); - webkitSettingsAttachSettingsToPage(priv->settings.get(), toAPI(page)); + + GRefPtr<WebKitSettings> settings = adoptGRef(webkit_settings_new()); + webkitWebViewSetSettings(webView, settings.get(), toAPI(page)); } static void webkitWebViewSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) @@ -262,9 +288,7 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) webViewClass->load_failed = webkitWebViewLoadFail; webViewClass->create = webkitWebViewCreate; - webViewClass->script_alert = webkitWebViewScriptAlert; - webViewClass->script_confirm = webkitWebViewScriptConfirm; - webViewClass->script_prompt = webkitWebViewScriptPrompt; + webViewClass->script_dialog = webkitWebViewScriptDialog; webViewClass->decide_policy = webkitWebViewDecidePolicy; g_type_class_add_private(webViewClass, sizeof(WebKitWebViewPrivate)); @@ -494,75 +518,40 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) G_TYPE_NONE, 0); /** - * WebKitWebView::script-alert: - * @web_view: the #WebKitWebView on which the signal is emitted - * @message: the message text - * - * Emitted when JavaScript code calls <function>window.alert</function>. If the - * signal is not handled a message dialog with a single Close button will be - * shown with the message text. - * - * Returns: %TRUE to stop other handlers from being invoked for the event. - * %FALSE to propagate the event further. - */ - signals[SCRIPT_ALERT] = - g_signal_new("script-alert", - G_TYPE_FROM_CLASS(webViewClass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitWebViewClass, script_alert), - g_signal_accumulator_true_handled, 0, - webkit_marshal_BOOLEAN__STRING, - G_TYPE_BOOLEAN, 1, - G_TYPE_STRING); - - /** - * WebKitWebView::script-confirm: - * @web_view: the #WebKitWebView on which the signal is emitted - * @message: the message text - * @confirmed: (out): return location for confirm dialog response - * - * Emitted when JavaScript code calls <function>confirm</function>. If the - * signal is not handled a message dialog with OK and Cancel buttons will be - * shown with the message text. If OK button is clicked @confirmed will be - * set to %TRUE, otherwise it will be %FALSE. - * - * Returns: %TRUE to stop other handlers from being invoked for the event. - * %FALSE to propagate the event further. - */ - signals[SCRIPT_CONFIRM] = - g_signal_new("script-confirm", - G_TYPE_FROM_CLASS(webViewClass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitWebViewClass, script_confirm), - g_signal_accumulator_true_handled, 0, - webkit_marshal_BOOLEAN__STRING_POINTER, - G_TYPE_BOOLEAN, 2, - G_TYPE_STRING, G_TYPE_POINTER); - - /** - * WebKitWebView::script-prompt: + * WebKitWebView::script-dialog: * @web_view: the #WebKitWebView on which the signal is emitted - * @message: the message text - * @default (allow-none): the default text - * @text: (out): return location for prompt dialog text response + * @dialog: the #WebKitScriptDialog to show * - * Emitted when JavaScript code calls <function>prompt</function>. If the - * signal is not handled a message dialog with OK and Cancel buttons and - * a text entry will be shown with the message text. If OK button is clicked - * @text will contain the text entered by the user, otherwise it will be %NULL. + * Emitted when JavaScript code calls <function>window.alert</function>, + * <function>window.confirm</function> or <function>window.prompt</function>. + * The @dialog parameter should be used to build the dialog. + * If the signal is not handled a different dialog will be built and shown depending + * on the dialog type: + * <itemizedlist> + * <listitem><para> + * %WEBKIT_SCRIPT_DIALOG_ALERT: message dialog with a single Close button. + * </para></listitem> + * <listitem><para> + * %WEBKIT_SCRIPT_DIALOG_CONFIRM: message dialog with OK and Cancel buttons. + * </para></listitem> + * <listitem><para> + * %WEBKIT_SCRIPT_DIALOG_PROMPT: message dialog with OK and Cancel buttons and + * a text entry with the default text. + * </para></listitem> + * </itemizedlist> * * Returns: %TRUE to stop other handlers from being invoked for the event. * %FALSE to propagate the event further. */ - signals[SCRIPT_PROMPT] = - g_signal_new("script-prompt", - G_TYPE_FROM_CLASS(webViewClass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(WebKitWebViewClass, script_prompt), - g_signal_accumulator_true_handled, 0, - webkit_marshal_BOOLEAN__STRING_STRING_POINTER, - G_TYPE_BOOLEAN, 3, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); + signals[SCRIPT_DIALOG] = + g_signal_new("script-dialog", + G_TYPE_FROM_CLASS(webViewClass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(WebKitWebViewClass, script_dialog), + g_signal_accumulator_true_handled, 0, + webkit_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, 1, + WEBKIT_TYPE_SCRIPT_DIALOG | G_SIGNAL_TYPE_STATIC_SCOPE); /** * WebKitWebView::decide-policy: @@ -679,14 +668,30 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) WEBKIT_TYPE_PRINT_OPERATION); } -void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent) +static bool updateReplaceContentStatus(WebKitWebView* webView, WebKitLoadEvent loadEvent) { - if (webView->priv->replacingContent) { + if (webView->priv->replaceContentStatus == ReplacingContent) { if (loadEvent == WEBKIT_LOAD_FINISHED) - webView->priv->replacingContent = false; - return; + webView->priv->replaceContentStatus = DidReplaceContent; + return true; + } + + if (loadEvent == WEBKIT_LOAD_STARTED) { + if (webView->priv->replaceContentStatus == WillReplaceContent) { + webView->priv->replaceContentStatus = ReplacingContent; + return true; + } + webView->priv->replaceContentStatus = NotReplacingContent; } + return false; +} + +void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent) +{ + if (updateReplaceContentStatus(webView, loadEvent)) + return; + if (loadEvent != WEBKIT_LOAD_FINISHED) webkitWebViewUpdateURI(webView); g_signal_emit(webView, signals[LOAD_CHANGED], 0, loadEvent); @@ -694,7 +699,7 @@ void webkitWebViewLoadChanged(WebKitWebView* webView, WebKitLoadEvent loadEvent) void webkitWebViewLoadFailed(WebKitWebView* webView, WebKitLoadEvent loadEvent, const char* failingURI, GError *error) { - if (webView->priv->replacingContent) + if (webView->priv->replaceContentStatus == ReplacingContent) return; gboolean returnValue; @@ -714,7 +719,7 @@ void webkitWebViewSetTitle(WebKitWebView* webView, const CString& title) void webkitWebViewSetEstimatedLoadProgress(WebKitWebView* webView, double estimatedLoadProgress) { - if (webView->priv->replacingContent) + if (webView->priv->replaceContentStatus != NotReplacingContent) return; if (webView->priv->estimatedLoadProgress == estimatedLoadProgress) @@ -763,23 +768,25 @@ void webkitWebViewClosePage(WebKitWebView* webView) void webkitWebViewRunJavaScriptAlert(WebKitWebView* webView, const CString& message) { + WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_ALERT, message); gboolean returnValue; - g_signal_emit(webView, signals[SCRIPT_ALERT], 0, message.data(), &returnValue); + g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue); } bool webkitWebViewRunJavaScriptConfirm(WebKitWebView* webView, const CString& message) { - gboolean returnValue, confirmed; - g_signal_emit(webView, signals[SCRIPT_CONFIRM], 0, message.data(), &confirmed, &returnValue); - return confirmed; + WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_CONFIRM, message); + gboolean returnValue; + g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue); + return dialog.confirmed; } WKStringRef webkitWebViewRunJavaScriptPrompt(WebKitWebView* webView, const CString& message, const CString& defaultText) { + WebKitScriptDialog dialog(WEBKIT_SCRIPT_DIALOG_PROMPT, message, defaultText); gboolean returnValue; - GOwnPtr<char> text; - g_signal_emit(webView, signals[SCRIPT_PROMPT], 0, message.data(), defaultText.data(), &text.outPtr(), &returnValue); - return text ? WKStringCreateWithUTF8CString(text.get()) : 0; + g_signal_emit(webView, signals[SCRIPT_DIALOG], 0, &dialog, &returnValue); + return dialog.text.isNull() ? 0 : WKStringCreateWithUTF8CString(dialog.text.data()); } void webkitWebViewMakePolicyDecision(WebKitWebView* webView, WebKitPolicyDecisionType type, WebKitPolicyDecision* decision) @@ -965,7 +972,7 @@ void webkit_web_view_replace_content(WebKitWebView* webView, const gchar* conten g_return_if_fail(content); g_return_if_fail(contentURI); - webView->priv->replacingContent = true; + webView->priv->replaceContentStatus = WillReplaceContent; WKRetainPtr<WKStringRef> htmlString(AdoptWK, WKStringCreateWithUTF8CString(content)); WKRetainPtr<WKURLRef> contentURL(AdoptWK, WKURLCreateWithUTF8CString(contentURI)); @@ -1279,8 +1286,8 @@ void webkit_web_view_set_settings(WebKitWebView* webView, WebKitSettings* settin if (webView->priv->settings == settings) return; - webView->priv->settings = settings; - webkitSettingsAttachSettingsToPage(settings, toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)))); + g_signal_handlers_disconnect_by_func(webView->priv->settings.get(), reinterpret_cast<gpointer>(zoomTextOnlyChanged), webView); + webkitWebViewSetSettings(webView, settings, toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView)))); } /** @@ -1338,11 +1345,14 @@ void webkit_web_view_set_zoom_level(WebKitWebView* webView, gdouble zoomLevel) { g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView)); - WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); - if (WKPageGetPageZoomFactor(wkPage) == zoomLevel) + if (webkit_web_view_get_zoom_level(webView) == zoomLevel) return; - WKPageSetPageZoomFactor(wkPage, zoomLevel); + WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); + if (webkit_settings_get_zoom_text_only(webView->priv->settings.get())) + WKPageSetTextZoomFactor(wkPage, zoomLevel); + else + WKPageSetPageZoomFactor(wkPage, zoomLevel); g_object_notify(G_OBJECT(webView), "zoom-level"); } @@ -1360,10 +1370,10 @@ gdouble webkit_web_view_get_zoom_level(WebKitWebView* webView) g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 1); WKPageRef wkPage = toAPI(webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(webView))); - return WKPageGetPageZoomFactor(wkPage); + gboolean zoomTextOnly = webkit_settings_get_zoom_text_only(webView->priv->settings.get()); + return zoomTextOnly ? WKPageGetTextZoomFactor(wkPage) : WKPageGetPageZoomFactor(wkPage); } - static void didValidateCommand(WKStringRef command, bool isEnabled, int32_t state, WKErrorRef, void* context) { GRefPtr<GSimpleAsyncResult> result = adoptGRef(G_SIMPLE_ASYNC_RESULT(context)); @@ -1436,3 +1446,23 @@ void webkit_web_view_execute_editing_command(WebKitWebView* webView, const char* WKRetainPtr<WKStringRef> wkCommand(AdoptWK, WKStringCreateWithUTF8CString(command)); WKPageExecuteCommand(toAPI(page), wkCommand.get()); } + +/** + * webkit_web_view_get_find_controller: + * @web_view: the #WebKitWebView + * + * Gets the #WebKitFindController that will allow the caller to query + * the #WebKitWebView for the text to look for. + * + * Returns: (transfer none): the #WebKitFindController associated to + * this particular #WebKitWebView. + */ +WebKitFindController* webkit_web_view_get_find_controller(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); + + if (!webView->priv->findController) + webView->priv->findController = adoptGRef(WEBKIT_FIND_CONTROLLER(g_object_new(WEBKIT_TYPE_FIND_CONTROLLER, "web-view", webView, NULL))); + + return webView->priv->findController.get(); +} diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h index a1b21420b..fb4c48a2d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitWebView.h @@ -30,7 +30,9 @@ #include <webkit2/WebKitBackForwardList.h> #include <webkit2/WebKitDefines.h> +#include <webkit2/WebKitFindController.h> #include <webkit2/WebKitHitTestResult.h> +#include <webkit2/WebKitScriptDialog.h> #include <webkit2/WebKitSettings.h> #include <webkit2/WebKitURIRequest.h> #include <webkit2/WebKitWebContext.h> @@ -47,7 +49,6 @@ G_BEGIN_DECLS #define WEBKIT_IS_WEB_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), WEBKIT_TYPE_WEB_VIEW)) #define WEBKIT_WEB_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), WEBKIT_TYPE_WEB_VIEW, WebKitWebViewClass)) -typedef struct _WebKitWebView WebKitWebView; typedef struct _WebKitWebViewClass WebKitWebViewClass; typedef struct _WebKitWebViewPrivate WebKitWebViewPrivate; @@ -77,7 +78,7 @@ typedef struct _WebKitWebViewPrivate WebKitWebViewPrivate; * or to block the transfer of resources entirely. * * Enum values used for determining the type of a policy decision during - * WebKitWebView::decide-policy. + * #WebKitWebView::decide-policy. */ typedef enum { WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION, @@ -86,7 +87,7 @@ typedef enum { } WebKitPolicyDecisionType; /** - * WebKitLoadEvent + * WebKitLoadEvent: * @WEBKIT_LOAD_STARTED: A new load request has been made. * No data has been received yet, empty structures have * been allocated to perform the load; the load may still @@ -99,6 +100,9 @@ typedef enum { * load is being performed. * @WEBKIT_LOAD_FINISHED: Load completed. All resources are done loading * or there was an error during the load operation. + * + * Enum values used to denote the different events that happen during a + * #WebKitWebView load operation. */ typedef enum { WEBKIT_LOAD_STARTED, @@ -128,15 +132,9 @@ struct _WebKitWebViewClass { void (* ready_to_show) (WebKitWebView *web_view); void (* close) (WebKitWebView *web_view); - gboolean (* script_alert) (WebKitWebView *web_view, - const gchar *message); - gboolean (* script_confirm) (WebKitWebView *web_view, - const gchar *message, - gboolean *confirmed); - gboolean (* script_prompt) (WebKitWebView *web_view, - const gchar *message, - const gchar *default_text, - gchar **text); + gboolean (* script_dialog) (WebKitWebView *web_view, + WebKitScriptDialog *dialog); + gboolean (* decide_policy) (WebKitWebView *web_view, WebKitPolicyDecision *decision, WebKitPolicyDecisionType type); @@ -265,6 +263,10 @@ webkit_web_view_can_execute_editing_command_finish (WebKitWebView *w WEBKIT_API void webkit_web_view_execute_editing_command (WebKitWebView *web_view, const gchar *command); + +WEBKIT_API WebKitFindController * +webkit_web_view_get_find_controller (WebKitWebView *web_view); + G_END_DECLS #endif diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml index 5cd859dad..4a9cc798c 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml @@ -27,6 +27,7 @@ <xi:include href="xml/WebKitHitTestResult.xml"/> <xi:include href="xml/WebKitPrintOperation.xml"/> <xi:include href="xml/WebKitError.xml"/> + <xi:include href="xml/WebKitFindController.xml"/> </chapter> <index id="index-all"> diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt index 5bfc129b2..a8f54083a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt @@ -49,6 +49,8 @@ webkit_web_context_get_type WebKitWebView WebKitLoadEvent WebKitPolicyDecisionType +WebKitScriptDialog +WebKitScriptDialogType <SUBSECTION Editing Commands> WEBKIT_EDITING_COMMAND_CUT @@ -86,6 +88,12 @@ webkit_web_view_get_zoom_level webkit_web_view_can_execute_editing_command webkit_web_view_can_execute_editing_command_finish webkit_web_view_execute_editing_command +webkit_web_view_get_find_controller +webkit_script_dialog_get_dialog_type +webkit_script_dialog_get_message +webkit_script_dialog_confirm_set_confirmed +webkit_script_dialog_prompt_get_default_text +webkit_script_dialog_prompt_set_text <SUBSECTION Standard> WebKitWebViewClass @@ -95,9 +103,11 @@ WEBKIT_TYPE_WEB_VIEW WEBKIT_WEB_VIEW_CLASS WEBKIT_IS_WEB_VIEW_CLASS WEBKIT_WEB_VIEW_GET_CLASS +WEBKIT_TYPE_SCRIPT_DIALOG <SUBSECTION Private> webkit_web_view_get_type +webkit_script_dialog_get_type WebKitWebViewPrivate </SECTION> @@ -220,6 +230,8 @@ webkit_settings_get_enable_webaudio webkit_settings_set_enable_webaudio webkit_settings_get_enable_webgl webkit_settings_set_enable_webgl +webkit_settings_get_zoom_text_only +webkit_settings_set_zoom_text_only <SUBSECTION Standard> WebKitSettingsClass @@ -461,3 +473,30 @@ webkit_policy_error_quark webkit_download_error_quark </SECTION> +<SECTION> +<FILE>WebKitFindController</FILE> +WebKitFindController +WebKitFindOptions +webkit_find_controller_search +webkit_find_controller_search_finish +webkit_find_controller_search_next +webkit_find_controller_search_previous +webkit_find_controller_get_search_text +webkit_find_controller_count_matches +webkit_find_controller_get_options +webkit_find_controller_get_max_match_count +webkit_find_controller_get_web_view + +<SUBSECTION Standard> +WebKitFindControllerClass +WEBKIT_TYPE_FIND_CONTROLLER +WEBKIT_FIND_CONTROLLER +WEBKIT_IS_FIND_CONTROLLER +WEBKIT_FIND_CONTROLLER_CLASS +WEBKIT_IS_FIND_CONTROLLER_CLASS +WEBKIT_FIND_CONTROLLER_GET_CLASS + +<SUBSECTION Private> +WebKitFindControllerPrivate +webkit_find_controller_get_type +</SECTION> diff --git a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types index cba2df42c..8e8d7b13a 100644 --- a/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types +++ b/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk.types @@ -9,4 +9,5 @@ webkit_uri_response_get_type webkit_uri_request_get_type webkit_window_properties_get_type webkit_download_get_type - +webkit_find_controller_get_type +webkit_script_dialog_get_type diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am index 35ece6845..6adb2d5cd 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am +++ b/Source/WebKit2/UIProcess/API/gtk/tests/GNUmakefile.am @@ -1,15 +1,16 @@ if ENABLE_WEBKIT2 TEST_PROGS += \ - Programs/WebKit2APITests/TestWebKitWebContext \ - Programs/WebKit2APITests/TestWebKitWebView \ - Programs/WebKit2APITests/TestLoaderClient \ - Programs/WebKit2APITests/TestWebKitSettings \ Programs/WebKit2APITests/TestBackForwardList \ Programs/WebKit2APITests/TestDownloads \ + Programs/WebKit2APITests/TestLoaderClient \ + Programs/WebKit2APITests/TestPrinting \ + Programs/WebKit2APITests/TestWebKitFindController \ Programs/WebKit2APITests/TestWebKitPolicyClient \ - Programs/WebKit2APITests/TestWebViewEditor \ - Programs/WebKit2APITests/TestPrinting + Programs/WebKit2APITests/TestWebKitSettings \ + Programs/WebKit2APITests/TestWebKitWebContext \ + Programs/WebKit2APITests/TestWebKitWebView \ + Programs/WebKit2APITests/TestWebViewEditor noinst_PROGRAMS += $(TEST_PROGS) @@ -128,4 +129,10 @@ Programs_WebKit2APITests_TestPrinting_CPPFLAGS = $(webkit2_tests_cppflags) $(GTK Programs_WebKit2APITests_TestPrinting_LDADD = $(webkit2_tests_ldadd) $(GTK_UNIX_PRINTING_LIBS) Programs_WebKit2APITests_TestPrinting_LDFLAGS = $(webkit2_tests_ldflags) +Programs_WebKit2APITests_TestWebKitFindController_SOURCES = \ + Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitFindController.cpp +Programs_WebKit2APITests_TestWebKitFindController_CPPFLAGS = $(webkit2_tests_cppflags) +Programs_WebKit2APITests_TestWebKitFindController_LDADD = $(webkit2_tests_ldadd) +Programs_WebKit2APITests_TestWebKitFindController_LDFLAGS = $(webkit2_tests_ldflags) + endif # ENABLE_WEBKIT2 diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitFindController.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitFindController.cpp new file mode 100644 index 000000000..ae9ff2f7a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitFindController.cpp @@ -0,0 +1,379 @@ +/* + * Copyright (C) 2012 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,1 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include "LoadTrackingTest.h" +#include <gtk/gtk.h> +#include <webkit2/webkit2.h> +#include <wtf/gobject/GRefPtr.h> + +static const char* testString = "<html><body>first testing second testing secondHalf</body></html>"; + +class FindControllerTest: public WebViewTest { +public: + MAKE_GLIB_TEST_FIXTURE(FindControllerTest); + + FindControllerTest() + : m_findController(webkit_web_view_get_find_controller(m_webView)) + , m_runFindUntilCompletion(false) + { + assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_findController.get())); + } + + ~FindControllerTest() + { + if (m_findController) + g_signal_handlers_disconnect_matched(m_findController.get(), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this); + } + + void find(const char* searchText, guint32 findOptions, guint maxMatchCount) + { + g_signal_connect(m_findController.get(), "found-text", G_CALLBACK(foundTextCallback), this); + g_signal_connect(m_findController.get(), "failed-to-find-text", G_CALLBACK(failedToFindTextCallback), this); + webkit_find_controller_search(m_findController.get(), searchText, findOptions, maxMatchCount); + } + + void count(const char* searchText, guint32 findOptions, guint maxMatchCount) + { + g_signal_connect(m_findController.get(), "counted-matches", G_CALLBACK(countedMatchesCallback), this); + webkit_find_controller_count_matches(m_findController.get(), searchText, findOptions, maxMatchCount); + } + + void waitUntilFindFinished() + { + m_runFindUntilCompletion = true; + g_main_loop_run(m_mainLoop); + } + + void waitUntilWebViewDrawSignal() + { + g_signal_connect_after(m_webView, "draw", G_CALLBACK(webViewDraw), this); + g_main_loop_run(m_mainLoop); + } + + GRefPtr<WebKitFindController> m_findController; + bool m_textFound; + unsigned m_matchCount; + +private: + bool m_runFindUntilCompletion; + + static void webViewDraw(GtkWidget *widget, cairo_t *cr, FindControllerTest* test) + { + g_main_loop_quit(test->m_mainLoop); + g_signal_handlers_disconnect_matched(widget, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, test); + } + + static void foundTextCallback(WebKitFindController*, guint matchCount, FindControllerTest* test) + { + test->m_textFound = true; + test->m_matchCount = matchCount; + if (test->m_runFindUntilCompletion) + g_main_loop_quit(test->m_mainLoop); + } + + static void failedToFindTextCallback(WebKitFindController*, FindControllerTest* test) + { + test->m_textFound = false; + if (test->m_runFindUntilCompletion) + g_main_loop_quit(test->m_mainLoop); + } + + static void countedMatchesCallback(WebKitFindController*, guint matchCount, FindControllerTest* test) + { + test->m_matchCount = matchCount; + if (test->m_runFindUntilCompletion) + g_main_loop_quit(test->m_mainLoop); + } +}; + +static void testFindControllerTextFound(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 1); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); +} + +static void testFindControllerTextNotFound(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("notFound", WEBKIT_FIND_OPTIONS_NONE, 1); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); +} + +static void testFindControllerMatchCount(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == 2); + g_assert(test->m_textFound); +} + +static void testFindControllerMaxMatchCount(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 1); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == G_MAXUINT); + g_assert(test->m_textFound); +} + +static void testFindControllerNext(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + g_assert(test->m_matchCount == 2); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + g_assert(test->m_matchCount == 2); + g_assert(!(webkit_find_controller_get_options(test->m_findController.get()) & WEBKIT_FIND_OPTIONS_BACKWARDS)); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); + g_assert(test->m_matchCount == 2); + g_assert(!(webkit_find_controller_get_options(test->m_findController.get()) & WEBKIT_FIND_OPTIONS_BACKWARDS)); +} + +static void testFindControllerPrevious(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == 2); + g_assert(test->m_textFound); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + g_assert(test->m_matchCount == 2); + g_assert(!(webkit_find_controller_get_options(test->m_findController.get()) & WEBKIT_FIND_OPTIONS_BACKWARDS)); + + webkit_find_controller_search_previous(test->m_findController.get()); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + g_assert(test->m_matchCount == 2); + g_assert(webkit_find_controller_get_options(test->m_findController.get()) & WEBKIT_FIND_OPTIONS_BACKWARDS); +} + +static void testFindControllerCountedMatches(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->count("testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == 2); + + test->count("first", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_matchCount == 1); + + test->count("notFound", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(!test->m_matchCount); +} + +static void testFindControllerOptions(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->find("Testing", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); + + test->find("Testing", WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + + test->find("esting", WEBKIT_FIND_OPTIONS_NONE, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + + test->find("esting", WEBKIT_FIND_OPTIONS_AT_WORD_STARTS, 2); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); + + test->find("Half", WEBKIT_FIND_OPTIONS_AT_WORD_STARTS, 2); + test->waitUntilFindFinished(); + + g_assert(!test->m_textFound); + + test->find("Half", WEBKIT_FIND_OPTIONS_AT_WORD_STARTS | WEBKIT_FIND_OPTIONS_TREAT_MEDIAL_CAPITAL_AS_WORD_START, 2); + test->waitUntilFindFinished(); + + g_assert(test->m_textFound); + + test->find("testing", WEBKIT_FIND_OPTIONS_WRAP_AROUND, 3); + test->waitUntilFindFinished(); + g_assert(test->m_textFound); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + g_assert(test->m_textFound); + + webkit_find_controller_search_next(test->m_findController.get()); + test->waitUntilFindFinished(); + g_assert(test->m_textFound); +} + +static gboolean gdkPixbufEqual(GdkPixbuf* firstPixbuf, GdkPixbuf* secondPixbuf) +{ + if (gdk_pixbuf_get_bits_per_sample(firstPixbuf) != gdk_pixbuf_get_bits_per_sample(secondPixbuf) + || gdk_pixbuf_get_has_alpha(firstPixbuf) != gdk_pixbuf_get_has_alpha(secondPixbuf) + || gdk_pixbuf_get_height(firstPixbuf) != gdk_pixbuf_get_height(secondPixbuf) + || gdk_pixbuf_get_n_channels(firstPixbuf) != gdk_pixbuf_get_n_channels(secondPixbuf) + || gdk_pixbuf_get_rowstride(firstPixbuf) != gdk_pixbuf_get_rowstride(secondPixbuf) + || gdk_pixbuf_get_width(firstPixbuf) != gdk_pixbuf_get_width(secondPixbuf)) + return FALSE; + + int pixbufRowstride = gdk_pixbuf_get_rowstride(firstPixbuf); + int pixbufHeight = gdk_pixbuf_get_height(firstPixbuf); + int pixbufWidth = gdk_pixbuf_get_width(firstPixbuf); + int numberOfChannels = gdk_pixbuf_get_n_channels(firstPixbuf); + int bitsPerSample = gdk_pixbuf_get_bits_per_sample(firstPixbuf); + + // Last row can be of different length. Taken from gdk-pixbuf documentation. + int totalLength = (pixbufHeight - 1) * pixbufRowstride \ + + pixbufWidth * ((numberOfChannels * bitsPerSample + 7) / 8); + + guchar* firstPixels = gdk_pixbuf_get_pixels(firstPixbuf); + guchar* secondPixels = gdk_pixbuf_get_pixels(secondPixbuf); + for (int i = 0; i < totalLength; i++) + if (firstPixels[i] != secondPixels[i]) + return FALSE; + + return TRUE; +} + +static void testFindControllerHide(FindControllerTest* test, gconstpointer) +{ + test->loadHtml(testString, 0); + test->waitUntilLoadFinished(); + + test->showInWindowAndWaitUntilMapped(); + int allocatedHeight = gtk_widget_get_allocated_height(GTK_WIDGET(test->m_webView)); + int allocatedWidth = gtk_widget_get_allocated_width(GTK_WIDGET(test->m_webView)); + GdkWindow* webViewGdkWindow = gtk_widget_get_window(GTK_WIDGET(test->m_webView)); + g_assert(webViewGdkWindow); + + test->waitUntilWebViewDrawSignal(); + GRefPtr<GdkPixbuf> originalPixbuf = gdk_pixbuf_get_from_window(webViewGdkWindow, 0, 0, allocatedHeight, allocatedWidth); + g_assert(originalPixbuf); + + test->find("testing", WEBKIT_FIND_OPTIONS_NONE, 1); + test->waitUntilFindFinished(); + g_assert(test->m_textFound); + + test->waitUntilWebViewDrawSignal(); + GRefPtr<GdkPixbuf> highlightPixbuf = gdk_pixbuf_get_from_window(webViewGdkWindow, 0, 0, allocatedHeight, allocatedWidth); + g_assert(highlightPixbuf); + g_assert(!gdkPixbufEqual(originalPixbuf.get(), highlightPixbuf.get())); + +#if (0) + // Requires http://webkit.org/b/77747 to be fixed + WebKitFindController* findController = webkit_web_view_get_find_controller(test->m_webView); + webkit_find_controller_search_finish(findController); + webkit_web_view_execute_editing_command(test->m_webView, "Unselect"); + + test->waitUntilWebViewDrawSignal(); + GRefPtr<GdkPixbuf> unhighlightPixbuf = gdk_pixbuf_get_from_window(webViewGdkWindow, 0, 0, allocatedHeight, allocatedWidth); + g_assert(unhighlightPixbuf); + g_assert(gdkPixbufEqual(originalPixbuf.get(), unhighlightPixbuf.get())); +#endif +} + +static void testFindControllerInstance(FindControllerTest* test, gconstpointer) +{ + WebKitFindController* findController1 = webkit_web_view_get_find_controller(test->m_webView); + WebKitFindController* findController2 = webkit_web_view_get_find_controller(test->m_webView); + + g_assert(findController1 == findController2); +} + +static void testFindControllerGetters(FindControllerTest* test, gconstpointer) +{ + const char* searchText = "testing"; + guint maxMatchCount = 1; + guint32 findOptions = WEBKIT_FIND_OPTIONS_WRAP_AROUND | WEBKIT_FIND_OPTIONS_AT_WORD_STARTS; + WebKitFindController* findController = webkit_web_view_get_find_controller(test->m_webView); + + webkit_find_controller_search(findController, searchText, findOptions, maxMatchCount); + g_assert(webkit_find_controller_get_web_view(findController) == test->m_webView); + g_assert(!g_strcmp0(webkit_find_controller_get_search_text(findController), searchText)); + g_assert(webkit_find_controller_get_max_match_count(findController) == maxMatchCount); + g_assert(webkit_find_controller_get_options(findController) == findOptions); +} + +void beforeAll() +{ + FindControllerTest::add("WebKitFindController", "getters", testFindControllerGetters); + FindControllerTest::add("WebKitFindController", "instance", testFindControllerInstance); + FindControllerTest::add("WebKitFindController", "text-found", testFindControllerTextFound); + FindControllerTest::add("WebKitFindController", "text-not-found", testFindControllerTextNotFound); + FindControllerTest::add("WebKitFindController", "match-count", testFindControllerMatchCount); + FindControllerTest::add("WebKitFindController", "max-match-count", testFindControllerMaxMatchCount); + FindControllerTest::add("WebKitFindController", "next", testFindControllerNext); + FindControllerTest::add("WebKitFindController", "previous", testFindControllerPrevious); + FindControllerTest::add("WebKitFindController", "counted-matches", testFindControllerCountedMatches); + FindControllerTest::add("WebKitFindController", "options", testFindControllerOptions); + FindControllerTest::add("WebKitFindController", "hide", testFindControllerHide); +} + +void afterAll() +{ +} diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp index a3ce7dece..03c5f2fe8 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitSettings.cpp @@ -199,6 +199,11 @@ static void testWebKitSettings(Test*, gconstpointer) webkit_settings_set_enable_webgl(settings, TRUE); g_assert(webkit_settings_get_enable_webgl(settings)); + // Zoom text only is disabled by default. + g_assert(!webkit_settings_get_zoom_text_only(settings)); + webkit_settings_set_zoom_text_only(settings, TRUE); + g_assert(webkit_settings_get_zoom_text_only(settings)); + g_object_unref(G_OBJECT(settings)); } diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp index 47da98eb3..bfeda169f 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/TestWebKitWebView.cpp @@ -71,24 +71,22 @@ static void testWebViewSettings(WebViewTest* test, gconstpointer) g_assert(webkit_settings_get_enable_javascript(settings)); } -static void replaceContentTitleChangedCallback(WebViewTest* test) +static void replaceContentLoadCallback(WebKitWebView* webView, WebKitLoadEvent loadEvent, WebViewTest* test) { - g_main_loop_quit(test->m_mainLoop); -} - -static void replaceContentLoadCallback() -{ - g_assert_not_reached(); + // There might be an event from a previous load, + // but never a WEBKIT_LOAD_STARTED after webkit_web_view_replace_content(). + g_assert_cmpint(loadEvent, !=, WEBKIT_LOAD_STARTED); } static void testWebViewReplaceContent(WebViewTest* test, gconstpointer) { - g_signal_connect_swapped(test->m_webView, "notify::title", G_CALLBACK(replaceContentTitleChangedCallback), test); + test->loadHtml("<html><head><title>Replace Content Test</title></head><body>Content to replace</body></html>", 0); + test->waitUntilTitleChangedTo("Replace Content Test"); + g_signal_connect(test->m_webView, "load-changed", G_CALLBACK(replaceContentLoadCallback), test); - g_signal_connect(test->m_webView, "load-failed", G_CALLBACK(replaceContentLoadCallback), test); - test->replaceContent("<html><head><title>Content Replaced</title></head><body>New Content</body></html>", + test->replaceContent("<html><body onload='document.title=\"Content Replaced\"'>New Content</body></html>", "http://foo.com/bar", 0); - g_main_loop_run(test->m_mainLoop); + test->waitUntilTitleChangedTo("Content Replaced"); } static const char* kAlertDialogMessage = "WebKitGTK+ alert dialog message"; @@ -106,12 +104,6 @@ public: Close }; - enum ScriptType { - Alert, - Confirm, - Prompt - }; - class WindowProperties { public: WindowProperties() @@ -226,43 +218,52 @@ public: return newWebView; } - static gboolean scriptAlert(WebKitWebView*, const char* message, UIClientTest* test) + void scriptAlert(WebKitScriptDialog* dialog) { - switch (test->m_scriptType) { - case UIClientTest::Alert: - g_assert_cmpstr(message, ==, kAlertDialogMessage); + switch (m_scriptDialogType) { + case WEBKIT_SCRIPT_DIALOG_ALERT: + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kAlertDialogMessage); break; - case UIClientTest::Confirm: - g_assert(test->m_scriptDialogConfirmed); - g_assert_cmpstr(message, ==, "confirmed"); + case WEBKIT_SCRIPT_DIALOG_CONFIRM: + g_assert(m_scriptDialogConfirmed); + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, "confirmed"); break; - case UIClientTest::Prompt: - g_assert_cmpstr(message, ==, kPromptDialogReturnedText); + case WEBKIT_SCRIPT_DIALOG_PROMPT: + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kPromptDialogReturnedText); break; } - g_main_loop_quit(test->m_mainLoop); - - return TRUE; + g_main_loop_quit(m_mainLoop); } - static gboolean scriptConfirm(WebKitWebView*, const char* message, gboolean* confirmed, UIClientTest* test) + void scriptConfirm(WebKitScriptDialog* dialog) { - g_assert_cmpstr(message, ==, kConfirmDialogMessage); - g_assert(confirmed); - test->m_scriptDialogConfirmed = !test->m_scriptDialogConfirmed; - *confirmed = test->m_scriptDialogConfirmed; + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kConfirmDialogMessage); + m_scriptDialogConfirmed = !m_scriptDialogConfirmed; + webkit_script_dialog_confirm_set_confirmed(dialog, m_scriptDialogConfirmed); + } - return TRUE; + void scriptPrompt(WebKitScriptDialog* dialog) + { + g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kPromptDialogMessage); + g_assert_cmpstr(webkit_script_dialog_prompt_get_default_text(dialog), ==, "default"); + webkit_script_dialog_prompt_set_text(dialog, kPromptDialogReturnedText); } - static gboolean scriptPrompt(WebKitWebView*, const char* message, const char* defaultText, char **text, UIClientTest* test) + static gboolean scriptDialog(WebKitWebView*, WebKitScriptDialog* dialog, UIClientTest* test) { - g_assert_cmpstr(message, ==, kPromptDialogMessage); - g_assert_cmpstr(defaultText, ==, "default"); - g_assert(text); - *text = g_strdup(kPromptDialogReturnedText); + switch (webkit_script_dialog_get_dialog_type(dialog)) { + case WEBKIT_SCRIPT_DIALOG_ALERT: + test->scriptAlert(dialog); + break; + case WEBKIT_SCRIPT_DIALOG_CONFIRM: + test->scriptConfirm(dialog); + break; + case WEBKIT_SCRIPT_DIALOG_PROMPT: + test->scriptPrompt(dialog); + break; + } return TRUE; } @@ -278,15 +279,13 @@ public: } UIClientTest() - : m_scriptType(Alert) + : m_scriptDialogType(WEBKIT_SCRIPT_DIALOG_ALERT) , m_scriptDialogConfirmed(true) , m_mouseTargetModifiers(0) { webkit_settings_set_javascript_can_open_windows_automatically(webkit_web_view_get_settings(m_webView), TRUE); g_signal_connect(m_webView, "create", G_CALLBACK(viewCreate), this); - g_signal_connect(m_webView, "script-alert", G_CALLBACK(scriptAlert), this); - g_signal_connect(m_webView, "script-confirm", G_CALLBACK(scriptConfirm), this); - g_signal_connect(m_webView, "script-prompt", G_CALLBACK(scriptPrompt), this); + g_signal_connect(m_webView, "script-dialog", G_CALLBACK(scriptDialog), this); g_signal_connect(m_webView, "mouse-target-changed", G_CALLBACK(mouseTargetChanged), this); } @@ -313,7 +312,7 @@ public: } Vector<WebViewEvents> m_webViewEvents; - ScriptType m_scriptType; + WebKitScriptDialogType m_scriptDialogType; bool m_scriptDialogConfirmed; WindowProperties m_windowProperties; HashSet<WTF::String> m_windowPropertiesChanged; @@ -340,19 +339,19 @@ static void testWebViewJavaScriptDialogs(UIClientTest* test, gconstpointer) static const char* jsConfirmFormat = "do { confirmed = confirm('%s'); } while (!confirmed); alert('confirmed');"; static const char* jsPromptFormat = "alert(prompt('%s', 'default'));"; - test->m_scriptType = UIClientTest::Alert; + test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_ALERT; GOwnPtr<char> alertDialogMessage(g_strdup_printf(jsAlertFormat, kAlertDialogMessage)); GOwnPtr<char> alertHTML(g_strdup_printf(htmlOnLoadFormat, alertDialogMessage.get())); test->loadHtml(alertHTML.get(), 0); test->waitUntilMainLoopFinishes(); - test->m_scriptType = UIClientTest::Confirm; + test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_CONFIRM; GOwnPtr<char> confirmDialogMessage(g_strdup_printf(jsConfirmFormat, kConfirmDialogMessage)); GOwnPtr<char> confirmHTML(g_strdup_printf(htmlOnLoadFormat, confirmDialogMessage.get())); test->loadHtml(confirmHTML.get(), 0); test->waitUntilMainLoopFinishes(); - test->m_scriptType = UIClientTest::Prompt; + test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_PROMPT; GOwnPtr<char> promptDialogMessage(g_strdup_printf(jsPromptFormat, kPromptDialogMessage)); GOwnPtr<char> promptHTML(g_strdup_printf(htmlOnLoadFormat, promptDialogMessage.get())); test->loadHtml(promptHTML.get(), 0); @@ -447,6 +446,10 @@ static void testWebViewZoomLevel(WebViewTest* test, gconstpointer) g_assert_cmpfloat(webkit_web_view_get_zoom_level(test->m_webView), ==, 1); webkit_web_view_set_zoom_level(test->m_webView, 2.5); g_assert_cmpfloat(webkit_web_view_get_zoom_level(test->m_webView), ==, 2.5); + + webkit_settings_set_zoom_text_only(webkit_web_view_get_settings(test->m_webView), TRUE); + // The zoom level shouldn't change when zoom-text-only setting changes. + g_assert_cmpfloat(webkit_web_view_get_zoom_level(test->m_webView), ==, 2.5); } void beforeAll() diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp index 00d3b3e20..31de72911 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp +++ b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.cpp @@ -136,6 +136,28 @@ void WebViewTest::waitUntilLoadFinished() g_main_loop_run(m_mainLoop); } +static void titleChanged(WebKitWebView* webView, GParamSpec*, WebViewTest* test) +{ + if (!test->m_expectedTitle.isNull() && test->m_expectedTitle != webkit_web_view_get_title(webView)) + return; + + g_signal_handlers_disconnect_by_func(webView, reinterpret_cast<void*>(titleChanged), test); + g_main_loop_quit(test->m_mainLoop); +} + +void WebViewTest::waitUntilTitleChangedTo(const char* expectedTitle) +{ + m_expectedTitle = expectedTitle; + g_signal_connect(m_webView, "notify::title", G_CALLBACK(titleChanged), this); + g_main_loop_run(m_mainLoop); + m_expectedTitle = CString(); +} + +void WebViewTest::waitUntilTitleChanged() +{ + waitUntilTitleChangedTo(0); +} + static gboolean parentWindowMapped(GtkWidget* widget, GdkEvent*, WebViewTest* test) { g_signal_handlers_disconnect_by_func(widget, reinterpret_cast<void*>(parentWindowMapped), test); diff --git a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h index 95a569cd6..01f468562 100644 --- a/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h +++ b/Source/WebKit2/UIProcess/API/gtk/tests/WebViewTest.h @@ -42,6 +42,8 @@ public: void wait(double seconds); void waitUntilLoadFinished(); + void waitUntilTitleChangedTo(const char* expectedTitle); + void waitUntilTitleChanged(); void showInWindowAndWaitUntilMapped(); void mouseMoveTo(int x, int y, unsigned int mouseModifiers = 0); @@ -50,6 +52,7 @@ public: GMainLoop* m_mainLoop; CString m_activeURI; GtkWidget* m_parentWindow; + CString m_expectedTitle; }; #endif // WebViewTest_h diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2.h b/Source/WebKit2/UIProcess/API/gtk/webkit2.h index f78b873a3..0a807bc3d 100644 --- a/Source/WebKit2/UIProcess/API/gtk/webkit2.h +++ b/Source/WebKit2/UIProcess/API/gtk/webkit2.h @@ -30,8 +30,10 @@ #include <webkit2/WebKitEditingCommands.h> #include <webkit2/WebKitEnumTypes.h> #include <webkit2/WebKitError.h> +#include <webkit2/WebKitFindController.h> #include <webkit2/WebKitHitTestResult.h> #include <webkit2/WebKitPrintOperation.h> +#include <webkit2/WebKitScriptDialog.h> #include <webkit2/WebKitSettings.h> #include <webkit2/WebKitURIRequest.h> #include <webkit2/WebKitURIResponse.h> diff --git a/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list b/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list index 77d269a75..5f7356039 100644 --- a/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list +++ b/Source/WebKit2/UIProcess/API/gtk/webkit2marshal.list @@ -1,15 +1,10 @@ +BOOLEAN:BOXED BOOLEAN:ENUM,STRING,POINTER BOOLEAN:OBJECT BOOLEAN:OBJECT,ENUM -BOOLEAN:OBJECT,STRING,POINTER -BOOLEAN:POINTER BOOLEAN:STRING -BOOLEAN:STRING,POINTER -BOOLEAN:STRING,STRING,POINTER -BOOLEAN:UINT64 -BOOLEAN:VOID OBJECT:VOID -VOID:ENUM VOID:OBJECT,UINT VOID:OBJECT,POINTER +VOID:UINT64 diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h index 953c378e1..dbe947a39 100644 --- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h @@ -37,10 +37,6 @@ namespace WebKit { class FindIndicatorWindow; -// NOTE: This does not use String::operator NSString*() since that function -// expects to be called on the thread running WebCore. -NSString* nsStringFromWebCoreString(const String&); - class PageClientImpl : public PageClient { public: static PassOwnPtr<PageClientImpl> create(WKView*); @@ -59,7 +55,8 @@ private: virtual bool isViewFocused(); virtual bool isViewVisible(); virtual bool isViewInWindow(); - + virtual LayerHostingMode layerHostingMode(); + virtual void processDidCrash(); virtual void pageClosed(); virtual void didRelaunchProcess(); @@ -95,6 +92,7 @@ private: virtual void enterAcceleratedCompositingMode(const LayerTreeContext&); virtual void exitAcceleratedCompositingMode(); + virtual void updateAcceleratedCompositingMode(const LayerTreeContext&); virtual void accessibilityWebProcessTokenReceived(const CoreIPC::DataReference&); diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm index 35e0e2e70..71a1a5075 100644 --- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm +++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm @@ -33,6 +33,7 @@ #import "WKAPICast.h" #import "WKStringCF.h" #import "WKViewInternal.h" +#import "StringUtilities.h" #import "WebContextMenuProxyMac.h" #import "WebEditCommandProxy.h" #import "WebPopupMenuProxyMac.h" @@ -51,6 +52,12 @@ - (NSCursor *)_cursorRectCursor; @end +#if HAVE(LAYER_HOSTING_IN_WINDOW_SERVER) +@interface NSWindow (WebNSWindowDetails) +- (BOOL)_hostsLayersInWindowServer; +@end +#endif + using namespace WebCore; using namespace WebKit; @@ -104,11 +111,6 @@ using namespace WebKit; namespace WebKit { -NSString* nsStringFromWebCoreString(const String& string) -{ - return string.impl() ? HardAutorelease(WKStringCopyCFString(0, toAPI(string.impl()))) : @""; -} - PassOwnPtr<PageClientImpl> PageClientImpl::create(WKView* wkView) { return adoptPtr(new PageClientImpl(wkView)); @@ -188,6 +190,18 @@ bool PageClientImpl::isViewInWindow() return [m_wkView window]; } +LayerHostingMode PageClientImpl::layerHostingMode() +{ +#if HAVE(LAYER_HOSTING_IN_WINDOW_SERVER) + if (![m_wkView window]) + return LayerHostingModeDefault; + + return [[m_wkView window] _hostsLayersInWindowServer] ? LayerHostingModeInWindowServer : LayerHostingModeDefault; +#else + return LayerHostingModeDefault; +#endif +} + void PageClientImpl::processDidCrash() { [m_wkView _processDidCrash]; @@ -341,6 +355,11 @@ void PageClientImpl::exitAcceleratedCompositingMode() { [m_wkView _exitAcceleratedCompositingMode]; } + +void PageClientImpl::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) +{ + [m_wkView _updateAcceleratedCompositingMode:layerTreeContext]; +} #endif // USE(ACCELERATED_COMPOSITING) void PageClientImpl::pluginFocusOrWindowFocusChanged(uint64_t pluginComplexTextInputIdentifier, bool pluginHasFocusAndWindowHasFocus) diff --git a/Source/WebKit2/UIProcess/API/mac/WKView.mm b/Source/WebKit2/UIProcess/API/mac/WKView.mm index d50a7269a..a326dd089 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKView.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKView.mm @@ -40,6 +40,7 @@ #import "PDFViewController.h" #import "PageClientImpl.h" #import "PasteboardTypes.h" +#import "StringUtilities.h" #import "TextChecker.h" #import "TextCheckerState.h" #import "TiledCoreAnimationDrawingAreaProxy.h" @@ -373,6 +374,7 @@ struct WKViewInterpretKeyEventsParameters { // Send back an empty string to the plug-in. This will disable text input. _data->_page->sendComplexTextInputToPlugin(_data->_pluginComplexTextInputIdentifier, String()); + _data->_pluginComplexTextInputIdentifier = 0; // Always reset the identifier when the plugin is disabled. } typedef HashMap<SEL, String> SelectorNameMap; @@ -1262,8 +1264,10 @@ static const short kIOHIDEventTypeScroll = 6; if (string) { _data->_page->sendComplexTextInputToPlugin(_data->_pluginComplexTextInputIdentifier, string); - if (!usingLegacyCocoaTextInput) + if (!usingLegacyCocoaTextInput) { _data->_pluginComplexTextInputState = PluginComplexTextInputDisabled; + _data->_pluginComplexTextInputIdentifier = 0; // Always reset the identifier when the plugin is disabled. + } } return didHandleEvent; @@ -2458,6 +2462,12 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I _data->_layerHostingView = nullptr; } +- (void)_updateAcceleratedCompositingMode:(const WebKit::LayerTreeContext&)layerTreeContext +{ + [self _exitAcceleratedCompositingMode]; + [self _enterAcceleratedCompositingMode:layerTreeContext]; +} + - (void)_setAccessibilityWebProcessToken:(NSData *)data { _data->_remoteAccessibilityChild = WKAXRemoteElementForToken(data); diff --git a/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h b/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h index fd3e152e9..83346d3f1 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h +++ b/Source/WebKit2/UIProcess/API/mac/WKViewInternal.h @@ -64,6 +64,7 @@ namespace WebKit { - (void)_enterAcceleratedCompositingMode:(const WebKit::LayerTreeContext&)layerTreeContext; - (void)_exitAcceleratedCompositingMode; +- (void)_updateAcceleratedCompositingMode:(const WebKit::LayerTreeContext&)layerTreeContext; - (void)_setAccessibilityWebProcessToken:(NSData *)data; diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp index d164a6b85..9293c972f 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp @@ -24,8 +24,10 @@ #include "LayerTreeHostProxy.h" #include "QtWebPageEventHandler.h" #include "TransformationMatrix.h" +#include "WebLayerTreeRenderer.h" #include "qquickwebpage_p_p.h" #include "qquickwebview_p.h" +#include <QPolygonF> #include <QtQuick/QQuickCanvas> #include <QtQuick/QSGGeometryNode> #include <QtQuick/QSGMaterial> @@ -36,6 +38,7 @@ QQuickWebPage::QQuickWebPage(QQuickWebView* viewportItem) , d(new QQuickWebPagePrivate(this, viewportItem)) { setFlag(ItemHasContents); + setClip(true); // We do the transform from the top left so the viewport can assume the position 0, 0 // is always where rendering starts. @@ -63,18 +66,6 @@ void QQuickWebPagePrivate::initialize(WebKit::WebPageProxy* webPageProxy) eventHandler.reset(new QtWebPageEventHandler(toAPI(webPageProxy), q, viewportItem)); } -static float computeEffectiveOpacity(const QQuickItem* item) -{ - if (!item) - return 1; - - float opacity = item->opacity(); - if (opacity < 0.01) - return 0; - - return opacity * computeEffectiveOpacity(item->parentItem()); -} - void QQuickWebPagePrivate::setDrawingAreaSize(const QSize& size) { DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); @@ -89,69 +80,109 @@ void QQuickWebPagePrivate::paint(QPainter* painter) webPageProxy->drawingArea()->paintLayerTree(painter); } -void QQuickWebPagePrivate::paintToCurrentGLContext() -{ - if (!q->isVisible()) - return; - - QTransform transform = q->itemTransform(0, 0); - transform.scale(contentsScale, contentsScale); - - float opacity = computeEffectiveOpacity(q); - QRectF clipRect = viewportItem->mapRectToScene(viewportItem->boundingRect()); - - if (!clipRect.isValid()) - return; - - DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); - if (!drawingArea) - return; - - drawingArea->paintToCurrentGLContext(transform, opacity, clipRect); -} - struct PageProxyNode : public QSGRenderNode { - PageProxyNode(QQuickWebPagePrivate* page) - : m_pagePrivate(page) + PageProxyNode(PassRefPtr<WebLayerTreeRenderer> renderer) + : m_renderer(renderer) + , m_scale(1) { } virtual StateFlags changedStates() { - return StateFlags(DepthState) | StencilState | ScissorState | ColorState | BlendState - | CullState | ViewportState; + return StateFlags(StencilState) | ColorState | BlendState; } - virtual void render(const RenderState &) + virtual void render(const RenderState&) { - if (m_pagePrivate) - m_pagePrivate->paintToCurrentGLContext(); + QMatrix4x4 renderMatrix = matrix() ? *matrix() : QMatrix4x4(); + + // Have to apply render scale manualy because it is not applied on page item. + // http://trac.webkit.org/changeset/104450 + renderMatrix.scale(m_scale); + + // FIXME: Support non-rectangular clippings. + layerTreeRenderer()->paintToCurrentGLContext(renderMatrix, inheritedOpacity(), clipRect()); } ~PageProxyNode() { - if (m_pagePrivate) - m_pagePrivate->resetPaintNode(); + layerTreeRenderer()->purgeGLResources(); } - QQuickWebPagePrivate* m_pagePrivate; + WebLayerTreeRenderer* layerTreeRenderer() const { return m_renderer.get(); } + void setScale(float scale) { m_scale = scale; } + +private: + QRectF clipRect() const + { + // Start with an invalid rect. + QRectF resultRect(0, 0, -1, -1); + + for (const QSGClipNode* clip = clipList(); clip; clip = clip->clipList()) { + QMatrix4x4 clipMatrix; + if (clip->matrix()) + clipMatrix = *clip->matrix(); + QRectF currentClip; + + if (clip->isRectangular()) + currentClip = clipMatrix.mapRect(clip->clipRect()); + else { + const QSGGeometry* geometry = clip->geometry(); + // Assume here that clipNode has only coordinate data. + const QSGGeometry::Point2D* geometryPoints = geometry->vertexDataAsPoint2D(); + + // Clip region should be at least triangle to make valid clip. + if (geometry->vertexCount() < 3) + continue; + + QPolygonF polygon; + + for (int i = 0; i < geometry->vertexCount(); i++) + polygon.append(clipMatrix.map(QPoint(geometryPoints[i].x, geometryPoints[i].y))); + currentClip = polygon.boundingRect(); + } + + if (currentClip.isEmpty()) + continue; + + if (resultRect.isValid()) + resultRect &= currentClip; + else + resultRect = currentClip; + } + + return resultRect; + } + + RefPtr<WebLayerTreeRenderer> m_renderer; + float m_scale; }; QSGNode* QQuickWebPage::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) { - if (!(flags() & ItemHasContents)) { - if (oldNode) - delete oldNode; - return 0; - } + if (!d->webPageProxy->drawingArea()) + return oldNode; + + LayerTreeHostProxy* layerTreeHostProxy = d->webPageProxy->drawingArea()->layerTreeHostProxy(); + WebLayerTreeRenderer* renderer = layerTreeHostProxy->layerTreeRenderer(); - PageProxyNode* proxyNode = static_cast<PageProxyNode*>(oldNode); - if (!proxyNode) { - proxyNode = new PageProxyNode(d); - d->m_paintNode = proxyNode; + PageProxyNode* node = static_cast<PageProxyNode*>(oldNode); + + if (node && node->layerTreeRenderer() != renderer) { + // This means that LayerTreeHostProxy was deleted and recreated while old paint node survived. + // This could happen if web process have crashed. In this case we have to recreate paint node. + delete node; + node = 0; } - return proxyNode; + renderer->syncRemoteContent(); + + if (!node) + node = new PageProxyNode(renderer); + + node->setScale(d->contentsScale); + + return node; } QtWebPageEventHandler* QQuickWebPage::eventHandler() const @@ -205,18 +236,8 @@ void QQuickWebPagePrivate::updateSize() viewportItem->updateContentsSize(scaledSize); } -void QQuickWebPagePrivate::resetPaintNode() -{ - m_paintNode = 0; - DrawingAreaProxy* drawingArea = webPageProxy->drawingArea(); - if (drawingArea && drawingArea->layerTreeHostProxy()) - drawingArea->layerTreeHostProxy()->purgeGLResources(); -} - QQuickWebPagePrivate::~QQuickWebPagePrivate() { - if (m_paintNode) - static_cast<PageProxyNode*>(m_paintNode)->m_pagePrivate = 0; } #include "moc_qquickwebpage_p.cpp" diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h index dfd223dbe..b28174124 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h @@ -41,7 +41,7 @@ public: void updateSize(); - void paintToCurrentGLContext(); + void paintToCurrentGLContext(const QTransform&, float opacity, const QRectF& clipRect); void paint(QPainter*); void resetPaintNode(); diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp index f40e28924..6e518ff12 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp @@ -23,7 +23,6 @@ #include "DownloadProxy.h" #include "DrawingAreaProxyImpl.h" -#include "QtDialogRunner.h" #include "QtDownloadManager.h" #include "QtWebContext.h" #include "QtWebIconDatabaseClient.h" @@ -38,6 +37,7 @@ #include "qquickwebpage_p_p.h" #include "qquickwebview_p_p.h" #include "qwebdownloaditem_p_p.h" +#include "qwebloadrequest_p.h" #include "qwebnavigationhistory_p.h" #include "qwebnavigationhistory_p_p.h" #include "qwebpreferences_p.h" @@ -79,9 +79,12 @@ QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* viewport) , userDidOverrideContentHeight(false) , m_navigatorQtObjectEnabled(false) , m_renderToOffscreenBuffer(false) + , m_loadStartedSignalSent(false) + , m_dialogRunnerActive(false) { viewport->setFlags(QQuickItem::ItemClipsChildrenToShape); QObject::connect(viewport, SIGNAL(visibleChanged()), viewport, SLOT(_q_onVisibleChanged())); + QObject::connect(viewport, SIGNAL(urlChanged()), viewport, SLOT(_q_onUrlChanged())); pageView.reset(new QQuickWebPage(viewport)); } @@ -112,7 +115,6 @@ void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pa QtWebIconDatabaseClient* iconDatabase = context->iconDatabase(); QObject::connect(iconDatabase, SIGNAL(iconChangedForPageURL(QUrl, QUrl)), q_ptr, SLOT(_q_onIconChangedForPageURL(QUrl, QUrl))); - QObject::connect(q_ptr, SIGNAL(urlChanged(QUrl)), iconDatabase, SLOT(requestIconForPageURL(QUrl))); // Any page setting should preferrable be set before creating the page. webPageProxy->pageGroup()->preferences()->setAcceleratedCompositingEnabled(true); @@ -123,6 +125,16 @@ void QQuickWebViewPrivate::initialize(WKContextRef contextRef, WKPageGroupRef pa webPageProxy->initializeWebPage(); } +void QQuickWebViewPrivate::setTransparentBackground(bool enable) +{ + webPageProxy->setDrawsTransparentBackground(enable); +} + +bool QQuickWebViewPrivate::transparentBackground() const +{ + return webPageProxy->drawsTransparentBackground(); +} + void QQuickWebViewPrivate::enableMouseEvents() { Q_Q(QQuickWebView); @@ -146,8 +158,17 @@ QPointF QQuickWebViewPrivate::pageItemPos() void QQuickWebViewPrivate::loadDidSucceed() { Q_Q(QQuickWebView); - emit q->navigationStateChanged(); - emit q->loadSucceeded(); + ASSERT(!q->loading()); + QWebLoadRequest loadRequest(q->url(), QQuickWebView::LoadSucceededStatus); + emit q->loadingChanged(&loadRequest); +} + +void QQuickWebViewPrivate::onComponentComplete() +{ + if (m_deferedUrlToLoad.isEmpty()) + return; + + q_ptr->setUrl(m_deferedUrlToLoad); } void QQuickWebViewPrivate::setNeedsDisplay() @@ -173,6 +194,14 @@ void QQuickWebViewPrivate::_q_onIconChangedForPageURL(const QUrl& pageURL, const setIcon(iconURL); } +void QQuickWebViewPrivate::didChangeLoadingState(QWebLoadRequest* loadRequest) +{ + Q_Q(QQuickWebView); + ASSERT(q->loading() == (loadRequest->status() == QQuickWebView::LoadStartedStatus)); + emit q->loadingChanged(loadRequest); + m_loadStartedSignalSent = loadRequest->status() == QQuickWebView::LoadStartedStatus; +} + void QQuickWebViewPrivate::didChangeBackForwardList() { navigationHistory->d->reset(); @@ -180,15 +209,17 @@ void QQuickWebViewPrivate::didChangeBackForwardList() void QQuickWebViewPrivate::processDidCrash() { - emit q_ptr->navigationStateChanged(); pageView->eventHandler()->resetGestureRecognizers(); - WebCore::KURL url(WebCore::ParsedURLString, webPageProxy->urlAtProcessExit()); - qWarning("WARNING: The web process experienced a crash on '%s'.", qPrintable(QUrl(url).toString(QUrl::RemoveUserInfo))); + QUrl url(KURL(WebCore::ParsedURLString, webPageProxy->urlAtProcessExit())); + if (m_loadStartedSignalSent) { + QWebLoadRequest loadRequest(url, QQuickWebView::LoadFailedStatus, QLatin1String("The web process crashed."), QQuickWebView::InternalErrorDomain, 0); + didChangeLoadingState(&loadRequest); + } + qWarning("WARNING: The web process experienced a crash on '%s'.", qPrintable(url.toString(QUrl::RemoveUserInfo))); } void QQuickWebViewPrivate::didRelaunchProcess() { - emit q_ptr->navigationStateChanged(); qWarning("WARNING: The web process has been successfully restarted."); pageView->d->setDrawingAreaSize(viewSize()); } @@ -217,6 +248,12 @@ void QQuickWebViewPrivate::_q_onVisibleChanged() webPageProxy->viewStateDidChange(WebPageProxy::ViewIsVisible); } +void QQuickWebViewPrivate::_q_onUrlChanged() +{ + Q_Q(QQuickWebView); + context->iconDatabase()->requestIconForPageURL(q->url()); +} + void QQuickWebViewPrivate::_q_onReceivedResponseFromDownload(QWebDownloadItem* downloadItem) { // Now that our downloadItem has everything we need we can emit downloadRequested. @@ -237,11 +274,8 @@ void QQuickWebViewPrivate::runJavaScriptAlert(const QString& alertText) QtDialogRunner dialogRunner; if (!dialogRunner.initForAlert(alertDialog, q, alertText)) return; - setViewInAttachedProperties(dialogRunner.dialog()); - disableMouseEvents(); - dialogRunner.exec(); - enableMouseEvents(); + execDialogRunner(dialogRunner); } bool QQuickWebViewPrivate::runJavaScriptConfirm(const QString& message) @@ -253,11 +287,8 @@ bool QQuickWebViewPrivate::runJavaScriptConfirm(const QString& message) QtDialogRunner dialogRunner; if (!dialogRunner.initForConfirm(confirmDialog, q, message)) return true; - setViewInAttachedProperties(dialogRunner.dialog()); - disableMouseEvents(); - dialogRunner.exec(); - enableMouseEvents(); + execDialogRunner(dialogRunner); return dialogRunner.wasAccepted(); } @@ -275,11 +306,8 @@ QString QQuickWebViewPrivate::runJavaScriptPrompt(const QString& message, const ok = true; return defaultValue; } - setViewInAttachedProperties(dialogRunner.dialog()); - disableMouseEvents(); - dialogRunner.exec(); - enableMouseEvents(); + execDialogRunner(dialogRunner); ok = dialogRunner.wasAccepted(); return dialogRunner.result(); @@ -295,11 +323,7 @@ void QQuickWebViewPrivate::handleAuthenticationRequiredRequest(const QString& ho if (!dialogRunner.initForAuthentication(authenticationDialog, q, hostname, realm, prefilledUsername)) return; - setViewInAttachedProperties(dialogRunner.dialog()); - - disableMouseEvents(); - dialogRunner.exec(); - enableMouseEvents(); + execDialogRunner(dialogRunner); username = dialogRunner.username(); password = dialogRunner.password(); @@ -315,10 +339,7 @@ void QQuickWebViewPrivate::handleProxyAuthenticationRequiredRequest(const QStrin if (!dialogRunner.initForProxyAuthentication(proxyAuthenticationDialog, q, hostname, port, prefilledUsername)) return; - setViewInAttachedProperties(dialogRunner.dialog()); - disableMouseEvents(); - dialogRunner.exec(); - enableMouseEvents(); + execDialogRunner(dialogRunner); username = dialogRunner.username(); password = dialogRunner.password(); @@ -334,13 +355,21 @@ bool QQuickWebViewPrivate::handleCertificateVerificationRequest(const QString& h if (!dialogRunner.initForCertificateVerification(certificateVerificationDialog, q, hostname)) return false; + execDialogRunner(dialogRunner); + + return dialogRunner.wasAccepted(); +} + +void QQuickWebViewPrivate::execDialogRunner(QtDialogRunner& dialogRunner) +{ setViewInAttachedProperties(dialogRunner.dialog()); disableMouseEvents(); + m_dialogRunnerActive = true; + dialogRunner.exec(); + m_dialogRunnerActive = false; enableMouseEvents(); - - return dialogRunner.wasAccepted(); } void QQuickWebViewPrivate::chooseFiles(WKOpenPanelResultListenerRef listenerRef, const QStringList& selectedFileNames, QtWebPageUIClient::FileChooserType type) @@ -417,7 +446,7 @@ void QQuickWebViewPrivate::setIcon(const QUrl& iconURL) } m_iconURL = iconURL; - emit q->iconChanged(m_iconURL); + emit q->iconChanged(); } bool QQuickWebViewPrivate::navigatorQtObjectEnabled() const @@ -433,6 +462,14 @@ void QQuickWebViewPrivate::setNavigatorQtObjectEnabled(bool enabled) context->setNavigatorQtObjectEnabled(webPageProxy.get(), enabled); } +QRect QQuickWebViewPrivate::visibleContentsRect() const +{ + Q_Q(const QQuickWebView); + const QRectF visibleRect(q->boundingRect().intersected(pageView->boundingRect())); + + return q->mapRectToWebContent(visibleRect).toAlignedRect(); +} + WebCore::IntSize QQuickWebViewPrivate::viewSize() const { return WebCore::IntSize(pageView->width(), pageView->height()); @@ -547,6 +584,8 @@ void QQuickWebViewFlickablePrivate::onComponentComplete() // Trigger setting of correct visibility flags after everything was allocated and initialized. _q_onVisibleChanged(); + + QQuickWebViewPrivate::onComponentComplete(); } void QQuickWebViewFlickablePrivate::loadDidSucceed() @@ -609,16 +648,14 @@ void QQuickWebViewFlickablePrivate::_q_commitScaleChange() return; Q_Q(QQuickWebView); - const QRectF visibleRectInCSSCoordinates = q->mapRectToWebContent(q->boundingRect()).intersected(pageView->boundingRect()); - float scale = pageView->contentsScale(); - // This is only for our QML ViewportInfo debugging API. q->experimental()->viewportInfo()->didUpdateCurrentScale(); - QRect alignedVisibleContentRect = visibleRectInCSSCoordinates.toAlignedRect(); - drawingArea->setVisibleContentsRectForScaling(alignedVisibleContentRect, scale); + const QRect visibleRect(visibleContentsRect()); + float scale = pageView->contentsScale(); - webPageProxy->setFixedVisibleContentRect(alignedVisibleContentRect); + drawingArea->setVisibleContentsRectForScaling(visibleRect, scale); + webPageProxy->setFixedVisibleContentRect(visibleRect); } void QQuickWebViewPrivate::_q_commitPositionChange(const QPointF& trajectoryVector) @@ -627,21 +664,19 @@ void QQuickWebViewPrivate::_q_commitPositionChange(const QPointF& trajectoryVect if (!drawingArea) return; - Q_Q(QQuickWebView); - const QRectF visibleRectInCSSCoordinates = q->mapRectToWebContent(q->boundingRect()).intersected(pageView->boundingRect()); - - QRect alignedVisibleContentRect = visibleRectInCSSCoordinates.toAlignedRect(); - drawingArea->setVisibleContentsRectForPanning(alignedVisibleContentRect, trajectoryVector); + const QRect visibleRect(visibleContentsRect()); + drawingArea->setVisibleContentsRectForPanning(visibleRect, trajectoryVector); if (!trajectoryVector.isNull()) return; - webPageProxy->setFixedVisibleContentRect(alignedVisibleContentRect); + webPageProxy->setFixedVisibleContentRect(visibleRect); } void QQuickWebViewFlickablePrivate::_q_suspend() { pageIsSuspended = true; + webPageProxy->suspendActiveDOMObjectsAndAnimations(); } void QQuickWebViewFlickablePrivate::_q_resume() @@ -650,6 +685,7 @@ void QQuickWebViewFlickablePrivate::_q_resume() return; pageIsSuspended = false; + webPageProxy->resumeActiveDOMObjectsAndAnimations(); if (isTransitioningToNewPage) { isTransitioningToNewPage = false; @@ -786,6 +822,17 @@ bool QQuickWebViewExperimental::renderToOffscreenBuffer() const return d->renderToOffscreenBuffer(); } +bool QQuickWebViewExperimental::transparentBackground() const +{ + Q_D(const QQuickWebView); + return d->transparentBackground(); +} +void QQuickWebViewExperimental::setTransparentBackground(bool enable) +{ + Q_D(QQuickWebView); + d->setTransparentBackground(enable); +} + void QQuickWebViewExperimental::setFlickableViewportEnabled(bool enable) { s_flickableViewportEnabled = enable; @@ -1093,6 +1140,7 @@ QQuickWebView::QQuickWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRe { Q_D(QQuickWebView); d->initialize(contextRef, pageGroupRef); + setClip(true); } QQuickWebView::~QQuickWebView() @@ -1105,15 +1153,6 @@ QQuickWebPage* QQuickWebView::page() return d->pageView.data(); } -void QQuickWebView::load(const QUrl& url) -{ - if (url.isEmpty()) - return; - - Q_D(QQuickWebView); - d->webPageProxy->loadURL(url.toString()); -} - void QQuickWebView::goBack() { Q_D(QQuickWebView); @@ -1148,6 +1187,21 @@ QUrl QQuickWebView::url() const return QUrl(QString(mainFrame->url())); } +void QQuickWebView::setUrl(const QUrl& url) +{ + Q_D(QQuickWebView); + + if (url.isEmpty()) + return; + + if (!isComponentComplete()) { + d->m_deferedUrlToLoad = url; + return; + } + + d->webPageProxy->loadURL(url.toString()); +} + QUrl QQuickWebView::icon() const { Q_D(const QQuickWebView); @@ -1179,15 +1233,6 @@ bool QQuickWebView::loading() const return mainFrame && !(WebFrameProxy::LoadStateFinished == mainFrame->loadState()); } -bool QQuickWebView::canReload() const -{ - Q_D(const QQuickWebView); - RefPtr<WebKit::WebFrameProxy> mainFrame = d->webPageProxy->mainFrame(); - if (mainFrame) - return (WebFrameProxy::LoadStateFinished == mainFrame->loadState()); - return d->webPageProxy->backForwardList()->currentItem(); -} - QPointF QQuickWebView::mapToWebContent(const QPointF& pointInViewCoordinates) const { Q_D(const QQuickWebView); @@ -1281,128 +1326,125 @@ void QQuickWebView::componentComplete() void QQuickWebView::keyPressEvent(QKeyEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleKeyPressEvent(event); } void QQuickWebView::keyReleaseEvent(QKeyEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleKeyReleaseEvent(event); } void QQuickWebView::inputMethodEvent(QInputMethodEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleInputMethodEvent(event); } void QQuickWebView::focusInEvent(QFocusEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleFocusInEvent(event); } void QQuickWebView::focusOutEvent(QFocusEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleFocusOutEvent(event); } void QQuickWebView::touchEvent(QTouchEvent* event) { + Q_D(QQuickWebView); + if (d->m_dialogRunnerActive) { + event->ignore(); + return; + } + forceActiveFocus(); - this->event(event); + d->pageView->eventHandler()->handleTouchEvent(event); } void QQuickWebView::mousePressEvent(QMouseEvent* event) { + Q_D(QQuickWebView); forceActiveFocus(); - this->event(event); + d->pageView->eventHandler()->handleMousePressEvent(event); } void QQuickWebView::mouseMoveEvent(QMouseEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleMouseMoveEvent(event); } void QQuickWebView::mouseReleaseEvent(QMouseEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleMouseReleaseEvent(event); } void QQuickWebView::mouseDoubleClickEvent(QMouseEvent* event) { - this->event(event); + Q_D(QQuickWebView); + // If a MouseButtonDblClick was received then we got a MouseButtonPress before + // handleMousePressEvent will take care of double clicks. + d->pageView->eventHandler()->handleMousePressEvent(event); } void QQuickWebView::wheelEvent(QWheelEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleWheelEvent(event); } void QQuickWebView::hoverEnterEvent(QHoverEvent* event) { - this->event(event); + Q_D(QQuickWebView); + // Map HoverEnter to Move, for WebKit the distinction doesn't matter. + d->pageView->eventHandler()->handleHoverMoveEvent(event); } void QQuickWebView::hoverMoveEvent(QHoverEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleHoverMoveEvent(event); } void QQuickWebView::hoverLeaveEvent(QHoverEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleHoverLeaveEvent(event); } void QQuickWebView::dragMoveEvent(QDragMoveEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleDragMoveEvent(event); } void QQuickWebView::dragEnterEvent(QDragEnterEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleDragEnterEvent(event); } void QQuickWebView::dragLeaveEvent(QDragLeaveEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleDragLeaveEvent(event); } void QQuickWebView::dropEvent(QDropEvent* event) { - this->event(event); + Q_D(QQuickWebView); + d->pageView->eventHandler()->handleDropEvent(event); } bool QQuickWebView::event(QEvent* ev) { - Q_D(QQuickWebView); - - switch (ev->type()) { - case QEvent::MouseMove: - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseButtonDblClick: - case QEvent::Wheel: - case QEvent::HoverLeave: - case QEvent::HoverEnter: - case QEvent::HoverMove: - case QEvent::DragEnter: - case QEvent::DragLeave: - case QEvent::DragMove: - case QEvent::Drop: - case QEvent::KeyPress: - case QEvent::KeyRelease: - case QEvent::FocusIn: - case QEvent::FocusOut: - case QEvent::TouchBegin: - case QEvent::TouchEnd: - case QEvent::TouchCancel: - case QEvent::TouchUpdate: - if (d->pageView->eventHandler()->handleEvent(ev)) - return true; - } - - if (ev->type() == QEvent::InputMethod) - return false; // This is necessary to avoid an endless loop in connection with QQuickItem::event(). - + // Re-implemented for possible future use without breaking binary compatibility. return QQuickItem::event(ev); } diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h index 674c18fe7..5302916eb 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h @@ -30,6 +30,7 @@ class QWebNavigationRequest; class QDeclarativeComponent; class QQuickWebPage; class QQuickWebViewAttached; +class QWebLoadRequest; class QQuickWebViewPrivate; class QQuickWebViewExperimental; class QWebDownloadItem; @@ -67,24 +68,30 @@ QT_END_NAMESPACE class QWEBKIT_EXPORT QQuickWebView : public QQuickItem { Q_OBJECT Q_PROPERTY(QString title READ title NOTIFY titleChanged) - Q_PROPERTY(QUrl url READ url NOTIFY urlChanged) + Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) Q_PROPERTY(QUrl icon READ icon NOTIFY iconChanged FINAL) + Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY navigationHistoryChanged FINAL) + Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY navigationHistoryChanged FINAL) + Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged FINAL) Q_PROPERTY(int loadProgress READ loadProgress NOTIFY loadProgressChanged) - Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY navigationStateChanged FINAL) - Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY navigationStateChanged FINAL) - Q_PROPERTY(bool loading READ loading NOTIFY navigationStateChanged FINAL) - Q_PROPERTY(bool canReload READ canReload NOTIFY navigationStateChanged FINAL) Q_ENUMS(NavigationRequestAction) + Q_ENUMS(LoadStatus) Q_ENUMS(ErrorDomain) Q_ENUMS(NavigationType) public: enum NavigationRequestAction { AcceptRequest, - IgnoreRequest + // Make room in the valid range of the enum for extra actions exposed in Experimental. + IgnoreRequest = 0xFF + }; + enum LoadStatus { + LoadStartedStatus, + LoadSucceededStatus, + LoadFailedStatus }; - enum ErrorDomain { + NoErrorDomain, InternalErrorDomain, NetworkErrorDomain, HttpErrorDomain, @@ -104,6 +111,7 @@ public: virtual ~QQuickWebView(); QUrl url() const; + void setUrl(const QUrl&); QUrl icon() const; QString title() const; int loadProgress() const; @@ -111,7 +119,6 @@ public: bool canGoBack() const; bool canGoForward() const; bool loading() const; - bool canReload() const; virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const; @@ -132,7 +139,6 @@ public: QPointF pageItemPos(); public Q_SLOTS: - void load(const QUrl&); void loadHtml(const QString& html, const QUrl& baseUrl = QUrl()); void goBack(); @@ -141,15 +147,13 @@ public Q_SLOTS: void reload(); Q_SIGNALS: - void titleChanged(const QString& title); - void loadStarted(); - void loadSucceeded(); - void loadFailed(QQuickWebView::ErrorDomain errorDomain, int errorCode, const QUrl& url, const QString& description); - void loadProgressChanged(int progress); - void urlChanged(const QUrl& url); - void iconChanged(const QUrl& iconURL); - void linkHovered(const QUrl& url, const QString& title); - void navigationStateChanged(); + void titleChanged(); + void navigationHistoryChanged(); + void loadingChanged(QWebLoadRequest* loadRequest); + void loadProgressChanged(); + void urlChanged(); + void iconChanged(); + void linkHovered(const QUrl& hoveredUrl, const QString& hoveredTitle); void navigationRequested(QWebNavigationRequest* request); protected: @@ -189,6 +193,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_onOpenPanelFilesSelected()); Q_PRIVATE_SLOT(d_func(), void _q_onOpenPanelFinished(int result)); Q_PRIVATE_SLOT(d_func(), void _q_onVisibleChanged()); + Q_PRIVATE_SLOT(d_func(), void _q_onUrlChanged()); Q_PRIVATE_SLOT(d_func(), void _q_onReceivedResponseFromDownload(QWebDownloadItem*)); Q_PRIVATE_SLOT(d_func(), void _q_onIconChangedForPageURL(const QUrl&, const QUrl&)); // Hides QObject::d_ptr allowing us to use the convenience macros. @@ -233,6 +238,7 @@ class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject { Q_PROPERTY(qreal contentY READ contentY WRITE setContentY NOTIFY contentYChanged) Q_PROPERTY(QQuickItem* contentItem READ contentItem CONSTANT) Q_PROPERTY(QDeclarativeListProperty<QObject> flickableData READ flickableData) + Q_PROPERTY(bool transparentBackground WRITE setTransparentBackground READ transparentBackground) Q_PROPERTY(QWebNavigationHistory* navigationHistory READ navigationHistory CONSTANT FINAL) Q_PROPERTY(QDeclarativeComponent* alertDialog READ alertDialog WRITE setAlertDialog NOTIFY alertDialogChanged) @@ -245,11 +251,11 @@ class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject { Q_PROPERTY(QWebPreferences* preferences READ preferences CONSTANT FINAL) Q_PROPERTY(QWebViewportInfo* viewportInfo READ viewportInfo CONSTANT FINAL) Q_PROPERTY(QDeclarativeListProperty<QQuickUrlSchemeDelegate> urlSchemeDelegates READ schemeDelegates) - Q_ENUMS(NavigationRequestAction) + Q_ENUMS(NavigationRequestActionExperimental) public: - enum NavigationRequestAction { - DownloadRequest = 2 + enum NavigationRequestActionExperimental { + DownloadRequest = QQuickWebView::IgnoreRequest - 1 }; QQuickWebViewExperimental(QQuickWebView* webView); @@ -294,6 +300,8 @@ public: void setContentX(qreal); qreal contentY() const; void setContentY(qreal); + bool transparentBackground() const; + void setTransparentBackground(bool); // C++ only bool renderToOffscreenBuffer() const; diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h index 300b4759d..39a14a7a6 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h @@ -22,6 +22,7 @@ #define qquickwebview_p_p_h #include "DrawingAreaProxy.h" +#include "QtDialogRunner.h" #include "QtFlickProvider.h" #include "QtPageClient.h" #include "QtViewportInteractionEngine.h" @@ -73,10 +74,11 @@ public: virtual void updateContentsSize(const QSizeF&) { } virtual void loadDidSucceed(); - virtual void onComponentComplete() { } + virtual void onComponentComplete(); virtual void loadDidCommit() { } virtual void didFinishFirstNonEmptyLayout() { } virtual void didChangeViewportProperties(const WebCore::ViewportArguments& args) { } + void didChangeLoadingState(QWebLoadRequest* loadRequest); void didChangeBackForwardList(); void setNeedsDisplay(); @@ -94,6 +96,7 @@ public: void _q_onOpenPanelFilesSelected(); void _q_onOpenPanelFinished(int result); void _q_onVisibleChanged(); + void _q_onUrlChanged(); void _q_onReceivedResponseFromDownload(QWebDownloadItem*); void _q_onIconChangedForPageURL(const QUrl& pageURL, const QUrl& iconURLString); @@ -106,14 +109,20 @@ public: bool handleCertificateVerificationRequest(const QString& hostname); void handleProxyAuthenticationRequiredRequest(const QString& hostname, uint16_t port, const QString& prefilledUsername, QString& username, QString& password); + void execDialogRunner(QtDialogRunner&); + void setRenderToOffscreenBuffer(bool enable) { m_renderToOffscreenBuffer = enable; } + void setTransparentBackground(bool); void setViewInAttachedProperties(QObject*); void setIcon(const QUrl&); bool navigatorQtObjectEnabled() const; bool renderToOffscreenBuffer() const { return m_renderToOffscreenBuffer; } + bool transparentBackground() const; void setNavigatorQtObjectEnabled(bool); + QRect visibleContentsRect() const; + // PageClient. WebCore::IntSize viewSize() const; void didReceiveMessageFromNavigatorQtObject(const String& message); @@ -158,7 +167,10 @@ protected: bool userDidOverrideContentHeight; bool m_navigatorQtObjectEnabled; bool m_renderToOffscreenBuffer; + bool m_loadStartedSignalSent; + bool m_dialogRunnerActive; QUrl m_iconURL; + QUrl m_deferedUrlToLoad; }; class QQuickWebViewLegacyPrivate : public QQuickWebViewPrivate { diff --git a/Source/WebKit2/UIProcess/API/qt/qwebloadrequest.cpp b/Source/WebKit2/UIProcess/API/qt/qwebloadrequest.cpp new file mode 100644 index 000000000..0b249a61a --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebloadrequest.cpp @@ -0,0 +1,75 @@ +/* + Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "qwebloadrequest_p.h" + +class QWebLoadRequestPrivate { +public: + QWebLoadRequestPrivate(const QUrl& url, QQuickWebView::LoadStatus status, const QString& errorString, QQuickWebView::ErrorDomain errorDomain, int errorCode) + : url(url) + , status(status) + , errorString(errorString) + , errorDomain(errorDomain) + , errorCode(errorCode) + { + } + + QUrl url; + QQuickWebView::LoadStatus status; + QString errorString; + QQuickWebView::ErrorDomain errorDomain; + int errorCode; +}; + +QWebLoadRequest::QWebLoadRequest(const QUrl& url, QQuickWebView::LoadStatus status, const QString& errorString, QQuickWebView::ErrorDomain errorDomain, int errorCode, QObject* parent) + : QObject(parent) + , d(new QWebLoadRequestPrivate(url, status, errorString, errorDomain, errorCode)) +{ +} + +QWebLoadRequest::~QWebLoadRequest() +{ +} + +QUrl QWebLoadRequest::url() const +{ + return d->url; +} + +QQuickWebView::LoadStatus QWebLoadRequest::status() const +{ + return d->status; +} + +QString QWebLoadRequest::errorString() const +{ + return d->errorString; +} + +QQuickWebView::ErrorDomain QWebLoadRequest::errorDomain() const +{ + return d->errorDomain; +} + +int QWebLoadRequest::errorCode() const +{ + return d->errorCode; +} diff --git a/Source/WebKit2/UIProcess/API/qt/qwebloadrequest_p.h b/Source/WebKit2/UIProcess/API/qt/qwebloadrequest_p.h new file mode 100644 index 000000000..ebff399a7 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/qwebloadrequest_p.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qwebloadrequest_p_h +#define qwebloadrequest_p_h + +#include "qquickwebview_p.h" +#include <QtCore/QObject> +#include <QtCore/QScopedPointer> +#include <QtCore/QUrl> + +class QWebLoadRequestPrivate; + +class QWEBKIT_EXPORT QWebLoadRequest : public QObject { + Q_OBJECT + Q_PROPERTY(QUrl url READ url) + Q_PROPERTY(QQuickWebView::LoadStatus status READ status) + Q_PROPERTY(QString errorString READ errorString) + Q_PROPERTY(QQuickWebView::ErrorDomain errorDomain READ errorDomain) + Q_PROPERTY(int errorCode READ errorCode) + +public: + QWebLoadRequest(const QUrl& url, QQuickWebView::LoadStatus status, const QString& errorString = QString(), QQuickWebView::ErrorDomain errorDomain = QQuickWebView::NoErrorDomain, int errorCode = 0, QObject* parent = 0); + ~QWebLoadRequest(); + QUrl url() const; + QQuickWebView::LoadStatus status() const; + QString errorString() const; + QQuickWebView::ErrorDomain errorDomain() const; + int errorCode() const; + +private: + QScopedPointer<QWebLoadRequestPrivate> d; +}; + +#endif // qwebloadrequest_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest.cpp b/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest.cpp index 3a63f80e3..92af27179 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest.cpp @@ -25,12 +25,10 @@ class QWebNavigationRequestPrivate { public: - QWebNavigationRequestPrivate(const QUrl& url, const QUrl& originatingUrl, Qt::MouseButton button, - Qt::KeyboardModifiers modifiers, QQuickWebView::NavigationType navigationType) + QWebNavigationRequestPrivate(const QUrl& url, Qt::MouseButton mouseButton, Qt::KeyboardModifiers keyboardModifiers, QQuickWebView::NavigationType navigationType) : url(url) - , originatingUrl(originatingUrl) - , button(button) - , modifiers(modifiers) + , mouseButton(mouseButton) + , keyboardModifiers(keyboardModifiers) , action(QQuickWebView::AcceptRequest) , navigationType(navigationType) { @@ -41,17 +39,15 @@ public: } QUrl url; - QUrl originatingUrl; - Qt::MouseButton button; - Qt::KeyboardModifiers modifiers; - int action; + Qt::MouseButton mouseButton; + Qt::KeyboardModifiers keyboardModifiers; + QQuickWebView::NavigationRequestAction action; QQuickWebView::NavigationType navigationType; }; -QWebNavigationRequest::QWebNavigationRequest(const QUrl& url, const QUrl& originatingUrl, Qt::MouseButton button, - Qt::KeyboardModifiers modifiers, QQuickWebView::NavigationType navigationType, QObject* parent) +QWebNavigationRequest::QWebNavigationRequest(const QUrl& url, Qt::MouseButton mouseButton, Qt::KeyboardModifiers keyboardModifiers, QQuickWebView::NavigationType navigationType, QObject* parent) : QObject(parent) - , d(new QWebNavigationRequestPrivate(url, originatingUrl, button, modifiers, navigationType)) + , d(new QWebNavigationRequestPrivate(url, mouseButton, keyboardModifiers, navigationType)) { } @@ -60,7 +56,7 @@ QWebNavigationRequest::~QWebNavigationRequest() delete d; } -void QWebNavigationRequest::setAction(int action) +void QWebNavigationRequest::setAction(QQuickWebView::NavigationRequestAction action) { if (d->action == action) return; @@ -74,24 +70,19 @@ QUrl QWebNavigationRequest::url() const return d->url; } -QUrl QWebNavigationRequest::originatingUrl() const +int QWebNavigationRequest::mouseButton() const { - return d->originatingUrl; + return int(d->mouseButton); } -int QWebNavigationRequest::button() const +int QWebNavigationRequest::keyboardModifiers() const { - return int(d->button); + return int(d->keyboardModifiers); } -int QWebNavigationRequest::modifiers() const +QQuickWebView::NavigationRequestAction QWebNavigationRequest::action() const { - return int(d->modifiers); -} - -int QWebNavigationRequest::action() const -{ - return int(d->action); + return d->action; } QQuickWebView::NavigationType QWebNavigationRequest::navigationType() const diff --git a/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest_p.h b/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest_p.h index 46333f0e8..b401deda5 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qwebnavigationrequest_p.h @@ -31,24 +31,21 @@ class QWebNavigationRequestPrivate; class QWEBKIT_EXPORT QWebNavigationRequest : public QObject { Q_OBJECT Q_PROPERTY(QUrl url READ url CONSTANT FINAL) - Q_PROPERTY(QUrl originatingUrl READ originatingUrl CONSTANT FINAL) - Q_PROPERTY(int button READ button CONSTANT FINAL) - Q_PROPERTY(int modifiers READ modifiers CONSTANT FINAL) - Q_PROPERTY(int action READ action WRITE setAction NOTIFY actionChanged FINAL) + Q_PROPERTY(int mouseButton READ mouseButton CONSTANT FINAL) + Q_PROPERTY(int keyboardModifiers READ keyboardModifiers CONSTANT FINAL) + Q_PROPERTY(QQuickWebView::NavigationRequestAction action READ action WRITE setAction NOTIFY actionChanged FINAL) Q_PROPERTY(QQuickWebView::NavigationType navigationType READ navigationType CONSTANT FINAL) public: - QWebNavigationRequest(const QUrl& url, const QUrl& originatingUrl, Qt::MouseButton button, Qt::KeyboardModifiers modifiers, - QQuickWebView::NavigationType navigationType, QObject* parent = 0); + QWebNavigationRequest(const QUrl& url, Qt::MouseButton mouseButton, Qt::KeyboardModifiers keyboardModifiers, QQuickWebView::NavigationType navigationType, QObject* parent = 0); ~QWebNavigationRequest(); QUrl url() const; - QUrl originatingUrl() const; - int button() const; - int modifiers() const; - int action() const; + int mouseButton() const; + int keyboardModifiers() const; + QQuickWebView::NavigationRequestAction action() const; - void setAction(int action); + void setAction(QQuickWebView::NavigationRequestAction action); QQuickWebView::NavigationType navigationType() const; Q_SIGNALS: diff --git a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h index 653018221..ab422e4e7 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo_p.h @@ -18,7 +18,7 @@ * */ -#ifndef qwebviewportinfp_p_h +#ifndef qwebviewportinfo_p_h #define qwebviewportinfo_p_h #include "qwebkitglobal.h" diff --git a/Source/WebKit2/UIProcess/API/qt/tests/publicapi/publicapi.pro b/Source/WebKit2/UIProcess/API/qt/tests/publicapi/publicapi.pro index 0f0d4f52c..02dc197c7 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/publicapi/publicapi.pro +++ b/Source/WebKit2/UIProcess/API/qt/tests/publicapi/publicapi.pro @@ -1,3 +1,3 @@ include(../tests.pri) SOURCES += $${TARGET}.cpp -CONFIG += qtwebkit-private +QT += webkit-private diff --git a/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp b/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp index 3ad4729a9..f5f976663 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp +++ b/Source/WebKit2/UIProcess/API/qt/tests/publicapi/tst_publicapi.cpp @@ -23,8 +23,9 @@ #include <QMetaProperty> #include <QMetaType> #include <QtTest/QtTest> -#include <qquickwebview_p.h> -#include <qwebnavigationrequest_p.h> +#include <private/qquickwebview_p.h> +#include <private/qwebloadrequest_p.h> +#include <private/qwebnavigationrequest_p.h> class tst_publicapi : public QObject { Q_OBJECT @@ -34,11 +35,16 @@ private slots: static QList<const QMetaObject*> typesToCheck = QList<const QMetaObject*>() << &QQuickWebView::staticMetaObject + << &QWebLoadRequest::staticMetaObject << &QWebNavigationRequest::staticMetaObject; static QStringList expectedAPI = QStringList() << "QQuickWebView.AcceptRequest --> NavigationRequestAction" << "QQuickWebView.IgnoreRequest --> NavigationRequestAction" + << "QQuickWebView.LoadStartedStatus --> LoadStatus" + << "QQuickWebView.LoadSucceededStatus --> LoadStatus" + << "QQuickWebView.LoadFailedStatus --> LoadStatus" + << "QQuickWebView.NoErrorDomain --> ErrorDomain" << "QQuickWebView.InternalErrorDomain --> ErrorDomain" << "QQuickWebView.NetworkErrorDomain --> ErrorDomain" << "QQuickWebView.HttpErrorDomain --> ErrorDomain" @@ -52,33 +58,33 @@ static QStringList expectedAPI = QStringList() << "QQuickWebView.title --> QString" << "QQuickWebView.url --> QUrl" << "QQuickWebView.icon --> QUrl" - << "QQuickWebView.loadProgress --> int" << "QQuickWebView.canGoBack --> bool" << "QQuickWebView.canGoForward --> bool" << "QQuickWebView.loading --> bool" - << "QQuickWebView.canReload --> bool" - << "QQuickWebView.titleChanged(QString) --> void" - << "QQuickWebView.loadStarted() --> void" - << "QQuickWebView.loadSucceeded() --> void" - << "QQuickWebView.loadFailed(QQuickWebView::ErrorDomain,int,QUrl,QString) --> void" - << "QQuickWebView.loadProgressChanged(int) --> void" - << "QQuickWebView.urlChanged(QUrl) --> void" - << "QQuickWebView.iconChanged(QUrl) --> void" + << "QQuickWebView.loadProgress --> int" + << "QQuickWebView.titleChanged() --> void" + << "QQuickWebView.navigationHistoryChanged() --> void" + << "QQuickWebView.loadingChanged(QWebLoadRequest*) --> void" + << "QQuickWebView.loadProgressChanged() --> void" + << "QQuickWebView.urlChanged() --> void" + << "QQuickWebView.iconChanged() --> void" << "QQuickWebView.linkHovered(QUrl,QString) --> void" - << "QQuickWebView.navigationStateChanged() --> void" << "QQuickWebView.navigationRequested(QWebNavigationRequest*) --> void" - << "QQuickWebView.load(QUrl) --> void" << "QQuickWebView.loadHtml(QString,QUrl) --> void" << "QQuickWebView.loadHtml(QString) --> void" << "QQuickWebView.goBack() --> void" << "QQuickWebView.goForward() --> void" << "QQuickWebView.stop() --> void" << "QQuickWebView.reload() --> void" + << "QWebLoadRequest.url --> QUrl" + << "QWebLoadRequest.status --> QQuickWebView::LoadStatus" + << "QWebLoadRequest.errorString --> QString" + << "QWebLoadRequest.errorDomain --> QQuickWebView::ErrorDomain" + << "QWebLoadRequest.errorCode --> int" << "QWebNavigationRequest.url --> QUrl" - << "QWebNavigationRequest.originatingUrl --> QUrl" - << "QWebNavigationRequest.button --> int" - << "QWebNavigationRequest.modifiers --> int" - << "QWebNavigationRequest.action --> int" + << "QWebNavigationRequest.mouseButton --> int" + << "QWebNavigationRequest.keyboardModifiers --> int" + << "QWebNavigationRequest.action --> QQuickWebView::NavigationRequestAction" << "QWebNavigationRequest.navigationType --> QQuickWebView::NavigationType" << "QWebNavigationRequest.actionChanged() --> void" ; diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro index 8b5b3cbb8..9d16a7bdd 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior.pro @@ -3,7 +3,7 @@ SOURCES += tst_qmltests.cpp TARGET = tst_qmltests_DesktopBehavior OBJECTS_DIR = obj_DesktopBehavior/$$activeBuildConfig() -CONFIG += qtwebkit-private +QT += webkit-private CONFIG += warn_on testcase QT -= testlib diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml index 432416a63..18763bfef 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_itemSelector.qml @@ -2,10 +2,11 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 import QtWebKit.experimental 1.0 +import "../common" // FIXME: Moved to Desktop tests because we want to have mouseClick() to open the <select> tag. We can move it back // when TestCase starts supporting touch events, see https://bugreports.qt.nokia.com/browse/QTBUG-23083. -WebView { +TestWebView { id: webView width: 400 @@ -37,12 +38,6 @@ WebView { } SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - - SignalSpy { id: titleSpy target: webView signalName: "titleChanged" @@ -58,9 +53,8 @@ WebView { webView.finalSelection = -1 webView.useAcceptDirectly = false webView.selectorLoaded = false - loadSpy.clear() - webView.load(Qt.resolvedUrl("../common/select.html")) - loadSpy.wait() + webView.url = Qt.resolvedUrl("../common/select.html") + verify(webView.waitForLoadSucceeded()) titleSpy.clear() } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_linkHovered.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_linkHovered.qml index b8ab29496..e035dc2a9 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_linkHovered.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_linkHovered.qml @@ -1,8 +1,9 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 200 height: 400 @@ -17,15 +18,9 @@ WebView { signalName: "linkHovered" } - SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - onLinkHovered: { - webView.lastUrl = url - webView.lastTitle = title + webView.lastUrl = hoveredUrl + webView.lastTitle = hoveredTitle } TestCase { @@ -48,8 +43,8 @@ WebView { function test_linkHovered() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/test2.html")) - loadSpy.wait() + webView.url = Qt.resolvedUrl("../common/test2.html") + verify(webView.waitForLoadSucceeded()) mouseMove(webView, 100, 100) spy.wait() compare(spy.count, 1) @@ -64,8 +59,8 @@ WebView { function test_linkHoveredDoesntEmitRepeated() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/test2.html")) - loadSpy.wait() + webView.url = Qt.resolvedUrl("../common/test2.html") + verify(webView.waitForLoadSucceeded()) for (var i = 0; i < 100; i += 10) mouseMove(webView, 100, 100 + i) diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_loadHtml.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_loadHtml.qml index 9e173d56a..b50aec371 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_loadHtml.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_loadHtml.qml @@ -1,8 +1,9 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 200 height: 400 @@ -11,19 +12,13 @@ WebView { property string lastUrl SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - - SignalSpy { id: linkHoveredSpy target: webView signalName: "linkHovered" } onLinkHovered: { - webView.lastUrl = url + webView.lastUrl = hoveredUrl } TestCase { @@ -41,15 +36,13 @@ WebView { function init() { webView.lastUrl = "" linkHoveredSpy.clear() - loadSpy.clear() } function test_baseUrlAfterLoadHtml() { - loadSpy.clear() linkHoveredSpy.clear() compare(linkHoveredSpy.count, 0) webView.loadHtml("<html><head><title>Test page with huge link area</title></head><body><a title=\"A title\" href=\"test1.html\"><img width=200 height=200></a></body></html>", "http://www.example.foo.com") - loadSpy.wait() + verify(webView.waitForLoadSucceeded()) compare("http://www.example.foo.com/", webView.url) mouseMove(webView, 100, 100) linkHoveredSpy.wait() diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_messaging.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_messaging.qml index eb18a8216..1b3ab6314 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_messaging.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_messaging.qml @@ -2,9 +2,10 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 import QtWebKit.experimental 1.0 +import "../common" Item { - WebView { + TestWebView { id: webView property variant lastMessage experimental.preferences.navigatorQtObjectEnabled: true @@ -13,7 +14,7 @@ Item { } } - WebView { + TestWebView { id: otherWebView property variant lastMessage experimental.preferences.navigatorQtObjectEnabled: true @@ -22,7 +23,7 @@ Item { } } - WebView { + TestWebView { id: disabledWebView property bool receivedMessage experimental.preferences.navigatorQtObjectEnabled: false @@ -32,51 +33,31 @@ Item { } SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - - SignalSpy { id: messageSpy target: webView.experimental signalName: "messageReceived" } SignalSpy { - id: otherLoadSpy - target: otherWebView - signalName: "loadSucceeded" - } - - SignalSpy { id: otherMessageSpy target: otherWebView.experimental signalName: "messageReceived" } - SignalSpy { - id: disabledWebViewLoadSpy - target: disabledWebView - signalName: "loadSucceeded" - } - TestCase { name: "DesktopWebViewMessaging" property url testUrl: Qt.resolvedUrl("../common/messaging.html") function init() { - loadSpy.clear() messageSpy.clear() webView.lastMessage = null - otherLoadSpy.clear() otherMessageSpy.clear() otherWebView.lastMessage = null } function test_basic() { - webView.load(testUrl) - loadSpy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) webView.experimental.postMessage("HELLO") messageSpy.wait() compare(webView.lastMessage.data, "OLLEH") @@ -84,10 +65,10 @@ Item { } function test_twoWebViews() { - webView.load(testUrl) - otherWebView.load(testUrl) - loadSpy.wait() - otherLoadSpy.wait() + webView.url = testUrl + otherWebView.url = testUrl + verify(webView.waitForLoadSucceeded()) + verify(otherWebView.waitForLoadSucceeded()) webView.experimental.postMessage("FIRST") otherWebView.experimental.postMessage("SECOND") messageSpy.wait() @@ -97,9 +78,9 @@ Item { } function test_disabled() { - disabledWebView.load(testUrl) + disabledWebView.url = testUrl verify(!disabledWebView.experimental.preferences.navigatorQtObjectEnabled) - disabledWebViewLoadSpy.wait() + verify(disabledWebView.waitForLoadSucceeded()) disabledWebView.experimental.postMessage("HI") wait(1000) verify(!disabledWebView.receivedMessage) diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_navigationRequested.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_navigationRequested.qml index 169a0273e..2aefce537 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_navigationRequested.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/DesktopBehavior/tst_navigationRequested.qml @@ -2,16 +2,16 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 import QtWebKit.experimental 1.0 +import "../common" Item { property int expectedLength: 0 property int totalBytes: 0 property bool shouldDownload: false - property string originatingUrl: "" property url beginUrl: Qt.resolvedUrl("../common/test2.html") property url endUrl: Qt.resolvedUrl("../common/test1.html") - WebView { + TestWebView { id: webView width: 200 height: 200 @@ -21,11 +21,10 @@ Item { onNavigationRequested: { if (shouldDownload) request.action = WebViewExperimental.DownloadRequest - else if (request.button == Qt.MiddleButton && request.modifiers & Qt.ControlModifier) { - otherWebView.load(request.url) + else if (request.mouseButton == Qt.MiddleButton && request.keyboardModifiers & Qt.ControlModifier) { + otherWebView.url = request.url request.action = WebView.IgnoreRequest } - originatingUrl = request.originatingUrl } experimental.onDownloadRequested: { @@ -45,23 +44,11 @@ Item { } } - SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - - WebView { + TestWebView { id: otherWebView } SignalSpy { - id: otherSpy - target: otherWebView - signalName: "loadSucceeded" - } - - SignalSpy { id: downloadSpy target: webView.experimental signalName: "downloadRequested" @@ -86,45 +73,34 @@ Item { } function init() { - spy.clear() - otherSpy.clear() downloadSpy.clear() downloadFinishedSpy.clear() shouldDownload = false - originatingUrl = "" } function test_usePolicy() { - webView.load(beginUrl) - spy.wait() - spy.clear() + webView.url = beginUrl + verify(webView.waitForLoadSucceeded()) mouseClick(webView, 100, 100, Qt.LeftButton) - spy.wait() - compare(spy.count, 1) + verify(webView.waitForLoadSucceeded()) compare(webView.title, "Test page 1") compare(webView.url, endUrl) } function test_ignorePolicy() { - webView.load(beginUrl) - spy.wait() - spy.clear() - compare(spy.count, 0) - compare(otherSpy.count, 0) + webView.url = beginUrl + verify(webView.waitForLoadSucceeded()) mouseClick(webView, 100, 100, Qt.MiddleButton, Qt.ControlModifier) - otherSpy.wait() - compare(spy.count, 0) - compare(otherSpy.count, 1) + verify(otherWebView.waitForLoadSucceeded()) + verify(webView.loadStatus == null) compare(webView.url, beginUrl) compare(otherWebView.title, "Test page 1") compare(otherWebView.url, endUrl) } function test_downloadPolicy() { - webView.load(beginUrl) - spy.wait() - spy.clear() - compare(spy.count, 0) + webView.url = beginUrl + verify(webView.waitForLoadSucceeded()) downloadSpy.clear() downloadFinishedSpy.clear() expectedLength = 0 @@ -136,16 +112,5 @@ Item { compare(downloadFinishedSpy.count, 1) compare(totalBytes, expectedLength) } - - function test_originatingUrl() { - webView.load(beginUrl) - spy.wait() - spy.clear() - mouseClick(webView, 100, 100, Qt.LeftButton) - spy.wait() - compare(webView.title, "Test page 1") - compare(webView.url, endUrl) - compare(originatingUrl, beginUrl) - } } } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView.pro b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView.pro index 7f4e3d12f..57307f07a 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView.pro +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView.pro @@ -3,7 +3,7 @@ SOURCES += tst_qmltests.cpp TARGET = tst_qmltests_WebView OBJECTS_DIR = obj_WebView/$$activeBuildConfig() -CONFIG += qtwebkit-private +QT += webkit-private CONFIG += warn_on testcase QT -= testlib diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml index 8bcb5eccb..875bcd060 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_applicationScheme.qml @@ -78,7 +78,7 @@ WebView { spyTitle.clear() compare(spyTitle.count, 0) var testUrl = "applicationScheme://something" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "Test Application Scheme") } @@ -88,12 +88,12 @@ WebView { spyTitle.clear() compare(spyTitle.count, 0) var testUrl = "scheme2://some-url-string" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "Scheme2 Reply") testUrl = "scheme1://some-url-string" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "Scheme1 Reply") @@ -104,12 +104,12 @@ WebView { spyTitle.clear() compare(spyTitle.count, 0) var testUrl = "scheme3://url1" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "Scheme3 Reply1") testUrl = "scheme3://url2" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "Scheme3 Reply2") @@ -120,12 +120,12 @@ WebView { spyTitle.clear() compare(spyTitle.count, 0) var testUrl = "schemeCharset://latin1" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "title with copyright ©") testUrl = "schemeCharset://utf-8" - webView.load(testUrl) + webView.url = testUrl spyTitle.wait() compare(webView.title, "title with copyright ©") } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_download.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_download.qml index f8324a606..9f1d43231 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_download.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_download.qml @@ -61,14 +61,14 @@ WebView { function test_downloadRequest() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/download.zip")) + webView.url = Qt.resolvedUrl("../common/download.zip") spy.wait() compare(spy.count, 1) } function test_expectedLength() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/download.zip")) + webView.url = Qt.resolvedUrl("../common/download.zip") spy.wait() compare(spy.count, 1) compare(expectedLength, 325) @@ -76,7 +76,7 @@ WebView { function test_succeeded() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/download.zip")) + webView.url = Qt.resolvedUrl("../common/download.zip") spy.wait() compare(spy.count, 1) downloadFinishedSpy.wait() diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml index 121809316..20d538fbf 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_favIconLoad.qml @@ -1,8 +1,9 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView SignalSpy { @@ -11,12 +12,6 @@ WebView { signalName: "iconChanged" } - SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - Image { id: favicon source: webView.icon @@ -29,18 +24,17 @@ WebView { function init() { if (webView.icon != '') { // If this is not the first test, then load a blank page without favicon, restoring the initial state. - webView.load('about:blank') + webView.url = 'about:blank' spy.wait() - loadSpy.wait() + verify(webView.waitForLoadSucceeded()) } - loadSpy.clear() spy.clear() } function test_favIconLoad() { compare(spy.count, 0) var url = Qt.resolvedUrl("../common/favicon.html") - webView.load(url) + webView.url = url spy.wait() compare(spy.count, 1) compare(favicon.width, 48) @@ -50,7 +44,7 @@ WebView { function test_favIconLoadEncodedUrl() { compare(spy.count, 0) var url = Qt.resolvedUrl("../common/favicon2.html?favicon=load should work with#whitespace!") - webView.load(url) + webView.url = url spy.wait() compare(spy.count, 1) compare(favicon.width, 16) diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_geopermission.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_geopermission.qml index fd898a78e..41097bbcf 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_geopermission.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_geopermission.qml @@ -46,7 +46,7 @@ WebView { function test_permissionRequest() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/geolocation.html")) + webView.url = Qt.resolvedUrl("../common/geolocation.html") spy.wait() compare(spy.count, 1) } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_javaScriptDialogs.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_javaScriptDialogs.qml index 13adb3b2d..4e15c2344 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_javaScriptDialogs.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_javaScriptDialogs.qml @@ -2,8 +2,9 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 import QtWebKit.experimental 1.0 +import "../common" -WebView { +TestWebView { id: webView property bool modelMessageEqualsMessage: false @@ -54,12 +55,6 @@ WebView { } } - SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - TestCase { id: test name: "WebViewJavaScriptDialogs" @@ -69,55 +64,48 @@ WebView { webView.messageFromAlertDialog = "" webView.confirmCount = 0 webView.promptCount = 0 - loadSpy.clear() } function test_alert() { - webView.load(Qt.resolvedUrl("../common/alert.html")) - loadSpy.wait() - compare(loadSpy.count, 1) + webView.url = Qt.resolvedUrl("../common/alert.html") + verify(webView.waitForLoadSucceeded()) compare(webView.messageFromAlertDialog, "Hello Qt") verify(webView.modelMessageEqualsMessage) } function test_alertWithoutDialog() { webView.experimental.alertDialog = null - webView.load(Qt.resolvedUrl("../common/alert.html")) - loadSpy.wait() - compare(loadSpy.count, 1) + webView.url = Qt.resolvedUrl("../common/alert.html") + verify(webView.waitForLoadSucceeded()) compare(webView.messageFromAlertDialog, "") } function test_confirm() { - webView.load(Qt.resolvedUrl("../common/confirm.html")) - loadSpy.wait() - compare(loadSpy.count, 1) + webView.url = Qt.resolvedUrl("../common/confirm.html") + verify(webView.waitForLoadSucceeded()) compare(webView.confirmCount, 2) compare(webView.title, "ACCEPTED REJECTED") } function test_confirmWithoutDialog() { webView.experimental.confirmDialog = null - webView.load(Qt.resolvedUrl("../common/confirm.html")) - loadSpy.wait() - compare(loadSpy.count, 1) + webView.url = Qt.resolvedUrl("../common/confirm.html") + verify(webView.waitForLoadSucceeded()) compare(webView.confirmCount, 0) compare(webView.title, "ACCEPTED ACCEPTED") } function test_prompt() { - webView.load(Qt.resolvedUrl("../common/prompt.html")) - loadSpy.wait() - compare(loadSpy.count, 1) + webView.url = Qt.resolvedUrl("../common/prompt.html") + verify(webView.waitForLoadSucceeded()) compare(webView.promptCount, 2) compare(webView.title, "tQ olleH") } function test_promptWithoutDialog() { webView.experimental.promptDialog = null - webView.load(Qt.resolvedUrl("../common/prompt.html")) - loadSpy.wait() - compare(loadSpy.count, 1) + webView.url = Qt.resolvedUrl("../common/prompt.html") + verify(webView.waitForLoadSucceeded()) compare(webView.promptCount, 0) compare(webView.title, "FAIL") } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadFail.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadFail.qml index 26a42c0b7..51c1f7dd0 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadFail.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadFail.qml @@ -1,35 +1,30 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 400 height: 300 property variant testUrl - SignalSpy { - id: spy - target: webView - signalName: "loadFailed" - } - TestCase { id: test name: "WebViewLoadFail" function test_fail() { - compare(spy.count, 0) testUrl = Qt.resolvedUrl("file_that_does_not_exist.html") - webView.load(testUrl) - spy.wait() - compare(spy.count, 1) + webView.url = testUrl + verify(webView.waitForLoadFailed()) } } - onLoadFailed: { - test.compare(url, testUrl) - test.compare(errorCode, NetworkReply.ContentNotFoundError) - test.compare(errorDomain, WebView.NetworkErrorDomain) + onLoadingChanged: { + if (loadRequest.status == WebView.LoadFailedStatus) { + test.compare(loadRequest.url, testUrl) + test.compare(loadRequest.errorCode, NetworkReply.ContentNotFoundError) + test.compare(loadRequest.errorDomain, WebView.NetworkErrorDomain) + } } } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadHtml.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadHtml.qml index b57df66a6..297c082e5 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadHtml.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadHtml.qml @@ -1,27 +1,20 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 200 height: 400 - SignalSpy { - id: loadSpy - target: webView - signalName: "loadSucceeded" - } - TestCase { name: "WebViewLoadHtml" function test_loadProgressAfterLoadHtml() { - loadSpy.clear() - compare(loadSpy.count, 0) compare(webView.loadProgress, 0) webView.loadHtml("<html><head><title>Test page 1</title></head><body>Hello.</body></html>") - loadSpy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.loadProgress, 100) } } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgress.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgress.qml index a51d6f69f..2f95ef11d 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgress.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgress.qml @@ -1,27 +1,21 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 400 height: 300 - SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - TestCase { name: "WebViewLoadProgress" function test_loadProgress() { - compare(spy.count, 0) compare(webView.loadProgress, 0) - webView.load(Qt.resolvedUrl("../common/test1.html")) + webView.url = Qt.resolvedUrl("../common/test1.html") compare(webView.loadProgress, 0) - spy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.loadProgress, 100) } } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgressSignal.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgressSignal.qml index 10ac879a8..620686003 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgressSignal.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadProgressSignal.qml @@ -1,19 +1,14 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 400 height: 300 SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - - SignalSpy { id: spyProgress target: webView signalName: "loadProgressChanged" @@ -25,11 +20,11 @@ WebView { function test_loadProgressSignal() { compare(spyProgress.count, 0) compare(webView.loadProgress, 0) - webView.load(Qt.resolvedUrl("../common/test1.html")) + webView.url = Qt.resolvedUrl("../common/test1.html") spyProgress.wait() compare(true, webView.loadProgress > -1 && webView.loadProgress < 101) if (webView.loadProgress > 0 && webView.loadProgress < 100) { - spy.wait() + verify(webView.waitForLoadSucceeded()) spyProgress.wait() compare(webView.loadProgress, 100) } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml index d70976c4a..8fcbae54a 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_loadUrl.qml @@ -1,11 +1,14 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView property variant lastUrl property bool watchProgress: false + property int numLoadStarted: 0 + property int numLoadSucceeded: 0 onLoadProgressChanged: { if (watchProgress && webView.loadProgress != 100) { @@ -14,40 +17,44 @@ WebView { } } - SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" + onLoadingChanged: { + if (loadRequest.status == WebView.LoadStartedStatus) + ++numLoadStarted + if (loadRequest.status == WebView.LoadSucceededStatus) + ++numLoadSucceeded } TestCase { id: test name: "WebViewLoadUrl" function test_loadIgnoreEmptyUrl() { - compare(spy.count, 0) var url = Qt.resolvedUrl("../common/test1.html") - webView.load(url) - spy.wait() - compare(spy.count, 1) + webView.url = url + verify(webView.waitForLoadSucceeded()) + compare(numLoadStarted, 1) + compare(numLoadSucceeded, 1) compare(webView.url, url) lastUrl = webView.url - webView.load('') + webView.url = '' wait(1000) - compare(spy.count, 1) + compare(numLoadStarted, 1) + compare(numLoadSucceeded, 1) compare(webView.url, lastUrl) - webView.load('about:blank') - spy.wait() - compare(spy.count, 2) + webView.url = 'about:blank' + verify(webView.waitForLoadSucceeded()) + compare(numLoadStarted, 2) + compare(numLoadSucceeded, 2) compare(webView.url, 'about:blank') // It shouldn't interrupt any ongoing load when an empty url is used. watchProgress = true - webView.load(url) - spy.wait() - compare(spy.count, 3) + webView.url = url + webView.waitForLoadSucceeded() + compare(numLoadStarted, 3) + compare(numLoadSucceeded, 3) verify(!watchProgress) compare(webView.url, url) } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_navigationHistory.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_navigationHistory.qml index b886e48f3..3b51c9cc1 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_navigationHistory.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_navigationHistory.qml @@ -2,18 +2,13 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 import QtWebKit.experimental 1.0 +import "../common" -WebView { +TestWebView { id: webView width: 400 height: 300 - SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - ListView { id: backItemsList anchors.fill: parent @@ -40,64 +35,56 @@ WebView { name: "WebViewNavigationHistory" function test_navigationHistory() { - compare(spy.count, 0) compare(webView.loadProgress, 0) - webView.load(Qt.resolvedUrl("../common/test1.html")) - spy.wait() + webView.url = Qt.resolvedUrl("../common/test1.html") + verify(webView.waitForLoadSucceeded()) compare(webView.canGoBack, false) compare(webView.canGoForward, false) compare(backItemsList.count, 0) compare(forwardItemsList.count, 0) - spy.clear() - webView.load(Qt.resolvedUrl("../common/test2.html")) - spy.wait() + webView.url = Qt.resolvedUrl("../common/test2.html") + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/test2.html")) compare(webView.canGoBack, true) compare(webView.canGoForward, false) compare(backItemsList.count, 1) - spy.clear() webView.experimental.goBackTo(0) - spy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/test1.html")) compare(webView.canGoBack, false) compare(webView.canGoForward, true) compare(backItemsList.count, 0) compare(forwardItemsList.count, 1) - spy.clear() webView.goForward() - spy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/test2.html")) compare(webView.canGoBack, true) compare(webView.canGoForward, false) compare(backItemsList.count, 1) compare(forwardItemsList.count, 0) - spy.clear() - webView.load(Qt.resolvedUrl("../common/javascript.html")) - spy.wait() + webView.url = Qt.resolvedUrl("../common/javascript.html") + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/javascript.html")) compare(webView.canGoBack, true) compare(webView.canGoForward, false) compare(backItemsList.count, 2) compare(forwardItemsList.count, 0) - spy.clear() webView.experimental.goBackTo(1) - spy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/test1.html")) compare(webView.canGoBack, false) compare(webView.canGoForward, true) compare(backItemsList.count, 0) compare(forwardItemsList.count, 2) - spy.clear() webView.experimental.goForwardTo(1) - spy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/javascript.html")) compare(webView.canGoBack, true) compare(webView.canGoForward, false) compare(backItemsList.count, 2) compare(forwardItemsList.count, 0) - spy.clear() webView.goBack() - spy.wait() + verify(webView.waitForLoadSucceeded()) compare(webView.url, Qt.resolvedUrl("../common/test2.html")) compare(webView.canGoBack, true) compare(webView.canGoForward, true) diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_origin.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_origin.qml index 70745d8d6..660ca7326 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_origin.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_origin.qml @@ -48,7 +48,7 @@ WebView { function test_permissionRequest() { compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/geolocation.html")) + webView.url = Qt.resolvedUrl("../common/geolocation.html") spy.wait() compare(spy.count, 1) compare(webView.success, true) diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml index 917b689e6..4f356e88b 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_preferences.qml @@ -2,9 +2,10 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 import QtWebKit.experimental 1.0 +import "../common" Item { - WebView { + TestWebView { id: webView width: 400 height: 300 @@ -13,19 +14,13 @@ Item { experimental.preferences.localStorageEnabled: true experimental.preferences.pluginsEnabled: true - WebView { + TestWebView { id: webView2 width: 400 height: 300 } SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - - SignalSpy { id: titleSpy target: webView signalName: "titleChanged" @@ -85,12 +80,6 @@ Item { signalName: "defaultFixedFontSizeChanged" } - SignalSpy { - id: otherSpy - target: webView2 - signalName: "loadSucceeded" - } - TestCase { name: "WebViewPreferences" @@ -132,9 +121,8 @@ Item { webView.experimental.preferences.defaultFixedFontSize = defaultFixedFontSize if (webView.url != '' && webView.url != 'about:blank') { - spy.clear() - webView.load('about:blank') - spy.wait() + webView.url = 'about:blank' + verify(webView.waitForLoadSucceeded()) } standardFontFamilySpy.clear() @@ -151,42 +139,40 @@ Item { webView.experimental.preferences.javascriptEnabled = true webView.experimental.preferences.localStorageEnabled = true webView.experimental.preferences.pluginsEnabled = true - spy.clear() titleSpy.clear() } function test_javascriptEnabled() { webView.experimental.preferences.javascriptEnabled = true var testUrl = Qt.resolvedUrl("../common/javascript.html") - webView.load(testUrl) - spy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) compare(webView.title, "New Title") } function test_javascriptDisabled() { webView.experimental.preferences.javascriptEnabled = false var testUrl = Qt.resolvedUrl("../common/javascript.html") - webView.load(testUrl) - spy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) compare(webView.title, "Original Title") } function test_localStorageDisabled() { webView.experimental.preferences.localStorageEnabled = false var testUrl = Qt.resolvedUrl("../common/localStorage.html") - webView.load(testUrl) - spy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) compare(webView.title, "Original Title") } function test_localStorageEnabled() { webView.experimental.preferences.localStorageEnabled = true var testUrl = Qt.resolvedUrl("../common/localStorage.html") - webView.load(testUrl) - spy.wait() - spy.clear() - webView.load(testUrl) - spy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) compare(webView.title, "New Title") } @@ -194,26 +180,24 @@ Item { webView.experimental.preferences.javascriptEnabled = true webView2.experimental.preferences.javascriptEnabled = true var testUrl = Qt.resolvedUrl("../common/javascript.html") - webView.load(testUrl) - spy.wait() - webView2.load(testUrl) - otherSpy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) + webView2.url = testUrl + verify(webView2.waitForLoadSucceeded()) compare(webView.title, "New Title") compare(webView2.title, "New Title") - spy.clear() - otherSpy.clear() webView.experimental.preferences.javascriptEnabled = false - webView.load(testUrl) - spy.wait() - webView2.load(testUrl) - otherSpy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) + webView2.url = testUrl + verify(webView2.waitForLoadSucceeded()) compare(webView.title, "Original Title") compare(webView2.title, "New Title") } function test_standardFontFamilyChanged() { var url = Qt.resolvedUrl("../common/font-preferences.html?standard#font-family") - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -222,7 +206,7 @@ Item { webView.experimental.preferences.standardFontFamily = "foobar" standardFontFamilySpy.wait() compare(standardFontFamilySpy.count, 1) - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -231,7 +215,7 @@ Item { function test_fontSizeChanged() { var url = Qt.resolvedUrl("../common/font-preferences.html?standard#font-size") - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -240,7 +224,7 @@ Item { webView.experimental.preferences.defaultFontSize = defaultFontSize + 1 defaultFontSizeSpy.wait() compare(defaultFontSizeSpy.count, 1) - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -249,7 +233,7 @@ Item { function test_fixedFontSizeChanged() { var url = Qt.resolvedUrl("../common/font-preferences.html?fixed#font-size") - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -258,13 +242,13 @@ Item { webView.experimental.preferences.defaultFixedFontSize = defaultFixedFontSize + 1 defaultFixedFontSizeSpy.wait() compare(defaultFixedFontSizeSpy.count, 1) - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() compare(webView.title, (defaultFixedFontSize + 1).toString() + "px") - webView.load(Qt.resolvedUrl("../common/font-preferences.html?standard#font-size")) + webView.url = Qt.resolvedUrl("../common/font-preferences.html?standard#font-size") titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -274,7 +258,7 @@ Item { function test_minimumFontSizeChanged() { verify(defaultMinimumFontSize < defaultFontSize) var url = Qt.resolvedUrl("../common/font-preferences.html?minimum#font-size") - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() @@ -286,7 +270,7 @@ Item { webView.experimental.preferences.minimumFontSize = defaultFontSize minimumFontSizeSpy.wait() compare(minimumFontSizeSpy.count, 1) - webView.load(url) + webView.url = url titleSpy.wait() compare(webView.title, "Original Title") titleSpy.wait() diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_properties.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_properties.qml index 4761cd322..036ee9d86 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_properties.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_properties.qml @@ -1,33 +1,26 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 400 height: 300 - SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - TestCase { name: "WebViewProperties" function test_title() { - compare(spy.count, 0) - webView.load(Qt.resolvedUrl("../common/test1.html")) - spy.wait() + webView.url = Qt.resolvedUrl("../common/test1.html") + verify(webView.waitForLoadSucceeded()) compare(webView.title, "Test page 1") } function test_url() { - compare(spy.count, 1) var testUrl = Qt.resolvedUrl("../common/test1.html") - webView.load(testUrl) - spy.wait() + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) compare(webView.url, testUrl) } } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_titleChanged.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_titleChanged.qml index f36ea8579..04f2c7e13 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_titleChanged.qml +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_titleChanged.qml @@ -1,19 +1,14 @@ import QtQuick 2.0 import QtTest 1.0 import QtWebKit 3.0 +import "../common" -WebView { +TestWebView { id: webView width: 400 height: 300 SignalSpy { - id: spy - target: webView - signalName: "loadSucceeded" - } - - SignalSpy { id: spyTitle target: webView signalName: "titleChanged" @@ -25,7 +20,8 @@ WebView { function test_titleFirstLoad() { compare(spyTitle.count, 0) var testUrl = Qt.resolvedUrl("../common/test3.html") - webView.load(testUrl) + webView.url = testUrl + verify(webView.waitForLoadSucceeded()) spyTitle.wait() compare(webView.title, "Test page 3") spyTitle.wait() diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/TestWebView.qml b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/TestWebView.qml new file mode 100644 index 000000000..aa0baae4f --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/TestWebView.qml @@ -0,0 +1,36 @@ +import QtQuick 2.0 +import QtTest 1.0 +import QtWebKit 3.0 +import QtWebKit.experimental 1.0 + +WebView { + property var loadStatus: null + + function waitForLoadSucceeded() { + var timeout = 5000 + var i = 0 + while (i < timeout && loadStatus != WebView.LoadSucceededStatus) { + testResult.wait(50) + i += 50 + } + var success = loadStatus == WebView.LoadSucceededStatus + loadStatus = null + return success + } + function waitForLoadFailed() { + var timeout = 5000 + var i = 0 + while (i < timeout && loadStatus != WebView.LoadFailedStatus) { + testResult.wait(50) + i += 50 + } + var failure = loadStatus == WebView.LoadFailedStatus + loadStatus = null + return failure + } + + TestResult { id: testResult } + + onLoadingChanged: loadStatus = loadRequest.status +} + diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp index bcc246db4..782b041ca 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/tst_qmltests.cpp @@ -20,7 +20,7 @@ #include "../bytearraytestdata.h" #include "../util.h" -#include "qquickwebview_p.h" +#include "private/qquickwebview_p.h" #include <QGuiApplication> #include <QVarLengthArray> #include <QtQuickTest/quicktest.h> diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/qquickwebview.pro b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/qquickwebview.pro index 25cd8324f..4a8d86f80 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/qquickwebview.pro +++ b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/qquickwebview.pro @@ -1,4 +1,4 @@ include(../tests.pri) SOURCES += $${TARGET}.cpp -CONFIG += qtwebkit-private +QT += webkit-private DEFINES += IMPORT_DIR=\"\\\"$${ROOT_BUILD_DIR}$${QMAKE_DIR_SEP}imports\\\"\" diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp index 12886b314..a6b13990a 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp @@ -23,8 +23,9 @@ #include <QDeclarativeEngine> #include <QScopedPointer> #include <QtTest/QtTest> -#include <qquickwebpage_p.h> -#include <qquickwebview_p.h> +#include <private/qquickwebpage_p.h> +#include <private/qquickwebview_p.h> +#include <private/qwebloadrequest_p.h> class tst_QQuickWebView : public QObject { Q_OBJECT @@ -54,6 +55,7 @@ private slots: void removeFromCanvas(); void multipleWebViewWindows(); void multipleWebViews(); + void transparentWebViews(); private: void prepareWebViewComponent(); @@ -120,8 +122,6 @@ void tst_QQuickWebView::navigationStatusAtStartup() QCOMPARE(webView()->canGoForward(), false); QCOMPARE(webView()->loading(), false); - - QCOMPARE(webView()->canReload(), false); } class LoadStartedCatcher : public QObject { @@ -130,15 +130,17 @@ public: LoadStartedCatcher(QQuickWebView* webView) : m_webView(webView) { - connect(m_webView, SIGNAL(loadStarted()), this, SLOT(onLoadStarted())); + connect(m_webView, SIGNAL(loadingChanged(QWebLoadRequest*)), this, SLOT(onLoadingChanged(QWebLoadRequest*))); } public slots: - void onLoadStarted() + void onLoadingChanged(QWebLoadRequest* loadRequest) { - QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); + if (loadRequest->status() == QQuickWebView::LoadStartedStatus) { + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); - QCOMPARE(m_webView->loading(), true); + QCOMPARE(m_webView->loading(), true); + } } signals: @@ -153,12 +155,12 @@ void tst_QQuickWebView::stopEnabledAfterLoadStarted() QCOMPARE(webView()->loading(), false); LoadStartedCatcher catcher(webView()); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); waitForSignal(&catcher, SIGNAL(finished())); QCOMPARE(webView()->loading(), true); - waitForSignal(webView(), SIGNAL(loadSucceeded())); + QVERIFY(waitForLoadSucceeded(webView())); } void tst_QQuickWebView::baseUrl() @@ -169,8 +171,8 @@ void tst_QQuickWebView::baseUrl() void tst_QQuickWebView::loadEmptyUrl() { - webView()->load(QUrl()); - webView()->load(QUrl(QLatin1String(""))); + webView()->setUrl(QUrl()); + webView()->setUrl(QUrl(QLatin1String(""))); } void tst_QQuickWebView::loadEmptyPageViewVisible() @@ -181,64 +183,64 @@ void tst_QQuickWebView::loadEmptyPageViewVisible() void tst_QQuickWebView::loadEmptyPageViewHidden() { - QSignalSpy loadStartedSpy(webView(), SIGNAL(loadStarted())); + QSignalSpy loadSpy(webView(), SIGNAL(loadingChanged(QWebLoadRequest*))); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView())); - QCOMPARE(loadStartedSpy.size(), 1); + QCOMPARE(loadSpy.size(), 2); } void tst_QQuickWebView::loadNonexistentFileUrl() { - QSignalSpy loadFailedSpy(webView(), SIGNAL(loadStarted())); + QSignalSpy loadSpy(webView(), SIGNAL(loadingChanged(QWebLoadRequest*))); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/file_that_does_not_exist.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadFailed(QQuickWebView::ErrorDomain, int, QUrl, QString)))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/file_that_does_not_exist.html"))); + QVERIFY(waitForLoadFailed(webView())); - QCOMPARE(loadFailedSpy.size(), 1); + QCOMPARE(loadSpy.size(), 2); } void tst_QQuickWebView::backAndForward() { - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html"))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html")); webView()->goBack(); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); webView()->goForward(); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page2.html")); } void tst_QQuickWebView::reload() { - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); webView()->reload(); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); } void tst_QQuickWebView::stop() { - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView())); QCOMPARE(webView()->url().path(), QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")); @@ -250,9 +252,9 @@ void tst_QQuickWebView::loadProgress() { QCOMPARE(webView()->loadProgress(), 0); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QSignalSpy loadProgressChangedSpy(webView(), SIGNAL(loadProgressChanged(int))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QSignalSpy loadProgressChangedSpy(webView(), SIGNAL(loadProgressChanged())); + QVERIFY(waitForLoadSucceeded(webView())); QVERIFY(loadProgressChangedSpy.count() >= 1); @@ -271,8 +273,8 @@ void tst_QQuickWebView::showWebView() { webView()->setSize(QSizeF(300, 400)); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/direct-image-compositing.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/direct-image-compositing.html"))); + QVERIFY(waitForLoadSucceeded(webView())); m_window->show(); // This should not crash. @@ -307,14 +309,14 @@ void tst_QQuickWebView::multipleWebViewWindows() QScopedPointer<TestWindow> window2(new TestWindow(webView2)); webView1->setSize(QSizeF(300, 400)); - webView1->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); - QVERIFY(waitForSignal(webView1, SIGNAL(loadSucceeded()))); + webView1->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); + QVERIFY(waitForLoadSucceeded(webView1)); window1->show(); webView1->setVisible(true); webView2->setSize(QSizeF(300, 400)); - webView2->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QVERIFY(waitForSignal(webView2, SIGNAL(loadSucceeded()))); + webView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView2)); window2->show(); webView2->setVisible(true); QTest::qWait(200); @@ -331,23 +333,50 @@ void tst_QQuickWebView::multipleWebViews() webView2->setParentItem(m_window->rootItem()); webView1->setSize(QSizeF(300, 400)); - webView1->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); - QVERIFY(waitForSignal(webView1.data(), SIGNAL(loadSucceeded()))); + webView1->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); + QVERIFY(waitForLoadSucceeded(webView1.data())); webView1->setVisible(true); webView2->setSize(QSizeF(300, 400)); - webView2->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); - QVERIFY(waitForSignal(webView2.data(), SIGNAL(loadSucceeded()))); + webView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView2.data())); webView2->setVisible(true); QTest::qWait(200); } +void tst_QQuickWebView::transparentWebViews() +{ + showWebView(); + + // This should not crash. + QScopedPointer<QQuickWebView> webView1(newWebView()); + webView1->setParentItem(m_window->rootItem()); + QScopedPointer<QQuickWebView> webView2(newWebView()); + webView2->setParentItem(m_window->rootItem()); + QVERIFY(!webView1->experimental()->transparentBackground()); + webView2->experimental()->setTransparentBackground(true); + QVERIFY(webView2->experimental()->transparentBackground()); + + webView1->setSize(QSizeF(300, 400)); + webView1->loadHtml("<html><body bgcolor=\"red\"></body></html>"); + QVERIFY(waitForLoadSucceeded(webView1.data())); + webView1->setVisible(true); + + webView2->setSize(QSizeF(300, 400)); + webView2->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html"))); + QVERIFY(waitForLoadSucceeded(webView2.data())); + webView2->setVisible(true); + + QTest::qWait(200); + // FIXME: test actual rendering results; https://bugs.webkit.org/show_bug.cgi?id=80609. +} + void tst_QQuickWebView::scrollRequest() { webView()->setSize(QSizeF(300, 400)); - webView()->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); - QVERIFY(waitForSignal(webView(), SIGNAL(loadSucceeded()))); + webView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html"))); + QVERIFY(waitForLoadSucceeded(webView())); // COMPARE with the position requested in the html // Use qRound as that is also used when calculating the position diff --git a/Source/WebKit2/UIProcess/API/qt/tests/tests.pri b/Source/WebKit2/UIProcess/API/qt/tests/tests.pri index faf445397..aa8da8bc9 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/tests.pri +++ b/Source/WebKit2/UIProcess/API/qt/tests/tests.pri @@ -9,9 +9,7 @@ SOURCES += ../util.cpp \ ../bytearraytestdata.cpp INCLUDEPATH += $$PWD -QT += testlib declarative quick - -CONFIG += qtwebkit +QT += testlib declarative quick webkit DEFINES += TESTS_SOURCE_DIR=\\\"$$PWD\\\" \ QWP_PATH=\\\"$${ROOT_BUILD_DIR}/bin\\\" diff --git a/Source/WebKit2/UIProcess/API/qt/tests/util.cpp b/Source/WebKit2/UIProcess/API/qt/tests/util.cpp index e230221e6..43a6696ef 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/util.cpp +++ b/Source/WebKit2/UIProcess/API/qt/tests/util.cpp @@ -18,6 +18,8 @@ */ #include "util.h" +#include "private/qquickwebview_p.h" +#include "private/qwebloadrequest_p.h" #include <stdio.h> void addQtWebProcessToPath() @@ -50,6 +52,58 @@ bool waitForSignal(QObject* obj, const char* signal, int timeout) return timeoutSpy.isEmpty(); } +class LoadSpy : public QEventLoop { + Q_OBJECT +public: + LoadSpy(QQuickWebView* webView) + { + connect(webView, SIGNAL(loadingChanged(QWebLoadRequest*)), SLOT(onLoadingChanged(QWebLoadRequest*))); + } +signals: + void loadSucceeded(); + void loadFailed(); +private slots: + void onLoadingChanged(QWebLoadRequest* loadRequest) + { + if (loadRequest->status() == QQuickWebView::LoadSucceededStatus) + emit loadSucceeded(); + else if (loadRequest->status() == QQuickWebView::LoadFailedStatus) + emit loadFailed(); + } +}; + +bool waitForLoadSucceeded(QQuickWebView* webView, int timeout) +{ + QEventLoop loop; + LoadSpy loadSpy(webView); + QObject::connect(&loadSpy, SIGNAL(loadSucceeded()), &loop, SLOT(quit())); + QTimer timer; + QSignalSpy timeoutSpy(&timer, SIGNAL(timeout())); + if (timeout > 0) { + QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + timer.setSingleShot(true); + timer.start(timeout); + } + loop.exec(); + return timeoutSpy.isEmpty(); +} + +bool waitForLoadFailed(QQuickWebView* webView, int timeout) +{ + QEventLoop loop; + LoadSpy loadSpy(webView); + QObject::connect(&loadSpy, SIGNAL(loadFailed()), &loop, SLOT(quit())); + QTimer timer; + QSignalSpy timeoutSpy(&timer, SIGNAL(timeout())); + if (timeout > 0) { + QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + timer.setSingleShot(true); + timer.start(timeout); + } + loop.exec(); + return timeoutSpy.isEmpty(); +} + static void messageHandler(QtMsgType type, const char* message) { if (type == QtCriticalMsg) { @@ -65,3 +119,5 @@ void suppressDebugOutput() if (qgetenv("QT_WEBKIT_SUPPRESS_WEB_PROCESS_OUTPUT").isEmpty()) \ qputenv("QT_WEBKIT_SUPPRESS_WEB_PROCESS_OUTPUT", "1"); } + +#include "util.moc" diff --git a/Source/WebKit2/UIProcess/API/qt/tests/util.h b/Source/WebKit2/UIProcess/API/qt/tests/util.h index 1c052bc9a..f7be8b11e 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/util.h +++ b/Source/WebKit2/UIProcess/API/qt/tests/util.h @@ -22,10 +22,14 @@ #include <QSignalSpy> #include <QTimer> +class QQuickWebView; + #if !defined(TESTS_SOURCE_DIR) #define TESTS_SOURCE_DIR "" #endif void addQtWebProcessToPath(); bool waitForSignal(QObject*, const char* signal, int timeout = 10000); +bool waitForLoadSucceeded(QQuickWebView* webView, int timeout = 10000); +bool waitForLoadFailed(QQuickWebView* webView, int timeout = 10000); void suppressDebugOutput(); diff --git a/Source/WebKit2/UIProcess/DrawingAreaProxy.cpp b/Source/WebKit2/UIProcess/DrawingAreaProxy.cpp index 9bb9783ca..08b225743 100644 --- a/Source/WebKit2/UIProcess/DrawingAreaProxy.cpp +++ b/Source/WebKit2/UIProcess/DrawingAreaProxy.cpp @@ -28,7 +28,7 @@ #include "WebPageProxy.h" -#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) +#if USE(UI_SIDE_COMPOSITING) #include "LayerTreeHostProxy.h" #include <CoreIPC/MessageID.h> #endif @@ -58,7 +58,7 @@ void DrawingAreaProxy::setSize(const IntSize& size, const IntSize& scrollOffset) sizeDidChange(); } -#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) +#if USE(UI_SIDE_COMPOSITING) void DrawingAreaProxy::updateViewport() { m_webPageProxy->setViewNeedsDisplay(viewportVisibleRect()); @@ -69,12 +69,9 @@ WebCore::IntRect DrawingAreaProxy::contentsRect() const return IntRect(IntPoint::zero(), m_webPageProxy->viewSize()); } -#if USE(TILED_BACKING_STORE) void DrawingAreaProxy::didReceiveLayerTreeHostProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) { } #endif -#endif - } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/DrawingAreaProxy.h b/Source/WebKit2/UIProcess/DrawingAreaProxy.h index e78c3cdf0..8b8dc2b0d 100644 --- a/Source/WebKit2/UIProcess/DrawingAreaProxy.h +++ b/Source/WebKit2/UIProcess/DrawingAreaProxy.h @@ -74,6 +74,8 @@ public: // FIXME: These should be pure virtual. virtual void visibilityDidChange() { } + virtual void layerHostingModeDidChange() { } + virtual void setBackingStoreIsDiscardable(bool) { } virtual void waitForBackingStoreUpdateOnNextPaint() { } @@ -83,7 +85,7 @@ public: virtual void pageCustomRepresentationChanged() { } -#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) +#if USE(UI_SIDE_COMPOSITING) virtual void updateViewport(); virtual WebCore::IntRect viewportVisibleRect() const { return contentsRect(); } virtual WebCore::IntRect contentsRect() const; @@ -91,8 +93,6 @@ public: virtual void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float, const WebCore::FloatRect&) { } virtual void paintLayerTree(BackingStore::PlatformGraphicsContext) { } LayerTreeHostProxy* layerTreeHostProxy() const { return m_layerTreeHostProxy.get(); } - -#if USE(TILED_BACKING_STORE) virtual void setVisibleContentsRectForScaling(const WebCore::IntRect& visibleContentsRect, float scale) { } virtual void setVisibleContentsRectForPanning(const WebCore::IntRect& visibleContentsRect, const WebCore::FloatPoint& trajectoryVector) { } virtual void createTileForLayer(int layerID, int tileID, const WebKit::UpdateInfo&) { } @@ -102,7 +102,6 @@ public: WebPageProxy* page() { return m_webPageProxy; } #endif -#endif protected: explicit DrawingAreaProxy(DrawingAreaType, WebPageProxy*); @@ -112,7 +111,7 @@ protected: WebCore::IntSize m_size; WebCore::IntSize m_scrollOffset; -#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) +#if USE(UI_SIDE_COMPOSITING) OwnPtr<LayerTreeHostProxy> m_layerTreeHostProxy; #endif @@ -126,6 +125,7 @@ private: #if USE(ACCELERATED_COMPOSITING) virtual void enterAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&) { } virtual void exitAcceleratedCompositingMode(uint64_t backingStoreStateID, const UpdateInfo&) { } + virtual void updateAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&) { } #endif #if PLATFORM(MAC) virtual void didUpdateGeometry() { } diff --git a/Source/WebKit2/UIProcess/DrawingAreaProxy.messages.in b/Source/WebKit2/UIProcess/DrawingAreaProxy.messages.in index e27b5bf26..7dbdcebab 100644 --- a/Source/WebKit2/UIProcess/DrawingAreaProxy.messages.in +++ b/Source/WebKit2/UIProcess/DrawingAreaProxy.messages.in @@ -26,6 +26,7 @@ messages -> DrawingAreaProxy { #if USE(ACCELERATED_COMPOSITING) EnterAcceleratedCompositingMode(uint64_t backingStoreStateID, WebKit::LayerTreeContext context) ExitAcceleratedCompositingMode(uint64_t backingStoreStateID, WebKit::UpdateInfo updateInfo) + UpdateAcceleratedCompositingMode(uint64_t backingStoreStateID, WebKit::LayerTreeContext context) #endif #if PLATFORM(MAC) diff --git a/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp b/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp index 220f9ece2..c0d044bf8 100644 --- a/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp +++ b/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp @@ -36,7 +36,7 @@ #include "WebProcessProxy.h" #include <WebCore/Region.h> -#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) +#if USE(UI_SIDE_COMPOSITING) #include "LayerTreeHostProxy.h" #endif @@ -58,7 +58,7 @@ DrawingAreaProxyImpl::DrawingAreaProxyImpl(WebPageProxy* webPageProxy) , m_isBackingStoreDiscardable(true) , m_discardBackingStoreTimer(RunLoop::current(), this, &DrawingAreaProxyImpl::discardBackingStore) { -#if USE(TEXTURE_MAPPER) +#if USE(UI_SIDE_COMPOSITING) // Construct the proxy early to allow messages to be sent to the web process while AC is entered there. if (webPageProxy->pageGroup()->preferences()->forceCompositingMode()) m_layerTreeHostProxy = adoptPtr(new LayerTreeHostProxy(this)); @@ -335,13 +335,13 @@ void DrawingAreaProxyImpl::enterAcceleratedCompositingMode(const LayerTreeContex m_backingStore = nullptr; m_layerTreeContext = layerTreeContext; m_webPageProxy->enterAcceleratedCompositingMode(layerTreeContext); -#if USE(TEXTURE_MAPPER) +#if USE(UI_SIDE_COMPOSITING) if (!m_layerTreeHostProxy) m_layerTreeHostProxy = adoptPtr(new LayerTreeHostProxy(this)); #endif } -#if USE(TILED_BACKING_STORE) +#if USE(UI_SIDE_COMPOSITING) void DrawingAreaProxyImpl::didReceiveLayerTreeHostProxyMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) { if (m_layerTreeHostProxy) diff --git a/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h b/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h index 25c279b0b..613073bab 100644 --- a/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h +++ b/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h @@ -77,7 +77,7 @@ private: bool isInAcceleratedCompositingMode() const { return !m_layerTreeContext.isEmpty(); } -#if USE(TILED_BACKING_STORE) +#if USE(UI_SIDE_COMPOSITING) virtual void setVisibleContentsRectForScaling(const WebCore::IntRect& visibleContentsRect, float scale); virtual void setVisibleContentsRectForPanning(const WebCore::IntRect& visibleContentsRect, const WebCore::FloatPoint&); virtual void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float opacity, const WebCore::FloatRect&); diff --git a/Source/WebKit2/UIProcess/GeolocationPermissionRequestManagerProxy.cpp b/Source/WebKit2/UIProcess/GeolocationPermissionRequestManagerProxy.cpp index 38bbd6a16..71beaf5a5 100644 --- a/Source/WebKit2/UIProcess/GeolocationPermissionRequestManagerProxy.cpp +++ b/Source/WebKit2/UIProcess/GeolocationPermissionRequestManagerProxy.cpp @@ -63,7 +63,10 @@ void GeolocationPermissionRequestManagerProxy::didReceiveGeolocationPermissionDe if (it == m_pendingRequests.end()) return; +#if ENABLE(GEOLOCATION) m_page->process()->send(Messages::WebPage::DidReceiveGeolocationPermissionDecision(geolocationID, allowed), m_page->pageID()); +#endif + m_pendingRequests.remove(it); } diff --git a/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h index 8dbfb1101..09c5589f3 100644 --- a/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h +++ b/Source/WebKit2/UIProcess/Launcher/ProcessLauncher.h @@ -31,10 +31,6 @@ #include <wtf/RefPtr.h> #include <wtf/Threading.h> -#if PLATFORM(QT) -class QLocalSocket; -#endif - namespace WebKit { class ProcessLauncher : public ThreadSafeRefCounted<ProcessLauncher> { diff --git a/Source/WebKit2/UIProcess/LayerTreeHostProxy.cpp b/Source/WebKit2/UIProcess/LayerTreeHostProxy.cpp new file mode 100644 index 000000000..e760a7dae --- /dev/null +++ b/Source/WebKit2/UIProcess/LayerTreeHostProxy.cpp @@ -0,0 +1,143 @@ +/* + Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#if USE(UI_SIDE_COMPOSITING) +#include "LayerTreeHostProxy.h" + +#include "LayerTreeHostMessages.h" +#include "UpdateInfo.h" +#include "WebCoreArgumentCoders.h" +#include "WebLayerTreeInfo.h" +#include "WebLayerTreeRenderer.h" +#include "WebPageProxy.h" +#include "WebProcessProxy.h" + +namespace WebKit { + +using namespace WebCore; + +LayerTreeHostProxy::LayerTreeHostProxy(DrawingAreaProxy* drawingAreaProxy) + : m_drawingAreaProxy(drawingAreaProxy) + , m_renderer(adoptRef(new WebLayerTreeRenderer(this))) +{ +} + +LayerTreeHostProxy::~LayerTreeHostProxy() +{ + m_renderer->detach(); +} + +void LayerTreeHostProxy::paintToCurrentGLContext(const WebCore::TransformationMatrix& matrix, float opacity, const WebCore::FloatRect& rect) +{ + m_renderer->syncRemoteContent(); + m_renderer->paintToCurrentGLContext(matrix, opacity, rect); +} + +void LayerTreeHostProxy::paintToGraphicsContext(BackingStore::PlatformGraphicsContext context) +{ + m_renderer->paintToGraphicsContext(context); +} + +void LayerTreeHostProxy::updateViewport() +{ + m_drawingAreaProxy->updateViewport(); +} + +void LayerTreeHostProxy::dispatchUpdate(const Function<void()>& function) +{ + m_renderer->appendUpdate(function); + updateViewport(); +} + +void LayerTreeHostProxy::createTileForLayer(int layerID, int tileID, const WebKit::UpdateInfo& updateInfo) +{ + dispatchUpdate(bind(&WebLayerTreeRenderer::createTile, m_renderer.get(), layerID, tileID, updateInfo.updateScaleFactor)); + updateTileForLayer(layerID, tileID, updateInfo); +} + +void LayerTreeHostProxy::updateTileForLayer(int layerID, int tileID, const WebKit::UpdateInfo& updateInfo) +{ + ASSERT(updateInfo.updateRects.size() == 1); + IntRect sourceRect = updateInfo.updateRects.first(); + IntRect targetRect = updateInfo.updateRectBounds; + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(updateInfo.bitmapHandle); + dispatchUpdate(bind(&WebLayerTreeRenderer::updateTile, m_renderer.get(), layerID, tileID, sourceRect, targetRect, bitmap)); +} + +void LayerTreeHostProxy::removeTileForLayer(int layerID, int tileID) +{ + dispatchUpdate(bind(&WebLayerTreeRenderer::removeTile, m_renderer.get(), layerID, tileID)); +} + +void LayerTreeHostProxy::deleteCompositingLayer(WebLayerID id) +{ + dispatchUpdate(bind(&WebLayerTreeRenderer::deleteLayer, m_renderer.get(), id)); +} + +void LayerTreeHostProxy::setRootCompositingLayer(WebLayerID id) +{ + dispatchUpdate(bind(&WebLayerTreeRenderer::setRootLayerID, m_renderer.get(), id)); +} + +void LayerTreeHostProxy::syncCompositingLayerState(const WebLayerInfo& info) +{ + dispatchUpdate(bind(&WebLayerTreeRenderer::syncLayerParameters, m_renderer.get(), info)); +} + +void LayerTreeHostProxy::didRenderFrame() +{ + dispatchUpdate(bind(&WebLayerTreeRenderer::flushLayerChanges, m_renderer.get())); +} + +void LayerTreeHostProxy::createDirectlyCompositedImage(int64_t key, const WebKit::ShareableBitmap::Handle& handle) +{ + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle); + dispatchUpdate(bind(&WebLayerTreeRenderer::createImage, m_renderer.get(), key, bitmap)); +} + +void LayerTreeHostProxy::destroyDirectlyCompositedImage(int64_t key) +{ + dispatchUpdate(bind(&WebLayerTreeRenderer::destroyImage, m_renderer.get(), key)); +} + +void LayerTreeHostProxy::setVisibleContentsRectForPanning(const IntRect& rect, const FloatPoint& trajectoryVector) +{ + m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::SetVisibleContentsRectForPanning(rect, trajectoryVector), m_drawingAreaProxy->page()->pageID()); +} + +void LayerTreeHostProxy::setVisibleContentsRectForScaling(const IntRect& rect, float scale) +{ + m_renderer->setVisibleContentsRectForScaling(rect, scale); + m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::SetVisibleContentsRectForScaling(rect, scale), m_drawingAreaProxy->page()->pageID()); +} + +void LayerTreeHostProxy::renderNextFrame() +{ + m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::RenderNextFrame(), m_drawingAreaProxy->page()->pageID()); +} + +void LayerTreeHostProxy::purgeBackingStores() +{ + m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::PurgeBackingStores(), m_drawingAreaProxy->page()->pageID()); +} + +} +#endif // USE(UI_SIDE_COMPOSITING) diff --git a/Source/WebKit2/UIProcess/LayerTreeHostProxy.h b/Source/WebKit2/UIProcess/LayerTreeHostProxy.h index 504c4e19e..f6c31d1bc 100644 --- a/Source/WebKit2/UIProcess/LayerTreeHostProxy.h +++ b/Source/WebKit2/UIProcess/LayerTreeHostProxy.h @@ -20,9 +20,10 @@ #ifndef LayerTreeHostProxy_h #define LayerTreeHostProxy_h +#if USE(UI_SIDE_COMPOSITING) + #include "BackingStore.h" #include "DrawingAreaProxy.h" -#include "MessageQueue.h" #include "Region.h" #include "WebLayerTreeInfo.h" #include <WebCore/GraphicsContext.h> @@ -31,22 +32,18 @@ #include <WebCore/IntSize.h> #include <WebCore/RunLoop.h> #include <WebCore/Timer.h> +#include <wtf/Functional.h> #include <wtf/HashSet.h> -#if USE(TEXTURE_MAPPER) -#include "TextureMapper.h" -#include "TextureMapperBackingStore.h" -#endif +class QSGNode; namespace WebKit { -class LayerBackingStore; class WebLayerInfo; +class WebLayerTreeRenderer; class WebLayerUpdateInfo; -class LayerTreeMessageToRenderer; - -class LayerTreeHostProxy : public WebCore::GraphicsLayerClient { +class LayerTreeHostProxy { public: LayerTreeHostProxy(DrawingAreaProxy*); virtual ~LayerTreeHostProxy(); @@ -54,14 +51,11 @@ public: void deleteCompositingLayer(WebLayerID); void setRootCompositingLayer(WebLayerID); void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); - void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float, const WebCore::FloatRect&); + void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float opacity, const WebCore::FloatRect& clip); void paintToGraphicsContext(BackingStore::PlatformGraphicsContext); void purgeGLResources(); void setVisibleContentsRectForScaling(const WebCore::IntRect&, float); void setVisibleContentsRectForPanning(const WebCore::IntRect&, const WebCore::FloatPoint&); -#if USE(TILED_BACKING_STORE) - void syncRemoteContent(); - void swapContentBuffers(); void didRenderFrame(); void createTileForLayer(int layerID, int tileID, const WebKit::UpdateInfo&); void updateTileForLayer(int layerID, int tileID, const WebKit::UpdateInfo&); @@ -70,64 +64,19 @@ public: void destroyDirectlyCompositedImage(int64_t); void didReceiveLayerTreeHostProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); void updateViewport(); -#endif + void renderNextFrame(); + void purgeBackingStores(); + WebLayerTreeRenderer* layerTreeRenderer() const { return m_renderer.get(); } protected: - PassOwnPtr<WebCore::GraphicsLayer> createLayer(WebLayerID); - - WebCore::GraphicsLayer* layerByID(WebLayerID id) { return (id == InvalidWebLayerID) ? 0 : m_layers.get(id); } - WebCore::GraphicsLayer* rootLayer() { return m_rootLayer.get(); } - - // Reimplementations from WebCore::GraphicsLayerClient. - virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double) { } - virtual void notifySyncRequired(const WebCore::GraphicsLayer*) { } - virtual bool showDebugBorders(const WebCore::GraphicsLayer*) const { return false; } - virtual bool showRepaintCounter(const WebCore::GraphicsLayer*) const { return false; } - void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect&) { } + void dispatchUpdate(const Function<void()>&); DrawingAreaProxy* m_drawingAreaProxy; - - typedef HashMap<WebLayerID, WebCore::GraphicsLayer*> LayerMap; - WebCore::IntRect m_visibleContentsRect; - float m_contentsScale; - - MessageQueue<LayerTreeMessageToRenderer> m_messagesToRenderer; - void pushUpdateToQueue(PassOwnPtr<LayerTreeMessageToRenderer>); - -#if USE(TEXTURE_MAPPER) - OwnPtr<WebCore::TextureMapper> m_textureMapper; -#endif - -#if PLATFORM(QT) - void scheduleWebViewUpdate(); - void synchronizeViewport(); - void deleteLayer(WebLayerID); - void setRootLayerID(WebLayerID); - void syncLayerParameters(const WebLayerInfo&); - void createTile(WebLayerID, int, float scale); - void removeTile(WebLayerID, int); - void updateTile(WebLayerID, int, const WebCore::IntRect&, const WebCore::IntRect&, ShareableBitmap*); - void createImage(int64_t, ShareableBitmap*); - void destroyImage(int64_t); - void assignImageToLayer(WebCore::GraphicsLayer*, int64_t imageID); - void flushLayerChanges(); - void ensureRootLayer(); - void ensureLayer(WebLayerID); - PassRefPtr<LayerBackingStore> getBackingStore(WebLayerID); - void swapBuffers(); - void syncAnimations(); -#endif - - OwnPtr<WebCore::GraphicsLayer> m_rootLayer; - Vector<WebLayerID> m_layersToDelete; - HashMap<int64_t, RefPtr<WebCore::TextureMapperBackingStore> > m_directlyCompositedImages; - HashSet<RefPtr<LayerBackingStore> > m_backingStoresWithPendingBuffers; - - LayerMap m_layers; - WebLayerID m_rootLayerID; - int m_id; + RefPtr<WebLayerTreeRenderer> m_renderer; }; } +#endif + #endif // LayerTreeHostProxy_h diff --git a/Source/WebKit2/UIProcess/Notifications/WebNotification.cpp b/Source/WebKit2/UIProcess/Notifications/WebNotification.cpp index d6b209286..99ba0ede1 100644 --- a/Source/WebKit2/UIProcess/Notifications/WebNotification.cpp +++ b/Source/WebKit2/UIProcess/Notifications/WebNotification.cpp @@ -33,10 +33,11 @@ namespace WebKit { -WebNotification::WebNotification(const String& title, const String& body, const String& iconURL, const String& originString, uint64_t notificationID) +WebNotification::WebNotification(const String& title, const String& body, const String& iconURL, const String& replaceID, const String& originString, uint64_t notificationID) : m_title(title) , m_body(body) , m_iconURL(iconURL) + , m_replaceID(replaceID) , m_origin(WebSecurityOrigin::createFromString(originString)) , m_notificationID(notificationID) { diff --git a/Source/WebKit2/UIProcess/Notifications/WebNotification.h b/Source/WebKit2/UIProcess/Notifications/WebNotification.h index 4a6fc7e49..19bda4050 100644 --- a/Source/WebKit2/UIProcess/Notifications/WebNotification.h +++ b/Source/WebKit2/UIProcess/Notifications/WebNotification.h @@ -45,26 +45,28 @@ class WebNotification : public APIObject { public: static const Type APIType = TypeNotification; - static PassRefPtr<WebNotification> create(const String& title, const String& body, const String& iconURL, const String& originString, uint64_t notificationID) + static PassRefPtr<WebNotification> create(const String& title, const String& body, const String& iconURL, const String& replaceID, const String& originString, uint64_t notificationID) { - return adoptRef(new WebNotification(title, body, iconURL, originString, notificationID)); + return adoptRef(new WebNotification(title, body, iconURL, replaceID, originString, notificationID)); } const String& title() const { return m_title; } const String& body() const { return m_body; } const String& iconURL() const { return m_iconURL; } + const String& replaceID() const { return m_replaceID; } WebSecurityOrigin* origin() const { return m_origin.get(); } uint64_t notificationID() const { return m_notificationID; } private: - WebNotification(const String& title, const String& body, const String& iconURL, const String& originString, uint64_t notificationID); + WebNotification(const String& title, const String& body, const String& iconURL, const String& replaceID, const String& originString, uint64_t notificationID); virtual Type type() const { return APIType; } String m_title; String m_body; String m_iconURL; + String m_replaceID; RefPtr<WebSecurityOrigin> m_origin; uint64_t m_notificationID; }; diff --git a/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.cpp b/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.cpp index 0c0850bee..27a889e26 100644 --- a/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.cpp +++ b/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.cpp @@ -77,12 +77,12 @@ void WebNotificationManagerProxy::didReceiveMessage(CoreIPC::Connection* connect didReceiveWebNotificationManagerProxyMessage(connection, messageID, arguments); } -void WebNotificationManagerProxy::show(WebPageProxy* page, const String& title, const String& body, const String& iconURL, const String& originString, uint64_t notificationID) +void WebNotificationManagerProxy::show(WebPageProxy* page, const String& title, const String& body, const String& iconURL, const String& replaceID, const String& originString, uint64_t notificationID) { if (!isNotificationIDValid(notificationID)) return; - RefPtr<WebNotification> notification = WebNotification::create(title, body, iconURL, originString, notificationID); + RefPtr<WebNotification> notification = WebNotification::create(title, body, iconURL, replaceID, originString, notificationID); m_notifications.set(notificationID, notification); m_provider.show(page, notification.get()); } diff --git a/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.h b/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.h index d62b9f28f..edfccc179 100644 --- a/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.h +++ b/Source/WebKit2/UIProcess/Notifications/WebNotificationManagerProxy.h @@ -29,7 +29,7 @@ #include "APIObject.h" #include "MessageID.h" #include "WebNotificationProvider.h" -#include <WebCore/NotificationPresenter.h> +#include <WebCore/NotificationClient.h> #include <wtf/HashMap.h> #include <wtf/OwnPtr.h> #include <wtf/PassRefPtr.h> @@ -60,7 +60,7 @@ public: void initializeProvider(const WKNotificationProvider*); void populateCopyOfNotificationPermissions(HashMap<String, bool>&); - void show(WebPageProxy*, const String& title, const String& body, const String& iconURL, const String& originString, uint64_t notificationID); + void show(WebPageProxy*, const String& title, const String& body, const String& iconURL, const String& replaceID, const String& originString, uint64_t notificationID); void providerDidShowNotification(uint64_t notificationID); void providerDidClickNotification(uint64_t notificationID); diff --git a/Source/WebKit2/UIProcess/PageClient.h b/Source/WebKit2/UIProcess/PageClient.h index 70ddf07fa..f06d8271f 100644 --- a/Source/WebKit2/UIProcess/PageClient.h +++ b/Source/WebKit2/UIProcess/PageClient.h @@ -93,7 +93,10 @@ public: // Return whether the view is in a window. virtual bool isViewInWindow() = 0; - + + // Return the layer hosting mode for the view. + virtual LayerHostingMode viewLayerHostingMode() { return LayerHostingModeDefault; } + virtual void processDidCrash() = 0; virtual void didRelaunchProcess() = 0; virtual void pageClosed() = 0; @@ -165,6 +168,7 @@ public: #if USE(ACCELERATED_COMPOSITING) virtual void enterAcceleratedCompositingMode(const LayerTreeContext&) = 0; virtual void exitAcceleratedCompositingMode() = 0; + virtual void updateAcceleratedCompositingMode(const LayerTreeContext&) = 0; #endif #if PLATFORM(WIN) diff --git a/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessProxyMac.mm b/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessProxyMac.mm index b072417fe..4e539beaa 100644 --- a/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessProxyMac.mm +++ b/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessProxyMac.mm @@ -35,6 +35,10 @@ #import <spawn.h> #import <wtf/text/CString.h> +#if !defined(BUILDING_ON_SNOW_LEOPARD) +#import <QuartzCore/CARemoteLayerServer.h> +#endif + @interface WKPlaceholderModalWindow : NSWindow @end @@ -116,7 +120,12 @@ void PluginProcessProxy::platformInitializePluginProcess(PluginProcessCreationPa { #if USE(ACCELERATED_COMPOSITING) && HAVE(HOSTED_CORE_ANIMATION) parameters.parentProcessName = [[NSProcessInfo processInfo] processName]; +#if !defined(BUILDING_ON_SNOW_LEOPARD) + mach_port_t renderServerPort = [[CARemoteLayerServer sharedServer] serverPort]; +#else mach_port_t renderServerPort = WKInitializeRenderServer(); +#endif + if (renderServerPort != MACH_PORT_NULL) parameters.acceleratedCompositingPort = CoreIPC::MachPort(renderServerPort, MACH_MSG_TYPE_COPY_SEND); #endif diff --git a/Source/WebKit2/UIProcess/WebContext.h b/Source/WebKit2/UIProcess/WebContext.h index 21f219149..c378725dc 100644 --- a/Source/WebKit2/UIProcess/WebContext.h +++ b/Source/WebKit2/UIProcess/WebContext.h @@ -224,7 +224,22 @@ private: void didGetSitesWithPluginData(const Vector<String>& sites, uint64_t callbackID); void didClearPluginSiteData(uint64_t callbackID); #endif - + +#if PLATFORM(MAC) + void getPasteboardTypes(const String& pasteboardName, Vector<String>& pasteboardTypes); + void getPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, Vector<String>& pathnames); + void getPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, String&); + void getPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, SharedMemory::Handle&, uint64_t& size); + void pasteboardCopy(const String& fromPasteboard, const String& toPasteboard); + void getPasteboardChangeCount(const String& pasteboardName, uint64_t& changeCount); + void getPasteboardUniqueName(String& pasteboardName); + void getPasteboardColor(const String& pasteboardName, WebCore::Color&); + void setPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes); + void setPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, const Vector<String>& pathnames); + void setPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, const String&); + void setPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, const SharedMemory::Handle&, uint64_t size); +#endif + void didGetWebCoreStatistics(const StatisticsData&, uint64_t callbackID); // Implemented in generated WebContextMessageReceiver.cpp diff --git a/Source/WebKit2/UIProcess/WebContext.messages.in b/Source/WebKit2/UIProcess/WebContext.messages.in index 954894f1e..4bc3ec7d4 100644 --- a/Source/WebKit2/UIProcess/WebContext.messages.in +++ b/Source/WebKit2/UIProcess/WebContext.messages.in @@ -42,4 +42,20 @@ messages -> WebContext { DidGetWebCoreStatistics(WebKit::StatisticsData statisticsData, uint64_t callbackID) +#if PLATFORM(MAC) + # Pasteboard messages. + + GetPasteboardTypes(WTF::String pasteboardName) -> (Vector<WTF::String> types) + GetPasteboardPathnamesForType(WTF::String pasteboardName, WTF::String pasteboardType) -> (Vector<WTF::String> pathnames) + GetPasteboardStringForType(WTF::String pasteboardName, WTF::String pasteboardType) -> (WTF::String string) + GetPasteboardBufferForType(WTF::String pasteboardName, WTF::String pasteboardType) -> (WebKit::SharedMemory::Handle handle, uint64_t size) + PasteboardCopy(WTF::String fromPasteboard, WTF::String toPasteboard) + GetPasteboardChangeCount(WTF::String pasteboardName) -> (uint64_t changeCount) + GetPasteboardUniqueName() -> (WTF::String pasteboardName) + GetPasteboardColor(WTF::String pasteboardName) -> (WebCore::Color color) + SetPasteboardTypes(WTF::String pasteboardName, Vector<WTF::String> pasteboardTypes) + SetPasteboardPathnamesForType(WTF::String pasteboardName, WTF::String pasteboardType, Vector<WTF::String> pathnames) + SetPasteboardStringForType(WTF::String pasteboardName, WTF::String pasteboardType, WTF::String string) + SetPasteboardBufferForType(WTF::String pasteboardName, WTF::String pasteboardType, WebKit::SharedMemory::Handle handle, uint64_t size) +#endif } diff --git a/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.cpp b/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.cpp index 729b62e9d..17c070b6d 100644 --- a/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.cpp +++ b/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.cpp @@ -84,19 +84,9 @@ void WebFullScreenManagerProxy::didExitFullScreen() m_page->process()->send(Messages::WebFullScreenManager::DidExitFullScreen(), m_page->pageID()); } -void WebFullScreenManagerProxy::beginEnterFullScreenAnimation(float duration) +void WebFullScreenManagerProxy::setAnimatingFullScreen(bool animating) { - m_page->process()->send(Messages::WebFullScreenManager::BeginEnterFullScreenAnimation(duration), m_page->pageID()); -} - -void WebFullScreenManagerProxy::beginExitFullScreenAnimation(float duration) -{ - m_page->process()->send(Messages::WebFullScreenManager::BeginExitFullScreenAnimation(duration), m_page->pageID()); -} - -void WebFullScreenManagerProxy::disposeOfLayerClient() -{ - m_page->process()->send(Messages::WebFullScreenManager::DisposeOfLayerClient(), m_page->pageID()); + m_page->process()->send(Messages::WebFullScreenManager::SetAnimatingFullScreen(animating), m_page->pageID()); } void WebFullScreenManagerProxy::supportsFullScreen(bool withKeyboard, bool& supports) diff --git a/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.h b/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.h index 1a1c94c93..c947f1652 100644 --- a/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.h +++ b/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.h @@ -80,9 +80,7 @@ public: void didEnterFullScreen(); void willExitFullScreen(); void didExitFullScreen(); - void beginEnterFullScreenAnimation(float duration); - void beginExitFullScreenAnimation(float duration); - void disposeOfLayerClient(); + void setAnimatingFullScreen(bool); private: WebFullScreenManagerProxy(WebPageProxy*); @@ -90,13 +88,8 @@ private: void supportsFullScreen(bool withKeyboard, bool&); void enterFullScreen(); void exitFullScreen(); - void beganEnterFullScreenAnimation(); - void finishedEnterFullScreenAnimation(bool completed); - void beganExitFullScreenAnimation(); - void finishedExitFullScreenAnimation(bool completed); - void enterAcceleratedCompositingMode(const LayerTreeContext&); - void exitAcceleratedCompositingMode(); - void getFullScreenRect(WebCore::IntRect&); + void beganEnterFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame); + void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame); WebPageProxy* m_page; PlatformWebView* m_webView; diff --git a/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.messages.in b/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.messages.in index 007e30916..c52cea92e 100644 --- a/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.messages.in +++ b/Source/WebKit2/UIProcess/WebFullScreenManagerProxy.messages.in @@ -25,14 +25,7 @@ messages -> WebFullScreenManagerProxy { SupportsFullScreen(bool withKeyboard) -> (bool supportsFullScreen) EnterFullScreen() ExitFullScreen() - BeganEnterFullScreenAnimation() - FinishedEnterFullScreenAnimation(bool completed) - BeganExitFullScreenAnimation() - FinishedExitFullScreenAnimation(bool completed) - GetFullScreenRect() -> (WebCore::IntRect rect) -#if USE(ACCELERATED_COMPOSITING) - EnterAcceleratedCompositingMode(WebKit::LayerTreeContext context) - ExitAcceleratedCompositingMode() -#endif + BeganEnterFullScreen(WebCore::IntRect initialRect, WebCore::IntRect finalRect) + BeganExitFullScreen(WebCore::IntRect initialRect, WebCore::IntRect finalRect) } #endif diff --git a/Source/WebKit2/UIProcess/WebInspectorProxy.cpp b/Source/WebKit2/UIProcess/WebInspectorProxy.cpp index 6da04a9cb..6bf7a6bd9 100644 --- a/Source/WebKit2/UIProcess/WebInspectorProxy.cpp +++ b/Source/WebKit2/UIProcess/WebInspectorProxy.cpp @@ -100,6 +100,14 @@ void WebInspectorProxy::invalidate() } // Public APIs +bool WebInspectorProxy::isFront() +{ + if (!m_page) + return false; + + return platformIsFront(); +} + void WebInspectorProxy::show() { if (!m_page) diff --git a/Source/WebKit2/UIProcess/WebInspectorProxy.h b/Source/WebKit2/UIProcess/WebInspectorProxy.h index aebb6f9b9..884b66621 100644 --- a/Source/WebKit2/UIProcess/WebInspectorProxy.h +++ b/Source/WebKit2/UIProcess/WebInspectorProxy.h @@ -80,6 +80,8 @@ public: WebPageProxy* page() const { return m_page; } bool isVisible() const { return m_isVisible; } + bool isFront(); + void show(); void close(); @@ -126,6 +128,7 @@ private: void platformOpen(); void platformDidClose(); void platformBringToFront(); + bool platformIsFront(); void platformInspectedURLChanged(const String&); unsigned platformInspectedWindowHeight(); void platformAttach(); diff --git a/Source/WebKit2/UIProcess/WebLayerTreeRenderer.cpp b/Source/WebKit2/UIProcess/WebLayerTreeRenderer.cpp new file mode 100644 index 000000000..f2c049592 --- /dev/null +++ b/Source/WebKit2/UIProcess/WebLayerTreeRenderer.cpp @@ -0,0 +1,410 @@ +/* + Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#if USE(UI_SIDE_COMPOSITING) + +#include "WebLayerTreeRenderer.h" + +#include "GraphicsLayerTextureMapper.h" +#include "LayerBackingStore.h" +#include "LayerTreeHostProxy.h" +#include "MainThread.h" +#include "MessageID.h" +#include "ShareableBitmap.h" +#include "TextureMapper.h" +#include "TextureMapperBackingStore.h" +#include "TextureMapperLayer.h" +#include "UpdateInfo.h" +#include <OpenGLShims.h> +#include <wtf/Atomics.h> + +namespace WebKit { + +using namespace WebCore; + +template<class T> class MainThreadGuardedInvoker { +public: + static void call(PassRefPtr<T> objectToGuard, const Function<void()>& function) + { + MainThreadGuardedInvoker<T>* invoker = new MainThreadGuardedInvoker<T>(objectToGuard, function); + callOnMainThread(invoke, invoker); + } + +private: + MainThreadGuardedInvoker(PassRefPtr<T> object, const Function<void()>& newFunction) + : objectToGuard(object) + , function(newFunction) + { + } + + RefPtr<T> objectToGuard; + Function<void()> function; + static void invoke(void* data) + { + MainThreadGuardedInvoker<T>* invoker = static_cast<MainThreadGuardedInvoker<T>*>(data); + invoker->function(); + delete invoker; + } +}; + +void WebLayerTreeRenderer::callOnMainTread(const Function<void()>& function) +{ + if (isMainThread()) + function(); + else + MainThreadGuardedInvoker<WebLayerTreeRenderer>::call(this, function); +} + +WebLayerTreeRenderer::WebLayerTreeRenderer(LayerTreeHostProxy* layerTreeHostProxy) + : m_layerTreeHostProxy(layerTreeHostProxy) + , m_rootLayerID(0) +{ +} + +WebLayerTreeRenderer::~WebLayerTreeRenderer() +{ +} + +PassOwnPtr<GraphicsLayer> WebLayerTreeRenderer::createLayer(WebLayerID layerID) +{ + GraphicsLayer* newLayer = new GraphicsLayerTextureMapper(this); + TextureMapperLayer* layer = toTextureMapperLayer(newLayer); + layer->setShouldUpdateBackingStoreFromLayer(false); + return adoptPtr(newLayer); +} + +void WebLayerTreeRenderer::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect) +{ + if (!m_textureMapper) + m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode); + ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode); + + syncRemoteContent(); + GraphicsLayer* currentRootLayer = rootLayer(); + if (!currentRootLayer) + return; + + TextureMapperLayer* layer = toTextureMapperLayer(currentRootLayer); + + if (!layer) + return; + + layer->setTextureMapper(m_textureMapper.get()); + m_textureMapper->beginPainting(); + m_textureMapper->bindSurface(0); + m_textureMapper->beginClip(TransformationMatrix(), clipRect); + + if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) { + currentRootLayer->setOpacity(opacity); + currentRootLayer->setTransform(matrix); + currentRootLayer->syncCompositingStateForThisLayerOnly(); + } + + layer->paint(); + m_textureMapper->endClip(); + m_textureMapper->endPainting(); + + syncAnimations(); +} + +void WebLayerTreeRenderer::syncAnimations() +{ + TextureMapperLayer* layer = toTextureMapperLayer(rootLayer()); + ASSERT(layer); + + layer->syncAnimationsRecursively(); + if (layer->descendantsOrSelfHaveRunningAnimations()) + callOnMainThread(bind(&WebLayerTreeRenderer::updateViewport, this)); +} + +void WebLayerTreeRenderer::paintToGraphicsContext(QPainter* painter) +{ + if (!m_textureMapper) + m_textureMapper = TextureMapper::create(); + ASSERT(m_textureMapper->accelerationMode() == TextureMapper::SoftwareMode); + syncRemoteContent(); + TextureMapperLayer* layer = toTextureMapperLayer(rootLayer()); + + if (!layer) + return; + + GraphicsContext graphicsContext(painter); + m_textureMapper->setGraphicsContext(&graphicsContext); + m_textureMapper->beginPainting(); + m_textureMapper->bindSurface(0); + layer->paint(); + m_textureMapper->endPainting(); + m_textureMapper->setGraphicsContext(0); +} + +void WebLayerTreeRenderer::setVisibleContentsRectForScaling(const IntRect& rect, float scale) +{ + m_visibleContentsRect = rect; + m_contentsScale = scale; +} + +void WebLayerTreeRenderer::updateViewport() +{ + if (m_layerTreeHostProxy) + m_layerTreeHostProxy->updateViewport(); +} + +void WebLayerTreeRenderer::syncLayerParameters(const WebLayerInfo& layerInfo) +{ + WebLayerID id = layerInfo.id; + ensureLayer(id); + LayerMap::iterator it = m_layers.find(id); + GraphicsLayer* layer = it->second; + bool needsToUpdateImageTiles = layerInfo.imageIsUpdated || (layerInfo.contentsRect != layer->contentsRect() && layerInfo.imageBackingStoreID); + + layer->setName(layerInfo.name); + + layer->setReplicatedByLayer(layerByID(layerInfo.replica)); + layer->setMaskLayer(layerByID(layerInfo.mask)); + + layer->setPosition(layerInfo.pos); + layer->setSize(layerInfo.size); + layer->setTransform(layerInfo.transform); + layer->setAnchorPoint(layerInfo.anchorPoint); + layer->setChildrenTransform(layerInfo.childrenTransform); + layer->setBackfaceVisibility(layerInfo.backfaceVisible); + layer->setContentsOpaque(layerInfo.contentsOpaque); + layer->setContentsRect(layerInfo.contentsRect); + layer->setDrawsContent(layerInfo.drawsContent); + + if (needsToUpdateImageTiles) + assignImageToLayer(layer, layerInfo.imageBackingStoreID); + + // Never make the root layer clip. + layer->setMasksToBounds(layerInfo.isRootLayer ? false : layerInfo.masksToBounds); + layer->setOpacity(layerInfo.opacity); + layer->setPreserves3D(layerInfo.preserves3D); + Vector<GraphicsLayer*> children; + + for (size_t i = 0; i < layerInfo.children.size(); ++i) { + WebLayerID childID = layerInfo.children[i]; + GraphicsLayer* child = layerByID(childID); + if (!child) { + child = createLayer(childID).leakPtr(); + m_layers.add(childID, child); + } + children.append(child); + } + layer->setChildren(children); + + for (size_t i = 0; i < layerInfo.animations.size(); ++i) { + const WebKit::WebLayerAnimation anim = layerInfo.animations[i]; + + switch (anim.operation) { + case WebKit::WebLayerAnimation::AddAnimation: { + const IntSize boxSize = anim.boxSize; + layer->addAnimation(anim.keyframeList, boxSize, anim.animation.get(), anim.name, anim.startTime); + break; + } + case WebKit::WebLayerAnimation::RemoveAnimation: + layer->removeAnimation(anim.name); + break; + case WebKit::WebLayerAnimation::PauseAnimation: + double offset = WTF::currentTime() - anim.startTime; + layer->pauseAnimation(anim.name, offset); + break; + } + } + + if (layerInfo.isRootLayer && m_rootLayerID != id) + setRootLayerID(id); +} + +void WebLayerTreeRenderer::deleteLayer(WebLayerID layerID) +{ + GraphicsLayer* layer = layerByID(layerID); + if (!layer) + return; + + layer->removeFromParent(); + m_layers.remove(layerID); + delete layer; +} + + +void WebLayerTreeRenderer::ensureLayer(WebLayerID id) +{ + // We have to leak the new layer's pointer and manage it ourselves, + // because OwnPtr is not copyable. + if (m_layers.find(id) == m_layers.end()) + m_layers.add(id, createLayer(id).leakPtr()); +} + +void WebLayerTreeRenderer::setRootLayerID(WebLayerID layerID) +{ + if (layerID == m_rootLayerID) + return; + + m_rootLayerID = layerID; + + m_rootLayer->removeAllChildren(); + + if (!layerID) + return; + + GraphicsLayer* layer = layerByID(layerID); + if (!layer) + return; + + m_rootLayer->addChild(layer); +} + +PassRefPtr<LayerBackingStore> WebLayerTreeRenderer::getBackingStore(WebLayerID id) +{ + ensureLayer(id); + TextureMapperLayer* layer = toTextureMapperLayer(layerByID(id)); + RefPtr<LayerBackingStore> backingStore = static_cast<LayerBackingStore*>(layer->backingStore().get()); + if (!backingStore) { + backingStore = LayerBackingStore::create(); + layer->setBackingStore(backingStore.get()); + } + ASSERT(backingStore); + return backingStore; +} + +void WebLayerTreeRenderer::createTile(WebLayerID layerID, int tileID, float scale) +{ + getBackingStore(layerID)->createTile(tileID, scale); +} + +void WebLayerTreeRenderer::removeTile(WebLayerID layerID, int tileID) +{ + getBackingStore(layerID)->removeTile(tileID); +} + +void WebLayerTreeRenderer::updateTile(WebLayerID layerID, int tileID, const IntRect& sourceRect, const IntRect& targetRect, PassRefPtr<ShareableBitmap> weakBitmap) +{ + RefPtr<ShareableBitmap> bitmap = weakBitmap; + RefPtr<LayerBackingStore> backingStore = getBackingStore(layerID); + backingStore->updateTile(tileID, sourceRect, targetRect, bitmap.get()); + m_backingStoresWithPendingBuffers.add(backingStore); +} + +void WebLayerTreeRenderer::createImage(int64_t imageID, PassRefPtr<ShareableBitmap> weakBitmap) +{ + RefPtr<ShareableBitmap> bitmap = weakBitmap; + RefPtr<TextureMapperTiledBackingStore> backingStore = TextureMapperTiledBackingStore::create(); + backingStore->updateContents(m_textureMapper.get(), bitmap->createImage().get(), BitmapTexture::BGRAFormat); + m_directlyCompositedImages.set(imageID, backingStore); +} + +void WebLayerTreeRenderer::destroyImage(int64_t imageID) +{ + m_directlyCompositedImages.remove(imageID); +} + +void WebLayerTreeRenderer::assignImageToLayer(GraphicsLayer* layer, int64_t imageID) +{ + HashMap<int64_t, RefPtr<TextureMapperBackingStore> >::iterator it = m_directlyCompositedImages.find(imageID); + ASSERT(it != m_directlyCompositedImages.end()); + layer->setContentsToMedia(it->second.get()); +} + +void WebLayerTreeRenderer::swapBuffers() +{ + HashSet<RefPtr<LayerBackingStore> >::iterator end = m_backingStoresWithPendingBuffers.end(); + for (HashSet<RefPtr<LayerBackingStore> >::iterator it = m_backingStoresWithPendingBuffers.begin(); it != end; ++it) + (*it)->swapBuffers(m_textureMapper.get()); + + m_backingStoresWithPendingBuffers.clear(); +} + +void WebLayerTreeRenderer::flushLayerChanges() +{ + m_rootLayer->syncCompositingState(FloatRect()); + swapBuffers(); + + // The pending tiles state is on its way for the screen, tell the web process to render the next one. + callOnMainThread(bind(&WebLayerTreeRenderer::renderNextFrame, this)); +} + +void WebLayerTreeRenderer::renderNextFrame() +{ + if (m_layerTreeHostProxy) + m_layerTreeHostProxy->renderNextFrame(); +} + +void WebLayerTreeRenderer::ensureRootLayer() +{ + if (m_rootLayer) + return; + if (!m_textureMapper) + m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode); + + m_rootLayer = createLayer(InvalidWebLayerID); + m_rootLayer->setMasksToBounds(false); + m_rootLayer->setDrawsContent(false); + m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0)); + + // The root layer should not have zero size, or it would be optimized out. + m_rootLayer->setSize(FloatSize(1.0, 1.0)); + toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get()); +} + +void WebLayerTreeRenderer::syncRemoteContent() +{ + // We enqueue messages and execute them during paint, as they require an active GL context. + ensureRootLayer(); + + for (size_t i = 0; i < m_renderQueue.size(); ++i) + m_renderQueue[i](); + + m_renderQueue.clear(); +} + +void WebLayerTreeRenderer::purgeGLResources() +{ + TextureMapperLayer* layer = toTextureMapperLayer(rootLayer()); + + if (layer) + layer->clearBackingStoresRecursive(); + + m_directlyCompositedImages.clear(); + m_textureMapper.clear(); + m_backingStoresWithPendingBuffers.clear(); + + callOnMainThread(bind(&WebLayerTreeRenderer::purgeBackingStores, this)); +} + +void WebLayerTreeRenderer::purgeBackingStores() +{ + if (m_layerTreeHostProxy) + m_layerTreeHostProxy->purgeBackingStores(); +} + +void WebLayerTreeRenderer::detach() +{ + m_layerTreeHostProxy = 0; +} + +void WebLayerTreeRenderer::appendUpdate(const Function<void()>& function) +{ + m_renderQueue.append(function); +} + +} // namespace WebKit + +#endif // USE(UI_SIDE_COMPOSITING) diff --git a/Source/WebKit2/UIProcess/WebLayerTreeRenderer.h b/Source/WebKit2/UIProcess/WebLayerTreeRenderer.h new file mode 100644 index 000000000..6c788652a --- /dev/null +++ b/Source/WebKit2/UIProcess/WebLayerTreeRenderer.h @@ -0,0 +1,122 @@ +/* + Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef WebLayerTreeRenderer_h +#define WebLayerTreeRenderer_h + +#if USE(UI_SIDE_COMPOSITING) + +#include "BackingStore.h" +#include "TextureMapper.h" +#include "TextureMapperBackingStore.h" +#include "WebLayerTreeInfo.h" +#include <WebCore/GraphicsContext.h> +#include <WebCore/GraphicsLayer.h> +#include <WebCore/IntRect.h> +#include <WebCore/IntSize.h> +#include <WebCore/RunLoop.h> +#include <WebCore/Timer.h> +#include <wtf/Functional.h> +#include <wtf/HashSet.h> +#include <wtf/ThreadingPrimitives.h> + +namespace WebKit { + +class LayerBackingStore; +class LayerTreeHostProxy; +class WebLayerInfo; +class WebLayerUpdateInfo; + +class WebLayerTreeRenderer : public ThreadSafeRefCounted<WebLayerTreeRenderer>, public WebCore::GraphicsLayerClient { +public: + WebLayerTreeRenderer(LayerTreeHostProxy*); + virtual ~WebLayerTreeRenderer(); + void purgeGLResources(); + void paintToCurrentGLContext(const WebCore::TransformationMatrix&, float, const WebCore::FloatRect&); + void paintToGraphicsContext(BackingStore::PlatformGraphicsContext); + void syncRemoteContent(); + void setVisibleContentsRectForScaling(const WebCore::IntRect&, float); + + void detach(); + void appendUpdate(const Function<void()>&); + void updateViewport(); + + void deleteLayer(WebLayerID); + void setRootLayerID(WebLayerID); + void syncLayerParameters(const WebLayerInfo&); + void createTile(WebLayerID, int, float scale); + void removeTile(WebLayerID, int); + void updateTile(WebLayerID, int, const WebCore::IntRect&, const WebCore::IntRect&, PassRefPtr<ShareableBitmap>); + void flushLayerChanges(); + void createImage(int64_t, PassRefPtr<ShareableBitmap>); + void destroyImage(int64_t); + +private: + PassOwnPtr<WebCore::GraphicsLayer> createLayer(WebLayerID); + + WebCore::GraphicsLayer* layerByID(WebLayerID id) { return (id == InvalidWebLayerID) ? 0 : m_layers.get(id); } + WebCore::GraphicsLayer* rootLayer() { return m_rootLayer.get(); } + + // Reimplementations from WebCore::GraphicsLayerClient. + virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double) { } + virtual void notifySyncRequired(const WebCore::GraphicsLayer*) { } + virtual bool showDebugBorders(const WebCore::GraphicsLayer*) const { return false; } + virtual bool showRepaintCounter(const WebCore::GraphicsLayer*) const { return false; } + void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect&) { } + void callOnMainTread(const Function<void()>&); + + typedef HashMap<WebLayerID, WebCore::GraphicsLayer*> LayerMap; + WebCore::IntRect m_visibleContentsRect; + float m_contentsScale; + + // Render queue can be accessed ony from main thread or updatePaintNode call stack! + Vector<Function<void()> > m_renderQueue; + +#if USE(TEXTURE_MAPPER) + OwnPtr<WebCore::TextureMapper> m_textureMapper; + PassRefPtr<LayerBackingStore> getBackingStore(WebLayerID); + HashMap<int64_t, RefPtr<WebCore::TextureMapperBackingStore> > m_directlyCompositedImages; + HashSet<RefPtr<LayerBackingStore> > m_backingStoresWithPendingBuffers; +#endif + + void scheduleWebViewUpdate(); + void synchronizeViewport(); + void assignImageToLayer(WebCore::GraphicsLayer*, int64_t imageID); + void ensureRootLayer(); + void ensureLayer(WebLayerID); + void swapBuffers(); + void syncAnimations(); + void renderNextFrame(); + void purgeBackingStores(); + + LayerTreeHostProxy* m_layerTreeHostProxy; + OwnPtr<WebCore::GraphicsLayer> m_rootLayer; + Vector<WebLayerID> m_layersToDelete; + + LayerMap m_layers; + WebLayerID m_rootLayerID; +}; + +}; + +#endif // USE(UI_SIDE_COMPOSITING) + +#endif // WebLayerTreeRenderer_h + + diff --git a/Source/WebKit2/UIProcess/WebPageContextMenuClient.cpp b/Source/WebKit2/UIProcess/WebPageContextMenuClient.cpp index 897511cc5..3f7d0289f 100644 --- a/Source/WebKit2/UIProcess/WebPageContextMenuClient.cpp +++ b/Source/WebKit2/UIProcess/WebPageContextMenuClient.cpp @@ -34,11 +34,14 @@ namespace WebKit { -bool WebPageContextMenuClient::getContextMenuFromProposedMenu(WebPageProxy* page, const Vector<WebContextMenuItemData>& proposedMenuVector, Vector<WebContextMenuItemData>& customMenu, APIObject* userData) +bool WebPageContextMenuClient::getContextMenuFromProposedMenu(WebPageProxy* page, const Vector<WebContextMenuItemData>& proposedMenuVector, Vector<WebContextMenuItemData>& customMenu, const WebHitTestResult::Data& hitTestResultData, APIObject* userData) { - if (!m_client.getContextMenuFromProposedMenu) + if (!m_client.getContextMenuFromProposedMenu && !m_client.getContextMenuFromProposedMenu_deprecatedForUseWithV0) return false; - + + if (m_client.version == kWKPageContextMenuClientCurrentVersion && !m_client.getContextMenuFromProposedMenu) + return false; + unsigned size = proposedMenuVector.size(); RefPtr<MutableArray> proposedMenu = MutableArray::create(); proposedMenu->reserveCapacity(size); @@ -46,7 +49,12 @@ bool WebPageContextMenuClient::getContextMenuFromProposedMenu(WebPageProxy* page proposedMenu->append(WebContextMenuItem::create(proposedMenuVector[i]).get()); WKArrayRef newMenu = 0; - m_client.getContextMenuFromProposedMenu(toAPI(page), toAPI(proposedMenu.get()), &newMenu, toAPI(userData), m_client.clientInfo); + if (m_client.version == kWKPageContextMenuClientCurrentVersion) { + RefPtr<WebHitTestResult> webHitTestResult = WebHitTestResult::create(hitTestResultData); + m_client.getContextMenuFromProposedMenu(toAPI(page), toAPI(proposedMenu.get()), &newMenu, toAPI(webHitTestResult.get()), toAPI(userData), m_client.clientInfo); + } else + m_client.getContextMenuFromProposedMenu_deprecatedForUseWithV0(toAPI(page), toAPI(proposedMenu.get()), &newMenu, toAPI(userData), m_client.clientInfo); + RefPtr<ImmutableArray> array = adoptRef(toImpl(newMenu)); customMenu.clear(); diff --git a/Source/WebKit2/UIProcess/WebPageContextMenuClient.h b/Source/WebKit2/UIProcess/WebPageContextMenuClient.h index 5cbb335d9..9e738bba4 100644 --- a/Source/WebKit2/UIProcess/WebPageContextMenuClient.h +++ b/Source/WebKit2/UIProcess/WebPageContextMenuClient.h @@ -27,6 +27,7 @@ #define WebPageContextMenuClient_h #include "APIClient.h" +#include "WebHitTestResult.h" #include "WKPage.h" #include <wtf/Vector.h> @@ -38,7 +39,7 @@ class WebPageProxy; class WebPageContextMenuClient : public APIClient<WKPageContextMenuClient, kWKPageContextMenuClientCurrentVersion> { public: - bool getContextMenuFromProposedMenu(WebPageProxy*, const Vector<WebContextMenuItemData>& proposedMenu, Vector<WebContextMenuItemData>& customMenu, APIObject* userData); + bool getContextMenuFromProposedMenu(WebPageProxy*, const Vector<WebContextMenuItemData>& proposedMenu, Vector<WebContextMenuItemData>& customMenu, const WebHitTestResult::Data&, APIObject* userData); void customContextMenuItemSelected(WebPageProxy*, const WebContextMenuItemData&); void contextMenuDismissed(WebPageProxy*); }; diff --git a/Source/WebKit2/UIProcess/WebPageProxy.cpp b/Source/WebKit2/UIProcess/WebPageProxy.cpp index 8ea3fe4a1..40973449a 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.cpp +++ b/Source/WebKit2/UIProcess/WebPageProxy.cpp @@ -85,7 +85,7 @@ #include <WebCore/WindowFeatures.h> #include <stdio.h> -#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) +#if USE(UI_SIDE_COMPOSITING) #include "LayerTreeHostProxyMessages.h" #endif @@ -161,6 +161,7 @@ WebPageProxy::WebPageProxy(PageClient* pageClient, PassRefPtr<WebProcessProxy> p , m_pageScaleFactor(1) , m_intrinsicDeviceScaleFactor(1) , m_customDeviceScaleFactor(0) + , m_layerHostingMode(LayerHostingModeDefault) , m_drawsBackground(true) , m_drawsTransparentBackground(false) , m_areMemoryCacheClientCallsEnabled(true) @@ -186,6 +187,7 @@ WebPageProxy::WebPageProxy(PageClient* pageClient, PassRefPtr<WebProcessProxy> p , m_needTouchEvents(false) #endif , m_pageID(pageID) + , m_isPageSuspended(false) #if PLATFORM(MAC) , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled()) #endif @@ -372,7 +374,10 @@ void WebPageProxy::close() m_openPanelResultListener = 0; } +#if ENABLE(GEOLOCATION) m_geolocationPermissionRequestManager.invalidateRequests(); +#endif + m_notificationPermissionRequestManager.invalidateRequests(); m_toolTip = String(); @@ -759,6 +764,12 @@ void WebPageProxy::viewStateDidChange(ViewStateFlags flags) m_isInWindow = isInWindow; process()->send(Messages::WebPage::SetIsInWindow(isInWindow), m_pageID); } + + LayerHostingMode layerHostingMode = m_pageClient->viewLayerHostingMode(); + if (m_layerHostingMode != layerHostingMode) { + m_layerHostingMode = layerHostingMode; + m_drawingArea->layerHostingModeDidChange(); + } } updateBackingStoreDiscardableState(); @@ -999,7 +1010,10 @@ void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event) if (!isValid()) return; - if (m_needTouchEvents) { + // If the page is suspended, which should be the case during panning, pinching + // and animation on the page itself (kinetic scrolling, tap to zoom) etc, then + // we do not send any of the events to the page even if is has listeners. + if (m_needTouchEvents && !m_isPageSuspended) { m_touchEventQueue.append(event); process()->responsivenessTimer()->start(); if (m_shouldSendEventsSynchronously) { @@ -1126,6 +1140,26 @@ void WebPageProxy::setCustomUserAgent(const String& customUserAgent) setUserAgent(m_customUserAgent); } +void WebPageProxy::resumeActiveDOMObjectsAndAnimations() +{ + if (!isValid() || !m_isPageSuspended) + return; + + m_isPageSuspended = false; + + process()->send(Messages::WebPage::ResumeActiveDOMObjectsAndAnimations(), m_pageID); +} + +void WebPageProxy::suspendActiveDOMObjectsAndAnimations() +{ + if (!isValid() || m_isPageSuspended) + return; + + m_isPageSuspended = true; + + process()->send(Messages::WebPage::SuspendActiveDOMObjectsAndAnimations(), m_pageID); +} + bool WebPageProxy::supportsTextEncoding() const { return !m_mainFrameHasCustomRepresentation && m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument(); @@ -1542,7 +1576,7 @@ void WebPageProxy::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::M return; } -#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER) && USE(TILED_BACKING_STORE) +#if USE(UI_SIDE_COMPOSITING) if (messageID.is<CoreIPC::MessageClassLayerTreeHostProxy>()) { m_drawingArea->didReceiveLayerTreeHostProxyMessage(connection, messageID, arguments); return; @@ -2604,22 +2638,22 @@ void WebPageProxy::hidePopupMenu() m_activePopupMenu = 0; } -void WebPageProxy::showContextMenu(const IntPoint& menuLocation, const ContextMenuState& contextMenuState, const Vector<WebContextMenuItemData>& proposedItems, CoreIPC::ArgumentDecoder* arguments) +void WebPageProxy::showContextMenu(const IntPoint& menuLocation, const WebHitTestResult::Data& hitTestResultData, const Vector<WebContextMenuItemData>& proposedItems, CoreIPC::ArgumentDecoder* arguments) { - internalShowContextMenu(menuLocation, contextMenuState, proposedItems, arguments); + internalShowContextMenu(menuLocation, hitTestResultData, proposedItems, arguments); // No matter the result of internalShowContextMenu, always notify the WebProcess that the menu is hidden so it starts handling mouse events again. process()->send(Messages::WebPage::ContextMenuHidden(), m_pageID); } -void WebPageProxy::internalShowContextMenu(const IntPoint& menuLocation, const ContextMenuState& contextMenuState, const Vector<WebContextMenuItemData>& proposedItems, CoreIPC::ArgumentDecoder* arguments) +void WebPageProxy::internalShowContextMenu(const IntPoint& menuLocation, const WebHitTestResult::Data& hitTestResultData, const Vector<WebContextMenuItemData>& proposedItems, CoreIPC::ArgumentDecoder* arguments) { RefPtr<APIObject> userData; WebContextUserMessageDecoder messageDecoder(userData, m_process->context()); if (!arguments->decode(messageDecoder)) return; - m_activeContextMenuState = contextMenuState; + m_activeContextMenuHitTestResultData = hitTestResultData; if (m_activeContextMenu) { m_activeContextMenu->hideContextMenu(); @@ -2633,7 +2667,7 @@ void WebPageProxy::internalShowContextMenu(const IntPoint& menuLocation, const C // Give the PageContextMenuClient one last swipe at changing the menu. Vector<WebContextMenuItemData> items; - if (!m_contextMenuClient.getContextMenuFromProposedMenu(this, proposedItems, items, userData.get())) + if (!m_contextMenuClient.getContextMenuFromProposedMenu(this, proposedItems, items, hitTestResultData, userData.get())) m_activeContextMenu->showContextMenu(menuLocation, proposedItems); else m_activeContextMenu->showContextMenu(menuLocation, items); @@ -2685,11 +2719,11 @@ void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item) } #endif if (item.action() == ContextMenuItemTagDownloadImageToDisk) { - m_process->context()->download(this, KURL(KURL(), m_activeContextMenuState.absoluteImageURLString)); + m_process->context()->download(this, KURL(KURL(), m_activeContextMenuHitTestResultData.absoluteImageURL)); return; } if (item.action() == ContextMenuItemTagDownloadLinkToDisk) { - m_process->context()->download(this, KURL(KURL(), m_activeContextMenuState.absoluteLinkURLString)); + m_process->context()->download(this, KURL(KURL(), m_activeContextMenuHitTestResultData.absoluteLinkURL)); return; } if (item.action() == ContextMenuItemTagCheckSpellingWhileTyping) { @@ -3191,6 +3225,7 @@ void WebPageProxy::processDidCrash() ASSERT(m_pageClient); m_isValid = false; + m_isPageSuspended = false; if (m_mainFrame) { m_urlAtProcessExit = m_mainFrame->url(); @@ -3219,7 +3254,10 @@ void WebPageProxy::processDidCrash() m_openPanelResultListener = nullptr; } +#if ENABLE(GEOLOCATION) m_geolocationPermissionRequestManager.invalidateRequests(); +#endif + m_notificationPermissionRequestManager.invalidateRequests(); m_toolTip = String(); @@ -3335,6 +3373,11 @@ void WebPageProxy::exitAcceleratedCompositingMode() { m_pageClient->exitAcceleratedCompositingMode(); } + +void WebPageProxy::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) +{ + m_pageClient->updateAcceleratedCompositingMode(layerTreeContext); +} #endif // USE(ACCELERATED_COMPOSITING) void WebPageProxy::backForwardClear() @@ -3397,9 +3440,9 @@ void WebPageProxy::requestNotificationPermission(uint64_t requestID, const Strin request->deny(); } -void WebPageProxy::showNotification(const String& title, const String& body, const String& iconURL, const String& originString, uint64_t notificationID) +void WebPageProxy::showNotification(const String& title, const String& body, const String& iconURL, const String& replaceID, const String& originString, uint64_t notificationID) { - m_process->context()->notificationManagerProxy()->show(this, title, body, iconURL, originString, notificationID); + m_process->context()->notificationManagerProxy()->show(this, title, body, iconURL, replaceID, originString, notificationID); } float WebPageProxy::headerHeight(WebFrameProxy* frame) diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h index af8da1bef..5049228e2 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.h +++ b/Source/WebKit2/UIProcess/WebPageProxy.h @@ -28,7 +28,6 @@ #include "APIObject.h" #include "Connection.h" -#include "ContextMenuState.h" #include "DragControllerAction.h" #include "DrawingAreaProxy.h" #include "EditorState.h" @@ -39,6 +38,7 @@ #if PLATFORM(QT) #include "QtNetworkRequestData.h" #endif +#include "LayerTreeContext.h" #include "NotificationPermissionRequestManagerProxy.h" #include "PlatformProcessIdentifier.h" #include "SandboxExtension.h" @@ -46,6 +46,7 @@ #include "WKBase.h" #include "WKPagePrivate.h" #include "WebContextMenuItemData.h" +#include "WebCoreArgumentCoders.h" #include "WebFindClient.h" #include "WebFormClient.h" #include "WebFrameProxy.h" @@ -407,6 +408,9 @@ public: void setCustomTextEncodingName(const String&); String customTextEncodingName() const { return m_customTextEncodingName; } + void resumeActiveDOMObjectsAndAnimations(); + void suspendActiveDOMObjectsAndAnimations(); + double estimatedProgress() const; void terminateProcess(); @@ -429,7 +433,9 @@ public: void setIntrinsicDeviceScaleFactor(float); void setCustomDeviceScaleFactor(float); void windowScreenDidChange(PlatformDisplayID); - + + LayerHostingMode layerHostingMode() const { return m_layerHostingMode; } + void setUseFixedLayout(bool); void setFixedLayoutSize(const WebCore::IntSize&); bool useFixedLayout() const { return m_useFixedLayout; }; @@ -528,6 +534,7 @@ public: #if USE(ACCELERATED_COMPOSITING) virtual void enterAcceleratedCompositingMode(const LayerTreeContext&); virtual void exitAcceleratedCompositingMode(); + virtual void updateAcceleratedCompositingMode(const LayerTreeContext&); #endif void didDraw(); @@ -727,7 +734,7 @@ private: void reattachToWebProcessWithItem(WebBackForwardListItem*); void requestNotificationPermission(uint64_t notificationID, const String& originString); - void showNotification(const String& title, const String& body, const String& iconURL, const String& originString, uint64_t notificationID); + void showNotification(const String& title, const String& body, const String& iconURL, const String& replaceID, const String& originString, uint64_t notificationID); #if USE(TILED_BACKING_STORE) void pageDidRequestScroll(const WebCore::IntPoint&); @@ -779,8 +786,8 @@ private: #endif // Context Menu. - void showContextMenu(const WebCore::IntPoint& menuLocation, const ContextMenuState&, const Vector<WebContextMenuItemData>&, CoreIPC::ArgumentDecoder*); - void internalShowContextMenu(const WebCore::IntPoint& menuLocation, const ContextMenuState&, const Vector<WebContextMenuItemData>&, CoreIPC::ArgumentDecoder*); + void showContextMenu(const WebCore::IntPoint& menuLocation, const WebHitTestResult::Data&, const Vector<WebContextMenuItemData>&, CoreIPC::ArgumentDecoder*); + void internalShowContextMenu(const WebCore::IntPoint& menuLocation, const WebHitTestResult::Data&, const Vector<WebContextMenuItemData>&, CoreIPC::ArgumentDecoder*); // Search popup results void saveRecentSearches(const String&, const Vector<String>&); @@ -910,7 +917,7 @@ private: RefPtr<WebPopupMenuProxy> m_activePopupMenu; RefPtr<WebContextMenuProxy> m_activeContextMenu; - ContextMenuState m_activeContextMenuState; + WebHitTestResult::Data m_activeContextMenuHitTestResultData; RefPtr<WebOpenPanelResultListenerProxy> m_openPanelResultListener; GeolocationPermissionRequestManagerProxy m_geolocationPermissionRequestManager; NotificationPermissionRequestManagerProxy m_notificationPermissionRequestManager; @@ -942,6 +949,8 @@ private: float m_intrinsicDeviceScaleFactor; float m_customDeviceScaleFactor; + LayerHostingMode m_layerHostingMode; + bool m_drawsBackground; bool m_drawsTransparentBackground; @@ -992,6 +1001,8 @@ private: uint64_t m_pageID; + bool m_isPageSuspended; + #if PLATFORM(MAC) bool m_isSmartInsertDeleteEnabled; #endif diff --git a/Source/WebKit2/UIProcess/WebPageProxy.messages.in b/Source/WebKit2/UIProcess/WebPageProxy.messages.in index cb0c629e6..347aa933d 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.messages.in +++ b/Source/WebKit2/UIProcess/WebPageProxy.messages.in @@ -194,7 +194,7 @@ messages -> WebPageProxy { #endif # ContextMenu messages - ShowContextMenu(WebCore::IntPoint menuLocation, WebKit::ContextMenuState state, Vector<WebKit::WebContextMenuItemData> items, WebKit::InjectedBundleUserMessageEncoder userData) + ShowContextMenu(WebCore::IntPoint menuLocation, WebKit::WebHitTestResult::Data hitTestResultData, Vector<WebKit::WebContextMenuItemData> items, WebKit::InjectedBundleUserMessageEncoder userData) # Authentication messages CanAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID, WebCore::ProtectionSpace protectionSpace) -> (bool canAuthenticate) @@ -208,7 +208,7 @@ messages -> WebPageProxy { # Notification messages RequestNotificationPermission(uint64_t requestID, WTF::String originIdentifier) - ShowNotification(WTF::String title, WTF::String body, WTF::String iconURL, WTF::String originIdentifier, uint64_t notificationID) + ShowNotification(WTF::String title, WTF::String body, WTF::String iconURL, WTF::String replaceID, WTF::String originIdentifier, uint64_t notificationID) # Spelling and grammar messages #if USE(UNIFIED_TEXT_CHECKING) diff --git a/Source/WebKit2/UIProcess/efl/WebInspectorEfl.cpp b/Source/WebKit2/UIProcess/efl/WebInspectorEfl.cpp index 9e7696716..a2683ba2e 100644 --- a/Source/WebKit2/UIProcess/efl/WebInspectorEfl.cpp +++ b/Source/WebKit2/UIProcess/efl/WebInspectorEfl.cpp @@ -54,6 +54,12 @@ void WebInspectorProxy::platformBringToFront() notImplemented(); } +bool WebInspectorProxy::platformIsFront() +{ + notImplemented(); + return false; +} + void WebInspectorProxy::platformInspectedURLChanged(const String&) { notImplemented(); diff --git a/Source/WebKit2/UIProcess/gtk/WebFullScreenManagerProxyGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebFullScreenManagerProxyGtk.cpp index 5b5bf0242..a136008cd 100644 --- a/Source/WebKit2/UIProcess/gtk/WebFullScreenManagerProxyGtk.cpp +++ b/Source/WebKit2/UIProcess/gtk/WebFullScreenManagerProxyGtk.cpp @@ -29,6 +29,8 @@ #include <WebCore/NotImplemented.h> +using namespace WebCore; + namespace WebKit { void WebFullScreenManagerProxy::invalidate() @@ -46,37 +48,12 @@ void WebFullScreenManagerProxy::exitFullScreen() notImplemented(); } -void WebFullScreenManagerProxy::beganEnterFullScreenAnimation() -{ - notImplemented(); -} - -void WebFullScreenManagerProxy::finishedEnterFullScreenAnimation(bool completed) -{ - notImplemented(); -} - -void WebFullScreenManagerProxy::beganExitFullScreenAnimation() -{ - notImplemented(); -} - -void WebFullScreenManagerProxy::finishedExitFullScreenAnimation(bool completed) -{ - notImplemented(); -} - -void WebFullScreenManagerProxy::enterAcceleratedCompositingMode(const LayerTreeContext& context) -{ - notImplemented(); -} - -void WebFullScreenManagerProxy::exitAcceleratedCompositingMode() +void WebFullScreenManagerProxy::beganEnterFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) { notImplemented(); } -void WebFullScreenManagerProxy::getFullScreenRect(WebCore::IntRect& rect) +void WebFullScreenManagerProxy::beganExitFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) { notImplemented(); } diff --git a/Source/WebKit2/UIProcess/gtk/WebInspectorGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebInspectorGtk.cpp index 1be2a0000..3aaab77e2 100644 --- a/Source/WebKit2/UIProcess/gtk/WebInspectorGtk.cpp +++ b/Source/WebKit2/UIProcess/gtk/WebInspectorGtk.cpp @@ -110,6 +110,12 @@ void WebInspectorProxy::platformBringToFront() notImplemented(); } +bool WebInspectorProxy::platformIsFront() +{ + notImplemented(); + return false; +} + void WebInspectorProxy::platformInspectedURLChanged(const String& url) { GOwnPtr<gchar> title(g_strdup_printf("%s - %s", _("Web Inspector"), url.utf8().data())); diff --git a/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp b/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp index 521cf5320..db94d6f33 100644 --- a/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp +++ b/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.cpp @@ -41,7 +41,6 @@ WebPopupMenuProxyGtk::WebPopupMenuProxyGtk(GtkWidget* webView, WebPopupMenuProxy : WebPopupMenuProxy(client) , m_webView(webView) , m_activeItem(-1) - , m_runLoop(0) { } @@ -96,14 +95,13 @@ void WebPopupMenuProxyGtk::showPopupMenu(const IntRect& rect, TextDirection text // WebPageProxy expects the menu to run in a nested run loop, since it invalidates the // menu right after calling WebPopupMenuProxy::showPopupMenu(). - m_runLoop = g_main_loop_new(0, FALSE); + m_runLoop = adoptGRef(g_main_loop_new(0, FALSE)); GDK_THREADS_LEAVE(); - g_main_loop_run(m_runLoop); + g_main_loop_run(m_runLoop.get()); GDK_THREADS_ENTER(); - g_main_loop_unref(m_runLoop); - m_runLoop = 0; + m_runLoop.clear(); g_signal_handler_disconnect(m_popup->platformMenu(), unmapHandler); @@ -120,8 +118,8 @@ void WebPopupMenuProxyGtk::hidePopupMenu() void WebPopupMenuProxyGtk::shutdownRunLoop() { - if (g_main_loop_is_running(m_runLoop)) - g_main_loop_quit(m_runLoop); + if (g_main_loop_is_running(m_runLoop.get())) + g_main_loop_quit(m_runLoop.get()); } void WebPopupMenuProxyGtk::menuItemActivated(GtkAction* action, WebPopupMenuProxyGtk* popupMenu) diff --git a/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.h b/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.h index 9399ec11f..4b335bcde 100644 --- a/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.h +++ b/Source/WebKit2/UIProcess/gtk/WebPopupMenuProxyGtk.h @@ -23,6 +23,7 @@ #include "WebPopupMenuProxy.h" #include <WebCore/GtkPopupMenu.h> #include <WebCore/IntRect.h> +#include <wtf/gobject/GRefPtr.h> typedef struct _GMainLoop GMainLoop; @@ -53,7 +54,7 @@ private: GtkWidget* m_webView; OwnPtr<WebCore::GtkPopupMenu> m_popup; int m_activeItem; - GMainLoop* m_runLoop; + GRefPtr<GMainLoop> m_runLoop; }; } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/mac/BackingStoreMac.mm b/Source/WebKit2/UIProcess/mac/BackingStoreMac.mm index 2d159137e..9ec30b216 100644 --- a/Source/WebKit2/UIProcess/mac/BackingStoreMac.mm +++ b/Source/WebKit2/UIProcess/mac/BackingStoreMac.mm @@ -143,7 +143,7 @@ CGContextRef BackingStore::backingStoreContext() // Try to create a layer. if (CGContextRef containingWindowContext = m_webPageProxy->containingWindowGraphicsContext()) { - m_cgLayer.adoptCF(CGLayerCreateWithContext(containingWindowContext, NSSizeToCGSize(m_size), 0)); + m_cgLayer.adoptCF(CGLayerCreateWithContext(containingWindowContext, m_size, 0)); CGContextRef layerContext = CGLayerGetContext(m_cgLayer.get()); CGContextSetBlendMode(layerContext, kCGBlendModeCopy); diff --git a/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h b/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h index 75b95c408..df6c41179 100644 --- a/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h +++ b/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.h @@ -41,9 +41,12 @@ private: // DrawingAreaProxy virtual void deviceScaleFactorDidChange() OVERRIDE; + virtual void layerHostingModeDidChange() OVERRIDE; virtual void sizeDidChange() OVERRIDE; + virtual void enterAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&) OVERRIDE; virtual void exitAcceleratedCompositingMode(uint64_t backingStoreStateID, const UpdateInfo&) OVERRIDE; + virtual void updateAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext&) OVERRIDE; // Message handlers. virtual void didUpdateGeometry() OVERRIDE; diff --git a/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm b/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm index 319bcb401..d8f7d9d49 100644 --- a/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm +++ b/Source/WebKit2/UIProcess/mac/TiledCoreAnimationDrawingAreaProxy.mm @@ -56,6 +56,11 @@ void TiledCoreAnimationDrawingAreaProxy::deviceScaleFactorDidChange() m_webPageProxy->process()->send(Messages::DrawingArea::SetDeviceScaleFactor(m_webPageProxy->deviceScaleFactor()), m_webPageProxy->pageID()); } +void TiledCoreAnimationDrawingAreaProxy::layerHostingModeDidChange() +{ + m_webPageProxy->process()->send(Messages::DrawingArea::SetLayerHostingMode(m_webPageProxy->layerHostingMode()), m_webPageProxy->pageID()); +} + void TiledCoreAnimationDrawingAreaProxy::sizeDidChange() { if (!m_webPageProxy->isValid()) @@ -87,6 +92,11 @@ void TiledCoreAnimationDrawingAreaProxy::exitAcceleratedCompositingMode(uint64_t ASSERT_NOT_REACHED(); } +void TiledCoreAnimationDrawingAreaProxy::updateAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext& layerTreeContext) +{ + m_webPageProxy->updateAcceleratedCompositingMode(layerTreeContext); +} + void TiledCoreAnimationDrawingAreaProxy::didUpdateGeometry() { ASSERT(m_isWaitingForDidUpdateGeometry); diff --git a/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.h b/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.h index 74e794704..4e9cbf08b 100644 --- a/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.h +++ b/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.h @@ -38,19 +38,23 @@ class IntRect; } @class WKView; +@class WebWindowScaleAnimation; +@class WebWindowFadeAnimation; @interface WKFullScreenWindowController : NSWindowController { @private WKView *_webView; - RetainPtr<NSView> _webViewPlaceholder; - RetainPtr<NSView> _layerHostingView; + RetainPtr<NSImageView> _webViewPlaceholder; + RetainPtr<WebWindowScaleAnimation> _scaleAnimation; + RetainPtr<WebWindowFadeAnimation> _fadeAnimation; + RetainPtr<NSWindow> _backgroundWindow; + NSRect _initialFrame; + NSRect _finalFrame; BOOL _isEnteringFullScreen; BOOL _isExitingFullScreen; BOOL _isFullScreen; - BOOL _forceDisableAnimation; BOOL _isPlaying; - OwnPtr<WebCore::DisplaySleepDisabler> _displaySleepDisabler; } - (WKView*)webView; @@ -58,14 +62,9 @@ class IntRect; - (void)enterFullScreen:(NSScreen *)screen; - (void)exitFullScreen; -- (void)beganEnterFullScreenAnimation; -- (void)beganExitFullScreenAnimation; -- (void)finishedEnterFullScreenAnimation:(bool)completed; -- (void)finishedExitFullScreenAnimation:(bool)completed; -- (void)enterAcceleratedCompositingMode:(const WebKit::LayerTreeContext&)context; -- (void)exitAcceleratedCompositingMode; -- (WebCore::IntRect)getFullScreenRect; - (void)close; +- (void)beganEnterFullScreenWithInitialFrame:(const WebCore::IntRect&)initialFrame finalFrame:(const WebCore::IntRect&)finalFrame; +- (void)beganExitFullScreenWithInitialFrame:(const WebCore::IntRect&)initialFrame finalFrame:(const WebCore::IntRect&)finalFrame; @end diff --git a/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm b/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm index 204439fa9..b32d5c9ee 100644 --- a/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm +++ b/Source/WebKit2/UIProcess/mac/WKFullScreenWindowController.mm @@ -35,11 +35,12 @@ #import "WKViewPrivate.h" #import "WebFullScreenManagerProxy.h" #import "WebPageProxy.h" -#import <Carbon/Carbon.h> // For SetSystemUIMode() #import <QuartzCore/QuartzCore.h> #import <WebCore/DisplaySleepDisabler.h> #import <WebCore/FloatRect.h> #import <WebCore/IntRect.h> +#import <WebCore/WebCoreFullScreenWindow.h> +#import <WebCore/WebWindowAnimation.h> #import <WebKit/WebNSWindowExtras.h> #import <WebKitSystemInterface.h> #import <wtf/UnusedParam.h> @@ -47,48 +48,34 @@ using namespace WebKit; using namespace WebCore; -#if defined(BUILDING_ON_LEOPARD) -@interface CATransaction(SnowLeopardConvenienceFunctions) -+ (void)setDisableActions:(BOOL)flag; -+ (void)setAnimationDuration:(CFTimeInterval)dur; -@end +static RetainPtr<NSWindow> createBackgroundFullscreenWindow(NSRect frame); -@implementation CATransaction(SnowLeopardConvenienceFunctions) -+ (void)setDisableActions:(BOOL)flag -{ - [self setValue:[NSNumber numberWithBool:flag] forKey:kCATransactionDisableActions]; -} +static const CFTimeInterval defaultAnimationDuration = 0.5; -+ (void)setAnimationDuration:(CFTimeInterval)dur -{ - [self setValue:[NSNumber numberWithDouble:dur] forKey:kCATransactionAnimationDuration]; -} +@interface WKFullScreenWindowController(Private)<NSAnimationDelegate> +- (void)_updateMenuAndDockForFullScreen; +- (void)_swapView:(NSView*)view with:(NSView*)otherView; +- (WebPageProxy*)_page; +- (WebFullScreenManagerProxy*)_manager; +- (void)_startEnterFullScreenAnimationWithDuration:(NSTimeInterval)duration; +- (void)_startExitFullScreenAnimationWithDuration:(NSTimeInterval)duration; @end -#endif +#if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD) +@interface NSWindow(convertRectToScreenForLeopardAndSnowLeopard) +- (NSRect)convertRectToScreen:(NSRect)aRect; +@end -@interface WKFullScreenWindow : NSWindow +@implementation NSWindow(convertRectToScreenForLeopardAndSnowLeopard) +- (NSRect)convertRectToScreen:(NSRect)rect { - NSView* _animationView; - CALayer* _backgroundLayer; + NSRect frame = [self frame]; + rect.origin.x += frame.origin.x; + rect.origin.y += frame.origin.y; + return rect; } -- (CALayer*)backgroundLayer; -- (NSView*)animationView; -@end - -static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, void* context); - -@interface WKFullScreenWindowController(Private) -- (void)_requestExitFullScreenWithAnimation:(BOOL)animation; -- (void)_updateMenuAndDockForFullScreen; -- (void)_updatePowerAssertions; -- (WKFullScreenWindow *)_fullScreenWindow; -- (CFTimeInterval)_animationDuration; -- (void)_swapView:(NSView*)view with:(NSView*)otherView; -- (WebPageProxy*)_page; -- (WebFullScreenManagerProxy*)_manager; -- (void)_continueExitCompositingModeAfterRepaint; @end +#endif @interface NSWindow(IsOnActiveSpaceAdditionForTigerAndLeopard) - (BOOL)isOnActiveSpace; @@ -100,7 +87,7 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo #pragma mark Initialization - (id)init { - NSWindow *window = [[WKFullScreenWindow alloc] initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]; + NSWindow *window = [[WebCoreFullScreenWindow alloc] initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]; self = [super initWithWindow:window]; [window release]; if (!self) @@ -144,13 +131,21 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo } #pragma mark - +#pragma mark NSWindowController overrides + +- (void)cancelOperation:(id)sender +{ + [self performSelector:@selector(exitFullScreen) withObject:nil afterDelay:0]; +} + +#pragma mark - #pragma mark Notifications - (void)applicationDidResignActive:(NSNotification*)notification -{ +{ // Check to see if the fullScreenWindow is on the active space; this function is available // on 10.6 and later, so default to YES if the function is not available: - NSWindow* fullScreenWindow = [self _fullScreenWindow]; + NSWindow* fullScreenWindow = [self window]; BOOL isOnActiveSpace = ([fullScreenWindow respondsToSelector:@selector(isOnActiveSpace)] ? [fullScreenWindow isOnActiveSpace] : YES); // Replicate the QuickTime Player (X) behavior when losing active application status: @@ -158,7 +153,7 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo // single screen is available.) Is the fullScreen screen on the current space? IFF so, // then exit fullScreen mode. if ([fullScreenWindow screen] == [[NSScreen screens] objectAtIndex:0] && isOnActiveSpace) - [self _requestExitFullScreenWithAnimation:NO]; + [self cancelOperation:self]; } - (void)applicationDidChangeScreenParameters:(NSNotification*)notification @@ -169,7 +164,9 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo // entire screen: [self _updateMenuAndDockForFullScreen]; NSWindow* window = [self window]; - [window setFrame:[[window screen] frame] display:YES]; + NSRect screenFrame = [[window screen] frame]; + [window setFrame:screenFrame display:YES]; + [_backgroundWindow.get() setFrame:screenFrame display:YES]; } #pragma mark - @@ -179,72 +176,62 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo { if (_isFullScreen) return; - _isFullScreen = YES; - - NSDisableScreenUpdates(); - + + [self _updateMenuAndDockForFullScreen]; + if (!screen) screen = [NSScreen mainScreen]; NSRect screenFrame = [screen frame]; - -#if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD) - NSRect webViewFrame = [_webView convertRectToBase:[_webView frame]]; - webViewFrame.origin = [[_webView window] convertBaseToScreen:webViewFrame.origin]; -#else + NSRect webViewFrame = [[_webView window] convertRectToScreen: - [_webView convertRect:[_webView frame] toView:nil]]; -#endif - - // In the case of a multi-monitor setup where the webView straddles two - // monitors, we must create a window large enough to contain the destination - // frame and the initial frame. - NSRect windowFrame = NSUnionRect(screenFrame, webViewFrame); - - [CATransaction begin]; - [CATransaction setDisableActions:YES]; - [[self window] setFrame:windowFrame display:YES]; - - CALayer* backgroundLayer = [[self _fullScreenWindow] backgroundLayer]; - NSRect backgroundFrame = {[[self window] convertScreenToBase:screenFrame.origin], screenFrame.size}; - backgroundFrame = [[[self window] contentView] convertRectFromBase:backgroundFrame]; + [_webView convertRect:[_webView frame] toView:nil]]; + + // Flip coordinate system: + webViewFrame.origin.y = NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]) - NSMaxY(webViewFrame); + + CGWindowID windowID = [[_webView window] windowNumber]; + RetainPtr<CGImageRef> webViewContents(AdoptCF, CGWindowListCreateImage(NSRectToCGRect(webViewFrame), kCGWindowListOptionIncludingWindow, windowID, kCGWindowImageShouldBeOpaque)); + + // Screen updates to be re-enabled in beganEnterFullScreenWithInitialFrame:finalFrame: + NSDisableScreenUpdates(); + [[self window] setAutodisplay:NO]; + + NSResponder *webWindowFirstResponder = [[_webView window] firstResponder]; + [[self window] setFrame:screenFrame display:NO]; + + // Swap the webView placeholder into place. + if (!_webViewPlaceholder) { + _webViewPlaceholder.adoptNS([[NSImageView alloc] init]); + [_webViewPlaceholder.get() setLayer:[CALayer layer]]; + [_webViewPlaceholder.get() setWantsLayer:YES]; + } + [[_webViewPlaceholder.get() layer] setContents:(id)webViewContents.get()]; + [self _swapView:_webView with:_webViewPlaceholder.get()]; - [backgroundLayer setFrame:NSRectToCGRect(backgroundFrame)]; - [CATransaction commit]; + // Then insert the WebView into the full screen window + NSView* contentView = [[self window] contentView]; + [contentView addSubview:_webView positioned:NSWindowBelow relativeTo:nil]; + [_webView setFrame:[contentView bounds]]; + + [[self window] makeResponder:webWindowFirstResponder firstResponderIfDescendantOfView:_webView]; - CFTimeInterval duration = [self _animationDuration]; [self _manager]->willEnterFullScreen(); - [self _manager]->beginEnterFullScreenAnimation(duration); + [self _manager]->setAnimatingFullScreen(true); } -- (void)beganEnterFullScreenAnimation +- (void)beganEnterFullScreenWithInitialFrame:(const WebCore::IntRect&)initialFrame finalFrame:(const WebCore::IntRect&)finalFrame { if (_isEnteringFullScreen) return; _isEnteringFullScreen = YES; - if (_isExitingFullScreen) - [self finishedExitFullScreenAnimation:NO]; + _initialFrame = initialFrame; + _finalFrame = finalFrame; [self _updateMenuAndDockForFullScreen]; - [self _updatePowerAssertions]; - - // In a previous incarnation, the NSWindow attached to this controller may have - // been on a different screen. Temporarily change the collectionBehavior of the window: - NSWindow* fullScreenWindow = [self window]; - NSWindowCollectionBehavior behavior = [fullScreenWindow collectionBehavior]; - [fullScreenWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; - [fullScreenWindow makeKeyAndOrderFront:self]; - [fullScreenWindow setCollectionBehavior:behavior]; - - // Start the opacity animation. We can use implicit animations here because we don't care when - // the animation finishes. - [CATransaction begin]; - [CATransaction setAnimationDuration:[self _animationDuration]]; - [[[self _fullScreenWindow] backgroundLayer] setOpacity:1]; - [CATransaction commit]; - NSEnableScreenUpdates(); + [self _startEnterFullScreenAnimationWithDuration:defaultAnimationDuration]; } - (void)finishedEnterFullScreenAnimation:(bool)completed @@ -252,22 +239,17 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo if (!_isEnteringFullScreen) return; _isEnteringFullScreen = NO; - - if (completed) { + + if (completed) { + // Screen updates to be re-enabled ta the end of the current block. NSDisableScreenUpdates(); + [self _manager]->setAnimatingFullScreen(false); + [self _manager]->didEnterFullScreen(); + + NSRect windowBounds = [[self window] frame]; + windowBounds.origin = NSZeroPoint; + WKWindowSetClipRect([self window], windowBounds); - // Swap the webView placeholder into place. - if (!_webViewPlaceholder) - _webViewPlaceholder.adoptNS([[NSView alloc] init]); - NSResponder *webWindowFirstResponder = [[_webView window] firstResponder]; - [self _swapView:_webView with:_webViewPlaceholder.get()]; - - // Then insert the WebView into the full screen window - NSView* contentView = [[self _fullScreenWindow] contentView]; - [contentView addSubview:_webView positioned:NSWindowBelow relativeTo:nil]; - [_webView setFrame:[contentView bounds]]; - [[self window] makeResponder:webWindowFirstResponder firstResponderIfDescendantOfView:_webView]; - NSWindow *webWindow = [_webViewPlaceholder.get() window]; #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) // In Lion, NSWindow will animate into and out of orderOut operations. Suppress that @@ -279,26 +261,33 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) [webWindow setAnimationBehavior:animationBehavior]; #endif - [self _manager]->didEnterFullScreen(); - } - // Complete the animation once -(void)exitCompositingMode is called. + [_fadeAnimation.get() stopAnimation]; + [_fadeAnimation.get() setWindow:nil]; + _fadeAnimation = nullptr; + + [_backgroundWindow.get() orderOut:self]; + [_backgroundWindow.get() setFrame:NSZeroRect display:YES]; + NSEnableScreenUpdates(); + } else + [_scaleAnimation.get() stopAnimation]; } - (void)exitFullScreen { if (!_isFullScreen) return; - _isFullScreen = NO; - + + // Screen updates to be re-enabled in beganExitFullScreenWithInitialFrame:finalFrame: NSDisableScreenUpdates(); - + [[self window] setAutodisplay:NO]; + [self _manager]->willExitFullScreen(); - [self _manager]->beginExitFullScreenAnimation([self _animationDuration]); + [self _manager]->setAnimatingFullScreen(true); } -- (void)beganExitFullScreenAnimation +- (void)beganExitFullScreenWithInitialFrame:(const WebCore::IntRect&)initialFrame finalFrame:(const WebCore::IntRect&)finalFrame { if (_isExitingFullScreen) return; @@ -307,52 +296,30 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo if (_isEnteringFullScreen) [self finishedEnterFullScreenAnimation:NO]; - [self _updateMenuAndDockForFullScreen]; - [self _updatePowerAssertions]; + [self _updateMenuAndDockForFullScreen]; - // Swap the webView back into its original position: - if ([_webView window] == [self window]) { - NSResponder *fullScreenWindowFirstResponder = [[self _fullScreenWindow] firstResponder]; -#if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD) - // Work around a bug in AppKit <rdar://problem/9443385> where moving a - // layer-hosted view from a layer-backed view to a non-layer-backed view - // generates an exception. - if (![_webView wantsLayer] && [_webView layer]) { - [_webView removeFromSuperview]; - for (NSView* child in [_webView subviews]) - [[child layer] removeFromSuperlayer]; - } -#endif - [self _swapView:_webViewPlaceholder.get() with:_webView]; - [[_webView window] makeResponder:fullScreenWindowFirstResponder firstResponderIfDescendantOfView:_webView]; - NSWindow* webWindow = [_webView window]; + NSWindow* webWindow = [_webViewPlaceholder.get() window]; #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) - // In Lion, NSWindow will animate into and out of orderOut operations. Suppress that - // behavior here, making sure to reset the animation behavior afterward. - NSWindowAnimationBehavior animationBehavior = [webWindow animationBehavior]; - [webWindow setAnimationBehavior:NSWindowAnimationBehaviorNone]; + // In Lion, NSWindow will animate into and out of orderOut operations. Suppress that + // behavior here, making sure to reset the animation behavior afterward. + NSWindowAnimationBehavior animationBehavior = [webWindow animationBehavior]; + [webWindow setAnimationBehavior:NSWindowAnimationBehaviorNone]; #endif - // If the user has moved the fullScreen window into a new space, temporarily change - // the collectionBehavior of the webView's window so that it is pulled into the active space: - if (![webWindow isOnActiveSpace]) { - NSWindowCollectionBehavior behavior = [webWindow collectionBehavior]; - [webWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; - [webWindow orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]]; - [webWindow setCollectionBehavior:behavior]; - } else - [webWindow orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]]; - + // If the user has moved the fullScreen window into a new space, temporarily change + // the collectionBehavior of the webView's window so that it is pulled into the active space: + if (![webWindow isOnActiveSpace]) { + NSWindowCollectionBehavior behavior = [webWindow collectionBehavior]; + [webWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces]; + [webWindow orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]]; + [webWindow setCollectionBehavior:behavior]; + } else + [webWindow orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]]; + #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) - [webWindow setAnimationBehavior:animationBehavior]; + [webWindow setAnimationBehavior:animationBehavior]; #endif - } - - [CATransaction begin]; - [CATransaction setAnimationDuration:[self _animationDuration]]; - [[[self _fullScreenWindow] backgroundLayer] setOpacity:0]; - [CATransaction commit]; - - NSEnableScreenUpdates(); + + [self _startExitFullScreenAnimationWithDuration:defaultAnimationDuration]; } - (void)finishedExitFullScreenAnimation:(bool)completed @@ -361,84 +328,33 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo return; _isExitingFullScreen = NO; - NSDisableScreenUpdates(); - [self _updateMenuAndDockForFullScreen]; - [self _updatePowerAssertions]; - [NSCursor setHiddenUntilMouseMoves:YES]; + // Screen updates to be re-enabled ta the end of the current function. + NSDisableScreenUpdates(); + + [self _manager]->setAnimatingFullScreen(false); [self _manager]->didExitFullScreen(); -} -- (void)enterAcceleratedCompositingMode:(const WebKit::LayerTreeContext&)layerTreeContext -{ - if (_layerHostingView) - return; - - // Create an NSView that will host our layer tree. - _layerHostingView.adoptNS([[NSView alloc] initWithFrame:[[self window] frame]]); - [_layerHostingView.get() setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - - [CATransaction begin]; - [CATransaction setDisableActions:YES]; - WKFullScreenWindow* window = [self _fullScreenWindow]; - [[window contentView] addSubview:_layerHostingView.get() positioned:NSWindowAbove relativeTo:nil]; - - // Create a root layer that will back the NSView. - RetainPtr<CALayer> rootLayer(AdoptNS, [[CALayer alloc] init]); -#ifndef NDEBUG - [rootLayer.get() setName:@"Hosting root layer"]; -#endif - - CALayer *renderLayer = WKMakeRenderLayer(layerTreeContext.contextID); - [rootLayer.get() addSublayer:renderLayer]; - - [_layerHostingView.get() setLayer:rootLayer.get()]; - [_layerHostingView.get() setWantsLayer:YES]; - [[window backgroundLayer] setHidden:NO]; - [CATransaction commit]; -} + NSResponder *firstResponder = [[self window] firstResponder]; + [self _swapView:_webViewPlaceholder.get() with:_webView]; + [[_webView window] makeResponder:firstResponder firstResponderIfDescendantOfView:_webView]; -- (void)exitAcceleratedCompositingMode -{ - if (!_layerHostingView) - return; + NSRect windowBounds = [[self window] frame]; + windowBounds.origin = NSZeroPoint; + WKWindowSetClipRect([self window], windowBounds); - [CATransaction begin]; - [CATransaction setDisableActions:YES]; - [_layerHostingView.get() removeFromSuperview]; - [_layerHostingView.get() setLayer:nil]; - [_layerHostingView.get() setWantsLayer:NO]; - [[[self _fullScreenWindow] backgroundLayer] setHidden:YES]; - [CATransaction commit]; + [[self window] orderOut:self]; + [[self window] setFrame:NSZeroRect display:YES]; - // Complete the animation out of full-screen mode - // by hiding the full-screen window: - if (!_isFullScreen) { - [[_webView window] display]; - [[self window] orderOut:self]; - [[_webView window] makeKeyAndOrderFront:self]; - } - - _layerHostingView = 0; - [self _page]->forceRepaint(VoidCallback::create(self, continueExitCompositingModeAfterRepaintCallback)); -} + [_fadeAnimation.get() stopAnimation]; + [_fadeAnimation.get() setWindow:nil]; + _fadeAnimation = nullptr; -static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, void* context) -{ - [(WKFullScreenWindowController*)context _continueExitCompositingModeAfterRepaint]; -} + [_backgroundWindow.get() orderOut:self]; + [_backgroundWindow.get() setFrame:NSZeroRect display:YES]; -- (void)_continueExitCompositingModeAfterRepaint -{ NSEnableScreenUpdates(); - - [self _manager]->disposeOfLayerClient(); -} - -- (WebCore::IntRect)getFullScreenRect -{ - return enclosingIntRect([[self window] frame]); } - (void)close @@ -447,10 +363,8 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo // has closed or the web process has crashed. Just walk through our // normal exit full screen sequence, but don't wait to be called back // in response. - if (_isFullScreen) { + if (_isFullScreen) [self exitFullScreen]; - [self beganExitFullScreenAnimation]; - } if (_isExitingFullScreen) [self finishedExitFullScreenAnimation:YES]; @@ -459,6 +373,17 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo } #pragma mark - +#pragma mark NSAnimation delegate + +- (void)animationDidEnd:(NSAnimation*)animation +{ + if (_isFullScreen) + [self finishedEnterFullScreenAnimation:YES]; + else + [self finishedExitFullScreenAnimation:YES]; +} + +#pragma mark - #pragma mark Internal Interface - (void)_updateMenuAndDockForFullScreen @@ -488,16 +413,6 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo SetSystemUIMode(_isFullScreen ? kUIModeNormal : kUIModeAllHidden, 0); } -- (void)_updatePowerAssertions -{ - // FIXME: _isPlaying is never modified so we never disable display sleep here! (<rdar://problem/10151029>) - if (_isPlaying && _isFullScreen) { - if (!_displaySleepDisabler) - _displaySleepDisabler = DisplaySleepDisabler::create("com.apple.WebKit2 - Fullscreen video"); - } else - _displaySleepDisabler = nullptr; -} - - (WebPageProxy*)_page { return toImpl([_webView pageRef]); @@ -511,19 +426,6 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo return webPage->fullScreenManager(); } -- (void)_requestExit -{ - [self exitFullScreen]; - _forceDisableAnimation = NO; -} - -- (void)_requestExitFullScreenWithAnimation:(BOOL)animation -{ - _forceDisableAnimation = !animation; - [self performSelector:@selector(_requestExit) withObject:nil afterDelay:0]; - -} - - (void)_swapView:(NSView*)view with:(NSView*)otherView { [CATransaction begin]; @@ -535,109 +437,117 @@ static void continueExitCompositingModeAfterRepaintCallback(WKErrorRef error, vo [CATransaction commit]; } -#pragma mark - -#pragma mark Utility Functions - -- (WKFullScreenWindow *)_fullScreenWindow +static RetainPtr<NSWindow> createBackgroundFullscreenWindow(NSRect frame) { - ASSERT([[self window] isKindOfClass:[WKFullScreenWindow class]]); - return (WKFullScreenWindow *)[self window]; + NSWindow *window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]; + [window setOpaque:YES]; + [window setBackgroundColor:[NSColor blackColor]]; + [window setReleasedWhenClosed:NO]; + return adoptNS(window); } -- (CFTimeInterval)_animationDuration +static NSRect windowFrameFromApparentFrames(NSRect screenFrame, NSRect initialFrame, NSRect finalFrame) { - static const CFTimeInterval defaultDuration = 0.5; - CFTimeInterval duration = defaultDuration; -#ifndef BUILDING_ON_LEOPARD - NSUInteger modifierFlags = [NSEvent modifierFlags]; -#else - NSUInteger modifierFlags = [[NSApp currentEvent] modifierFlags]; -#endif - if ((modifierFlags & NSControlKeyMask) == NSControlKeyMask) - duration *= 2; - if ((modifierFlags & NSShiftKeyMask) == NSShiftKeyMask) - duration *= 10; - if (_forceDisableAnimation) { - // This will disable scale animation - duration = 0; - } - return duration; + NSRect initialWindowFrame; + CGFloat xScale = NSWidth(screenFrame) / NSWidth(finalFrame); + CGFloat yScale = NSHeight(screenFrame) / NSHeight(finalFrame); + CGFloat xTrans = NSMinX(screenFrame) - NSMinX(finalFrame); + CGFloat yTrans = NSMinY(screenFrame) - NSMinY(finalFrame); + initialWindowFrame.size = NSMakeSize(NSWidth(initialFrame) * xScale, NSHeight(initialFrame) * yScale); + initialWindowFrame.origin = NSMakePoint + ( NSMinX(initialFrame) + xTrans / (NSWidth(finalFrame) / NSWidth(initialFrame)) + , NSMinY(initialFrame) + yTrans / (NSHeight(finalFrame) / NSHeight(initialFrame))); + return initialWindowFrame; } -@end - -#pragma mark - -@implementation WKFullScreenWindow - -- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag +- (void)_startEnterFullScreenAnimationWithDuration:(NSTimeInterval)duration { - UNUSED_PARAM(aStyle); - self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:bufferingType defer:flag]; - if (!self) - return nil; - [self setOpaque:NO]; - [self setBackgroundColor:[NSColor clearColor]]; - [self setIgnoresMouseEvents:NO]; - [self setAcceptsMouseMovedEvents:YES]; - [self setReleasedWhenClosed:NO]; - [self setHasShadow:YES]; -#ifndef BUILDING_ON_LEOPARD - [self setMovable:NO]; -#else - [self setMovableByWindowBackground:NO]; -#endif + NSRect screenFrame = [[[self window] screen] frame]; + NSRect initialWindowFrame = windowFrameFromApparentFrames(screenFrame, _initialFrame, _finalFrame); - NSView* contentView = [self contentView]; - [contentView setWantsLayer:YES]; - _animationView = [[NSView alloc] initWithFrame:[contentView bounds]]; + _scaleAnimation.adoptNS([[WebWindowScaleAnimation alloc] initWithHintedDuration:duration window:[self window] initalFrame:initialWindowFrame finalFrame:screenFrame]); - CALayer* contentLayer = [[CALayer alloc] init]; - [_animationView setLayer:contentLayer]; - [_animationView setWantsLayer:YES]; - [_animationView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; - [contentView addSubview:_animationView]; - - _backgroundLayer = [[CALayer alloc] init]; - [contentLayer addSublayer:_backgroundLayer]; - - [_backgroundLayer setBackgroundColor:CGColorGetConstantColor(kCGColorBlack)]; - [_backgroundLayer setOpacity:0]; - return self; -} + [_scaleAnimation.get() setAnimationBlockingMode:NSAnimationNonblocking]; + [_scaleAnimation.get() setDelegate:self]; + [_scaleAnimation.get() setCurrentProgress:0]; + [_scaleAnimation.get() startAnimation]; -- (void)dealloc -{ - [_animationView release]; - [_backgroundLayer release]; - [super dealloc]; -} + // WKWindowSetClipRect takes window coordinates, so convert from screen coordinates here: + NSRect finalBounds = _finalFrame; + finalBounds.origin = [[self window] convertScreenToBase:finalBounds.origin]; + WKWindowSetClipRect([self window], finalBounds); -- (BOOL)canBecomeKeyWindow -{ - return YES; -} + [[self window] makeKeyAndOrderFront:self]; -- (void)keyDown:(NSEvent *)theEvent -{ - if ([[theEvent charactersIgnoringModifiers] isEqual:@"\e"]) // Esacpe key-code - [self cancelOperation:self]; - else [super keyDown:theEvent]; -} + if (!_backgroundWindow) + _backgroundWindow = createBackgroundFullscreenWindow(screenFrame); + else + [_backgroundWindow.get() setFrame:screenFrame display:NO]; -- (void)cancelOperation:(id)sender -{ - UNUSED_PARAM(sender); - [[self windowController] _requestExitFullScreenWithAnimation:YES]; -} + CGFloat currentAlpha = 0; + if (_fadeAnimation) { + currentAlpha = [_fadeAnimation.get() currentAlpha]; + [_fadeAnimation.get() stopAnimation]; + [_fadeAnimation.get() setWindow:nil]; + } -- (CALayer*)backgroundLayer -{ - return _backgroundLayer; + _fadeAnimation.adoptNS([[WebWindowFadeAnimation alloc] initWithDuration:duration + window:_backgroundWindow.get() + initialAlpha:currentAlpha + finalAlpha:1]); + [_fadeAnimation.get() setAnimationBlockingMode:NSAnimationNonblocking]; + [_fadeAnimation.get() setCurrentProgress:0]; + [_fadeAnimation.get() startAnimation]; + + [_backgroundWindow.get() orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]]; + + [[self window] setAutodisplay:YES]; + [[self window] displayIfNeeded]; + NSEnableScreenUpdates(); } -- (NSView*)animationView +- (void)_startExitFullScreenAnimationWithDuration:(NSTimeInterval)duration { - return _animationView; + NSRect screenFrame = [[[self window] screen] frame]; + NSRect initialWindowFrame = windowFrameFromApparentFrames(screenFrame, _initialFrame, _finalFrame); + + NSRect currentFrame = _scaleAnimation ? [_scaleAnimation.get() currentFrame] : [[self window] frame]; + _scaleAnimation.adoptNS([[WebWindowScaleAnimation alloc] initWithHintedDuration:duration window:[self window] initalFrame:currentFrame finalFrame:initialWindowFrame]); + + [_scaleAnimation.get() setAnimationBlockingMode:NSAnimationNonblocking]; + [_scaleAnimation.get() setDelegate:self]; + [_scaleAnimation.get() setCurrentProgress:0]; + [_scaleAnimation.get() startAnimation]; + + if (!_backgroundWindow) + _backgroundWindow = createBackgroundFullscreenWindow(screenFrame); + else + [_backgroundWindow.get() setFrame:screenFrame display:NO]; + + CGFloat currentAlpha = 1; + if (_fadeAnimation) { + currentAlpha = [_fadeAnimation.get() currentAlpha]; + [_fadeAnimation.get() stopAnimation]; + [_fadeAnimation.get() setWindow:nil]; + } + _fadeAnimation.adoptNS([[WebWindowFadeAnimation alloc] initWithDuration:duration + window:_backgroundWindow.get() + initialAlpha:currentAlpha + finalAlpha:0]); + [_fadeAnimation.get() setAnimationBlockingMode:NSAnimationNonblocking]; + [_fadeAnimation.get() setCurrentProgress:0]; + [_fadeAnimation.get() startAnimation]; + + [_backgroundWindow.get() orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]]; + + // WKWindowSetClipRect takes window coordinates, so convert from screen coordinates here: + NSRect finalBounds = _finalFrame; + finalBounds.origin = [[self window] convertScreenToBase:finalBounds.origin]; + WKWindowSetClipRect([self window], finalBounds); + + [[self window] setAutodisplay:YES]; + [[self window] displayIfNeeded]; + NSEnableScreenUpdates(); } @end diff --git a/Source/WebKit2/UIProcess/mac/WebContextMac.mm b/Source/WebKit2/UIProcess/mac/WebContextMac.mm index 5270b7396..ab5721bb8 100644 --- a/Source/WebKit2/UIProcess/mac/WebContextMac.mm +++ b/Source/WebKit2/UIProcess/mac/WebContextMac.mm @@ -28,9 +28,15 @@ #import "WebKitSystemInterface.h" #import "WebProcessCreationParameters.h" +#import <WebCore/Color.h> #import <WebCore/FileSystem.h> +#import <WebCore/PlatformPasteboard.h> #import <sys/param.h> +#if !defined(BUILDING_ON_SNOW_LEOPARD) +#import <QuartzCore/CARemoteLayerServer.h> +#endif + using namespace WebCore; NSString *WebDatabaseDirectoryDefaultsKey = @"WebDatabaseDirectory"; @@ -93,7 +99,11 @@ void WebContext::platformInitializeWebProcess(WebProcessCreationParameters& para #endif #if USE(ACCELERATED_COMPOSITING) && HAVE(HOSTED_CORE_ANIMATION) +#if !defined(BUILDING_ON_SNOW_LEOPARD) + mach_port_t renderServerPort = [[CARemoteLayerServer sharedServer] serverPort]; +#else mach_port_t renderServerPort = WKInitializeRenderServer(); +#endif if (renderServerPort != MACH_PORT_NULL) parameters.acceleratedCompositingPort = CoreIPC::MachPort(renderServerPort, MACH_MSG_TYPE_COPY_SEND); #endif @@ -147,5 +157,77 @@ bool WebContext::omitPDFSupport() return [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitOmitPDFSupport"]; } +void WebContext::getPasteboardTypes(const String& pasteboardName, Vector<String>& pasteboardTypes) +{ + PlatformPasteboard(pasteboardName).getTypes(pasteboardTypes); +} + +void WebContext::getPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, Vector<String>& pathnames) +{ + PlatformPasteboard(pasteboardName).getPathnamesForType(pathnames, pasteboardType); +} + +void WebContext::getPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, String& string) +{ + string = PlatformPasteboard(pasteboardName).stringForType(pasteboardType); +} + +void WebContext::getPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, SharedMemory::Handle& handle, uint64_t& size) +{ + RefPtr<SharedBuffer> buffer = PlatformPasteboard(pasteboardName).bufferForType(pasteboardType); + if (!buffer) + return; + size = buffer->size(); + RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(size); + memcpy(sharedMemoryBuffer->data(), buffer->data(), size); + sharedMemoryBuffer->createHandle(handle, SharedMemory::ReadOnly); +} + +void WebContext::pasteboardCopy(const String& fromPasteboard, const String& toPasteboard) +{ + PlatformPasteboard(toPasteboard).copy(fromPasteboard); +} + +void WebContext::getPasteboardChangeCount(const String& pasteboardName, uint64_t& changeCount) +{ + changeCount = PlatformPasteboard(pasteboardName).changeCount(); +} + +void WebContext::getPasteboardUniqueName(String& pasteboardName) +{ + pasteboardName = PlatformPasteboard::uniqueName(); +} + +void WebContext::getPasteboardColor(const String& pasteboardName, WebCore::Color& color) +{ + color = PlatformPasteboard(pasteboardName).color(); +} + +void WebContext::setPasteboardTypes(const String& pasteboardName, const Vector<String>& pasteboardTypes) +{ + PlatformPasteboard(pasteboardName).setTypes(pasteboardTypes); +} + +void WebContext::setPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, const Vector<String>& pathnames) +{ + PlatformPasteboard(pasteboardName).setPathnamesForType(pathnames, pasteboardType); +} + +void WebContext::setPasteboardStringForType(const String& pasteboardName, const String& pasteboardType, const String& string) +{ + PlatformPasteboard(pasteboardName).setStringForType(string, pasteboardType); +} + +void WebContext::setPasteboardBufferForType(const String& pasteboardName, const String& pasteboardType, const SharedMemory::Handle& handle, uint64_t size) +{ + if (handle.isNull()) { + PlatformPasteboard(pasteboardName).setBufferForType(0, pasteboardType); + return; + } + RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::create(handle, SharedMemory::ReadOnly); + RefPtr<SharedBuffer> buffer = SharedBuffer::create(static_cast<unsigned char *>(sharedMemoryBuffer->data()), size); + PlatformPasteboard(pasteboardName).setBufferForType(buffer, pasteboardType); +} + } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/mac/WebContextMenuProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebContextMenuProxyMac.mm index 81552dc5e..74c64464d 100644 --- a/Source/WebKit2/UIProcess/mac/WebContextMenuProxyMac.mm +++ b/Source/WebKit2/UIProcess/mac/WebContextMenuProxyMac.mm @@ -27,6 +27,7 @@ #import "WebContextMenuProxyMac.h" #import "PageClientImpl.h" +#import "StringUtilities.h" #import "WebContextMenuItemData.h" #import "WKView.h" diff --git a/Source/WebKit2/UIProcess/mac/WebFullScreenManagerProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebFullScreenManagerProxyMac.mm index 20e92c054..04667b6cd 100644 --- a/Source/WebKit2/UIProcess/mac/WebFullScreenManagerProxyMac.mm +++ b/Source/WebKit2/UIProcess/mac/WebFullScreenManagerProxyMac.mm @@ -33,6 +33,8 @@ #if ENABLE(FULLSCREEN_API) +using namespace WebCore; + namespace WebKit { void WebFullScreenManagerProxy::invalidate() @@ -57,54 +59,17 @@ void WebFullScreenManagerProxy::exitFullScreen() return; [[m_webView fullScreenWindowController] exitFullScreen]; } - -void WebFullScreenManagerProxy::beganEnterFullScreenAnimation() -{ - if (!m_webView) - return; - [[m_webView fullScreenWindowController] beganEnterFullScreenAnimation]; -} - -void WebFullScreenManagerProxy::finishedEnterFullScreenAnimation(bool completed) -{ - if (!m_webView) - return; - [[m_webView fullScreenWindowController] finishedEnterFullScreenAnimation:completed]; -} - -void WebFullScreenManagerProxy::beganExitFullScreenAnimation() -{ - if (!m_webView) - return; - [[m_webView fullScreenWindowController] beganExitFullScreenAnimation]; -} - -void WebFullScreenManagerProxy::finishedExitFullScreenAnimation(bool completed) -{ - if (!m_webView) - return; - [[m_webView fullScreenWindowController] finishedExitFullScreenAnimation:completed]; -} -void WebFullScreenManagerProxy::enterAcceleratedCompositingMode(const LayerTreeContext& context) +void WebFullScreenManagerProxy::beganEnterFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) { - if (!m_webView) - return; - [[m_webView fullScreenWindowController] enterAcceleratedCompositingMode:context]; + if (m_webView) + [[m_webView fullScreenWindowController] beganEnterFullScreenWithInitialFrame:initialFrame finalFrame:finalFrame]; } -void WebFullScreenManagerProxy::exitAcceleratedCompositingMode() +void WebFullScreenManagerProxy::beganExitFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) { - if (!m_webView) - return; - [[m_webView fullScreenWindowController] exitAcceleratedCompositingMode]; -} - -void WebFullScreenManagerProxy::getFullScreenRect(WebCore::IntRect& rect) -{ - if (!m_webView) - return; - rect = [[m_webView fullScreenWindowController] getFullScreenRect]; + if (m_webView) + [[m_webView fullScreenWindowController] beganExitFullScreenWithInitialFrame:initialFrame finalFrame:finalFrame]; } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/mac/WebInspectorProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebInspectorProxyMac.mm index d90ad1215..0db662c42 100644 --- a/Source/WebKit2/UIProcess/mac/WebInspectorProxyMac.mm +++ b/Source/WebKit2/UIProcess/mac/WebInspectorProxyMac.mm @@ -30,7 +30,7 @@ #import "WKAPICast.h" #import "WebContext.h" -#import "WKInspectorMac.h" +#import "WKInspectorPrivateMac.h" #import "WKViewPrivate.h" #import "WebPageGroup.h" #import "WebPageProxy.h" @@ -51,9 +51,7 @@ static const CGFloat windowContentBorderThickness = 55; // WKWebInspectorProxyObjCAdapter is a helper ObjC object used as a delegate or notification observer // for the sole purpose of getting back into the C++ code from an ObjC caller. -@interface WKWebInspectorProxyObjCAdapter : NSObject <NSWindowDelegate> { - WebInspectorProxy* _inspectorProxy; // Not retained to prevent cycles -} +@interface WKWebInspectorProxyObjCAdapter () - (id)initWithWebInspectorProxy:(WebInspectorProxy*)inspectorProxy; @@ -61,6 +59,11 @@ static const CGFloat windowContentBorderThickness = 55; @implementation WKWebInspectorProxyObjCAdapter +- (WKInspectorRef)inspectorRef +{ + return toAPI(static_cast<WebInspectorProxy*>(_inspectorProxy)); +} + - (id)initWithWebInspectorProxy:(WebInspectorProxy*)inspectorProxy { ASSERT_ARG(inspectorProxy, inspectorProxy); @@ -68,19 +71,19 @@ static const CGFloat windowContentBorderThickness = 55; if (!(self = [super init])) return nil; - _inspectorProxy = inspectorProxy; // Not retained to prevent cycles + _inspectorProxy = static_cast<void*>(inspectorProxy); // Not retained to prevent cycles return self; } - (void)windowWillClose:(NSNotification *)notification { - _inspectorProxy->close(); + static_cast<WebInspectorProxy*>(_inspectorProxy)->close(); } - (void)inspectedViewFrameDidChange:(NSNotification *)notification { - _inspectorProxy->inspectedViewFrameDidChange(); + static_cast<WebInspectorProxy*>(_inspectorProxy)->inspectedViewFrameDidChange(); } @end @@ -191,10 +194,16 @@ void WebInspectorProxy::platformDidClose() void WebInspectorProxy::platformBringToFront() { - // FIXME: this will not bring a background tab in Safari to the front, only its window. + // FIXME <rdar://problem/10937688>: this will not bring a background tab in Safari to the front, only its window. [m_inspectorView.get().window makeKeyAndOrderFront:nil]; } +bool WebInspectorProxy::platformIsFront() +{ + // FIXME <rdar://problem/10937688>: this will not return false for a background tab in Safari, only a background window. + return m_isVisible && [m_inspectorView.get().window isMainWindow]; +} + void WebInspectorProxy::platformInspectedURLChanged(const String& urlString) { m_urlString = urlString; diff --git a/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm index 192eb419f..120dc5d28 100644 --- a/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm +++ b/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm @@ -34,6 +34,7 @@ #import "PluginComplexTextInputState.h" #import "PageClient.h" #import "PageClientImpl.h" +#import "StringUtilities.h" #import "TextChecker.h" #import "WebPageMessages.h" #import "WebProcessProxy.h" diff --git a/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm index 30e2e2087..c5c715437 100644 --- a/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm +++ b/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm @@ -29,6 +29,7 @@ #import "NativeWebMouseEvent.h" #import "PageClientImpl.h" #import "PlatformPopupMenuData.h" +#import "StringUtilities.h" #import "WKView.h" #import "WebPopupItem.h" #import <WebKitSystemInterface.h> diff --git a/Source/WebKit2/UIProcess/mac/WebPreferencesMac.mm b/Source/WebKit2/UIProcess/mac/WebPreferencesMac.mm index f2f41d331..6fd41d389 100644 --- a/Source/WebKit2/UIProcess/mac/WebPreferencesMac.mm +++ b/Source/WebKit2/UIProcess/mac/WebPreferencesMac.mm @@ -26,7 +26,7 @@ #import "config.h" #import "WebPreferences.h" -#import "PageClientImpl.h" +#import "StringUtilities.h" #import <wtf/text/StringConcatenate.h> namespace WebKit { diff --git a/Source/WebKit2/UIProcess/qt/LayerBackingStore.cpp b/Source/WebKit2/UIProcess/qt/LayerBackingStore.cpp index c6df57efb..d66cc19b7 100644 --- a/Source/WebKit2/UIProcess/qt/LayerBackingStore.cpp +++ b/Source/WebKit2/UIProcess/qt/LayerBackingStore.cpp @@ -20,6 +20,7 @@ #include "config.h" #include "LayerBackingStore.h" +#if USE(UI_SIDE_COMPOSITING) #include "GraphicsLayer.h" #include "TextureMapper.h" @@ -141,3 +142,4 @@ void LayerBackingStore::swapBuffers(TextureMapper* textureMapper) } } +#endif diff --git a/Source/WebKit2/UIProcess/qt/LayerBackingStore.h b/Source/WebKit2/UIProcess/qt/LayerBackingStore.h index e62fcc840..9b9913e38 100644 --- a/Source/WebKit2/UIProcess/qt/LayerBackingStore.h +++ b/Source/WebKit2/UIProcess/qt/LayerBackingStore.h @@ -20,6 +20,7 @@ #ifndef LayerBackingStore_h #define LayerBackingStore_h +#if USE(UI_SIDE_COMPOSITING) #include "HashMap.h" #include "ShareableBitmap.h" #include "TextureMapper.h" @@ -65,4 +66,6 @@ private: }; } +#endif + #endif // LayerBackingStore_h diff --git a/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp b/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp deleted file mode 100644 index ee05eaf41..000000000 --- a/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp +++ /dev/null @@ -1,592 +0,0 @@ -/* - Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if USE(ACCELERATED_COMPOSITING) -#include "LayerTreeHostProxy.h" - -#include "GraphicsLayerTextureMapper.h" -#include "LayerBackingStore.h" -#include "LayerTreeHostMessages.h" -#include "MainThread.h" -#include "MessageID.h" -#include "ShareableBitmap.h" -#include "TextureMapper.h" -#include "TextureMapperBackingStore.h" -#include "TextureMapperLayer.h" -#include "UpdateInfo.h" -#include "WebCoreArgumentCoders.h" -#include "WebLayerTreeInfo.h" -#include "WebPageProxy.h" -#include "WebProcessProxy.h" -#include <OpenGLShims.h> -#include <QDateTime> - -namespace WebKit { - -class LayerTreeMessageToRenderer { -public: - enum Type { - DeleteLayer, - CreateTile, - RemoveTile, - UpdateTile, - CreateImage, - DestroyImage, - SyncLayerParameters, - FlushLayerChanges, - SetRootLayer - }; - virtual ~LayerTreeMessageToRenderer() { } - virtual Type type() const = 0; -}; - -using namespace WebCore; - -template<class MessageData, LayerTreeMessageToRenderer::Type messageType> -class LayerTreeMessageToRendererWithData : public LayerTreeMessageToRenderer { -public: - virtual Type type() const { return messageType; } - - static PassOwnPtr<LayerTreeMessageToRenderer> create(const MessageData& data = MessageData()) - { - return adoptPtr(new LayerTreeMessageToRendererWithData(data)); - } - - const MessageData& data() const - { - return m_data; - } - -private: - LayerTreeMessageToRendererWithData(const MessageData& data) - : m_data(data) - { - } - - MessageData m_data; -}; - - -namespace { -struct CreateTileMessageData { - WebLayerID layerID; - int remoteTileID; - float scale; -}; - -struct UpdateTileMessageData { - WebLayerID layerID; - int remoteTileID; - IntRect sourceRect; - IntRect targetRect; - RefPtr<ShareableBitmap> bitmap; -}; - -struct RemoveTileMessageData { - WebLayerID layerID; - int remoteTileID; -}; - -struct CreateImageMessageData { - int64_t imageID; - RefPtr<ShareableBitmap> bitmap; -}; - -struct DestroyImageMessageData { - int64_t imageID; -}; - -struct SyncLayerParametersMessageData { - WebLayerInfo layerInfo; -}; - -struct EmptyMessageData { }; -struct DeleteLayerMessageData { - WebLayerID layerID; -}; -struct SetRootLayerMessageData { - WebLayerID layerID; -}; - -class CreateTileMessage - : public LayerTreeMessageToRendererWithData<CreateTileMessageData, LayerTreeMessageToRenderer::CreateTile> { }; -class UpdateTileMessage - : public LayerTreeMessageToRendererWithData<UpdateTileMessageData, LayerTreeMessageToRenderer::UpdateTile> { }; -class RemoveTileMessage - : public LayerTreeMessageToRendererWithData<RemoveTileMessageData, LayerTreeMessageToRenderer::RemoveTile> { }; -class CreateImageMessage - : public LayerTreeMessageToRendererWithData<CreateImageMessageData, LayerTreeMessageToRenderer::CreateImage> { }; -class DestroyImageMessage - : public LayerTreeMessageToRendererWithData<DestroyImageMessageData, LayerTreeMessageToRenderer::DestroyImage> { }; -class FlushLayerChangesMessage - : public LayerTreeMessageToRendererWithData<EmptyMessageData, LayerTreeMessageToRenderer::FlushLayerChanges> { }; -class SyncLayerParametersMessage - : public LayerTreeMessageToRendererWithData<SyncLayerParametersMessageData, LayerTreeMessageToRenderer::SyncLayerParameters> { }; -class DeleteLayerMessage - : public LayerTreeMessageToRendererWithData<DeleteLayerMessageData, LayerTreeMessageToRenderer::DeleteLayer> { }; -class SetRootLayerMessage - : public LayerTreeMessageToRendererWithData<SetRootLayerMessageData, LayerTreeMessageToRenderer::SetRootLayer> { }; -} - -PassOwnPtr<GraphicsLayer> LayerTreeHostProxy::createLayer(WebLayerID layerID) -{ - GraphicsLayer* newLayer = new GraphicsLayerTextureMapper(this); - TextureMapperLayer* layer = toTextureMapperLayer(newLayer); - layer->setShouldUpdateBackingStoreFromLayer(false); - return adoptPtr(newLayer); -} - -LayerTreeHostProxy::LayerTreeHostProxy(DrawingAreaProxy* drawingAreaProxy) - : m_drawingAreaProxy(drawingAreaProxy) - , m_rootLayerID(0) -{ -} - -LayerTreeHostProxy::~LayerTreeHostProxy() -{ -} - -// This function needs to be reentrant. -void LayerTreeHostProxy::paintToCurrentGLContext(const TransformationMatrix& matrix, float opacity, const FloatRect& clipRect) -{ - if (!m_textureMapper) - m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode); - ASSERT(m_textureMapper->accelerationMode() == TextureMapper::OpenGLMode); - - syncRemoteContent(); - GraphicsLayer* currentRootLayer = rootLayer(); - if (!currentRootLayer) - return; - - TextureMapperLayer* layer = toTextureMapperLayer(currentRootLayer); - - if (!layer) - return; - - layer->setTextureMapper(m_textureMapper.get()); - m_textureMapper->beginPainting(); - m_textureMapper->bindSurface(0); - m_textureMapper->beginClip(TransformationMatrix(), clipRect); - - if (currentRootLayer->opacity() != opacity || currentRootLayer->transform() != matrix) { - currentRootLayer->setOpacity(opacity); - currentRootLayer->setTransform(matrix); - currentRootLayer->syncCompositingStateForThisLayerOnly(); - } - - layer->paint(); - m_textureMapper->endClip(); - m_textureMapper->endPainting(); - - syncAnimations(); -} - -void LayerTreeHostProxy::syncAnimations() -{ - TextureMapperLayer* layer = toTextureMapperLayer(rootLayer()); - ASSERT(layer); - - layer->syncAnimationsRecursively(); - if (layer->descendantsOrSelfHaveRunningAnimations()) - updateViewport(); -} - -void LayerTreeHostProxy::paintToGraphicsContext(QPainter* painter) -{ - if (!m_textureMapper) - m_textureMapper = TextureMapper::create(); - ASSERT(m_textureMapper->accelerationMode() == TextureMapper::SoftwareMode); - syncRemoteContent(); - TextureMapperLayer* layer = toTextureMapperLayer(rootLayer()); - - if (!layer) - return; - - GraphicsContext graphicsContext(painter); - m_textureMapper->setGraphicsContext(&graphicsContext); - m_textureMapper->beginPainting(); - m_textureMapper->bindSurface(0); - layer->paint(); - m_textureMapper->endPainting(); - m_textureMapper->setGraphicsContext(0); -} - -void LayerTreeHostProxy::updateViewport() -{ - m_drawingAreaProxy->updateViewport(); -} - -void LayerTreeHostProxy::syncLayerParameters(const WebLayerInfo& layerInfo) -{ - WebLayerID id = layerInfo.id; - ensureLayer(id); - LayerMap::iterator it = m_layers.find(id); - GraphicsLayer* layer = it->second; - bool needsToUpdateImageTiles = layerInfo.imageIsUpdated || (layerInfo.contentsRect != layer->contentsRect() && layerInfo.imageBackingStoreID); - - layer->setName(layerInfo.name); - - layer->setReplicatedByLayer(layerByID(layerInfo.replica)); - layer->setMaskLayer(layerByID(layerInfo.mask)); - - layer->setPosition(layerInfo.pos); - layer->setSize(layerInfo.size); - layer->setTransform(layerInfo.transform); - layer->setAnchorPoint(layerInfo.anchorPoint); - layer->setChildrenTransform(layerInfo.childrenTransform); - layer->setBackfaceVisibility(layerInfo.backfaceVisible); - layer->setContentsOpaque(layerInfo.contentsOpaque); - layer->setContentsRect(layerInfo.contentsRect); - layer->setDrawsContent(layerInfo.drawsContent); - - if (needsToUpdateImageTiles) - assignImageToLayer(layer, layerInfo.imageBackingStoreID); - - // Never make the root layer clip. - layer->setMasksToBounds(layerInfo.isRootLayer ? false : layerInfo.masksToBounds); - layer->setOpacity(layerInfo.opacity); - layer->setPreserves3D(layerInfo.preserves3D); - Vector<GraphicsLayer*> children; - - for (size_t i = 0; i < layerInfo.children.size(); ++i) { - WebLayerID childID = layerInfo.children[i]; - GraphicsLayer* child = layerByID(childID); - if (!child) { - child = createLayer(childID).leakPtr(); - m_layers.add(childID, child); - } - children.append(child); - } - layer->setChildren(children); - - for (size_t i = 0; i < layerInfo.animations.size(); ++i) { - const WebKit::WebLayerAnimation anim = layerInfo.animations[i]; - - switch (anim.operation) { - case WebKit::WebLayerAnimation::AddAnimation: { - const IntSize boxSize = anim.boxSize; - layer->addAnimation(anim.keyframeList, boxSize, anim.animation.get(), anim.name, anim.startTime); - break; - } - case WebKit::WebLayerAnimation::RemoveAnimation: - layer->removeAnimation(anim.name); - break; - case WebKit::WebLayerAnimation::PauseAnimation: - double offset = WTF::currentTime() - anim.startTime; - layer->pauseAnimation(anim.name, offset); - break; - } - } - - if (layerInfo.isRootLayer && m_rootLayerID != id) - setRootLayerID(id); -} - -void LayerTreeHostProxy::deleteLayer(WebLayerID layerID) -{ - GraphicsLayer* layer = layerByID(layerID); - if (!layer) - return; - - layer->removeFromParent(); - m_layers.remove(layerID); - delete layer; -} - - -void LayerTreeHostProxy::ensureLayer(WebLayerID id) -{ - // We have to leak the new layer's pointer and manage it ourselves, - // because OwnPtr is not copyable. - if (m_layers.find(id) == m_layers.end()) - m_layers.add(id, createLayer(id).leakPtr()); -} - -void LayerTreeHostProxy::setRootLayerID(WebLayerID layerID) -{ - if (layerID == m_rootLayerID) - return; - - m_rootLayerID = layerID; - - m_rootLayer->removeAllChildren(); - - if (!layerID) - return; - - GraphicsLayer* layer = layerByID(layerID); - if (!layer) - return; - - m_rootLayer->addChild(layer); -} - -PassRefPtr<LayerBackingStore> LayerTreeHostProxy::getBackingStore(WebLayerID id) -{ - ensureLayer(id); - TextureMapperLayer* layer = toTextureMapperLayer(layerByID(id)); - RefPtr<LayerBackingStore> backingStore = static_cast<LayerBackingStore*>(layer->backingStore().get()); - if (!backingStore) { - backingStore = LayerBackingStore::create(); - layer->setBackingStore(backingStore.get()); - } - ASSERT(backingStore); - return backingStore; -} - -void LayerTreeHostProxy::createTile(WebLayerID layerID, int tileID, float scale) -{ - getBackingStore(layerID)->createTile(tileID, scale); -} - -void LayerTreeHostProxy::removeTile(WebLayerID layerID, int tileID) -{ - getBackingStore(layerID)->removeTile(tileID); -} - -void LayerTreeHostProxy::updateTile(WebLayerID layerID, int tileID, const IntRect& sourceRect, const IntRect& targetRect, ShareableBitmap* bitmap) -{ - RefPtr<LayerBackingStore> backingStore = getBackingStore(layerID); - backingStore->updateTile(tileID, sourceRect, targetRect, bitmap); - m_backingStoresWithPendingBuffers.add(backingStore); -} - -void LayerTreeHostProxy::createImage(int64_t imageID, ShareableBitmap* bitmap) -{ - RefPtr<TextureMapperTiledBackingStore> backingStore = TextureMapperTiledBackingStore::create(); - backingStore->updateContents(m_textureMapper.get(), bitmap->createImage().get(), BitmapTexture::BGRAFormat); - m_directlyCompositedImages.set(imageID, backingStore); -} - -void LayerTreeHostProxy::destroyImage(int64_t imageID) -{ - m_directlyCompositedImages.remove(imageID); -} - -void LayerTreeHostProxy::assignImageToLayer(GraphicsLayer* layer, int64_t imageID) -{ - HashMap<int64_t, RefPtr<TextureMapperBackingStore> >::iterator it = m_directlyCompositedImages.find(imageID); - ASSERT(it != m_directlyCompositedImages.end()); - layer->setContentsToMedia(it->second.get()); -} - -void LayerTreeHostProxy::swapBuffers() -{ - HashSet<RefPtr<LayerBackingStore> >::iterator end = m_backingStoresWithPendingBuffers.end(); - for (HashSet<RefPtr<LayerBackingStore> >::iterator it = m_backingStoresWithPendingBuffers.begin(); it != end; ++it) - (*it)->swapBuffers(m_textureMapper.get()); - - m_backingStoresWithPendingBuffers.clear(); -} - -void LayerTreeHostProxy::flushLayerChanges() -{ - m_rootLayer->syncCompositingState(FloatRect()); - swapBuffers(); - - // The pending tiles state is on its way for the screen, tell the web process to render the next one. - m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::RenderNextFrame(), m_drawingAreaProxy->page()->pageID()); -} - -void LayerTreeHostProxy::ensureRootLayer() -{ - if (m_rootLayer) - return; - m_rootLayer = createLayer(InvalidWebLayerID); - m_rootLayer->setMasksToBounds(false); - m_rootLayer->setDrawsContent(false); - m_rootLayer->setAnchorPoint(FloatPoint3D(0, 0, 0)); - - // The root layer should not have zero size, or it would be optimized out. - m_rootLayer->setSize(FloatSize(1.0, 1.0)); - if (!m_textureMapper) - m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode); - toTextureMapperLayer(m_rootLayer.get())->setTextureMapper(m_textureMapper.get()); -} - -void LayerTreeHostProxy::syncRemoteContent() -{ - // We enqueue messages and execute them during paint, as they require an active GL context. - ensureRootLayer(); - - while (OwnPtr<LayerTreeMessageToRenderer> nextMessage = m_messagesToRenderer.tryGetMessage()) { - switch (nextMessage->type()) { - case LayerTreeMessageToRenderer::SetRootLayer: { - const SetRootLayerMessageData& data = static_cast<SetRootLayerMessage*>(nextMessage.get())->data(); - setRootLayerID(data.layerID); - break; - } - - case LayerTreeMessageToRenderer::DeleteLayer: { - const DeleteLayerMessageData& data = static_cast<DeleteLayerMessage*>(nextMessage.get())->data(); - deleteLayer(data.layerID); - break; - } - - case LayerTreeMessageToRenderer::SyncLayerParameters: { - const SyncLayerParametersMessageData& data = static_cast<SyncLayerParametersMessage*>(nextMessage.get())->data(); - syncLayerParameters(data.layerInfo); - break; - } - - case LayerTreeMessageToRenderer::CreateTile: { - const CreateTileMessageData& data = static_cast<CreateTileMessage*>(nextMessage.get())->data(); - createTile(data.layerID, data.remoteTileID, data.scale); - break; - } - - case LayerTreeMessageToRenderer::RemoveTile: { - const RemoveTileMessageData& data = static_cast<RemoveTileMessage*>(nextMessage.get())->data(); - removeTile(data.layerID, data.remoteTileID); - break; - } - - case LayerTreeMessageToRenderer::UpdateTile: { - const UpdateTileMessageData& data = static_cast<UpdateTileMessage*>(nextMessage.get())->data(); - updateTile(data.layerID, data.remoteTileID, data.sourceRect, data.targetRect, data.bitmap.get()); - break; - } - - case LayerTreeMessageToRenderer::CreateImage: { - const CreateImageMessageData& data = static_cast<CreateImageMessage*>(nextMessage.get())->data(); - createImage(data.imageID, data.bitmap.get()); - break; - } - - case LayerTreeMessageToRenderer::DestroyImage: { - const DestroyImageMessageData& data = static_cast<DestroyImageMessage*>(nextMessage.get())->data(); - destroyImage(data.imageID); - break; - } - - case LayerTreeMessageToRenderer::FlushLayerChanges: - flushLayerChanges(); - break; - } - } -} - -void LayerTreeHostProxy::pushUpdateToQueue(PassOwnPtr<LayerTreeMessageToRenderer> message) -{ - m_messagesToRenderer.append(message); - updateViewport(); -} - -void LayerTreeHostProxy::createTileForLayer(int layerID, int tileID, const WebKit::UpdateInfo& updateInfo) -{ - CreateTileMessageData data; - data.layerID = layerID; - data.remoteTileID = tileID; - data.scale = updateInfo.updateScaleFactor; - pushUpdateToQueue(CreateTileMessage::create(data)); - updateTileForLayer(layerID, tileID, updateInfo); -} - -void LayerTreeHostProxy::updateTileForLayer(int layerID, int tileID, const WebKit::UpdateInfo& updateInfo) -{ - UpdateTileMessageData data; - data.layerID = layerID; - data.remoteTileID = tileID; - data.bitmap = ShareableBitmap::create(updateInfo.bitmapHandle); - ASSERT(updateInfo.updateRects.size() == 1); - data.sourceRect = updateInfo.updateRects.first(); - data.targetRect = updateInfo.updateRectBounds; - pushUpdateToQueue(UpdateTileMessage::create(data)); -} - -void LayerTreeHostProxy::removeTileForLayer(int layerID, int tileID) -{ - RemoveTileMessageData data; - data.layerID = layerID; - data.remoteTileID = tileID; - pushUpdateToQueue(RemoveTileMessage::create(data)); -} - - -void LayerTreeHostProxy::deleteCompositingLayer(WebLayerID id) -{ - DeleteLayerMessageData data; - data.layerID = id; - pushUpdateToQueue(DeleteLayerMessage::create(data)); -} - -void LayerTreeHostProxy::setRootCompositingLayer(WebLayerID id) -{ - SetRootLayerMessageData data; - data.layerID = id; - pushUpdateToQueue(SetRootLayerMessage::create(data)); -} - -void LayerTreeHostProxy::syncCompositingLayerState(const WebLayerInfo& info) -{ - SyncLayerParametersMessageData data; - data.layerInfo = info; - pushUpdateToQueue(SyncLayerParametersMessage::create(data)); -} - -void LayerTreeHostProxy::didRenderFrame() -{ - pushUpdateToQueue(FlushLayerChangesMessage::create()); - updateViewport(); -} - -void LayerTreeHostProxy::createDirectlyCompositedImage(int64_t key, const WebKit::ShareableBitmap::Handle& handle) -{ - CreateImageMessageData data; - data.imageID = key; - data.bitmap = ShareableBitmap::create(handle); - pushUpdateToQueue(CreateImageMessage::create(data)); -} - -void LayerTreeHostProxy::destroyDirectlyCompositedImage(int64_t key) -{ - DestroyImageMessageData data; - data.imageID = key; - pushUpdateToQueue(DestroyImageMessage::create(data)); -} - -void LayerTreeHostProxy::setVisibleContentsRectForPanning(const IntRect& rect, const FloatPoint& trajectoryVector) -{ - m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::SetVisibleContentsRectForPanning(rect, trajectoryVector), m_drawingAreaProxy->page()->pageID()); -} - -void LayerTreeHostProxy::setVisibleContentsRectForScaling(const IntRect& rect, float scale) -{ - m_visibleContentsRect = rect; - m_contentsScale = scale; - m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::SetVisibleContentsRectForScaling(rect, scale), m_drawingAreaProxy->page()->pageID()); -} - -void LayerTreeHostProxy::purgeGLResources() -{ - TextureMapperLayer* layer = toTextureMapperLayer(rootLayer()); - - if (layer) - layer->clearBackingStoresRecursive(); - - m_directlyCompositedImages.clear(); - m_textureMapper.clear(); - m_backingStoresWithPendingBuffers.clear(); - m_drawingAreaProxy->page()->process()->send(Messages::LayerTreeHost::PurgeBackingStores(), m_drawingAreaProxy->page()->pageID()); -} - -} -#endif diff --git a/Source/WebKit2/UIProcess/qt/QtFlickProvider.cpp b/Source/WebKit2/UIProcess/qt/QtFlickProvider.cpp index 3760c0cfb..b34bba642 100644 --- a/Source/WebKit2/UIProcess/qt/QtFlickProvider.cpp +++ b/Source/WebKit2/UIProcess/qt/QtFlickProvider.cpp @@ -26,7 +26,9 @@ #include <QCoreApplication> #include <QDeclarativeEngine> +#include <QMouseEvent> #include <QPointF> +#include <QQuickCanvas> #include <QQuickItem> #include <QTouchEvent> #include <wtf/Assertions.h> @@ -106,7 +108,8 @@ QtFlickProvider::QtFlickProvider(QQuickWebView* viewItem, QQuickWebPage* pageIte pageItem->setParentItem(m_contentItem); // Propagate flickable signals. - connect(m_flickable, SIGNAL(movingChanged()), SIGNAL(movingChanged()), Qt::DirectConnection); + connect(m_flickable, SIGNAL(movementStarted()), SIGNAL(movementStarted()), Qt::DirectConnection); + connect(m_flickable, SIGNAL(movementEnded()), SIGNAL(movementEnded()), Qt::DirectConnection); connect(m_flickable, SIGNAL(flickingChanged()), SIGNAL(flickingChanged()), Qt::DirectConnection); connect(m_flickable, SIGNAL(draggingChanged()), SIGNAL(draggingChanged()), Qt::DirectConnection); connect(m_flickable, SIGNAL(contentWidthChanged()), SIGNAL(contentWidthChanged()), Qt::DirectConnection); @@ -115,9 +118,42 @@ QtFlickProvider::QtFlickProvider(QQuickWebView* viewItem, QQuickWebPage* pageIte connect(m_flickable, SIGNAL(contentYChanged()), SIGNAL(contentYChanged()), Qt::DirectConnection); } -void QtFlickProvider::handleTouchFlickEvent(QTouchEvent* event) +void QtFlickProvider::handleTouchFlickEvent(QTouchEvent* touchEvent) { - QCoreApplication::sendEvent(m_flickable, event); + // Since the Flickable does not handle touch events directly the sent + // touch event would end up in the WebView again and would thus trigger + // an infinite loop. + // Hence do the touch to mouse event conversion for the Flickable here. + QEvent::Type mouseEventType = QEvent::None; + Qt::MouseButton mouseButton = Qt::NoButton; + + switch (touchEvent->type()) { + case QEvent::TouchBegin: + mouseEventType = QEvent::MouseButtonPress; + + // We need to set the mouse button so that the Flickable + // item receives the initial mouse press event. + mouseButton = Qt::LeftButton; + break; + case QEvent::TouchUpdate: + mouseEventType = QEvent::MouseMove; + break; + case QEvent::TouchEnd: + mouseEventType = QEvent::MouseButtonRelease; + break; + default: + ASSERT_NOT_REACHED(); + break; + } + + QPointF touchPosition = touchEvent->touchPoints().last().pos(); + QMouseEvent mouseEvent(mouseEventType, touchPosition, mouseButton, mouseButton, Qt::NoModifier); + + // Send the event to the canvas and let the canvas propagate it + // to the Flickable. This makes sure that the Flickable grabs + // the mouse so that it also receives the events of gestures + // which started inside the viewport but ended outside of it. + QCoreApplication::sendEvent(m_flickable->canvas(), &mouseEvent); } QQuickItem* QtFlickProvider::contentItem() diff --git a/Source/WebKit2/UIProcess/qt/QtFlickProvider.h b/Source/WebKit2/UIProcess/qt/QtFlickProvider.h index f388a0b4b..275810bbf 100644 --- a/Source/WebKit2/UIProcess/qt/QtFlickProvider.h +++ b/Source/WebKit2/UIProcess/qt/QtFlickProvider.h @@ -72,7 +72,8 @@ Q_SIGNALS: void contentHeightChanged(); void contentXChanged(); void contentYChanged(); - void movingChanged(); + void movementStarted(); + void movementEnded(); void flickingChanged(); void draggingChanged(); diff --git a/Source/WebKit2/UIProcess/qt/QtPageClient.cpp b/Source/WebKit2/UIProcess/qt/QtPageClient.cpp index 8d6ebbb03..d7049cb3b 100644 --- a/Source/WebKit2/UIProcess/qt/QtPageClient.cpp +++ b/Source/WebKit2/UIProcess/qt/QtPageClient.cpp @@ -289,3 +289,8 @@ void QtPageClient::exitAcceleratedCompositingMode() // FIXME: Implement. } +void QtPageClient::updateAcceleratedCompositingMode(const LayerTreeContext&) +{ + // FIXME: Implement. +} + diff --git a/Source/WebKit2/UIProcess/qt/QtPageClient.h b/Source/WebKit2/UIProcess/qt/QtPageClient.h index f4ffa18ad..f09db8243 100644 --- a/Source/WebKit2/UIProcess/qt/QtPageClient.h +++ b/Source/WebKit2/UIProcess/qt/QtPageClient.h @@ -65,6 +65,7 @@ public: #if USE(ACCELERATED_COMPOSITING) virtual void enterAcceleratedCompositingMode(const LayerTreeContext&); virtual void exitAcceleratedCompositingMode(); + virtual void updateAcceleratedCompositingMode(const LayerTreeContext&); #endif // USE(ACCELERATED_COMPOSITING) virtual void pageClosed() { } virtual void startDrag(const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage); diff --git a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp index 1787391b7..be17aacbf 100644 --- a/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp +++ b/Source/WebKit2/UIProcess/qt/QtPanGestureRecognizer.cpp @@ -63,6 +63,7 @@ bool QtPanGestureRecognizer::recognize(const QTouchEvent* event) m_state = GestureRecognitionStarted; m_firstPosition = touchPoint.screenPos(); m_touchBegin.reset(new QTouchEvent(*event)); + interactionEngine()->panGestureCancelled(); return false; case QEvent::TouchUpdate: { ASSERT(m_state != NoGesture); diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp index bfec37138..c838767b6 100644 --- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp +++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp @@ -61,13 +61,18 @@ static const int kScaleAnimationDurationMillis = 250; class ViewportUpdateDeferrer { public: - ViewportUpdateDeferrer(QtViewportInteractionEngine* engine) + enum SuspendContentFlag { DeferUpdate, DeferUpdateAndSuspendContent }; + ViewportUpdateDeferrer(QtViewportInteractionEngine* engine, SuspendContentFlag suspendContentFlag = DeferUpdate) : engine(engine) { - if (engine->m_suspendCount++) - return; - - emit engine->contentSuspendRequested(); + engine->m_suspendCount++; + + // There is no need to suspend content for immediate updates + // only during animations or longer gestures. + if (suspendContentFlag == DeferUpdateAndSuspendContent && !engine->m_hasSuspendedContent) { + engine->m_hasSuspendedContent = true; + emit engine->contentSuspendRequested(); + } } ~ViewportUpdateDeferrer() @@ -75,7 +80,10 @@ public: if (--(engine->m_suspendCount)) return; - emit engine->contentResumeRequested(); + if (engine->m_hasSuspendedContent) { + engine->m_hasSuspendedContent = false; + emit engine->contentResumeRequested(); + } // Make sure that tiles all around the viewport will be requested. emit engine->contentWasMoved(QPointF()); @@ -117,6 +125,7 @@ QtViewportInteractionEngine::QtViewportInteractionEngine(QQuickWebView* viewport , m_content(content) , m_flickProvider(flickProvider) , m_suspendCount(0) + , m_hasSuspendedContent(false) , m_hadUserInteraction(false) , m_scaleAnimation(new ScaleAnimation(this)) , m_pinchStartScale(-1) @@ -125,7 +134,8 @@ QtViewportInteractionEngine::QtViewportInteractionEngine(QQuickWebView* viewport connect(m_content, SIGNAL(widthChanged()), SLOT(itemSizeChanged()), Qt::DirectConnection); connect(m_content, SIGNAL(heightChanged()), SLOT(itemSizeChanged()), Qt::DirectConnection); - connect(m_flickProvider, SIGNAL(movingChanged()), SLOT(flickableMovingStateChanged()), Qt::DirectConnection); + connect(m_flickProvider, SIGNAL(movementStarted()), SLOT(flickableMoveStarted()), Qt::DirectConnection); + connect(m_flickProvider, SIGNAL(movementEnded()), SLOT(flickableMoveEnded()), Qt::DirectConnection); connect(m_scaleAnimation, SIGNAL(valueChanged(QVariant)), SLOT(scaleAnimationValueChanged(QVariant)), Qt::DirectConnection); @@ -187,27 +197,19 @@ bool QtViewportInteractionEngine::animateItemRectVisible(const QRectF& itemRect) return true; } -void QtViewportInteractionEngine::flickableMovingStateChanged() -{ - if (m_flickProvider->isMoving()) { - if (m_scrollUpdateDeferrer) - return; // We get the isMoving() signal multiple times. - panMoveStarted(); - } else - panMoveEnded(); -} - -void QtViewportInteractionEngine::panMoveStarted() +void QtViewportInteractionEngine::flickableMoveStarted() { - m_scrollUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this)); + Q_ASSERT(m_flickProvider->isMoving()); + m_scrollUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this, ViewportUpdateDeferrer::DeferUpdateAndSuspendContent)); m_lastScrollPosition = m_flickProvider->contentPos(); connect(m_flickProvider, SIGNAL(contentXChanged()), SLOT(flickableMovingPositionUpdate())); connect(m_flickProvider, SIGNAL(contentYChanged()), SLOT(flickableMovingPositionUpdate())); } -void QtViewportInteractionEngine::panMoveEnded() +void QtViewportInteractionEngine::flickableMoveEnded() { + Q_ASSERT(!m_flickProvider->isMoving()); // This method is called on the end of the pan or pan kinetic animation. m_scrollUpdateDeferrer.clear(); @@ -230,7 +232,7 @@ void QtViewportInteractionEngine::scaleAnimationStateChanged(QAbstractAnimation: switch (newState) { case QAbstractAnimation::Running: if (!m_scaleUpdateDeferrer) - m_scaleUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this)); + m_scaleUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this, ViewportUpdateDeferrer::DeferUpdateAndSuspendContent)); break; case QAbstractAnimation::Stopped: m_scaleUpdateDeferrer.clear(); @@ -507,7 +509,7 @@ void QtViewportInteractionEngine::pinchGestureStarted(const QPointF& pinchCenter m_hadUserInteraction = true; - m_scaleUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this)); + m_scaleUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this, ViewportUpdateDeferrer::DeferUpdateAndSuspendContent)); m_lastPinchCenterInViewportCoordinates = pinchCenterInViewportCoordinates; m_pinchStartScale = m_content->contentsScale(); diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h index 9419be0f6..017c307cd 100644 --- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h +++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h @@ -113,12 +113,14 @@ private Q_SLOTS: // Respond to changes of content that are not driven by us, like the page resizing itself. void itemSizeChanged(); - void flickableMovingStateChanged(); void flickableMovingPositionUpdate(); void scaleAnimationStateChanged(QAbstractAnimation::State, QAbstractAnimation::State); void scaleAnimationValueChanged(QVariant value) { setItemRectVisible(value.toRectF()); } + void flickableMoveStarted(); // Called when panning starts. + void flickableMoveEnded(); // Called when panning (+ kinetic animation) ends. + private: friend class ViewportUpdateDeferrer; @@ -130,9 +132,6 @@ private: qreal innerBoundedCSSScale(qreal); qreal outerBoundedCSSScale(qreal); - void panMoveStarted(); // Called when panning starts. - void panMoveEnded(); // Called when panning (+ kinetic animation) ends. - QRectF computePosRangeForItemAtScale(qreal itemScale) const; bool ensureContentWithinViewportBoundary(bool immediate = false); @@ -146,6 +145,7 @@ private: Constraints m_constraints; int m_suspendCount; + bool m_hasSuspendedContent; OwnPtr<ViewportUpdateDeferrer> m_scaleUpdateDeferrer; OwnPtr<ViewportUpdateDeferrer> m_scrollUpdateDeferrer; diff --git a/Source/WebKit2/UIProcess/qt/QtWebContext.cpp b/Source/WebKit2/UIProcess/qt/QtWebContext.cpp index df27961b5..a800fef15 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebContext.cpp +++ b/Source/WebKit2/UIProcess/qt/QtWebContext.cpp @@ -45,9 +45,11 @@ static HashMap<uint64_t, QtWebContext*> contextMap; QtWebContext* QtWebContext::s_defaultContext = 0; QtWebContext::QtWebContext(WebContext* context) - : m_context(context) + : m_contextID(generateContextID()) + , m_context(context) + , m_downloadManager(adoptPtr(new QtDownloadManager(context))) + , m_iconDatabase(adoptPtr(new QtWebIconDatabaseClient(this))) { - m_contextID = generateContextID(); contextMap.set(m_contextID, this); } @@ -72,7 +74,8 @@ PassRefPtr<QtWebContext> QtWebContext::defaultContext() RefPtr<WebContext> context = WebContext::sharedProcessContext(); RefPtr<QtWebContext> defaultContext = QtWebContext::create(context.get()); s_defaultContext = defaultContext.get(); - defaultContext->initialize(); + // Make sure that this doesn't get called in WebKitTestRunner (defaultContext isn't used there). + defaultContext->initializeContextInjectedBundleClient(); return defaultContext.release(); } @@ -107,13 +110,6 @@ QtWebContext* QtWebContext::contextByID(uint64_t id) return contextMap.get(id); } -void QtWebContext::initialize() -{ - m_downloadManager = adoptPtr(new QtDownloadManager(m_context.get())); - m_iconDatabase = adoptPtr(new QtWebIconDatabaseClient(this)); - initializeContextInjectedBundleClient(); -} - void QtWebContext::initializeContextInjectedBundleClient() { WKContextInjectedBundleClient injectedBundleClient; diff --git a/Source/WebKit2/UIProcess/qt/QtWebContext.h b/Source/WebKit2/UIProcess/qt/QtWebContext.h index 202db2242..7703db459 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebContext.h +++ b/Source/WebKit2/UIProcess/qt/QtWebContext.h @@ -63,7 +63,6 @@ public: private: explicit QtWebContext(WebContext*); - void initialize(); void initializeContextInjectedBundleClient(); static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, const void*); diff --git a/Source/WebKit2/UIProcess/qt/QtWebError.h b/Source/WebKit2/UIProcess/qt/QtWebError.h index 3bd7bd508..3fe9eb906 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebError.h +++ b/Source/WebKit2/UIProcess/qt/QtWebError.h @@ -34,6 +34,7 @@ QT_END_NAMESPACE class QtWebError { public: enum Type { + NoError, InternalError, NetworkError, HttpError, diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp index 7d089929a..95ed43191 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp +++ b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp @@ -106,57 +106,7 @@ QtWebPageEventHandler::~QtWebPageEventHandler() disconnect(qApp->inputPanel(), SIGNAL(visibleChanged()), this, SLOT(inputPanelVisibleChanged())); } -bool QtWebPageEventHandler::handleEvent(QEvent* ev) -{ - switch (ev->type()) { - case QEvent::MouseMove: - return handleMouseMoveEvent(static_cast<QMouseEvent*>(ev)); - case QEvent::MouseButtonPress: - case QEvent::MouseButtonDblClick: - // If a MouseButtonDblClick was received then we got a MouseButtonPress before - // handleMousePressEvent will take care of double clicks. - return handleMousePressEvent(static_cast<QMouseEvent*>(ev)); - case QEvent::MouseButtonRelease: - return handleMouseReleaseEvent(static_cast<QMouseEvent*>(ev)); - case QEvent::Wheel: - return handleWheelEvent(static_cast<QWheelEvent*>(ev)); - case QEvent::HoverLeave: - return handleHoverLeaveEvent(static_cast<QHoverEvent*>(ev)); - case QEvent::HoverEnter: // Fall-through, for WebKit the distinction doesn't matter. - case QEvent::HoverMove: - return handleHoverMoveEvent(static_cast<QHoverEvent*>(ev)); - case QEvent::DragEnter: - return handleDragEnterEvent(static_cast<QDragEnterEvent*>(ev)); - case QEvent::DragLeave: - return handleDragLeaveEvent(static_cast<QDragLeaveEvent*>(ev)); - case QEvent::DragMove: - return handleDragMoveEvent(static_cast<QDragMoveEvent*>(ev)); - case QEvent::Drop: - return handleDropEvent(static_cast<QDropEvent*>(ev)); - case QEvent::KeyPress: - return handleKeyPressEvent(static_cast<QKeyEvent*>(ev)); - case QEvent::KeyRelease: - return handleKeyReleaseEvent(static_cast<QKeyEvent*>(ev)); - case QEvent::FocusIn: - return handleFocusInEvent(static_cast<QFocusEvent*>(ev)); - case QEvent::FocusOut: - return handleFocusOutEvent(static_cast<QFocusEvent*>(ev)); - case QEvent::TouchBegin: - case QEvent::TouchEnd: - case QEvent::TouchCancel: - case QEvent::TouchUpdate: - touchEvent(static_cast<QTouchEvent*>(ev)); - return true; - case QEvent::InputMethod: - inputMethodEvent(static_cast<QInputMethodEvent*>(ev)); - return false; // This is necessary to avoid an endless loop in connection with QQuickItem::event(). - } - - // FIXME: Move all common event handling here. - return false; -} - -bool QtWebPageEventHandler::handleMouseMoveEvent(QMouseEvent* ev) +void QtWebPageEventHandler::handleMouseMoveEvent(QMouseEvent* ev) { // For some reason mouse press results in mouse hover (which is // converted to mouse move for WebKit). We ignore these hover @@ -167,15 +117,13 @@ bool QtWebPageEventHandler::handleMouseMoveEvent(QMouseEvent* ev) QTransform fromItemTransform = m_webPage->transformFromItem(); QPointF webPagePoint = fromItemTransform.map(ev->localPos()); if (lastPos == webPagePoint) - return ev->isAccepted(); + return; lastPos = webPagePoint; m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, fromItemTransform, /*eventClickCount*/ 0)); - - return ev->isAccepted(); } -bool QtWebPageEventHandler::handleMousePressEvent(QMouseEvent* ev) +void QtWebPageEventHandler::handleMousePressEvent(QMouseEvent* ev) { QTransform fromItemTransform = m_webPage->transformFromItem(); QPointF webPagePoint = fromItemTransform.map(ev->localPos()); @@ -193,48 +141,43 @@ bool QtWebPageEventHandler::handleMousePressEvent(QMouseEvent* ev) m_lastClick = webPagePoint; m_clickTimer.start(qApp->styleHints()->mouseDoubleClickInterval(), this); - - return ev->isAccepted(); } -bool QtWebPageEventHandler::handleMouseReleaseEvent(QMouseEvent* ev) +void QtWebPageEventHandler::handleMouseReleaseEvent(QMouseEvent* ev) { QTransform fromItemTransform = m_webPage->transformFromItem(); m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, fromItemTransform, /*eventClickCount*/ 0)); - return ev->isAccepted(); } -bool QtWebPageEventHandler::handleWheelEvent(QWheelEvent* ev) +void QtWebPageEventHandler::handleWheelEvent(QWheelEvent* ev) { QTransform fromItemTransform = m_webPage->transformFromItem(); m_webPageProxy->handleWheelEvent(NativeWebWheelEvent(ev, fromItemTransform)); // FIXME: Handle whether the page used the wheel event or not. if (m_interactionEngine) m_interactionEngine->wheelEvent(ev); - return ev->isAccepted(); } -bool QtWebPageEventHandler::handleHoverLeaveEvent(QHoverEvent* ev) +void QtWebPageEventHandler::handleHoverLeaveEvent(QHoverEvent* ev) { // To get the correct behavior of mouseout, we need to turn the Leave event of our webview into a mouse move // to a very far region. QTransform fromItemTransform = m_webPage->transformFromItem(); QHoverEvent fakeEvent(QEvent::HoverMove, QPoint(INT_MIN, INT_MIN), fromItemTransform.map(ev->oldPosF())); fakeEvent.setTimestamp(ev->timestamp()); - return handleHoverMoveEvent(&fakeEvent); + handleHoverMoveEvent(&fakeEvent); } -bool QtWebPageEventHandler::handleHoverMoveEvent(QHoverEvent* ev) +void QtWebPageEventHandler::handleHoverMoveEvent(QHoverEvent* ev) { QTransform fromItemTransform = m_webPage->transformFromItem(); QMouseEvent me(QEvent::MouseMove, fromItemTransform.map(ev->posF()), Qt::NoButton, Qt::NoButton, Qt::NoModifier); me.setAccepted(ev->isAccepted()); me.setTimestamp(ev->timestamp()); - - return handleMouseMoveEvent(&me); + handleMouseMoveEvent(&me); } -bool QtWebPageEventHandler::handleDragEnterEvent(QDragEnterEvent* ev) +void QtWebPageEventHandler::handleDragEnterEvent(QDragEnterEvent* ev) { m_webPageProxy->resetDragOperation(); QTransform fromItemTransform = m_webPage->transformFromItem(); @@ -242,10 +185,9 @@ bool QtWebPageEventHandler::handleDragEnterEvent(QDragEnterEvent* ev) DragData dragData(ev->mimeData(), fromItemTransform.map(ev->pos()), QCursor::pos(), dropActionToDragOperation(ev->possibleActions())); m_webPageProxy->dragEntered(&dragData); ev->acceptProposedAction(); - return true; } -bool QtWebPageEventHandler::handleDragLeaveEvent(QDragLeaveEvent* ev) +void QtWebPageEventHandler::handleDragLeaveEvent(QDragLeaveEvent* ev) { bool accepted = ev->isAccepted(); @@ -255,10 +197,9 @@ bool QtWebPageEventHandler::handleDragLeaveEvent(QDragLeaveEvent* ev) m_webPageProxy->resetDragOperation(); ev->setAccepted(accepted); - return accepted; } -bool QtWebPageEventHandler::handleDragMoveEvent(QDragMoveEvent* ev) +void QtWebPageEventHandler::handleDragMoveEvent(QDragMoveEvent* ev) { bool accepted = ev->isAccepted(); @@ -271,10 +212,9 @@ bool QtWebPageEventHandler::handleDragMoveEvent(QDragMoveEvent* ev) ev->accept(); ev->setAccepted(accepted); - return accepted; } -bool QtWebPageEventHandler::handleDropEvent(QDropEvent* ev) +void QtWebPageEventHandler::handleDropEvent(QDropEvent* ev) { bool accepted = ev->isAccepted(); QTransform fromItemTransform = m_webPage->transformFromItem(); @@ -286,7 +226,6 @@ bool QtWebPageEventHandler::handleDropEvent(QDropEvent* ev) ev->accept(); ev->setAccepted(accepted); - return accepted; } void QtWebPageEventHandler::handlePotentialSingleTapEvent(const QTouchEvent::TouchPoint& point) @@ -319,28 +258,24 @@ void QtWebPageEventHandler::timerEvent(QTimerEvent* ev) QObject::timerEvent(ev); } -bool QtWebPageEventHandler::handleKeyPressEvent(QKeyEvent* ev) +void QtWebPageEventHandler::handleKeyPressEvent(QKeyEvent* ev) { m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(ev)); - return true; } -bool QtWebPageEventHandler::handleKeyReleaseEvent(QKeyEvent* ev) +void QtWebPageEventHandler::handleKeyReleaseEvent(QKeyEvent* ev) { m_webPageProxy->handleKeyboardEvent(NativeWebKeyboardEvent(ev)); - return true; } -bool QtWebPageEventHandler::handleFocusInEvent(QFocusEvent*) +void QtWebPageEventHandler::handleFocusInEvent(QFocusEvent*) { m_webPageProxy->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive); - return true; } -bool QtWebPageEventHandler::handleFocusOutEvent(QFocusEvent*) +void QtWebPageEventHandler::handleFocusOutEvent(QFocusEvent*) { m_webPageProxy->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive); - return true; } void QtWebPageEventHandler::setViewportInteractionEngine(QtViewportInteractionEngine* engine) @@ -348,7 +283,7 @@ void QtWebPageEventHandler::setViewportInteractionEngine(QtViewportInteractionEn m_interactionEngine = engine; } -void QtWebPageEventHandler::inputMethodEvent(QInputMethodEvent* ev) +void QtWebPageEventHandler::handleInputMethodEvent(QInputMethodEvent* ev) { QString commit = ev->commitString(); QString composition = ev->preeditString(); @@ -415,7 +350,7 @@ void QtWebPageEventHandler::inputMethodEvent(QInputMethodEvent* ev) ev->accept(); } -void QtWebPageEventHandler::touchEvent(QTouchEvent* event) +void QtWebPageEventHandler::handleTouchEvent(QTouchEvent* event) { #if ENABLE(TOUCH_EVENTS) QTransform fromItemTransform = m_webPage->transformFromItem(); diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h index ebe95dd8d..519ec5471 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h +++ b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h @@ -43,7 +43,22 @@ public: QtWebPageEventHandler(WKPageRef, QQuickWebPage*, QQuickWebView*); ~QtWebPageEventHandler(); - bool handleEvent(QEvent*); + void handleKeyPressEvent(QKeyEvent*); + void handleKeyReleaseEvent(QKeyEvent*); + void handleFocusInEvent(QFocusEvent*); + void handleFocusOutEvent(QFocusEvent*); + void handleMouseMoveEvent(QMouseEvent*); + void handleMousePressEvent(QMouseEvent*); + void handleMouseReleaseEvent(QMouseEvent*); + void handleWheelEvent(QWheelEvent*); + void handleHoverLeaveEvent(QHoverEvent*); + void handleHoverMoveEvent(QHoverEvent*); + void handleDragEnterEvent(QDragEnterEvent*); + void handleDragLeaveEvent(QDragLeaveEvent*); + void handleDragMoveEvent(QDragMoveEvent*); + void handleDropEvent(QDropEvent*); + void handleInputMethodEvent(QInputMethodEvent*); + void handleTouchEvent(QTouchEvent*); void setViewportInteractionEngine(QtViewportInteractionEngine*); @@ -74,26 +89,8 @@ private slots: void inputPanelVisibleChanged(); private: - bool handleKeyPressEvent(QKeyEvent*); - bool handleKeyReleaseEvent(QKeyEvent*); - bool handleFocusInEvent(QFocusEvent*); - bool handleFocusOutEvent(QFocusEvent*); - bool handleMouseMoveEvent(QMouseEvent*); - bool handleMousePressEvent(QMouseEvent*); - bool handleMouseReleaseEvent(QMouseEvent*); - bool handleWheelEvent(QWheelEvent*); - bool handleHoverLeaveEvent(QHoverEvent*); - bool handleHoverMoveEvent(QHoverEvent*); - bool handleDragEnterEvent(QDragEnterEvent*); - bool handleDragLeaveEvent(QDragLeaveEvent*); - bool handleDragMoveEvent(QDragMoveEvent*); - bool handleDropEvent(QDropEvent*); - void timerEvent(QTimerEvent*); - void touchEvent(QTouchEvent*); - void inputMethodEvent(QInputMethodEvent*); - QPointF m_lastClick; QBasicTimer m_clickTimer; Qt::MouseButton m_previousClickButton; diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp b/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp index 2601f4802..de22a9fb3 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp +++ b/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.cpp @@ -24,6 +24,7 @@ #include "WKStringQt.h" #include "qquickwebview_p.h" #include "qquickwebview_p_p.h" +#include "qwebloadrequest_p.h" #include <WKFrame.h> QtWebPageLoadClient::QtWebPageLoadClient(WKPageRef pageRef, QQuickWebView* webView) @@ -49,28 +50,28 @@ QtWebPageLoadClient::QtWebPageLoadClient(WKPageRef pageRef, QQuickWebView* webVi WKPageSetPageLoaderClient(pageRef, &loadClient); } -void QtWebPageLoadClient::didStartProvisionalLoadForFrame() +void QtWebPageLoadClient::didStartProvisionalLoadForFrame(const QUrl& url) { - emit m_webView->navigationStateChanged(); - emit m_webView->loadStarted(); + QWebLoadRequest loadRequest(url, QQuickWebView::LoadStartedStatus); + m_webView->d_func()->didChangeLoadingState(&loadRequest); } -void QtWebPageLoadClient::didCommitLoadForFrame(const QUrl& url) +void QtWebPageLoadClient::didCommitLoadForFrame() { - emit m_webView->navigationStateChanged(); - emit m_webView->urlChanged(url); + emit m_webView->navigationHistoryChanged(); + emit m_webView->urlChanged(); m_webView->d_func()->loadDidCommit(); } -void QtWebPageLoadClient::didSameDocumentNavigationForFrame(const QUrl& url) +void QtWebPageLoadClient::didSameDocumentNavigationForFrame() { - emit m_webView->navigationStateChanged(); - emit m_webView->urlChanged(url); + emit m_webView->navigationHistoryChanged(); + emit m_webView->urlChanged(); } -void QtWebPageLoadClient::didReceiveTitleForFrame(const QString& title) +void QtWebPageLoadClient::didReceiveTitleForFrame() { - emit m_webView->titleChanged(title); + emit m_webView->titleChanged(); } void QtWebPageLoadClient::didFirstVisuallyNonEmptyLayoutForFrame() @@ -90,20 +91,22 @@ void QtWebPageLoadClient::dispatchLoadSucceeded() void QtWebPageLoadClient::dispatchLoadFailed(WKErrorRef error) { - emit m_webView->navigationStateChanged(); - int errorCode = WKErrorGetErrorCode(error); - if (toImpl(error)->platformError().isCancellation() || errorCode == kWKErrorCodeFrameLoadInterruptedByPolicyChange || errorCode == kWKErrorCodePlugInWillHandleLoad) + if (toImpl(error)->platformError().isCancellation() || errorCode == kWKErrorCodeFrameLoadInterruptedByPolicyChange || errorCode == kWKErrorCodePlugInWillHandleLoad) { + // Make sure that LoadStartedStatus has a counterpart when e.g. requesting a download. + dispatchLoadSucceeded(); return; + } QtWebError qtError(error); - emit m_webView->loadFailed(static_cast<QQuickWebView::ErrorDomain>(qtError.type()), qtError.errorCode(), qtError.url(), qtError.description()); + QWebLoadRequest loadRequest(qtError.url(), QQuickWebView::LoadFailedStatus, qtError.description(), static_cast<QQuickWebView::ErrorDomain>(qtError.type()), qtError.errorCode()); + emit m_webView->loadingChanged(&loadRequest); } void QtWebPageLoadClient::setLoadProgress(int loadProgress) { m_loadProgress = loadProgress; - emit m_webView->loadProgressChanged(m_loadProgress); + emit m_webView->loadProgressChanged(); } static QtWebPageLoadClient* toQtWebPageLoadClient(const void* clientInfo) @@ -116,7 +119,10 @@ void QtWebPageLoadClient::didStartProvisionalLoadForFrame(WKPageRef, WKFrameRef { if (!WKFrameIsMainFrame(frame)) return; - toQtWebPageLoadClient(clientInfo)->didStartProvisionalLoadForFrame(); + WebFrameProxy* wkframe = toImpl(frame); + QString urlStr(wkframe->provisionalURL()); + QUrl qUrl = urlStr; + toQtWebPageLoadClient(clientInfo)->didStartProvisionalLoadForFrame(qUrl); } void QtWebPageLoadClient::didFailProvisionalLoadWithErrorForFrame(WKPageRef, WKFrameRef frame, WKErrorRef error, WKTypeRef, const void* clientInfo) @@ -130,10 +136,7 @@ void QtWebPageLoadClient::didCommitLoadForFrame(WKPageRef, WKFrameRef frame, WKT { if (!WKFrameIsMainFrame(frame)) return; - WebFrameProxy* wkframe = toImpl(frame); - QString urlStr(wkframe->url()); - QUrl qUrl = urlStr; - toQtWebPageLoadClient(clientInfo)->didCommitLoadForFrame(qUrl); + toQtWebPageLoadClient(clientInfo)->didCommitLoadForFrame(); } void QtWebPageLoadClient::didFinishLoadForFrame(WKPageRef, WKFrameRef frame, WKTypeRef, const void* clientInfo) @@ -152,18 +155,14 @@ void QtWebPageLoadClient::didFailLoadWithErrorForFrame(WKPageRef, WKFrameRef fra void QtWebPageLoadClient::didSameDocumentNavigationForFrame(WKPageRef page, WKFrameRef frame, WKSameDocumentNavigationType type, WKTypeRef userData, const void* clientInfo) { - WebFrameProxy* wkframe = toImpl(frame); - QString urlStr(wkframe->url()); - QUrl qUrl = urlStr; - toQtWebPageLoadClient(clientInfo)->didSameDocumentNavigationForFrame(qUrl); + toQtWebPageLoadClient(clientInfo)->didSameDocumentNavigationForFrame(); } void QtWebPageLoadClient::didReceiveTitleForFrame(WKPageRef, WKStringRef title, WKFrameRef frame, WKTypeRef, const void* clientInfo) { if (!WKFrameIsMainFrame(frame)) return; - QString qTitle = WKStringCopyQString(title); - toQtWebPageLoadClient(clientInfo)->didReceiveTitleForFrame(qTitle); + toQtWebPageLoadClient(clientInfo)->didReceiveTitleForFrame(); } void QtWebPageLoadClient::didStartProgress(WKPageRef, const void* clientInfo) diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h b/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h index fbdb92e7b..672597af7 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h +++ b/Source/WebKit2/UIProcess/qt/QtWebPageLoadClient.h @@ -35,10 +35,10 @@ public: int loadProgress() const { return m_loadProgress; } private: - void didStartProvisionalLoadForFrame(); - void didCommitLoadForFrame(const QUrl&); - void didSameDocumentNavigationForFrame(const QUrl&); - void didReceiveTitleForFrame(const QString&); + void didStartProvisionalLoadForFrame(const QUrl&); + void didCommitLoadForFrame(); + void didSameDocumentNavigationForFrame(); + void didReceiveTitleForFrame(); void didFirstVisuallyNonEmptyLayoutForFrame(); void didChangeBackForwardList(); diff --git a/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.cpp b/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.cpp index ad8ced73f..ad5f6aa12 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.cpp +++ b/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.cpp @@ -41,12 +41,11 @@ QtWebPagePolicyClient::QtWebPagePolicyClient(WKPageRef pageRef, QQuickWebView* w WKPageSetPagePolicyClient(pageRef, &policyClient); } -void QtWebPagePolicyClient::decidePolicyForNavigationAction(const QUrl& url, const QUrl& originatingUrl, Qt::MouseButton mouseButton, - Qt::KeyboardModifiers keyboardModifiers, QQuickWebView::NavigationType navigationType, WKFramePolicyListenerRef listener) +void QtWebPagePolicyClient::decidePolicyForNavigationAction(const QUrl& url, Qt::MouseButton mouseButton, Qt::KeyboardModifiers keyboardModifiers, QQuickWebView::NavigationType navigationType, WKFramePolicyListenerRef listener) { // NOTE: even though the C API (and the WebKit2 IPC) supports an asynchronous answer, this is not currently working. // We are expected to call the listener immediately. See the patch for https://bugs.webkit.org/show_bug.cgi?id=53785. - QWebNavigationRequest navigationRequest(url, originatingUrl, mouseButton, keyboardModifiers, navigationType); + QWebNavigationRequest navigationRequest(url, mouseButton, keyboardModifiers, navigationType); emit m_webView->navigationRequested(&navigationRequest); switch (navigationRequest.action()) { @@ -123,9 +122,8 @@ void QtWebPagePolicyClient::decidePolicyForNavigationAction(WKPageRef, WKFrameRe { WKRetainPtr<WKURLRef> frameURL(AdoptWK, WKFrameCopyURL(frame)); WKRetainPtr<WKURLRef> requestURL(AdoptWK, WKURLRequestCopyURL(request)); - QUrl qUrlFrame = WKURLCopyQUrl(frameURL.get()); QUrl qUrl = WKURLCopyQUrl(requestURL.get()); - toQtWebPagePolicyClient(clientInfo)->decidePolicyForNavigationAction(qUrl, qUrlFrame, toQtMouseButton(mouseButton), toQtKeyboardModifiers(modifiers), toQuickWebViewNavigationType(navigationType), listener); + toQtWebPagePolicyClient(clientInfo)->decidePolicyForNavigationAction(qUrl, toQtMouseButton(mouseButton), toQtKeyboardModifiers(modifiers), toQuickWebViewNavigationType(navigationType), listener); } void QtWebPagePolicyClient::decidePolicyForResponse(WKPageRef page, WKFrameRef frame, WKURLResponseRef response, WKURLRequestRef, WKFramePolicyListenerRef listener, WKTypeRef, const void*) diff --git a/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.h b/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.h index e393d54f3..9e397fb77 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.h +++ b/Source/WebKit2/UIProcess/qt/QtWebPagePolicyClient.h @@ -31,7 +31,7 @@ public: QtWebPagePolicyClient(WKPageRef, QQuickWebView*); private: - void decidePolicyForNavigationAction(const QUrl&, const QUrl&, Qt::MouseButton, Qt::KeyboardModifiers, QQuickWebView::NavigationType, WKFramePolicyListenerRef); + void decidePolicyForNavigationAction(const QUrl&, Qt::MouseButton, Qt::KeyboardModifiers, QQuickWebView::NavigationType, WKFramePolicyListenerRef); // WKPagePolicyClient callbacks. static void decidePolicyForNavigationAction(WKPageRef, WKFrameRef, WKFrameNavigationType, WKEventModifiers, WKEventMouseButton, WKURLRequestRef, WKFramePolicyListenerRef, WKTypeRef userData, const void* clientInfo); diff --git a/Source/WebKit2/UIProcess/qt/WebFullScreenManagerProxyQt.cpp b/Source/WebKit2/UIProcess/qt/WebFullScreenManagerProxyQt.cpp index c4a13fad8..bea1aebac 100644 --- a/Source/WebKit2/UIProcess/qt/WebFullScreenManagerProxyQt.cpp +++ b/Source/WebKit2/UIProcess/qt/WebFullScreenManagerProxyQt.cpp @@ -29,6 +29,8 @@ #include <WebCore/NotImplemented.h> +using namespace WebCore; + namespace WebKit { void WebFullScreenManagerProxy::invalidate() @@ -46,37 +48,12 @@ void WebFullScreenManagerProxy::exitFullScreen() notImplemented(); } -void WebFullScreenManagerProxy::beganEnterFullScreenAnimation() -{ - notImplemented(); -} - -void WebFullScreenManagerProxy::finishedEnterFullScreenAnimation(bool completed) -{ - notImplemented(); -} - -void WebFullScreenManagerProxy::beganExitFullScreenAnimation() -{ - notImplemented(); -} - -void WebFullScreenManagerProxy::finishedExitFullScreenAnimation(bool completed) -{ - notImplemented(); -} - -void WebFullScreenManagerProxy::enterAcceleratedCompositingMode(const LayerTreeContext& context) -{ - notImplemented(); -} - -void WebFullScreenManagerProxy::exitAcceleratedCompositingMode() +void WebFullScreenManagerProxy::beganEnterFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) { notImplemented(); } -void WebFullScreenManagerProxy::getFullScreenRect(WebCore::IntRect& rect) +void WebFullScreenManagerProxy::beganExitFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) { notImplemented(); } diff --git a/Source/WebKit2/UIProcess/qt/WebInspectorProxyQt.cpp b/Source/WebKit2/UIProcess/qt/WebInspectorProxyQt.cpp index 6b69e9975..dcc05b947 100644 --- a/Source/WebKit2/UIProcess/qt/WebInspectorProxyQt.cpp +++ b/Source/WebKit2/UIProcess/qt/WebInspectorProxyQt.cpp @@ -54,6 +54,12 @@ void WebInspectorProxy::platformBringToFront() notImplemented(); } +bool WebInspectorProxy::platformIsFront() +{ + notImplemented(); + return false; +} + void WebInspectorProxy::platformInspectedURLChanged(const String&) { notImplemented(); diff --git a/Source/WebKit2/UIProcess/win/WebFullScreenManagerProxyWin.cpp b/Source/WebKit2/UIProcess/win/WebFullScreenManagerProxyWin.cpp index 878fa134e..fe11c7127 100644 --- a/Source/WebKit2/UIProcess/win/WebFullScreenManagerProxyWin.cpp +++ b/Source/WebKit2/UIProcess/win/WebFullScreenManagerProxyWin.cpp @@ -32,6 +32,8 @@ #include <WebCore/FullScreenController.h> #include <WebCore/IntRect.h> +using namespace WebCore; + namespace WebKit { void WebFullScreenManagerProxy::invalidate() @@ -57,53 +59,14 @@ void WebFullScreenManagerProxy::exitFullScreen() m_webView->fullScreenController()->exitFullScreen(); } -void WebFullScreenManagerProxy::beganEnterFullScreenAnimation() -{ - if (!m_webView) - return; - // FIXME: Implement -} - -void WebFullScreenManagerProxy::finishedEnterFullScreenAnimation(bool completed) -{ - if (!m_webView) - return; - // FIXME: Implement -} - -void WebFullScreenManagerProxy::beganExitFullScreenAnimation() -{ - if (!m_webView) - return; - // FIXME: Implement -} - -void WebFullScreenManagerProxy::finishedExitFullScreenAnimation(bool completed) -{ - if (!m_webView) - return; - // FIXME: Implement -} - -void WebFullScreenManagerProxy::enterAcceleratedCompositingMode(const LayerTreeContext& context) +void WebFullScreenManagerProxy::beganEnterFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) { - if (!m_webView) - return; - // FIXME: Implement + // No-op. } -void WebFullScreenManagerProxy::exitAcceleratedCompositingMode() +void WebFullScreenManagerProxy::beganExitFullScreen(const IntRect& initialFrame, const IntRect& finalFrame) { - if (!m_webView) - return; - // FIXME: Implement -} - -void WebFullScreenManagerProxy::getFullScreenRect(WebCore::IntRect& rect) -{ - if (!m_webView) - return; - // FIXME: Implement + // No-op. } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/win/WebInspectorProxyWin.cpp b/Source/WebKit2/UIProcess/win/WebInspectorProxyWin.cpp index f0c533410..67cfcf676 100644 --- a/Source/WebKit2/UIProcess/win/WebInspectorProxyWin.cpp +++ b/Source/WebKit2/UIProcess/win/WebInspectorProxyWin.cpp @@ -33,6 +33,7 @@ #include "WebProcessProxy.h" #include "WebView.h" #include <WebCore/InspectorFrontendClientLocal.h> +#include <WebCore/NotImplemented.h> #include <WebCore/WebCoreInstanceHandle.h> #include <WebCore/WindowMessageBroadcaster.h> #include <wtf/PassRefPtr.h> @@ -240,6 +241,12 @@ void WebInspectorProxy::platformBringToFront() ::SetWindowPos(parentWindow, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); } +bool WebInspectorProxy::platformIsFront() +{ + notImplemented(); + return false; +} + void WebInspectorProxy::platformInspectedURLChanged(const String& urlString) { // FIXME: this should be made localizable once WebKit2 supports it. <rdar://problem/8728860> diff --git a/Source/WebKit2/UIProcess/win/WebView.cpp b/Source/WebKit2/UIProcess/win/WebView.cpp index c0e9f1729..4e4e33f1f 100644 --- a/Source/WebKit2/UIProcess/win/WebView.cpp +++ b/Source/WebKit2/UIProcess/win/WebView.cpp @@ -1564,6 +1564,9 @@ void WebView::exitAcceleratedCompositingMode() #endif } +void WebView::updateAcceleratedCompositingMode(const LayerTreeContext&) +{ +} #endif // USE(ACCELERATED_COMPOSITING) HWND WebView::nativeWindow() diff --git a/Source/WebKit2/UIProcess/win/WebView.h b/Source/WebKit2/UIProcess/win/WebView.h index ecd708071..daa13c17b 100644 --- a/Source/WebKit2/UIProcess/win/WebView.h +++ b/Source/WebKit2/UIProcess/win/WebView.h @@ -204,6 +204,7 @@ private: #if USE(ACCELERATED_COMPOSITING) virtual void enterAcceleratedCompositingMode(const LayerTreeContext&); virtual void exitAcceleratedCompositingMode(); + virtual void updateAcceleratedCompositingMode(const LayerTreeContext&); #endif void didCommitLoadForMainFrame(bool useCustomRepresentation); |