Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwaylandintegration.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
13#if QT_CONFIG(clipboard)
14#include "qwaylandclipboard_p.h"
15#endif
16#include "qwaylanddnd_p.h"
21
22#if defined(Q_OS_MACOS)
23# include <QtGui/private/qcoretextfontdatabase_p.h>
24# include <QtGui/private/qfontengine_coretext_p.h>
25#else
26# include <QtGui/private/qgenericunixfontdatabase_p.h>
27#endif
28#include <QtGui/private/qgenericunixeventdispatcher_p.h>
29#if __has_include(<QtGui/private/qgenericunixtheme_p.h>)
30#include <QtGui/private/qgenericunixtheme_p.h>
31#else
32#include <QtGui/private/qgenericunixthemes_p.h>
33#endif
34
35#include <QtGui/private/qguiapplication_p.h>
36
37#include <qpa/qwindowsysteminterface.h>
38#include <qpa/qplatformcursor.h>
39#include <QtGui/QSurfaceFormat>
40#if QT_CONFIG(opengl)
41#include <QtGui/QOpenGLContext>
42#endif // QT_CONFIG(opengl)
43#include <QSocketNotifier>
44
45#include <qpa/qplatforminputcontextfactory_p.h>
46#include <qpa/qplatformaccessibility.h>
47#include <qpa/qplatforminputcontext.h>
48
52
56
59
63
64#include <QtWaylandClient/private/qwayland-xdg-system-bell-v1.h>
65
66#if QT_CONFIG(accessibility_atspi_bridge)
67#include <QtGui/private/qspiaccessiblebridge_p.h>
68#endif
69
70#if QT_CONFIG(xkbcommon)
71#include <QtGui/private/qxkbcommon_p.h>
72#endif
73
74#if QT_CONFIG(vulkan)
75#include "qwaylandvulkaninstance_p.h"
76#include "qwaylandvulkanwindow_p.h"
77#endif
78
80
81using namespace Qt::StringLiterals;
82
83namespace QtWaylandClient {
84
86
104
109
111{
112 return mDisplay->initialize();
113}
114
119
121{
122 switch (cap) {
123 case ThreadedPixmaps: return true;
124 case OpenGL:
126 case ThreadedOpenGL:
129 return true;
130 case MultipleWindows:
132 return true;
133 case RasterGLSurface:
134 return true;
135 case WindowActivation:
136 return true;
137 case ScreenWindowGrabbing: // whether QScreen::grabWindow() is supported
138 return false;
139 default: return QPlatformIntegration::hasCapability(cap);
140 }
141}
142
156
157#if QT_CONFIG(opengl)
159{
162 return nullptr;
163}
164#endif // opengl
165
170
175
180
181// Support platform specific initialization
183{
185
188#if QT_CONFIG(clipboard)
190#endif
191#if QT_CONFIG(draganddrop)
193#endif
194
196}
197
199{
201
202 // Call this after initializing event thread for QWaylandDisplay::flushRequests()
206
207 // Qt does not support running with no screens
209}
210
215
216#if QT_CONFIG(clipboard)
218{
219 return mClipboard.data();
220}
221#endif
222
223#if QT_CONFIG(draganddrop)
225{
226 return mDrag.data();
227}
228#endif // draganddrop
229
234
242
243#if QT_CONFIG(accessibility)
245{
246 if (!mAccessibility) {
247#if QT_CONFIG(accessibility_atspi_bridge)
248 Q_ASSERT_X(QCoreApplication::eventDispatcher(), "QWaylandIntegration",
249 "Initializing accessibility without event-dispatcher!");
251#else
253#endif
254 }
255 return mAccessibility.data();
256}
257#endif
258
263
265{
266 return mDisplay.data();
267}
268
270{
271 if (auto *seat = mDisplay->currentInputDevice(); seat && seat->keyboardFocus()) {
272 return seat->modifiers();
273 }
274 return Qt::NoModifier;
275}
276
278{
279 if (auto *seat = mDisplay->currentInputDevice())
280 return seat->possibleKeys(event);
281 return {};
282}
283
288
293
298
303
304#if QT_CONFIG(vulkan)
306{
308}
309#endif // QT_CONFIG(vulkan)
310
311// May be called from non-GUI threads
321
329
337
338// May be called from non-GUI threads
340{
343 return;
344
345 QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION"));
346 if (mPlatformName == "wayland-egl"_L1)
347 targetKey = "wayland-egl"_L1;
348 else if (mPlatformName == "wayland-brcm"_L1)
349 targetKey = "brcm"_L1;
350
351 if (targetKey.isEmpty()) {
353 && mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("wayland-eglstream-controller")
354 && mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("linux-dmabuf-unstable-v1")) {
356 } else {
357 targetKey = QLatin1String("wayland-egl");
358 }
359 }
360
361 if (targetKey.isEmpty()) {
362 qWarning("Failed to determine what client buffer integration to use");
363 } else {
365 qCDebug(lcQpaWayland) << "Available client buffer integrations:" << keys;
366
369
371 qCDebug(lcQpaWayland) << "Initializing client buffer integration" << targetKey;
373 } else {
374 qCWarning(lcQpaWayland) << "Failed to load client buffer integration:" << targetKey;
375 qCWarning(lcQpaWayland) << "Available client buffer integrations:" << keys;
376 }
377 }
378
379 // This must be set last to make sure other threads don't use the
380 // integration before initialization is complete.
382}
383
385{
387
388 QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION"));
389
392
393 if (targetKey.isEmpty()) {
394 qWarning("Failed to determine what server buffer integration to use");
395 return;
396 }
397
399 qCDebug(lcQpaWayland) << "Available server buffer integrations:" << keys;
400
403
405 qCDebug(lcQpaWayland) << "Initializing server buffer integration" << targetKey;
407 } else {
408 qCWarning(lcQpaWayland) << "Failed to load server buffer integration: " << targetKey;
409 qCWarning(lcQpaWayland) << "Available server buffer integrations:" << keys;
410 }
411}
412
414{
416
417 QByteArray integrationNames = qgetenv("QT_WAYLAND_SHELL_INTEGRATION");
419
421 if (!targetKeys.isEmpty()) {
423 } else {
424 preferredShells << QLatin1String("xdg-shell");
425 preferredShells << QLatin1String("wl-shell") << QLatin1String("ivi-shell");
426 preferredShells << QLatin1String("qt-shell");
427 }
428
431 if (mShellIntegration) {
432 qCDebug(lcQpaWayland, "Using the '%s' shell integration", qPrintable(preferredShell));
433 break;
434 }
435 }
436
437 if (!mShellIntegration) {
438 qCWarning(lcQpaWayland) << "Loading shell integration failed.";
439 qCWarning(lcQpaWayland) << "Attempted to load the following shells" << preferredShells;
440 }
441
443}
444
452
454{
455 QByteArray integrationName = qgetenv("QT_WAYLAND_INPUTDEVICE_INTEGRATION");
457
458 if (targetKey.isEmpty()) {
459 return;
460 }
461
463 if (keys.contains(targetKey)) {
465 qDebug("Using the '%s' input device integration", qPrintable(targetKey));
466 } else {
467 qWarning("Wayland inputdevice integration '%s' not found, using default", qPrintable(targetKey));
468 }
469}
470
472{
473 if (!mDisplay) {
474 // This function can be called from QWaylandDisplay::registry_global() when we
475 // are in process of constructing QWaylandDisplay. Configuring input context
476 // in that case is done by calling reconfigureInputContext() from QWaylandIntegration
477 // constructor, after QWaylandDisplay has been constructed.
478 return;
479 }
480
482 if (requested.contains(QLatin1String("qtvirtualkeyboard")))
483 qCWarning(lcQpaWayland) << "qtvirtualkeyboard currently is not supported at client-side,"
484 " use QT_IM_MODULES=qtvirtualkeyboard at compositor-side.";
485
489
493
494 for (const QString &imKey : requested) {
497 if (mDisplay->textInputMethodManager() != nullptr)
499 else if (mDisplay->textInputManagerv1() != nullptr
500 || mDisplay->textInputManagerv2() != nullptr
501 || mDisplay->textInputManagerv3() != nullptr)
503 } else {
505 }
506
508 break;
509 }
510
511#if QT_CONFIG(xkbcommon)
515 }
516#endif
517
518 qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>");
519}
520
522{
525 } else {
526 qCWarning(lcQpaWayland) << "No shell integration named" << integrationName << "found";
527 return nullptr;
528 }
529}
530
541
546
548{
549 if (auto bell = mDisplay->systemBell()) {
550 bell->ring(nullptr);
551 }
552}
553
554}
555
556QT_END_NAMESPACE
Combined button and popup list for selecting options.
#define __has_include(x)
#define WAYLAND_IM_KEY