Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: Source/web/WebFrameWidgetImpl.cpp

Issue 638003004: Introduce WebFrameWidget to Blink (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Style Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/web/WebFrameWidgetImpl.h ('k') | Source/web/WebLocalFrameImpl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2014 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "web/WebFrameWidgetImpl.h"
33
34 #include "core/editing/Editor.h"
35 #include "core/editing/FrameSelection.h"
36 #include "core/editing/InputMethodController.h"
37 #include "core/editing/PlainTextRange.h"
38 #include "core/frame/FrameView.h"
39 #include "core/frame/RemoteFrame.h"
40 #include "core/frame/Settings.h"
41 #include "core/page/EventHandler.h"
42 #include "core/page/FocusController.h"
43 #include "core/page/Page.h"
44 #include "core/rendering/RenderView.h"
45 #include "core/rendering/compositing/RenderLayerCompositor.h"
46 #include "platform/KeyboardCodes.h"
47 #include "platform/NotImplemented.h"
48 #include "public/web/WebBeginFrameArgs.h"
49 #include "public/web/WebWidgetClient.h"
50 #include "web/WebInputEventConversion.h"
51 #include "web/WebLocalFrameImpl.h"
52 #include "web/WebPluginContainerImpl.h"
53 #include "web/WebRemoteFrameImpl.h"
54 #include "web/WebViewImpl.h"
55
56 namespace blink {
57
58 // WebFrameWidget -------------------------------------------------------------- --
59
60 WebFrameWidget* WebFrameWidget::create(WebWidgetClient* client, WebLocalFrame* l ocalRoot)
61 {
62 // Pass the WebFrameWidget's self-reference to the caller.
63 return WebFrameWidgetImpl::create(client, localRoot);
64 }
65
66 WebFrameWidgetImpl* WebFrameWidgetImpl::create(WebWidgetClient* client, WebLocal Frame* localRoot)
67 {
68 // Pass the WebFrameWidgetImpl's self-reference to the caller.
69 return adoptRef(new WebFrameWidgetImpl(client, localRoot)).leakRef();
70 }
71
72 WebFrameWidgetImpl::WebFrameWidgetImpl(WebWidgetClient* client, WebLocalFrame* l ocalRoot)
73 : m_client(client)
74 , m_localRoot(toWebLocalFrameImpl(localRoot))
75 , m_layerTreeView(nullptr)
76 , m_rootLayer(nullptr)
77 , m_rootGraphicsLayer(nullptr)
78 , m_isAcceleratedCompositingActive(false)
79 , m_layerTreeViewClosed(false)
80 , m_webView(m_localRoot->viewImpl())
81 , m_page(m_webView->page())
82 , m_suppressNextKeypressEvent(false)
83 , m_ignoreInputEvents(false)
84 {
85 ASSERT(m_localRoot->frame()->isLocalRoot());
86 initializeLayerTreeView();
87 m_localRoot->setFrameWidget(this);
88 }
89
90 WebFrameWidgetImpl::~WebFrameWidgetImpl()
91 {
92 }
93
94 // WebWidget ------------------------------------------------------------------
95
96 void WebFrameWidgetImpl::close()
97 {
98 // Reset the delegate to prevent notifications being sent as we're being
99 // deleted.
100 m_client = nullptr;
101
102 deref(); // Balances ref() acquired in WebFrameWidget::create
103 }
104
105 WebSize WebFrameWidgetImpl::size()
106 {
107 return m_size;
108 }
109
110 void WebFrameWidgetImpl::willStartLiveResize()
111 {
112 if (m_localRoot->frameView())
113 m_localRoot->frameView()->willStartLiveResize();
114
115 LocalFrame* frame = m_localRoot->frame();
116 WebPluginContainerImpl* pluginContainer = WebLocalFrameImpl::pluginContainer FromFrame(frame);
117 if (pluginContainer)
118 pluginContainer->willStartLiveResize();
119 }
120
121 void WebFrameWidgetImpl::resize(const WebSize& newSize)
122 {
123 if (m_size == newSize)
124 return;
125
126 FrameView* view = m_localRoot->frameView();
127 if (!view)
128 return;
129
130 m_size = newSize;
131
132 updateMainFrameLayoutSize();
133
134 view->resize(m_size);
135
136 // FIXME: In WebViewImpl this layout was a precursor to setting the minimum scale limit.
137 // It is not clear if this is necessary for frame-level widget resize.
138 if (view->needsLayout())
139 view->layout();
140
141 // FIXME: Investigate whether this is needed; comment from eseidel suggests that this function
142 // is flawed.
143 sendResizeEventAndRepaint();
144 }
145
146 void WebFrameWidgetImpl::sendResizeEventAndRepaint()
147 {
148 // FIXME: This is wrong. The FrameView is responsible sending a resizeEvent
149 // as part of layout. Layout is also responsible for sending invalidations
150 // to the embedder. This method and all callers may be wrong. -- eseidel.
151 if (m_localRoot->frameView()) {
152 // Enqueues the resize event.
153 m_localRoot->frame()->document()->enqueueResizeEvent();
154 }
155
156 if (m_client) {
157 if (isAcceleratedCompositingActive()) {
158 updateLayerTreeViewport();
159 } else {
160 WebRect damagedRect(0, 0, m_size.width, m_size.height);
161 m_client->didInvalidateRect(damagedRect);
162 }
163 }
164 }
165
166 void WebFrameWidgetImpl::resizePinchViewport(const WebSize& newSize)
167 {
168 // FIXME: Implement pinch viewport for out-of-process iframes.
169 }
170
171 void WebFrameWidgetImpl::updateMainFrameLayoutSize()
172 {
173 if (!m_localRoot)
174 return;
175
176 RefPtr<FrameView> view = m_localRoot->frameView();
177 if (!view)
178 return;
179
180 WebSize layoutSize = m_size;
181
182 view->setLayoutSize(layoutSize);
183 }
184
185 void WebFrameWidgetImpl::willEndLiveResize()
186 {
187 if (m_localRoot->frameView())
188 m_localRoot->frameView()->willEndLiveResize();
189
190 LocalFrame* frame = m_localRoot->frame();
191 WebPluginContainerImpl* pluginContainer = WebLocalFrameImpl::pluginContainer FromFrame(frame);
192 if (pluginContainer)
193 pluginContainer->willEndLiveResize();
194 }
195
196 void WebFrameWidgetImpl::willEnterFullScreen()
197 {
198 // FIXME: Implement full screen for out-of-process iframes.
199 }
200
201 void WebFrameWidgetImpl::didEnterFullScreen()
202 {
203 // FIXME: Implement full screen for out-of-process iframes.
204 }
205
206 void WebFrameWidgetImpl::willExitFullScreen()
207 {
208 // FIXME: Implement full screen for out-of-process iframes.
209 }
210
211 void WebFrameWidgetImpl::didExitFullScreen()
212 {
213 // FIXME: Implement full screen for out-of-process iframes.
214 }
215
216 void WebFrameWidgetImpl::beginFrame(const WebBeginFrameArgs& frameTime)
217 {
218 TRACE_EVENT0("blink", "WebFrameWidgetImpl::beginFrame");
219
220 WebBeginFrameArgs validFrameTime(frameTime);
221 if (!validFrameTime.lastFrameTimeMonotonic)
222 validFrameTime.lastFrameTimeMonotonic = monotonicallyIncreasingTime();
223
224 PageWidgetDelegate::animate(*m_page, validFrameTime.lastFrameTimeMonotonic, *m_localRoot->frame());
225 }
226
227 void WebFrameWidgetImpl::layout()
228 {
229 TRACE_EVENT0("blink", "WebFrameWidgetImpl::layout");
230 if (!m_localRoot)
231 return;
232
233 PageWidgetDelegate::layout(*m_page, *m_localRoot->frame());
234 updateLayerTreeBackgroundColor();
235 }
236
237 void WebFrameWidgetImpl::paint(WebCanvas* canvas, const WebRect& rect)
238 {
239 // Out-of-process iframes require compositing.
240 ASSERT_NOT_REACHED();
241 }
242
243
244 void WebFrameWidgetImpl::updateLayerTreeViewport()
245 {
246 if (!page() || !m_layerTreeView)
247 return;
248
249 // FIXME: We need access to page scale information from the WebView.
250 m_layerTreeView->setPageScaleFactorAndLimits(1, 1, 1);
251 }
252
253 void WebFrameWidgetImpl::updateLayerTreeBackgroundColor()
254 {
255 if (!m_layerTreeView)
256 return;
257
258 m_layerTreeView->setBackgroundColor(alphaChannel(m_webView->backgroundColorO verride()) ? m_webView->backgroundColorOverride() : m_webView->backgroundColor() );
259 }
260
261 void WebFrameWidgetImpl::updateLayerTreeDeviceScaleFactor()
262 {
263 ASSERT(page());
264 ASSERT(m_layerTreeView);
265
266 float deviceScaleFactor = page()->deviceScaleFactor();
267 m_layerTreeView->setDeviceScaleFactor(deviceScaleFactor);
268 }
269
270 bool WebFrameWidgetImpl::isTransparent() const
271 {
272 // FIXME: This might need to proxy to the WebView's isTransparent().
273 return false;
274 }
275
276 void WebFrameWidgetImpl::compositeAndReadbackAsync(WebCompositeAndReadbackAsyncC allback* callback)
277 {
278 m_layerTreeView->compositeAndReadbackAsync(callback);
279 }
280
281 bool WebFrameWidgetImpl::isTrackingRepaints() const
282 {
283 return m_localRoot->frameView()->isTrackingPaintInvalidations();
284 }
285
286 void WebFrameWidgetImpl::themeChanged()
287 {
288 FrameView* view = m_localRoot->frameView();
289
290 WebRect damagedRect(0, 0, m_size.width, m_size.height);
291 view->invalidateRect(damagedRect);
292 }
293
294 const WebInputEvent* WebFrameWidgetImpl::m_currentInputEvent = nullptr;
295
296 // FIXME: autogenerate this kind of code, and use it throughout Blink rather tha n
297 // the one-offs for subsets of these values.
298 static String inputTypeToName(WebInputEvent::Type type)
299 {
300 switch (type) {
301 case WebInputEvent::MouseDown:
302 return EventTypeNames::mousedown;
303 case WebInputEvent::MouseUp:
304 return EventTypeNames::mouseup;
305 case WebInputEvent::MouseMove:
306 return EventTypeNames::mousemove;
307 case WebInputEvent::MouseEnter:
308 return EventTypeNames::mouseenter;
309 case WebInputEvent::MouseLeave:
310 return EventTypeNames::mouseleave;
311 case WebInputEvent::ContextMenu:
312 return EventTypeNames::contextmenu;
313 case WebInputEvent::MouseWheel:
314 return EventTypeNames::mousewheel;
315 case WebInputEvent::KeyDown:
316 return EventTypeNames::keydown;
317 case WebInputEvent::KeyUp:
318 return EventTypeNames::keyup;
319 case WebInputEvent::GestureScrollBegin:
320 return EventTypeNames::gesturescrollstart;
321 case WebInputEvent::GestureScrollEnd:
322 return EventTypeNames::gesturescrollend;
323 case WebInputEvent::GestureScrollUpdate:
324 return EventTypeNames::gesturescrollupdate;
325 case WebInputEvent::GestureTapDown:
326 return EventTypeNames::gesturetapdown;
327 case WebInputEvent::GestureShowPress:
328 return EventTypeNames::gestureshowpress;
329 case WebInputEvent::GestureTap:
330 return EventTypeNames::gesturetap;
331 case WebInputEvent::GestureTapUnconfirmed:
332 return EventTypeNames::gesturetapunconfirmed;
333 case WebInputEvent::TouchStart:
334 return EventTypeNames::touchstart;
335 case WebInputEvent::TouchMove:
336 return EventTypeNames::touchmove;
337 case WebInputEvent::TouchEnd:
338 return EventTypeNames::touchend;
339 case WebInputEvent::TouchCancel:
340 return EventTypeNames::touchcancel;
341 default:
342 return String("unknown");
343 }
344 }
345
346 bool WebFrameWidgetImpl::handleInputEvent(const WebInputEvent& inputEvent)
347 {
348
349 TRACE_EVENT1("input", "WebFrameWidgetImpl::handleInputEvent", "type", inputT ypeToName(inputEvent.type).ascii());
350
351 // Report the event to be NOT processed by WebKit, so that the browser can h andle it appropriately.
352 if (m_ignoreInputEvents)
353 return false;
354
355 TemporaryChange<const WebInputEvent*> currentEventChange(m_currentInputEvent , &inputEvent);
356
357 if (m_mouseCaptureNode && WebInputEvent::isMouseEventType(inputEvent.type)) {
358 TRACE_EVENT1("input", "captured mouse event", "type", inputEvent.type);
359 // Save m_mouseCaptureNode since mouseCaptureLost() will clear it.
360 RefPtrWillBeRawPtr<Node> node = m_mouseCaptureNode;
361
362 // Not all platforms call mouseCaptureLost() directly.
363 if (inputEvent.type == WebInputEvent::MouseUp)
364 mouseCaptureLost();
365
366 OwnPtr<UserGestureIndicator> gestureIndicator;
367
368 AtomicString eventType;
369 switch (inputEvent.type) {
370 case WebInputEvent::MouseMove:
371 eventType = EventTypeNames::mousemove;
372 break;
373 case WebInputEvent::MouseLeave:
374 eventType = EventTypeNames::mouseout;
375 break;
376 case WebInputEvent::MouseDown:
377 eventType = EventTypeNames::mousedown;
378 gestureIndicator = adoptPtr(new UserGestureIndicator(DefinitelyProce ssingNewUserGesture));
379 m_mouseCaptureGestureToken = gestureIndicator->currentToken();
380 break;
381 case WebInputEvent::MouseUp:
382 eventType = EventTypeNames::mouseup;
383 gestureIndicator = adoptPtr(new UserGestureIndicator(m_mouseCaptureG estureToken.release()));
384 break;
385 default:
386 ASSERT_NOT_REACHED();
387 }
388
389 node->dispatchMouseEvent(
390 PlatformMouseEventBuilder(m_localRoot->frameView(), static_cast<cons t WebMouseEvent&>(inputEvent)),
391 eventType, static_cast<const WebMouseEvent&>(inputEvent).clickCount) ;
392 return true;
393 }
394
395 return PageWidgetDelegate::handleInputEvent(*this, inputEvent, m_localRoot-> frame());
396 }
397
398 void WebFrameWidgetImpl::setCursorVisibilityState(bool isVisible)
399 {
400 m_page->setIsCursorVisible(isVisible);
401 }
402
403 bool WebFrameWidgetImpl::hasTouchEventHandlersAt(const WebPoint& point)
404 {
405 // FIXME: Implement this. Note that the point must be divided by pageScaleFa ctor.
406 return true;
407 }
408
409 void WebFrameWidgetImpl::scheduleAnimation()
410 {
411 if (m_layerTreeView) {
412 m_layerTreeView->setNeedsAnimate();
413 return;
414 }
415 if (m_client)
416 m_client->scheduleAnimation();
417 }
418
419 void WebFrameWidgetImpl::applyViewportDeltas(
420 const WebSize& pinchViewportDelta,
421 const WebSize& mainFrameDelta,
422 const WebFloatSize& elasticOverscrollDelta,
423 float pageScaleDelta,
424 float topControlsDelta)
425 {
426 // FIXME: To be implemented.
427 }
428
429 void WebFrameWidgetImpl::applyViewportDeltas(const WebSize& scrollDelta, float p ageScaleDelta, float topControlsDelta)
430 {
431 // FIXME: To be implemented.
432 }
433
434 void WebFrameWidgetImpl::mouseCaptureLost()
435 {
436 TRACE_EVENT_ASYNC_END0("input", "capturing mouse", this);
437 m_mouseCaptureNode = nullptr;
438 }
439
440 void WebFrameWidgetImpl::setFocus(bool enable)
441 {
442 m_page->focusController().setFocused(enable);
443 if (enable) {
444 m_page->focusController().setActive(true);
445 RefPtr<Frame> focusedFrame = m_page->focusController().focusedFrame();
446 if (focusedFrame && focusedFrame->isLocalFrame()) {
447 LocalFrame* localFrame = toLocalFrame(focusedFrame.get());
448 Element* element = localFrame->document()->focusedElement();
449 if (element && localFrame->selection().selection().isNone()) {
450 // If the selection was cleared while the WebView was not
451 // focused, then the focus element shows with a focus ring but
452 // no caret and does respond to keyboard inputs.
453 if (element->isTextFormControl()) {
454 element->updateFocusAppearance(true);
455 } else if (element->isContentEditable()) {
456 // updateFocusAppearance() selects all the text of
457 // contentseditable DIVs. So we set the selection explicitly
458 // instead. Note that this has the side effect of moving the
459 // caret back to the beginning of the text.
460 Position position(element, 0, Position::PositionIsOffsetInAn chor);
461 localFrame->selection().setSelection(VisibleSelection(positi on, SEL_DEFAULT_AFFINITY));
462 }
463 }
464 }
465 }
466 }
467
468 bool WebFrameWidgetImpl::setComposition(
469 const WebString& text,
470 const WebVector<WebCompositionUnderline>& underlines,
471 int selectionStart,
472 int selectionEnd)
473 {
474 // FIXME: To be implemented.
475 return false;
476 }
477
478 bool WebFrameWidgetImpl::confirmComposition()
479 {
480 // FIXME: To be implemented.
481 return false;
482 }
483
484 bool WebFrameWidgetImpl::confirmComposition(ConfirmCompositionBehavior selection Behavior)
485 {
486 // FIXME: To be implemented.
487 return false;
488 }
489
490 bool WebFrameWidgetImpl::confirmComposition(const WebString& text)
491 {
492 // FIXME: To be implemented.
493 return false;
494 }
495
496 bool WebFrameWidgetImpl::compositionRange(size_t* location, size_t* length)
497 {
498 // FIXME: To be implemented.
499 return false;
500 }
501
502 WebTextInputInfo WebFrameWidgetImpl::textInputInfo()
503 {
504 WebTextInputInfo info;
505 // FIXME: To be implemented.
506 return info;
507 }
508
509 WebColor WebFrameWidgetImpl::backgroundColor() const
510 {
511 if (isTransparent())
512 return Color::transparent;
513 if (!m_localRoot->frameView())
514 return m_webView->backgroundColor();
515 FrameView* view = m_localRoot->frameView();
516 return view->documentBackgroundColor().rgb();
517 }
518
519 bool WebFrameWidgetImpl::selectionBounds(WebRect& anchor, WebRect& focus) const
520 {
521 const Frame* frame = focusedCoreFrame();
522 if (!frame || !frame->isLocalFrame())
523 return false;
524
525 const LocalFrame* localFrame = toLocalFrame(frame);
526 if (!localFrame)
527 return false;
528 FrameSelection& selection = localFrame->selection();
529
530 if (selection.isCaret()) {
531 anchor = focus = selection.absoluteCaretBounds();
532 } else {
533 RefPtrWillBeRawPtr<Range> selectedRange = selection.toNormalizedRange();
534 if (!selectedRange)
535 return false;
536
537 RefPtrWillBeRawPtr<Range> range(Range::create(selectedRange->startContai ner()->document(),
538 selectedRange->startContainer(),
539 selectedRange->startOffset(),
540 selectedRange->startContainer(),
541 selectedRange->startOffset()));
542 anchor = localFrame->editor().firstRectForRange(range.get());
543
544 range = Range::create(selectedRange->endContainer()->document(),
545 selectedRange->endContainer(),
546 selectedRange->endOffset(),
547 selectedRange->endContainer(),
548 selectedRange->endOffset());
549 focus = localFrame->editor().firstRectForRange(range.get());
550 }
551
552 IntRect scaledAnchor(localFrame->view()->contentsToWindow(anchor));
553 IntRect scaledFocus(localFrame->view()->contentsToWindow(focus));
554
555 anchor = scaledAnchor;
556 focus = scaledFocus;
557
558 if (!selection.selection().isBaseFirst())
559 std::swap(anchor, focus);
560 return true;
561 }
562
563 bool WebFrameWidgetImpl::selectionTextDirection(WebTextDirection& start, WebText Direction& end) const
564 {
565 if (!focusedCoreFrame()->isLocalFrame())
566 return false;
567 const LocalFrame* frame = toLocalFrame(focusedCoreFrame());
568 if (!frame)
569 return false;
570 FrameSelection& selection = frame->selection();
571 if (!selection.toNormalizedRange())
572 return false;
573 start = toWebTextDirection(selection.start().primaryDirection());
574 end = toWebTextDirection(selection.end().primaryDirection());
575 return true;
576 }
577
578 bool WebFrameWidgetImpl::isSelectionAnchorFirst() const
579 {
580 if (!focusedCoreFrame()->isLocalFrame())
581 return false;
582 if (const LocalFrame* frame = toLocalFrame(focusedCoreFrame()))
583 return frame->selection().selection().isBaseFirst();
584 return false;
585 }
586
587 bool WebFrameWidgetImpl::caretOrSelectionRange(size_t* location, size_t* length)
588 {
589 if (!focusedCoreFrame()->isLocalFrame())
590 return false;
591 const LocalFrame* focused = toLocalFrame(focusedCoreFrame());
592 if (!focused)
593 return false;
594
595 PlainTextRange selectionOffsets = focused->inputMethodController().getSelect ionOffsets();
596 if (selectionOffsets.isNull())
597 return false;
598
599 *location = selectionOffsets.start();
600 *length = selectionOffsets.length();
601 return true;
602 }
603
604 void WebFrameWidgetImpl::setTextDirection(WebTextDirection direction)
605 {
606 // The Editor::setBaseWritingDirection() function checks if we can change
607 // the text direction of the selected node and updates its DOM "dir"
608 // attribute and its CSS "direction" property.
609 // So, we just call the function as Safari does.
610 if (!focusedCoreFrame()->isLocalFrame())
611 return;
612 const LocalFrame* focused = toLocalFrame(focusedCoreFrame());
613 if (!focused)
614 return;
615
616 Editor& editor = focused->editor();
617 if (!editor.canEdit())
618 return;
619
620 switch (direction) {
621 case WebTextDirectionDefault:
622 editor.setBaseWritingDirection(NaturalWritingDirection);
623 break;
624
625 case WebTextDirectionLeftToRight:
626 editor.setBaseWritingDirection(LeftToRightWritingDirection);
627 break;
628
629 case WebTextDirectionRightToLeft:
630 editor.setBaseWritingDirection(RightToLeftWritingDirection);
631 break;
632
633 default:
634 notImplemented();
635 break;
636 }
637 }
638
639 bool WebFrameWidgetImpl::isAcceleratedCompositingActive() const
640 {
641 return m_isAcceleratedCompositingActive;
642 }
643
644 void WebFrameWidgetImpl::willCloseLayerTreeView()
645 {
646 setIsAcceleratedCompositingActive(false);
647 m_layerTreeView = nullptr;
648 m_layerTreeViewClosed = true;
649 }
650
651 void WebFrameWidgetImpl::didChangeWindowResizerRect()
652 {
653 if (m_localRoot->frameView())
654 m_localRoot->frameView()->windowResizerRectChanged();
655 }
656
657 void WebFrameWidgetImpl::handleMouseLeave(LocalFrame& mainFrame, const WebMouseE vent& event)
658 {
659 // FIXME: WebWidget doesn't have the method below.
660 // m_client->setMouseOverURL(WebURL());
661 PageWidgetEventHandler::handleMouseLeave(mainFrame, event);
662 }
663
664 void WebFrameWidgetImpl::handleMouseDown(LocalFrame& mainFrame, const WebMouseEv ent& event)
665 {
666 // Take capture on a mouse down on a plugin so we can send it mouse events.
667 // If the hit node is a plugin but a scrollbar is over it don't start mouse
668 // capture because it will interfere with the scrollbar receiving events.
669 IntPoint point(event.x, event.y);
670 if (event.button == WebMouseEvent::ButtonLeft) {
671 point = m_localRoot->frameView()->windowToContents(point);
672 HitTestResult result(m_localRoot->frame()->eventHandler().hitTestResultA tPoint(point));
673 result.setToShadowHostIfInUserAgentShadowRoot();
674 Node* hitNode = result.innerNonSharedNode();
675
676 if (!result.scrollbar() && hitNode && hitNode->renderer() && hitNode->re nderer()->isEmbeddedObject()) {
677 m_mouseCaptureNode = hitNode;
678 TRACE_EVENT_ASYNC_BEGIN0("input", "capturing mouse", this);
679 }
680 }
681
682 PageWidgetEventHandler::handleMouseDown(mainFrame, event);
683
684 if (event.button == WebMouseEvent::ButtonLeft && m_mouseCaptureNode)
685 m_mouseCaptureGestureToken = mainFrame.eventHandler().takeLastMouseDownG estureToken();
686
687 // FIXME: Add context menu support.
688 }
689
690 void WebFrameWidgetImpl::handleMouseUp(LocalFrame& mainFrame, const WebMouseEven t& event)
691 {
692 PageWidgetEventHandler::handleMouseUp(mainFrame, event);
693
694 // FIXME: Add context menu support (Windows).
695 }
696
697 bool WebFrameWidgetImpl::handleMouseWheel(LocalFrame& mainFrame, const WebMouseW heelEvent& event)
698 {
699 return PageWidgetEventHandler::handleMouseWheel(mainFrame, event);
700 }
701
702 bool WebFrameWidgetImpl::handleGestureEvent(const WebGestureEvent& event)
703 {
704 // FIXME: Add gesture support.
705 return false;
706 }
707
708 bool WebFrameWidgetImpl::handleKeyEvent(const WebKeyboardEvent& event)
709 {
710 ASSERT((event.type == WebInputEvent::RawKeyDown)
711 || (event.type == WebInputEvent::KeyDown)
712 || (event.type == WebInputEvent::KeyUp));
713
714 // Please refer to the comments explaining the m_suppressNextKeypressEvent
715 // member.
716 // The m_suppressNextKeypressEvent is set if the KeyDown is handled by
717 // Webkit. A keyDown event is typically associated with a keyPress(char)
718 // event and a keyUp event. We reset this flag here as this is a new keyDown
719 // event.
720 m_suppressNextKeypressEvent = false;
721
722 RefPtr<Frame> focusedFrame = focusedCoreFrame();
723 if (focusedFrame && focusedFrame->isRemoteFrame()) {
724 WebRemoteFrameImpl* webFrame = WebRemoteFrameImpl::fromFrame(*toRemoteFr ame(focusedFrame.get()));
725 webFrame->client()->forwardInputEvent(&event);
726 return true;
727 }
728
729 if (!focusedFrame || !focusedFrame->isLocalFrame())
730 return false;
731
732 RefPtr<LocalFrame> frame = toLocalFrame(focusedFrame.get());
733
734 PlatformKeyboardEventBuilder evt(event);
735
736 if (frame->eventHandler().keyEvent(evt)) {
737 if (WebInputEvent::RawKeyDown == event.type) {
738 // Suppress the next keypress event unless the focused node is a plu g-in node.
739 // (Flash needs these keypress events to handle non-US keyboards.)
740 Element* element = focusedElement();
741 if (!element || !element->renderer() || !element->renderer()->isEmbe ddedObject())
742 m_suppressNextKeypressEvent = true;
743 }
744 return true;
745 }
746
747 return keyEventDefault(event);
748 }
749
750 bool WebFrameWidgetImpl::handleCharEvent(const WebKeyboardEvent& event)
751 {
752 ASSERT(event.type == WebInputEvent::Char);
753
754 // Please refer to the comments explaining the m_suppressNextKeypressEvent
755 // member. The m_suppressNextKeypressEvent is set if the KeyDown is
756 // handled by Webkit. A keyDown event is typically associated with a
757 // keyPress(char) event and a keyUp event. We reset this flag here as it
758 // only applies to the current keyPress event.
759 bool suppress = m_suppressNextKeypressEvent;
760 m_suppressNextKeypressEvent = false;
761
762 LocalFrame* frame = toLocalFrame(focusedCoreFrame());
763 if (!frame)
764 return suppress;
765
766 EventHandler& handler = frame->eventHandler();
767
768 PlatformKeyboardEventBuilder evt(event);
769 if (!evt.isCharacterKey())
770 return true;
771
772 // Accesskeys are triggered by char events and can't be suppressed.
773 if (handler.handleAccessKey(evt))
774 return true;
775
776 // Safari 3.1 does not pass off windows system key messages (WM_SYSCHAR) to
777 // the eventHandler::keyEvent. We mimic this behavior on all platforms since
778 // for now we are converting other platform's key events to windows key
779 // events.
780 if (evt.isSystemKey())
781 return false;
782
783 if (!suppress && !handler.keyEvent(evt))
784 return keyEventDefault(event);
785
786 return true;
787 }
788
789
790 bool WebFrameWidgetImpl::keyEventDefault(const WebKeyboardEvent& event)
791 {
792 LocalFrame* frame = toLocalFrame(focusedCoreFrame());
793 if (!frame)
794 return false;
795
796 switch (event.type) {
797 case WebInputEvent::Char:
798 if (event.windowsKeyCode == VKEY_SPACE) {
799 int keyCode = ((event.modifiers & WebInputEvent::ShiftKey) ? VKEY_PR IOR : VKEY_NEXT);
800 return scrollViewWithKeyboard(keyCode, event.modifiers);
801 }
802 break;
803 case WebInputEvent::RawKeyDown:
804 if (event.modifiers == WebInputEvent::ControlKey) {
805 switch (event.windowsKeyCode) {
806 #if !OS(MACOSX)
807 case 'A':
808 WebFrame::fromFrame(focusedCoreFrame())->executeCommand(WebStrin g::fromUTF8("SelectAll"));
809 return true;
810 case VKEY_INSERT:
811 case 'C':
812 WebFrame::fromFrame(focusedCoreFrame())->executeCommand(WebStrin g::fromUTF8("Copy"));
813 return true;
814 #endif
815 // Match FF behavior in the sense that Ctrl+home/end are the only Ct rl
816 // key combinations which affect scrolling. Safari is buggy in the
817 // sense that it scrolls the page for all Ctrl+scrolling key
818 // combinations. For e.g. Ctrl+pgup/pgdn/up/down, etc.
819 case VKEY_HOME:
820 case VKEY_END:
821 break;
822 default:
823 return false;
824 }
825 }
826 if (!event.isSystemKey && !(event.modifiers & WebInputEvent::ShiftKey))
827 return scrollViewWithKeyboard(event.windowsKeyCode, event.modifiers) ;
828 break;
829 default:
830 break;
831 }
832 return false;
833 }
834
835 bool WebFrameWidgetImpl::scrollViewWithKeyboard(int keyCode, int modifiers)
836 {
837 ScrollDirection scrollDirection;
838 ScrollGranularity scrollGranularity;
839 #if OS(MACOSX)
840 // Control-Up/Down should be PageUp/Down on Mac.
841 if (modifiers & WebMouseEvent::ControlKey) {
842 if (keyCode == VKEY_UP)
843 keyCode = VKEY_PRIOR;
844 else if (keyCode == VKEY_DOWN)
845 keyCode = VKEY_NEXT;
846 }
847 #endif
848 if (!mapKeyCodeForScroll(keyCode, &scrollDirection, &scrollGranularity))
849 return false;
850
851 if (LocalFrame* frame = toLocalFrame(focusedCoreFrame()))
852 return frame->eventHandler().bubblingScroll(scrollDirection, scrollGranu larity);
853 return false;
854 }
855
856 bool WebFrameWidgetImpl::mapKeyCodeForScroll(
857 int keyCode,
858 ScrollDirection* scrollDirection,
859 ScrollGranularity* scrollGranularity)
860 {
861 switch (keyCode) {
862 case VKEY_LEFT:
863 *scrollDirection = ScrollLeft;
864 *scrollGranularity = ScrollByLine;
865 break;
866 case VKEY_RIGHT:
867 *scrollDirection = ScrollRight;
868 *scrollGranularity = ScrollByLine;
869 break;
870 case VKEY_UP:
871 *scrollDirection = ScrollUp;
872 *scrollGranularity = ScrollByLine;
873 break;
874 case VKEY_DOWN:
875 *scrollDirection = ScrollDown;
876 *scrollGranularity = ScrollByLine;
877 break;
878 case VKEY_HOME:
879 *scrollDirection = ScrollUp;
880 *scrollGranularity = ScrollByDocument;
881 break;
882 case VKEY_END:
883 *scrollDirection = ScrollDown;
884 *scrollGranularity = ScrollByDocument;
885 break;
886 case VKEY_PRIOR: // page up
887 *scrollDirection = ScrollUp;
888 *scrollGranularity = ScrollByPage;
889 break;
890 case VKEY_NEXT: // page down
891 *scrollDirection = ScrollDown;
892 *scrollGranularity = ScrollByPage;
893 break;
894 default:
895 return false;
896 }
897
898 return true;
899 }
900
901 Frame* WebFrameWidgetImpl::focusedCoreFrame() const
902 {
903 return m_page ? m_page->focusController().focusedOrMainFrame() : nullptr;
904 }
905
906 Element* WebFrameWidgetImpl::focusedElement() const
907 {
908 Frame* frame = m_page->focusController().focusedFrame();
909 if (!frame || !frame->isLocalFrame())
910 return nullptr;
911
912 Document* document = toLocalFrame(frame)->document();
913 if (!document)
914 return nullptr;
915
916 return document->focusedElement();
917 }
918
919 void WebFrameWidgetImpl::initializeLayerTreeView()
920 {
921 if (m_client) {
922 m_client->initializeLayerTreeView();
923 m_layerTreeView = m_client->layerTreeView();
924 }
925
926 m_page->settings().setAcceleratedCompositingEnabled(m_layerTreeView);
927
928 // FIXME: only unittests, click to play, Android priting, and printing (for headers and footers)
929 // make this assert necessary. We should make them not hit this code and the n delete allowsBrokenNullLayerTreeView.
930 ASSERT(m_layerTreeView || !m_client || m_client->allowsBrokenNullLayerTreeVi ew());
931 }
932
933 void WebFrameWidgetImpl::setIsAcceleratedCompositingActive(bool active)
934 {
935 // In the middle of shutting down; don't try to spin back up a compositor.
936 // FIXME: compositing startup/shutdown should be refactored so that it
937 // turns on explicitly rather than lazily, which causes this awkwardness.
938 if (m_layerTreeViewClosed)
939 return;
940
941 ASSERT(!active || m_layerTreeView);
942
943 if (m_isAcceleratedCompositingActive == active)
944 return;
945
946 if (!m_client)
947 return;
948
949 if (active) {
950 TRACE_EVENT0("blink", "WebViewImpl::setIsAcceleratedCompositingActive(tr ue)");
951 m_layerTreeView->setRootLayer(*m_rootLayer);
952
953 bool visible = page()->visibilityState() == PageVisibilityStateVisible;
954 m_layerTreeView->setVisible(visible);
955 updateLayerTreeDeviceScaleFactor();
956 updateLayerTreeBackgroundColor();
957 m_layerTreeView->setHasTransparentBackground(isTransparent());
958 updateLayerTreeViewport();
959 m_isAcceleratedCompositingActive = true;
960 }
961 if (m_localRoot->frameView())
962 m_localRoot->frameView()->setClipsRepaints(!m_isAcceleratedCompositingAc tive);
963 }
964
965 RenderLayerCompositor* WebFrameWidgetImpl::compositor() const
966 {
967 LocalFrame* frame = toLocalFrame(toCoreFrame(m_localRoot));
968 if (!frame || !frame->document() || !frame->document()->renderView())
969 return nullptr;
970
971 return frame->document()->renderView()->compositor();
972 }
973
974 void WebFrameWidgetImpl::suppressInvalidations(bool enable)
975 {
976 if (m_client)
977 m_client->suppressCompositorScheduling(enable);
978 }
979
980 void WebFrameWidgetImpl::setRootGraphicsLayer(GraphicsLayer* layer)
981 {
982 suppressInvalidations(true);
983
984 m_rootGraphicsLayer = layer;
985 m_rootLayer = layer ? layer->platformLayer() : nullptr;
986
987 setIsAcceleratedCompositingActive(layer);
988
989 if (m_layerTreeView) {
990 if (m_rootLayer) {
991 m_layerTreeView->setRootLayer(*m_rootLayer);
992 // We register viewport layers here since there may not be a layer
993 // tree view prior to this point.
994 GraphicsLayer* rootScrollLayer = compositor()->scrollLayer();
995 ASSERT(rootScrollLayer);
996 WebLayer* pageScaleLayer = rootScrollLayer->parent() ? rootScrollLay er->parent()->platformLayer() : nullptr;
997 m_layerTreeView->registerViewportLayers(nullptr, pageScaleLayer, roo tScrollLayer->platformLayer(), nullptr);
998 } else {
999 m_layerTreeView->clearRootLayer();
1000 m_layerTreeView->clearViewportLayers();
1001 }
1002 }
1003
1004 suppressInvalidations(false);
1005 }
1006
1007 } // namespace blink
OLDNEW
« no previous file with comments | « Source/web/WebFrameWidgetImpl.h ('k') | Source/web/WebLocalFrameImpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698