diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-11 10:03:25 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-11 10:03:25 +0100 |
commit | d11f84f5b5cdc0d92a08af01b13472fdd5f9acb9 (patch) | |
tree | b318cf594dc1da2fa48224005945c9157f35bb41 /Source/WebKit2/UIProcess | |
parent | 6300a96eca9f152b379f1bcf3d9efdc5572d989a (diff) | |
download | qtwebkit-d11f84f5b5cdc0d92a08af01b13472fdd5f9acb9.tar.gz |
Imported WebKit commit 75bb2fc5882d2e1b3d5572c2961507996cbca5e3 (http://svn.webkit.org/repository/webkit/trunk@104681)
Diffstat (limited to 'Source/WebKit2/UIProcess')
32 files changed, 973 insertions, 325 deletions
diff --git a/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp b/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp index c5bca11b4..592f58034 100644 --- a/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp +++ b/Source/WebKit2/UIProcess/API/efl/ewk_view.cpp @@ -348,20 +348,17 @@ static void _ewk_view_smart_calculate(Evas_Object* ewkView) smartData->changed.any = false; evas_object_geometry_get(ewkView, &x, &y, &width, &height); - Evas_Object* clip = evas_object_clip_get(smartData->image); if (smartData->changed.size) { if (priv->pageClient->page()->drawingArea()) priv->pageClient->page()->drawingArea()->setSize(IntSize(width, height), IntSize()); smartData->view.w = width; smartData->view.h = height; - evas_object_resize(clip, width, height); smartData->changed.size = false; } if (smartData->changed.position) { evas_object_move(smartData->image, x, y); - evas_object_move(clip, x, y); smartData->view.x = x; smartData->view.y = y; smartData->changed.position = false; @@ -385,6 +382,33 @@ static void _ewk_view_smart_hide(Evas_Object* ewkView) evas_object_hide(smartData->image); } +static void _ewk_view_smart_color_set(Evas_Object* ewkView, int red, int green, int blue, int alpha) +{ + EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData); + EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv); + + if (alpha < 0) + alpha = 0; + else if (alpha > 255) + alpha = 255; + +#define CHECK_COLOR(color, alpha) \ + if (color < 0) \ + color = 0; \ + else if (color > alpha) \ + color = alpha; + CHECK_COLOR(red, alpha); + CHECK_COLOR(green, alpha); + CHECK_COLOR(blue, alpha); +#undef CHECK_COLOR + + evas_object_image_alpha_set(smartData->image, alpha < 255); + priv->pageClient->page()->setDrawsBackground(red || green || blue); + priv->pageClient->page()->setDrawsTransparentBackground(alpha < 255); + + g_parentSmartClass.color_set(ewkView, red, green, blue, alpha); +} + Eina_Bool ewk_view_smart_class_init(Ewk_View_Smart_Class* api) { EINA_SAFETY_ON_NULL_RETURN_VAL(api, false); @@ -407,6 +431,7 @@ Eina_Bool ewk_view_smart_class_init(Ewk_View_Smart_Class* api) api->sc.resize = _ewk_view_smart_resize; api->sc.show = _ewk_view_smart_show; api->sc.hide = _ewk_view_smart_hide; + api->sc.color_set = _ewk_view_smart_color_set; api->sc.calculate = _ewk_view_smart_calculate; api->sc.data = EWK_VIEW_TYPE_STR; // It is used by type checking. diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h index 8e3c5b7aa..953c378e1 100644 --- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.h @@ -82,7 +82,10 @@ private: virtual WebCore::FloatRect convertToUserSpace(const WebCore::FloatRect&); virtual WebCore::IntPoint screenToWindow(const WebCore::IntPoint&); virtual WebCore::IntRect windowToScreen(const WebCore::IntRect&); - + +#if ENABLE(GESTURE_EVENTS) + virtual void doneWithGestureEvent(const WebGestureEvent&, bool wasEventHandled); +#endif virtual void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool wasEventHandled); virtual PassRefPtr<WebPopupMenuProxy> createPopupMenuProxy(WebPageProxy*); diff --git a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm index c1ae66643..35e0e2e70 100644 --- a/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm +++ b/Source/WebKit2/UIProcess/API/mac/PageClientImpl.mm @@ -298,6 +298,13 @@ IntRect PageClientImpl::windowToScreen(const IntRect& rect) return enclosingIntRect(tempRect); } +#if ENABLE(GESTURE_EVENTS) +void PageClientImpl::doneWithGestureEvent(const WebGestureEvent&, bool wasEventHandled) +{ + notImplemented(); +} +#endif + void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool eventWasHandled) { [m_wkView _doneWithKeyEvent:event.nativeEvent() eventWasHandled:eventWasHandled]; diff --git a/Source/WebKit2/UIProcess/API/mac/WKPrintingView.h b/Source/WebKit2/UIProcess/API/mac/WKPrintingView.h index 87d81f4d3..cd3b1f984 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKPrintingView.h +++ b/Source/WebKit2/UIProcess/API/mac/WKPrintingView.h @@ -27,6 +27,7 @@ #import <wtf/RetainPtr.h> @class WKPrintingViewData; +@class PDFDocument; namespace WebKit { class WebFrameProxy; @@ -43,7 +44,7 @@ namespace WebKit { HashMap<WebCore::IntRect, Vector<uint8_t> > _pagePreviews; Vector<uint8_t> _printedPagesData; - RetainPtr<CGPDFDocumentRef> _printedPagesPDFDocument; + RetainPtr<PDFDocument> _printedPagesPDFDocument; uint64_t _expectedComputedPagesCallback; HashMap<uint64_t, WebCore::IntRect> _expectedPreviewCallbacks; diff --git a/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm b/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm index 14fe79add..13aefb82b 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKPrintingView.mm @@ -30,6 +30,8 @@ #import "PrintInfo.h" #import "WebData.h" #import "WebPageProxy.h" +#import <PDFKit/PDFKit.h> +#import <WebCore/WebCoreObjCExtras.h> #import <wtf/MainThread.h> using namespace WebKit; @@ -56,6 +58,14 @@ static BOOL isForcingPreviewUpdate; return self; } +- (void)dealloc +{ + if (WebCoreObjCScheduleDeallocateOnMainThread([WKPrintingView class], self)) + return; + + [super dealloc]; +} + - (BOOL)isFlipped { return YES; @@ -110,6 +120,8 @@ static BOOL isForcingPreviewUpdate; - (void)_adjustPrintingMarginsForHeaderAndFooter { + ASSERT(isMainThread()); // This funciton calls the client, which should only be done on main thread. + NSPrintInfo *info = [_printOperation printInfo]; NSMutableDictionary *infoDictionary = [info dictionary]; @@ -364,7 +376,7 @@ static void prepareDataForPrintingOnSecondaryThread(void* untypedContext) [self _suspendAutodisplay]; - [self _adjustPrintingMarginsForHeaderAndFooter]; + [self performSelectorOnMainThread:@selector(_adjustPrintingMarginsForHeaderAndFooter) withObject:nil waitUntilDone:YES]; if ([self _hasPageRects]) *range = NSMakeRange(1, _printingPageRects.size()); @@ -399,16 +411,45 @@ static void prepareDataForPrintingOnSecondaryThread(void* untypedContext) return 0; // Invalid page number. } -- (void)_drawPDFDocument:(CGPDFDocumentRef)pdfDocument page:(unsigned)page atPoint:(NSPoint)point +static NSString *pdfKitFrameworkPath() +{ + NSString *systemLibraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSSystemDomainMask, NO) objectAtIndex:0]; + return [systemLibraryPath stringByAppendingPathComponent:@"Frameworks/Quartz.framework/Frameworks/PDFKit.framework"]; +} + +static Class classFromPDFKit(NSString *className) +{ + static NSBundle *pdfKitBundle = [NSBundle bundleWithPath:pdfKitFrameworkPath()]; + [pdfKitBundle load]; + return [pdfKitBundle classNamed:className]; +} + +static Class pdfAnnotationLinkClass() +{ + static Class pdfAnnotationLinkClass = classFromPDFKit(@"PDFAnnotationLink"); + ASSERT(pdfAnnotationLinkClass); + return pdfAnnotationLinkClass; +} + +static Class pdfDocumentClass() +{ + static Class pdfDocumentClass = classFromPDFKit(@"PDFDocument"); + ASSERT(pdfDocumentClass); + return pdfDocumentClass; +} + +- (void)_drawPDFDocument:(PDFDocument *)pdfDocument page:(unsigned)page atPoint:(NSPoint)point { if (!pdfDocument) { LOG_ERROR("Couldn't create a PDF document with data passed for preview"); return; } - CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdfDocument, page); - if (!pdfPage) { - LOG_ERROR("Preview data doesn't have page %d", page); + PDFPage *pdfPage; + @try { + pdfPage = [pdfDocument pageAtIndex:page]; + } @catch (id exception) { + LOG_ERROR("Preview data doesn't have page %d: %@", page, exception); return; } @@ -418,8 +459,25 @@ static void prepareDataForPrintingOnSecondaryThread(void* untypedContext) CGContextSaveGState(context); CGContextTranslateCTM(context, point.x, point.y); CGContextScaleCTM(context, _totalScaleFactorForPrinting, -_totalScaleFactorForPrinting); - CGContextTranslateCTM(context, 0, -CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox).size.height); - CGContextDrawPDFPage(context, pdfPage); + CGContextTranslateCTM(context, 0, -[pdfPage boundsForBox:kPDFDisplayBoxMediaBox].size.height); + [pdfPage drawWithBox:kPDFDisplayBoxMediaBox]; + + CGAffineTransform transform = CGContextGetCTM(context); + + for (PDFAnnotation *annotation in [pdfPage annotations]) { + if (![annotation isKindOfClass:pdfAnnotationLinkClass()]) + continue; + + PDFAnnotationLink *linkAnnotation = (PDFAnnotationLink *)annotation; + NSURL *url = [linkAnnotation URL]; + if (!url) + continue; + + CGRect urlRect = NSRectToCGRect([linkAnnotation bounds]); + CGRect transformedRect = CGRectApplyAffineTransform(urlRect, transform); + CGPDFContextSetURLForRect(context, (CFURLRef)url, transformedRect); + } + CGContextRestoreGState(context); } @@ -462,11 +520,11 @@ static void prepareDataForPrintingOnSecondaryThread(void* untypedContext) return; } - const Vector<uint8_t>& pdfData = pagePreviewIterator->second; - RetainPtr<CGDataProviderRef> pdfDataProvider(AdoptCF, CGDataProviderCreateWithData(0, pdfData.data(), pdfData.size(), 0)); - RetainPtr<CGPDFDocumentRef> pdfDocument(AdoptCF, CGPDFDocumentCreateWithProvider(pdfDataProvider.get())); + const Vector<uint8_t>& pdfDataBytes = pagePreviewIterator->second; + RetainPtr<NSData> pdfData(AdoptNS, [[NSData alloc] initWithBytes:pdfDataBytes.data() length:pdfDataBytes.size()]); + RetainPtr<PDFDocument> pdfDocument(AdoptNS, [[pdfDocumentClass() alloc] initWithData:pdfData.get()]); - [self _drawPDFDocument:pdfDocument.get() page:1 atPoint:NSMakePoint(nsRect.origin.x, nsRect.origin.y)]; + [self _drawPDFDocument:pdfDocument.get() page:0 atPoint:NSMakePoint(nsRect.origin.x, nsRect.origin.y)]; } - (void)drawRect:(NSRect)nsRect @@ -487,11 +545,11 @@ static void prepareDataForPrintingOnSecondaryThread(void* untypedContext) ASSERT(!_printedPagesData.isEmpty()); // Prepared by knowsPageRange: if (!_printedPagesPDFDocument) { - RetainPtr<CGDataProviderRef> pdfDataProvider(AdoptCF, CGDataProviderCreateWithData(0, _printedPagesData.data(), _printedPagesData.size(), 0)); - _printedPagesPDFDocument.adoptCF(CGPDFDocumentCreateWithProvider(pdfDataProvider.get())); + RetainPtr<NSData> pdfData(AdoptNS, [[NSData alloc] initWithBytes:_printedPagesData.data() length:_printedPagesData.size()]); + _printedPagesPDFDocument.adoptNS([[pdfDocumentClass() alloc] initWithData:pdfData.get()]); } - unsigned printedPageNumber = [self _pageForRect:nsRect] - [self _firstPrintedPageNumber] + 1; + unsigned printedPageNumber = [self _pageForRect:nsRect] - [self _firstPrintedPageNumber]; [self _drawPDFDocument:_printedPagesPDFDocument.get() page:printedPageNumber atPoint:NSMakePoint(nsRect.origin.x, nsRect.origin.y)]; } diff --git a/Source/WebKit2/UIProcess/API/mac/WKView.mm b/Source/WebKit2/UIProcess/API/mac/WKView.mm index 0bb174337..1e2509ba6 100644 --- a/Source/WebKit2/UIProcess/API/mac/WKView.mm +++ b/Source/WebKit2/UIProcess/API/mac/WKView.mm @@ -225,7 +225,6 @@ struct WKViewInterpretKeyEventsParameters { - (void)dealloc { _data->_page->close(); - [NSEvent removeMonitor:_data->_flagsChangedEventMonitor]; ASSERT(!_data->_inSecureInputState); @@ -1823,12 +1822,20 @@ static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOl _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible | WebPageProxy::ViewIsInWindow); [self _updateWindowVisibility]; [self _updateWindowAndViewFrames]; - - [self _accessibilityRegisterUIProcessTokens]; + + _data->_flagsChangedEventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSFlagsChangedMask handler:^(NSEvent *flagsChangedEvent) { + [self _postFakeMouseMovedEventForFlagsChangedEvent:flagsChangedEvent]; + return flagsChangedEvent; + }]; + + [self _accessibilityRegisterUIProcessTokens]; } else { _data->_page->viewStateDidChange(WebPageProxy::ViewIsVisible); _data->_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive | WebPageProxy::ViewIsInWindow); + [NSEvent removeMonitor:_data->_flagsChangedEventMonitor]; + _data->_flagsChangedEventMonitor = nil; + #if ENABLE(GESTURE_EVENTS) if (_data->_endGestureMonitor) { [NSEvent removeMonitor:_data->_endGestureMonitor]; @@ -2703,10 +2710,6 @@ static void drawPageBackground(CGContextRef context, WebPageProxy* page, const I #endif _data->_mouseDownEvent = nil; _data->_ignoringMouseDraggedEvents = NO; - _data->_flagsChangedEventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSFlagsChangedMask handler:^(NSEvent *flagsChangedEvent) { - [self _postFakeMouseMovedEventForFlagsChangedEvent:flagsChangedEvent]; - return flagsChangedEvent; - }]; [self _registerDraggedTypes]; diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp index 7d3b2d6a6..b5db3938f 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp @@ -25,6 +25,7 @@ #include "QtWebPageEventHandler.h" #include "TransformationMatrix.h" #include "qquickwebpage_p_p.h" +#include "qquickwebview_p.h" #include <QtQuick/QQuickCanvas> #include <QtQuick/QSGGeometryNode> #include <QtQuick/QSGMaterial> @@ -50,112 +51,15 @@ QtSGUpdateQueue *QQuickWebPage::sceneGraphUpdateQueue() const return &d->sgUpdateQueue; } -void QQuickWebPage::keyPressEvent(QKeyEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::keyReleaseEvent(QKeyEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::inputMethodEvent(QInputMethodEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::focusInEvent(QFocusEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::focusOutEvent(QFocusEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::mousePressEvent(QMouseEvent* event) -{ - forceActiveFocus(); - this->event(event); -} - -void QQuickWebPage::mouseMoveEvent(QMouseEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::mouseReleaseEvent(QMouseEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::mouseDoubleClickEvent(QMouseEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::wheelEvent(QWheelEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::hoverEnterEvent(QHoverEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::hoverMoveEvent(QHoverEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::hoverLeaveEvent(QHoverEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::dragMoveEvent(QDragMoveEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::dragEnterEvent(QDragEnterEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::dragLeaveEvent(QDragLeaveEvent* event) -{ - this->event(event); -} - -void QQuickWebPage::dropEvent(QDropEvent* event) -{ - this->event(event); -} - void QQuickWebPage::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) { QQuickItem::geometryChanged(newGeometry, oldGeometry); - if (newGeometry.size() != oldGeometry.size()) - d->setDrawingAreaSize(newGeometry.size().toSize()); -} -bool QQuickWebPage::event(QEvent* ev) -{ - if (d->eventHandler.data()->handleEvent(ev)) - return true; - if (ev->type() == QEvent::InputMethod) - return false; // This is necessary to avoid an endless loop in connection with QQuickItem::event(). - return QQuickItem::event(ev); -} + if (!d->useTraditionalDesktopBehaviour) + return; -void QQuickWebPage::touchEvent(QTouchEvent* event) -{ - forceActiveFocus(); - this->event(event); + if (newGeometry.size() != oldGeometry.size()) + d->setDrawingAreaSize(newGeometry.size().toSize()); } QQuickWebPagePrivate::QQuickWebPagePrivate(QQuickWebPage* q) @@ -164,6 +68,8 @@ QQuickWebPagePrivate::QQuickWebPagePrivate(QQuickWebPage* q) , sgUpdateQueue(q) , paintingIsInitialized(false) , m_paintNode(0) + , contentScale(1) + , useTraditionalDesktopBehaviour(false) { } @@ -199,6 +105,7 @@ void QQuickWebPagePrivate::paintToCurrentGLContext() return; QTransform transform = q->itemTransform(0, 0); + transform.scale(contentScale, contentScale); float opacity = computeEffectiveOpacity(q); QRectF clipRect = q->parentItem()->mapRectToScene(q->parentItem()->boundingRect()); @@ -322,6 +229,65 @@ QSGNode* QQuickWebPage::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*) return proxyNode; } +bool QQuickWebPage::usesTraditionalDesktopBehaviour() const +{ + return d->useTraditionalDesktopBehaviour; +} + +void QQuickWebPage::setUsesTraditionalDesktopBehaviour(bool enable) +{ + d->useTraditionalDesktopBehaviour = enable; +} + +QtWebPageEventHandler* QQuickWebPage::eventHandler() const +{ + return d->eventHandler.data(); +} + +void QQuickWebPage::setContentSize(const QSizeF& size) +{ + if (size.isEmpty() || d->contentSize == size) + return; + + d->contentSize = size; + d->updateSize(); + d->setDrawingAreaSize(d->contentSize.toSize()); +} + +const QSizeF& QQuickWebPage::contentSize() const +{ + return d->contentSize; +} + +void QQuickWebPage::setContentScale(qreal scale) +{ + ASSERT(scale > 0); + d->contentScale = scale; + d->updateSize(); +} + +qreal QQuickWebPage::contentScale() const +{ + ASSERT(d->contentScale > 0); + return d->contentScale; +} + +QTransform QQuickWebPage::transformFromItem() const +{ + return transformToItem().inverted(); +} + +QTransform QQuickWebPage::transformToItem() const +{ + return QTransform(d->contentScale, 0, 0, 0, d->contentScale, 0, x(), y(), 1); +} + +void QQuickWebPagePrivate::updateSize() +{ + QSizeF scaledSize = contentSize * contentScale; + q->setSize(scaledSize); +} + void QQuickWebPagePrivate::resetPaintNode() { m_paintNode = 0; diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h index f7c35064e..f797810f6 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p.h @@ -27,6 +27,7 @@ #include <QtQuick/QQuickItem> class QQuickWebPagePrivate; +class QtWebPageEventHandler; class QWebPreferences; namespace WebKit { @@ -39,29 +40,23 @@ public: QQuickWebPage(QQuickItem* parent = 0); virtual ~QQuickWebPage(); + void setContentSize(const QSizeF& size); + const QSizeF& contentSize() const; + void setContentScale(qreal); + qreal contentScale() const; + + QTransform transformFromItem() const; + QTransform transformToItem() const; + + bool usesTraditionalDesktopBehaviour() const; + void setUsesTraditionalDesktopBehaviour(bool enable); + + QtWebPageEventHandler* eventHandler() const; + // Internal. To be removed soon. WebKit::QtSGUpdateQueue* sceneGraphUpdateQueue() const; protected: - virtual void keyPressEvent(QKeyEvent*); - virtual void keyReleaseEvent(QKeyEvent*); - virtual void inputMethodEvent(QInputMethodEvent*); - virtual void focusInEvent(QFocusEvent*); - virtual void focusOutEvent(QFocusEvent*); - virtual void mousePressEvent(QMouseEvent*); - virtual void mouseMoveEvent(QMouseEvent*); - virtual void mouseReleaseEvent(QMouseEvent *); - virtual void mouseDoubleClickEvent(QMouseEvent*); - virtual void wheelEvent(QWheelEvent*); - virtual void hoverEnterEvent(QHoverEvent*); - virtual void hoverMoveEvent(QHoverEvent*); - virtual void hoverLeaveEvent(QHoverEvent*); - virtual void dragMoveEvent(QDragMoveEvent*); - virtual void dragEnterEvent(QDragEnterEvent*); - virtual void dragLeaveEvent(QDragLeaveEvent*); - virtual void dropEvent(QDropEvent*); - virtual void touchEvent(QTouchEvent*); - virtual bool event(QEvent*); virtual void geometryChanged(const QRectF&, const QRectF&); virtual QSGNode* updatePaintNode(QSGNode*, UpdatePaintNodeData*); diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h index 7224f3975..3b58eb510 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebpage_p_p.h @@ -23,6 +23,7 @@ #include "QtSGUpdateQueue.h" #include "qquickwebpage_p.h" +#include <QTransform> namespace WebKit { class WebPageProxy; @@ -39,6 +40,8 @@ public: void initialize(WebKit::WebPageProxy*); void setDrawingAreaSize(const QSize&); + void updateSize(); + void paintToCurrentGLContext(); void resetPaintNode(); @@ -48,6 +51,10 @@ public: WebKit::QtSGUpdateQueue sgUpdateQueue; bool paintingIsInitialized; QSGNode* m_paintNode; + + QSizeF contentSize; + qreal contentScale; + bool useTraditionalDesktopBehaviour; }; #endif // qquickwebpage_p_p_h diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp index 264cbb044..187b9b4ca 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp @@ -113,8 +113,6 @@ void QQuickWebViewPrivate::enableMouseEvents() Q_Q(QQuickWebView); q->setAcceptedMouseButtons(Qt::MouseButtonMask); q->setAcceptHoverEvents(true); - pageView->setAcceptedMouseButtons(Qt::MouseButtonMask); - pageView->setAcceptHoverEvents(true); } void QQuickWebViewPrivate::disableMouseEvents() @@ -122,8 +120,6 @@ void QQuickWebViewPrivate::disableMouseEvents() Q_Q(QQuickWebView); q->setAcceptedMouseButtons(Qt::NoButton); q->setAcceptHoverEvents(false); - pageView->setAcceptedMouseButtons(Qt::NoButton); - pageView->setAcceptHoverEvents(false); } void QQuickWebViewPrivate::initializeDesktop(QQuickWebView* viewport) @@ -154,7 +150,7 @@ void QQuickWebViewPrivate::loadDidCommit() // Due to entering provisional load before committing, we // might actually be suspended here. - if (useTraditionalDesktopBehaviour) + if (pageView->usesTraditionalDesktopBehaviour()) return; isTransitioningToNewPage = true; @@ -162,7 +158,7 @@ void QQuickWebViewPrivate::loadDidCommit() void QQuickWebViewPrivate::didFinishFirstNonEmptyLayout() { - if (useTraditionalDesktopBehaviour) + if (pageView->usesTraditionalDesktopBehaviour()) return; if (!pageIsSuspended) { @@ -200,7 +196,7 @@ void QQuickWebViewPrivate::_q_resume() void QQuickWebViewPrivate::didChangeContentsSize(const QSize& newSize) { Q_Q(QQuickWebView); - if (useTraditionalDesktopBehaviour) + if (pageView->usesTraditionalDesktopBehaviour()) return; // FIXME: We probably want to handle suspend here as well @@ -209,15 +205,13 @@ void QQuickWebViewPrivate::didChangeContentsSize(const QSize& newSize) return; } - pageView->setWidth(newSize.width()); - pageView->setHeight(newSize.height()); - + pageView->setContentSize(newSize); q->m_experimental->viewportInfo()->didUpdateContentsSize(); } void QQuickWebViewPrivate::didChangeViewportProperties(const WebCore::ViewportArguments& args) { - if (useTraditionalDesktopBehaviour) + if (pageView->usesTraditionalDesktopBehaviour()) return; viewportArguments = args; @@ -235,7 +229,7 @@ void QQuickWebViewPrivate::didChangeBackForwardList() void QQuickWebViewPrivate::pageDidRequestScroll(const QPoint& pos) { - if (useTraditionalDesktopBehaviour) + if (pageView->usesTraditionalDesktopBehaviour()) return; if (isTransitioningToNewPage) { @@ -287,10 +281,10 @@ void QQuickWebViewPrivate::updateVisibleContentRectAndScale() return; Q_Q(QQuickWebView); - const QRectF visibleRectInPageViewCoordinates = q->mapRectToItem(pageView.data(), q->boundingRect()).intersected(pageView->boundingRect()); - float scale = pageView->scale(); + const QRectF visibleRectInCSSCoordinates = q->mapRectToWebContent(q->boundingRect()).intersected(pageView->boundingRect()); + float scale = pageView->contentScale(); - QRect alignedVisibleContentRect = visibleRectInPageViewCoordinates.toAlignedRect(); + QRect alignedVisibleContentRect = visibleRectInCSSCoordinates.toAlignedRect(); drawingArea->setVisibleContentsRectAndScale(alignedVisibleContentRect, scale); // FIXME: Once we support suspend and resume, this should be delayed until the page is active if the page is suspended. @@ -345,8 +339,7 @@ void QQuickWebViewPrivate::PostTransitionState::apply() p->interactionEngine->pagePositionRequest(position); if (contentsSize.isValid()) { - p->pageView->setWidth(contentsSize.width()); - p->pageView->setHeight(contentsSize.height()); + p->pageView->setContentSize(contentsSize); p->q_ptr->experimental()->viewportInfo()->didUpdateContentsSize(); } @@ -502,9 +495,8 @@ void QQuickWebViewPrivate::setUseTraditionalDesktopBehaviour(bool enable) // Do not guard, testing for the same value, as we call this from the constructor. webPageProxy->setUseFixedLayout(!enable); - - useTraditionalDesktopBehaviour = enable; - if (useTraditionalDesktopBehaviour) + pageView->setUsesTraditionalDesktopBehaviour(enable); + if (enable) initializeDesktop(q); else initializeTouch(q); @@ -609,7 +601,7 @@ void QQuickWebViewExperimental::setUseTraditionalDesktopBehaviour(bool enable) { Q_D(QQuickWebView); - if (enable == d->useTraditionalDesktopBehaviour) + if (enable == d->pageView->usesTraditionalDesktopBehaviour()) return; d->setUseTraditionalDesktopBehaviour(enable); @@ -697,7 +689,7 @@ void QQuickWebViewExperimental::setItemSelector(QDeclarativeComponent* itemSelec bool QQuickWebViewExperimental::useTraditionalDesktopBehaviour() const { Q_D(const QQuickWebView); - return d->useTraditionalDesktopBehaviour; + return d->pageView->usesTraditionalDesktopBehaviour(); } QQuickUrlSchemeDelegate* QQuickWebViewExperimental::schemeDelegates_At(QDeclarativeListProperty<QQuickUrlSchemeDelegate>* property, int index) @@ -895,6 +887,30 @@ bool QQuickWebView::canReload() const return d->webPageProxy->backForwardList()->currentItem(); } +QPointF QQuickWebView::mapToWebContent(const QPointF& pointInViewCoordinates) const +{ + Q_D(const QQuickWebView); + return d->pageView->transformFromItem().map(pointInViewCoordinates); +} + +QRectF QQuickWebView::mapRectToWebContent(const QRectF& rectInViewCoordinates) const +{ + Q_D(const QQuickWebView); + return d->pageView->transformFromItem().mapRect(rectInViewCoordinates); +} + +QPointF QQuickWebView::mapFromWebContent(const QPointF& pointInCSSCoordinates) const +{ + Q_D(const QQuickWebView); + return d->pageView->transformToItem().map(pointInCSSCoordinates); +} + +QRectF QQuickWebView::mapRectFromWebContent(const QRectF& rectInCSSCoordinates) const +{ + Q_D(const QQuickWebView); + return d->pageView->transformToItem().mapRect(rectInCSSCoordinates); +} + QString QQuickWebView::title() const { Q_D(const QQuickWebView); @@ -948,7 +964,7 @@ void QQuickWebView::geometryChanged(const QRectF& newGeometry, const QRectF& old Q_D(QQuickWebView); QQuickItem::geometryChanged(newGeometry, oldGeometry); if (newGeometry.size() != oldGeometry.size()) { - if (d->useTraditionalDesktopBehaviour) { + if (d->pageView->usesTraditionalDesktopBehaviour()) { d->pageView->setWidth(newGeometry.width()); d->pageView->setHeight(newGeometry.height()); } else @@ -956,16 +972,130 @@ void QQuickWebView::geometryChanged(const QRectF& newGeometry, const QRectF& old } } +void QQuickWebView::keyPressEvent(QKeyEvent* event) +{ + this->event(event); +} + +void QQuickWebView::keyReleaseEvent(QKeyEvent* event) +{ + this->event(event); +} + +void QQuickWebView::inputMethodEvent(QInputMethodEvent* event) +{ + this->event(event); +} + void QQuickWebView::focusInEvent(QFocusEvent* event) { - Q_D(QQuickWebView); - d->pageView->event(event); + this->event(event); } void QQuickWebView::focusOutEvent(QFocusEvent* event) { + this->event(event); +} + +void QQuickWebView::touchEvent(QTouchEvent* event) +{ + forceActiveFocus(); + this->event(event); +} + +void QQuickWebView::mousePressEvent(QMouseEvent* event) +{ + forceActiveFocus(); + this->event(event); +} + +void QQuickWebView::mouseMoveEvent(QMouseEvent* event) +{ + this->event(event); +} + +void QQuickWebView::mouseReleaseEvent(QMouseEvent* event) +{ + this->event(event); +} + +void QQuickWebView::mouseDoubleClickEvent(QMouseEvent* event) +{ + this->event(event); +} + +void QQuickWebView::wheelEvent(QWheelEvent* event) +{ + this->event(event); +} + +void QQuickWebView::hoverEnterEvent(QHoverEvent* event) +{ + this->event(event); +} + +void QQuickWebView::hoverMoveEvent(QHoverEvent* event) +{ + this->event(event); +} + +void QQuickWebView::hoverLeaveEvent(QHoverEvent* event) +{ + this->event(event); +} + +void QQuickWebView::dragMoveEvent(QDragMoveEvent* event) +{ + this->event(event); +} + +void QQuickWebView::dragEnterEvent(QDragEnterEvent* event) +{ + this->event(event); +} + +void QQuickWebView::dragLeaveEvent(QDragLeaveEvent* event) +{ + this->event(event); +} + +void QQuickWebView::dropEvent(QDropEvent* event) +{ + this->event(event); +} + +bool QQuickWebView::event(QEvent* ev) +{ Q_D(QQuickWebView); - d->pageView->event(event); + + 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::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(). + + return QQuickItem::event(ev); } WKPageRef QQuickWebView::pageRef() const diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h index e5d3f1e5a..0fa0791cf 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h @@ -100,6 +100,11 @@ public: virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const; + QPointF mapToWebContent(const QPointF&) const; + QRectF mapRectToWebContent(const QRectF&) const; + QPointF mapFromWebContent(const QPointF&) const; + QRectF mapRectFromWebContent(const QRectF&) const; + QQuickWebPage* page(); QQuickWebViewExperimental* experimental() const; @@ -130,8 +135,26 @@ Q_SIGNALS: protected: virtual void geometryChanged(const QRectF&, const QRectF&); + + virtual void keyPressEvent(QKeyEvent*); + virtual void keyReleaseEvent(QKeyEvent*); + virtual void inputMethodEvent(QInputMethodEvent*); virtual void focusInEvent(QFocusEvent*); virtual void focusOutEvent(QFocusEvent*); + virtual void touchEvent(QTouchEvent*); + virtual void mousePressEvent(QMouseEvent*); + virtual void mouseMoveEvent(QMouseEvent*); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void mouseDoubleClickEvent(QMouseEvent*); + virtual void wheelEvent(QWheelEvent*); + virtual void hoverEnterEvent(QHoverEvent*); + virtual void hoverMoveEvent(QHoverEvent*); + virtual void hoverLeaveEvent(QHoverEvent*); + virtual void dragMoveEvent(QDragMoveEvent*); + virtual void dragEnterEvent(QDragEnterEvent*); + virtual void dragLeaveEvent(QDragLeaveEvent*); + virtual void dropEvent(QDropEvent*); + virtual bool event(QEvent*); private: Q_DECLARE_PRIVATE(QQuickWebView) diff --git a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h index 3b999282b..4be71707c 100644 --- a/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h +++ b/Source/WebKit2/UIProcess/API/qt/qquickwebview_p_p.h @@ -159,8 +159,6 @@ private: bool isTransitioningToNewPage; bool pageIsSuspended; - - bool useTraditionalDesktopBehaviour; bool m_navigatorQtObjectEnabled; QUrl m_iconURL; }; diff --git a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp index 8b6fb418b..735196f86 100644 --- a/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp +++ b/Source/WebKit2/UIProcess/API/qt/qwebviewportinfo.cpp @@ -38,7 +38,7 @@ QWebViewportInfo::~QWebViewportInfo() QSize QWebViewportInfo::contentsSize() const { - return QSize(m_webViewPrivate->pageView->width(), m_webViewPrivate->pageView->height()); + return QSize(m_webViewPrivate->pageView->contentSize().toSize()); } QVariant QWebViewportInfo::currentScale() const 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 0554abb2d..8bec01418 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 @@ -26,6 +26,66 @@ Item { } SignalSpy { + id: titleSpy + target: webView + signalName: "titleChanged" + } + + SignalSpy { + id: standardFontFamilySpy + target: webView.experimental.preferences + signalName: "standardFontFamilyChanged" + } + + SignalSpy { + id: fixedFontFamilySpy + target: webView.experimental.preferences + signalName: "fixedFontFamilyChanged" + } + + SignalSpy { + id: serifFontFamilySpy + target: webView.experimental.preferences + signalName: "serifFontFamilyChanged" + } + + SignalSpy { + id: sansSerifFontFamilySpy + target: webView.experimental.preferences + signalName: "sansSerifFontFamilyChanged" + } + + SignalSpy { + id: cursiveFontFamilySpy + target: webView.experimental.preferences + signalName: "cursiveFontFamilyChanged" + } + + SignalSpy { + id: fantasyFontFamilySpy + target: webView.experimental.preferences + signalName: "fantasyFontFamilyChanged" + } + + SignalSpy { + id: minimumFontSizeSpy + target: webView.experimental.preferences + signalName: "minimumFontSizeChanged" + } + + SignalSpy { + id: defaultFontSizeSpy + target: webView.experimental.preferences + signalName: "defaultFontSizeChanged" + } + + SignalSpy { + id: defaultFixedFontSizeSpy + target: webView.experimental.preferences + signalName: "defaultFixedFontSizeChanged" + } + + SignalSpy { id: otherSpy target: webView2 signalName: "loadSucceeded" @@ -34,11 +94,65 @@ Item { TestCase { name: "WebViewPreferences" + property bool shouldSetupFonts: true + property string defaultStandardFontFamily + property string defaultFixedFontFamily + property string defaultSerifFontFamily + property string defaultSansSerifFontFamily + property string defaultCursiveFontFamily + property string defaultFantasyFontFamily + property int defaultMinimumFontSize + property int defaultFontSize + property int defaultFixedFontSize + function init() { + if (shouldSetupFonts) { + // Setup initial values (may be different per platform). + shouldSetupFonts = false + defaultStandardFontFamily = webView.experimental.preferences.standardFontFamily + defaultFixedFontFamily = webView.experimental.preferences.fixedFontFamily + defaultSerifFontFamily = webView.experimental.preferences.serifFontFamily + defaultSansSerifFontFamily = webView.experimental.preferences.sansSerifFontFamily + defaultCursiveFontFamily = webView.experimental.preferences.cursiveFontFamily + defaultFantasyFontFamily = webView.experimental.preferences.fantasyFontFamily + defaultMinimumFontSize = webView.experimental.preferences.minimumFontSize + defaultFontSize = webView.experimental.preferences.defaultFontSize + defaultFixedFontSize = webView.experimental.preferences.defaultFixedFontSize + } + else { + // Restore default values before starting a new test case. + webView.experimental.preferences.standardFontFamily = defaultStandardFontFamily + webView.experimental.preferences.fixedFontFamily = defaultFixedFontFamily + webView.experimental.preferences.serifFontFamily = defaultSerifFontFamily + webView.experimental.preferences.sansSerifFontFamily = defaultSansSerifFontFamily + webView.experimental.preferences.cursiveFontFamily = defaultCursiveFontFamily + webView.experimental.preferences.fantasyFontFamily = defaultFantasyFontFamily + webView.experimental.preferences.minimumFontSize = defaultMinimumFontSize + webView.experimental.preferences.defaultFontSize = defaultFontSize + webView.experimental.preferences.defaultFixedFontSize = defaultFixedFontSize + + if (webView.url != '' && webView.url != 'about:blank') { + spy.clear() + webView.load('about:blank') + spy.wait() + } + + standardFontFamilySpy.clear() + fixedFontFamilySpy.clear() + serifFontFamilySpy.clear() + sansSerifFontFamilySpy.clear() + cursiveFontFamilySpy.clear() + fantasyFontFamilySpy.clear() + minimumFontSizeSpy.clear() + defaultFontSizeSpy.clear() + defaultFixedFontSizeSpy.clear() + } + webView.experimental.preferences.javascriptEnabled = true webView.experimental.preferences.localStorageEnabled = true webView.experimental.preferences.pluginsEnabled = true spy.clear() + titleSpy.clear() } function test_javascriptEnabled() { @@ -96,6 +210,122 @@ Item { 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) + titleSpy.wait() + compare(webView.title, "Original Title") + titleSpy.wait() + compare(webView.title, defaultStandardFontFamily) + + webView.experimental.preferences.standardFontFamily = "foobar" + standardFontFamilySpy.wait() + compare(standardFontFamilySpy.count, 1) + webView.load(url) + titleSpy.wait() + compare(webView.title, "Original Title") + titleSpy.wait() + compare(webView.title, "foobar") + } + + function test_fontSizeChanged() { + var url = Qt.resolvedUrl("../common/font-preferences.html?standard#font-size") + webView.load(url) + titleSpy.wait() + compare(webView.title, "Original Title") + titleSpy.wait() + compare(webView.title, defaultFontSize.toString() + "px") + + webView.experimental.preferences.defaultFontSize = defaultFontSize + 1 + defaultFontSizeSpy.wait() + compare(defaultFontSizeSpy.count, 1) + webView.load(url) + titleSpy.wait() + compare(webView.title, "Original Title") + titleSpy.wait() + compare(webView.title, (defaultFontSize + 1).toString() + "px") + } + + function test_fixedFontSizeChanged() { + var url = Qt.resolvedUrl("../common/font-preferences.html?fixed#font-size") + webView.load(url) + titleSpy.wait() + compare(webView.title, "Original Title") + titleSpy.wait() + compare(webView.title, defaultFixedFontSize.toString() + "px") + + webView.experimental.preferences.defaultFixedFontSize = defaultFixedFontSize + 1 + defaultFixedFontSizeSpy.wait() + compare(defaultFixedFontSizeSpy.count, 1) + webView.load(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")) + titleSpy.wait() + compare(webView.title, "Original Title") + titleSpy.wait() + compare(webView.title, defaultFontSize.toString() + "px") + } + + function test_minimumFontSizeChanged() { + verify(defaultMinimumFontSize < defaultFontSize) + var url = Qt.resolvedUrl("../common/font-preferences.html?minimum#font-size") + webView.load(url) + titleSpy.wait() + compare(webView.title, "Original Title") + titleSpy.wait() + var smallerFontSize = webView.title + smallerFontSize = smallerFontSize.substring(0, smallerFontSize.length - 2) + smallerFontSize = parseInt(smallerFontSize) + verify(smallerFontSize < defaultFontSize) + + webView.experimental.preferences.minimumFontSize = defaultFontSize + minimumFontSizeSpy.wait() + compare(minimumFontSizeSpy.count, 1) + webView.load(url) + titleSpy.wait() + compare(webView.title, "Original Title") + titleSpy.wait() + compare(webView.title, defaultFontSize.toString() + "px") + } + + function test_defaultFontsChanged() { + // As there's currently no way to test through JS if a generic font was indeed changed + // we keep this test for really basic coverage. + + webView.experimental.preferences.standardFontFamily = "foobar0" + standardFontFamilySpy.wait() + webView.experimental.preferences.fixedFontFamily = "foobar1" + fixedFontFamilySpy.wait() + webView.experimental.preferences.serifFontFamily = "foobar2" + serifFontFamilySpy.wait() + webView.experimental.preferences.sansSerifFontFamily = "foobar3" + sansSerifFontFamilySpy.wait() + webView.experimental.preferences.cursiveFontFamily = "foobar4" + cursiveFontFamilySpy.wait() + webView.experimental.preferences.fantasyFontFamily = "foobar5" + fantasyFontFamilySpy.wait() + + compare(standardFontFamilySpy.count, 1) + compare(fixedFontFamilySpy.count, 1) + compare(serifFontFamilySpy.count, 1) + compare(sansSerifFontFamilySpy.count, 1) + compare(cursiveFontFamilySpy.count, 1) + compare(fantasyFontFamilySpy.count, 1) + + compare(webView.experimental.preferences.standardFontFamily, "foobar0") + compare(webView.experimental.preferences.fixedFontFamily, "foobar1") + compare(webView.experimental.preferences.serifFontFamily, "foobar2") + compare(webView.experimental.preferences.sansSerifFontFamily, "foobar3") + compare(webView.experimental.preferences.cursiveFontFamily, "foobar4") + compare(webView.experimental.preferences.fantasyFontFamily, "foobar5") + } + + } } } diff --git a/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/font-preferences.html b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/font-preferences.html new file mode 100644 index 000000000..cbc11432d --- /dev/null +++ b/Source/WebKit2/UIProcess/API/qt/tests/qmltests/common/font-preferences.html @@ -0,0 +1,31 @@ +<html> +<head> +<title>Original Title</title> +</head> +<script type="text/javascript"> +function getTestId() { + url = document.location.href + var i, j = 0; + for (i = url.length - 1; i >= 0; --i) { + if (url[i] == '?') + break + else if (url[i] == '#') + j = i - 1 + } + return url.substr(i + 1, j - i) +} + +function getStyleForId(id, styleProp) { + return document.defaultView.getComputedStyle(document.getElementById(id), null).getPropertyValue(styleProp); +} + +function changeTitle() { + document.title = getStyleForId(getTestId(), window.location.hash.substr(1)) +} +</script> +<body onload='setTimeout("changeTitle()", 100)'> +<p id="standard">hello</p> +<code id="fixed">hello</code> +<p id="minimum" style="font-size: smaller">hello</p> +</body> +</html> 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 57b7ec14a..1d14d1844 100644 --- a/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp +++ b/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp @@ -51,6 +51,8 @@ private slots: void show(); void showWebView(); void removeFromCanvas(); + void multipleWebViewWindows(); + void multipleWebViews(); private: inline QQuickWebView* webView() const; @@ -270,6 +272,52 @@ void tst_QQuickWebView::removeFromCanvas() QTest::qWait(200); } +void tst_QQuickWebView::multipleWebViewWindows() +{ + showWebView(); + + // This should not crash. + QQuickWebView* webView1 = new QQuickWebView(); + QScopedPointer<TestWindow> window1(new TestWindow(webView1)); + QQuickWebView* webView2 = new QQuickWebView(); + 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()))); + 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()))); + window2->show(); + webView2->setVisible(true); + QTest::qWait(200); +} + +void tst_QQuickWebView::multipleWebViews() +{ + showWebView(); + + // This should not crash. + QScopedPointer<QQuickWebView> webView1(new QQuickWebView()); + webView1->setParentItem(m_window->rootItem()); + QScopedPointer<QQuickWebView> webView2(new QQuickWebView()); + 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->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->setVisible(true); + QTest::qWait(200); +} + void tst_QQuickWebView::scrollRequest() { webView()->setSize(QSizeF(300, 400)); @@ -280,7 +328,7 @@ void tst_QQuickWebView::scrollRequest() // COMPARE with the position requested in the html // Use qRound as that is also used when calculating the position // in WebKit. - int y = -qRound(50 * webView()->page()->scale()); + int y = -qRound(50 * webView()->page()->contentScale()); QVERIFY(webView()->page()->pos().y() == y); } diff --git a/Source/WebKit2/UIProcess/PageClient.h b/Source/WebKit2/UIProcess/PageClient.h index 1db4eaa9b..c94ea1a13 100644 --- a/Source/WebKit2/UIProcess/PageClient.h +++ b/Source/WebKit2/UIProcess/PageClient.h @@ -52,6 +52,9 @@ class NativeWebKeyboardEvent; #if ENABLE(TOUCH_EVENTS) class NativeWebTouchEvent; #endif +#if ENABLE(GESTURE_EVENTS) +class WebGestureEvent; +#endif class WebContextMenuProxy; class WebEditCommandProxy; class WebPopupMenuProxy; @@ -106,6 +109,7 @@ public: virtual void focusEditableArea(const WebCore::IntRect&, const WebCore::IntRect&) = 0; virtual void didReceiveMessageFromNavigatorQtObject(const String&) = 0; virtual void handleDownloadRequest(DownloadProxy*) = 0; + virtual void updateTextInputState() = 0; #endif #if PLATFORM(QT) || PLATFORM(GTK) @@ -141,6 +145,9 @@ public: virtual WebCore::IntRect windowToScreen(const WebCore::IntRect&) = 0; virtual void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool wasEventHandled) = 0; +#if ENABLE(GESTURE_EVENTS) + virtual void doneWithGestureEvent(const WebGestureEvent&, bool wasEventHandled) = 0; +#endif #if ENABLE(TOUCH_EVENTS) virtual void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled) = 0; #endif diff --git a/Source/WebKit2/UIProcess/WebConnectionToWebProcess.cpp b/Source/WebKit2/UIProcess/WebConnectionToWebProcess.cpp index 18f74a99f..b1d103fbc 100644 --- a/Source/WebKit2/UIProcess/WebConnectionToWebProcess.cpp +++ b/Source/WebKit2/UIProcess/WebConnectionToWebProcess.cpp @@ -46,8 +46,6 @@ WebConnectionToWebProcess::WebConnectionToWebProcess(WebProcessProxy* process, C #elif PLATFORM(QT) m_connection->setShouldCloseConnectionOnProcessTermination(process->processIdentifier()); #endif - - m_connection->open(); } void WebConnectionToWebProcess::invalidate() diff --git a/Source/WebKit2/UIProcess/WebPageProxy.cpp b/Source/WebKit2/UIProcess/WebPageProxy.cpp index 15abf9ccc..7e08cecd8 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.cpp +++ b/Source/WebKit2/UIProcess/WebPageProxy.cpp @@ -968,6 +968,8 @@ void WebPageProxy::handleGestureEvent(const WebGestureEvent& event) if (!isValid()) return; + m_gestureEventQueue.append(event); + process()->responsivenessTimer()->start(); process()->send(Messages::EventDispatcher::GestureEvent(m_pageID, event), 0); } @@ -2427,6 +2429,8 @@ void WebPageProxy::editorStateChanged(const EditorState& editorState) #if PLATFORM(MAC) m_pageClient->updateTextInputState(couldChangeSecureInputState); +#elif PLATFORM(QT) + m_pageClient->updateTextInputState(); #endif } @@ -2908,12 +2912,19 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled) } break; case WebEvent::MouseDown: + break; #if ENABLE(GESTURE_EVENTS) case WebEvent::GestureScrollBegin: case WebEvent::GestureScrollEnd: - case WebEvent::GestureSingleTap: -#endif + case WebEvent::GestureSingleTap: { + WebGestureEvent event = m_gestureEventQueue.first(); + MESSAGE_CHECK(type == event.type()); + + m_gestureEventQueue.removeFirst(); + m_pageClient->doneWithGestureEvent(event, handled); break; + } +#endif case WebEvent::MouseUp: m_currentlyProcessedMouseDownEvent = nullptr; break; diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h index 42a18f3e1..cf5130419 100644 --- a/Source/WebKit2/UIProcess/WebPageProxy.h +++ b/Source/WebKit2/UIProcess/WebPageProxy.h @@ -952,6 +952,9 @@ private: WebCore::PolicyAction m_syncNavigationActionPolicyAction; uint64_t m_syncNavigationActionPolicyDownloadID; +#if ENABLE(GESTURE_EVENTS) + Deque<WebGestureEvent> m_gestureEventQueue; +#endif Deque<NativeWebKeyboardEvent> m_keyEventQueue; Deque<NativeWebWheelEvent> m_wheelEventQueue; Vector<NativeWebWheelEvent> m_currentlyProcessedWheelEvents; diff --git a/Source/WebKit2/UIProcess/WebProcessProxy.cpp b/Source/WebKit2/UIProcess/WebProcessProxy.cpp index 0c11caa5b..8c99b4efa 100644 --- a/Source/WebKit2/UIProcess/WebProcessProxy.cpp +++ b/Source/WebKit2/UIProcess/WebProcessProxy.cpp @@ -117,6 +117,7 @@ void WebProcessProxy::connect() void WebProcessProxy::disconnect() { if (m_connection) { + m_connection->connection()->removeQueueClient(this); m_connection->invalidate(); m_connection = nullptr; } @@ -349,6 +350,12 @@ void WebProcessProxy::didReceiveSyncMessage(CoreIPC::Connection* connection, Cor pageProxy->didReceiveSyncMessage(connection, messageID, arguments, reply); } +void WebProcessProxy::didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, bool& didHandleMessage) +{ + if (messageID.is<CoreIPC::MessageClassWebProcessProxy>()) + didReceiveWebProcessProxyMessageOnConnectionWorkQueue(connection, messageID, arguments, didHandleMessage); +} + void WebProcessProxy::didClose(CoreIPC::Connection*) { // Protect ourselves, as the call to disconnect() below may otherwise cause us @@ -409,7 +416,9 @@ void WebProcessProxy::didFinishLaunching(CoreIPC::Connection::Identifier connect ASSERT(!m_connection); m_connection = WebConnectionToWebProcess::create(this, connectionIdentifier, RunLoop::main()); - + m_connection->connection()->addQueueClient(this); + m_connection->connection()->open(); + for (size_t i = 0; i < m_pendingMessages.size(); ++i) { CoreIPC::Connection::OutgoingMessage& outgoingMessage = m_pendingMessages[i].first; unsigned messageSendFlags = m_pendingMessages[i].second; diff --git a/Source/WebKit2/UIProcess/WebProcessProxy.h b/Source/WebKit2/UIProcess/WebProcessProxy.h index 129e0ea1b..11cfa5b27 100644 --- a/Source/WebKit2/UIProcess/WebProcessProxy.h +++ b/Source/WebKit2/UIProcess/WebProcessProxy.h @@ -57,7 +57,7 @@ class WebContext; class WebPageGroup; struct WebNavigationDataStore; -class WebProcessProxy : public RefCounted<WebProcessProxy>, CoreIPC::Connection::Client, ResponsivenessTimer::Client, ProcessLauncher::Client, ThreadLauncher::Client { +class WebProcessProxy : public RefCounted<WebProcessProxy>, CoreIPC::Connection::Client, ResponsivenessTimer::Client, ProcessLauncher::Client, ThreadLauncher::Client, CoreIPC::Connection::QueueClient { public: typedef HashMap<uint64_t, RefPtr<WebFrameProxy> > WebFrameProxyMap; typedef HashMap<uint64_t, RefPtr<WebBackForwardListItem> > WebBackForwardListItemMap; @@ -139,13 +139,8 @@ private: void pluginSyncMessageSendTimedOut(const String& pluginPath); #endif #if PLATFORM(MAC) - void secItemCopyMatching(const SecItemRequestData&, SecItemResponseData&); - void secItemAdd(const SecItemRequestData&, SecItemResponseData&); - void secItemUpdate(const SecItemRequestData&, SecItemResponseData&); - void secItemDelete(const SecItemRequestData&, SecItemResponseData&); - void secKeychainItemCopyContent(const SecKeychainItemRequestData&, SecKeychainItemResponseData&); - void secKeychainItemCreateFromContent(const SecKeychainItemRequestData&, SecKeychainItemResponseData&); - void secKeychainItemModifyContent(const SecKeychainItemRequestData&, SecKeychainItemResponseData&); + void secItemRequest(CoreIPC::Connection*, uint64_t requestID, const SecItemRequestData&); + void secKeychainItemRequest(CoreIPC::Connection*, uint64_t requestID, const SecKeychainItemRequestData&); #endif // CoreIPC::Connection::Client @@ -159,6 +154,9 @@ private: virtual Vector<HWND> windowsToReceiveSentMessagesWhileWaitingForSyncReply(); #endif + // CoreIPC::Connection::QueueClient + virtual void didReceiveMessageOnConnectionWorkQueue(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, bool& didHandleMessage); + // ResponsivenessTimer::Client void didBecomeUnresponsive(ResponsivenessTimer*); void didBecomeResponsive(ResponsivenessTimer*); @@ -174,6 +172,7 @@ private: // Implemented in generated WebProcessProxyMessageReceiver.cpp void didReceiveWebProcessProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); void didReceiveSyncWebProcessProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply); + void didReceiveWebProcessProxyMessageOnConnectionWorkQueue(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder* arguments, bool& didHandleMessage); ResponsivenessTimer m_responsivenessTimer; diff --git a/Source/WebKit2/UIProcess/WebProcessProxy.messages.in b/Source/WebKit2/UIProcess/WebProcessProxy.messages.in index 8943ffc70..93961da44 100644 --- a/Source/WebKit2/UIProcess/WebProcessProxy.messages.in +++ b/Source/WebKit2/UIProcess/WebProcessProxy.messages.in @@ -33,14 +33,8 @@ messages -> WebProcessProxy { #endif #if PLATFORM(MAC) - SecItemCopyMatching(WebKit::SecItemRequestData query) -> (WebKit::SecItemResponseData result) - SecItemAdd(WebKit::SecItemRequestData query) -> (WebKit::SecItemResponseData result) - SecItemUpdate(WebKit::SecItemRequestData query) -> (WebKit::SecItemResponseData result) - SecItemDelete(WebKit::SecItemRequestData query) -> (WebKit::SecItemResponseData result) - - SecKeychainItemCopyContent(WebKit::SecKeychainItemRequestData query) -> (WebKit::SecKeychainItemResponseData result) - SecKeychainItemCreateFromContent(WebKit::SecKeychainItemRequestData query) -> (WebKit::SecKeychainItemResponseData result) - SecKeychainItemModifyContent(WebKit::SecKeychainItemRequestData query) -> (WebKit::SecKeychainItemResponseData result) + SecItemRequest(uint64_t requestID, WebKit::SecItemRequestData request) DispatchOnConnectionQueue + SecKeychainItemRequest(uint64_t requestID, WebKit::SecKeychainItemRequestData request) DispatchOnConnectionQueue #endif } diff --git a/Source/WebKit2/UIProcess/mac/WebProcessProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebProcessProxyMac.mm index 467155e92..37e8caae0 100644 --- a/Source/WebKit2/UIProcess/mac/WebProcessProxyMac.mm +++ b/Source/WebKit2/UIProcess/mac/WebProcessProxyMac.mm @@ -30,82 +30,105 @@ #import "SecItemResponseData.h" #import "SecKeychainItemRequestData.h" #import "SecKeychainItemResponseData.h" +#import "WebProcessMessages.h" #import "WKFullKeyboardAccessWatcher.h" #import <Security/SecItem.h> namespace WebKit { -void WebProcessProxy::secItemCopyMatching(const SecItemRequestData& queryData, SecItemResponseData& result) +static void handleSecItemRequest(CoreIPC::Connection* connection, uint64_t requestID, const SecItemRequestData& request) { - CFDictionaryRef query = queryData.query(); - CFTypeRef resultObjectRef; - OSStatus resultCode = SecItemCopyMatching(query, &resultObjectRef); - - RetainPtr<CFTypeRef> resultObject(AdoptCF, resultObjectRef); - result = SecItemResponseData(resultCode, resultObject.get()); -} - -void WebProcessProxy::secItemAdd(const SecItemRequestData& queryData, SecItemResponseData& result) -{ - CFDictionaryRef query = queryData.query(); - CFTypeRef resultObjectRef; - OSStatus resultCode = SecItemAdd(query, &resultObjectRef); - - RetainPtr<CFTypeRef> resultObject(AdoptCF, resultObjectRef); - result = SecItemResponseData(resultCode, resultObject.get()); -} - -void WebProcessProxy::secItemUpdate(const SecItemRequestData& queryData, SecItemResponseData& result) -{ - CFDictionaryRef query = queryData.query(); - CFDictionaryRef attributesToMatch = queryData.attributesToMatch(); - OSStatus resultCode; - - resultCode = SecItemUpdate(query, attributesToMatch); - - result = SecItemResponseData(resultCode, 0); -} - -void WebProcessProxy::secItemDelete(const SecItemRequestData& queryData, SecItemResponseData& result) -{ - CFDictionaryRef query = queryData.query(); - OSStatus resultCode; - - resultCode = SecItemDelete(query); - - result = SecItemResponseData(resultCode, 0); + SecItemResponseData response; + + switch (request.type()) { + case SecItemRequestData::CopyMatching: { + CFTypeRef resultObject = 0; + OSStatus resultCode = SecItemCopyMatching(request.query(), &resultObject); + response = SecItemResponseData(resultCode, adoptCF(resultObject).get()); + break; + } + + case SecItemRequestData::Add: { + CFTypeRef resultObject = 0; + OSStatus resultCode = SecItemAdd(request.query(), &resultObject); + response = SecItemResponseData(resultCode, adoptCF(resultObject).get()); + break; + } + + case SecItemRequestData::Update: { + OSStatus resultCode = SecItemUpdate(request.query(), request.attributesToMatch()); + response = SecItemResponseData(resultCode, 0); + break; + } + + case SecItemRequestData::Delete: { + OSStatus resultCode = SecItemDelete(request.query()); + response = SecItemResponseData(resultCode, 0); + break; + } + + default: + return; + } + + connection->send(Messages::WebProcess::SecItemResponse(requestID, response), 0); } -void WebProcessProxy::secKeychainItemCopyContent(const SecKeychainItemRequestData& request, SecKeychainItemResponseData& response) +void WebProcessProxy::secItemRequest(CoreIPC::Connection* connection, uint64_t requestID, const SecItemRequestData& request) { - SecKeychainItemRef item = request.keychainItem(); - SecItemClass itemClass; - SecKeychainAttributeList* attrList = request.attributeList(); - UInt32 length = 0; - void* outData = 0; - - OSStatus resultCode = SecKeychainItemCopyContent(item, &itemClass, attrList, &length, &outData); - - RetainPtr<CFDataRef> data(AdoptCF, CFDataCreate(0, static_cast<const UInt8*>(outData), length)); - response = SecKeychainItemResponseData(resultCode, itemClass, attrList, data.get()); - - SecKeychainItemFreeContent(attrList, outData); + // Since we don't want the connection work queue to be held up, we do all + // keychain interaction work on a global dispatch queue. + dispatch_queue_t keychainWorkQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + dispatch_async(keychainWorkQueue, bind(handleSecItemRequest, RefPtr<CoreIPC::Connection>(connection), requestID, request)); } -void WebProcessProxy::secKeychainItemCreateFromContent(const SecKeychainItemRequestData& request, SecKeychainItemResponseData& response) +static void handleSecKeychainItemRequest(CoreIPC::Connection* connection, uint64_t requestID, const SecKeychainItemRequestData& request) { - SecKeychainItemRef keychainItem; - - OSStatus resultCode = SecKeychainItemCreateFromContent(request.itemClass(), request.attributeList(), request.length(), request.data(), 0, 0, &keychainItem); - - response = SecKeychainItemResponseData(resultCode, RetainPtr<SecKeychainItemRef>(AdoptCF, keychainItem)); + SecKeychainItemResponseData response; + + switch (request.type()) { + case SecKeychainItemRequestData::CopyContent: { + SecKeychainItemRef item = request.keychainItem(); + SecItemClass itemClass; + SecKeychainAttributeList* attrList = request.attributeList(); + UInt32 length = 0; + void* outData = 0; + + OSStatus resultCode = SecKeychainItemCopyContent(item, &itemClass, attrList, &length, &outData); + RetainPtr<CFDataRef> data(AdoptCF, CFDataCreate(0, static_cast<const UInt8*>(outData), length)); + response = SecKeychainItemResponseData(resultCode, itemClass, attrList, data.get()); + + SecKeychainItemFreeContent(attrList, outData); + break; + } + + case SecKeychainItemRequestData::CreateFromContent: { + SecKeychainItemRef keychainItem; + + OSStatus resultCode = SecKeychainItemCreateFromContent(request.itemClass(), request.attributeList(), request.length(), request.data(), 0, 0, &keychainItem); + response = SecKeychainItemResponseData(resultCode, adoptCF(keychainItem)); + break; + } + + case SecKeychainItemRequestData::ModifyContent: { + OSStatus resultCode = SecKeychainItemModifyContent(request.keychainItem(), request.attributeList(), request.length(), request.data()); + response = resultCode; + break; + } + + default: + return; + } + + connection->send(Messages::WebProcess::SecKeychainItemResponse(requestID, response), 0); } -void WebProcessProxy::secKeychainItemModifyContent(const SecKeychainItemRequestData& request, SecKeychainItemResponseData& response) +void WebProcessProxy::secKeychainItemRequest(CoreIPC::Connection* connection, uint64_t requestID, const SecKeychainItemRequestData& request) { - OSStatus resultCode = SecKeychainItemModifyContent(request.keychainItem(), request.attributeList(), request.length(), request.data()); - - response = resultCode; + // Since we don't want the connection work queue to be held up, we do all + // keychain interaction work on a global dispatch queue. + dispatch_queue_t keychainWorkQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + dispatch_async(keychainWorkQueue, bind(handleSecKeychainItemRequest, RefPtr<CoreIPC::Connection>(connection), requestID, request)); } bool WebProcessProxy::fullKeyboardAccessEnabled() diff --git a/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp b/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp index a1dd272a7..60736b1df 100644 --- a/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp +++ b/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp @@ -460,7 +460,8 @@ void LayerTreeHostProxy::ensureRootLayer() // The root layer should not have zero size, or it would be optimized out. m_rootLayer->setSize(FloatSize(1.0, 1.0)); - m_textureMapper = TextureMapperGL::create(); + if (!m_textureMapper) + m_textureMapper = TextureMapperGL::create(); toTextureMapperNode(m_rootLayer.get())->setTextureMapper(m_textureMapper.get()); } @@ -623,7 +624,9 @@ void LayerTreeHostProxy::purgeGLResources() { TextureMapperNode* node = toTextureMapperNode(rootLayer()); - node->purgeNodeTexturesRecursive(); + if (node) + node->purgeNodeTexturesRecursive(); + m_directlyCompositedImages.clear(); m_textureMapper.clear(); diff --git a/Source/WebKit2/UIProcess/qt/QtPageClient.cpp b/Source/WebKit2/UIProcess/qt/QtPageClient.cpp index b173776d8..cc96876be 100644 --- a/Source/WebKit2/UIProcess/qt/QtPageClient.cpp +++ b/Source/WebKit2/UIProcess/qt/QtPageClient.cpp @@ -195,6 +195,20 @@ void QtPageClient::didReceiveMessageFromNavigatorQtObject(const String& message) QQuickWebViewPrivate::get(m_webView)->didReceiveMessageFromNavigatorQtObject(message); } +void QtPageClient::updateTextInputState() +{ + ASSERT(m_eventHandler); + m_eventHandler->updateTextInputState(); +} + +#if ENABLE(GESTURE_EVENTS) +void QtPageClient::doneWithGestureEvent(const WebGestureEvent& event, bool wasEventHandled) +{ + ASSERT(m_eventHandler); + m_eventHandler->doneWithGestureEvent(event, wasEventHandled); +} +#endif + #if ENABLE(TOUCH_EVENTS) void QtPageClient::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled) { diff --git a/Source/WebKit2/UIProcess/qt/QtPageClient.h b/Source/WebKit2/UIProcess/qt/QtPageClient.h index a3149b631..7715026f8 100644 --- a/Source/WebKit2/UIProcess/qt/QtPageClient.h +++ b/Source/WebKit2/UIProcess/qt/QtPageClient.h @@ -93,10 +93,9 @@ public: virtual void countStringMatchesInCustomRepresentation(const String&, WebKit::FindOptions, unsigned maxMatchCount) { } virtual void didFindZoomableArea(const WebCore::IntPoint&, const WebCore::IntRect&); virtual void focusEditableArea(const WebCore::IntRect&, const WebCore::IntRect&); - -#if ENABLE(TOUCH_EVENTS) + virtual void updateTextInputState(); + virtual void doneWithGestureEvent(const WebGestureEvent&, bool wasEventHandled); virtual void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled); -#endif private: QQuickWebView* m_webView; diff --git a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp index 9167792c4..7699ad366 100644 --- a/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp +++ b/Source/WebKit2/UIProcess/qt/QtPinchGestureRecognizer.cpp @@ -112,8 +112,8 @@ bool QtPinchGestureRecognizer::recognize(const QTouchEvent* event) const qreal currentSpanDistance = QLineF(point1.screenPos(), point2.screenPos()).length(); const qreal initialSpanDistance = QLineF(m_point1.initialScreenPosition, m_point2.initialScreenPosition).length(); const qreal totalScaleFactor = currentSpanDistance / initialSpanDistance; - const QPointF touchCenterInPageViewCoordinates = computePinchCenter(point1, point2); - interactionEngine()->pinchGestureRequestUpdate(touchCenterInPageViewCoordinates, totalScaleFactor); + const QPointF touchCenterInViewCoordinates = computePinchCenter(point1, point2); + interactionEngine()->pinchGestureRequestUpdate(touchCenterInViewCoordinates, totalScaleFactor); return true; break; } diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp index 788349ae0..d12eb0bbd 100644 --- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp +++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp @@ -23,10 +23,13 @@ #include "QtViewportInteractionEngine.h" #include "PassOwnPtr.h" +#include "qquickwebpage_p.h" +#include "qquickwebview_p.h" #include <QPointF> #include <QScrollEvent> #include <QScrollPrepareEvent> #include <QScrollerProperties> +#include <QTransform> #include <QWheelEvent> #include <QtQuick/qquickitem.h> @@ -111,7 +114,7 @@ inline QRectF QtViewportInteractionEngine::itemRectFromCSS(const QRectF& cssRect return itemRect; } -QtViewportInteractionEngine::QtViewportInteractionEngine(const QQuickItem* viewport, QQuickItem* content) +QtViewportInteractionEngine::QtViewportInteractionEngine(const QQuickWebView* viewport, QQuickWebPage* content) : m_viewport(viewport) , m_content(content) , m_suspendCount(0) @@ -174,7 +177,7 @@ void QtViewportInteractionEngine::setItemRectVisible(const QRectF& itemRect) qreal itemScale = m_viewport->width() / itemRect.width(); - m_content->setScale(itemScale); + m_content->setContentScale(itemScale); // We need to animate the content but the position represents the viewport hence we need to invert the position here. // To animate the position together with the scale we multiply the position with the current scale; @@ -183,7 +186,7 @@ void QtViewportInteractionEngine::setItemRectVisible(const QRectF& itemRect) bool QtViewportInteractionEngine::animateItemRectVisible(const QRectF& itemRect) { - QRectF currentItemRectVisible = m_content->mapRectFromItem(m_viewport, m_viewport->boundingRect()); + QRectF currentItemRectVisible = m_viewport->mapRectToWebContent(m_viewport->boundingRect()); if (itemRect == currentItemRectVisible) return false; @@ -238,7 +241,7 @@ bool QtViewportInteractionEngine::event(QEvent* event) QScrollPrepareEvent* prepareEvent = static_cast<QScrollPrepareEvent*>(event); const QRectF viewportRect = m_viewport->boundingRect(); const QRectF contentRect = m_viewport->mapRectFromItem(m_content, m_content->boundingRect()); - const QRectF posRange = computePosRangeForItemAtScale(m_content->scale()); + const QRectF posRange = computePosRangeForItemAtScale(m_content->contentScale()); prepareEvent->setContentPosRange(posRange); prepareEvent->setViewportSize(viewportRect.size()); @@ -251,11 +254,11 @@ bool QtViewportInteractionEngine::event(QEvent* event) QScrollEvent* scrollEvent = static_cast<QScrollEvent*>(event); QPointF newPos = -scrollEvent->contentPos() - scrollEvent->overshootDistance(); if (m_content->pos() != newPos) { - QPointF currentPosInContentCoordinates = m_content->mapToItem(m_content->parentItem(), m_content->pos()); - QPointF newPosInContentCoordinates = m_content->mapToItem(m_content->parentItem(), newPos); + QPointF currentPosInCSSCoordinates = m_viewport->mapToWebContent(m_content->pos()); + QPointF newPosInCSSCoordinates = m_viewport->mapToWebContent(newPos); // This must be emitted before viewportUpdateRequested so that the web process knows where to look for tiles. - emit viewportTrajectoryVectorChanged(currentPosInContentCoordinates- newPosInContentCoordinates); + emit viewportTrajectoryVectorChanged(currentPosInCSSCoordinates - newPosInCSSCoordinates); m_content->setPos(newPos); } return true; @@ -297,7 +300,7 @@ void QtViewportInteractionEngine::wheelEvent(QWheelEvent* ev) else newPos.ry() += delta; - QRectF endPosRange = computePosRangeForItemAtScale(m_content->scale()); + QRectF endPosRange = computePosRangeForItemAtScale(m_content->contentScale()); m_content->setPos(-boundPosition(endPosRange.topLeft(), newPos, endPosRange.bottomRight())); } @@ -307,7 +310,7 @@ void QtViewportInteractionEngine::pagePositionRequest(const QPoint& pagePosition if (m_suspendCount) return; - qreal endItemScale = m_content->scale(); // Stay at same scale. + qreal endItemScale = m_content->contentScale(); // Stay at same scale. QRectF endPosRange = computePosRangeForItemAtScale(endItemScale); QPointF endPosition = boundPosition(endPosRange.topLeft(), pagePosition * endItemScale, endPosRange.bottomRight()); @@ -319,7 +322,7 @@ void QtViewportInteractionEngine::pagePositionRequest(const QPoint& pagePosition QRectF QtViewportInteractionEngine::computePosRangeForItemAtScale(qreal itemScale) const { - const QSizeF contentItemSize = m_content->boundingRect().size() * itemScale; + const QSizeF contentItemSize = m_content->contentSize() * itemScale; const QSizeF viewportItemSize = m_viewport->boundingRect().size(); const qreal horizontalRange = contentItemSize.width() - viewportItemSize.width(); @@ -406,7 +409,7 @@ bool QtViewportInteractionEngine::ensureContentWithinViewportBoundary(bool immed const QRectF viewportRect = m_viewport->boundingRect(); QPointF viewportHotspot = viewportRect.center(); - QPointF endPosition = m_content->mapFromItem(m_viewport, viewportHotspot) * endItemScale - viewportHotspot; + QPointF endPosition = m_viewport->mapToWebContent(viewportHotspot) * endItemScale - viewportHotspot; QRectF endPosRange = computePosRangeForItemAtScale(endItemScale); endPosition = boundPosition(endPosRange.topLeft(), endPosition, endPosRange.bottomRight()); @@ -441,7 +444,7 @@ void QtViewportInteractionEngine::applyConstraints(const Constraints& constraint if (!m_hadUserInteraction) { qreal initialScale = innerBoundedCSSScale(m_constraints.initialScale); - m_content->setScale(itemScaleFromCSS(initialScale)); + m_content->setContentScale(itemScaleFromCSS(initialScale)); } // If the web app changes successively changes the viewport on purpose @@ -451,7 +454,7 @@ void QtViewportInteractionEngine::applyConstraints(const Constraints& constraint qreal QtViewportInteractionEngine::currentCSSScale() { - return cssScaleFromItem(m_content->scale()); + return cssScaleFromItem(m_content->contentScale()); } bool QtViewportInteractionEngine::scrollAnimationActive() const @@ -473,15 +476,15 @@ bool QtViewportInteractionEngine::panGestureActive() const return scroller->state() == QScroller::Pressed || scroller->state() == QScroller::Dragging; } -void QtViewportInteractionEngine::panGestureStarted(const QPointF& touchPoint, qint64 eventTimestampMillis) +void QtViewportInteractionEngine::panGestureStarted(const QPointF& viewportTouchPoint, qint64 eventTimestampMillis) { m_hadUserInteraction = true; - scroller()->handleInput(QScroller::InputPress, m_viewport->mapFromItem(m_content, touchPoint), eventTimestampMillis); + scroller()->handleInput(QScroller::InputPress, viewportTouchPoint, eventTimestampMillis); } -void QtViewportInteractionEngine::panGestureRequestUpdate(const QPointF& touchPoint, qint64 eventTimestampMillis) +void QtViewportInteractionEngine::panGestureRequestUpdate(const QPointF& viewportTouchPoint, qint64 eventTimestampMillis) { - scroller()->handleInput(QScroller::InputMove, m_viewport->mapFromItem(m_content, touchPoint), eventTimestampMillis); + scroller()->handleInput(QScroller::InputMove, viewportTouchPoint, eventTimestampMillis); } void QtViewportInteractionEngine::panGestureCancelled() @@ -491,9 +494,9 @@ void QtViewportInteractionEngine::panGestureCancelled() scroller()->stop(); } -void QtViewportInteractionEngine::panGestureEnded(const QPointF& touchPoint, qint64 eventTimestampMillis) +void QtViewportInteractionEngine::panGestureEnded(const QPointF& viewportTouchPoint, qint64 eventTimestampMillis) { - scroller()->handleInput(QScroller::InputRelease, m_viewport->mapFromItem(m_content, touchPoint), eventTimestampMillis); + scroller()->handleInput(QScroller::InputRelease, viewportTouchPoint, eventTimestampMillis); } bool QtViewportInteractionEngine::scaleAnimationActive() const @@ -512,7 +515,7 @@ bool QtViewportInteractionEngine::pinchGestureActive() const return m_pinchStartScale > 0; } -void QtViewportInteractionEngine::pinchGestureStarted(const QPointF& pinchCenterInContentCoordinates) +void QtViewportInteractionEngine::pinchGestureStarted(const QPointF& pinchCenterInViewportCoordinates) { ASSERT(!m_suspendCount); @@ -523,14 +526,14 @@ void QtViewportInteractionEngine::pinchGestureStarted(const QPointF& pinchCenter m_scaleUpdateDeferrer = adoptPtr(new ViewportUpdateDeferrer(this)); - m_lastPinchCenterInViewportCoordinates = m_viewport->mapFromItem(m_content, pinchCenterInContentCoordinates); - m_pinchStartScale = m_content->scale(); + m_lastPinchCenterInViewportCoordinates = pinchCenterInViewportCoordinates; + m_pinchStartScale = m_content->contentScale(); // Reset the tiling look-ahead vector so that tiles all around the viewport will be requested on pinch-end. emit viewportTrajectoryVectorChanged(QPointF()); } -void QtViewportInteractionEngine::pinchGestureRequestUpdate(const QPointF& pinchCenterInContentCoordinates, qreal totalScaleFactor) +void QtViewportInteractionEngine::pinchGestureRequestUpdate(const QPointF& pinchCenterInViewportCoordinates, qreal totalScaleFactor) { ASSERT(m_suspendCount); @@ -544,12 +547,11 @@ void QtViewportInteractionEngine::pinchGestureRequestUpdate(const QPointF& pinch // Allow zooming out beyond mimimum scale on pages that do not explicitly disallow it. const qreal targetCSSScale = outerBoundedCSSScale(cssScale); - QPointF pinchCenterInViewportCoordinates = m_viewport->mapFromItem(m_content, pinchCenterInContentCoordinates); - - scaleContent(pinchCenterInContentCoordinates, targetCSSScale); + scaleContent(m_viewport->mapToWebContent(pinchCenterInViewportCoordinates), targetCSSScale); const QPointF positionDiff = pinchCenterInViewportCoordinates - m_lastPinchCenterInViewportCoordinates; m_lastPinchCenterInViewportCoordinates = pinchCenterInViewportCoordinates; + m_content->setPos(m_content->pos() + positionDiff); } @@ -576,12 +578,12 @@ void QtViewportInteractionEngine::itemSizeChanged() ensureContentWithinViewportBoundary(); } -void QtViewportInteractionEngine::scaleContent(const QPointF& centerInContentCoordinates, qreal cssScale) +void QtViewportInteractionEngine::scaleContent(const QPointF& centerInCSSCoordinates, qreal cssScale) { - QPointF oldPinchCenterOnParent = m_content->mapToItem(m_content->parentItem(), centerInContentCoordinates); - m_content->setScale(itemScaleFromCSS(cssScale)); - QPointF newPinchCenterOnParent = m_content->mapToItem(m_content->parentItem(), centerInContentCoordinates); - m_content->setPos(m_content->pos() - (newPinchCenterOnParent - oldPinchCenterOnParent)); + QPointF oldPinchCenterOnViewport = m_viewport->mapFromWebContent(centerInCSSCoordinates); + m_content->setContentScale(itemScaleFromCSS(cssScale)); + QPointF newPinchCenterOnViewport = m_viewport->mapFromWebContent(centerInCSSCoordinates); + m_content->setPos(m_content->pos() - (newPinchCenterOnViewport - oldPinchCenterOnViewport)); } #include "moc_QtViewportInteractionEngine.cpp" diff --git a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h index 68377a41c..1790c72ed 100644 --- a/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h +++ b/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h @@ -33,6 +33,8 @@ QT_BEGIN_NAMESPACE class QPointF; class QQuickItem; +class QQuickWebPage; +class QQuickWebView; class QWheelEvent; QT_END_NAMESPACE @@ -44,7 +46,7 @@ class QtViewportInteractionEngine : public QObject { Q_OBJECT public: - QtViewportInteractionEngine(const QQuickItem*, QQuickItem*); + QtViewportInteractionEngine(const QQuickWebView*, QQuickWebPage*); ~QtViewportInteractionEngine(); struct Constraints { @@ -80,17 +82,17 @@ public: void interruptScrollAnimation(); bool panGestureActive() const; - void panGestureStarted(const QPointF& touchPoint, qint64 eventTimestampMillis); - void panGestureRequestUpdate(const QPointF& touchPoint, qint64 eventTimestampMillis); + void panGestureStarted(const QPointF& viewportTouchPoint, qint64 eventTimestampMillis); + void panGestureRequestUpdate(const QPointF& viewportTouchPoint, qint64 eventTimestampMillis); void panGestureCancelled(); - void panGestureEnded(const QPointF& touchPoint, qint64 eventTimestampMillis); + void panGestureEnded(const QPointF& viewportTouchPoint, qint64 eventTimestampMillis); bool scaleAnimationActive() const; void interruptScaleAnimation(); bool pinchGestureActive() const; - void pinchGestureStarted(const QPointF& pinchCenterInContentCoordinates); - void pinchGestureRequestUpdate(const QPointF& pinchCenterInContentCoordinates, qreal totalScaleFactor); + void pinchGestureStarted(const QPointF& pinchCenterInViewportCoordinates); + void pinchGestureRequestUpdate(const QPointF& pinchCenterInViewportCoordinates, qreal totalScaleFactor); void pinchGestureEnded(); void zoomToAreaGestureEnded(const QPointF& touchPoint, const QRectF& targetArea); @@ -127,14 +129,14 @@ private: QRectF computePosRangeForItemAtScale(qreal itemScale) const; bool ensureContentWithinViewportBoundary(bool immediate = false); - void scaleContent(const QPointF& centerInContentCoordinates, qreal scale); + void scaleContent(const QPointF& centerInCSSCoordinates, qreal cssScale); // As long as the object exists this function will always return the same QScroller instance. QScroller* scroller() { return QScroller::scroller(this); } - const QQuickItem* const m_viewport; - QQuickItem* const m_content; + const QQuickWebView* const m_viewport; + QQuickWebPage* const m_content; Constraints m_constraints; diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp index d0196880d..e5175201a 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp +++ b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp @@ -29,11 +29,13 @@ #include <QDrag> #include <QGraphicsSceneMouseEvent> #include <QGuiApplication> +#include <QInputPanel> #include <QMimeData> #include <QtQuick/QQuickCanvas> #include <QStyleHints> #include <QTextFormat> #include <QTouchEvent> +#include <QTransform> #include <WebCore/DragData.h> #include <WebCore/Editor.h> @@ -90,6 +92,7 @@ QtWebPageEventHandler::QtWebPageEventHandler(WKPageRef pageRef, QQuickWebPage* q , m_webPage(qmlWebPage) , m_previousClickButton(Qt::NoButton) , m_clickCount(0) + , m_postponeTextInputStateChanged(false) { } @@ -139,7 +142,7 @@ bool QtWebPageEventHandler::handleEvent(QEvent* ev) return true; case QEvent::InputMethod: inputMethodEvent(static_cast<QInputMethodEvent*>(ev)); - return false; // Look at comment in qquickwebpage.cpp + return false; // This is necessary to avoid an endless loop in connection with QQuickItem::event(). } // FIXME: Move all common event handling here. @@ -154,42 +157,50 @@ bool QtWebPageEventHandler::handleMouseMoveEvent(QMouseEvent* ev) // NOTE: lastPos from the event always comes empty, so we work // around that here. static QPointF lastPos = QPointF(); - if (lastPos == ev->pos()) + QTransform fromItemTransform = m_webPage->transformFromItem(); + QPointF webPagePoint = fromItemTransform.map(ev->localPos()); + if (lastPos == webPagePoint) return ev->isAccepted(); - lastPos = ev->pos(); + lastPos = webPagePoint; - m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, /*eventClickCount*/ 0)); + m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, fromItemTransform, /*eventClickCount*/ 0)); return ev->isAccepted(); } bool QtWebPageEventHandler::handleMousePressEvent(QMouseEvent* ev) { + QTransform fromItemTransform = m_webPage->transformFromItem(); + QPointF webPagePoint = fromItemTransform.map(ev->localPos()); + if (m_clickTimer.isActive() && m_previousClickButton == ev->button() - && (ev->pos() - m_lastClick).manhattanLength() < qApp->styleHints()->startDragDistance()) { + && (webPagePoint - m_lastClick).manhattanLength() < qApp->styleHints()->startDragDistance()) { m_clickCount++; } else { m_clickCount = 1; m_previousClickButton = ev->button(); } - m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, m_clickCount)); + m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, fromItemTransform, m_clickCount)); - m_lastClick = ev->pos(); + m_lastClick = webPagePoint; m_clickTimer.start(qApp->styleHints()->mouseDoubleClickInterval(), this); + return ev->isAccepted(); } bool QtWebPageEventHandler::handleMouseReleaseEvent(QMouseEvent* ev) { - m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, /*eventClickCount*/ 0)); + QTransform fromItemTransform = m_webPage->transformFromItem(); + m_webPageProxy->handleMouseEvent(NativeWebMouseEvent(ev, fromItemTransform, /*eventClickCount*/ 0)); return ev->isAccepted(); } bool QtWebPageEventHandler::handleWheelEvent(QWheelEvent* ev) { - m_webPageProxy->handleWheelEvent(NativeWebWheelEvent(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); @@ -200,14 +211,16 @@ bool 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. - QHoverEvent fakeEvent(QEvent::HoverMove, QPoint(INT_MIN, INT_MIN), ev->oldPos()); + 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); } bool QtWebPageEventHandler::handleHoverMoveEvent(QHoverEvent* ev) { - QMouseEvent me(QEvent::MouseMove, ev->pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier); + 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()); @@ -217,8 +230,9 @@ bool QtWebPageEventHandler::handleHoverMoveEvent(QHoverEvent* ev) bool QtWebPageEventHandler::handleDragEnterEvent(QDragEnterEvent* ev) { m_webPageProxy->resetDragOperation(); + QTransform fromItemTransform = m_webPage->transformFromItem(); // FIXME: Should not use QCursor::pos() - DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), dropActionToDragOperation(ev->possibleActions())); + DragData dragData(ev->mimeData(), fromItemTransform.map(ev->pos()), QCursor::pos(), dropActionToDragOperation(ev->possibleActions())); m_webPageProxy->dragEntered(&dragData); ev->acceptProposedAction(); return true; @@ -241,8 +255,9 @@ bool QtWebPageEventHandler::handleDragMoveEvent(QDragMoveEvent* ev) { bool accepted = ev->isAccepted(); + QTransform fromItemTransform = m_webPage->transformFromItem(); // FIXME: Should not use QCursor::pos() - DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), dropActionToDragOperation(ev->possibleActions())); + DragData dragData(ev->mimeData(), fromItemTransform.map(ev->pos()), QCursor::pos(), dropActionToDragOperation(ev->possibleActions())); m_webPageProxy->dragUpdated(&dragData); ev->setDropAction(dragOperationToDropAction(m_webPageProxy->dragSession().operation)); if (m_webPageProxy->dragSession().operation != DragOperationNone) @@ -255,9 +270,9 @@ bool QtWebPageEventHandler::handleDragMoveEvent(QDragMoveEvent* ev) bool QtWebPageEventHandler::handleDropEvent(QDropEvent* ev) { bool accepted = ev->isAccepted(); - + QTransform fromItemTransform = m_webPage->transformFromItem(); // FIXME: Should not use QCursor::pos() - DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), dropActionToDragOperation(ev->possibleActions())); + DragData dragData(ev->mimeData(), fromItemTransform.map(ev->pos()), QCursor::pos(), dropActionToDragOperation(ev->possibleActions())); SandboxExtension::Handle handle; m_webPageProxy->performDrag(&dragData, String(), handle); ev->setDropAction(dragOperationToDropAction(m_webPageProxy->dragSession().operation)); @@ -269,13 +284,17 @@ bool QtWebPageEventHandler::handleDropEvent(QDropEvent* ev) void QtWebPageEventHandler::handleSingleTapEvent(const QTouchEvent::TouchPoint& point) { - WebGestureEvent gesture(WebEvent::GestureSingleTap, point.pos().toPoint(), point.screenPos().toPoint(), WebEvent::Modifiers(0), 0); + m_postponeTextInputStateChanged = true; + + QTransform fromItemTransform = m_webPage->transformFromItem(); + WebGestureEvent gesture(WebEvent::GestureSingleTap, fromItemTransform.map(point.pos()).toPoint(), point.screenPos().toPoint(), WebEvent::Modifiers(0), 0); m_webPageProxy->handleGestureEvent(gesture); } void QtWebPageEventHandler::handleDoubleTapEvent(const QTouchEvent::TouchPoint& point) { - m_webPageProxy->findZoomableAreaForPoint(point.pos().toPoint()); + QTransform fromItemTransform = m_webPage->transformFromItem(); + m_webPageProxy->findZoomableAreaForPoint(fromItemTransform.map(point.pos()).toPoint()); } void QtWebPageEventHandler::timerEvent(QTimerEvent* ev) @@ -386,11 +405,12 @@ void QtWebPageEventHandler::inputMethodEvent(QInputMethodEvent* ev) void QtWebPageEventHandler::touchEvent(QTouchEvent* event) { #if ENABLE(TOUCH_EVENTS) - m_webPageProxy->handleTouchEvent(NativeWebTouchEvent(event)); + QTransform fromItemTransform = m_webPage->transformFromItem(); + m_webPageProxy->handleTouchEvent(NativeWebTouchEvent(event, fromItemTransform)); event->accept(); #else ASSERT_NOT_REACHED(); - ev->ignore(); + event->ignore(); #endif } @@ -401,6 +421,42 @@ void QtWebPageEventHandler::resetGestureRecognizers() m_tapGestureRecognizer.reset(); } +static void setInputPanelVisible(bool visible) +{ + if (qApp->inputPanel()->visible() == visible) + return; + + qApp->inputPanel()->setVisible(visible); +} + +void QtWebPageEventHandler::updateTextInputState() +{ + if (m_postponeTextInputStateChanged) + return; + + const EditorState& editor = m_webPageProxy->editorState(); + + // Ignore input method requests not due to a tap gesture. + if (!editor.isContentEditable) + setInputPanelVisible(false); +} + +void QtWebPageEventHandler::doneWithGestureEvent(const WebGestureEvent& event, bool wasEventHandled) +{ + if (event.type() != WebEvent::GestureSingleTap) + return; + + m_postponeTextInputStateChanged = false; + + if (!wasEventHandled) + return; + + const EditorState& editor = m_webPageProxy->editorState(); + bool newVisible = editor.isContentEditable; + + setInputPanelVisible(newVisible); +} + void QtWebPageEventHandler::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled) { if (!m_interactionEngine) diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h index dfab4c8b9..f5b7fb317 100644 --- a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h +++ b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.h @@ -52,6 +52,8 @@ public: void didFindZoomableArea(const WebCore::IntPoint& target, const WebCore::IntRect& area); void focusEditableArea(const WebCore::IntRect& caret, const WebCore::IntRect& area); + void updateTextInputState(); + void doneWithGestureEvent(const WebGestureEvent& event, bool wasEventHandled); void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled); void resetGestureRecognizers(); @@ -88,10 +90,11 @@ private: void touchEvent(QTouchEvent*); void inputMethodEvent(QInputMethodEvent*); - QPoint m_lastClick; + QPointF m_lastClick; QBasicTimer m_clickTimer; Qt::MouseButton m_previousClickButton; int m_clickCount; + bool m_postponeTextInputStateChanged; }; #endif /* QtWebPageEventHandler_h */ |