[Qt] Separate QWidget dependant code into separate WebKitWidgets static library
[WebKit-https.git] / Source / WebKit / qt / WebCoreSupport / ChromeClientQt.cpp
1 /*
2  * Copyright (C) 2006 Zack Rusin <zack@kde.org>
3  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
4  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "ChromeClientQt.h"
32
33 #include "ApplicationCacheStorage.h"
34 #include "ColorChooser.h"
35 #include "ColorChooserClient.h"
36 #include "DatabaseTracker.h"
37 #include "Document.h"
38 #include "FileChooser.h"
39 #include "FileIconLoader.h"
40 #include "Frame.h"
41 #include "FrameLoadRequest.h"
42 #include "FrameLoader.h"
43 #include "FrameLoaderClientQt.h"
44 #include "FrameView.h"
45 #include "Geolocation.h"
46 #if USE(ACCELERATED_COMPOSITING)
47 #include "GraphicsLayer.h"
48 #endif
49 #include "HTMLFormElement.h"
50 #include "HitTestResult.h"
51 #include "Icon.h"
52 #include "NavigationAction.h"
53 #include "NetworkingContext.h"
54 #include "NotImplemented.h"
55 #include "Page.h"
56 #include "PopupMenuQt.h"
57 #include "QWebFrameAdapter.h"
58 #include "QWebPageAdapter.h"
59 #include "QWebPageClient.h"
60 #include "ScrollbarTheme.h"
61 #include "SearchPopupMenuQt.h"
62 #include "SecurityOrigin.h"
63 #include "TiledBackingStore.h"
64 #include "ViewportArguments.h"
65 #include "WindowFeatures.h"
66 #include "qwebkitplatformplugin.h"
67 #include "qwebsecurityorigin.h"
68 #include "qwebsecurityorigin_p.h"
69 #include "qwebsettings.h"
70
71 #include <qabstractanimation.h>
72 #include <qdebug.h>
73 #include <qeventloop.h>
74 #include <qwindow.h>
75 #include <wtf/OwnPtr.h>
76
77 #if ENABLE(VIDEO) && ((USE(GSTREAMER) && !defined(GST_API_VERSION_1)) || USE(QT_MULTIMEDIA) || USE(QTKIT))
78 #include "FullScreenVideoQt.h"
79 #include "HTMLMediaElement.h"
80 #include "HTMLNames.h"
81 #include "HTMLVideoElement.h"
82 #if USE(QT_MULTIMEDIA)
83 #include "MediaPlayerPrivateQt.h"
84 #endif
85 #endif
86
87 namespace WebCore {
88
89 #if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER)
90 class RefreshAnimation : public QAbstractAnimation {
91 public:
92     RefreshAnimation(ChromeClientQt* chromeClient)
93         : QAbstractAnimation()
94         , m_chromeClient(chromeClient)
95         , m_animationScheduled(false)
96     { }
97
98     virtual int duration() const { return -1; }
99
100     void scheduleAnimation()
101     {
102         m_animationScheduled = true;
103         if (state() != QAbstractAnimation::Running)
104             QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
105     }
106
107 protected:
108     virtual void updateCurrentTime(int currentTime)
109     {
110         UNUSED_PARAM(currentTime);
111         if (m_animationScheduled) {
112             m_animationScheduled = false;
113             m_chromeClient->serviceScriptedAnimations();
114         } else
115             stop();
116     }
117 private:
118     ChromeClientQt* m_chromeClient;
119     bool m_animationScheduled;
120 };
121 #endif
122
123 bool ChromeClientQt::dumpVisitedLinksCallbacks = false;
124
125 ChromeClientQt::ChromeClientQt(QWebPageAdapter* webPageAdapter)
126     : m_webPage(webPageAdapter)
127     , m_eventLoop(0)
128 #if ENABLE(VIDEO) && ((USE(GSTREAMER) && !defined(GST_API_VERSION_1)) || USE(QT_MULTIMEDIA) || USE(QTKIT))
129     , m_fullScreenVideo(0)
130 #endif
131 {
132     toolBarsVisible = statusBarVisible = menuBarVisible = true;
133 }
134
135 ChromeClientQt::~ChromeClientQt()
136 {
137     if (m_eventLoop)
138         m_eventLoop->exit();
139
140 #if ENABLE(VIDEO) && ((USE(GSTREAMER) && !defined(GST_API_VERSION_1)) || USE(QT_MULTIMEDIA) || USE(QTKIT))
141     delete m_fullScreenVideo;
142 #endif
143 }
144
145 void ChromeClientQt::setWindowRect(const FloatRect& rect)
146 {
147     if (!m_webPage)
148         return;
149     m_webPage->setWindowRect(QRect(qRound(rect.x()), qRound(rect.y()), qRound(rect.width()), qRound(rect.height())));
150 }
151
152 /*!
153     windowRect represents the rect of the Window, including all interface elements
154     like toolbars/scrollbars etc. It is used by the viewport meta tag as well as
155     by the DOM Window object: outerHeight(), outerWidth(), screenX(), screenY().
156 */
157 FloatRect ChromeClientQt::windowRect()
158 {
159     if (!platformPageClient())
160         return FloatRect();
161     return platformPageClient()->windowRect();
162 }
163
164 bool ChromeClientQt::allowsAcceleratedCompositing() const
165 {
166     if (!platformPageClient())
167         return false;
168     return platformPageClient()->allowsAcceleratedCompositing();
169 }
170
171 FloatRect ChromeClientQt::pageRect()
172 {
173     if (!m_webPage)
174         return FloatRect();
175     return FloatRect(QRectF(QPointF(0, 0), m_webPage->viewportSize()));
176 }
177
178 void ChromeClientQt::focus()
179 {
180     if (!m_webPage)
181         return;
182     m_webPage->setFocus();
183 }
184
185
186 void ChromeClientQt::unfocus()
187 {
188     if (!m_webPage)
189         return;
190     m_webPage->unfocus();
191 }
192
193 bool ChromeClientQt::canTakeFocus(FocusDirection)
194 {
195     // This is called when cycling through links/focusable objects and we
196     // reach the last focusable object. Then we want to claim that we can
197     // take the focus to avoid wrapping.
198     return true;
199 }
200
201 void ChromeClientQt::takeFocus(FocusDirection)
202 {
203     // don't do anything. This is only called when cycling to links/focusable objects,
204     // which in turn is called from focusNextPrevChild. We let focusNextPrevChild
205     // call QWidget::focusNextPrevChild accordingly, so there is no need to do anything
206     // here.
207 }
208
209
210 void ChromeClientQt::focusedNodeChanged(Node*)
211 {
212 }
213
214 void ChromeClientQt::focusedFrameChanged(Frame*)
215 {
216 }
217
218 Page* ChromeClientQt::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction&)
219 {
220     QWebPageAdapter* newPage = m_webPage->createWindow(features.dialog);
221     if (!newPage)
222         return 0;
223
224     return newPage->page;
225 }
226
227 void ChromeClientQt::show()
228 {
229     if (!m_webPage)
230         return;
231     m_webPage->show();
232 }
233
234
235 bool ChromeClientQt::canRunModal()
236 {
237     return true;
238 }
239
240
241 void ChromeClientQt::runModal()
242 {
243     m_eventLoop = new QEventLoop();
244     QEventLoop* eventLoop = m_eventLoop;
245     m_eventLoop->exec();
246     delete eventLoop;
247 }
248
249
250 void ChromeClientQt::setToolbarsVisible(bool visible)
251 {
252     toolBarsVisible = visible;
253     QMetaObject::invokeMethod(m_webPage->handle(), "toolBarVisibilityChangeRequested", Q_ARG(bool, visible));
254 }
255
256
257 bool ChromeClientQt::toolbarsVisible()
258 {
259     return toolBarsVisible;
260 }
261
262
263 void ChromeClientQt::setStatusbarVisible(bool visible)
264 {
265     QMetaObject::invokeMethod(m_webPage->handle(), "statusBarVisibilityChangeRequested", Q_ARG(bool, visible));
266     statusBarVisible = visible;
267 }
268
269
270 bool ChromeClientQt::statusbarVisible()
271 {
272     return statusBarVisible;
273 }
274
275
276 void ChromeClientQt::setScrollbarsVisible(bool)
277 {
278     notImplemented();
279 }
280
281
282 bool ChromeClientQt::scrollbarsVisible()
283 {
284     notImplemented();
285     return true;
286 }
287
288
289 void ChromeClientQt::setMenubarVisible(bool visible)
290 {
291     menuBarVisible = visible;
292     QMetaObject::invokeMethod(m_webPage->handle(), "menuBarVisibilityChangeRequested", Q_ARG(bool, visible));
293 }
294
295 bool ChromeClientQt::menubarVisible()
296 {
297     return menuBarVisible;
298 }
299
300 void ChromeClientQt::setResizable(bool)
301 {
302     notImplemented();
303 }
304
305 void ChromeClientQt::addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID)
306 {
307     QString x = message;
308     QString y = sourceID;
309     m_webPage->javaScriptConsoleMessage(x, lineNumber, y);
310 }
311
312 void ChromeClientQt::chromeDestroyed()
313 {
314     delete this;
315 }
316
317 bool ChromeClientQt::canRunBeforeUnloadConfirmPanel()
318 {
319     return true;
320 }
321
322 bool ChromeClientQt::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
323 {
324     return runJavaScriptConfirm(frame, message);
325 }
326
327 void ChromeClientQt::closeWindowSoon()
328 {
329     m_webPage->page->setGroupName(String());
330     m_webPage->page->mainFrame()->loader()->stopAllLoaders();
331     QMetaObject::invokeMethod(m_webPage->handle(), "windowCloseRequested");
332 }
333
334 void ChromeClientQt::runJavaScriptAlert(Frame* f, const String& msg)
335 {
336     m_webPage->javaScriptAlert(QWebFrameAdapter::kit(f), msg);
337 }
338
339 bool ChromeClientQt::runJavaScriptConfirm(Frame* f, const String& msg)
340 {
341     return m_webPage->javaScriptConfirm(QWebFrameAdapter::kit(f), msg);
342 }
343
344 bool ChromeClientQt::runJavaScriptPrompt(Frame* f, const String& message, const String& defaultValue, String& result)
345 {
346     QString x = result;
347     QWebFrameAdapter* webFrame = QWebFrameAdapter::kit(f);
348     bool rc = m_webPage->javaScriptPrompt(webFrame, message, defaultValue, &x);
349
350     // Fix up a quirk in the QInputDialog class. If no input happened the string should be empty
351     // but it is null. See https://bugs.webkit.org/show_bug.cgi?id=30914.
352     if (rc && x.isNull())
353         result = String("");
354     else
355         result = x;
356
357     return rc;
358 }
359
360 void ChromeClientQt::setStatusbarText(const String& msg)
361 {
362     QString x = msg;
363     QMetaObject::invokeMethod(m_webPage->handle(), "statusBarMessage", Q_ARG(QString, x));
364 }
365
366 bool ChromeClientQt::shouldInterruptJavaScript()
367 {
368     bool shouldInterrupt = false;
369     QMetaObject::invokeMethod(m_webPage->handle(), "shouldInterruptJavaScript", Qt::DirectConnection, Q_RETURN_ARG(bool, shouldInterrupt));
370     return shouldInterrupt;
371 }
372
373 KeyboardUIMode ChromeClientQt::keyboardUIMode()
374 {
375     return m_webPage->settings->testAttribute(QWebSettings::LinksIncludedInFocusChain)
376         ? KeyboardAccessTabsToLinks : KeyboardAccessDefault;
377 }
378
379 IntRect ChromeClientQt::windowResizerRect() const
380 {
381 #if defined(Q_WS_MAC)
382     if (!m_webPage)
383         return IntRect();
384
385     QWebPageClient* pageClient = platformPageClient();
386     if (!pageClient)
387         return IntRect();
388
389     QWindow* topLevelWidget = pageClient->ownerWindow();
390     if (!topLevelWidget)
391         return IntRect();
392
393     QRect topLevelGeometry(topLevelWidget->geometry());
394
395     // There's no API in Qt to query for the size of the resizer, so we assume
396     // it has the same width and height as the scrollbar thickness.
397     int scollbarThickness = ScrollbarTheme::theme()->scrollbarThickness();
398
399     // There's no API in Qt to query for the position of the resizer. Sometimes
400     // it's drawn by the system, and sometimes it's a QSizeGrip. For RTL locales
401     // it might even be on the lower left side of the window, but in WebKit we
402     // always draw scrollbars on the right hand side, so we assume this to be the
403     // location when computing the resize rect to reserve for WebKit.
404     QPoint resizeCornerTopLeft = QPoint(topLevelGeometry.width(), topLevelGeometry.height())
405         - QPoint(scollbarThickness, scollbarThickness))
406         - m_webPage->viewRectRelativeToWindow().topLeft();
407
408     QRect resizeCornerRect = QRect(resizeCornerTopLeft, QSize(scollbarThickness, scollbarThickness));
409     return resizeCornerRect.intersected(pageClient->geometryRelativeToOwnerWidget());
410
411 #else
412     return IntRect();
413 #endif
414 }
415
416 void ChromeClientQt::invalidateRootView(const IntRect& windowRect, bool)
417 {
418 #if USE(TILED_BACKING_STORE)
419     if (platformPageClient()) {
420         WebCore::TiledBackingStore* backingStore = m_webPage->mainFrameAdapter()->frame->tiledBackingStore();
421         if (!backingStore)
422             return;
423         backingStore->invalidate(windowRect);
424     }
425 #else
426     Q_UNUSED(windowRect);
427 #endif
428 }
429
430 void ChromeClientQt::invalidateContentsAndRootView(const IntRect& windowRect, bool)
431 {
432     // No double buffer, so only update the QWidget if content changed.
433     if (platformPageClient()) {
434         QRect rect(windowRect);
435         rect = rect.intersected(QRect(QPoint(0, 0), m_webPage->viewportSize()));
436         if (!rect.isEmpty())
437             platformPageClient()->update(rect);
438     }
439     QMetaObject::invokeMethod(m_webPage->handle(), "repaintRequested", Qt::QueuedConnection, Q_ARG(QRect, windowRect));
440
441     // FIXME: There is no "immediate" support for window painting. This should be done always whenever the flag
442     // is set.
443 }
444
445 void ChromeClientQt::invalidateContentsForSlowScroll(const IntRect& windowRect, bool immediate)
446 {
447     invalidateContentsAndRootView(windowRect, immediate);
448 }
449
450 void ChromeClientQt::scroll(const IntSize& delta, const IntRect& scrollViewRect, const IntRect&)
451 {
452     if (platformPageClient())
453         platformPageClient()->scroll(delta.width(), delta.height(), scrollViewRect);
454     QMetaObject::invokeMethod(m_webPage->handle(), "scrollRequested", Q_ARG(int, delta.width()), Q_ARG(int, delta.height()), Q_ARG(QRect, scrollViewRect));
455 }
456
457 #if USE(TILED_BACKING_STORE)
458 void ChromeClientQt::delegatedScrollRequested(const IntPoint& point)
459 {
460
461     IntSize currentPosition = m_webPage->mainFrameAdapter()->scrollPosition();
462     int x = point.x() - currentPosition.width();
463     int y = point.y() - currentPosition.height();
464     const QRect rect(QPoint(0, 0), m_webPage->viewportSize());
465     QMetaObject::invokeMethod(m_webPage->handle(), "scrollRequested", Q_ARG(int, x), Q_ARG(int, y), Q_ARG(QRect, rect));
466 }
467 #endif
468
469 IntRect ChromeClientQt::rootViewToScreen(const IntRect& rect) const
470 {
471     QWebPageClient* pageClient = platformPageClient();
472     if (!pageClient)
473         return rect;
474
475     QWindow* ownerWindow = pageClient->ownerWindow();
476     if (!ownerWindow)
477         return rect;
478
479     QRect screenRect(rect);
480     screenRect.translate(ownerWindow->mapToGlobal(m_webPage->viewRectRelativeToWindow().topLeft()));
481
482     return screenRect;
483 }
484
485 IntPoint ChromeClientQt::screenToRootView(const IntPoint& point) const
486 {
487     QWebPageClient* pageClient = platformPageClient();
488     if (!pageClient)
489         return point;
490
491     QWindow* ownerWindow = pageClient->ownerWindow();
492     if (!ownerWindow)
493         return point;
494
495     return ownerWindow->mapFromGlobal(point) - m_webPage->viewRectRelativeToWindow().topLeft();
496 }
497
498 PlatformPageClient ChromeClientQt::platformPageClient() const
499 {
500     return m_webPage->client.data();
501 }
502
503 void ChromeClientQt::contentsSizeChanged(Frame* frame, const IntSize& size) const
504 {
505     if (frame->loader()->networkingContext())
506         QWebFrameAdapter::kit(frame)->contentsSizeDidChange(size);
507 }
508
509 void ChromeClientQt::mouseDidMoveOverElement(const HitTestResult& result, unsigned)
510 {
511     TextDirection dir;
512     if (result.absoluteLinkURL() != lastHoverURL
513         || result.title(dir) != lastHoverTitle
514         || result.textContent() != lastHoverContent) {
515         lastHoverURL = result.absoluteLinkURL();
516         lastHoverTitle = result.title(dir);
517         lastHoverContent = result.textContent();
518         QMetaObject::invokeMethod(m_webPage->handle(), "linkHovered", Q_ARG(QString, lastHoverURL.string()),
519             Q_ARG(QString, lastHoverTitle), Q_ARG(QString, lastHoverContent));
520     }
521 }
522
523 void ChromeClientQt::setToolTip(const String &tip, TextDirection)
524 {
525     m_webPage->setToolTip(tip);
526 }
527
528 void ChromeClientQt::print(Frame* frame)
529 {
530     emit m_webPage->printRequested(QWebFrameAdapter::kit(frame));
531 }
532
533 #if ENABLE(SQL_DATABASE)
534 void ChromeClientQt::exceededDatabaseQuota(Frame* frame, const String& databaseName)
535 {
536     quint64 quota = QWebSettings::offlineStorageDefaultQuota();
537
538     if (!DatabaseTracker::tracker().hasEntryForOrigin(frame->document()->securityOrigin()))
539         DatabaseTracker::tracker().setQuota(frame->document()->securityOrigin(), quota);
540
541     m_webPage->databaseQuotaExceeded(QWebFrameAdapter::kit(frame), databaseName);
542 }
543 #endif
544
545 void ChromeClientQt::reachedMaxAppCacheSize(int64_t)
546 {
547     // FIXME: Free some space.
548     notImplemented();
549 }
550
551 void ChromeClientQt::reachedApplicationCacheOriginQuota(SecurityOrigin* origin, int64_t totalSpaceNeeded)
552 {
553     int64_t quota;
554     quint64 defaultOriginQuota = WebCore::cacheStorage().defaultOriginQuota();
555
556     QWebSecurityOriginPrivate* priv = new QWebSecurityOriginPrivate(origin);
557     QWebSecurityOrigin* securityOrigin = new QWebSecurityOrigin(priv);
558
559     if (!WebCore::cacheStorage().calculateQuotaForOrigin(origin, quota))
560         WebCore::cacheStorage().storeUpdatedQuotaForOrigin(origin, defaultOriginQuota);
561
562     emit m_webPage->applicationCacheQuotaExceeded(securityOrigin, defaultOriginQuota, static_cast<quint64>(totalSpaceNeeded));
563 }
564
565 #if ENABLE(INPUT_TYPE_COLOR)
566 PassOwnPtr<ColorChooser> ChromeClientQt::createColorChooser(ColorChooserClient* client, const Color& color)
567 {
568     const QColor selectedColor = m_webPage->colorSelectionRequested(QColor(color));
569     client->didChooseColor(selectedColor);
570     client->didEndChooser();
571     return nullptr;
572 }
573 #endif
574
575 void ChromeClientQt::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser)
576 {
577     RefPtr<FileChooser> fileChooser = prpFileChooser;
578
579     QStringList suggestedFileNames;
580     for (unsigned i = 0; i < fileChooser->settings().selectedFiles.size(); ++i)
581         suggestedFileNames += fileChooser->settings().selectedFiles[i];
582
583     const bool allowMultiple = fileChooser->settings().allowsMultipleFiles;
584
585     QStringList result = m_webPage->chooseFiles(QWebFrameAdapter::kit(frame), allowMultiple, suggestedFileNames);
586     if (!result.isEmpty()) {
587         if (allowMultiple) {
588             Vector<String> names;
589             for (int i = 0; i < result.count(); ++i)
590                 names.append(result.at(i));
591             fileChooser->chooseFiles(names);
592         } else
593             fileChooser->chooseFile(result.first());
594     }
595 }
596
597 void ChromeClientQt::loadIconForFiles(const Vector<String>& filenames, FileIconLoader* loader)
598 {
599     loader->notifyFinished(Icon::createIconForFiles(filenames));
600 }
601
602 void ChromeClientQt::setCursor(const Cursor& cursor)
603 {
604 #ifndef QT_NO_CURSOR
605     QWebPageClient* pageClient = platformPageClient();
606     if (!pageClient)
607         return;
608     pageClient->setCursor(*cursor.platformCursor());
609 #else
610     UNUSED_PARAM(cursor);
611 #endif
612 }
613
614 #if ENABLE(REQUEST_ANIMATION_FRAME) && !USE(REQUEST_ANIMATION_FRAME_TIMER)
615 void ChromeClientQt::scheduleAnimation()
616 {
617     if (!m_refreshAnimation)
618         m_refreshAnimation = adoptPtr(new RefreshAnimation(this));
619     m_refreshAnimation->scheduleAnimation();
620 }
621
622 void ChromeClientQt::serviceScriptedAnimations()
623 {
624     m_webPage->mainFrameAdapter()->frame->view()->serviceScriptedAnimations(convertSecondsToDOMTimeStamp(currentTime()));
625 }
626 #endif
627
628 #if USE(ACCELERATED_COMPOSITING)
629 void ChromeClientQt::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer)
630 {
631     if (platformPageClient())
632         platformPageClient()->setRootGraphicsLayer(graphicsLayer);
633 }
634
635 void ChromeClientQt::setNeedsOneShotDrawingSynchronization()
636 {
637     // we want the layers to synchronize next time we update the screen anyway
638     if (platformPageClient())
639         platformPageClient()->markForSync(false);
640 }
641
642 void ChromeClientQt::scheduleCompositingLayerFlush()
643 {
644     // we want the layers to synchronize ASAP
645     if (platformPageClient())
646         platformPageClient()->markForSync(true);
647 }
648
649 ChromeClient::CompositingTriggerFlags ChromeClientQt::allowedCompositingTriggers() const
650 {
651     if (platformPageClient() && platformPageClient()->allowsAcceleratedCompositing())
652         return ThreeDTransformTrigger | VideoTrigger | CanvasTrigger | AnimationTrigger;
653
654     return 0;
655 }
656
657 #endif
658
659 #if USE(TILED_BACKING_STORE)
660 IntRect ChromeClientQt::visibleRectForTiledBackingStore() const
661 {
662     if (!platformPageClient() || !m_webPage)
663         return IntRect();
664
665     if (!platformPageClient()->viewResizesToContentsEnabled()) {
666         IntSize offset = m_webPage->mainFrameAdapter()->scrollPosition();
667         return QRect(QPoint(offset.width(), offset.height()), m_webPage->mainFrameAdapter()->frameRect().size());
668     }
669
670     return enclosingIntRect(FloatRect(platformPageClient()->graphicsItemVisibleRect()));
671 }
672 #endif
673
674 #if ENABLE(VIDEO) && ((USE(GSTREAMER) && !defined(GST_API_VERSION_1)) || USE(QT_MULTIMEDIA) || USE(QTKIT))
675 FullScreenVideoQt* ChromeClientQt::fullScreenVideo()
676 {
677     if (!m_fullScreenVideo)
678         m_fullScreenVideo = new FullScreenVideoQt(this);
679     return m_fullScreenVideo;
680 }
681
682 bool ChromeClientQt::supportsFullscreenForNode(const Node* node)
683 {
684     ASSERT(node);
685     return node->hasTagName(HTMLNames::videoTag) && fullScreenVideo()->isValid();
686 }
687
688 bool ChromeClientQt::requiresFullscreenForVideoPlayback()
689 {
690     return fullScreenVideo()->requiresFullScreenForVideoPlayback();
691 }
692
693 void ChromeClientQt::enterFullscreenForNode(Node* node)
694 {
695     ASSERT(node && node->hasTagName(HTMLNames::videoTag));
696
697     fullScreenVideo()->enterFullScreenForNode(node);
698 }
699
700 void ChromeClientQt::exitFullscreenForNode(Node* node)
701 {
702     ASSERT(node && node->hasTagName(HTMLNames::videoTag));
703
704     fullScreenVideo()->exitFullScreenForNode(node);
705
706 #endif
707
708 PassOwnPtr<QWebSelectMethod> ChromeClientQt::createSelectPopup() const
709 {
710     OwnPtr<QWebSelectMethod> result = m_platformPlugin.createSelectInputMethod();
711     if (result)
712         return result.release();
713
714 #if !defined(QT_NO_COMBOBOX)
715     return adoptPtr(m_webPage->createSelectPopup());
716 #else
717     return nullptr;
718 #endif
719 }
720
721 void ChromeClientQt::dispatchViewportPropertiesDidChange(const ViewportArguments&) const
722 {
723     m_webPage->emitViewportChangeRequested();
724 }
725
726 #if USE(QT_MULTIMEDIA)
727 QWebFullScreenVideoHandler* ChromeClientQt::createFullScreenVideoHandler()
728 {
729     QWebFullScreenVideoHandler* handler = m_platformPlugin.createFullScreenVideoHandler().leakPtr();
730     if (!handler)
731         handler = m_webPage->createFullScreenVideoHandler();
732     return handler;
733 }
734 #endif
735
736 bool ChromeClientQt::selectItemWritingDirectionIsNatural()
737 {
738     return false;
739 }
740
741 bool ChromeClientQt::selectItemAlignmentFollowsMenuWritingDirection()
742 {
743     return false;
744 }
745
746 bool ChromeClientQt::hasOpenedPopup() const
747 {
748     notImplemented();
749     return false;
750 }
751
752 PassRefPtr<PopupMenu> ChromeClientQt::createPopupMenu(PopupMenuClient* client) const
753 {
754     return adoptRef(new PopupMenuQt(client, this));
755 }
756
757 PassRefPtr<SearchPopupMenu> ChromeClientQt::createSearchPopupMenu(PopupMenuClient* client) const
758 {
759     return adoptRef(new SearchPopupMenuQt(createPopupMenu(client)));
760 }
761
762 void ChromeClientQt::populateVisitedLinks()
763 {
764     // We don't need to do anything here because history is tied to QWebPage rather than stored
765     // in a separate database
766     if (dumpVisitedLinksCallbacks) {
767         printf("Asked to populate visited links for WebView \"%s\"\n",
768             qPrintable(QUrl(m_webPage->mainFrameAdapter()->url).toString()));
769     }
770 }
771
772 } // namespace WebCore