Home | History | Annotate | Download | only in WebCoreSupport
      1 /*
      2  * Copyright (C) 2006 Zack Rusin <zack (at) 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 "DatabaseTracker.h"
     35 #include "FileChooser.h"
     36 #include "Frame.h"
     37 #include "FrameLoadRequest.h"
     38 #include "FrameLoader.h"
     39 #include "FrameLoaderClientQt.h"
     40 #include "FrameView.h"
     41 #include "Geolocation.h"
     42 #if USE(ACCELERATED_COMPOSITING)
     43 #include "GraphicsLayer.h"
     44 #endif
     45 #include "HitTestResult.h"
     46 #include "Icon.h"
     47 #include "NavigationAction.h"
     48 #include "NetworkingContext.h"
     49 #include "NotImplemented.h"
     50 #include "NotificationPresenterClientQt.h"
     51 #include "PageClientQt.h"
     52 #include "PopupMenuQt.h"
     53 #if defined(Q_WS_MAEMO_5)
     54 #include "QtMaemoWebPopup.h"
     55 #else
     56 #include "QtFallbackWebPopup.h"
     57 #endif
     58 #include "QWebPageClient.h"
     59 #include "ScrollbarTheme.h"
     60 #include "SearchPopupMenuQt.h"
     61 #include "SecurityOrigin.h"
     62 #include "ViewportArguments.h"
     63 #include "WindowFeatures.h"
     64 
     65 #include "qgraphicswebview.h"
     66 #include "qwebframe_p.h"
     67 #include "qwebpage.h"
     68 #include "qwebpage_p.h"
     69 #include "qwebsecurityorigin.h"
     70 #include "qwebsecurityorigin_p.h"
     71 #include "qwebview.h"
     72 #include <qdebug.h>
     73 #include <qeventloop.h>
     74 #include <qtextdocument.h>
     75 #include <qtooltip.h>
     76 #include <wtf/OwnPtr.h>
     77 
     78 #if ENABLE(VIDEO) && (USE(GSTREAMER) || USE(QT_MULTIMEDIA))
     79 #include "FullScreenVideoQt.h"
     80 #include "HTMLMediaElement.h"
     81 #include "HTMLNames.h"
     82 #include "HTMLVideoElement.h"
     83 #if USE(QT_MULTIMEDIA)
     84 #include "MediaPlayerPrivateQt.h"
     85 #endif
     86 #endif
     87 
     88 namespace WebCore {
     89 
     90 bool ChromeClientQt::dumpVisitedLinksCallbacks = false;
     91 
     92 ChromeClientQt::ChromeClientQt(QWebPage* webPage)
     93     : m_webPage(webPage)
     94     , m_eventLoop(0)
     95 #if ENABLE(VIDEO) && (USE(GSTREAMER) || USE(QT_MULTIMEDIA))
     96     , m_fullScreenVideo(0)
     97 #endif
     98 {
     99     toolBarsVisible = statusBarVisible = menuBarVisible = true;
    100 }
    101 
    102 ChromeClientQt::~ChromeClientQt()
    103 {
    104     if (m_eventLoop)
    105         m_eventLoop->exit();
    106 
    107 #if ENABLE(VIDEO) && (USE(GSTREAMER) || USE(QT_MULTIMEDIA))
    108     delete m_fullScreenVideo;
    109 #endif
    110 }
    111 
    112 void ChromeClientQt::setWindowRect(const FloatRect& rect)
    113 {
    114     if (!m_webPage)
    115         return;
    116     emit m_webPage->geometryChangeRequested(QRect(qRound(rect.x()), qRound(rect.y()),
    117                             qRound(rect.width()), qRound(rect.height())));
    118 }
    119 
    120 /*!
    121     windowRect represents the rect of the Window, including all interface elements
    122     like toolbars/scrollbars etc. It is used by the viewport meta tag as well as
    123     by the DOM Window object: outerHeight(), outerWidth(), screenX(), screenY().
    124 */
    125 FloatRect ChromeClientQt::windowRect()
    126 {
    127     if (!platformPageClient())
    128         return FloatRect();
    129     return platformPageClient()->windowRect();
    130 }
    131 
    132 FloatRect ChromeClientQt::pageRect()
    133 {
    134     if (!m_webPage)
    135         return FloatRect();
    136     return FloatRect(QRectF(QPointF(0, 0), m_webPage->viewportSize()));
    137 }
    138 
    139 float ChromeClientQt::scaleFactor()
    140 {
    141     if (!m_webPage)
    142         return 1;
    143     return m_webPage->d->pixelRatio;
    144 }
    145 
    146 void ChromeClientQt::focus()
    147 {
    148     if (!m_webPage)
    149         return;
    150     QWidget* view = m_webPage->view();
    151     if (!view)
    152         return;
    153 
    154     view->setFocus();
    155 }
    156 
    157 
    158 void ChromeClientQt::unfocus()
    159 {
    160     if (!m_webPage)
    161         return;
    162     QWidget* view = m_webPage->view();
    163     if (!view)
    164         return;
    165     view->clearFocus();
    166 }
    167 
    168 bool ChromeClientQt::canTakeFocus(FocusDirection)
    169 {
    170     // This is called when cycling through links/focusable objects and we
    171     // reach the last focusable object. Then we want to claim that we can
    172     // take the focus to avoid wrapping.
    173     return true;
    174 }
    175 
    176 void ChromeClientQt::takeFocus(FocusDirection)
    177 {
    178     // don't do anything. This is only called when cycling to links/focusable objects,
    179     // which in turn is called from focusNextPrevChild. We let focusNextPrevChild
    180     // call QWidget::focusNextPrevChild accordingly, so there is no need to do anything
    181     // here.
    182 }
    183 
    184 
    185 void ChromeClientQt::focusedNodeChanged(Node*)
    186 {
    187 }
    188 
    189 void ChromeClientQt::focusedFrameChanged(Frame*)
    190 {
    191 }
    192 
    193 Page* ChromeClientQt::createWindow(Frame*, const FrameLoadRequest& request, const WindowFeatures& features, const NavigationAction&)
    194 {
    195     QWebPage* newPage = m_webPage->createWindow(features.dialog ? QWebPage::WebModalDialog : QWebPage::WebBrowserWindow);
    196     if (!newPage)
    197         return 0;
    198 
    199     // A call to QWebPage::mainFrame() implicitly creates the main frame.
    200     // Make sure it exists, as WebCore expects it when returning from this call.
    201     newPage->mainFrame();
    202     return newPage->d->page;
    203 }
    204 
    205 void ChromeClientQt::show()
    206 {
    207     if (!m_webPage)
    208         return;
    209     QWidget* view = m_webPage->view();
    210     if (!view)
    211         return;
    212     view->window()->show();
    213 }
    214 
    215 
    216 bool ChromeClientQt::canRunModal()
    217 {
    218     return true;
    219 }
    220 
    221 
    222 void ChromeClientQt::runModal()
    223 {
    224     m_eventLoop = new QEventLoop();
    225     QEventLoop* eventLoop = m_eventLoop;
    226     m_eventLoop->exec();
    227     delete eventLoop;
    228 }
    229 
    230 
    231 void ChromeClientQt::setToolbarsVisible(bool visible)
    232 {
    233     toolBarsVisible = visible;
    234     emit m_webPage->toolBarVisibilityChangeRequested(visible);
    235 }
    236 
    237 
    238 bool ChromeClientQt::toolbarsVisible()
    239 {
    240     return toolBarsVisible;
    241 }
    242 
    243 
    244 void ChromeClientQt::setStatusbarVisible(bool visible)
    245 {
    246     emit m_webPage->statusBarVisibilityChangeRequested(visible);
    247     statusBarVisible = visible;
    248 }
    249 
    250 
    251 bool ChromeClientQt::statusbarVisible()
    252 {
    253     return statusBarVisible;
    254 }
    255 
    256 
    257 void ChromeClientQt::setScrollbarsVisible(bool)
    258 {
    259     notImplemented();
    260 }
    261 
    262 
    263 bool ChromeClientQt::scrollbarsVisible()
    264 {
    265     notImplemented();
    266     return true;
    267 }
    268 
    269 
    270 void ChromeClientQt::setMenubarVisible(bool visible)
    271 {
    272     menuBarVisible = visible;
    273     emit m_webPage->menuBarVisibilityChangeRequested(visible);
    274 }
    275 
    276 bool ChromeClientQt::menubarVisible()
    277 {
    278     return menuBarVisible;
    279 }
    280 
    281 void ChromeClientQt::setResizable(bool)
    282 {
    283     notImplemented();
    284 }
    285 
    286 void ChromeClientQt::addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message,
    287                                          unsigned int lineNumber, const String& sourceID)
    288 {
    289     QString x = message;
    290     QString y = sourceID;
    291     m_webPage->javaScriptConsoleMessage(x, lineNumber, y);
    292 }
    293 
    294 void ChromeClientQt::chromeDestroyed()
    295 {
    296     delete this;
    297 }
    298 
    299 bool ChromeClientQt::canRunBeforeUnloadConfirmPanel()
    300 {
    301     return true;
    302 }
    303 
    304 bool ChromeClientQt::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
    305 {
    306     return runJavaScriptConfirm(frame, message);
    307 }
    308 
    309 void ChromeClientQt::closeWindowSoon()
    310 {
    311     m_webPage->d->page->setGroupName(String());
    312     m_webPage->mainFrame()->d->frame->loader()->stopAllLoaders();
    313     emit m_webPage->windowCloseRequested();
    314 }
    315 
    316 void ChromeClientQt::runJavaScriptAlert(Frame* f, const String& msg)
    317 {
    318     QString x = msg;
    319     QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
    320     m_webPage->javaScriptAlert(webFrame, x);
    321 }
    322 
    323 bool ChromeClientQt::runJavaScriptConfirm(Frame* f, const String& msg)
    324 {
    325     QString x = msg;
    326     QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
    327     return m_webPage->javaScriptConfirm(webFrame, x);
    328 }
    329 
    330 bool ChromeClientQt::runJavaScriptPrompt(Frame* f, const String& message, const String& defaultValue, String& result)
    331 {
    332     QString x = result;
    333     QWebFrame* webFrame = qobject_cast<QWebFrame*>(f->loader()->networkingContext()->originatingObject());
    334     bool rc = m_webPage->javaScriptPrompt(webFrame, (QString)message, (QString)defaultValue, &x);
    335 
    336     // Fix up a quirk in the QInputDialog class. If no input happened the string should be empty
    337     // but it is null. See https://bugs.webkit.org/show_bug.cgi?id=30914.
    338     if (rc && x.isNull())
    339         result = String("");
    340     else
    341         result = x;
    342 
    343     return rc;
    344 }
    345 
    346 void ChromeClientQt::setStatusbarText(const String& msg)
    347 {
    348     QString x = msg;
    349     emit m_webPage->statusBarMessage(x);
    350 }
    351 
    352 bool ChromeClientQt::shouldInterruptJavaScript()
    353 {
    354     bool shouldInterrupt = false;
    355     QMetaObject::invokeMethod(m_webPage, "shouldInterruptJavaScript", Qt::DirectConnection, Q_RETURN_ARG(bool, shouldInterrupt));
    356     return shouldInterrupt;
    357 }
    358 
    359 KeyboardUIMode ChromeClientQt::keyboardUIMode()
    360 {
    361     return m_webPage->settings()->testAttribute(QWebSettings::LinksIncludedInFocusChain)
    362         ? KeyboardAccessTabsToLinks : KeyboardAccessDefault;
    363 }
    364 
    365 IntRect ChromeClientQt::windowResizerRect() const
    366 {
    367 #if defined(Q_WS_MAC)
    368     if (!m_webPage)
    369         return IntRect();
    370 
    371     QWebPageClient* pageClient = platformPageClient();
    372     if (!pageClient)
    373         return IntRect();
    374 
    375     QWidget* ownerWidget = pageClient->ownerWidget();
    376     if (!ownerWidget)
    377         return IntRect();
    378 
    379     QWidget* topLevelWidget = ownerWidget->window();
    380     QRect topLevelGeometry(topLevelWidget->geometry());
    381 
    382     // There's no API in Qt to query for the size of the resizer, so we assume
    383     // it has the same width and height as the scrollbar thickness.
    384     int scollbarThickness = ScrollbarTheme::nativeTheme()->scrollbarThickness();
    385 
    386     // There's no API in Qt to query for the position of the resizer. Sometimes
    387     // it's drawn by the system, and sometimes it's a QSizeGrip. For RTL locales
    388     // it might even be on the lower left side of the window, but in WebKit we
    389     // always draw scrollbars on the right hand side, so we assume this to be the
    390     // location when computing the resize rect to reserve for WebKit.
    391     QPoint resizeCornerTopLeft = ownerWidget->mapFrom(topLevelWidget,
    392             QPoint(topLevelGeometry.width(), topLevelGeometry.height())
    393             - QPoint(scollbarThickness, scollbarThickness));
    394 
    395     QRect resizeCornerRect = QRect(resizeCornerTopLeft, QSize(scollbarThickness, scollbarThickness));
    396     return resizeCornerRect.intersected(pageClient->geometryRelativeToOwnerWidget());
    397 #else
    398     return IntRect();
    399 #endif
    400 }
    401 
    402 void ChromeClientQt::invalidateWindow(const IntRect& windowRect, bool)
    403 {
    404 #if ENABLE(TILED_BACKING_STORE)
    405     if (platformPageClient()) {
    406         WebCore::TiledBackingStore* backingStore = QWebFramePrivate::core(m_webPage->mainFrame())->tiledBackingStore();
    407         if (!backingStore)
    408             return;
    409         backingStore->invalidate(windowRect);
    410     }
    411 #else
    412     Q_UNUSED(windowRect);
    413 #endif
    414 }
    415 
    416 void ChromeClientQt::invalidateContentsAndWindow(const IntRect& windowRect, bool immediate)
    417 {
    418     // No double buffer, so only update the QWidget if content changed.
    419     if (platformPageClient()) {
    420         QRect rect(windowRect);
    421         rect = rect.intersected(QRect(QPoint(0, 0), m_webPage->viewportSize()));
    422         if (!rect.isEmpty())
    423             platformPageClient()->update(rect);
    424     }
    425     QMetaObject::invokeMethod(m_webPage, "repaintRequested", Qt::QueuedConnection, Q_ARG(QRect, windowRect));
    426 
    427     // FIXME: There is no "immediate" support for window painting.  This should be done always whenever the flag
    428     // is set.
    429 }
    430 
    431 void ChromeClientQt::invalidateContentsForSlowScroll(const IntRect& windowRect, bool immediate)
    432 {
    433     invalidateContentsAndWindow(windowRect, immediate);
    434 }
    435 
    436 void ChromeClientQt::scroll(const IntSize& delta, const IntRect& scrollViewRect, const IntRect&)
    437 {
    438     if (platformPageClient())
    439         platformPageClient()->scroll(delta.width(), delta.height(), scrollViewRect);
    440     emit m_webPage->scrollRequested(delta.width(), delta.height(), scrollViewRect);
    441 }
    442 
    443 #if ENABLE(TILED_BACKING_STORE)
    444 void ChromeClientQt::delegatedScrollRequested(const IntPoint& point)
    445 {
    446     QPoint currentPosition(m_webPage->mainFrame()->scrollPosition());
    447     emit m_webPage->scrollRequested(point.x() - currentPosition.x(), point.y() - currentPosition.y(), QRect(QPoint(0, 0), m_webPage->viewportSize()));
    448 }
    449 #endif
    450 
    451 IntRect ChromeClientQt::windowToScreen(const IntRect& rect) const
    452 {
    453     QWebPageClient* pageClient = platformPageClient();
    454     if (!pageClient)
    455         return rect;
    456 
    457     QWidget* ownerWidget = pageClient->ownerWidget();
    458     if (!ownerWidget)
    459        return rect;
    460 
    461     QRect screenRect(rect);
    462     screenRect.translate(ownerWidget->mapToGlobal(QPoint(0, 0)));
    463 
    464     return screenRect;
    465 }
    466 
    467 IntPoint ChromeClientQt::screenToWindow(const IntPoint& point) const
    468 {
    469     QWebPageClient* pageClient = platformPageClient();
    470     if (!pageClient)
    471         return point;
    472 
    473     QWidget* ownerWidget = pageClient->ownerWidget();
    474     if (!ownerWidget)
    475         return point;
    476 
    477     return ownerWidget->mapFromGlobal(point);
    478 }
    479 
    480 PlatformPageClient ChromeClientQt::platformPageClient() const
    481 {
    482     return m_webPage->d->client.get();
    483 }
    484 
    485 void ChromeClientQt::contentsSizeChanged(Frame* frame, const IntSize& size) const
    486 {
    487     if (frame->loader()->networkingContext())
    488         QWebFramePrivate::kit(frame)->contentsSizeChanged(size);
    489 }
    490 
    491 void ChromeClientQt::mouseDidMoveOverElement(const HitTestResult& result, unsigned)
    492 {
    493     TextDirection dir;
    494     if (result.absoluteLinkURL() != lastHoverURL
    495         || result.title(dir) != lastHoverTitle
    496         || result.textContent() != lastHoverContent) {
    497         lastHoverURL = result.absoluteLinkURL();
    498         lastHoverTitle = result.title(dir);
    499         lastHoverContent = result.textContent();
    500         emit m_webPage->linkHovered(lastHoverURL.string(),
    501                 lastHoverTitle, lastHoverContent);
    502     }
    503 }
    504 
    505 void ChromeClientQt::setToolTip(const String &tip, TextDirection)
    506 {
    507 #ifndef QT_NO_TOOLTIP
    508     QWidget* view = m_webPage->view();
    509     if (!view)
    510         return;
    511 
    512     if (tip.isEmpty()) {
    513         view->setToolTip(QString());
    514         QToolTip::hideText();
    515     } else {
    516         QString dtip = QLatin1String("<p>") + Qt::escape(tip) + QLatin1String("</p>");
    517         view->setToolTip(dtip);
    518     }
    519 #else
    520     Q_UNUSED(tip);
    521 #endif
    522 }
    523 
    524 void ChromeClientQt::print(Frame* frame)
    525 {
    526     emit m_webPage->printRequested(QWebFramePrivate::kit(frame));
    527 }
    528 
    529 #if ENABLE(DATABASE)
    530 void ChromeClientQt::exceededDatabaseQuota(Frame* frame, const String& databaseName)
    531 {
    532     quint64 quota = QWebSettings::offlineStorageDefaultQuota();
    533 
    534     if (!DatabaseTracker::tracker().hasEntryForOrigin(frame->document()->securityOrigin()))
    535         DatabaseTracker::tracker().setQuota(frame->document()->securityOrigin(), quota);
    536 
    537     emit m_webPage->databaseQuotaExceeded(QWebFramePrivate::kit(frame), databaseName);
    538 }
    539 #endif
    540 
    541 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
    542 void ChromeClientQt::reachedMaxAppCacheSize(int64_t)
    543 {
    544     // FIXME: Free some space.
    545     notImplemented();
    546 }
    547 
    548 void ChromeClientQt::reachedApplicationCacheOriginQuota(SecurityOrigin* origin)
    549 {
    550     int64_t quota;
    551     quint64 defaultOriginQuota = WebCore::cacheStorage().defaultOriginQuota();
    552 
    553     QWebSecurityOriginPrivate* priv = new QWebSecurityOriginPrivate(origin);
    554     QWebSecurityOrigin* securityOrigin = new QWebSecurityOrigin(priv);
    555 
    556     if (!WebCore::cacheStorage().quotaForOrigin(origin, quota))
    557        WebCore::cacheStorage().storeUpdatedQuotaForOrigin(origin, defaultOriginQuota);
    558 
    559     emit m_webPage->applicationCacheQuotaExceeded(securityOrigin, defaultOriginQuota);
    560 }
    561 #endif
    562 
    563 #if ENABLE(NOTIFICATIONS)
    564 NotificationPresenter* ChromeClientQt::notificationPresenter() const
    565 {
    566     return NotificationPresenterClientQt::notificationPresenter();
    567 }
    568 #endif
    569 
    570 void ChromeClientQt::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> prpFileChooser)
    571 {
    572     RefPtr<FileChooser> fileChooser = prpFileChooser;
    573     bool supportMulti = m_webPage->supportsExtension(QWebPage::ChooseMultipleFilesExtension);
    574 
    575     if (fileChooser->allowsMultipleFiles() && supportMulti) {
    576         QWebPage::ChooseMultipleFilesExtensionOption option;
    577         option.parentFrame = QWebFramePrivate::kit(frame);
    578 
    579         if (!fileChooser->filenames().isEmpty())
    580             for (unsigned i = 0; i < fileChooser->filenames().size(); ++i)
    581                 option.suggestedFileNames += fileChooser->filenames()[i];
    582 
    583         QWebPage::ChooseMultipleFilesExtensionReturn output;
    584         m_webPage->extension(QWebPage::ChooseMultipleFilesExtension, &option, &output);
    585 
    586         if (!output.fileNames.isEmpty()) {
    587             Vector<String> names;
    588             for (int i = 0; i < output.fileNames.count(); ++i)
    589                 names.append(output.fileNames.at(i));
    590             fileChooser->chooseFiles(names);
    591         }
    592     } else {
    593         QString suggestedFile;
    594         if (!fileChooser->filenames().isEmpty())
    595             suggestedFile = fileChooser->filenames()[0];
    596         QString file = m_webPage->chooseFile(QWebFramePrivate::kit(frame), suggestedFile);
    597         if (!file.isEmpty())
    598             fileChooser->chooseFile(file);
    599     }
    600 }
    601 
    602 void ChromeClientQt::chooseIconForFiles(const Vector<String>& filenames, FileChooser* chooser)
    603 {
    604     chooser->iconLoaded(Icon::createIconForFiles(filenames));
    605 }
    606 
    607 void ChromeClientQt::setCursor(const Cursor& cursor)
    608 {
    609 #ifndef QT_NO_CURSOR
    610     QWebPageClient* pageClient = platformPageClient();
    611     if (!pageClient)
    612         return;
    613     pageClient->setCursor(*cursor.platformCursor());
    614 #else
    615     UNUSED_PARAM(cursor);
    616 #endif
    617 }
    618 
    619 
    620 #if USE(ACCELERATED_COMPOSITING)
    621 void ChromeClientQt::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer)
    622 {
    623     if (platformPageClient())
    624         platformPageClient()->setRootGraphicsLayer(graphicsLayer ? graphicsLayer->platformLayer() : 0);
    625 }
    626 
    627 void ChromeClientQt::setNeedsOneShotDrawingSynchronization()
    628 {
    629     // we want the layers to synchronize next time we update the screen anyway
    630     if (platformPageClient())
    631         platformPageClient()->markForSync(false);
    632 }
    633 
    634 void ChromeClientQt::scheduleCompositingLayerSync()
    635 {
    636     // we want the layers to synchronize ASAP
    637     if (platformPageClient())
    638         platformPageClient()->markForSync(true);
    639 }
    640 
    641 ChromeClient::CompositingTriggerFlags ChromeClientQt::allowedCompositingTriggers() const
    642 {
    643     if (platformPageClient() && platformPageClient()->allowsAcceleratedCompositing())
    644         return AllTriggers;
    645 
    646     return 0;
    647 }
    648 
    649 #endif
    650 
    651 #if ENABLE(TILED_BACKING_STORE)
    652 IntRect ChromeClientQt::visibleRectForTiledBackingStore() const
    653 {
    654     if (!platformPageClient() || !m_webPage)
    655         return IntRect();
    656 
    657     if (!platformPageClient()->viewResizesToContentsEnabled())
    658         return QRect(m_webPage->mainFrame()->scrollPosition(), m_webPage->mainFrame()->geometry().size());
    659 
    660     return enclosingIntRect(FloatRect(platformPageClient()->graphicsItemVisibleRect()));
    661 }
    662 #endif
    663 
    664 #if ENABLE(VIDEO) && (USE(GSTREAMER) || USE(QT_MULTIMEDIA))
    665 FullScreenVideoQt* ChromeClientQt::fullScreenVideo()
    666 {
    667     if (!m_fullScreenVideo)
    668         m_fullScreenVideo = new FullScreenVideoQt(this);
    669     return m_fullScreenVideo;
    670 }
    671 
    672 bool ChromeClientQt::supportsFullscreenForNode(const Node* node)
    673 {
    674     ASSERT(node);
    675     return node->hasTagName(HTMLNames::videoTag) && fullScreenVideo()->isValid();
    676 }
    677 
    678 bool ChromeClientQt::requiresFullscreenForVideoPlayback()
    679 {
    680     return fullScreenVideo()->requiresFullScreenForVideoPlayback();
    681 }
    682 
    683 void ChromeClientQt::enterFullscreenForNode(Node* node)
    684 {
    685     ASSERT(node && node->hasTagName(HTMLNames::videoTag));
    686 
    687     fullScreenVideo()->enterFullScreenForNode(node);
    688 }
    689 
    690 void ChromeClientQt::exitFullscreenForNode(Node* node)
    691 {
    692     ASSERT(node && node->hasTagName(HTMLNames::videoTag));
    693 
    694     fullScreenVideo()->exitFullScreenForNode(node);
    695 }
    696 #endif
    697 
    698 QWebSelectMethod* ChromeClientQt::createSelectPopup() const
    699 {
    700     QWebSelectMethod* result = m_platformPlugin.createSelectInputMethod();
    701     if (result)
    702         return result;
    703 
    704 #if defined(Q_WS_MAEMO_5)
    705     return new QtMaemoWebPopup;
    706 #elif !defined(QT_NO_COMBOBOX)
    707     return new QtFallbackWebPopup(this);
    708 #else
    709     return 0;
    710 #endif
    711 }
    712 
    713 void ChromeClientQt::dispatchViewportDataDidChange(const ViewportArguments&) const
    714 {
    715     emit m_webPage->viewportChangeRequested();
    716 }
    717 
    718 bool ChromeClientQt::selectItemWritingDirectionIsNatural()
    719 {
    720     return false;
    721 }
    722 
    723 bool ChromeClientQt::selectItemAlignmentFollowsMenuWritingDirection()
    724 {
    725     return false;
    726 }
    727 
    728 PassRefPtr<PopupMenu> ChromeClientQt::createPopupMenu(PopupMenuClient* client) const
    729 {
    730     return adoptRef(new PopupMenuQt(client, this));
    731 }
    732 
    733 PassRefPtr<SearchPopupMenu> ChromeClientQt::createSearchPopupMenu(PopupMenuClient* client) const
    734 {
    735     return adoptRef(new SearchPopupMenuQt(createPopupMenu(client)));
    736 }
    737 
    738 void ChromeClientQt::populateVisitedLinks()
    739 {
    740     // We don't need to do anything here because history is tied to QWebPage rather than stored
    741     // in a separate database
    742     if (dumpVisitedLinksCallbacks) {
    743         printf("Asked to populate visited links for WebView \"%s\"\n",
    744                 qPrintable(m_webPage->mainFrame()->url().toString()));
    745     }
    746 }
    747 
    748 } // namespace WebCore
    749