void MiniBrowser::handlePointerMoveEvent(const XPointerMovedEvent& event) { NIXMouseEvent nixEvent; nixEvent.type = kNIXInputEventTypeMouseMove; nixEvent.button = kWKEventMouseButtonNoButton; WKPoint contentsPoint = NIXViewUserViewportToContents(m_view, WKPointMake(event.x, event.y)); nixEvent.x = contentsPoint.x; nixEvent.y = contentsPoint.y; nixEvent.globalX = event.x_root; nixEvent.globalY = event.y_root; nixEvent.clickCount = 0; nixEvent.modifiers = convertXEventModifiersToNativeModifiers(event.state); nixEvent.timestamp = convertXEventTimeToNixTimestamp(event.time); if (m_touchMocker && m_touchMocker->handleMouseMove(nixEvent, WKPointMake(event.x, event.y))) { scheduleUpdateDisplay(); return; } // The mouse move event was allowed to be sent to the TouchMocker because it // may be tracking a button press that happened in a valid position. NIXView view = webViewAtX11Position(WKPointMake(event.x, event.y)); if (!view) return; NIXViewSendMouseEvent(view, &nixEvent); }
void GestureRecognizer::setupPinchData(const NIXTouchEvent& event) { const NIXTouchPoint& first = event.touchPoints[0]; const NIXTouchPoint& second = event.touchPoints[1]; m_initialPinchDistance = computeDistance(WKPointMake(first.globalX, first.globalY), WKPointMake(second.globalX, second.globalY)); m_initialPinchScale = m_client->scale(); m_initialPinchContentCenter = computeCenter(WKPointMake(first.x, first.y), WKPointMake(second.x, second.y)); m_previousPinchGlobalCenter = computeCenter(WKPointMake(first.globalX, first.globalY), WKPointMake(second.globalX, second.globalY)); }
void MiniBrowser::handleDoubleTap(double timestamp, const NIXTouchPoint& touchPoint) { if (!m_viewportUserScalable) return; WKPoint contentsPoint = WKPointMake(touchPoint.x, touchPoint.y); NIXViewFindZoomableAreaForPoint(m_view, contentsPoint, touchPoint.verticalRadius, touchPoint.horizontalRadius); }
void MiniBrowser::handleWheelEvent(const XButtonPressedEvent& event) { WKPoint contentsPoint = NIXViewUserViewportToContents(m_view, WKPointMake(event.x, event.y)); if (m_mode == MobileMode && event.state & ControlMask) { double newScale = NIXViewScale(m_view) * (event.button == 4 ? 1.1 : 0.9); scaleAtPoint(contentsPoint, newScale); return; } // Same constant we use inside WebView to calculate the ticks. See also WebCore::Scrollbar::pixelsPerLineStep(). const float pixelsPerStep = 40.0f; NIXWheelEvent nixEvent; nixEvent.type = kNIXInputEventTypeWheel; nixEvent.modifiers = convertXEventModifiersToNativeModifiers(event.state); nixEvent.timestamp = convertXEventTimeToNixTimestamp(event.time); nixEvent.x = contentsPoint.x; nixEvent.y = contentsPoint.y; nixEvent.globalX = event.x_root; nixEvent.globalY = event.y_root; nixEvent.delta = pixelsPerStep * (event.button == 4 ? 1 : -1); nixEvent.orientation = event.state & ShiftMask ? kNIXWheelEventOrientationHorizontal : kNIXWheelEventOrientationVertical; NIXViewSendWheelEvent(m_view, &nixEvent); }
void PageViewportControllerClientEfl::setViewportPosition(const WebCore::FloatPoint& contentsPoint) { m_contentPosition = contentsPoint; WKViewSetContentPosition(m_view->wkView(), WKPointMake(contentsPoint.x(), contentsPoint.y())); m_controller->didChangeContentsVisibility(m_contentPosition, m_controller->currentScale()); }
void GestureRecognizer::updatePinchData(double timestamp, const NIXTouchEvent& event) { assert(m_initialPinchScale > 0); const NIXTouchPoint& first = event.touchPoints[0]; const NIXTouchPoint& second = event.touchPoints[1]; WKPoint currentCenter = computeCenter(WKPointMake(first.globalX, first.globalY), WKPointMake(second.globalX, second.globalY)); WKPoint delta = WKPointMake((currentCenter.x - m_previousPinchGlobalCenter.x) / m_client->scale(), (currentCenter.y - m_previousPinchGlobalCenter.y) / m_client->scale()); double currentDistance = computeDistance(WKPointMake(first.globalX, first.globalY), WKPointMake(second.globalX, second.globalY)); double newScale = m_initialPinchScale * (currentDistance / m_initialPinchDistance); m_client->handlePinch(timestamp, delta, newScale, m_initialPinchContentCenter); m_previousPinchGlobalCenter = currentCenter; }
void MiniBrowser::handleButtonPressEvent(const XButtonPressedEvent& event) { NIXView view = webViewAtX11Position(WKPointMake(event.x, event.y)); if (!view) return; if (event.button == 4 || event.button == 5) { handleWheelEvent(event); return; } updateClickCount(event); NIXMouseEvent nixEvent = convertXButtonEventToNixButtonEvent(view, event, kNIXInputEventTypeMouseDown, m_clickCount); if (m_touchMocker && m_touchMocker->handleMousePress(nixEvent, WKPointMake(event.x, event.y))) { scheduleUpdateDisplay(); return; } NIXViewSendMouseEvent(view, &nixEvent); }
void MiniBrowser::handlePinch(double timestamp, WKPoint delta, double scale, WKPoint contentCenter) { if (!m_viewportUserScalable) return; // Scaling: The page should be scaled proportionally to the distance of the pinch. // Scrolling: If the center of the pinch initially was position (120,120) in content // coordinates, them during the page must be scrolled to keep the pinch center // at the same coordinates. NIXViewSuspendActiveDOMObjectsAndAnimations(m_view); WKPoint position = WKPointMake(NIXViewScrollPosition(m_view).x - delta.x, NIXViewScrollPosition(m_view).y - delta.y); NIXViewSetScrollPosition(m_view, position); scaleAtPoint(contentCenter, scale, LowerMinimumScale); }
static NIXMouseEvent convertXButtonEventToNixButtonEvent(NIXView view, const XButtonEvent& event, NIXInputEventType type, unsigned clickCount) { NIXMouseEvent nixEvent; nixEvent.type = type; nixEvent.button = convertXEventButtonToNativeMouseButton(event.button); WKPoint contentsPoint = NIXViewUserViewportToContents(view, WKPointMake(event.x, event.y)); nixEvent.x = contentsPoint.x; nixEvent.y = contentsPoint.y; nixEvent.globalX = event.x_root; nixEvent.globalY = event.y_root; nixEvent.clickCount = clickCount; nixEvent.modifiers = convertXEventModifiersToNativeModifiers(event.state); nixEvent.timestamp = convertXEventTimeToNixTimestamp(event.time); return nixEvent; }
void MiniBrowser::handleButtonReleaseEvent(const XButtonReleasedEvent& event) { if (event.button == 4 || event.button == 5) return; NIXMouseEvent nixEvent = convertXButtonEventToNixButtonEvent(m_view, event, kNIXInputEventTypeMouseUp, 0); if (m_touchMocker && m_touchMocker->handleMouseRelease(nixEvent)) { scheduleUpdateDisplay(); return; } // The mouse release event was allowed to be sent to the TouchMocker because it // may be tracking a button press that happened in a valid position. NIXView view = webViewAtX11Position(WKPointMake(event.x, event.y)); if (!view) return; NIXViewSendMouseEvent(view, &nixEvent); }
void MiniBrowser::didFindZoomableArea(NIXView, WKPoint target, WKRect area, const void* clientInfo) { MiniBrowser* mb = static_cast<MiniBrowser*>(const_cast<void*>(clientInfo)); // Zoomable area width is the same as web page width, and this is fully visible. if (mb->m_contentsSize.width == area.size.width && mb->m_contentsSize.width == NIXViewVisibleContentsSize(mb->m_view).width) return; // The zoomed area will look nicer with a horizontal margin. double scale = NIXViewSize(mb->m_view).width / (area.size.width + horizontalMarginForViewportAdjustment * 2.0); // Trying to zoom to an area with the same scale factor causes a zoom out. if (scale == NIXViewScale(mb->m_view)) scale = mb->scaleToFitContents(); else { // We want the zoomed content area to fit horizontally in the WebView, // so let's give the scaleAtPoint method a suitable value. target.x = area.origin.x - horizontalMarginForViewportAdjustment; NIXViewSetScrollPosition(mb->m_view, WKPointMake(target.x, NIXViewScrollPosition(mb->m_view).y)); } mb->scaleAtPoint(target, scale); }
void MiniBrowser::scaleAtPoint(const WKPoint& point, double scale, ScaleBehavior scaleBehavior) { if (!m_viewportUserScalable) return; double minimumScale = double(NIXViewSize(m_view).width) / m_contentsSize.width; if (scaleBehavior & LowerMinimumScale) minimumScale *= 0.5; if (scale < minimumScale) scale = minimumScale; // Calculate new scroll points that will keep the content // approximately at the same visual point. double scaleRatio = NIXViewScale(m_view) / scale; WKPoint position = WKPointMake(point.x - (point.x - NIXViewScrollPosition(m_view).x) * scaleRatio, point.y - (point.y - NIXViewScrollPosition(m_view).y) * scaleRatio); NIXViewSetScale(m_view, scale); if (scaleBehavior & AdjustToBoundaries) position = adjustScrollPositionToBoundaries(position); NIXViewSetScrollPosition(m_view, position); }
TEST(WebKit2, WKViewUserViewportToContents) { // This test creates a WKView and uses the WKViewUserViewportToContents // function to convert viewport coordinates to contents (page) coordinates. // It scrolls and scales around the contents and check if the coordinates // conversion math is right. WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate()); WKRetainPtr<WKViewRef> webView(AdoptWK, WKViewCreate(context.get(), 0)); WKViewInitialize(webView.get()); WKPageSetUseFixedLayout(WKViewGetPage(webView.get()), false); WKPoint out; // At scale 1.0 the viewport and contents coordinates should match. WKViewSetContentScaleFactor(webView.get(), 1.0); WKViewSetContentPosition(webView.get(), WKPointMake(0, 0)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 0); EXPECT_EQ(out.y, 0); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 10); EXPECT_EQ(out.y, 10); WKViewSetContentPosition(webView.get(), WKPointMake(20, 20)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 20); EXPECT_EQ(out.y, 20); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 30); EXPECT_EQ(out.y, 30); // At scale 2.0 the viewport distance values will be half // the ones seem in the contents. WKViewSetContentScaleFactor(webView.get(), 2.0); WKViewSetContentPosition(webView.get(), WKPointMake(0, 0)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 0); EXPECT_EQ(out.y, 0); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 5); EXPECT_EQ(out.y, 5); WKViewSetContentPosition(webView.get(), WKPointMake(20, 20)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 20); EXPECT_EQ(out.y, 20); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 25); EXPECT_EQ(out.y, 25); // At scale 0.5 the viewport distance values will be twice // the ones seem in the contents. WKViewSetContentScaleFactor(webView.get(), 0.5); WKViewSetContentPosition(webView.get(), WKPointMake(0, 0)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 0); EXPECT_EQ(out.y, 0); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 20); EXPECT_EQ(out.y, 20); WKViewSetContentPosition(webView.get(), WKPointMake(20, 20)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 20); EXPECT_EQ(out.y, 20); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 40); EXPECT_EQ(out.y, 40); // Let's add translation to the viewport. const int delta = 10; WKViewSetUserViewportTranslation(webView.get(), delta, delta); WKViewSetContentPosition(webView.get(), WKPointMake(0, 0)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 0 - delta / 0.5); EXPECT_EQ(out.y, 0 - delta / 0.5); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 20 - delta / 0.5); EXPECT_EQ(out.y, 20 - delta / 0.5); WKViewSetContentPosition(webView.get(), WKPointMake(20, 20)); out = WKViewUserViewportToContents(webView.get(), WKPointMake(0, 0)); EXPECT_EQ(out.x, 20 - delta / 0.5); EXPECT_EQ(out.y, 20 - delta / 0.5); out = WKViewUserViewportToContents(webView.get(), WKPointMake(10, 10)); EXPECT_EQ(out.x, 40 - delta / 0.5); EXPECT_EQ(out.y, 40 - delta / 0.5); }
void InjectedBundleFrameHitTestTest::frameLoadFinished(WKBundleFrameRef frame) { WKBundleHitTestResultRef hitTestResult = WKBundleFrameCreateHitTestResult(frame, WKPointMake(50, 50)); WKRetainPtr<WKStringRef> linkTitle(AdoptWK, WKBundleHitTestResultCopyLinkTitle(hitTestResult)); WKBundlePostMessage(m_bundle, Util::toWK("InjectedBundleFrameHitTestDone").get(), linkTitle.get()); }
static WKPoint computeCenter(WKPoint a, WKPoint b) { return WKPointMake((a.x + b.x) / 2, (a.y + b.y) / 2); }
void GestureRecognizer::updatePanningData(double timestamp, const NIXTouchPoint& current) { WKPoint delta = WKPointMake((current.globalX - m_previousTouchPoint.globalX) / m_client->scale(), (current.globalY - m_previousTouchPoint.globalY) / m_client->scale()); m_client->handlePanning(timestamp, delta); }