diff options
Diffstat (limited to 'src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp')
-rw-r--r-- | src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp | 534 |
1 files changed, 0 insertions, 534 deletions
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp deleted file mode 100644 index 0695806a6..000000000 --- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp +++ /dev/null @@ -1,534 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "render_widget_host_view_qt_delegate_widget.h" - -#include "render_widget_host_view_qt_delegate_client.h" - -#include "qwebenginepage_p.h" -#include "qwebengineview.h" -#include "qwebengineview_p.h" -#include <QGuiApplication> -#include <QLayout> -#include <QMouseEvent> -#include <QOpenGLContext> -#include <QResizeEvent> -#include <QSGNode> -#include <QWindow> -#include <QtQuick/private/qquickwindow_p.h> - -namespace QtWebEngineCore { - -class RenderWidgetHostViewQuickItem : public QQuickItem { -public: - RenderWidgetHostViewQuickItem(RenderWidgetHostViewQtDelegateClient *client) : m_client(client) - { - setFlag(ItemHasContents, true); - // Mark that this item should receive focus when the parent QQuickWidget receives focus. - setFocus(true); - } -protected: - bool event(QEvent *event) override - { - if (event->type() == QEvent::ShortcutOverride) - return m_client->forwardEvent(event); - - return QQuickItem::event(event); - } - void focusInEvent(QFocusEvent *event) override - { - m_client->forwardEvent(event); - } - void focusOutEvent(QFocusEvent *event) override - { - m_client->forwardEvent(event); - } - void inputMethodEvent(QInputMethodEvent *event) override - { - m_client->forwardEvent(event); - } - QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override - { - return m_client->updatePaintNode(oldNode); - } - - QVariant inputMethodQuery(Qt::InputMethodQuery query) const override - { - return m_client->inputMethodQuery(query); - } -private: - RenderWidgetHostViewQtDelegateClient *m_client; -}; - -RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(RenderWidgetHostViewQtDelegateClient *client, QWidget *parent) - : QQuickWidget(parent) - , m_client(client) - , m_rootItem(new RenderWidgetHostViewQuickItem(client)) - , m_isPopup(false) -{ - setFocusPolicy(Qt::StrongFocus); - - QSurfaceFormat format; - format.setDepthBufferSize(24); - format.setStencilBufferSize(8); - -#if QT_CONFIG(opengl) - QOpenGLContext *globalSharedContext = QOpenGLContext::globalShareContext(); - if (globalSharedContext) { - QSurfaceFormat sharedFormat = globalSharedContext->format(); - -#ifdef Q_OS_OSX - // Check that the default QSurfaceFormat OpenGL profile is compatible with the global OpenGL - // shared context profile, otherwise this could lead to a nasty crash. - QSurfaceFormat defaultFormat = QSurfaceFormat::defaultFormat(); - - if (defaultFormat.profile() != sharedFormat.profile() - && defaultFormat.profile() == QSurfaceFormat::CoreProfile - && defaultFormat.version() >= qMakePair(3, 2)) { - qFatal("QWebEngine: Default QSurfaceFormat OpenGL profile is not compatible with the " - "global shared context OpenGL profile. Please make sure you set a compatible " - "QSurfaceFormat before the QtGui application instance is created."); - } -#endif - int major; - int minor; - QSurfaceFormat::OpenGLContextProfile profile; -#ifdef Q_OS_MACOS - // Due to QTBUG-63180, requesting the sharedFormat.majorVersion() on macOS will lead to - // a failed creation of QQuickWidget shared context. Thus make sure to request the - // major version specified in the defaultFormat instead. - major = defaultFormat.majorVersion(); - minor = defaultFormat.minorVersion(); - profile = defaultFormat.profile(); -#else - major = sharedFormat.majorVersion(); - minor = sharedFormat.minorVersion(); - profile = sharedFormat.profile(); -#endif - - // Make sure the OpenGL profile of the QQuickWidget matches the shared context profile. - // It covers the following cases: - // 1) Desktop OpenGL Core Profile. - // 2) Windows ANGLE OpenGL ES profile. - if (sharedFormat.profile() == QSurfaceFormat::CoreProfile -#ifdef Q_OS_WIN - || globalSharedContext->isOpenGLES() -#endif - ) { - format.setMajorVersion(major); - format.setMinorVersion(minor); - format.setProfile(profile); - } - } - - setFormat(format); -#endif - setMouseTracking(true); - setAttribute(Qt::WA_AcceptTouchEvents); - setAttribute(Qt::WA_OpaquePaintEvent); - setAttribute(Qt::WA_AlwaysShowToolTips); - - setContent(QUrl(), nullptr, m_rootItem.data()); - - connectRemoveParentBeforeParentDelete(); -} - -RenderWidgetHostViewQtDelegateWidget::~RenderWidgetHostViewQtDelegateWidget() -{ - QWebEnginePagePrivate::bindPageAndWidget(nullptr, this); -} - -void RenderWidgetHostViewQtDelegateWidget::connectRemoveParentBeforeParentDelete() -{ - disconnect(m_parentDestroyedConnection); - - if (QWidget *parent = parentWidget()) { - m_parentDestroyedConnection = connect(parent, &QObject::destroyed, - this, - &RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete); - } else { - m_parentDestroyedConnection = QMetaObject::Connection(); - } -} - -void RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete() -{ - // Unset the parent, because parent is being destroyed, but the owner of this - // RenderWidgetHostViewQtDelegateWidget is actually a RenderWidgetHostViewQt instance. - setParent(nullptr); - - // If this widget represents a popup window, make sure to close it, so that if the popup was the - // last visible top level window, the application event loop can quit if it deems it necessarry. - if (m_isPopup) - close(); -} - -void RenderWidgetHostViewQtDelegateWidget::initAsPopup(const QRect& screenRect) -{ - m_isPopup = true; - - // The keyboard events are supposed to go to the parent RenderHostView - // so the WebUI popups should never have focus. Besides, if the parent view - // loses focus, WebKit will cause its associated popups (including this one) - // to be destroyed. - setAttribute(Qt::WA_ShowWithoutActivating); - setFocusPolicy(Qt::NoFocus); - setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus); - - setGeometry(screenRect); - show(); -} - -void RenderWidgetHostViewQtDelegateWidget::closeEvent(QCloseEvent *event) -{ - Q_UNUSED(event); - - // If a close event was received from the window manager (e.g. when moving the parent window, - // clicking outside the popup area) - // make sure to notify the Chromium WebUI popup and its underlying - // RenderWidgetHostViewQtDelegate instance to be closed. - if (m_isPopup) - m_client->closePopup(); -} - -QRectF RenderWidgetHostViewQtDelegateWidget::viewGeometry() const -{ - return QRectF(mapToGlobal(pos()), size()); -} - -QRect RenderWidgetHostViewQtDelegateWidget::windowGeometry() const -{ - if (!window()) - return QRect(); - return window()->frameGeometry(); -} - -void RenderWidgetHostViewQtDelegateWidget::setKeyboardFocus() -{ - // The root item always has focus within the root focus scope: - Q_ASSERT(m_rootItem->hasFocus()); - - setFocus(); -} - -bool RenderWidgetHostViewQtDelegateWidget::hasKeyboardFocus() -{ - // The root item always has focus within the root focus scope: - Q_ASSERT(m_rootItem->hasFocus()); - - return hasFocus(); -} - -void RenderWidgetHostViewQtDelegateWidget::lockMouse() -{ - grabMouse(); -} - -void RenderWidgetHostViewQtDelegateWidget::unlockMouse() -{ - releaseMouse(); -} - -void RenderWidgetHostViewQtDelegateWidget::show() -{ - m_rootItem->setVisible(true); - // Check if we're attached to a QWebEngineView, we don't - // want to show anything else than popups as top-level. - if (parent() || m_isPopup) { - QQuickWidget::show(); - } -} - -void RenderWidgetHostViewQtDelegateWidget::hide() -{ - m_rootItem->setVisible(false); - QQuickWidget::hide(); -} - -bool RenderWidgetHostViewQtDelegateWidget::isVisible() const -{ - return QQuickWidget::isVisible() && m_rootItem->isVisible(); -} - -QWindow* RenderWidgetHostViewQtDelegateWidget::window() const -{ - const QWidget* root = QQuickWidget::window(); - return root ? root->windowHandle() : 0; -} - -QSGTexture *RenderWidgetHostViewQtDelegateWidget::createTextureFromImage(const QImage &image) -{ - return quickWindow()->createTextureFromImage(image, QQuickWindow::TextureCanUseAtlas); -} - -QSGLayer *RenderWidgetHostViewQtDelegateWidget::createLayer() -{ - QSGRenderContext *renderContext = QQuickWindowPrivate::get(quickWindow())->context; - return renderContext->sceneGraphContext()->createLayer(renderContext); -} - -QSGImageNode *RenderWidgetHostViewQtDelegateWidget::createImageNode() -{ - return quickWindow()->createImageNode(); -} - -QSGRectangleNode *RenderWidgetHostViewQtDelegateWidget::createRectangleNode() -{ - return quickWindow()->createRectangleNode(); -} - -void RenderWidgetHostViewQtDelegateWidget::update() -{ - m_rootItem->update(); -} - -void RenderWidgetHostViewQtDelegateWidget::updateCursor(const QCursor &cursor) -{ - QQuickWidget::setCursor(cursor); -} - -void RenderWidgetHostViewQtDelegateWidget::resize(int width, int height) -{ - QQuickWidget::resize(width, height); -} - -void RenderWidgetHostViewQtDelegateWidget::move(const QPoint &screenPos) -{ - Q_ASSERT(m_isPopup); - QQuickWidget::move(screenPos); -} - -void RenderWidgetHostViewQtDelegateWidget::inputMethodStateChanged(bool editorVisible, bool passwordInput) -{ - QQuickWidget::setAttribute(Qt::WA_InputMethodEnabled, editorVisible && !passwordInput); - qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints); - if (qApp->inputMethod()->isVisible() != editorVisible) - qApp->inputMethod()->setVisible(editorVisible); -} - -void RenderWidgetHostViewQtDelegateWidget::setInputMethodHints(Qt::InputMethodHints hints) -{ - QQuickWidget::setInputMethodHints(hints); -} - -void RenderWidgetHostViewQtDelegateWidget::setClearColor(const QColor &color) -{ - QQuickWidget::setClearColor(color); - // QQuickWidget is usually blended by punching holes into widgets - // above it to simulate the visual stacking order. If we want it to be - // transparent we have to throw away the proper stacking order and always - // blend the complete normal widgets backing store under it. - bool isTranslucent = color.alpha() < 255; - setAttribute(Qt::WA_AlwaysStackOnTop, isTranslucent); - setAttribute(Qt::WA_OpaquePaintEvent, !isTranslucent); - update(); -} - -QVariant RenderWidgetHostViewQtDelegateWidget::inputMethodQuery(Qt::InputMethodQuery query) const -{ - return m_client->inputMethodQuery(query); -} - -void RenderWidgetHostViewQtDelegateWidget::resizeEvent(QResizeEvent *resizeEvent) -{ - QQuickWidget::resizeEvent(resizeEvent); - m_client->visualPropertiesChanged(); -} - -void RenderWidgetHostViewQtDelegateWidget::showEvent(QShowEvent *event) -{ - QQuickWidget::showEvent(event); - // We don't have a way to catch a top-level window change with QWidget - // but a widget will most likely be shown again if it changes, so do - // the reconnection at this point. - for (const QMetaObject::Connection &c : qAsConst(m_windowConnections)) - disconnect(c); - m_windowConnections.clear(); - if (QWindow *w = window()) { - m_windowConnections.append(connect(w, SIGNAL(xChanged(int)), SLOT(onWindowPosChanged()))); - m_windowConnections.append(connect(w, SIGNAL(yChanged(int)), SLOT(onWindowPosChanged()))); - } - m_client->visualPropertiesChanged(); - m_client->notifyShown(); -} - -void RenderWidgetHostViewQtDelegateWidget::hideEvent(QHideEvent *event) -{ - QQuickWidget::hideEvent(event); - m_client->notifyHidden(); -} - -bool RenderWidgetHostViewQtDelegateWidget::copySurface(const QRect &rect, const QSize &size, QImage &image) -{ - QPixmap pixmap = rect.isEmpty() ? QQuickWidget::grab(QQuickWidget::rect()) : QQuickWidget::grab(rect); - if (pixmap.isNull()) - return false; - image = pixmap.toImage().scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - return true; -} - -bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event) -{ - bool handled = false; - - // Track parent to make sure we don't get deleted. - switch (event->type()) { - case QEvent::ParentChange: - connectRemoveParentBeforeParentDelete(); - break; - default: - break; - } - - // Mimic QWidget::event() by ignoring mouse, keyboard, touch and tablet events if the widget is - // disabled. - if (!isEnabled()) { - switch (event->type()) { - case QEvent::TabletPress: - case QEvent::TabletRelease: - case QEvent::TabletMove: - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseButtonDblClick: - case QEvent::MouseMove: - case QEvent::TouchBegin: - case QEvent::TouchUpdate: - case QEvent::TouchEnd: - case QEvent::TouchCancel: - case QEvent::ContextMenu: - case QEvent::KeyPress: - case QEvent::KeyRelease: -#ifndef QT_NO_WHEELEVENT - case QEvent::Wheel: -#endif - return false; - default: - break; - } - } - - switch (event->type()) { - case QEvent::FocusIn: - case QEvent::FocusOut: - // We forward focus events later, once they have made it to the m_rootItem. - return QQuickWidget::event(event); - case QEvent::DragEnter: - case QEvent::DragLeave: - case QEvent::DragMove: - case QEvent::Drop: - case QEvent::HoverEnter: - case QEvent::HoverLeave: - case QEvent::HoverMove: - // Let the parent handle these events. - return false; - default: - break; - } - - if (event->type() == QEvent::MouseButtonDblClick) { - // QWidget keeps the Qt4 behavior where the DblClick event would replace the Press event. - // QtQuick is different by sending both the Press and DblClick events for the second press - // where we can simply ignore the DblClick event. - QMouseEvent *dblClick = static_cast<QMouseEvent *>(event); - QMouseEvent press(QEvent::MouseButtonPress, dblClick->localPos(), dblClick->windowPos(), dblClick->screenPos(), - dblClick->button(), dblClick->buttons(), dblClick->modifiers(), dblClick->source()); - press.setTimestamp(dblClick->timestamp()); - handled = m_client->forwardEvent(&press); - } else - handled = m_client->forwardEvent(event); - - if (!handled) - return QQuickWidget::event(event); - event->accept(); - return true; -} - -void RenderWidgetHostViewQtDelegateWidget::unhandledWheelEvent(QWheelEvent *ev) -{ - if (QWidget *p = parentWidget()) - qApp->sendEvent(p, ev); -} - -void RenderWidgetHostViewQtDelegateWidget::onWindowPosChanged() -{ - m_client->visualPropertiesChanged(); -} - -#if QT_CONFIG(accessibility) -RenderWidgetHostViewQtDelegateWidgetAccessible::RenderWidgetHostViewQtDelegateWidgetAccessible(RenderWidgetHostViewQtDelegateWidget *o, QWebEngineView *view) - : QAccessibleWidget(o) - , m_view(view) -{ -} - -bool RenderWidgetHostViewQtDelegateWidgetAccessible::isValid() const -{ - if (!viewAccessible() || !viewAccessible()->isValid()) - return false; - - return QAccessibleWidget::isValid(); -} - -QAccessibleInterface *RenderWidgetHostViewQtDelegateWidgetAccessible::focusChild() const -{ - return viewAccessible()->focusChild(); -} - -int RenderWidgetHostViewQtDelegateWidgetAccessible::childCount() const -{ - return viewAccessible()->childCount(); -} - -QAccessibleInterface *RenderWidgetHostViewQtDelegateWidgetAccessible::child(int index) const -{ - return viewAccessible()->child(index); -} - -int RenderWidgetHostViewQtDelegateWidgetAccessible::indexOfChild(const QAccessibleInterface *c) const -{ - return viewAccessible()->indexOfChild(c); -} - -QWebEngineViewAccessible *RenderWidgetHostViewQtDelegateWidgetAccessible::viewAccessible() const -{ - return static_cast<QWebEngineViewAccessible *>(QAccessible::queryAccessibleInterface(m_view)); -} -#endif // QT_CONFIG(accessibility) - -} // namespace QtWebEngineCore |