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")
368 && mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("linux-dmabuf-unstable-v1")) {
370 } else {
371 targetKey = QLatin1String("wayland-egl");
372 }
373 }
374
375 if (targetKey.isEmpty()) {
376 qWarning("Failed to determine what client buffer integration to use");
377 } else {
379 qCDebug(lcQpaWayland) << "Available client buffer integrations:" << keys;
380
383
385 qCDebug(lcQpaWayland) << "Initializing client buffer integration" << targetKey;
387 } else {
388 qCWarning(lcQpaWayland) << "Failed to load client buffer integration:" << targetKey;
389 qCWarning(lcQpaWayland) << "Available client buffer integrations:" << keys;
390 }
391 }
392
393 // This must be set last to make sure other threads don't use the
394 // integration before initialization is complete.
396}
397
399{
401
402 QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION"));
403
406
407 if (targetKey.isEmpty()) {
408 qWarning("Failed to determine what server buffer integration to use");
409 return;
410 }
411
413 qCDebug(lcQpaWayland) << "Available server buffer integrations:" << keys;
414
417
419 qCDebug(lcQpaWayland) << "Initializing server buffer integration" << targetKey;
421 } else {
422 qCWarning(lcQpaWayland) << "Failed to load server buffer integration: " << targetKey;
423 qCWarning(lcQpaWayland) << "Available server buffer integrations:" << keys;
424 }
425}
426
428{
430
431 QByteArray integrationNames = qgetenv("QT_WAYLAND_SHELL_INTEGRATION");
433
435 if (!targetKeys.isEmpty()) {
437 } else {
438 preferredShells << QLatin1String("xdg-shell");
439 preferredShells << QLatin1String("wl-shell") << QLatin1String("ivi-shell");
440 preferredShells << QLatin1String("qt-shell");
441 }
442
445 if (mShellIntegration) {
446 qCDebug(lcQpaWayland, "Using the '%s' shell integration", qPrintable(preferredShell));
447 break;
448 }
449 }
450
451 if (!mShellIntegration) {
452 qCWarning(lcQpaWayland) << "Loading shell integration failed.";
453 qCWarning(lcQpaWayland) << "Attempted to load the following shells" << preferredShells;
454 }
455
457}
458
466
468{
469 QByteArray integrationName = qgetenv("QT_WAYLAND_INPUTDEVICE_INTEGRATION");
471
472 if (targetKey.isEmpty()) {
473 return;
474 }
475
477 if (keys.contains(targetKey)) {
479 qDebug("Using the '%s' input device integration", qPrintable(targetKey));
480 } else {
481 qWarning("Wayland inputdevice integration '%s' not found, using default", qPrintable(targetKey));
482 }
483}
484
486{
487 if (!mDisplay) {
488 // This function can be called from QWaylandDisplay::registry_global() when we
489 // are in process of constructing QWaylandDisplay. Configuring input context
490 // in that case is done by calling reconfigureInputContext() from QWaylandIntegration
491 // constructor, after QWaylandDisplay has been constructed.
492 return;
493 }
494
496 if (requested.contains(QLatin1String("qtvirtualkeyboard")))
497 qCWarning(lcQpaWayland) << "qtvirtualkeyboard currently is not supported at client-side,"
498 " use QT_IM_MODULES=qtvirtualkeyboard at compositor-side.";
499
503
507
508 for (const QString &imKey : requested) {
511 if (mDisplay->textInputMethodManager() != nullptr)
513 else if (mDisplay->textInputManagerv1() != nullptr
514 || mDisplay->textInputManagerv2() != nullptr
515 || mDisplay->textInputManagerv3() != nullptr)
517 } else {
519 }
520
522 break;
523 }
524
525#if QT_CONFIG(xkbcommon)
529 }
530#endif
531
532 qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>");
533}
534
536{
539 } else {
540 qCWarning(lcQpaWayland) << "No shell integration named" << integrationName << "found";
541 return nullptr;
542 }
543}
544
545#ifndef QT_NO_SESSIONMANAGER
551#endif
552
563
568
570{
571 if (auto bell = mDisplay->systemBell()) {
572 bell->ring(nullptr);
573 }
574}
575
576}
577
578QT_END_NAMESPACE
Combined button and popup list for selecting options.
#define WAYLAND_IM_KEY