diff options
Diffstat (limited to 'Source/WebKit/blackberry')
20 files changed, 1066 insertions, 427 deletions
diff --git a/Source/WebKit/blackberry/Api/BackingStore.cpp b/Source/WebKit/blackberry/Api/BackingStore.cpp index 61b90cc24..3daa490d5 100644 --- a/Source/WebKit/blackberry/Api/BackingStore.cpp +++ b/Source/WebKit/blackberry/Api/BackingStore.cpp @@ -200,12 +200,14 @@ BackingStorePrivate::BackingStorePrivate() , m_resumeOperation(BackingStore::None) , m_suspendRenderJobs(false) , m_suspendRegularRenderJobs(false) + , m_tileMatrixNeedsUpdate(false) , m_isScrollingOrZooming(false) , m_webPage(0) , m_client(0) , m_renderQueue(adoptPtr(new RenderQueue(this))) , m_defersBlit(true) , m_hasBlitJobs(false) + , m_webPageBackgroundColor(WebCore::Color::white) , m_currentWindowBackBuffer(0) , m_preferredTileMatrixDimension(Vertical) #if USE(ACCELERATED_COMPOSITING) @@ -278,14 +280,22 @@ bool BackingStorePrivate::isOpenGLCompositing() const return true; } -void BackingStorePrivate::suspendScreenAndBackingStoreUpdates() +void BackingStorePrivate::suspendBackingStoreUpdates() { - if (m_suspendScreenUpdates) { + if (atomic_add_value(&m_suspendBackingStoreUpdates, 0)) { BBLOG(BlackBerry::Platform::LogLevelInfo, - "Screen and backingstore already suspended, increasing suspend counter."); + "Backingstore already suspended, increasing suspend counter."); } - ++m_suspendBackingStoreUpdates; + atomic_add(&m_suspendBackingStoreUpdates, 1); +} + +void BackingStorePrivate::suspendScreenUpdates() +{ + if (m_suspendScreenUpdates) { + BBLOG(BlackBerry::Platform::LogLevelInfo, + "Screen already suspended, increasing suspend counter."); + } // Make sure the user interface thread gets the message before we proceed // because blitVisibleContents() can be called from the user interface @@ -295,17 +305,32 @@ void BackingStorePrivate::suspendScreenAndBackingStoreUpdates() BlackBerry::Platform::userInterfaceThreadMessageClient()->syncToCurrentMessage(); } -void BackingStorePrivate::resumeScreenAndBackingStoreUpdates(BackingStore::ResumeUpdateOperation op) +void BackingStorePrivate::resumeBackingStoreUpdates() { - ASSERT(m_suspendScreenUpdates); - ASSERT(m_suspendBackingStoreUpdates); + unsigned currentValue = atomic_add_value(&m_suspendBackingStoreUpdates, 0); + ASSERT(currentValue >= 1); + if (currentValue < 1) { + BlackBerry::Platform::logAlways(BlackBerry::Platform::LogLevelCritical, + "Call mismatch: Backingstore hasn't been suspended, therefore won't resume!"); + return; + } + + // Set a flag indicating that we're about to resume backingstore updates and + // the tile matrix should be updated as a consequence by the first render + // job that happens after this resumption of backingstore updates. + if (currentValue == 1) + setTileMatrixNeedsUpdate(); + + atomic_sub(&m_suspendBackingStoreUpdates, 1); +} - // Both variables are similar except for the timing of setting them. - ASSERT(m_suspendScreenUpdates == m_suspendBackingStoreUpdates); +void BackingStorePrivate::resumeScreenUpdates(BackingStore::ResumeUpdateOperation op) +{ + ASSERT(m_suspendScreenUpdates); - if (!m_suspendScreenUpdates || !m_suspendBackingStoreUpdates) { + if (!m_suspendScreenUpdates) { BlackBerry::Platform::logAlways(BlackBerry::Platform::LogLevelCritical, - "Call mismatch: Screen and backingstore haven't been suspended, therefore won't resume!"); + "Call mismatch: Screen hasn't been suspended, therefore won't resume!"); return; } @@ -314,16 +339,13 @@ void BackingStorePrivate::resumeScreenAndBackingStoreUpdates(BackingStore::Resum || (m_resumeOperation == BackingStore::None && op == BackingStore::Blit)) m_resumeOperation = op; - if (m_suspendScreenUpdates >= 2 && m_suspendBackingStoreUpdates >= 2) { // we're still suspended + if (m_suspendScreenUpdates >= 2) { // we're still suspended BBLOG(BlackBerry::Platform::LogLevelInfo, "Screen and backingstore still suspended, decreasing suspend counter."); - --m_suspendBackingStoreUpdates; --m_suspendScreenUpdates; return; } - --m_suspendBackingStoreUpdates; - op = m_resumeOperation; m_resumeOperation = BackingStore::None; @@ -375,9 +397,6 @@ void BackingStorePrivate::resumeScreenAndBackingStoreUpdates(BackingStore::Resum void BackingStorePrivate::repaint(const Platform::IntRect& windowRect, bool contentChanged, bool immediate) { - if (m_suspendBackingStoreUpdates) - return; - // If immediate is true, then we're being asked to perform synchronously. // NOTE: WebCore::ScrollView will call this method with immediate:true and contentChanged:false. // This is a special case introduced specifically for the Apple's windows port and can be safely ignored I believe. @@ -406,6 +425,9 @@ void BackingStorePrivate::repaint(const Platform::IntRect& windowRect, #endif if (immediate) { + if (m_suspendBackingStoreUpdates) + return; + if (render(rect)) { if (!shouldDirectRenderingToWindow() && !m_webPage->d->commitRootLayerIfNeeded()) blitVisibleContents(); @@ -701,6 +723,9 @@ void BackingStorePrivate::setBackingStoreRect(const Platform::IntRect& backingSt return; } + if (m_suspendBackingStoreUpdates) + return; + Platform::IntRect currentBackingStoreRect = frontState()->backingStoreRect(); double currentScale = frontState()->scale(); @@ -1039,6 +1064,11 @@ bool BackingStorePrivate::render(const Platform::IntRect& rect) if (!isActive()) return false; + // This is the first render job that has been performed since resumption of + // backingstore updates and the tile matrix needs updating since we suspend + // tile matrix updating with backingstore updates + updateTileMatrixIfNeeded(); + TileRectList tileRectList = mapFromTransformedContentsToTiles(rect); if (tileRectList.isEmpty()) return false; @@ -1144,6 +1174,7 @@ void BackingStorePrivate::requestLayoutIfNeeded() const bool BackingStorePrivate::renderVisibleContents() { + updateTileMatrixIfNeeded(); Platform::IntRect renderRect = shouldDirectRenderingToWindow() ? visibleContentsRect() : visibleTilesRect(); if (render(renderRect)) { m_renderQueue->clear(renderRect, true /*clearRegularRenderJobs*/); @@ -1154,6 +1185,7 @@ bool BackingStorePrivate::renderVisibleContents() bool BackingStorePrivate::renderBackingStore() { + updateTileMatrixIfNeeded(); return render(frontState()->backingStoreRect()); } @@ -1289,6 +1321,10 @@ void BackingStorePrivate::blitVisibleContents(bool force) viewportAccessor->scale()); #endif +#if DEBUG_CHECKERBOARD + bool blitCheckered = false; +#endif + Vector<TileBuffer*> blittedTiles; if (isActive() && !m_webPage->d->compositorDrawsRootLayer()) { @@ -1315,10 +1351,6 @@ void BackingStorePrivate::blitVisibleContents(bool force) if (!transformedSrcRect.isEmpty()) transformation = TransformationMatrix::rectToRect(FloatRect(FloatPoint(0.0, 0.0), WebCore::IntSize(transformedSrcRect.size())), WebCore::IntRect(dstRect)); -#if DEBUG_CHECKERBOARD - bool blitCheckered = false; -#endif - // Don't clip to contents if it is empty so we can still paint default background. if (!transformedContentsRect.isEmpty()) { clippedTransformedSrcRect.intersect(transformedContentsRect); @@ -1949,12 +1981,18 @@ void BackingStorePrivate::updateTileMatrixIfNeeded() { ASSERT(BlackBerry::Platform::webKitThreadMessageClient()->isCurrentThread()); + if (!m_tileMatrixNeedsUpdate) + return; + + m_tileMatrixNeedsUpdate = false; + // This will update the tile matrix. scrollBackingStore(0, 0); } void BackingStorePrivate::contentsSizeChanged(const Platform::IntSize&) { + setTileMatrixNeedsUpdate(); updateTileMatrixIfNeeded(); } @@ -2023,6 +2061,7 @@ void BackingStorePrivate::transformChanged() void BackingStorePrivate::orientationChanged() { ASSERT(BlackBerry::Platform::webKitThreadMessageClient()->isCurrentThread()); + setTileMatrixNeedsUpdate(); updateTileMatrixIfNeeded(); createVisibleTileBuffer(); } @@ -2053,6 +2092,10 @@ void BackingStorePrivate::createSurfaces() return; } + // Don't try to blit to screen unless we have a buffer. + if (!buffer()) + suspendScreenUpdates(); + SurfacePool* surfacePool = SurfacePool::globalSurfacePool(); surfacePool->initialize(tileSize()); @@ -2085,10 +2128,6 @@ void BackingStorePrivate::createSurfaces() swapState(); createVisibleTileBufferForWebPage(m_webPage->d); - - // Don't try to blit to screen unless we have a buffer. - if (!buffer()) - suspendScreenAndBackingStoreUpdates(); } void BackingStorePrivate::createVisibleTileBuffer() @@ -2366,9 +2405,38 @@ void BackingStorePrivate::fillWindow(Platform::Graphics::FillPattern pattern, "Empty window buffer, couldn't fillWindow"); } + if (pattern == BlackBerry::Platform::Graphics::CheckerboardPattern && BlackBerry::Platform::Settings::isPublicBuild()) { + // For public builds, convey the impression of less checkerboard. + // For developer builds, keep the checkerboard to get it fixed better. + BlackBerry::Platform::Graphics::clearBuffer(dstBuffer, dstRect, + m_webPageBackgroundColor.red(), m_webPageBackgroundColor.green(), + m_webPageBackgroundColor.blue(), m_webPageBackgroundColor.alpha()); + return; + } + BlackBerry::Platform::Graphics::fillBuffer(dstBuffer, pattern, dstRect, contentsOrigin, contentsScale); } +WebCore::Color BackingStorePrivate::webPageBackgroundColorUserInterfaceThread() const +{ + ASSERT(BlackBerry::Platform::userInterfaceThreadMessageClient()->isCurrentThread()); + return m_webPageBackgroundColor; +} + +void BackingStorePrivate::setWebPageBackgroundColor(const WebCore::Color& color) +{ + if (!BlackBerry::Platform::userInterfaceThreadMessageClient()->isCurrentThread()) { + typedef void (BlackBerry::WebKit::BackingStorePrivate::*FunctionType)(const WebCore::Color&); + + BlackBerry::Platform::userInterfaceThreadMessageClient()->dispatchMessage( + BlackBerry::Platform::createMethodCallMessage<FunctionType, BackingStorePrivate, WebCore::Color>( + &BackingStorePrivate::setWebPageBackgroundColor, this, color)); + return; + } + + m_webPageBackgroundColor = color; +} + void BackingStorePrivate::invalidateWindow() { // Grab a rect appropriate for the current thread. @@ -2490,6 +2558,8 @@ void BackingStorePrivate::setScrollingOrZooming(bool scrollingOrZooming, bool sh else if (shouldBlit && !shouldDirectRenderingToWindow()) blitVisibleContents(); #endif + if (!scrollingOrZooming && shouldPerformRegularRenderJobs()) + dispatchRenderJob(); } void BackingStorePrivate::lockBackingStore() @@ -2602,14 +2672,24 @@ void BackingStore::createSurface() d->m_webPage->setFocused(true); } -void BackingStore::suspendScreenAndBackingStoreUpdates() +void BackingStore::suspendBackingStoreUpdates() +{ + d->suspendBackingStoreUpdates(); +} + +void BackingStore::resumeBackingStoreUpdates() +{ + d->resumeBackingStoreUpdates(); +} + +void BackingStore::suspendScreenUpdates() { - d->suspendScreenAndBackingStoreUpdates(); + d->suspendScreenUpdates(); } -void BackingStore::resumeScreenAndBackingStoreUpdates(ResumeUpdateOperation op) +void BackingStore::resumeScreenUpdates(ResumeUpdateOperation op) { - d->resumeScreenAndBackingStoreUpdates(op); + d->resumeScreenUpdates(op); } bool BackingStore::isScrollingOrZooming() const @@ -2643,10 +2723,14 @@ void BackingStore::createBackingStoreMemory() { if (BackingStorePrivate::s_currentBackingStoreOwner == d->m_webPage) SurfacePool::globalSurfacePool()->createBuffers(); + resumeBackingStoreUpdates(); + resumeScreenUpdates(BackingStore::RenderAndBlit); } void BackingStore::releaseBackingStoreMemory() { + suspendBackingStoreUpdates(); + suspendScreenUpdates(); if (BackingStorePrivate::s_currentBackingStoreOwner == d->m_webPage) SurfacePool::globalSurfacePool()->releaseBuffers(); } diff --git a/Source/WebKit/blackberry/Api/BackingStore.h b/Source/WebKit/blackberry/Api/BackingStore.h index 2501c98d9..a5f99b7db 100644 --- a/Source/WebKit/blackberry/Api/BackingStore.h +++ b/Source/WebKit/blackberry/Api/BackingStore.h @@ -53,8 +53,11 @@ public: void createSurface(); - void suspendScreenAndBackingStoreUpdates(); - void resumeScreenAndBackingStoreUpdates(ResumeUpdateOperation); + void suspendBackingStoreUpdates(); + void resumeBackingStoreUpdates(); + + void suspendScreenUpdates(); + void resumeScreenUpdates(BackingStore::ResumeUpdateOperation); bool isScrollingOrZooming() const; void setScrollingOrZooming(bool); diff --git a/Source/WebKit/blackberry/Api/BackingStore_p.h b/Source/WebKit/blackberry/Api/BackingStore_p.h index 8e52a12ae..455217871 100644 --- a/Source/WebKit/blackberry/Api/BackingStore_p.h +++ b/Source/WebKit/blackberry/Api/BackingStore_p.h @@ -20,6 +20,7 @@ #define BackingStore_p_h #include "BackingStore.h" +#include "Color.h" #include "RenderQueue.h" #include "TileIndex.h" #include "TileIndexHash.h" @@ -126,11 +127,17 @@ public: bool isSuspended() const { return m_suspendBackingStoreUpdates; } + // Suspends all backingstore updates so that rendering to the backingstore is disabled. + void suspendBackingStoreUpdates(); + + // Resumes all backingstore updates so that rendering to the backingstore is enabled. + void resumeBackingStoreUpdates(); + // Suspends all screen updates so that 'blitVisibleContents' is disabled. - void suspendScreenAndBackingStoreUpdates(); + void suspendScreenUpdates(); // Resumes all screen updates so that 'blitVisibleContents' is enabled. - void resumeScreenAndBackingStoreUpdates(BackingStore::ResumeUpdateOperation); + void resumeScreenUpdates(BackingStore::ResumeUpdateOperation); // The functions repaint(), slowScroll(), scroll(), scrollingStartedHelper() are // called from outside WebKit and within WebKit via ChromeClientBlackBerry. @@ -275,6 +282,7 @@ public: TileRectList mapFromTransformedContentsToTiles(const Platform::IntRect&) const; TileRectList mapFromTransformedContentsToTiles(const Platform::IntRect&, BackingStoreGeometry*) const; + void setTileMatrixNeedsUpdate() { m_tileMatrixNeedsUpdate = true; } void updateTileMatrixIfNeeded(); // Called by WebPagePrivate::notifyTransformedContentsSizeChanged. @@ -319,6 +327,9 @@ public: void blitToWindow(const Platform::IntRect& dstRect, const BlackBerry::Platform::Graphics::Buffer* srcBuffer, const Platform::IntRect& srcRect, bool blend, unsigned char globalAlpha); void fillWindow(Platform::Graphics::FillPattern, const Platform::IntRect& dstRect, const Platform::IntPoint& contentsOrigin, double contentsScale); + WebCore::Color webPageBackgroundColorUserInterfaceThread() const; // use WebSettings::backgroundColor() for the WebKit thread + void setWebPageBackgroundColor(const WebCore::Color&); + void invalidateWindow(); void invalidateWindow(const Platform::IntRect& dst); void clearWindow(const Platform::IntRect&, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha = 255); @@ -354,6 +365,7 @@ public: bool m_suspendRenderJobs; bool m_suspendRegularRenderJobs; + bool m_tileMatrixNeedsUpdate; bool m_isScrollingOrZooming; WebPage* m_webPage; BackingStoreClient* m_client; @@ -363,6 +375,8 @@ public: bool m_defersBlit; bool m_hasBlitJobs; + WebCore::Color m_webPageBackgroundColor; // for user interface thread operations such as blitting + mutable unsigned m_frontState; mutable unsigned m_backState; diff --git a/Source/WebKit/blackberry/Api/WebPage.cpp b/Source/WebKit/blackberry/Api/WebPage.cpp index a2b354a5c..bd372b961 100644 --- a/Source/WebKit/blackberry/Api/WebPage.cpp +++ b/Source/WebKit/blackberry/Api/WebPage.cpp @@ -72,6 +72,7 @@ #include "HTTPParsers.h" #include "HistoryItem.h" #include "IconDatabaseClientBlackBerry.h" +#include "ImageDocument.h" #include "InPageSearchManager.h" #include "InRegionScrollableArea.h" #include "InRegionScroller_p.h" @@ -222,6 +223,7 @@ const IntSize minimumLayoutSize(10, 10); // Needs to be a small size, greater th const double minimumExpandingRatio = 0.15; const double minimumZoomToFitScale = 0.25; +const double maximumImageDocumentZoomToFitScale = 2; // Helper function to parse a URL and fill in missing parts. static KURL parseUrl(const String& url) @@ -417,12 +419,11 @@ WebPagePrivate::WebPagePrivate(WebPage* webPage, WebPageClient* client, const In , m_needsCommit(false) , m_suspendRootLayerCommit(false) #endif - , m_hasPendingSurfaceSizeChange(false) , m_pendingOrientation(-1) , m_fullscreenVideoNode(0) , m_hasInRegionScrollableAreas(false) , m_updateDelegatedOverlaysDispatched(false) - , m_enableQnxJavaScriptObject(true) + , m_enableQnxJavaScriptObject(false) , m_deferredTasksTimer(this, &WebPagePrivate::deferredTasksTimerFired) , m_selectPopup(0) , m_autofillManager(AutofillManager::create(this)) @@ -571,9 +572,6 @@ void WebPagePrivate::init(const BlackBerry::Platform::String& pageGroupName) WebCore::provideNetworkInfoTo(m_page, new WebCore::NetworkInfoClientBlackBerry(this)); #endif - m_page->setCustomHTMLTokenizerChunkSize(256); - m_page->setCustomHTMLTokenizerTimeDelay(0.3); - m_webSettings = WebSettings::createFromStandardSettings(); m_webSettings->setUserAgentString(defaultUserAgent()); m_page->setDeviceScaleFactor(m_webSettings->devicePixelRatio()); @@ -1033,6 +1031,11 @@ void WebPagePrivate::setLoadState(LoadState state) if (state == Finished && m_mainFrame && m_mainFrame->document()) m_mainFrame->document()->updateStyleIfNeeded(); + // Dispatch the backingstore background color at important state changes. + m_backingStore->d->setWebPageBackgroundColor(m_mainFrame && m_mainFrame->view() + ? m_mainFrame->view()->documentBackgroundColor() + : m_webSettings->backgroundColor()); + m_loadState = state; #if DEBUG_WEBPAGE_LOAD @@ -1065,7 +1068,9 @@ void WebPagePrivate::setLoadState(LoadState state) #endif // Suspend screen update to avoid ui thread blitting while resetting backingstore. - m_backingStore->d->suspendScreenAndBackingStoreUpdates(); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->suspendBackingStoreUpdates(); + m_backingStore->d->suspendScreenUpdates(); m_previousContentsSize = IntSize(); m_backingStore->d->resetRenderQueue(); @@ -1121,7 +1126,9 @@ void WebPagePrivate::setLoadState(LoadState state) setScrollPosition(IntPoint::zero()); notifyTransformedScrollChanged(); - m_backingStore->d->resumeScreenAndBackingStoreUpdates(BackingStore::None); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->resumeBackingStoreUpdates(); + m_backingStore->d->resumeScreenUpdates(BackingStore::None); // Paints the visible backingstore as white. Note it is important we do // this strictly after re-setting the scroll position to origin and resetting @@ -1223,7 +1230,9 @@ bool WebPagePrivate::zoomAboutPoint(double unclampedScale, const FloatPoint& anc *m_transformationMatrix = zoom; // Suspend all screen updates to the backingstore. - m_backingStore->d->suspendScreenAndBackingStoreUpdates(); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->suspendBackingStoreUpdates(); + m_backingStore->d->suspendScreenUpdates(); updateViewportSize(); @@ -1263,13 +1272,16 @@ bool WebPagePrivate::zoomAboutPoint(double unclampedScale, const FloatPoint& anc if (m_pendingOrientation != -1) m_client->updateInteractionViews(); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->resumeBackingStoreUpdates(); + // Clear window to make sure there are no artifacts. if (shouldRender) { // Resume all screen updates to the backingstore and render+blit visible contents to screen. - m_backingStore->d->resumeScreenAndBackingStoreUpdates(BackingStore::RenderAndBlit); + m_backingStore->d->resumeScreenUpdates(BackingStore::RenderAndBlit); } else { // Resume all screen updates to the backingstore but do not blit to the screen because we not rendering. - m_backingStore->d->resumeScreenAndBackingStoreUpdates(BackingStore::None); + m_backingStore->d->resumeScreenUpdates(BackingStore::None); } return true; @@ -1660,12 +1672,24 @@ void WebPagePrivate::zoomToInitialScaleOnLoad() double WebPagePrivate::zoomToFitScale() const { int contentWidth = contentsSize().width(); - int contentHeight = contentsSize().height(); + + // For image document, zoom to fit the screen based on the actual image width + // instead of the contents width within a maximum scale . + Document* doc = m_page->mainFrame()->document(); + bool isImageDocument = doc && doc->isImageDocument(); + if (isImageDocument) + contentWidth = static_cast<ImageDocument*>(doc)->imageSize().width(); + double zoomToFitScale = contentWidth > 0.0 ? static_cast<double>(m_actualVisibleWidth) / contentWidth : 1.0; + int contentHeight = contentsSize().height(); if (contentHeight * zoomToFitScale < static_cast<double>(m_defaultLayoutSize.height())) zoomToFitScale = contentHeight > 0 ? static_cast<double>(m_defaultLayoutSize.height()) / contentHeight : 1.0; + zoomToFitScale = std::max(zoomToFitScale, minimumZoomToFitScale); + + if (!isImageDocument) + return zoomToFitScale; - return std::max(zoomToFitScale, minimumZoomToFitScale); + return std::min(zoomToFitScale, maximumImageDocumentZoomToFitScale); } double WebPagePrivate::initialScale() const @@ -2234,11 +2258,6 @@ Platform::WebContext WebPagePrivate::webContext(TargetDetectionStrategy strategy return context; } - // Unpress the mouse button if we're actually getting context. - EventHandler* eventHandler = focusedOrMainFrame()->eventHandler(); - if (eventHandler->mousePressed()) - eventHandler->setMousePressed(false); - requestLayoutIfNeeded(); bool nodeAllowSelectionOverride = false; @@ -2328,6 +2347,10 @@ Platform::WebContext WebPagePrivate::webContext(TargetDetectionStrategy strategy String elementText(DOMSupport::inputElementText(element)); if (!elementText.stripWhiteSpace().isEmpty()) context.setText(elementText); + else if (!node->focused() && m_touchEventHandler->lastFatFingersResult().isValid() && strategy == RectBased) { + // If an input field is empty and not focused send a mouse click so that it gets a cursor and we can paste into it. + m_touchEventHandler->sendClickAtFatFingersPoint(); + } } } @@ -2624,17 +2647,19 @@ PassRefPtr<Node> WebPagePrivate::contextNode(TargetDetectionStrategy strategy) if (isTouching && lastFatFingersResult.isTextInput()) return lastFatFingersResult.node(FatFingersResult::ShadowContentNotAllowed); + if (strategy == RectBased) { + FatFingersResult result = FatFingers(this, lastFatFingersResult.adjustedPosition(), FatFingers::Text).findBestPoint(); + return result.node(FatFingersResult::ShadowContentNotAllowed); + } + if (strategy == FocusBased) + return m_inputHandler->currentFocusElement(); + IntPoint contentPos; if (isTouching) contentPos = lastFatFingersResult.adjustedPosition(); else contentPos = mapFromViewportToContents(m_lastMouseEvent.position()); - if (strategy == RectBased) { - FatFingersResult result = FatFingers(this, lastFatFingersResult.adjustedPosition(), FatFingers::Text).findBestPoint(); - return result.node(FatFingersResult::ShadowContentNotAllowed); - } - HitTestResult result = eventHandler->hitTestResultAtPoint(contentPos, false /*allowShadowContent*/); return result.innerNode(); } @@ -2701,12 +2726,12 @@ double WebPagePrivate::maxBlockZoomScale() const return std::min(maximumBlockZoomScale, maximumScale()); } -Node* WebPagePrivate::nodeForZoomUnderPoint(const IntPoint& point) +Node* WebPagePrivate::nodeForZoomUnderPoint(const IntPoint& documentPoint) { if (!m_mainFrame) return 0; - HitTestResult result = m_mainFrame->eventHandler()->hitTestResultAtPoint(mapFromTransformed(point), false); + HitTestResult result = m_mainFrame->eventHandler()->hitTestResultAtPoint(documentPoint, false); Node* node = result.innerNonSharedNode(); @@ -2932,7 +2957,9 @@ void WebPagePrivate::zoomBlock() zoom.scale(m_blockZoomFinalScale); *m_transformationMatrix = zoom; m_client->resetBitmapZoomScale(m_blockZoomFinalScale); - m_backingStore->d->suspendScreenAndBackingStoreUpdates(); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->suspendBackingStoreUpdates(); + m_backingStore->d->suspendScreenUpdates(); updateViewportSize(); #if ENABLE(VIEWPORT_REFLOW) @@ -2989,7 +3016,9 @@ void WebPagePrivate::zoomBlock() notifyTransformChanged(); m_client->scaleChanged(); - m_backingStore->d->resumeScreenAndBackingStoreUpdates(BackingStore::RenderAndBlit); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->resumeBackingStoreUpdates(); + m_backingStore->d->resumeScreenUpdates(BackingStore::RenderAndBlit); } void WebPage::blockZoomAnimationFinished() @@ -3026,7 +3055,9 @@ void WebPage::destroy() disableWebInspector(); // WebPage::destroyWebPageCompositor() - d->m_backingStore->d->suspendScreenAndBackingStoreUpdates(); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + d->m_backingStore->d->suspendBackingStoreUpdates(); + d->m_backingStore->d->suspendScreenUpdates(); // Close the backforward list and release the cached pages. d->m_page->backForward()->close(); @@ -3525,12 +3556,6 @@ void WebPagePrivate::setScreenOrientation(int orientation) void WebPage::setScreenOrientation(int orientation) { d->m_pendingOrientation = orientation; - d->m_hasPendingSurfaceSizeChange = true; -} - -void WebPage::setHasPendingSurfaceSizeChange() -{ - d->m_hasPendingSurfaceSizeChange = true; } void WebPage::applyPendingOrientationIfNeeded() @@ -3539,29 +3564,16 @@ void WebPage::applyPendingOrientationIfNeeded() d->setScreenOrientation(d->m_pendingOrientation); } -void WebPagePrivate::resizeSurfaceIfNeeded() -{ - // This call will cause the client to reallocate the window buffer to new size, - // which needs to be serialized with usage of the window buffer. Accomplish - // this by sending a sync message to the compositing thread. All other usage of - // the window buffer happens on the compositing thread. - if (!Platform::userInterfaceThreadMessageClient()->isCurrentThread()) { - Platform::userInterfaceThreadMessageClient()->dispatchSyncMessage( - Platform::createMethodCallMessage(&WebPagePrivate::resizeSurfaceIfNeeded, this)); - return; - } - - m_client->resizeSurfaceIfNeeded(); -} - void WebPagePrivate::setViewportSize(const IntSize& transformedActualVisibleSize, bool ensureFocusElementVisible) { - if (m_pendingOrientation == -1 && !m_hasPendingSurfaceSizeChange && transformedActualVisibleSize == this->transformedActualVisibleSize()) + if (m_pendingOrientation == -1 && transformedActualVisibleSize == this->transformedActualVisibleSize()) return; // Suspend all screen updates to the backingstore to make sure no-one tries to blit // while the window surface and the BackingStore are out of sync. - m_backingStore->d->suspendScreenAndBackingStoreUpdates(); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->suspendBackingStoreUpdates(); + m_backingStore->d->suspendScreenUpdates(); // The screen rotation is a major state transition that in this case is not properly // communicated to the backing store, since it does early return in most methods when @@ -3571,11 +3583,6 @@ void WebPagePrivate::setViewportSize(const IntSize& transformedActualVisibleSize bool hasPendingOrientation = m_pendingOrientation != -1; - if (m_hasPendingSurfaceSizeChange) { - resizeSurfaceIfNeeded(); - m_hasPendingSurfaceSizeChange = false; - } - // The window buffers might have been recreated, cleared, moved, etc., so: m_backingStore->d->windowFrontBufferState()->clearBlittedRegion(); m_backingStore->d->windowBackBufferState()->clearBlittedRegion(); @@ -3680,7 +3687,9 @@ void WebPagePrivate::setViewportSize(const IntSize& transformedActualVisibleSize // Need to resume so that the backingstore will start recording the invalidated // rects from below. - m_backingStore->d->resumeScreenAndBackingStoreUpdates(BackingStore::None); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->resumeBackingStoreUpdates(); + m_backingStore->d->resumeScreenUpdates(BackingStore::None); // We might need to layout here to get a correct contentsSize so that zoomToFit // is calculated correctly. @@ -3753,7 +3762,9 @@ void WebPagePrivate::setViewportSize(const IntSize& transformedActualVisibleSize } else { // Suspend all screen updates to the backingstore. - m_backingStore->d->suspendScreenAndBackingStoreUpdates(); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->suspendBackingStoreUpdates(); + m_backingStore->d->suspendScreenUpdates(); // If the zoom failed, then we should still preserve the special case of scroll position. IntPoint scrollPosition = this->scrollPosition(); @@ -3781,7 +3792,9 @@ void WebPagePrivate::setViewportSize(const IntSize& transformedActualVisibleSize } // If we need layout then render and blit, otherwise just blit as our viewport has changed. - m_backingStore->d->resumeScreenAndBackingStoreUpdates(needsLayout ? BackingStore::RenderAndBlit : BackingStore::Blit); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->resumeBackingStoreUpdates(); + m_backingStore->d->resumeScreenUpdates(needsLayout ? BackingStore::RenderAndBlit : BackingStore::Blit); } } @@ -3993,11 +4006,6 @@ bool WebPage::touchEvent(const Platform::TouchEvent& event) if (d->m_needTouchEvents && !event.m_type != Platform::TouchEvent::TouchInjected) handled = d->m_mainFrame->eventHandler()->handleTouchEvent(PlatformTouchEvent(&tEvent)); - // Unpress mouse if touch end is consumed by a JavaScript touch handler, otherwise the mouse state will remain pressed - // which could either mess up the internal mouse state or start text selection on the next mouse move/down. - if (tEvent.m_type == Platform::TouchEvent::TouchEnd && handled && d->m_mainFrame->eventHandler()->mousePressed()) - d->m_touchEventHandler->touchEventCancel(); - if (d->m_preventDefaultOnTouchStart) { if (tEvent.m_type == Platform::TouchEvent::TouchEnd || tEvent.m_type == Platform::TouchEvent::TouchCancel) d->m_preventDefaultOnTouchStart = false; @@ -4011,7 +4019,8 @@ bool WebPage::touchEvent(const Platform::TouchEvent& event) } if (event.isTouchHold()) - d->m_touchEventHandler->touchHoldEvent(); + d->m_touchEventHandler->doFatFingers(tEvent.m_points[0]); + #endif return false; @@ -4094,14 +4103,14 @@ bool WebPagePrivate::dispatchTouchEventToFullScreenPlugin(PluginView* plugin, co return handled; } -bool WebPage::touchPointAsMouseEvent(const Platform::TouchPoint& point, bool useFatFingers) +void WebPage::touchPointAsMouseEvent(const Platform::TouchPoint& point) { if (d->m_page->defersLoading()) - return false; + return; PluginView* pluginView = d->m_fullScreenPluginView.get(); if (pluginView) - return d->dispatchTouchPointAsMouseEventToFullScreenPlugin(pluginView, point); + d->dispatchTouchPointAsMouseEventToFullScreenPlugin(pluginView, point); d->m_lastUserEventTimestamp = currentTime(); @@ -4109,7 +4118,12 @@ bool WebPage::touchPointAsMouseEvent(const Platform::TouchPoint& point, bool use tPoint.m_pos = d->mapFromTransformed(tPoint.m_pos); tPoint.m_screenPos = tPoint.m_screenPos; - return d->m_touchEventHandler->handleTouchPoint(tPoint, useFatFingers); + d->m_touchEventHandler->handleTouchPoint(tPoint); +} + +void WebPage::playSoundIfAnchorIsTarget() const +{ + d->m_touchEventHandler->playSoundIfAnchorIsTarget(); } bool WebPagePrivate::dispatchTouchPointAsMouseEventToFullScreenPlugin(PluginView* pluginView, const Platform::TouchPoint& point) @@ -4146,7 +4160,6 @@ void WebPage::touchEventCancel() d->m_pluginMayOpenNewTab = false; if (d->m_page->defersLoading()) return; - d->m_touchEventHandler->touchEventCancel(); } Frame* WebPagePrivate::focusedOrMainFrame() const @@ -5136,12 +5149,16 @@ void WebPage::enableWebInspector() d->m_page->inspectorController()->connectFrontend(d->m_inspectorClient); d->m_page->settings()->setDeveloperExtrasEnabled(true); + d->setPreventsScreenDimming(true); } void WebPage::disableWebInspector() { - d->m_page->inspectorController()->disconnectFrontend(); - d->m_page->settings()->setDeveloperExtrasEnabled(false); + if (isWebInspectorEnabled()) { + d->m_page->inspectorController()->disconnectFrontend(); + d->m_page->settings()->setDeveloperExtrasEnabled(false); + d->setPreventsScreenDimming(false); + } } bool WebPage::isWebInspectorEnabled() @@ -5261,14 +5278,14 @@ void WebPagePrivate::setCompositor(PassRefPtr<WebPageCompositorPrivate> composit ASSERT(webKitThreadMessageClient()->isCurrentThread()); if (m_compositor || m_client->window()) - m_backingStore->d->suspendScreenAndBackingStoreUpdates(); + m_backingStore->d->suspendScreenUpdates(); // The m_compositor member has to be modified during a sync call for thread // safe access to m_compositor and its refcount. userInterfaceThreadMessageClient()->dispatchSyncMessage(createMethodCallMessage(&WebPagePrivate::setCompositorHelper, this, compositor)); if (m_compositor || m_client->window()) // the new compositor, if one was set - m_backingStore->d->resumeScreenAndBackingStoreUpdates(BackingStore::RenderAndBlit); + m_backingStore->d->resumeScreenUpdates(BackingStore::RenderAndBlit); } void WebPagePrivate::setCompositorHelper(PassRefPtr<WebPageCompositorPrivate> compositor) @@ -5714,7 +5731,9 @@ void WebPagePrivate::exitFullScreenForElement(Element* element) // The Browser chrome has its own fullscreen video widget. exitFullscreenForNode(element); } else { - m_backingStore->d->suspendScreenAndBackingStoreUpdates(); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->suspendBackingStoreUpdates(); + m_backingStore->d->suspendScreenUpdates(); // When leaving fullscreen mode, we need to restore the 'x' scroll position // before fullscreen. @@ -5735,7 +5754,9 @@ void WebPagePrivate::exitFullScreenForElement(Element* element) } notifyTransformChanged(); - m_backingStore->d->resumeScreenAndBackingStoreUpdates(BackingStore::RenderAndBlit); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->resumeBackingStoreUpdates(); + m_backingStore->d->resumeScreenUpdates(BackingStore::RenderAndBlit); // This is where we would restore the browser's chrome // if hidden above. @@ -5849,6 +5870,11 @@ void WebPagePrivate::didChangeSettings(WebSettings* webSettings) Platform::userInterfaceThreadMessageClient()->dispatchMessage( createMethodCallMessage(&WebPagePrivate::setCompositorBackgroundColor, this, backgroundColor)); } + if (m_backingStore) { + m_backingStore->d->setWebPageBackgroundColor(m_mainFrame && m_mainFrame->view() + ? m_mainFrame->view()->documentBackgroundColor() + : webSettings->backgroundColor()); + } m_page->setDeviceScaleFactor(webSettings->devicePixelRatio()); } @@ -6044,7 +6070,9 @@ void WebPagePrivate::setTextZoomFactor(float textZoomFactor) void WebPagePrivate::restoreHistoryViewState(Platform::IntSize contentsSize, Platform::IntPoint scrollPosition, double scale, bool shouldReflowBlock) { if (!m_mainFrame) { - m_backingStore->d->resumeScreenAndBackingStoreUpdates(BackingStore::RenderAndBlit); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->resumeBackingStoreUpdates(); + m_backingStore->d->resumeScreenUpdates(BackingStore::RenderAndBlit); return; } @@ -6062,7 +6090,9 @@ void WebPagePrivate::restoreHistoryViewState(Platform::IntSize contentsSize, Pla bool didZoom = zoomAboutPoint(scale, m_mainFrame->view()->scrollPosition(), true /* enforceScaleClamping */, true /*forceRendering*/, true /*isRestoringZoomLevel*/); // If we're already at that scale, then we should still force rendering // since our scroll position changed. - m_backingStore->d->resumeScreenAndBackingStoreUpdates(BackingStore::RenderAndBlit); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_backingStore->d->resumeBackingStoreUpdates(); + m_backingStore->d->resumeScreenUpdates(BackingStore::RenderAndBlit); if (!didZoom) { // We need to notify the client of the scroll position and content size change(s) above even if we didn't scale. diff --git a/Source/WebKit/blackberry/Api/WebPage.h b/Source/WebKit/blackberry/Api/WebPage.h index a8999db37..2fe56ca31 100644 --- a/Source/WebKit/blackberry/Api/WebPage.h +++ b/Source/WebKit/blackberry/Api/WebPage.h @@ -82,7 +82,7 @@ enum JavaScriptDataType { JSUndefined = 0, JSNull, JSBoolean, JSNumber, JSString enum ActivationStateType { ActivationActive, ActivationInactive, ActivationStandby }; -enum TargetDetectionStrategy {PointBased, RectBased}; +enum TargetDetectionStrategy {PointBased, RectBased, FocusBased}; class BLACKBERRY_EXPORT WebPage : public Platform::GuardedPointerBase { public: @@ -135,7 +135,6 @@ public: bool isVisible() const; void setScreenOrientation(int); - void setHasPendingSurfaceSizeChange(); void applyPendingOrientationIfNeeded(); Platform::ViewportAccessor* webkitThreadViewportAccessor() const; @@ -155,7 +154,9 @@ public: // For conversion to mouse events. void touchEventCancel(); - bool touchPointAsMouseEvent(const Platform::TouchPoint&, bool useFatFingers = true); + void touchPointAsMouseEvent(const Platform::TouchPoint&); + + void playSoundIfAnchorIsTarget() const; // Returns true if the key stroke was handled by WebKit. bool keyEvent(const Platform::KeyboardEvent&); diff --git a/Source/WebKit/blackberry/Api/WebPageClient.h b/Source/WebKit/blackberry/Api/WebPageClient.h index 83574c651..69035ba1f 100644 --- a/Source/WebKit/blackberry/Api/WebPageClient.h +++ b/Source/WebKit/blackberry/Api/WebPageClient.h @@ -141,7 +141,6 @@ public: virtual Platform::Graphics::Window* window() const = 0; virtual void notifyPixelContentRendered(const Platform::IntRect&) = 0; - virtual void resizeSurfaceIfNeeded() = 0; virtual void inputFocusGained(int64_t inputStyle, Platform::VirtualKeyboardType, Platform::VirtualKeyboardEnterKeyType) = 0; virtual void inputFocusLost() = 0; diff --git a/Source/WebKit/blackberry/Api/WebPage_p.h b/Source/WebKit/blackberry/Api/WebPage_p.h index 4331b3ed9..9c0a26dcb 100644 --- a/Source/WebKit/blackberry/Api/WebPage_p.h +++ b/Source/WebKit/blackberry/Api/WebPage_p.h @@ -367,7 +367,6 @@ public: // Scroll and/or zoom so that the WebPage fits the new actual // visible size. void setViewportSize(const WebCore::IntSize& transformedActualVisibleSize, bool ensureFocusElementVisible); - void resizeSurfaceIfNeeded(); // Helper method for setViewportSize(). void scheduleDeferrableTimer(WebCore::Timer<WebPagePrivate>*, double timeOut); void unscheduleAllDeferrableTimers(); @@ -568,7 +567,6 @@ public: bool m_suspendRootLayerCommit; #endif - bool m_hasPendingSurfaceSizeChange; int m_pendingOrientation; RefPtr<WebCore::Node> m_fullscreenVideoNode; diff --git a/Source/WebKit/blackberry/ChangeLog b/Source/WebKit/blackberry/ChangeLog index 2ab4cf3b0..ebd5d4673 100644 --- a/Source/WebKit/blackberry/ChangeLog +++ b/Source/WebKit/blackberry/ChangeLog @@ -1,3 +1,619 @@ +2012-11-21 Genevieve Mak <gmak@rim.com> + + [BlackBerry] Drop Synchronous Mouse Events + https://bugs.webkit.org/show_bug.cgi?id=102980 + + Reviewed by Rob Buis. + + Reviewed Internally by George Staikos, Mike Lattanzio and Mike Fenton. + Get rid of unneeded methods and simplify code. + Send click if getting context over an empty text field + so that it will be focused and have a caret. + PR #242781 + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::webContext): + (BlackBerry::WebKit::WebPage::touchEvent): + (BlackBerry::WebKit::WebPage::touchPointAsMouseEvent): + (BlackBerry::WebKit::WebPage::touchEventCancel): + * Api/WebPage.h: + * WebKitSupport/TouchEventHandler.cpp: + (BlackBerry::WebKit::TouchEventHandler::TouchEventHandler): + (BlackBerry::WebKit::TouchEventHandler::doFatFingers): + (BlackBerry::WebKit::TouchEventHandler::sendClickAtFatFingersPoint): + (BlackBerry::WebKit::TouchEventHandler::handleTouchPoint): + (BlackBerry::WebKit::TouchEventHandler::handleFatFingerPressed): + * WebKitSupport/TouchEventHandler.h: + (TouchEventHandler): + +2012-11-21 Konrad Piascik <kpiascik@rim.com> + + [BlackBerry] Prevent screen from dimming on device when inspector front-end is connected + https://bugs.webkit.org/show_bug.cgi?id=102978 + + Reviewed by Rob Buis. + + Internal PR 200848 + We prevent screen from going dim when the front-end is connected and return to normal when + the front-end disconnects. + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPage::enableWebInspector): + (BlackBerry::WebKit::WebPage::disableWebInspector): + +2012-11-21 Konrad Piascik <kpiascik@rim.com> + + [BlackBerry] Don't add empty rects to the tap highlight region. + https://bugs.webkit.org/show_bug.cgi?id=102966 + + Reviewed by George Staikos. + + Internal PR 246960 + Tap highlight is way too large sometimes. + When we add an empty rect it inflates by 2 and causes the tap region to extend to the origin. + + * WebKitSupport/TouchEventHandler.cpp: + (BlackBerry::WebKit::TouchEventHandler::drawTapHighlight): + +2012-11-21 Mike Fenton <mifenton@rim.com> + + [BlackBerry] Switch to point instead of VisiblePosition comparison for input bounds check + https://bugs.webkit.org/show_bug.cgi?id=102962 + + Reviewed by Rob Buis. + + PR 247270. + + Switch from using VisiblePosition to determine if we are in a node + to a comparison of the field bounds. This fixes the case where + there is no node before the target node to match. + + Reviewed Internally by Gen Mak. + + * WebKitSupport/DOMSupport.cpp: + * WebKitSupport/DOMSupport.h: + * WebKitSupport/SelectionHandler.cpp: + (BlackBerry::WebKit::SelectionHandler::setCaretPosition): + +2012-11-20 Andrew Lo <anlo@rim.com> + + [BlackBerry] Animated gifs pause on scroll or zoom and sometimes don't resume after scroll or zoom completes + https://bugs.webkit.org/show_bug.cgi?id=102838 + + Reviewed by Rob Buis. + + Internally reviewed by Adam Treat. + Internal PR244646 + When entering scrolling & zooming, we suspend regular render jobs + in order to pause animations. When finishing scrolling or zooming, + dispatch a render job in order to resume those animations. + + If an animation requests a repaint while the backing store is suspended, + add the regular render job to the render queue so that it can be + processed later. + + * Api/BackingStore.cpp: + (BlackBerry::WebKit::BackingStorePrivate::repaint): + (BlackBerry::WebKit::BackingStorePrivate::setScrollingOrZooming): + +2012-11-20 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r135295. + http://trac.webkit.org/changeset/135295 + https://bugs.webkit.org/show_bug.cgi?id=102834 + + This patch causes assertion to some layout tests on chromium + (Requested by jianli on #webkit). + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::load): + (BlackBerry::WebKit::WebPagePrivate::loadString): + * WebCoreSupport/FrameLoaderClientBlackBerry.cpp: + (WebCore::FrameLoaderClientBlackBerry::dispatchDidFailProvisionalLoad): + +2012-11-20 James Simonsen <simonjam@chromium.org> + + Consolidate FrameLoader::load() into one function taking a FrameLoadRequest + https://bugs.webkit.org/show_bug.cgi?id=102151 + + Reviewed by Adam Barth. + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::load): + (BlackBerry::WebKit::WebPagePrivate::loadString): + * WebCoreSupport/FrameLoaderClientBlackBerry.cpp: + (WebCore::FrameLoaderClientBlackBerry::dispatchDidFailProvisionalLoad): + +2012-11-19 Genevieve Mak <gmak@rim.com> + + [BlackBerry] Block Zoom picks wrong block + https://bugs.webkit.org/show_bug.cgi?id=102728 + + Reviewed by Rob Buis. + + Reviewed Internally by Jakob Petsovits + Remove transform missed in previous commit for + https://bugs.webkit.org/show_bug.cgi?id=101608 + PR #247198 + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::nodeForZoomUnderPoint): + +2012-11-19 Liam Quinn <lquinn@rim.com> + + [BlackBerry] Remove RTSP handling from FrameLoaderClientBlackBerry + https://bugs.webkit.org/show_bug.cgi?id=102692 + + Reviewed by Rob Buis. + + Reviewed internally by George Staikos. Internal PR 242750. + + Our RTSP handling in FrameLoaderClientBlackBerry causes HTTP redirects to "rtsp:" URIs to fail. Remove handling of RTSP from this class; it will be moved to the network layer alongside other URI schemes like "data:" and "file:". + + * WebCoreSupport/FrameLoaderClientBlackBerry.cpp: + (WebCore::FrameLoaderClientBlackBerry::createDocumentLoader): + +2012-11-16 Adam Treat <atreat@rim.com> + + https://bugs.webkit.org/show_bug.cgi?id=102540 + [BlackBerry] Checkerboard flicker when pinch zooming out on google.com/nwshp + + Reviewed by George Staikos. + PR 245827 + + Disable updates to the backingstore tile matrix when backingstore updates + are disabled. This prevents changes to the tile matrix when we are in the + middle of a pinch zoom which can cause checkebroard flickering. + + * Api/BackingStore.cpp: + (BlackBerry::WebKit::BackingStorePrivate::BackingStorePrivate): + (BlackBerry::WebKit::BackingStorePrivate::resumeBackingStoreUpdates): + (BlackBerry::WebKit::BackingStorePrivate::setBackingStoreRect): + (BlackBerry::WebKit::BackingStorePrivate::render): + (BlackBerry::WebKit::BackingStorePrivate::renderVisibleContents): + (BlackBerry::WebKit::BackingStorePrivate::renderBackingStore): + (BlackBerry::WebKit::BackingStorePrivate::updateTileMatrixIfNeeded): + (BlackBerry::WebKit::BackingStorePrivate::contentsSizeChanged): + (BlackBerry::WebKit::BackingStorePrivate::orientationChanged): + * Api/BackingStore_p.h: + (BlackBerry::WebKit::BackingStorePrivate::setTileMatrixNeedsUpdate): + (BackingStorePrivate): + +2012-11-16 Rob Buis <rbuis@rim.com> + + [BlackBerry] FCC doesn't work in textarea + https://bugs.webkit.org/show_bug.cgi?id=102088 + + Reviewed by Antonio Gomes. + + Remove the cancel button specializations, it was needed at some point but hitting it + works just as well without it. This unbreaks FCC in textarea's. + + * WebKitSupport/FatFingers.cpp: + (BlackBerry::WebKit::FatFingers::isElementClickable): + +2012-11-16 Adam Treat <atreat@rim.com> + + [BlackBerry] Fix regression causing checkerboard flicker after app wake-up + https://bugs.webkit.org/show_bug.cgi?id=102526 + + Reviewed by George Staikos. + PR 245027 + + The webkit patch for 219976 introduced an undesirable behavior change + resulting in a regression where there was checkerboard flickering on + resuming from an inactive application state. This patch restores the + previous behavior and fixes the regression. + + * Api/BackingStore.cpp: + (BlackBerry::WebKit::BackingStore::createBackingStoreMemory): + (BlackBerry::WebKit::BackingStore::releaseBackingStoreMemory): + +2012-11-16 Mike Fenton <mifenton@rim.com> + + [BlackBerry] Use proper keycode value for space instead of hardcoded value. + https://bugs.webkit.org/show_bug.cgi?id=102518 + + Reviewed by Rob Buis. + + Remove hard coded value for space. + + Reviewed Internally by Gen Mak. + + * WebKitSupport/InputHandler.cpp: + (BlackBerry::WebKit::InputHandler::setText): + +2012-11-15 Andrew Lo <anlo@rim.com> + + [BlackBerry] Animate changes to viewport due to input focus changes. + https://bugs.webkit.org/show_bug.cgi?id=102410 + + Reviewed by Rob Buis. + + When changing scroll position or zoom level for input field focus, + animate the change. + Internal PR 231937 + + Internally reviewed by Mike Fenton. + + * WebKitSupport/InputHandler.cpp: + (BlackBerry::WebKit::InputHandler::ensureFocusTextElementVisible): + +2012-11-15 Mike Fenton <mifenton@rim.com> + + [BlackBerry] Don't restore zoom and scroll when leaving an input field. + https://bugs.webkit.org/show_bug.cgi?id=102376 + + Reviewed by Yong Li. + + Restoring the zoom causes undesirable behavior when switching between fields. + + Reviewed Internally by Andrew Lo. + + * WebKitSupport/InputHandler.cpp: + (BlackBerry::WebKit::InputHandler::InputHandler): + (BlackBerry::WebKit::InputHandler::ensureFocusTextElementVisible): + * WebKitSupport/InputHandler.h: + (InputHandler): + +2012-11-15 Jakob Petsovits <jpetsovits@rim.com> + + [BlackBerry] Fix suspend/resume assertion in setCompositor(). + https://bugs.webkit.org/show_bug.cgi?id=102397 + RIM PR 244701 + + Reviewed by Adam Treat. + + If a compositor is used but no surface pool is ever + allocated (which is a perfectly valid use case), initial + suspension of the backingstore is skipped because of an + early return. This will cause an assertion to be triggered + and a bug. Fix this by suspending it before the return. + + With Adam Treat's recent change to split suspension of + screen and backingstore into two different functions, + this can now be reduced to a mere screen (blitting) + suspension. That was the original intention of this code. + + * Api/BackingStore.cpp: + (BlackBerry::WebKit::BackingStorePrivate::createSurfaces): + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::setCompositor): + +2012-11-15 Jakob Petsovits <jpetsovits@rim.com> + + [BlackBerry] Leave surface resizing to the client. + https://bugs.webkit.org/show_bug.cgi?id=102280 + RIM PR 235034 + RIM PR 160619 + + Reviewed by Adam Treat. + + Now that we always blit on the user interface thread and + use the client's userInterfaceViewportAccessor() to determine + the destination rectangle for blitting, changing the viewport + size does not affect the window or target surface directly. + The only way that blitted output is affected is through + layout, scroll position or scale changes. None of these + require us to synchronize with the UI thread to resize its + target surface. + + This commit simplifies setViewportSize() and removes a + blocking message dispatch by simply offloading all surface + resizing responsibilities to the client. This is safer, + cleaner and easier. + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::WebPagePrivate): + (BlackBerry::WebKit::WebPage::setScreenOrientation): + (BlackBerry::WebKit::WebPagePrivate::setViewportSize): + * Api/WebPage.h: + * Api/WebPageClient.h: + * Api/WebPage_p.h: + (WebPagePrivate): + +2012-11-14 Nima Ghanavatian <nghanavatian@rim.com> + + [BlackBerry] Do not clear the ProcessingChangeGuard state on DeleteBackward + https://bugs.webkit.org/show_bug.cgi?id=102284 + + Reviewed by Rob Buis. + + PR237497 + When holding backspace, clearing the state forces a keyboard + update which resets the state of the keyboard. Handling this + specific corner case separate from all other editor commands. + + Internally reviewed by Mike Fenton. + + * WebCoreSupport/EditorClientBlackBerry.cpp: + (WebCore::EditorClientBlackBerry::handleKeyboardEvent): + +2012-11-14 Rob Buis <rbuis@rim.com> + + [BlackBerry] Improve debug functionality in FatFingers + https://bugs.webkit.org/show_bug.cgi?id=102263 + + Reviewed by Antonio Gomes. + + - use logAlways to log even in release. + - dump shadow tree info if available. + + * WebKitSupport/FatFingers.cpp: + (BlackBerry::WebKit::FatFingers::isElementClickable): + (BlackBerry::WebKit::FatFingers::checkFingerIntersection): + (BlackBerry::WebKit::FatFingers::findIntersectingRegions): + (BlackBerry::WebKit::FatFingers::checkForText): + +2012-11-14 Adam Treat <atreat@rim.com> + + [BlackBerry] Break suspend/resume of the backingstore and screen into separate methods + https://bugs.webkit.org/show_bug.cgi?id=102126 + + Reviewed by George Staikos. + PR 219976 + + Modify the suspend/resume methods so that they can be called from the UI thread + itself and split up the suspend/resume methods so that we can suspend/resume + the screen or backingstore separately. + + * Api/BackingStore.cpp: + (BlackBerry::WebKit::BackingStorePrivate::suspendBackingStoreUpdates): + (WebKit): + (BlackBerry::WebKit::BackingStorePrivate::suspendScreenUpdates): + (BlackBerry::WebKit::BackingStorePrivate::resumeBackingStoreUpdates): + (BlackBerry::WebKit::BackingStorePrivate::resumeScreenUpdates): + (BlackBerry::WebKit::BackingStorePrivate::blitVisibleContents): + (BlackBerry::WebKit::BackingStorePrivate::createSurfaces): + (BlackBerry::WebKit::BackingStore::suspendBackingStoreUpdates): + (BlackBerry::WebKit::BackingStore::resumeBackingStoreUpdates): + (BlackBerry::WebKit::BackingStore::suspendScreenUpdates): + (BlackBerry::WebKit::BackingStore::resumeScreenUpdates): + (BlackBerry::WebKit::BackingStore::createBackingStoreMemory): + (BlackBerry::WebKit::BackingStore::releaseBackingStoreMemory): + * Api/BackingStore.h: + * Api/BackingStore_p.h: + (BackingStorePrivate): + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::setLoadState): + (BlackBerry::WebKit::WebPagePrivate::zoomAboutPoint): + (BlackBerry::WebKit::WebPagePrivate::zoomBlock): + (BlackBerry::WebKit::WebPage::destroy): + (BlackBerry::WebKit::WebPagePrivate::setViewportSize): + (BlackBerry::WebKit::WebPagePrivate::setCompositor): + (BlackBerry::WebKit::WebPagePrivate::exitFullScreenForElement): + (BlackBerry::WebKit::WebPagePrivate::restoreHistoryViewState): + * WebCoreSupport/FrameLoaderClientBlackBerry.cpp: + (WebCore::FrameLoaderClientBlackBerry::transitionToCommittedForNewPage): + (WebCore::FrameLoaderClientBlackBerry::restoreViewState): + * WebKitSupport/InputHandler.cpp: + (BlackBerry::WebKit::InputHandler::setBatchEditingActive): + +2012-11-14 Andy Chen <andchen@rim.com> + + [BlackBerry] Add FocusBased context node detection strategy + https://bugs.webkit.org/show_bug.cgi?id=102238 + + Reviewed by Rob Buis. + + If last fat finger result is invalid, we need to return current + focus element as context node, because when user tap on selection + overlay, there is not touch event sent to webkit. + PR 241382 + + Internally reviewed by Genevieve Mak and Mike Fenton. + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::contextNode): + * Api/WebPage.h: + * WebKitSupport/InputHandler.h: + (BlackBerry::WebKit::InputHandler::currentFocusElement): + +2012-11-14 Nima Ghanavatian <nghanavatian@rim.com> + + [BlackBerry] Use mispelled-marker offsets relative to the element + https://bugs.webkit.org/show_bug.cgi?id=102236 + + Reviewed by Rob Buis. + + DocumentMarker offsets are calculated relative to a node. This is causing + problems for contenteditable which can have numerous nodes. Creating a Range around a word + and calculating its location and length gives us the correct override in this case for starting + and ending points to pass to IMF. + + Internally reviewed by Mike Fenton. + + * WebKitSupport/InputHandler.cpp: + (BlackBerry::WebKit::InputHandler::requestSpellingCheckingOptions): + +2012-11-13 Mike Fenton <mifenton@rim.com> + + [BlackBerry] Fully restore both zoom and scroll when leaving an input field. + https://bugs.webkit.org/show_bug.cgi?id=102094 + + Reviewed by Rob Buis. + + PR 234187. + + Cache both the zoom and scroll position prior to adjusting + for input focus so that state can be reset fully. + + Reviewed Internally by Gen Mak. + + * WebKitSupport/InputHandler.cpp: + (BlackBerry::WebKit::InputHandler::ensureFocusTextElementVisible): + * WebKitSupport/InputHandler.h: + (InputHandler): + +2012-11-12 Nima Ghanavatian <nghanavatian@rim.com> + + [BlackBerry] Ensure we only receive one KeyUp per key event + https://bugs.webkit.org/show_bug.cgi?id=101967 + + Reviewed by Rob Buis. + + We are creating synthetic KeyUps too often, and get into trouble since IMF will send up a KeyUp on all key events. + Furthermore, these KeyUps can arrive both when we are composing and not. To bypass this check, we are storing the KeyDown + character and comparing against it on KeyUp. + + Internally reviewed by Mike Fenton. + + * WebKitSupport/InputHandler.cpp: + (BlackBerry::WebKit::InputHandler::InputHandler): + (BlackBerry::WebKit::InputHandler::handleKeyboardInput): + (BlackBerry::WebKit::InputHandler::insertText): + (BlackBerry::WebKit::InputHandler::setText): + * WebKitSupport/InputHandler.h: + (InputHandler): + +2012-11-12 Jacky Jiang <zhajiang@rim.com> + + [BlackBerry] When opening an image it does not scale to fit our window + https://bugs.webkit.org/show_bug.cgi?id=101778 + + Reviewed by Rob Buis. + Internally reviewed by Konrad Piascik. + + PR: 230935 + For image document, the actual image size can be different with the + contents size. Zoom the document based on the image width so that + images can fit the screen horizontally. Set 2.0 as the maximum zoom to + fit scale for image document so that very small images won't get + ridiculous large scales during the initial load. + + * Api/WebPage.cpp: + (WebKit): + (BlackBerry::WebKit::WebPagePrivate::zoomToFitScale): + +2012-11-12 Nima Ghanavatian <nghanavatian@rim.com> + + [BlackBerry] Use keyevents instead of editor commands for backspace + https://bugs.webkit.org/show_bug.cgi?id=101663 + + Reviewed by Rob Buis. + + PR229395 + Sending keyEvents for backspace and switching from KeyChar + to KeyDown since we are still receiving an unadultered KeyUp + from the input service. This was causing us to get two keyUps + for regular keys and no key downs for backspace since it was + triggering an editor command and bypassing JS listeners. + + Reviewed internally by Mike Fenton. + + * WebKitSupport/InputHandler.cpp: + (BlackBerry::WebKit::InputHandler::handleKeyboardInput): + (BlackBerry::WebKit::relativeRightOffset): + (WebKit): + (BlackBerry::WebKit::InputHandler::deleteTextRelativeToCursor): + (BlackBerry::WebKit::InputHandler::setText): + +2012-11-12 Rob Buis <rbuis@rim.com> + + [BlackBerry] Crash in InRegionScrollerPrivate. + https://bugs.webkit.org/show_bug.cgi?id=101399 + + Reviewed by Yong Li. + + Fix warning caused by the previous patch for this bug (r133679). + + * WebKitSupport/InRegionScrollableArea.cpp: + (BlackBerry::WebKit::InRegionScrollableArea::InRegionScrollableArea): + +2012-11-11 George Staikos <staikos@webkit.org> + + [BlackBerry] The QNX extension method should not be enabled by default + https://bugs.webkit.org/show_bug.cgi?id=101863 + + Reviewed by Rob Buis. + + Simply change the default to false. + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::WebPagePrivate): + +2012-11-09 Otto Derek Cheung <otcheung@rim.com> + + [BlackBerry] Adding a sound to touch events on anchor elements + https://bugs.webkit.org/show_bug.cgi?id=101655 + + Reviewed by Antonio Gomes. + + Adding audio feedback to touchevents on html anchor elements. + + The feedback is called directly from client instead of using the + mouseup event to avoid the delay between touch start and end caused + by the tap sequence recognizer. + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPage::playSoundIfAnchorIsTarget): + (WebKit): + * Api/WebPage.h: + * WebKitSupport/TouchEventHandler.cpp: + (WebKit): + (BlackBerry::WebKit::TouchEventHandler::playSoundIfAnchorIsTarget): + * WebKitSupport/TouchEventHandler.h: + (TouchEventHandler): + +2012-11-09 George Staikos <staikos@webkit.org> + + [BlackBerry] Remove obsolete tokenizer settings + https://bugs.webkit.org/show_bug.cgi?id=101689 + + Reviewed by Yong Li. + + These tokenizer settings are obsolete and should not be here. Remove them. + + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::init): + +2012-11-08 Chris Guan <chris.guan@torchmobile.com.cn> + + [BlackBerry] need to call closePopup at setValueAndClosePopup + https://bugs.webkit.org/show_bug.cgi?id=101568 + + Reviewed by George Staikos. + + When early return occurs, we need to call closePopup + at setValueAndClosePopup function. See the comments + in WebCore/page/PagePopupClient.h. If we have not it, + Webkit thread is held and browser will be unresponsive + in BlackBerry port. + + RIM PR 232962 + Internally reviewed by Charles Wei. + + * WebCoreSupport/SelectPopupClient.cpp: + (WebCore::SelectPopupClient::setValueAndClosePopup): + +2012-11-08 Jakob Petsovits <jpetsovits@rim.com> + + [BlackBerry] Replace checkerboard with page background color. + https://bugs.webkit.org/show_bug.cgi?id=101652 + RIM PR 188235 + + Reviewed by George Staikos. + + In order to do this, we introduce a new member variable for + BackingStore because when blitting, we can't access the + page background color in a threadsafe way. + + Solid background color fill is still only used for public builds. + Developers and beta testers should still see checkerboard and + do something about it. + + * Api/BackingStore.cpp: + (BlackBerry::WebKit::BackingStorePrivate::BackingStorePrivate): + (BlackBerry::WebKit::BackingStorePrivate::fillWindow): + (BlackBerry::WebKit::BackingStorePrivate::webPageBackgroundColorUserInterfaceThread): + (WebKit): + (BlackBerry::WebKit::BackingStorePrivate::setWebPageBackgroundColor): + * Api/BackingStore_p.h: + (BackingStorePrivate): + * Api/WebPage.cpp: + (BlackBerry::WebKit::WebPagePrivate::setLoadState): + (BlackBerry::WebKit::WebPagePrivate::didChangeSettings): + 2012-11-08 Tiancheng Jiang <tijiang@rim.com> [BlackBerry] Update BB10 date input form. diff --git a/Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.cpp b/Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.cpp index 95d02f7d5..9db591956 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.cpp +++ b/Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.cpp @@ -466,7 +466,9 @@ void EditorClientBlackBerry::handleKeyboardEvent(KeyboardEvent* event) if (!commandName.isEmpty()) { // Hot key handling. Cancel processing mode. - m_webPagePrivate->m_inputHandler->setProcessingChange(false); + if (commandName != "DeleteBackward") + m_webPagePrivate->m_inputHandler->setProcessingChange(false); + if (frame->editor()->command(commandName).execute()) event->setDefaultHandled(); return; diff --git a/Source/WebKit/blackberry/WebCoreSupport/FrameLoaderClientBlackBerry.cpp b/Source/WebKit/blackberry/WebCoreSupport/FrameLoaderClientBlackBerry.cpp index 9669c938b..0e0619b4b 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/FrameLoaderClientBlackBerry.cpp +++ b/Source/WebKit/blackberry/WebCoreSupport/FrameLoaderClientBlackBerry.cpp @@ -74,7 +74,6 @@ #include <BlackBerryPlatformExecutableMessage.h> #include <BlackBerryPlatformLog.h> -#include <BlackBerryPlatformMediaDocument.h> #include <BlackBerryPlatformMessageClient.h> #include <BlackBerryPlatformScreen.h> #include <JavaScriptCore/APICast.h> @@ -404,8 +403,7 @@ PassRefPtr<DocumentLoader> FrameLoaderClientBlackBerry::createDocumentLoader(con // The first 6 letters is "about:" String aboutWhat = request.url().string().substring(6); source = aboutData(aboutWhat); - } else if (request.url().protocolIs("rtsp")) - source = BlackBerry::Platform::mediaDocument(request.url().string()); + } if (!source.isEmpty()) { // Always ignore existing substitute data if any. @@ -435,8 +433,11 @@ void FrameLoaderClientBlackBerry::transitionToCommittedForNewPage() // in the backing store from another thread (see BackingStorePrivate::blitVisibleContents method), // so we suspend and resume screen update to make sure we do not get a invalid FrameView // state. - if (isMainFrame() && m_webPagePrivate->backingStoreClient()) - m_webPagePrivate->backingStoreClient()->backingStore()->d->suspendScreenAndBackingStoreUpdates(); + if (isMainFrame() && m_webPagePrivate->backingStoreClient()) { + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_webPagePrivate->backingStoreClient()->backingStore()->d->suspendBackingStoreUpdates(); + m_webPagePrivate->backingStoreClient()->backingStore()->d->suspendScreenUpdates(); + } // We are navigating away from this document, so clean up any footprint we might have. if (m_frame->document()) @@ -456,8 +457,11 @@ void FrameLoaderClientBlackBerry::transitionToCommittedForNewPage() ScrollbarAlwaysOff, /* ver mode */ true); /* lock the mode */ - if (isMainFrame() && m_webPagePrivate->backingStoreClient()) - m_webPagePrivate->backingStoreClient()->backingStore()->d->resumeScreenAndBackingStoreUpdates(BackingStore::None); + if (isMainFrame() && m_webPagePrivate->backingStoreClient()) { + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_webPagePrivate->backingStoreClient()->backingStore()->d->resumeBackingStoreUpdates(); + m_webPagePrivate->backingStoreClient()->backingStore()->d->resumeScreenUpdates(BackingStore::None); + } m_frame->view()->updateCanHaveScrollbars(); @@ -1122,7 +1126,9 @@ void FrameLoaderClientBlackBerry::restoreViewState() // Don't flash checkerboard before WebPagePrivate::restoreHistoryViewState() finished. // This call will be balanced by BackingStorePrivate::resumeScreenAndBackingStoreUpdates() in WebPagePrivate::restoreHistoryViewState(). - m_webPagePrivate->m_backingStore->d->suspendScreenAndBackingStoreUpdates(); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + m_webPagePrivate->m_backingStore->d->suspendBackingStoreUpdates(); + m_webPagePrivate->m_backingStore->d->suspendScreenUpdates(); // It is not safe to render the page at this point. So we post a message instead. Messages have higher priority than timers. BlackBerry::Platform::webKitThreadMessageClient()->dispatchMessage(BlackBerry::Platform::createMethodCallMessage( diff --git a/Source/WebKit/blackberry/WebCoreSupport/SelectPopupClient.cpp b/Source/WebKit/blackberry/WebCoreSupport/SelectPopupClient.cpp index b37b5e668..b1af6fa63 100644 --- a/Source/WebKit/blackberry/WebCoreSupport/SelectPopupClient.cpp +++ b/Source/WebKit/blackberry/WebCoreSupport/SelectPopupClient.cpp @@ -173,8 +173,11 @@ void SelectPopupClient::setValueAndClosePopup(int, const String& stringValue) const Vector<HTMLElement*>& items = m_element->listItems(); - if (items.size() != static_cast<unsigned int>(m_size)) + // If element changed after select UI showed, do nothing but closePopup(). + if (items.size() != static_cast<unsigned>(m_size)) { + closePopup(); return; + } HTMLOptionElement* option; for (unsigned i = 0; i < m_size; i++) { diff --git a/Source/WebKit/blackberry/WebKitSupport/DOMSupport.cpp b/Source/WebKit/blackberry/WebKitSupport/DOMSupport.cpp index 1d81a5eaa..752c573e8 100644 --- a/Source/WebKit/blackberry/WebKitSupport/DOMSupport.cpp +++ b/Source/WebKit/blackberry/WebKitSupport/DOMSupport.cpp @@ -314,34 +314,6 @@ VisibleSelection visibleSelectionForRangeInputElement(Element* element, int star return VisibleSelection(visibleStart, visibleEnd); } -Node* DOMContainerNodeForPosition(const Position& position) -{ - Node* nodeAtPos = position.containerNode(); - if (nodeAtPos && nodeAtPos->isInShadowTree()) - nodeAtPos = nodeAtPos->shadowAncestorNode(); - - return nodeAtPos; -} - -bool isPositionInNode(Node* node, const Position& position) -{ - if (!node) - return false; - - Node* domNodeAtPos = DOMContainerNodeForPosition(position); - if (!domNodeAtPos) - return false; - - int offset = 0; - if (domNodeAtPos == position.containerNode()) - offset = position.computeOffsetInContainerNode(); - - RefPtr<Range> rangeForNode = rangeOfContents(node); - int ec; - - return rangeForNode->isPointInRange(domNodeAtPos, offset, ec); -} - static bool matchesReservedStringEmail(const AtomicString& string) { return string.contains("email", false /* caseSensitive */); diff --git a/Source/WebKit/blackberry/WebKitSupport/DOMSupport.h b/Source/WebKit/blackberry/WebKitSupport/DOMSupport.h index a86e12a35..74175ecd4 100644 --- a/Source/WebKit/blackberry/WebKitSupport/DOMSupport.h +++ b/Source/WebKit/blackberry/WebKitSupport/DOMSupport.h @@ -76,9 +76,6 @@ void visibleTextQuads(const WebCore::VisibleSelection&, WTF::Vector<WebCore::Flo WebCore::VisibleSelection visibleSelectionForRangeInputElement(WebCore::Element*, int start, int end); WebCore::VisibleSelection visibleSelectionForInputElement(WebCore::Element*); -WebCore::Node* DOMContainerNodeForPosition(const WebCore::Position&); -bool isPositionInNode(WebCore::Node*, const WebCore::Position&); - bool elementIdOrNameIndicatesNoAutocomplete(const WebCore::Element*); bool elementIdOrNameIndicatesEmail(const WebCore::HTMLInputElement*); bool elementIdOrNameIndicatesUrl(const WebCore::HTMLInputElement*); diff --git a/Source/WebKit/blackberry/WebKitSupport/FatFingers.cpp b/Source/WebKit/blackberry/WebKitSupport/FatFingers.cpp index 877dc2009..6494186be 100644 --- a/Source/WebKit/blackberry/WebKitSupport/FatFingers.cpp +++ b/Source/WebKit/blackberry/WebKitSupport/FatFingers.cpp @@ -92,8 +92,8 @@ bool FatFingers::isElementClickable(Element* element) const ExceptionCode ec = 0; return element->webkitMatchesSelector("a[href],*:link,*:visited,*[role=button],button,input,select,label[for],area[href],textarea,embed,object", ec) || element->isMediaControlElement() - || (element->isContentEditable() && !element->isInShadowTree()) - || element->shadowPseudoId() == "-webkit-search-cancel-button"; + || element->isContentEditable(); + } case MadeClickableByTheWebpage: @@ -278,7 +278,13 @@ bool FatFingers::checkFingerIntersection(const IntRectRegion& region, const IntR nodeName = String::format("%s node", toElement(node)->tagName().latin1().data()); else nodeName = "unknown node"; - BBLOG(LogLevelInfo, "%s has region %s, intersecting at %s (area %d)", nodeName.latin1().data(), + if (node->isInShadowTree()) { + nodeName = nodeName + "(in shadow tree"; + if (node->isElementNode() && !toElement(node)->shadowPseudoId().isEmpty()) + nodeName = nodeName + ", pseudo id " + toElement(node)->shadowPseudoId(); + nodeName = nodeName + ")"; + } + logAlways(LogLevelInfo, "%s has region %s, intersecting at %s (area %d)", nodeName.latin1().data(), regionCopy.toString().c_str(), intersection.toString().c_str(), intersection.area()); #endif @@ -303,7 +309,7 @@ bool FatFingers::findIntersectingRegions(Document* document, Vector<Intersecting #if DEBUG_FAT_FINGERS IntRect fingerRect(fingerRectForPoint(frameContentPos)); IntRect screenFingerRect = m_webPage->mapToTransformed(fingerRect); - BBLOG(LogLevelInfo, "fat finger rect now %d, %d, %d, %d", screenFingerRect.x(), screenFingerRect.y(), screenFingerRect.width(), screenFingerRect.height()); + logAlways(LogLevelInfo, "fat finger rect now %d, %d, %d, %d", screenFingerRect.x(), screenFingerRect.y(), screenFingerRect.width(), screenFingerRect.height()); // only record the first finger rect if (document == m_webPage->m_mainFrame->document()) @@ -433,7 +439,7 @@ bool FatFingers::checkForText(Node* curNode, Vector<IntersectingRegion>& interse RefPtr<Range> range = Range::create(document, curText, lastOffset, curText, offset); if (!range->text().stripWhiteSpace().isEmpty()) { #if DEBUG_FAT_FINGERS - BBLOG(LogLevelInfo, "Checking word '%s'", range->text().latin1().data()); + logAlways(LogLevelInfo, "Checking word '%s'", range->text().latin1().data()); #endif IntRectRegion rangeRegion(DOMSupport::transformedBoundingBoxForRange(*range)); foundOne |= checkFingerIntersection(rangeRegion, fingerRegion, curNode, intersectingRegions); diff --git a/Source/WebKit/blackberry/WebKitSupport/InRegionScrollableArea.cpp b/Source/WebKit/blackberry/WebKitSupport/InRegionScrollableArea.cpp index 443db8b8c..43dbde887 100644 --- a/Source/WebKit/blackberry/WebKitSupport/InRegionScrollableArea.cpp +++ b/Source/WebKit/blackberry/WebKitSupport/InRegionScrollableArea.cpp @@ -52,8 +52,8 @@ InRegionScrollableArea::~InRegionScrollableArea() InRegionScrollableArea::InRegionScrollableArea(WebPagePrivate* webPage, RenderLayer* layer) : m_webPage(webPage) , m_layer(layer) - , m_hasWindowVisibleRectCalculated(false) , m_document(0) + , m_hasWindowVisibleRectCalculated(false) { ASSERT(webPage); ASSERT(layer); diff --git a/Source/WebKit/blackberry/WebKitSupport/InputHandler.cpp b/Source/WebKit/blackberry/WebKitSupport/InputHandler.cpp index a1199ca72..3622e0adb 100644 --- a/Source/WebKit/blackberry/WebKitSupport/InputHandler.cpp +++ b/Source/WebKit/blackberry/WebKitSupport/InputHandler.cpp @@ -139,8 +139,8 @@ InputHandler::InputHandler(WebPagePrivate* page) , m_delayKeyboardVisibilityChange(false) , m_request(0) , m_processingTransactionId(-1) - , m_focusZoomScale(0.0) , m_receivedBackspaceKeyDown(false) + , m_expectedKeyUpChar(0) { } @@ -749,6 +749,24 @@ void InputHandler::requestSpellingCheckingOptions(imf_sp_text_t& spellCheckingOp const WebCore::IntPoint scrollPosition = m_webPage->mainFrame()->view()->scrollPosition(); caretRect.move(scrollPosition.x(), scrollPosition.y()); + // Calculate the offset for contentEditable since the marker offsets are relative to the node. + // Get caret position. Though the spelling markers might no longer exist, if this method is called we can assume the caret was placed on top of a marker earlier. + VisiblePosition caretPosition = m_currentFocusElement->document()->frame()->selection()->selection().visibleStart(); + + // Create a range from the start to end of word. + RefPtr<Range> rangeSelection = VisibleSelection(startOfWord(caretPosition), endOfWord(caretPosition)).toNormalizedRange(); + if (!rangeSelection) + return; + + unsigned location = 0; + unsigned length = 0; + TextIterator::getLocationAndLengthFromRange(m_currentFocusElement.get(), rangeSelection.get(), location, length); + + if (location != notFound && length) { + spellCheckingOptionRequest.startTextPosition = location; + spellCheckingOptionRequest.endTextPosition = location + length; + } + InputLog(LogLevelInfo, "InputHandler::requestSpellingCheckingOptions caretRect topLeft=(%d,%d), bottomRight=(%d,%d), startTextPosition=%d, endTextPosition=%d" , caretRect.minXMinYCorner().x(), caretRect.minXMinYCorner().y(), caretRect.maxXMaxYCorner().x(), caretRect.maxXMaxYCorner().y() , spellCheckingOptionRequest.startTextPosition, spellCheckingOptionRequest.endTextPosition); @@ -1097,11 +1115,6 @@ void InputHandler::ensureFocusTextElementVisible(CaretScrollType scrollType) break; } case VisibleSelection::NoSelection: - if (m_focusZoomScale) { - m_webPage->zoomAboutPoint(m_focusZoomScale, m_focusZoomLocation); - m_focusZoomScale = 0.0; - m_focusZoomLocation = WebCore::IntPoint(); - } return; } @@ -1113,18 +1126,17 @@ void InputHandler::ensureFocusTextElementVisible(CaretScrollType scrollType) // The minimum size being defined as 3 mm is a good value based on my observations. static const int s_minimumTextHeightInPixels = Graphics::Screen::primaryScreen()->heightInMMToPixels(3); - if (m_webPage->isUserScalable() && fontHeight && fontHeight * m_webPage->currentScale() < s_minimumTextHeightInPixels && !isRunningDrt()) { - if (!m_focusZoomScale) { - m_focusZoomScale = m_webPage->currentScale(); - m_focusZoomLocation = selectionFocusRect.location(); - } - double zoomScaleRequired = static_cast<double>(s_minimumTextHeightInPixels) / fontHeight; - m_webPage->zoomAboutPoint(zoomScaleRequired, m_focusZoomLocation); - InputLog(LogLevelInfo, "InputHandler::ensureFocusTextElementVisible zooming in to %f at point %d, %d", zoomScaleRequired, m_focusZoomLocation.x(), m_focusZoomLocation.y()); - } else { - m_focusZoomScale = 0.0; - m_focusZoomLocation = WebCore::IntPoint(); - } + double zoomScaleRequired; + if (m_webPage->isUserScalable() && fontHeight && fontHeight * m_webPage->currentScale() < s_minimumTextHeightInPixels && !isRunningDrt()) + zoomScaleRequired = static_cast<double>(s_minimumTextHeightInPixels) / fontHeight; + else + zoomScaleRequired = m_webPage->currentScale(); // Don't scale. + + // The scroll location we should go to given the zoom required, could be adjusted later. + WebCore::FloatPoint offset(selectionFocusRect.location().y() - m_webPage->scrollPosition().x(), selectionFocusRect.location().y() - m_webPage->scrollPosition().y()); + double inverseScale = zoomScaleRequired / m_webPage->currentScale(); + WebCore::IntPoint destinationScrollLocation = WebCore::IntPoint(max(0, static_cast<int>(roundf(selectionFocusRect.location().x() - offset.x() / inverseScale))), + max(0, static_cast<int>(roundf(selectionFocusRect.location().y() - offset.y() / inverseScale)))); if (elementFrame != mainFrame) { // Element is in a subframe. // Remove any scroll offset within the subframe to get the point relative to the main frame. @@ -1140,7 +1152,9 @@ void InputHandler::ensureFocusTextElementVisible(CaretScrollType scrollType) Position start = elementFrame->selection()->start(); if (start.anchorNode() && start.anchorNode()->renderer()) { if (RenderLayer* layer = start.anchorNode()->renderer()->enclosingLayer()) { - WebCore::IntRect actualScreenRect = WebCore::IntRect(mainFrameView->scrollPosition(), m_webPage->actualVisibleSize()); + // Screen rect after the required zoom. + WebCore::IntRect actualScreenRect = WebCore::IntRect(destinationScrollLocation.x(), destinationScrollLocation.y(), m_webPage->actualVisibleSize().width() / inverseScale, m_webPage->actualVisibleSize().height() / inverseScale); + ScrollAlignment horizontalScrollAlignment = ScrollAlignment::alignToEdgeIfNeeded; ScrollAlignment verticalScrollAlignment = ScrollAlignment::alignToEdgeIfNeeded; @@ -1187,15 +1201,26 @@ void InputHandler::ensureFocusTextElementVisible(CaretScrollType scrollType) // In order to adjust the scroll position to ensure the focused input field is visible, // we allow overscrolling. However this overscroll has to be strictly allowed towards the // bottom of the page on the y axis only, where the virtual keyboard pops up from. - WebCore::IntPoint scrollLocation = revealRect.location(); - scrollLocation.clampNegativeToZero(); + destinationScrollLocation = revealRect.location(); + destinationScrollLocation.clampNegativeToZero(); WebCore::IntPoint maximumScrollPosition = WebCore::IntPoint(mainFrameView->contentsWidth() - actualScreenRect.width(), mainFrameView->contentsHeight() - actualScreenRect.height()); - scrollLocation = scrollLocation.shrunkTo(maximumScrollPosition); - mainFrameView->setScrollPosition(scrollLocation); - mainFrameView->setConstrainsScrollingToContentEdge(true); - InputLog(LogLevelInfo, "InputHandler::ensureFocusTextElementVisible scrolling to point %d, %d", scrollLocation.x(), scrollLocation.y()); + destinationScrollLocation = destinationScrollLocation.shrunkTo(maximumScrollPosition); } } + + if (destinationScrollLocation != mainFrameView->scrollPosition() || zoomScaleRequired != m_webPage->currentScale()) { + mainFrameView->setConstrainsScrollingToContentEdge(true); + + InputLog(LogLevelInfo, "InputHandler::ensureFocusTextElementVisible zooming in to %f and scrolling to point %d, %d", zoomScaleRequired, destinationScrollLocation.x(), destinationScrollLocation.y()); + + // Animate to given scroll position & zoom level + m_webPage->m_finalBlockPoint = WebCore::FloatPoint(destinationScrollLocation); + m_webPage->m_blockZoomFinalScale = zoomScaleRequired; + m_webPage->m_shouldReflowBlock = false; + m_webPage->m_userPerformedManualZoom = true; + m_webPage->m_userPerformedManualScroll = true; + m_webPage->client()->animateBlockZoom(zoomScaleRequired, m_webPage->m_finalBlockPoint); + } m_webPage->resumeBackingStore(); } @@ -1473,9 +1498,23 @@ bool InputHandler::handleKeyboardInput(const Platform::KeyboardEvent& keyboardEv // Enable input mode if we are processing a key event. setInputModeEnabled(); + Platform::KeyboardEvent::Type type = keyboardEvent.type(); + /* + * IMF sends us an unadultered KeyUp for all key presses. This key event should be allowed to be processed at all times. + * We bypass the check because the state of composition has no implication on this key event. + * In order to ensure we allow the correct key event through, we keep track of key down events with m_expectedKeyUpChar. + */ + if (type == Platform::KeyboardEvent::KeyUp) { + // When IMF auto-capitalizes a KeyDown, say the first letter of a new sentence, our KeyUp will still be in lowercase. + if (m_expectedKeyUpChar == keyboardEvent.character() || (isASCIIUpper(m_expectedKeyUpChar) && m_expectedKeyUpChar == toASCIIUpper(keyboardEvent.character()))) { + m_expectedKeyUpChar = 0; + changeIsPartOfComposition = true; + } + } + // If we aren't specifically part of a composition, fail, IMF should never send key input // while composing text. If IMF has failed, we should have already finished the - // composition manually. + // composition manually. There is a caveat for KeyUp which is explained above. if (!changeIsPartOfComposition && compositionActive()) return false; @@ -1488,16 +1527,18 @@ bool InputHandler::handleKeyboardInput(const Platform::KeyboardEvent& keyboardEv ASSERT(m_webPage->m_page->focusController()); bool keyboardEventHandled = false; if (Frame* focusedFrame = m_webPage->m_page->focusController()->focusedFrame()) { - bool isKeyChar = keyboardEvent.type() == Platform::KeyboardEvent::KeyChar; - Platform::KeyboardEvent::Type type = keyboardEvent.type(); + bool isKeyChar = type == Platform::KeyboardEvent::KeyChar; // If this is a KeyChar type then we handle it as a keydown followed by a key up. if (isKeyChar) type = Platform::KeyboardEvent::KeyDown; + else if (type == Platform::KeyboardEvent::KeyDown) { + m_expectedKeyUpChar = keyboardEvent.character(); - // If we receive the KeyDown of a Backspace, set this flag to prevent sending unnecessary selection and caret changes to IMF. - if (keyboardEvent.character() == KEYCODE_BACKSPACE && type == Platform::KeyboardEvent::KeyDown) - m_receivedBackspaceKeyDown = true; + // If we receive the KeyDown of a Backspace, set this flag to prevent sending unnecessary selection and caret changes to IMF. + if (keyboardEvent.character() == KEYCODE_BACKSPACE) + m_receivedBackspaceKeyDown = true; + } Platform::KeyboardEvent adjustedKeyboardEvent(keyboardEvent.character(), type, adjustedModifiers); keyboardEventHandled = focusedFrame->eventHandler()->keyEvent(PlatformKeyboardEvent(adjustedKeyboardEvent)); @@ -1528,7 +1569,7 @@ bool InputHandler::deleteSelection() return false; ASSERT(frame->editor()); - return frame->editor()->command("DeleteBackward").execute(); + return handleKeyboardInput(Platform::KeyboardEvent(KEYCODE_BACKSPACE, Platform::KeyboardEvent::KeyDown, 0), false /* changeIsPartOfComposition */); } void InputHandler::insertText(const WTF::String& string) @@ -1538,7 +1579,6 @@ void InputHandler::insertText(const WTF::String& string) ASSERT(m_currentFocusElement->document() && m_currentFocusElement->document()->frame() && m_currentFocusElement->document()->frame()->editor()); Editor* editor = m_currentFocusElement->document()->frame()->editor(); - editor->command("InsertText").execute(string); } @@ -1798,10 +1838,14 @@ bool InputHandler::setBatchEditingActive(bool active) ASSERT(backingStoreClient); // Enable / Disable the backingstore to prevent visual updates. - if (!active) - backingStoreClient->backingStore()->resumeScreenAndBackingStoreUpdates(BackingStore::RenderAndBlit); - else - backingStoreClient->backingStore()->suspendScreenAndBackingStoreUpdates(); + // FIXME: Do we really need to suspend/resume both backingstore and screen here? + if (!active) { + backingStoreClient->backingStore()->resumeBackingStoreUpdates(); + backingStoreClient->backingStore()->resumeScreenUpdates(BackingStore::RenderAndBlit); + } else { + backingStoreClient->backingStore()->suspendBackingStoreUpdates(); + backingStoreClient->backingStore()->suspendScreenUpdates(); + } return true; } @@ -1843,7 +1887,12 @@ bool InputHandler::deleteTextRelativeToCursor(int leftOffset, int rightOffset) int caretOffset = caretPosition(); int start = relativeLeftOffset(caretOffset, leftOffset); int end = relativeRightOffset(caretOffset, elementText().length(), rightOffset); - if (!deleteText(start, end)) + + // If we have backspace in a single character, send this to webkit as a KeyboardEvent. Otherwise, call deleteText. + if (leftOffset == 1 && !rightOffset) { + if (!handleKeyboardInput(Platform::KeyboardEvent(KEYCODE_BACKSPACE, Platform::KeyboardEvent::KeyDown, 0), true /* changeIsPartOfComposition */)) + return false; + } else if (!deleteText(start, end)) return false; // Scroll the field if necessary. The automatic update is suppressed @@ -1860,6 +1909,9 @@ bool InputHandler::deleteText(int start, int end) ProcessingChangeGuard guard(this); + if (end - start == 1) + return handleKeyboardInput(Platform::KeyboardEvent(KEYCODE_BACKSPACE, Platform::KeyboardEvent::KeyDown, 0), true /* changeIsPartOfComposition */); + if (!setSelection(start, end, true /*changeIsPartOfComposition*/)) return false; @@ -2119,7 +2171,7 @@ bool InputHandler::setText(spannable_string_t* spannableString) return editor->command("InsertText").execute(textToInsert.right(1)); } InputLog(LogLevelInfo, "InputHandler::setText Single trailing character detected."); - return handleKeyboardInput(Platform::KeyboardEvent(textToInsert[textLength - 1], Platform::KeyboardEvent::KeyChar, 0), false /* changeIsPartOfComposition */); + return handleKeyboardInput(Platform::KeyboardEvent(textToInsert[textLength - 1], Platform::KeyboardEvent::KeyDown, 0), false /* changeIsPartOfComposition */); } // If no spans have changed, treat it as a delete operation. @@ -2132,7 +2184,7 @@ bool InputHandler::setText(spannable_string_t* spannableString) if (composingTextLength - textLength == 1) { InputLog(LogLevelInfo, "InputHandler::setText No spans have changed. New text is one character shorter than the old. Treating as 'delete'."); - return editor->command("DeleteBackward").execute(); + return handleKeyboardInput(Platform::KeyboardEvent(KEYCODE_BACKSPACE, Platform::KeyboardEvent::KeyDown, 0), true /* changeIsPartOfComposition */); } } @@ -2142,7 +2194,7 @@ bool InputHandler::setText(spannable_string_t* spannableString) // If there is no text to add just delete. if (!textLength) { if (selectionActive()) - return editor->command("DeleteBackward").execute(); + return handleKeyboardInput(Platform::KeyboardEvent(KEYCODE_BACKSPACE, Platform::KeyboardEvent::KeyDown, 0), true /* changeIsPartOfComposition */); // Nothing to do. return true; @@ -2153,7 +2205,7 @@ bool InputHandler::setText(spannable_string_t* spannableString) // Remove it and apply it as a keypress later. // Upstream Webkit bug created https://bugs.webkit.org/show_bug.cgi?id=70823 bool requiresSpaceKeyPress = false; - if (textLength > 0 && textToInsert[textLength - 1] == 32 /* space */) { + if (textLength > 0 && textToInsert[textLength - 1] == KEYCODE_SPACE) { requiresSpaceKeyPress = true; textLength--; textToInsert.remove(textLength, 1); @@ -2165,7 +2217,7 @@ bool InputHandler::setText(spannable_string_t* spannableString) // Handle single key non-attributed entry as key press rather than insert to allow // triggering of javascript events. InputLog(LogLevelInfo, "InputHandler::setText Single character entry treated as key-press in the absense of spans."); - return handleKeyboardInput(Platform::KeyboardEvent(textToInsert[0], Platform::KeyboardEvent::KeyChar, 0), true /* changeIsPartOfComposition */); + return handleKeyboardInput(Platform::KeyboardEvent(textToInsert[0], Platform::KeyboardEvent::KeyDown, 0), true /* changeIsPartOfComposition */); } // Perform the text change as a single command if there is one. @@ -2175,7 +2227,7 @@ bool InputHandler::setText(spannable_string_t* spannableString) } if (requiresSpaceKeyPress) - handleKeyboardInput(Platform::KeyboardEvent(32 /* space */, Platform::KeyboardEvent::KeyChar, 0), true /* changeIsPartOfComposition */); + handleKeyboardInput(Platform::KeyboardEvent(KEYCODE_SPACE, Platform::KeyboardEvent::KeyDown, 0), true /* changeIsPartOfComposition */); InputLog(LogLevelInfo, "InputHandler::setText Request being processed. Text after processing '%s'", elementText().latin1().data()); diff --git a/Source/WebKit/blackberry/WebKitSupport/InputHandler.h b/Source/WebKit/blackberry/WebKitSupport/InputHandler.h index 9e271ae2f..34de9b28f 100644 --- a/Source/WebKit/blackberry/WebKitSupport/InputHandler.h +++ b/Source/WebKit/blackberry/WebKitSupport/InputHandler.h @@ -101,6 +101,7 @@ public: bool isInputMode() const { return isActiveTextEdit(); } bool isMultilineInputMode() const { return isActiveTextEdit() && elementType(m_currentFocusElement.get()) == BlackBerry::Platform::InputTypeTextArea; } + PassRefPtr<WebCore::Element> currentFocusElement() const { return m_currentFocusElement; } void ensureFocusElementVisible(bool centerFieldInDisplay = true); void handleInputLocaleChanged(bool isRTL); @@ -223,10 +224,8 @@ private: RefPtr<WebCore::TextCheckingRequest> m_request; int32_t m_processingTransactionId; - double m_focusZoomScale; - WebCore::FloatPoint m_focusZoomLocation; - bool m_receivedBackspaceKeyDown; + unsigned short m_expectedKeyUpChar; }; } diff --git a/Source/WebKit/blackberry/WebKitSupport/SelectionHandler.cpp b/Source/WebKit/blackberry/WebKitSupport/SelectionHandler.cpp index fcd2e7e10..1b89071ac 100644 --- a/Source/WebKit/blackberry/WebKitSupport/SelectionHandler.cpp +++ b/Source/WebKit/blackberry/WebKitSupport/SelectionHandler.cpp @@ -253,14 +253,17 @@ void SelectionHandler::setCaretPosition(const WebCore::IntPoint &position) VisiblePosition visibleCaretPosition(focusedFrame->visiblePositionForPoint(relativePoint)); - if (!DOMSupport::isPositionInNode(m_webPage->focusedOrMainFrame()->document()->focusedNode(), visibleCaretPosition.deepEquivalent())) { - if (unsigned short character = directionOfPointRelativeToRect(relativePoint, currentCaretRect)) - m_webPage->m_inputHandler->handleKeyboardInput(Platform::KeyboardEvent(character)); - - // Send the selection changed in case this does not trigger a selection change to - // ensure the caret position is accurate. This may be a duplicate event. - selectionPositionChanged(true /* forceUpdateWithoutChange */); - return; + if (RenderObject* focusedRenderer = focusedFrame->document()->focusedNode()->renderer()) { + WebCore::IntRect nodeOutlineBounds(focusedRenderer->absoluteOutlineBounds()); + if (!nodeOutlineBounds.contains(relativePoint)) { + if (unsigned short character = directionOfPointRelativeToRect(relativePoint, currentCaretRect)) + m_webPage->m_inputHandler->handleKeyboardInput(Platform::KeyboardEvent(character)); + + // Send the selection changed in case this does not trigger a selection change to + // ensure the caret position is accurate. This may be a duplicate event. + selectionPositionChanged(true /* forceUpdateWithoutChange */); + return; + } } VisibleSelection newSelection(visibleCaretPosition); diff --git a/Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.cpp b/Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.cpp index 3d9e92ff0..790c46403 100644 --- a/Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.cpp +++ b/Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.cpp @@ -19,6 +19,7 @@ #include "config.h" #include "TouchEventHandler.h" +#include "BlackBerryPlatformSystemSound.h" #include "DOMSupport.h" #include "Document.h" #include "DocumentMarkerController.h" @@ -54,62 +55,10 @@ using namespace WTF; namespace BlackBerry { namespace WebKit { -static bool hasMouseMoveListener(Element* element) -{ - ASSERT(element); - return element->hasEventListeners(eventNames().mousemoveEvent) || element->document()->hasEventListeners(eventNames().mousemoveEvent); -} - -static bool hasTouchListener(Element* element) -{ - ASSERT(element); - return element->hasEventListeners(eventNames().touchstartEvent) - || element->hasEventListeners(eventNames().touchmoveEvent) - || element->hasEventListeners(eventNames().touchcancelEvent) - || element->hasEventListeners(eventNames().touchendEvent); -} - -static bool isRangeControlElement(Element* element) -{ - ASSERT(element); - if (!element->hasTagName(HTMLNames::inputTag)) - return false; - - HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(element); - return inputElement->isRangeControl(); -} - -static bool shouldConvertTouchToMouse(Element* element) -{ - if (!element) - return false; - - if ((element->hasTagName(HTMLNames::objectTag) || element->hasTagName(HTMLNames::embedTag)) && static_cast<HTMLPlugInElement*>(element)) - return true; - - // Input Range element is a special case that requires natural mouse events - // in order to allow dragging of the slider handle. - // Input Range element might appear in the webpage, or it might appear in the shadow tree, - // like the timeline and volume media controls all use Input Range. - // won't operate on the shadow node of other element type, because the webpages - // aren't able to attach listeners to shadow content. - do { - if (isRangeControlElement(element)) - return true; - element = toElement(element->shadowAncestorNode()); // If an element is not in shadow tree, shadowAncestorNode returns itself. - } while (element->isInShadowTree()); - - // Check if the element has a mouse listener and no touch listener. If so, - // the field will require touch events be converted to mouse events to function properly. - return hasMouseMoveListener(element) && !hasTouchListener(element); - -} - TouchEventHandler::TouchEventHandler(WebPagePrivate* webpage) : m_webPage(webpage) - , m_didCancelTouch(false) - , m_convertTouchToMouse(false) , m_existingTouchMode(ProcessedTouchEvents) + , m_shouldRequestSpellCheckOptions(false) { } @@ -117,140 +66,51 @@ TouchEventHandler::~TouchEventHandler() { } -bool TouchEventHandler::shouldSuppressMouseDownOnTouchDown() const -{ - return m_lastFatFingersResult.isTextInput() || m_webPage->m_inputHandler->isInputMode() || m_webPage->m_selectionHandler->isSelectionActive(); -} - -void TouchEventHandler::touchEventCancel() -{ - m_webPage->m_inputHandler->processPendingKeyboardVisibilityChange(); - - // Input elements delay mouse down and do not need to be released on touch cancel. - if (!shouldSuppressMouseDownOnTouchDown()) - m_webPage->m_page->focusController()->focusedOrMainFrame()->eventHandler()->setMousePressed(false); - - m_convertTouchToMouse = m_webPage->m_touchEventMode == PureTouchEventsWithMouseConversion; - m_didCancelTouch = true; - - // If we cancel a single touch event, we need to also clean up any hover - // state we get into by synthetically moving the mouse to the m_fingerPoint. - Element* elementUnderFatFinger = m_lastFatFingersResult.positionWasAdjusted() ? m_lastFatFingersResult.nodeAsElementIfApplicable() : 0; - do { - if (!elementUnderFatFinger || !elementUnderFatFinger->renderer()) - break; - - if (!elementUnderFatFinger->renderer()->style()->affectedByHoverRules() - && !elementUnderFatFinger->renderer()->style()->affectedByActiveRules()) - break; - - HitTestRequest request(HitTestRequest::TouchEvent | HitTestRequest::Release); - // The HitTestResult point is not actually needed. - HitTestResult result(IntPoint::zero()); - result.setInnerNode(elementUnderFatFinger); - - Document* document = elementUnderFatFinger->document(); - ASSERT(document); - document->renderView()->layer()->updateHoverActiveState(request, result); - document->updateStyleIfNeeded(); - - // Updating the document style may destroy the renderer. - if (!elementUnderFatFinger->renderer()) - break; - - elementUnderFatFinger->renderer()->repaint(); - ASSERT(!elementUnderFatFinger->hovered()); - } while (0); - - m_lastFatFingersResult.reset(); -} - -void TouchEventHandler::touchHoldEvent() +void TouchEventHandler::doFatFingers(Platform::TouchPoint& point) { - // This is a hack for our hack that converts the touch pressed event that we've delayed because the user has focused a input field - // to the page as a mouse pressed event. - if (shouldSuppressMouseDownOnTouchDown()) - handleFatFingerPressed(); - - // Clear the focus ring indication if tap-and-hold'ing on a link. - if (m_lastFatFingersResult.node() && m_lastFatFingersResult.node()->isLink()) - m_webPage->clearFocusNode(); + m_lastScreenPoint = point.m_screenPos; + m_lastFatFingersResult.reset(); // Theoretically this shouldn't be required. Keep it just in case states get mangled. + IntPoint contentPos(m_webPage->mapFromViewportToContents(point.m_pos)); + m_webPage->postponeDocumentStyleRecalc(); + m_lastFatFingersResult = FatFingers(m_webPage, contentPos, FatFingers::ClickableElement).findBestPoint(); + m_webPage->resumeDocumentStyleRecalc(); } -static bool isMainFrameScrollable(const WebPagePrivate* page) +void TouchEventHandler::sendClickAtFatFingersPoint() { - return page->viewportSize().width() < page->contentsSize().width() || page->viewportSize().height() < page->contentsSize().height(); + handleFatFingerPressed(); + PlatformMouseEvent mouseRelease(m_webPage->mapFromContentsToViewport(m_lastFatFingersResult.adjustedPosition()), m_lastScreenPoint, PlatformEvent::MouseReleased, 1, LeftButton, TouchScreen); + m_webPage->handleMouseEvent(mouseRelease); } -bool TouchEventHandler::handleTouchPoint(Platform::TouchPoint& point, bool useFatFingers) +void TouchEventHandler::handleTouchPoint(Platform::TouchPoint& point) { // Enable input mode on any touch event. m_webPage->m_inputHandler->setInputModeEnabled(); - bool pureWithMouseConversion = m_webPage->m_touchEventMode == PureTouchEventsWithMouseConversion; - bool alwaysEnableMouseConversion = pureWithMouseConversion || (!isMainFrameScrollable(m_webPage) && !m_webPage->m_inRegionScroller->d->isActive()); - switch (point.m_state) { case Platform::TouchPoint::TouchPressed: { - // FIXME: bypass FatFingers if useFatFingers is false - m_lastFatFingersResult.reset(); // Theoretically this shouldn't be required. Keep it just in case states get mangled. - m_didCancelTouch = false; - m_lastScreenPoint = point.m_screenPos; - - IntPoint contentPos(m_webPage->mapFromViewportToContents(point.m_pos)); - - m_webPage->postponeDocumentStyleRecalc(); - m_lastFatFingersResult = FatFingers(m_webPage, contentPos, FatFingers::ClickableElement).findBestPoint(); - - Element* elementUnderFatFinger = 0; - if (m_lastFatFingersResult.positionWasAdjusted() && m_lastFatFingersResult.node()) { - ASSERT(m_lastFatFingersResult.node()->isElementNode()); - elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable(); - } - - // Set or reset the touch mode. - Element* possibleTargetNodeForMouseMoveEvents = static_cast<Element*>(m_lastFatFingersResult.positionWasAdjusted() ? elementUnderFatFinger : m_lastFatFingersResult.node()); - m_convertTouchToMouse = alwaysEnableMouseConversion ? true : shouldConvertTouchToMouse(possibleTargetNodeForMouseMoveEvents); - - if (!possibleTargetNodeForMouseMoveEvents || (!possibleTargetNodeForMouseMoveEvents->hasEventListeners(eventNames().touchmoveEvent) && !m_convertTouchToMouse)) - m_webPage->client()->notifyNoMouseMoveOrTouchMoveHandlers(); - - m_webPage->resumeDocumentStyleRecalc(); + doFatFingers(point); + // FIXME Draw tap highlight as soon as possible if we can + Element* elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable(); if (elementUnderFatFinger) drawTapHighlight(); - // Lets be conservative here: since we have problems on major website having - // mousemove listener for no good reason (e.g. google.com, desktop edition), - // let only delay client notifications when there is not input text node involved. - if (m_convertTouchToMouse - && (m_webPage->m_inputHandler->isInputMode() && !m_lastFatFingersResult.isTextInput())) { - m_webPage->m_inputHandler->setDelayKeyboardVisibilityChange(true); - handleFatFingerPressed(); - } else if (!shouldSuppressMouseDownOnTouchDown()) - handleFatFingerPressed(); - - return true; + // Check for text selection + if (m_lastFatFingersResult.isTextInput()) { + elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable(FatFingersResult::ShadowContentNotAllowed, true /* shouldUseRootEditableElement */); + m_shouldRequestSpellCheckOptions = m_webPage->m_inputHandler->shouldRequestSpellCheckingOptionsForPoint(point.m_pos, elementUnderFatFinger, m_spellCheckOptionRequest); + } + + handleFatFingerPressed(); + break; } case Platform::TouchPoint::TouchReleased: { - imf_sp_text_t spellCheckOptionRequest; - bool shouldRequestSpellCheckOptions = false; - - if (m_lastFatFingersResult.isTextInput()) - shouldRequestSpellCheckOptions = m_webPage->m_inputHandler->shouldRequestSpellCheckingOptionsForPoint(point.m_pos - , m_lastFatFingersResult.nodeAsElementIfApplicable(FatFingersResult::ShadowContentNotAllowed, true /* shouldUseRootEditableElement */) - , spellCheckOptionRequest); - - // Apply any suppressed changes. This does not eliminate the need - // for the show after the handling of fat finger pressed as it may - // have triggered a state change. Leave the change suppressed if - // we are triggering spell check options. - if (!shouldRequestSpellCheckOptions) - m_webPage->m_inputHandler->processPendingKeyboardVisibilityChange(); - if (shouldSuppressMouseDownOnTouchDown()) - handleFatFingerPressed(); + if (!m_shouldRequestSpellCheckOptions) + m_webPage->m_inputHandler->processPendingKeyboardVisibilityChange(); // The rebase has eliminated a necessary event when the mouse does not // trigger an actual selection change preventing re-showing of the @@ -261,52 +121,40 @@ bool TouchEventHandler::handleTouchPoint(Platform::TouchPoint& point, bool useFa m_webPage->m_tapHighlight->hide(); - IntPoint adjustedPoint; - // always use the true touch point if using the meta-tag, otherwise only use it if we sent mouse moves - // to the page and its requested. - if (pureWithMouseConversion || (m_convertTouchToMouse && !useFatFingers)) { - adjustedPoint = point.m_pos; - m_convertTouchToMouse = pureWithMouseConversion; - } else // Fat finger point in viewport coordinates. - adjustedPoint = m_webPage->mapFromContentsToViewport(m_lastFatFingersResult.adjustedPosition()); - + IntPoint adjustedPoint = m_webPage->mapFromContentsToViewport(m_lastFatFingersResult.adjustedPosition()); PlatformMouseEvent mouseEvent(adjustedPoint, m_lastScreenPoint, PlatformEvent::MouseReleased, 1, LeftButton, TouchScreen); m_webPage->handleMouseEvent(mouseEvent); - m_lastFatFingersResult.reset(); // Reset the fat finger result as its no longer valid when a user's finger is not on the screen. - if (shouldRequestSpellCheckOptions) { + + if (m_shouldRequestSpellCheckOptions) { IntPoint pixelPositionRelativeToViewport = m_webPage->mapToTransformed(adjustedPoint); - m_webPage->m_inputHandler->requestSpellingCheckingOptions(spellCheckOptionRequest, IntSize(m_lastScreenPoint - pixelPositionRelativeToViewport)); + m_webPage->m_inputHandler->requestSpellingCheckingOptions(m_spellCheckOptionRequest, IntSize(m_lastScreenPoint - pixelPositionRelativeToViewport)); } - return true; + + m_lastFatFingersResult.reset(); // Reset the fat finger result as its no longer valid when a user's finger is not on the screen. + break; } case Platform::TouchPoint::TouchMoved: - if (m_convertTouchToMouse) { + { + // You can still send mouse move events PlatformMouseEvent mouseEvent(point.m_pos, m_lastScreenPoint, PlatformEvent::MouseMoved, 1, LeftButton, TouchScreen); m_lastScreenPoint = point.m_screenPos; - if (!m_webPage->handleMouseEvent(mouseEvent)) { - m_convertTouchToMouse = alwaysEnableMouseConversion; - return false; - } - return true; + m_webPage->handleMouseEvent(mouseEvent); + break; } - break; default: break; } - return false; } void TouchEventHandler::handleFatFingerPressed() { - if (!m_didCancelTouch) { - // First update the mouse position with a MouseMoved event. - PlatformMouseEvent mouseMoveEvent(m_webPage->mapFromContentsToViewport(m_lastFatFingersResult.adjustedPosition()), m_lastScreenPoint, PlatformEvent::MouseMoved, 0, LeftButton, TouchScreen); - m_webPage->handleMouseEvent(mouseMoveEvent); - - // Then send the MousePressed event. - PlatformMouseEvent mousePressedEvent(m_webPage->mapFromContentsToViewport(m_lastFatFingersResult.adjustedPosition()), m_lastScreenPoint, PlatformEvent::MousePressed, 1, LeftButton, TouchScreen); - m_webPage->handleMouseEvent(mousePressedEvent); - } + // First update the mouse position with a MouseMoved event. + PlatformMouseEvent mouseMoveEvent(m_webPage->mapFromContentsToViewport(m_lastFatFingersResult.adjustedPosition()), m_lastScreenPoint, PlatformEvent::MouseMoved, 0, LeftButton, TouchScreen); + m_webPage->handleMouseEvent(mouseMoveEvent); + + // Then send the MousePressed event. + PlatformMouseEvent mousePressedEvent(m_webPage->mapFromContentsToViewport(m_lastFatFingersResult.adjustedPosition()), m_lastScreenPoint, PlatformEvent::MousePressed, 1, LeftButton, TouchScreen); + m_webPage->handleMouseEvent(mousePressedEvent); } // This method filters what element will get tap-highlight'ed or not. To start with, @@ -394,6 +242,9 @@ void TouchEventHandler::drawTapHighlight() IntRect rect = focusRingQuads[i].enclosingBoundingBox(); rect.move(framePos.x(), framePos.y()); IntRect clippedRect = intersection(clippingRect, rect); + // FIXME we shouldn't have any empty rects here PR 246960 + if (clippedRect.isEmpty()) + continue; clippedRect.inflate(2); region = unionRegions(region, Platform::IntRect(clippedRect)); } @@ -405,5 +256,11 @@ void TouchEventHandler::drawTapHighlight() shouldHideTapHighlightRightAfterScrolling); } +void TouchEventHandler::playSoundIfAnchorIsTarget() const +{ + if (m_lastFatFingersResult.node() && m_lastFatFingersResult.node()->isLink()) + BlackBerry::Platform::SystemSound::instance()->playSound(BlackBerry::Platform::SystemSoundType::InputKeypress); +} + } } diff --git a/Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.h b/Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.h index bce187dfa..0d0f35ace 100644 --- a/Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.h +++ b/Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.h @@ -35,31 +35,28 @@ public: TouchEventHandler(WebPagePrivate* webpage); ~TouchEventHandler(); - bool handleTouchPoint(Platform::TouchPoint&, bool useFatFingers); - void touchEventCancel(); - void touchHoldEvent(); - - bool shouldSuppressMouseDownOnTouchDown() const; + void doFatFingers(Platform::TouchPoint&); + void handleTouchPoint(Platform::TouchPoint&); + void sendClickAtFatFingersPoint(); const FatFingersResult& lastFatFingersResult() const { return m_lastFatFingersResult; } void resetLastFatFingersResult() { m_lastFatFingersResult.reset(); } + void playSoundIfAnchorIsTarget() const; + private: void handleFatFingerPressed(); - void drawTapHighlight(); private: WebPagePrivate* m_webPage; - bool m_didCancelTouch; - bool m_convertTouchToMouse; - WebCore::TouchEventMode m_existingTouchMode; - WebCore::IntPoint m_lastScreenPoint; // Screen Position - FatFingersResult m_lastFatFingersResult; + imf_sp_text_t m_spellCheckOptionRequest; + bool m_shouldRequestSpellCheckOptions; + }; } |
