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// Qt-Security score:significant reason:default
4
6
14#if QT_CONFIG(clipboard)
15#include "qwaylandclipboard_p.h"
16#endif
17#include "qwaylanddnd_p.h"
22
23#if defined(Q_OS_MACOS)
24# include <QtGui/private/qcoretextfontdatabase_p.h>
25# include <QtGui/private/qfontengine_coretext_p.h>
26#else
27# include <QtGui/private/qgenericunixfontdatabase_p.h>
28#endif
29#include <QtGui/private/qgenericunixeventdispatcher_p.h>
30#include <QtGui/private/qgenericunixtheme_p.h>
31
32#include <QtGui/private/qguiapplication_p.h>
33
34#include <qpa/qwindowsysteminterface.h>
35#include <qpa/qplatformcursor.h>
36#include <QtGui/QSurfaceFormat>
37#if QT_CONFIG(opengl)
38#include <QtGui/QOpenGLContext>
39#endif // QT_CONFIG(opengl)
40#include <QSocketNotifier>
41
42#include <qpa/qplatforminputcontextfactory_p.h>
43#include <qpa/qplatformaccessibility.h>
44#include <qpa/qplatforminputcontext.h>
45
49
53
56
61
62#include <QtWaylandClient/private/qwayland-xdg-system-bell-v1.h>
63
64#if QT_CONFIG(accessibility_atspi_bridge)
65#include <QtGui/private/qspiaccessiblebridge_p.h>
66#endif
67
68#if QT_CONFIG(xkbcommon)
69#include <QtGui/private/qxkbcommon_p.h>
70#endif
71
72#if QT_CONFIG(vulkan)
73#include "qwaylandvulkaninstance_p.h"
74#include "qwaylandvulkanwindow_p.h"
75#endif
76
78
79using namespace Qt::StringLiterals;
80
81namespace QtWaylandClient {
82
84
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 WindowActivation:
134 return true;
135 case ScreenWindowGrabbing: // whether QScreen::grabWindow() is supported
136 return false;
137 case OffscreenSurface:
140 default: return QPlatformIntegration::hasCapability(cap);
141 }
142}
143
145{
149
150#if QT_CONFIG(vulkan)
153#endif // QT_CONFIG(vulkan)
154
155 return new QWaylandShmWindow(window, mDisplay.data());
156}
157
158#if QT_CONFIG(opengl)
160{
163 return nullptr;
164}
165
167{
170 return nullptr;
171}
172
174{
176}
177#endif // opengl
178
183
188
193
194// Support platform specific initialization
196{
198
201#if QT_CONFIG(clipboard)
203#endif
204#if QT_CONFIG(draganddrop)
206#endif
207
209}
210
212{
214
215 // Call this after initializing event thread for QWaylandDisplay::flushRequests()
219
220 // Qt does not support running with no screens
222}
223
228
229#if QT_CONFIG(clipboard)
231{
232 return mClipboard.data();
233}
234#endif
235
236#if QT_CONFIG(draganddrop)
238{
239 return mDrag.data();
240}
241#endif // draganddrop
242
247
255
256#if QT_CONFIG(accessibility)
258{
259 if (!mAccessibility) {
260#if QT_CONFIG(accessibility_atspi_bridge)
261 Q_ASSERT_X(QCoreApplication::eventDispatcher(), "QWaylandIntegration",
262 "Initializing accessibility without event-dispatcher!");
264#else
266#endif
267 }
268 return mAccessibility.data();
269}
270#endif
271
276
278{
279 return mDisplay.data();
280}
281
283{
284 if (auto *seat = mDisplay->currentInputDevice(); seat && seat->keyboardFocus()) {
285 return seat->modifiers();
286 }
287 return Qt::NoModifier;
288}
289
291{
292 if (auto *seat = mDisplay->currentInputDevice())
293 return seat->possibleKeys(event);
294 return {};
295}
296
301
306
311
316
317#if QT_CONFIG(vulkan)
319{
321}
322#endif // QT_CONFIG(vulkan)
323
324// May be called from non-GUI threads
334
342
350
351// May be called from non-GUI threads
353{
356 return;
357
358 QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION"));
359 if (mPlatformName == "wayland-egl"_L1)
360 targetKey = "wayland-egl"_L1;
361 else if (mPlatformName == "wayland-brcm"_L1)
362 targetKey = "brcm"_L1;
363
364 if (targetKey.isEmpty()) {
366 && mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("wayland-eglstream-controller")
367 && mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("linux-dmabuf-unstable-v1")) {
369 } else {
370 targetKey = QLatin1String("wayland-egl");
371 }
372 }
373
374 if (targetKey.isEmpty()) {
375 qWarning("Failed to determine what client buffer integration to use");
376 } else {
378 qCDebug(lcQpaWayland) << "Available client buffer integrations:" << keys;
379
382
384 qCDebug(lcQpaWayland) << "Initializing client buffer integration" << targetKey;
386 } else {
387 qCWarning(lcQpaWayland) << "Failed to load client buffer integration:" << targetKey;
388 qCWarning(lcQpaWayland) << "Available client buffer integrations:" << keys;
389 }
390 }
391
392 // This must be set last to make sure other threads don't use the
393 // integration before initialization is complete.
395}
396
398{
400
401 QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION"));
402
405
406 if (targetKey.isEmpty()) {
407 qWarning("Failed to determine what server buffer integration to use");
408 return;
409 }
410
412 qCDebug(lcQpaWayland) << "Available server buffer integrations:" << keys;
413
416
418 qCDebug(lcQpaWayland) << "Initializing server buffer integration" << targetKey;
420 } else {
421 qCWarning(lcQpaWayland) << "Failed to load server buffer integration: " << targetKey;
422 qCWarning(lcQpaWayland) << "Available server buffer integrations:" << keys;
423 }
424}
425
427{
429
430 QByteArray integrationNames = qgetenv("QT_WAYLAND_SHELL_INTEGRATION");
432
434 if (!targetKeys.isEmpty()) {
436 } else {
437 preferredShells << QLatin1String("xdg-shell");
438 preferredShells << QLatin1String("wl-shell") << QLatin1String("ivi-shell");
439 preferredShells << QLatin1String("qt-shell");
440 }
441
444 if (mShellIntegration) {
445 qCDebug(lcQpaWayland, "Using the '%s' shell integration", qPrintable(preferredShell));
446 break;
447 }
448 }
449
450 if (!mShellIntegration) {
451 qCWarning(lcQpaWayland) << "Loading shell integration failed.";
452 qCWarning(lcQpaWayland) << "Attempted to load the following shells" << preferredShells;
453 }
454
456}
457
465
467{
468 QByteArray integrationName = qgetenv("QT_WAYLAND_INPUTDEVICE_INTEGRATION");
470
471 if (targetKey.isEmpty()) {
472 return;
473 }
474
476 if (keys.contains(targetKey)) {
478 qDebug("Using the '%s' input device integration", qPrintable(targetKey));
479 } else {
480 qWarning("Wayland inputdevice integration '%s' not found, using default", qPrintable(targetKey));
481 }
482}
483
485{
486 if (!mDisplay) {
487 // This function can be called from QWaylandDisplay::registry_global() when we
488 // are in process of constructing QWaylandDisplay. Configuring input context
489 // in that case is done by calling reconfigureInputContext() from QWaylandIntegration
490 // constructor, after QWaylandDisplay has been constructed.
491 return;
492 }
493
495 if (requested.contains(QLatin1String("qtvirtualkeyboard")))
496 qCWarning(lcQpaWayland) << "qtvirtualkeyboard currently is not supported at client-side,"
497 " use QT_IM_MODULES=qtvirtualkeyboard at compositor-side.";
498
502
506
507 for (const QString &imKey : requested) {
510 if (mDisplay->textInputMethodManager() != nullptr)
512 else if (mDisplay->textInputManagerv1() != nullptr
513 || mDisplay->textInputManagerv2() != nullptr
514 || mDisplay->textInputManagerv3() != nullptr)
516 } else {
518 }
519
521 break;
522 }
523
524#if QT_CONFIG(xkbcommon)
528 }
529#endif
530
531 qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>");
532}
533
535{
538 } else {
539 qCWarning(lcQpaWayland) << "No shell integration named" << integrationName << "found";
540 return nullptr;
541 }
542}
543
544#ifndef QT_NO_SESSIONMANAGER
550#endif
551
562
567
569{
570 if (auto bell = mDisplay->systemBell()) {
571 bell->ring(nullptr);
572 }
573}
574
575}
576
577QT_END_NAMESPACE
Combined button and popup list for selecting options.
#define WAYLAND_IM_KEY