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.get());
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.get();
233}
234#endif
235
236#if QT_CONFIG(draganddrop)
238{
239 return mDrag.get();
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.get();
269}
270#endif
271
276
278{
279 return mDisplay.get();
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
335
343
351
352// May be called from non-GUI threads
354{
357 return;
358
359 QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION"));
360 if (mPlatformName == "wayland-egl"_L1)
361 targetKey = "wayland-egl"_L1;
362 else if (mPlatformName == "wayland-brcm"_L1)
363 targetKey = "brcm"_L1;
364
365 if (targetKey.isEmpty()) {
367 && mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("wayland-eglstream-controller")
369 && mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("linux-dmabuf-unstable-v1")) {
371 } else {
372 targetKey = QLatin1String("wayland-egl");
373 }
374 }
375
376 if (targetKey.isEmpty()) {
377 qWarning("Failed to determine what client buffer integration to use");
378 } else {
380 qCDebug(lcQpaWayland) << "Available client buffer integrations:" << keys;
381
384
386 qCDebug(lcQpaWayland) << "Initializing client buffer integration" << targetKey;
388 } else {
389 qCWarning(lcQpaWayland) << "Failed to load client buffer integration:" << targetKey;
390 qCWarning(lcQpaWayland) << "Available client buffer integrations:" << keys;
391 }
392 }
393
394 // This must be set last to make sure other threads don't use the
395 // integration before initialization is complete.
397}
398
400{
402
403 QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION"));
404
407
408 if (targetKey.isEmpty()) {
409 qWarning("Failed to determine what server buffer integration to use");
410 return;
411 }
412
414 qCDebug(lcQpaWayland) << "Available server buffer integrations:" << keys;
415
418
420 qCDebug(lcQpaWayland) << "Initializing server buffer integration" << targetKey;
422 } else {
423 qCWarning(lcQpaWayland) << "Failed to load server buffer integration: " << targetKey;
424 qCWarning(lcQpaWayland) << "Available server buffer integrations:" << keys;
425 }
426}
427
429{
431
432 QByteArray integrationNames = qgetenv("QT_WAYLAND_SHELL_INTEGRATION");
434
436 if (!targetKeys.isEmpty()) {
438 } else {
439 preferredShells << QLatin1String("xdg-shell");
440 preferredShells << QLatin1String("wl-shell") << QLatin1String("ivi-shell");
441 preferredShells << QLatin1String("qt-shell");
442 }
443
446 if (mShellIntegration) {
447 qCDebug(lcQpaWayland, "Using the '%s' shell integration", qPrintable(preferredShell));
448 break;
449 }
450 }
451
452 if (!mShellIntegration) {
453 qCWarning(lcQpaWayland) << "Loading shell integration failed.";
454 qCWarning(lcQpaWayland) << "Attempted to load the following shells" << preferredShells;
455 }
456
458}
459
467
469{
470 QByteArray integrationName = qgetenv("QT_WAYLAND_INPUTDEVICE_INTEGRATION");
472
473 if (targetKey.isEmpty()) {
474 return;
475 }
476
478 if (keys.contains(targetKey)) {
480 qDebug("Using the '%s' input device integration", qPrintable(targetKey));
481 } else {
482 qWarning("Wayland inputdevice integration '%s' not found, using default", qPrintable(targetKey));
483 }
484}
485
487{
488 if (!mDisplay) {
489 // This function can be called from QWaylandDisplay::registry_global() when we
490 // are in process of constructing QWaylandDisplay. Configuring input context
491 // in that case is done by calling reconfigureInputContext() from QWaylandIntegration
492 // constructor, after QWaylandDisplay has been constructed.
493 return;
494 }
495
497 if (requested.contains(QLatin1String("qtvirtualkeyboard")))
498 qCWarning(lcQpaWayland) << "qtvirtualkeyboard currently is not supported at client-side,"
499 " use QT_IM_MODULES=qtvirtualkeyboard at compositor-side.";
500
504
508
509 for (const QString &imKey : requested) {
512 if (mDisplay->textInputMethodManager() != nullptr)
514 else if (mDisplay->textInputManagerv1() != nullptr
515 || mDisplay->textInputManagerv2() != nullptr
516 || mDisplay->textInputManagerv3() != nullptr)
518 } else {
520 }
521
523 break;
524 }
525
526#if QT_CONFIG(xkbcommon)
530 }
531#endif
532
533 qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>");
534}
535
537{
540 } else {
541 qCWarning(lcQpaWayland) << "No shell integration named" << integrationName << "found";
542 return nullptr;
543 }
544}
545
546#ifndef QT_NO_SESSIONMANAGER
552#endif
553
564
569
571{
572 if (auto bell = mDisplay->systemBell()) {
573 bell->ring(nullptr);
574 }
575}
576
577}
578
579QT_END_NAMESPACE
Combined button and popup list for selecting options.
#define WAYLAND_IM_KEY