diff options
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbintegration.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbintegration.cpp | 162 |
1 files changed, 91 insertions, 71 deletions
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 5dd6fbe57a..4dafae31e3 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.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 "qxcbintegration.h" #include "qxcbconnection.h" @@ -56,14 +20,12 @@ #ifndef QT_NO_SESSIONMANAGER #include "qxcbsessionmanager.h" #endif +#include "qxcbxsettings.h" #include <xcb/xcb.h> #include <QtGui/private/qgenericunixfontdatabase_p.h> #include <QtGui/private/qgenericunixservices_p.h> -#if QT_CONFIG(opengl) -#include <QtOpenGL/qpa/qplatformbackingstoreopenglsupport.h> -#endif #include <stdio.h> @@ -87,9 +49,9 @@ #include <QtGui/QOpenGLContext> #include <QtGui/QScreen> #include <QtGui/QOffscreenSurface> -#ifndef QT_NO_ACCESSIBILITY +#if QT_CONFIG(accessibility) #include <qpa/qplatformaccessibility.h> -#ifndef QT_NO_ACCESSIBILITY_ATSPI_BRIDGE +#if QT_CONFIG(accessibility_atspi_bridge) #include <QtGui/private/qspiaccessiblebridge_p.h> #endif #endif @@ -103,16 +65,18 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + // Find out if our parent process is gdb by looking at the 'exe' symlink under /proc,. // or, for older Linuxes, read out 'cmdline'. static bool runningUnderDebugger() { #if defined(QT_DEBUG) && defined(Q_OS_LINUX) - const QString parentProc = QLatin1String("/proc/") + QString::number(getppid()); - const QFileInfo parentProcExe(parentProc + QLatin1String("/exe")); + const QString parentProc = "/proc/"_L1 + QString::number(getppid()); + const QFileInfo parentProcExe(parentProc + "/exe"_L1); if (parentProcExe.isSymLink()) - return parentProcExe.symLinkTarget().endsWith(QLatin1String("/gdb")); - QFile f(parentProc + QLatin1String("/cmdline")); + return parentProcExe.symLinkTarget().endsWith("/gdb"_L1); + QFile f(parentProc + "/cmdline"_L1); if (!f.open(QIODevice::ReadOnly)) return false; QByteArray s; @@ -129,10 +93,17 @@ static bool runningUnderDebugger() #endif } +class QXcbUnixServices : public QGenericUnixServices +{ +public: + QString portalWindowIdentifier(QWindow *window) override; +}; + + QXcbIntegration *QXcbIntegration::m_instance = nullptr; QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char **argv) - : m_services(new QGenericUnixServices) + : m_services(new QXcbUnixServices) , m_instanceName(nullptr) , m_canGrab(true) , m_defaultVisualId(UINT_MAX) @@ -180,7 +151,7 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char bool underDebugger = runningUnderDebugger(); if (noGrabArg && doGrabArg && underDebugger) { - qWarning("Both -nograb and -dograb command line arguments specified. Please pick one. -nograb takes prcedence"); + qWarning("Both -nograb and -dograb command line arguments specified. Please pick one. -nograb takes precedence"); doGrabArg = false; } @@ -233,7 +204,7 @@ QPlatformPixmap *QXcbIntegration::createPlatformPixmap(QPlatformPixmap::PixelTyp QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const { QXcbGlIntegration *glIntegration = nullptr; - const bool isTrayIconWindow = QXcbWindow::isTrayIconWindow(window);; + const bool isTrayIconWindow = QXcbWindow::isTrayIconWindow(window); if (window->type() != Qt::Desktop && !isTrayIconWindow) { if (window->supportsOpenGL()) { glIntegration = connection()->glIntegration(); @@ -274,19 +245,21 @@ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLCont return glIntegration->createPlatformOpenGLContext(context); } +# if QT_CONFIG(xcb_glx_plugin) QOpenGLContext *QXcbIntegration::createOpenGLContext(GLXContext context, void *visualInfo, QOpenGLContext *shareContext) const { - using namespace QPlatformInterface::Private; + using namespace QNativeInterface::Private; if (auto *glxIntegration = dynamic_cast<QGLXIntegration*>(m_connection->glIntegration())) return glxIntegration->createOpenGLContext(context, visualInfo, shareContext); else return nullptr; } +# endif #if QT_CONFIG(egl) QOpenGLContext *QXcbIntegration::createOpenGLContext(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext) const { - using namespace QPlatformInterface::Private; + using namespace QNativeInterface::Private; if (auto *eglIntegration = dynamic_cast<QEGLIntegration*>(m_connection->glIntegration())) return eglIntegration->createOpenGLContext(context, display, shareContext); else @@ -359,19 +332,38 @@ QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const return QXcbEventDispatcher::createEventDispatcher(connection()); } +using namespace Qt::Literals::StringLiterals; +static const auto xsNetCursorBlink = "Net/CursorBlink"_ba; +static const auto xsNetCursorBlinkTime = "Net/CursorBlinkTime"_ba; +static const auto xsNetDoubleClickTime = "Net/DoubleClickTime"_ba; +static const auto xsNetDoubleClickDistance = "Net/DoubleClickDistance"_ba; +static const auto xsNetDndDragThreshold = "Net/DndDragThreshold"_ba; + void QXcbIntegration::initialize() { - const QLatin1String defaultInputContext("compose"); + const auto defaultInputContext = "compose"_L1; // Perform everything that may potentially need the event dispatcher (timers, socket // notifiers) here instead of the constructor. - QString icStr = QPlatformInputContextFactory::requested(); - if (icStr.isNull()) - icStr = defaultInputContext; - m_inputContext.reset(QPlatformInputContextFactory::create(icStr)); - if (!m_inputContext && icStr != defaultInputContext && icStr != QLatin1String("none")) + auto icStrs = QPlatformInputContextFactory::requested(); + if (icStrs.isEmpty()) + icStrs = { defaultInputContext }; + m_inputContext.reset(QPlatformInputContextFactory::create(icStrs)); + if (!m_inputContext && !icStrs.contains(defaultInputContext) + && icStrs != QStringList{"none"_L1}) m_inputContext.reset(QPlatformInputContextFactory::create(defaultInputContext)); connection()->keyboard()->initialize(); + + auto notifyThemeChanged = [](QXcbVirtualDesktop *, const QByteArray &, const QVariant &, void *) { + QWindowSystemInterface::handleThemeChange(); + }; + + auto *xsettings = connection()->primaryScreen()->xSettings(); + xsettings->registerCallbackForProperty(xsNetCursorBlink, notifyThemeChanged, this); + xsettings->registerCallbackForProperty(xsNetCursorBlinkTime, notifyThemeChanged, this); + xsettings->registerCallbackForProperty(xsNetDoubleClickTime, notifyThemeChanged, this); + xsettings->registerCallbackForProperty(xsNetDoubleClickDistance, notifyThemeChanged, this); + xsettings->registerCallbackForProperty(xsNetDndDragThreshold, notifyThemeChanged, this); } void QXcbIntegration::moveToScreen(QWindow *window, int screen) @@ -418,7 +410,7 @@ QPlatformInputContext *QXcbIntegration::inputContext() const return m_inputContext.data(); } -#ifndef QT_NO_ACCESSIBILITY +#if QT_CONFIG(accessibility) QPlatformAccessibility *QXcbIntegration::accessibility() const { #if !defined(QT_NO_ACCESSIBILITY_ATSPI_BRIDGE) @@ -438,14 +430,9 @@ QPlatformServices *QXcbIntegration::services() const return m_services.data(); } -Qt::KeyboardModifiers QXcbIntegration::queryKeyboardModifiers() const +QPlatformKeyMapper *QXcbIntegration::keyMapper() const { - return m_connection->queryKeyboardModifiers(); -} - -QList<int> QXcbIntegration::possibleKeys(const QKeyEvent *e) const -{ - return m_connection->keyboard()->possibleKeys(e); + return m_connection->keyboard(); } QStringList QXcbIntegration::themeNames() const @@ -458,31 +445,53 @@ QPlatformTheme *QXcbIntegration::createPlatformTheme(const QString &name) const return QGenericUnixTheme::createUnixTheme(name); } +#define RETURN_VALID_XSETTINGS(key) { \ + auto value = connection()->primaryScreen()->xSettings()->setting(key); \ + if (value.isValid()) return value; \ +} + QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const { switch (hint) { - case QPlatformIntegration::CursorFlashTime: - case QPlatformIntegration::KeyboardInputInterval: + case QPlatformIntegration::CursorFlashTime: { + bool ok = false; + // If cursor blinking is off, returns 0 to keep the cursor awlays display. + if (connection()->primaryScreen()->xSettings()->setting(xsNetCursorBlink).toInt(&ok) == 0 && ok) + return 0; + + RETURN_VALID_XSETTINGS(xsNetCursorBlinkTime); + break; + } case QPlatformIntegration::MouseDoubleClickInterval: + RETURN_VALID_XSETTINGS(xsNetDoubleClickTime); + break; + case QPlatformIntegration::MouseDoubleClickDistance: + RETURN_VALID_XSETTINGS(xsNetDoubleClickDistance); + break; + case QPlatformIntegration::KeyboardInputInterval: case QPlatformIntegration::StartDragTime: case QPlatformIntegration::KeyboardAutoRepeatRate: case QPlatformIntegration::PasswordMaskDelay: case QPlatformIntegration::StartDragVelocity: case QPlatformIntegration::UseRtlExtensions: case QPlatformIntegration::PasswordMaskCharacter: + case QPlatformIntegration::FlickMaximumVelocity: + case QPlatformIntegration::FlickDeceleration: // TODO using various xcb, gnome or KDE settings break; // Not implemented, use defaults + case QPlatformIntegration::FlickStartDistance: case QPlatformIntegration::StartDragDistance: { + RETURN_VALID_XSETTINGS(xsNetDndDragThreshold); // The default (in QPlatformTheme::defaultThemeHint) is 10 pixels, but // on a high-resolution screen it makes sense to increase it. - qreal dpi = 100.0; + qreal dpi = 100; if (const QXcbScreen *screen = connection()->primaryScreen()) { if (screen->logicalDpi().first > dpi) dpi = screen->logicalDpi().first; if (screen->logicalDpi().second > dpi) dpi = screen->logicalDpi().second; } - return 10.0 * dpi / 100.0; + return (hint == QPlatformIntegration::FlickStartDistance ? qreal(15) : qreal(10)) * dpi / qreal(100); } case QPlatformIntegration::ShowIsFullScreen: // X11 always has support for windows, but the @@ -502,7 +511,7 @@ static QString argv0BaseName() const QStringList arguments = QCoreApplication::arguments(); if (!arguments.isEmpty() && !arguments.front().isEmpty()) { result = arguments.front(); - const int lastSlashPos = result.lastIndexOf(QLatin1Char('/')); + const int lastSlashPos = result.lastIndexOf(u'/'); if (lastSlashPos != -1) result.remove(0, lastSlashPos + 1); } @@ -581,4 +590,15 @@ QPlatformVulkanInstance *QXcbIntegration::createPlatformVulkanInstance(QVulkanIn } #endif +void QXcbIntegration::setApplicationBadge(qint64 number) +{ + auto unixServices = dynamic_cast<QGenericUnixServices *>(services()); + unixServices->setApplicationBadge(number); +} + +QString QXcbUnixServices::portalWindowIdentifier(QWindow *window) +{ + return "x11:"_L1 + QString::number(window->winId(), 16); +} + QT_END_NAMESPACE |