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"
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/qgenericunixtheme_p.h>
30
31#include <QtGui/private/qguiapplication_p.h>
32
33#include <qpa/qwindowsysteminterface.h>
34#include <qpa/qplatformcursor.h>
35#include <QtGui/QSurfaceFormat>
36#if QT_CONFIG(opengl)
37#include <QtGui/QOpenGLContext>
38#endif // QT_CONFIG(opengl)
39#include <QSocketNotifier>
40
41#include <qpa/qplatforminputcontextfactory_p.h>
42#include <qpa/qplatformaccessibility.h>
43#include <qpa/qplatforminputcontext.h>
44
48
52
55
60
61#include <QtWaylandClient/private/qwayland-xdg-system-bell-v1.h>
62
63#if QT_CONFIG(accessibility_atspi_bridge)
64#include <QtGui/private/qspiaccessiblebridge_p.h>
65#endif
66
67#if QT_CONFIG(xkbcommon)
68#include <QtGui/private/qxkbcommon_p.h>
69#endif
70
71#if QT_CONFIG(vulkan)
72#include "qwaylandvulkaninstance_p.h"
73#include "qwaylandvulkanwindow_p.h"
74#endif
75
77
78using namespace Qt::StringLiterals;
79
80namespace QtWaylandClient {
81
83
103
108
110{
111 return mDisplay->initialize();
112}
113
118
120{
121 switch (cap) {
122 case ThreadedPixmaps: return true;
123 case OpenGL:
125 case ThreadedOpenGL:
128 return true;
129 case MultipleWindows:
131 return true;
132 case WindowActivation:
133 return true;
134 case ScreenWindowGrabbing: // whether QScreen::grabWindow() is supported
135 return false;
136 default: return QPlatformIntegration::hasCapability(cap);
137 }
138}
139
141{
145
146#if QT_CONFIG(vulkan)
149#endif // QT_CONFIG(vulkan)
150
151 return new QWaylandShmWindow(window, mDisplay.data());
152}
153
154#if QT_CONFIG(opengl)
156{
159 return nullptr;
160}
161
163{
166 return nullptr;
167}
168
170{
172}
173#endif // opengl
174
179
184
189
190// Support platform specific initialization
192{
194
197#if QT_CONFIG(clipboard)
199#endif
200#if QT_CONFIG(draganddrop)
202#endif
203
205}
206
208{
210
211 // Call this after initializing event thread for QWaylandDisplay::flushRequests()
215
216 // Qt does not support running with no screens
218}
219
224
225#if QT_CONFIG(clipboard)
227{
228 return mClipboard.data();
229}
230#endif
231
232#if QT_CONFIG(draganddrop)
234{
235 return mDrag.data();
236}
237#endif // draganddrop
238
243
251
252#if QT_CONFIG(accessibility)
254{
255 if (!mAccessibility) {
256#if QT_CONFIG(accessibility_atspi_bridge)
257 Q_ASSERT_X(QCoreApplication::eventDispatcher(), "QWaylandIntegration",
258 "Initializing accessibility without event-dispatcher!");
260#else
262#endif
263 }
264 return mAccessibility.data();
265}
266#endif
267
272
274{
275 return mDisplay.data();
276}
277
279{
280 if (auto *seat = mDisplay->currentInputDevice(); seat && seat->keyboardFocus()) {
281 return seat->modifiers();
282 }
283 return Qt::NoModifier;
284}
285
287{
288 if (auto *seat = mDisplay->currentInputDevice())
289 return seat->possibleKeys(event);
290 return {};
291}
292
297
302
307
312
313#if QT_CONFIG(vulkan)
315{
317}
318#endif // QT_CONFIG(vulkan)
319
320// May be called from non-GUI threads
330
338
346
347// May be called from non-GUI threads
349{
352 return;
353
354 QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION"));
355 if (mPlatformName == "wayland-egl"_L1)
356 targetKey = "wayland-egl"_L1;
357 else if (mPlatformName == "wayland-brcm"_L1)
358 targetKey = "brcm"_L1;
359
360 if (targetKey.isEmpty()) {
362 && mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("wayland-eglstream-controller")
363 && mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("linux-dmabuf-unstable-v1")) {
365 } else {
366 targetKey = QLatin1String("wayland-egl");
367 }
368 }
369
370 if (targetKey.isEmpty()) {
371 qWarning("Failed to determine what client buffer integration to use");
372 } else {
374 qCDebug(lcQpaWayland) << "Available client buffer integrations:" << keys;
375
378
380 qCDebug(lcQpaWayland) << "Initializing client buffer integration" << targetKey;
382 } else {
383 qCWarning(lcQpaWayland) << "Failed to load client buffer integration:" << targetKey;
384 qCWarning(lcQpaWayland) << "Available client buffer integrations:" << keys;
385 }
386 }
387
388 // This must be set last to make sure other threads don't use the
389 // integration before initialization is complete.
391}
392
394{
396
397 QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION"));
398
401
402 if (targetKey.isEmpty()) {
403 qWarning("Failed to determine what server buffer integration to use");
404 return;
405 }
406
408 qCDebug(lcQpaWayland) << "Available server buffer integrations:" << keys;
409
412
414 qCDebug(lcQpaWayland) << "Initializing server buffer integration" << targetKey;
416 } else {
417 qCWarning(lcQpaWayland) << "Failed to load server buffer integration: " << targetKey;
418 qCWarning(lcQpaWayland) << "Available server buffer integrations:" << keys;
419 }
420}
421
423{
425
426 QByteArray integrationNames = qgetenv("QT_WAYLAND_SHELL_INTEGRATION");
428
430 if (!targetKeys.isEmpty()) {
432 } else {
433 preferredShells << QLatin1String("xdg-shell");
434 preferredShells << QLatin1String("wl-shell") << QLatin1String("ivi-shell");
435 preferredShells << QLatin1String("qt-shell");
436 }
437
440 if (mShellIntegration) {
441 qCDebug(lcQpaWayland, "Using the '%s' shell integration", qPrintable(preferredShell));
442 break;
443 }
444 }
445
446 if (!mShellIntegration) {
447 qCWarning(lcQpaWayland) << "Loading shell integration failed.";
448 qCWarning(lcQpaWayland) << "Attempted to load the following shells" << preferredShells;
449 }
450
452}
453
461
463{
464 QByteArray integrationName = qgetenv("QT_WAYLAND_INPUTDEVICE_INTEGRATION");
466
467 if (targetKey.isEmpty()) {
468 return;
469 }
470
472 if (keys.contains(targetKey)) {
474 qDebug("Using the '%s' input device integration", qPrintable(targetKey));
475 } else {
476 qWarning("Wayland inputdevice integration '%s' not found, using default", qPrintable(targetKey));
477 }
478}
479
481{
482 if (!mDisplay) {
483 // This function can be called from QWaylandDisplay::registry_global() when we
484 // are in process of constructing QWaylandDisplay. Configuring input context
485 // in that case is done by calling reconfigureInputContext() from QWaylandIntegration
486 // constructor, after QWaylandDisplay has been constructed.
487 return;
488 }
489
491 if (requested.contains(QLatin1String("qtvirtualkeyboard")))
492 qCWarning(lcQpaWayland) << "qtvirtualkeyboard currently is not supported at client-side,"
493 " use QT_IM_MODULES=qtvirtualkeyboard at compositor-side.";
494
498
502
503 for (const QString &imKey : requested) {
506 if (mDisplay->textInputMethodManager() != nullptr)
508 else if (mDisplay->textInputManagerv1() != nullptr
509 || mDisplay->textInputManagerv2() != nullptr
510 || mDisplay->textInputManagerv3() != nullptr)
512 } else {
514 }
515
517 break;
518 }
519
520#if QT_CONFIG(xkbcommon)
524 }
525#endif
526
527 qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>");
528}
529
531{
534 } else {
535 qCWarning(lcQpaWayland) << "No shell integration named" << integrationName << "found";
536 return nullptr;
537 }
538}
539
540#ifndef QT_NO_SESSIONMANAGER
546#endif
547
558
563
565{
566 if (auto bell = mDisplay->systemBell()) {
567 bell->ring(nullptr);
568 }
569}
570
571}
572
573QT_END_NAMESPACE
#define WAYLAND_IM_KEY