diff options
Diffstat (limited to 'src/plugins/platforms/offscreen')
-rw-r--r-- | src/plugins/platforms/offscreen/CMakeLists.txt | 13 | ||||
-rw-r--r-- | src/plugins/platforms/offscreen/main.cpp | 44 | ||||
-rw-r--r-- | src/plugins/platforms/offscreen/qoffscreencommon.cpp | 114 | ||||
-rw-r--r-- | src/plugins/platforms/offscreen/qoffscreencommon.h | 50 | ||||
-rw-r--r-- | src/plugins/platforms/offscreen/qoffscreenintegration.cpp | 262 | ||||
-rw-r--r-- | src/plugins/platforms/offscreen/qoffscreenintegration.h | 55 | ||||
-rw-r--r-- | src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp | 61 | ||||
-rw-r--r-- | src/plugins/platforms/offscreen/qoffscreenintegration_x11.h | 51 | ||||
-rw-r--r-- | src/plugins/platforms/offscreen/qoffscreenwindow.cpp | 64 | ||||
-rw-r--r-- | src/plugins/platforms/offscreen/qoffscreenwindow.h | 42 |
10 files changed, 334 insertions, 422 deletions
diff --git a/src/plugins/platforms/offscreen/CMakeLists.txt b/src/plugins/platforms/offscreen/CMakeLists.txt index bb73ce38aa..907c2c9cc6 100644 --- a/src/plugins/platforms/offscreen/CMakeLists.txt +++ b/src/plugins/platforms/offscreen/CMakeLists.txt @@ -1,4 +1,5 @@ -# Generated from offscreen.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## QOffscreenIntegrationPlugin Plugin: @@ -6,8 +7,8 @@ qt_internal_add_plugin(QOffscreenIntegrationPlugin OUTPUT_NAME qoffscreen - TYPE platforms - DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES offscreen # special case + PLUGIN_TYPE platforms + DEFAULT_IF "offscreen" IN_LIST QT_QPA_PLATFORMS SOURCES main.cpp qoffscreencommon.cpp qoffscreencommon.h @@ -22,9 +23,6 @@ qt_internal_add_plugin(QOffscreenIntegrationPlugin Qt::GuiPrivate ) -#### Keys ignored in scope 1:.:.:offscreen.pro:<TRUE>: -# OTHER_FILES = "offscreen.json" - ## Scopes: ##################################################################### @@ -34,6 +32,3 @@ qt_internal_extend_target(QOffscreenIntegrationPlugin CONDITION QT_FEATURE_openg LIBRARIES X11::X11 ) - -#### Keys ignored in scope 3:.:.:offscreen.pro:NOT TARGET___equals____ss_QT_DEFAULT_QPA_PLUGIN: -# PLUGIN_EXTENDS = "-" diff --git a/src/plugins/platforms/offscreen/main.cpp b/src/plugins/platforms/offscreen/main.cpp index 6b696ed073..4b5527cbde 100644 --- a/src/plugins/platforms/offscreen/main.cpp +++ b/src/plugins/platforms/offscreen/main.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include <qpa/qplatformintegrationplugin.h> @@ -43,6 +7,8 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + class QOffscreenIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT @@ -53,7 +19,7 @@ public: QPlatformIntegration *QOffscreenIntegrationPlugin::create(const QString& system, const QStringList& paramList) { - if (!system.compare(QLatin1String("offscreen"), Qt::CaseInsensitive)) + if (!system.compare("offscreen"_L1, Qt::CaseInsensitive)) return QOffscreenIntegration::createOffscreenIntegration(paramList); return nullptr; diff --git a/src/plugins/platforms/offscreen/qoffscreencommon.cpp b/src/plugins/platforms/offscreen/qoffscreencommon.cpp index 33b98cfa1b..923fffb29c 100644 --- a/src/plugins/platforms/offscreen/qoffscreencommon.cpp +++ b/src/plugins/platforms/offscreen/qoffscreencommon.cpp @@ -1,47 +1,12 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qoffscreencommon.h" #include "qoffscreenintegration.h" #include "qoffscreenwindow.h" +#include <QtGui/QPainter> #include <QtGui/private/qpixmap_raster_p.h> #include <QtGui/private/qguiapplication_p.h> @@ -55,7 +20,11 @@ QPlatformWindow *QOffscreenScreen::windowContainingCursor = nullptr; QList<QPlatformScreen *> QOffscreenScreen::virtualSiblings() const { - return m_integration->screens(); + QList<QPlatformScreen *> platformScreens; + for (auto screen : m_integration->screens()) { + platformScreens.append(screen); + } + return platformScreens; } class QOffscreenCursor : public QPlatformCursor @@ -112,22 +81,25 @@ QPixmap QOffscreenScreen::grabWindow(WId id, int x, int y, int width, int height { QRect rect(x, y, width, height); - QOffscreenWindow *window = QOffscreenWindow::windowForWinId(id); - if (!window || window->window()->type() == Qt::Desktop) { + // id == 0 -> grab the screen, so all windows intersecting rect + if (!id) { + if (width == -1) + rect.setWidth(m_geometry.width()); + if (height == -1) + rect.setHeight(m_geometry.height()); + QPixmap screenImage(rect.size()); + QPainter painter(&screenImage); + painter.translate(-x, -y); const QWindowList wl = QGuiApplication::topLevelWindows(); - QWindow *containing = nullptr; for (QWindow *w : wl) { - if (w->type() != Qt::Desktop && w->isExposed() && w->geometry().contains(rect)) { - containing = w; - break; + if (w->isExposed() && w->geometry().intersects(rect)) { + QOffscreenBackingStore *store = QOffscreenBackingStore::backingStoreForWinId(w->winId()); + const QImage windowImage = store ? store->toImage() : QImage(); + if (!windowImage.isNull()) + painter.drawImage(w->position(), windowImage); } } - - if (!containing) - return QPixmap(); - - id = containing->winId(); - rect = rect.translated(-containing->geometry().topLeft()); + return screenImage; } QOffscreenBackingStore *store = QOffscreenBackingStore::backingStoreForWinId(id); @@ -189,8 +161,8 @@ bool QOffscreenBackingStore::scroll(const QRegion &area, int dx, int dy) if (m_image.isNull()) return false; - for (const QRect &rect : area) - qt_scrollRectInImage(m_image, rect, QPoint(dx, dy)); + const QRect rect = area.boundingRect(); + qt_scrollRectInImage(m_image, rect, QPoint(dx, dy)); return true; } @@ -217,13 +189,13 @@ QPixmap QOffscreenBackingStore::grabWindow(WId window, const QRect &rect) const QOffscreenBackingStore *QOffscreenBackingStore::backingStoreForWinId(WId id) { - return m_backingStoreForWinIdHash.value(id, 0); + return m_backingStoreForWinIdHash.value(id, nullptr); } void QOffscreenBackingStore::clearHash() { for (auto it = m_windowAreaHash.cbegin(), end = m_windowAreaHash.cend(); it != end; ++it) { - const auto it2 = qAsConst(m_backingStoreForWinIdHash).find(it.key()); + const auto it2 = std::as_const(m_backingStoreForWinIdHash).find(it.key()); if (it2.value() == this) m_backingStoreForWinIdHash.erase(it2); } @@ -232,6 +204,38 @@ void QOffscreenBackingStore::clearHash() QHash<WId, QOffscreenBackingStore *> QOffscreenBackingStore::m_backingStoreForWinIdHash; +QOffscreenPlatformNativeInterface::QOffscreenPlatformNativeInterface(QOffscreenIntegration *integration) + : m_integration(integration) +{ + +} + QOffscreenPlatformNativeInterface::~QOffscreenPlatformNativeInterface() = default; +/* + Set platform configuration, e.g. screen configuration +*/ +void QOffscreenPlatformNativeInterface::setConfiguration(const QJsonObject &configuration, QOffscreenPlatformNativeInterface *iface) +{ + iface->m_integration->setConfiguration(configuration); +} + +/* + Get the current platform configuration +*/ +QJsonObject QOffscreenPlatformNativeInterface::configuration(QOffscreenPlatformNativeInterface *iface) +{ + return iface->m_integration->configuration(); +} + +void *QOffscreenPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource) +{ + if (resource == "setConfiguration") + return reinterpret_cast<void*>(&QOffscreenPlatformNativeInterface::setConfiguration); + else if (resource == "configuration") + return reinterpret_cast<void*>(&QOffscreenPlatformNativeInterface::configuration); + else + return nullptr; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/offscreen/qoffscreencommon.h b/src/plugins/platforms/offscreen/qoffscreencommon.h index 7f92c5b4d9..a3d6227168 100644 --- a/src/plugins/platforms/offscreen/qoffscreencommon.h +++ b/src/plugins/platforms/offscreen/qoffscreencommon.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QOFFSCREENCOMMON_H #define QOFFSCREENCOMMON_H @@ -51,6 +15,7 @@ #include <qscopedpointer.h> #include <qimage.h> +#include <qjsonobject.h> #include <qhash.h> QT_BEGIN_NAMESPACE @@ -105,6 +70,7 @@ public: bool scroll(const QRegion &area, int dx, int dy) override; QPixmap grabWindow(WId window, const QRect &rect) const; + QImage toImage() const override { return m_image; } static QOffscreenBackingStore *backingStoreForWinId(WId id); @@ -120,7 +86,15 @@ private: class QOffscreenPlatformNativeInterface : public QPlatformNativeInterface { public: + QOffscreenPlatformNativeInterface(QOffscreenIntegration *integration); ~QOffscreenPlatformNativeInterface(); + + static void setConfiguration(const QJsonObject &configuration, QOffscreenPlatformNativeInterface *iface); + static QJsonObject configuration(QOffscreenPlatformNativeInterface *iface); + + void *nativeResourceForIntegration(const QByteArray &resource) override; +private: + QOffscreenIntegration *m_integration; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp index 310e71ae13..ea8042928a 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qoffscreenintegration.h" #include "qoffscreenwindow.h" @@ -74,6 +38,8 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + class QCoreTextFontEngine; template <typename BaseEventDispatcher> @@ -93,7 +59,7 @@ public: } }; -QOffscreenIntegration::QOffscreenIntegration() +QOffscreenIntegration::QOffscreenIntegration(const QStringList& paramList) { #if defined(Q_OS_UNIX) #if defined(Q_OS_MAC) @@ -109,17 +75,24 @@ QOffscreenIntegration::QOffscreenIntegration() m_drag.reset(new QOffscreenDrag); #endif m_services.reset(new QPlatformServices); + + QJsonObject config = resolveConfigFileConfiguration(paramList).value_or(defaultConfiguration()); + setConfiguration(config); } QOffscreenIntegration::~QOffscreenIntegration() { - for (auto screen : std::as_const(m_screens)) - QWindowSystemInterface::handleScreenRemoved(screen); + while (!m_screens.isEmpty()) + QWindowSystemInterface::handleScreenRemoved(m_screens.takeLast()); } /* - The offscren platform plugin is configurable with a JSON configuration - file. Write the config to disk and pass the file path as a platform argument: + The offscren platform plugin is configurable with a JSON configuration. + The confiuration can be provided either from a file on disk on startup, + or at by calling setConfiguration(). + + To provide a configuration on startuip, write the config to disk and pass + the file path as a platform argument: ./myapp -platform offscreen:configfile=/path/to/config.json @@ -130,9 +103,9 @@ QOffscreenIntegration::~QOffscreenIntegration() "screens": [<screens>], } - Screen: + "screens" is an array of: { - "name" : string, + "name": string, "x": int, "y": int, "width": int, @@ -142,27 +115,41 @@ QOffscreenIntegration::~QOffscreenIntegration() "dpr": double, } */ -void QOffscreenIntegration::configure(const QStringList& paramList) + +QJsonObject QOffscreenIntegration::defaultConfiguration() const +{ + const auto defaultScreen = QJsonObject { + {"name", ""}, + {"x", 0}, + {"y", 0}, + {"width", 800}, + {"height", 800}, + {"logicalDpi", 96}, + {"logicalBaseDpi", 96}, + {"dpr", 1.0}, + }; + const auto defaultConfiguration = QJsonObject { + {"synchronousWindowSystemEvents", false}, + {"windowFrameMargins", true}, + {"screens", QJsonArray { defaultScreen } }, + }; + return defaultConfiguration; +} + +std::optional<QJsonObject> QOffscreenIntegration::resolveConfigFileConfiguration(const QStringList& paramList) const { - // Use config file configuring platform plugin, if one was specified bool hasConfigFile = false; QString configFilePath; for (const QString ¶m : paramList) { // Look for "configfile=/path/to/file/" - QString configPrefix(QLatin1String("configfile=")); + QString configPrefix("configfile="_L1); if (param.startsWith(configPrefix)) { hasConfigFile = true; - configFilePath= param.mid(configPrefix.length()); + configFilePath = param.mid(configPrefix.size()); } } - - // Create the default screen if there was no config file - if (!hasConfigFile) { - QOffscreenScreen *offscreenScreen = new QOffscreenScreen(this); - m_screens.append(offscreenScreen); - QWindowSystemInterface::handleScreenAdded(offscreenScreen); - return; - } + if (!hasConfigFile) + return std::nullopt; // Read config file if (configFilePath.isEmpty()) @@ -179,28 +166,145 @@ void QOffscreenIntegration::configure(const QStringList& paramList) if (config.isNull()) qFatal("Platform config file parse error: %s", qPrintable(error.errorString())); - // Apply configuration (create screens) - bool synchronousWindowSystemEvents = config["synchronousWindowSystemEvents"].toBool(false); + return config.object(); +} + + +void QOffscreenIntegration::setConfiguration(const QJsonObject &configuration) +{ + // Apply the new configuration, diffing against the current m_configuration + + const bool synchronousWindowSystemEvents = configuration["synchronousWindowSystemEvents"].toBool( + m_configuration["synchronousWindowSystemEvents"].toBool(false)); QWindowSystemInterface::setSynchronousWindowSystemEvents(synchronousWindowSystemEvents); - m_windowFrameMarginsEnabled = config["windowFrameMargins"].toBool(true); - QJsonArray screens = config["screens"].toArray(); - for (QJsonValue screenValue : screens) { - QJsonObject screen = screenValue.toObject(); - if (screen.isEmpty()) { - qWarning("QOffscreenIntegration::initializeWithPlatformArguments: empty screen object"); + + m_windowFrameMarginsEnabled = configuration["windowFrameMargins"].toBool( + m_configuration["windowFrameMargins"].toBool(true)); + + // Diff screens array, using the screen name as the screen identity. + QJsonArray currentScreens = m_configuration["screens"].toArray(); + QJsonArray newScreens = configuration["screens"].toArray(); + + auto getScreenNames = [](const QJsonArray &screens) -> QList<QString> { + QList<QString> names; + for (QJsonValue screen : screens) { + names.append(screen["name"].toString()); + }; + std::sort(names.begin(), names.end()); + return names; + }; + + auto currentNames = getScreenNames(currentScreens); + auto newNames = getScreenNames(newScreens); + + QList<QString> present; + std::set_intersection(currentNames.begin(), currentNames.end(), newNames.begin(), newNames.end(), + std::inserter(present, present.begin())); + QList<QString> added; + std::set_difference(newNames.begin(), newNames.end(), currentNames.begin(), currentNames.end(), + std::inserter(added, added.begin())); + QList<QString> removed; + std::set_difference(currentNames.begin(), currentNames.end(), newNames.begin(), newNames.end(), + std::inserter(removed, removed.begin())); + + auto platformScreenByName = [](const QString &name, QList<QOffscreenScreen *> screens) -> QOffscreenScreen * { + for (QOffscreenScreen *screen : screens) { + if (screen->m_name == name) + return screen; + } + Q_UNREACHABLE(); + }; + + auto screenConfigByName = [](const QString &name, QJsonArray screenConfigs) -> QJsonValue { + for (QJsonValue screenConfig : screenConfigs) { + if (screenConfig["name"].toString() == name) + return screenConfig; + } + Q_UNREACHABLE(); + }; + + auto geometryFromConfig = [](const QJsonObject &config) -> QRect { + return QRect(config["x"].toInt(0), config["y"].toInt(0), config["width"].toInt(640), config["height"].toInt(480)); + }; + + // Remove removed screens + for (const QString &remove : removed) { + QOffscreenScreen *screen = platformScreenByName(remove, m_screens); + m_screens.removeAll(screen); + QWindowSystemInterface::handleScreenRemoved(screen); + } + + // Add new screens + for (const QString &add : added) { + QJsonValue configValue = screenConfigByName(add, newScreens); + QJsonObject config = configValue.toObject(); + if (config.isEmpty()) { + qWarning("empty screen object"); continue; } QOffscreenScreen *offscreenScreen = new QOffscreenScreen(this); - offscreenScreen->m_name = screen["name"].toString(); - offscreenScreen->m_geometry = QRect(screen["x"].toInt(0), screen["y"].toInt(0), - screen["width"].toInt(640), screen["height"].toInt(480)); - offscreenScreen->m_logicalDpi = screen["logicalDpi"].toInt(96); - offscreenScreen->m_logicalBaseDpi = screen["logicalBaseDpi"].toInt(96); - offscreenScreen->m_dpr = screen["dpr"].toDouble(1.0); - + offscreenScreen->m_name = config["name"].toString(); + offscreenScreen->m_geometry = geometryFromConfig(config); + offscreenScreen->m_logicalDpi = config["logicalDpi"].toInt(96); + offscreenScreen->m_logicalBaseDpi = config["logicalBaseDpi"].toInt(96); + offscreenScreen->m_dpr = config["dpr"].toDouble(1.0); m_screens.append(offscreenScreen); QWindowSystemInterface::handleScreenAdded(offscreenScreen); } + + // Update present screens + for (const QString &pres : present) { + QOffscreenScreen *screen = platformScreenByName(pres, m_screens); + Q_ASSERT(screen); + QJsonObject currentConfig = screenConfigByName(pres, currentScreens).toObject(); + QJsonObject newConfig = screenConfigByName(pres, newScreens).toObject(); + + // Name can't change, because it'd be a different screen + Q_ASSERT(currentConfig["name"] == newConfig["name"]); + + // Geometry + QRect currentGeomtry = geometryFromConfig(currentConfig); + QRect newGeomtry = geometryFromConfig(newConfig); + if (currentGeomtry != newGeomtry) { + screen->m_geometry = newGeomtry; + QWindowSystemInterface::handleScreenGeometryChange(screen->screen(), newGeomtry, newGeomtry); + } + + // logical DPI + int currentLogicalDpi = currentConfig["logicalDpi"].toInt(96); + int newLogicalDpi = newConfig["logicalDpi"].toInt(96); + if (currentLogicalDpi != newLogicalDpi) { + screen->m_logicalDpi = newLogicalDpi; + QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen->screen(), newLogicalDpi, newLogicalDpi); + } + + // The base DPI is more of a platform constant, and should not change, and + // there is no handleChange function for it. Print a warning. + int currentLogicalBaseDpi = currentConfig["logicalBaseDpi"].toInt(96); + int newLogicalBaseDpi = newConfig["logicalBaseDpi"].toInt(96); + if (currentLogicalBaseDpi != newLogicalBaseDpi) { + screen->m_logicalBaseDpi = newLogicalBaseDpi; + qWarning("You ain't supposed to change logicalBaseDpi - its a platform constant. Qt may not react to the change"); + } + + // DPR. There is also no handleChange function in Qt at this point, instead + // the new DPR value will be used during the next repaint. We could repaint + // all windows here, but don't. Print a warning. + double currentDpr = currentConfig["dpr"].toDouble(1); + double newDpr = newConfig["dpr"].toDouble(1); + if (currentDpr != newDpr) { + screen->m_dpr = newDpr; + qWarning("DPR change notifications is not implemented - Qt may not react to the change"); + } + } + + // Now the new configuration is the current configuration + m_configuration = configuration; +} + +QJsonObject QOffscreenIntegration::configuration() const +{ + return m_configuration; } void QOffscreenIntegration::initialize() @@ -250,7 +354,7 @@ QAbstractEventDispatcher *QOffscreenIntegration::createEventDispatcher() const QPlatformNativeInterface *QOffscreenIntegration::nativeInterface() const { if (!m_nativeInterface) - m_nativeInterface.reset(new QOffscreenPlatformNativeInterface); + m_nativeInterface.reset(new QOffscreenPlatformNativeInterface(const_cast<QOffscreenIntegration*>(this))); return m_nativeInterface.get(); } @@ -281,8 +385,8 @@ public: virtual const QFont *font(Font type = SystemFont) const override { - static QFont systemFont(QLatin1String("Sans Serif"), 9); - static QFont fixedFont(QLatin1String("monospace"), 9); + static QFont systemFont("Sans Serif"_L1, 9); + static QFont fixedFont("monospace"_L1, 9); switch (type) { case QPlatformTheme::SystemFont: return &systemFont; @@ -323,17 +427,15 @@ QOffscreenIntegration *QOffscreenIntegration::createOffscreenIntegration(const Q #if QT_CONFIG(xlib) && QT_CONFIG(opengl) && !QT_CONFIG(opengles2) QByteArray glx = qgetenv("QT_QPA_OFFSCREEN_NO_GLX"); if (glx.isEmpty()) - offscreenIntegration = new QOffscreenX11Integration; + offscreenIntegration = new QOffscreenX11Integration(paramList); #endif if (!offscreenIntegration) - offscreenIntegration = new QOffscreenIntegration; - - offscreenIntegration->configure(paramList); + offscreenIntegration = new QOffscreenIntegration(paramList); return offscreenIntegration; } -QList<QPlatformScreen *> QOffscreenIntegration::screens() const +QList<QOffscreenScreen *> QOffscreenIntegration::screens() const { return m_screens; } diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.h b/src/plugins/platforms/offscreen/qoffscreenintegration.h index 38d145eee3..aab8d305b4 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QOFFSCREENINTEGRATION_H #define QOFFSCREENINTEGRATION_H @@ -44,18 +8,24 @@ #include <qpa/qplatformnativeinterface.h> #include <qscopedpointer.h> +#include <qjsonobject.h> QT_BEGIN_NAMESPACE class QOffscreenBackendData; +class QOffscreenScreen; class QOffscreenIntegration : public QPlatformIntegration { public: - QOffscreenIntegration(); + QOffscreenIntegration(const QStringList& paramList); ~QOffscreenIntegration(); - void configure(const QStringList& paramList); + QJsonObject defaultConfiguration() const; + std::optional<QJsonObject> resolveConfigFileConfiguration(const QStringList& paramList) const; + void setConfiguration(const QJsonObject &configuration); + QJsonObject configuration() const; + void initialize() override; bool hasCapability(QPlatformIntegration::Capability cap) const override; @@ -78,7 +48,7 @@ public: static QOffscreenIntegration *createOffscreenIntegration(const QStringList& paramList); - QList<QPlatformScreen *> screens() const; + QList<QOffscreenScreen *> screens() const; protected: QScopedPointer<QPlatformFontDatabase> m_fontDatabase; #if QT_CONFIG(draganddrop) @@ -87,8 +57,9 @@ protected: QScopedPointer<QPlatformInputContext> m_inputContext; QScopedPointer<QPlatformServices> m_services; mutable QScopedPointer<QPlatformNativeInterface> m_nativeInterface; - QList<QPlatformScreen *> m_screens; + QList<QOffscreenScreen *> m_screens; bool m_windowFrameMarginsEnabled = true; + QJsonObject m_configuration; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp index 1e533f87dc..fbee6667ea 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qoffscreenintegration_x11.h" @@ -76,6 +40,12 @@ private: QOffscreenX11Connection *m_connection; }; +QOffscreenX11Integration::QOffscreenX11Integration(const QStringList& paramList) +: QOffscreenIntegration(paramList) +{ + +} + QOffscreenX11Integration::~QOffscreenX11Integration() = default; bool QOffscreenX11Integration::hasCapability(QPlatformIntegration::Capability cap) const @@ -106,10 +76,16 @@ QPlatformOpenGLContext *QOffscreenX11Integration::createPlatformOpenGLContext(QO QOffscreenX11PlatformNativeInterface *QOffscreenX11Integration::nativeInterface() const { if (!m_nativeInterface) - m_nativeInterface.reset(new QOffscreenX11PlatformNativeInterface); + m_nativeInterface.reset(new QOffscreenX11PlatformNativeInterface(const_cast<QOffscreenX11Integration *>(this))); return static_cast<QOffscreenX11PlatformNativeInterface *>(m_nativeInterface.data()); } +QOffscreenX11PlatformNativeInterface::QOffscreenX11PlatformNativeInterface(QOffscreenIntegration *integration) +:QOffscreenPlatformNativeInterface(integration) +{ + +} + QOffscreenX11PlatformNativeInterface::~QOffscreenX11PlatformNativeInterface() = default; void *QOffscreenX11PlatformNativeInterface::nativeResourceForScreen(const QByteArray &resource, QScreen *screen) @@ -143,6 +119,13 @@ void *QOffscreenX11PlatformNativeInterface::nativeResourceForContext(const QByte } #endif +#if QT_CONFIG(xcb) +Display *QOffscreenX11PlatformNativeInterface::display() const +{ + return m_connection ? reinterpret_cast<Display *>(m_connection->display()) : nullptr; +} +#endif + QOffscreenX11Connection::QOffscreenX11Connection() { XInitThreads(); diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h index 7e26b76759..d7b5120332 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QOFFSCREENINTEGRATION_X11_H #define QOFFSCREENINTEGRATION_X11_H @@ -47,6 +11,7 @@ #include <qscopedpointer.h> #include <qpa/qplatformopenglcontext.h> +#include <QtGui/qguiapplication.h> QT_BEGIN_NAMESPACE @@ -54,21 +19,29 @@ class QOffscreenX11Connection; class QOffscreenX11Info; class QOffscreenX11PlatformNativeInterface : public QOffscreenPlatformNativeInterface +#if QT_CONFIG(xcb) + , public QNativeInterface::QX11Application +#endif { public: + QOffscreenX11PlatformNativeInterface(QOffscreenIntegration *integration); ~QOffscreenX11PlatformNativeInterface(); void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) override; #if !defined(QT_NO_OPENGL) && QT_CONFIG(xcb_glx_plugin) void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override; #endif - +#if QT_CONFIG(xcb) + Display *display() const override; + xcb_connection_t *connection() const override { return nullptr; }; +#endif QScopedPointer<QOffscreenX11Connection> m_connection; }; class QOffscreenX11Integration : public QOffscreenIntegration { public: + QOffscreenX11Integration(const QStringList& paramList); ~QOffscreenX11Integration(); bool hasCapability(QPlatformIntegration::Capability cap) const override; diff --git a/src/plugins/platforms/offscreen/qoffscreenwindow.cpp b/src/plugins/platforms/offscreen/qoffscreenwindow.cpp index a46258a401..1a1471c687 100644 --- a/src/plugins/platforms/offscreen/qoffscreenwindow.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenwindow.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qoffscreenwindow.h" #include "qoffscreencommon.h" @@ -44,6 +8,7 @@ #include <qpa/qwindowsysteminterface.h> #include <private/qwindow_p.h> +#include <private/qguiapplication_p.h> QT_BEGIN_NAMESPACE @@ -121,7 +86,7 @@ void QOffscreenWindow::setVisible(bool visible) if (visible) { if (window()->type() != Qt::ToolTip) - QWindowSystemInterface::handleWindowActivated(window()); + QWindowSystemInterface::handleFocusWindowChanged(window(), Qt::ActiveWindowFocusReason); if (m_pendingGeometryChangeOnShow) { m_pendingGeometryChangeOnShow = false; @@ -129,11 +94,26 @@ void QOffscreenWindow::setVisible(bool visible) } } + const QPoint cursorPos = QCursor::pos(); if (visible) { QRect rect(QPoint(), geometry().size()); QWindowSystemInterface::handleExposeEvent(window(), rect); + if (QWindowPrivate::get(window())->isPopup() && QGuiApplicationPrivate::currentMouseWindow) { + QWindowSystemInterface::handleLeaveEvent<QWindowSystemInterface::SynchronousDelivery> + (QGuiApplicationPrivate::currentMouseWindow); + } + if (geometry().contains(cursorPos)) + QWindowSystemInterface::handleEnterEvent(window(), + window()->mapFromGlobal(cursorPos), cursorPos); } else { QWindowSystemInterface::handleExposeEvent(window(), QRegion()); + if (window()->type() & Qt::Window) { + if (QWindow *windowUnderMouse = QGuiApplication::topLevelAt(cursorPos)) { + QWindowSystemInterface::handleEnterEvent(windowUnderMouse, + windowUnderMouse->mapFromGlobal(cursorPos), + cursorPos); + } + } } m_visible = visible; @@ -142,7 +122,7 @@ void QOffscreenWindow::setVisible(bool visible) void QOffscreenWindow::requestActivateWindow() { if (m_visible) - QWindowSystemInterface::handleWindowActivated(window()); + QWindowSystemInterface::handleFocusWindowChanged(window(), Qt::ActiveWindowFocusReason); } WId QOffscreenWindow::winId() const @@ -185,9 +165,9 @@ void QOffscreenWindow::setWindowState(Qt::WindowStates state) QOffscreenWindow *QOffscreenWindow::windowForWinId(WId id) { - return m_windowForWinIdHash.value(id, 0); + return m_windowForWinIdHash.value(id, nullptr); } -QHash<WId, QOffscreenWindow *> QOffscreenWindow::m_windowForWinIdHash; +Q_CONSTINIT QHash<WId, QOffscreenWindow *> QOffscreenWindow::m_windowForWinIdHash; QT_END_NAMESPACE diff --git a/src/plugins/platforms/offscreen/qoffscreenwindow.h b/src/plugins/platforms/offscreen/qoffscreenwindow.h index 32b8ca33cb..d525f2c657 100644 --- a/src/plugins/platforms/offscreen/qoffscreenwindow.h +++ b/src/plugins/platforms/offscreen/qoffscreenwindow.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins 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$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QOFFSCREENWINDOW_H #define QOFFSCREENWINDOW_H @@ -77,7 +41,7 @@ private: bool m_frameMarginsRequested; WId m_winId; - static QHash<WId, QOffscreenWindow *> m_windowForWinIdHash; + Q_CONSTINIT static QHash<WId, QOffscreenWindow *> m_windowForWinIdHash; }; QT_END_NAMESPACE |