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#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 case OffscreenSurface:
139 default: return QPlatformIntegration::hasCapability(cap);
140 }
141}
142
144{
148
149#if QT_CONFIG(vulkan)
152#endif // QT_CONFIG(vulkan)
153
154 return new QWaylandShmWindow(window, mDisplay.data());
155}
156
157#if QT_CONFIG(opengl)
159{
162 return nullptr;
163}
164
166{
169 return nullptr;
170}
171
173{
175}
176#endif // opengl
177
182
187
192
193// Support platform specific initialization
195{
197
200#if QT_CONFIG(clipboard)
202#endif
203#if QT_CONFIG(draganddrop)
205#endif
206
208}
209
211{
213
214 // Call this after initializing event thread for QWaylandDisplay::flushRequests()
218
219 // Qt does not support running with no screens
221}
222
227
228#if QT_CONFIG(clipboard)
230{
231 return mClipboard.data();
232}
233#endif
234
235#if QT_CONFIG(draganddrop)
237{
238 return mDrag.data();
239}
240#endif // draganddrop
241
246
254
255#if QT_CONFIG(accessibility)
257{
258 if (!mAccessibility) {
259#if QT_CONFIG(accessibility_atspi_bridge)
260 Q_ASSERT_X(QCoreApplication::eventDispatcher(), "QWaylandIntegration",
261 "Initializing accessibility without event-dispatcher!");
263#else
265#endif
266 }
267 return mAccessibility.data();
268}
269#endif
270
275
277{
278 return mDisplay.data();
279}
280
282{
283 if (auto *seat = mDisplay->currentInputDevice(); seat && seat->keyboardFocus()) {
284 return seat->modifiers();
285 }
286 return Qt::NoModifier;
287}
288
290{
291 if (auto *seat = mDisplay->currentInputDevice())
292 return seat->possibleKeys(event);
293 return {};
294}
295
300
305
310
315
316#if QT_CONFIG(vulkan)
318{
320}
321#endif // QT_CONFIG(vulkan)
322
323// May be called from non-GUI threads
333
341
349
350// May be called from non-GUI threads
352{
355 return;
356
357 QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION"));
358 if (mPlatformName == "wayland-egl"_L1)
359 targetKey = "wayland-egl"_L1;
360 else if (mPlatformName == "wayland-brcm"_L1)
361 targetKey = "brcm"_L1;
362
363 if (targetKey.isEmpty()) {
365 && mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("wayland-eglstream-controller")
366 && mDisplay->hardwareIntegration()->clientBufferIntegration() != QLatin1String("linux-dmabuf-unstable-v1")) {
368 } else {
369 targetKey = QLatin1String("wayland-egl");
370 }
371 }
372
373 if (targetKey.isEmpty()) {
374 qWarning("Failed to determine what client buffer integration to use");
375 } else {
377 qCDebug(lcQpaWayland) << "Available client buffer integrations:" << keys;
378
381
383 qCDebug(lcQpaWayland) << "Initializing client buffer integration" << targetKey;
385 } else {
386 qCWarning(lcQpaWayland) << "Failed to load client buffer integration:" << targetKey;
387 qCWarning(lcQpaWayland) << "Available client buffer integrations:" << keys;
388 }
389 }
390
391 // This must be set last to make sure other threads don't use the
392 // integration before initialization is complete.
394}
395
397{
399
400 QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION"));
401
404
405 if (targetKey.isEmpty()) {
406 qWarning("Failed to determine what server buffer integration to use");
407 return;
408 }
409
411 qCDebug(lcQpaWayland) << "Available server buffer integrations:" << keys;
412
415
417 qCDebug(lcQpaWayland) << "Initializing server buffer integration" << targetKey;
419 } else {
420 qCWarning(lcQpaWayland) << "Failed to load server buffer integration: " << targetKey;
421 qCWarning(lcQpaWayland) << "Available server buffer integrations:" << keys;
422 }
423}
424
426{
428
429 QByteArray integrationNames = qgetenv("QT_WAYLAND_SHELL_INTEGRATION");
431
433 if (!targetKeys.isEmpty()) {
435 } else {
436 preferredShells << QLatin1String("xdg-shell");
437 preferredShells << QLatin1String("wl-shell") << QLatin1String("ivi-shell");
438 preferredShells << QLatin1String("qt-shell");
439 }
440
443 if (mShellIntegration) {
444 qCDebug(lcQpaWayland, "Using the '%s' shell integration", qPrintable(preferredShell));
445 break;
446 }
447 }
448
449 if (!mShellIntegration) {
450 qCWarning(lcQpaWayland) << "Loading shell integration failed.";
451 qCWarning(lcQpaWayland) << "Attempted to load the following shells" << preferredShells;
452 }
453
455}
456
464
466{
467 QByteArray integrationName = qgetenv("QT_WAYLAND_INPUTDEVICE_INTEGRATION");
469
470 if (targetKey.isEmpty()) {
471 return;
472 }
473
475 if (keys.contains(targetKey)) {
477 qDebug("Using the '%s' input device integration", qPrintable(targetKey));
478 } else {
479 qWarning("Wayland inputdevice integration '%s' not found, using default", qPrintable(targetKey));
480 }
481}
482
484{
485 if (!mDisplay) {
486 // This function can be called from QWaylandDisplay::registry_global() when we
487 // are in process of constructing QWaylandDisplay. Configuring input context
488 // in that case is done by calling reconfigureInputContext() from QWaylandIntegration
489 // constructor, after QWaylandDisplay has been constructed.
490 return;
491 }
492
494 if (requested.contains(QLatin1String("qtvirtualkeyboard")))
495 qCWarning(lcQpaWayland) << "qtvirtualkeyboard currently is not supported at client-side,"
496 " use QT_IM_MODULES=qtvirtualkeyboard at compositor-side.";
497
501
505
506 for (const QString &imKey : requested) {
509 if (mDisplay->textInputMethodManager() != nullptr)
511 else if (mDisplay->textInputManagerv1() != nullptr
512 || mDisplay->textInputManagerv2() != nullptr
513 || mDisplay->textInputManagerv3() != nullptr)
515 } else {
517 }
518
520 break;
521 }
522
523#if QT_CONFIG(xkbcommon)
527 }
528#endif
529
530 qCDebug(lcQpaWayland) << "using input method:" << (inputContext() ? inputContext()->metaObject()->className() : "<none>");
531}
532
534{
537 } else {
538 qCWarning(lcQpaWayland) << "No shell integration named" << integrationName << "found";
539 return nullptr;
540 }
541}
542
543#ifndef QT_NO_SESSIONMANAGER
549#endif
550
561
566
568{
569 if (auto bell = mDisplay->systemBell()) {
570 bell->ring(nullptr);
571 }
572}
573
574}
575
576QT_END_NAMESPACE
Combined button and popup list for selecting options.
#define WAYLAND_IM_KEY