KWin
Loading...
Searching...
No Matches
xwayland.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
6 SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
7 SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
8
9 SPDX-License-Identifier: GPL-2.0-or-later
10*/
11#include "xwayland.h"
12
13#include <config-kwin.h>
14
15#include "databridge.h"
16#include "dnd.h"
17#include "window.h"
18#include "xwaylandlauncher.h"
19#include "xwldrophandler.h"
20
21#include "core/output.h"
22#include "input_event_spy.h"
23#include "keyboard_input.h"
24#include "main_wayland.h"
25#include "utils/common.h"
26#include "utils/xcbutils.h"
27#include "wayland_server.h"
28#include "waylandwindow.h"
29#include "workspace.h"
30#include "x11eventfilter.h"
31#include "xkb.h"
32#include "xwayland_logging.h"
33
34#include <KSelectionOwner>
35#include <wayland/keyboard.h>
36#include <wayland/seat.h>
37#include <wayland/surface.h>
38
39#include <QAbstractEventDispatcher>
40#include <QDataStream>
41#include <QFile>
42#include <QRandomGenerator>
43#include <QScopeGuard>
44#include <QSocketNotifier>
45#include <QTimer>
46#include <QtConcurrentRun>
47
48#include <cerrno>
49#include <cstring>
50#include <input_event.h>
51#include <sys/socket.h>
52#include <unistd.h>
53#include <xkbcommon/xkbcommon-keysyms.h>
54
55namespace KWin
56{
57namespace Xwl
58{
59
61{
62public:
63 explicit XrandrEventFilter(Xwayland *backend);
64
65 bool event(xcb_generic_event_t *event) override;
66
67private:
68 Xwayland *const m_backend;
69};
70
72 : X11EventFilter(Xcb::Extensions::self()->randrNotifyEvent())
73 , m_backend(backend)
74{
75}
76
77bool XrandrEventFilter::event(xcb_generic_event_t *event)
78{
79 Q_ASSERT((event->response_type & ~0x80) == Xcb::Extensions::self()->randrNotifyEvent());
80 m_backend->updatePrimary();
81 return false;
82}
83
84class XwaylandInputSpy : public QObject, public KWin::InputEventSpy
85{
86public:
88 {
90 this, [this](SurfaceInterface *newSurface) {
91 auto keyboard = waylandServer()->seat()->keyboard();
92 if (!newSurface) {
93 return;
94 }
95
96 if (waylandServer()->xWaylandConnection() == newSurface->client()) {
97 // Since this is a spy but the keyboard interface gets its normal sendKey calls through filters,
98 // there can be a mismatch in both states.
99 // This loop makes sure all key press events are reset before we switch back to the
100 // Xwayland client and the state is correctly restored.
101 for (auto it = m_states.constBegin(); it != m_states.constEnd(); ++it) {
102 if (it.value() == KeyboardKeyState::Pressed) {
104 }
105 }
106 m_states.clear();
107 }
108 });
109 }
110
112 {
113 static const Qt::KeyboardModifiers modifierKeys = {
114 Qt::ControlModifier,
115 Qt::AltModifier,
116 Qt::MetaModifier,
117 };
118
119 static const QSet<quint32> characterKeys = {
120 Qt::Key_Any,
121 Qt::Key_Space,
122 Qt::Key_Exclam,
123 Qt::Key_QuoteDbl,
124 Qt::Key_NumberSign,
125 Qt::Key_Dollar,
126 Qt::Key_Percent,
127 Qt::Key_Ampersand,
128 Qt::Key_Apostrophe,
129 Qt::Key_ParenLeft,
130 Qt::Key_ParenRight,
131 Qt::Key_Asterisk,
132 Qt::Key_Plus,
133 Qt::Key_Comma,
134 Qt::Key_Minus,
135 Qt::Key_Period,
136 Qt::Key_Slash,
137 Qt::Key_0,
138 Qt::Key_1,
139 Qt::Key_2,
140 Qt::Key_3,
141 Qt::Key_4,
142 Qt::Key_5,
143 Qt::Key_6,
144 Qt::Key_7,
145 Qt::Key_8,
146 Qt::Key_9,
147 Qt::Key_Colon,
148 Qt::Key_Semicolon,
149 Qt::Key_Less,
150 Qt::Key_Equal,
151 Qt::Key_Greater,
152 Qt::Key_Question,
153 Qt::Key_At,
154 Qt::Key_A,
155 Qt::Key_B,
156 Qt::Key_C,
157 Qt::Key_D,
158 Qt::Key_E,
159 Qt::Key_F,
160 Qt::Key_G,
161 Qt::Key_H,
162 Qt::Key_I,
163 Qt::Key_J,
164 Qt::Key_K,
165 Qt::Key_L,
166 Qt::Key_M,
167 Qt::Key_N,
168 Qt::Key_O,
169 Qt::Key_P,
170 Qt::Key_Q,
171 Qt::Key_R,
172 Qt::Key_S,
173 Qt::Key_T,
174 Qt::Key_U,
175 Qt::Key_V,
176 Qt::Key_W,
177 Qt::Key_X,
178 Qt::Key_Y,
179 Qt::Key_Z,
180 Qt::Key_BracketLeft,
181 Qt::Key_Backslash,
182 Qt::Key_BracketRight,
183 Qt::Key_AsciiCircum,
184 Qt::Key_Underscore,
185 Qt::Key_QuoteLeft,
186 Qt::Key_BraceLeft,
187 Qt::Key_Bar,
188 Qt::Key_BraceRight,
189 Qt::Key_AsciiTilde,
190 Qt::Key_nobreakspace,
191 Qt::Key_exclamdown,
192 Qt::Key_cent,
193 Qt::Key_sterling,
194 Qt::Key_currency,
195 Qt::Key_yen,
196 Qt::Key_brokenbar,
197 Qt::Key_section,
198 Qt::Key_diaeresis,
199 Qt::Key_copyright,
200 Qt::Key_ordfeminine,
201 Qt::Key_guillemotleft,
202 Qt::Key_notsign,
203 Qt::Key_hyphen,
204 Qt::Key_registered,
205 Qt::Key_macron,
206 Qt::Key_degree,
207 Qt::Key_plusminus,
208 Qt::Key_twosuperior,
209 Qt::Key_threesuperior,
210 Qt::Key_acute,
211 Qt::Key_mu,
212 Qt::Key_paragraph,
213 Qt::Key_periodcentered,
214 Qt::Key_cedilla,
215 Qt::Key_onesuperior,
216 Qt::Key_masculine,
217 Qt::Key_guillemotright,
218 Qt::Key_onequarter,
219 Qt::Key_onehalf,
220 Qt::Key_threequarters,
221 Qt::Key_questiondown,
222 Qt::Key_Agrave,
223 Qt::Key_Aacute,
224 Qt::Key_Acircumflex,
225 Qt::Key_Atilde,
226 Qt::Key_Adiaeresis,
227 Qt::Key_Aring,
228 Qt::Key_AE,
229 Qt::Key_Ccedilla,
230 Qt::Key_Egrave,
231 Qt::Key_Eacute,
232 Qt::Key_Ecircumflex,
233 Qt::Key_Ediaeresis,
234 Qt::Key_Igrave,
235 Qt::Key_Iacute,
236 Qt::Key_Icircumflex,
237 Qt::Key_Idiaeresis,
238 Qt::Key_ETH,
239 Qt::Key_Ntilde,
240 Qt::Key_Ograve,
241 Qt::Key_Oacute,
242 Qt::Key_Ocircumflex,
243 Qt::Key_Otilde,
244 Qt::Key_Odiaeresis,
245 Qt::Key_multiply,
246 Qt::Key_Ooblique,
247 Qt::Key_Ugrave,
248 Qt::Key_Uacute,
249 Qt::Key_Ucircumflex,
250 Qt::Key_Udiaeresis,
251 Qt::Key_Yacute,
252 Qt::Key_THORN,
253 Qt::Key_ssharp,
254 Qt::Key_division,
255 Qt::Key_ydiaeresis,
256 Qt::Key_Multi_key,
257 Qt::Key_Codeinput,
258 Qt::Key_SingleCandidate,
259 Qt::Key_MultipleCandidate,
260 Qt::Key_PreviousCandidate,
261 Qt::Key_Mode_switch,
262 Qt::Key_Kanji,
263 Qt::Key_Muhenkan,
264 Qt::Key_Henkan,
265 Qt::Key_Romaji,
266 Qt::Key_Hiragana,
267 Qt::Key_Katakana,
268 Qt::Key_Hiragana_Katakana,
269 Qt::Key_Zenkaku,
270 Qt::Key_Hankaku,
271 Qt::Key_Zenkaku_Hankaku,
272 Qt::Key_Touroku,
273 Qt::Key_Massyo,
274 Qt::Key_Kana_Lock,
275 Qt::Key_Kana_Shift,
276 Qt::Key_Eisu_Shift,
277 Qt::Key_Eisu_toggle,
278 Qt::Key_Hangul,
279 Qt::Key_Hangul_Start,
280 Qt::Key_Hangul_End,
281 Qt::Key_Hangul_Hanja,
282 Qt::Key_Hangul_Jamo,
283 Qt::Key_Hangul_Romaja,
284 Qt::Key_Hangul_Jeonja,
285 Qt::Key_Hangul_Banja,
286 Qt::Key_Hangul_PreHanja,
287 Qt::Key_Hangul_PostHanja,
288 Qt::Key_Hangul_Special,
289 Qt::Key_Dead_Grave,
290 Qt::Key_Dead_Acute,
291 Qt::Key_Dead_Circumflex,
292 Qt::Key_Dead_Tilde,
293 Qt::Key_Dead_Macron,
294 Qt::Key_Dead_Breve,
295 Qt::Key_Dead_Abovedot,
296 Qt::Key_Dead_Diaeresis,
297 Qt::Key_Dead_Abovering,
298 Qt::Key_Dead_Doubleacute,
299 Qt::Key_Dead_Caron,
300 Qt::Key_Dead_Cedilla,
301 Qt::Key_Dead_Ogonek,
302 Qt::Key_Dead_Iota,
303 Qt::Key_Dead_Voiced_Sound,
304 Qt::Key_Dead_Semivoiced_Sound,
305 Qt::Key_Dead_Belowdot,
306 Qt::Key_Dead_Hook,
307 Qt::Key_Dead_Horn,
308 Qt::Key_Dead_Stroke,
309 Qt::Key_Dead_Abovecomma,
310 Qt::Key_Dead_Abovereversedcomma,
311 Qt::Key_Dead_Doublegrave,
312 Qt::Key_Dead_Belowring,
313 Qt::Key_Dead_Belowmacron,
314 Qt::Key_Dead_Belowcircumflex,
315 Qt::Key_Dead_Belowtilde,
316 Qt::Key_Dead_Belowbreve,
317 Qt::Key_Dead_Belowdiaeresis,
318 Qt::Key_Dead_Invertedbreve,
319 Qt::Key_Dead_Belowcomma,
320 Qt::Key_Dead_Currency,
321 Qt::Key_Dead_a,
322 Qt::Key_Dead_A,
323 Qt::Key_Dead_e,
324 Qt::Key_Dead_E,
325 Qt::Key_Dead_i,
326 Qt::Key_Dead_I,
327 Qt::Key_Dead_o,
328 Qt::Key_Dead_O,
329 Qt::Key_Dead_u,
330 Qt::Key_Dead_U,
331 Qt::Key_Dead_Small_Schwa,
332 Qt::Key_Dead_Capital_Schwa,
333 Qt::Key_Dead_Greek,
334 Qt::Key_Dead_Lowline,
335 Qt::Key_Dead_Aboveverticalline,
336 Qt::Key_Dead_Belowverticalline};
337
338 switch (mode) {
339 case None:
340 m_filter = {};
341 break;
342 case NonCharacterKeys:
343 m_filter = [](int key, Qt::KeyboardModifiers) {
344 return !characterKeys.contains(key);
345 };
346 break;
348 m_filter = [](int key, Qt::KeyboardModifiers m) {
349 return m.testAnyFlags(modifierKeys) || !characterKeys.contains(key);
350 };
351 break;
352 case All:
353 m_filter = [](int, Qt::KeyboardModifiers) {
354 return true;
355 };
356 break;
357 }
358 }
359
360 void keyEvent(KWin::KeyEvent *event) override
361 {
362 if (event->isAutoRepeat()) {
363 return;
364 }
365
366 Window *window = workspace()->activeWindow();
367 if (!m_filter || !m_filter(event->key(), event->modifiers()) || (window && window->isLockScreen())) {
368 return;
369 }
370
371 auto keyboard = waylandServer()->seat()->keyboard();
372 auto surface = keyboard->focusedSurface();
373 if (!surface) {
374 return;
375 }
376
377 ClientConnection *client = surface->client();
379 if (xwaylandClient && xwaylandClient != client) {
380 KeyboardKeyState state{event->type() == QEvent::KeyPress};
381 if (!updateKey(event->nativeScanCode(), state)) {
382 return;
383 }
384
385 auto xkb = input()->keyboard()->xkb();
386 keyboard->sendModifiers(xkb->modifierState().depressed,
387 xkb->modifierState().latched,
388 xkb->modifierState().locked,
389 xkb->currentLayout());
390
391 waylandServer()->seat()->keyboard()->sendKey(event->nativeScanCode(), state, xwaylandClient);
392 }
393 }
394
395 bool updateKey(quint32 key, KeyboardKeyState state)
396 {
397 auto it = m_states.find(key);
398 if (it == m_states.end()) {
399 m_states.insert(key, state);
400 return true;
401 }
402 if (it.value() == state) {
403 return false;
404 }
405 it.value() = state;
406 return true;
407 }
408
409 QHash<quint32, KeyboardKeyState> m_states;
410 std::function<bool(int key, Qt::KeyboardModifiers)> m_filter;
411};
412
414 : m_app(app)
415 , m_launcher(new XwaylandLauncher(this))
416{
417 connect(m_launcher, &XwaylandLauncher::started, this, &Xwayland::handleXwaylandReady);
418 connect(m_launcher, &XwaylandLauncher::finished, this, &Xwayland::handleXwaylandFinished);
419 connect(m_launcher, &XwaylandLauncher::errorOccurred, this, &Xwayland::errorOccurred);
420}
421
423{
424 m_launcher->stop();
425}
426
428{
429 m_launcher->enable();
430
431 auto env = m_app->processStartupEnvironment();
432 env.insert(QStringLiteral("DISPLAY"), m_launcher->displayName());
433 env.insert(QStringLiteral("XAUTHORITY"), m_launcher->xauthority());
434 qputenv("DISPLAY", m_launcher->displayName().toLatin1());
435 qputenv("XAUTHORITY", m_launcher->xauthority().toLatin1());
437}
438
440{
441 return m_launcher;
442}
443
444void Xwayland::dispatchEvents(DispatchEventsMode mode)
445{
446 xcb_connection_t *connection = kwinApp()->x11Connection();
447 if (!connection) {
448 qCWarning(KWIN_XWL, "Attempting to dispatch X11 events with no connection");
449 return;
450 }
451
452 const int connectionError = xcb_connection_has_error(connection);
453 if (connectionError) {
454 qCWarning(KWIN_XWL, "The X11 connection broke (error %d)", connectionError);
455 m_launcher->stop();
456 return;
457 }
458
459 auto pollEventFunc = mode == DispatchEventsMode::Poll ? xcb_poll_for_event : xcb_poll_for_queued_event;
460
461 while (xcb_generic_event_t *event = pollEventFunc(connection)) {
462 qintptr result = 0;
463
464 QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher();
465 dispatcher->filterNativeEvent(QByteArrayLiteral("xcb_generic_event_t"), event, &result);
466 free(event);
467 }
468
469 xcb_flush(connection);
470}
471
472void Xwayland::installSocketNotifier()
473{
474 const int fileDescriptor = xcb_get_file_descriptor(kwinApp()->x11Connection());
475
476 m_socketNotifier = new QSocketNotifier(fileDescriptor, QSocketNotifier::Read, this);
477 connect(m_socketNotifier, &QSocketNotifier::activated, this, [this]() {
478 dispatchEvents(DispatchEventsMode::Poll);
479 });
480
481 QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher();
482 connect(dispatcher, &QAbstractEventDispatcher::aboutToBlock, this, [this]() {
483 dispatchEvents(DispatchEventsMode::EventQueue);
484 });
485 connect(dispatcher, &QAbstractEventDispatcher::awake, this, [this]() {
486 dispatchEvents(DispatchEventsMode::EventQueue);
487 });
488}
489
490void Xwayland::uninstallSocketNotifier()
491{
492 QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher();
493 disconnect(dispatcher, nullptr, this, nullptr);
494
495 delete m_socketNotifier;
496 m_socketNotifier = nullptr;
497}
498
499void Xwayland::handleXwaylandFinished()
500{
501 disconnect(workspace(), &Workspace::outputOrderChanged, this, &Xwayland::updatePrimary);
502
503 delete m_xrandrEventsFilter;
504 m_xrandrEventsFilter = nullptr;
505
506 // If Xwayland has crashed, we must deactivate the socket notifier and ensure that no X11
507 // events will be dispatched before blocking; otherwise we will simply hang...
508 uninstallSocketNotifier();
509
510 m_dataBridge.reset();
511 m_compositingManagerSelectionOwner.reset();
512 m_windowManagerSelectionOwner.reset();
513
514 m_inputSpy.reset();
515 disconnect(options, &Options::xwaylandEavesdropsChanged, this, &Xwayland::refreshEavesdropping);
516
517 destroyX11Connection();
518}
519
520void Xwayland::handleXwaylandReady()
521{
522 if (!createX11Connection()) {
523 Q_EMIT errorOccurred();
524 return;
525 }
526
527 qCInfo(KWIN_XWL) << "Xwayland server started on display" << m_launcher->displayName();
528
529 m_compositingManagerSelectionOwner = std::make_unique<KSelectionOwner>("_NET_WM_CM_S0", kwinApp()->x11Connection(), kwinApp()->x11RootWindow());
530 m_compositingManagerSelectionOwner->claim(true);
531
532 xcb_composite_redirect_subwindows(kwinApp()->x11Connection(),
533 kwinApp()->x11RootWindow(),
534 XCB_COMPOSITE_REDIRECT_MANUAL);
535
536 // create selection owner for WM_S0 - magic X display number expected by XWayland
537 m_windowManagerSelectionOwner = std::make_unique<KSelectionOwner>("WM_S0", kwinApp()->x11Connection(), kwinApp()->x11RootWindow());
538 connect(m_windowManagerSelectionOwner.get(), &KSelectionOwner::lostOwnership,
539 this, &Xwayland::handleSelectionLostOwnership);
540 connect(m_windowManagerSelectionOwner.get(), &KSelectionOwner::claimedOwnership,
541 this, &Xwayland::handleSelectionClaimedOwnership);
542 connect(m_windowManagerSelectionOwner.get(), &KSelectionOwner::failedToClaimOwnership,
543 this, &Xwayland::handleSelectionFailedToClaimOwnership);
544 m_windowManagerSelectionOwner->claim(true);
545
546 m_dataBridge = std::make_unique<DataBridge>();
547
548 connect(workspace(), &Workspace::outputOrderChanged, this, &Xwayland::updatePrimary);
549 updatePrimary();
550
551 Xcb::sync(); // Trigger possible errors, there's still a chance to abort
552
553 delete m_xrandrEventsFilter;
554 m_xrandrEventsFilter = new XrandrEventFilter(this);
555
556 refreshEavesdropping();
557 connect(options, &Options::xwaylandEavesdropsChanged, this, &Xwayland::refreshEavesdropping);
558}
559
560void Xwayland::refreshEavesdropping()
561{
562 if (!waylandServer()->seat()->keyboard()) {
563 return;
564 }
565
566 const bool enabled = options->xwaylandEavesdrops() != None;
567 if (enabled == bool(m_inputSpy)) {
568 if (m_inputSpy) {
569 m_inputSpy->setMode(options->xwaylandEavesdrops());
570 }
571 return;
572 }
573
574 if (enabled) {
575 m_inputSpy = std::make_unique<XwaylandInputSpy>();
576 input()->installInputEventSpy(m_inputSpy.get());
577 m_inputSpy->setMode(options->xwaylandEavesdrops());
578 } else {
579 input()->uninstallInputEventSpy(m_inputSpy.get());
580 m_inputSpy.reset();
581 }
582}
583
584void Xwayland::updatePrimary()
585{
586 if (workspace()->outputOrder().empty()) {
587 return;
588 }
589 Xcb::RandR::ScreenResources resources(kwinApp()->x11RootWindow());
590 xcb_randr_crtc_t *crtcs = resources.crtcs();
591 if (!crtcs) {
592 return;
593 }
594
595 Output *const primaryOutput = workspace()->outputOrder().front();
596 const QRect primaryOutputGeometry = Xcb::toXNative(primaryOutput->geometryF());
597 for (int i = 0; i < resources->num_crtcs; ++i) {
598 Xcb::RandR::CrtcInfo crtcInfo(crtcs[i], resources->config_timestamp);
599 const QRect geometry = crtcInfo.rect();
600 if (geometry.topLeft() == primaryOutputGeometry.topLeft()) {
601 auto outputs = crtcInfo.outputs();
602 if (outputs && crtcInfo->num_outputs > 0) {
603 qCDebug(KWIN_XWL) << "Setting primary" << primaryOutput << outputs[0];
604 xcb_randr_set_output_primary(kwinApp()->x11Connection(), kwinApp()->x11RootWindow(), outputs[0]);
605 break;
606 }
607 }
608 }
609}
610
611void Xwayland::handleSelectionLostOwnership()
612{
613 qCWarning(KWIN_XWL) << "Somebody else claimed ownership of WM_S0. This should never happen!";
614 m_launcher->stop();
615}
616
617void Xwayland::handleSelectionFailedToClaimOwnership()
618{
619 qCWarning(KWIN_XWL) << "Failed to claim ownership of WM_S0. This should never happen!";
620 m_launcher->stop();
621}
622
623void Xwayland::handleSelectionClaimedOwnership()
624{
625 Q_EMIT started();
626}
627
628bool Xwayland::createX11Connection()
629{
630 xcb_connection_t *connection = xcb_connect_to_fd(m_launcher->xcbConnectionFd(), nullptr);
631
632 const int errorCode = xcb_connection_has_error(connection);
633 if (errorCode) {
634 qCDebug(KWIN_XWL, "Failed to establish the XCB connection (error %d)", errorCode);
635 return false;
636 }
637
638 xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
639 Q_ASSERT(screen);
640
642 m_app->setX11RootWindow(screen->root);
643
644 m_app->createAtoms();
646
647 installSocketNotifier();
648
649 // Note that it's very important to have valid x11RootWindow(), and atoms when the
650 // rest of kwin is notified about the new X11 connection.
651 Q_EMIT m_app->x11ConnectionChanged();
652
653 return true;
654}
655
656void Xwayland::destroyX11Connection()
657{
658 if (!m_app->x11Connection()) {
659 return;
660 }
661
662 Q_EMIT m_app->x11ConnectionAboutToBeDestroyed();
663
664 Xcb::setInputFocus(XCB_INPUT_FOCUS_POINTER_ROOT);
665 m_app->destroyAtoms();
667
668 xcb_disconnect(m_app->x11Connection());
669
670 m_app->setX11Connection(nullptr);
671 m_app->setX11RootWindow(XCB_WINDOW_NONE);
672
673 Q_EMIT m_app->x11ConnectionChanged();
674}
675
676DragEventReply Xwayland::dragMoveFilter(Window *target)
677{
678 if (m_dataBridge) {
679 return m_dataBridge->dragMoveFilter(target);
680 } else {
682 }
683}
684
685AbstractDropHandler *Xwayland::xwlDropHandler()
686{
687 if (m_dataBridge) {
688 return m_dataBridge->dnd()->dropHandler();
689 } else {
690 return nullptr;
691 }
692}
693
694} // namespace Xwl
695} // namespace KWin
696
697#include "moc_xwayland.cpp"
void installNativeX11EventFilter()
Definition main.cpp:298
void setX11RootWindow(xcb_window_t root)
Definition main.h:204
void createAtoms()
Definition main.cpp:263
void destroyAtoms()
Definition main.cpp:151
void setProcessStartupEnvironment(const QProcessEnvironment &environment)
Definition main.cpp:633
QProcessEnvironment processStartupEnvironment() const
Definition main.cpp:628
void removeNativeX11EventFilter()
Definition main.cpp:303
void * x11Connection
Definition main.h:73
void x11ConnectionChanged()
void x11ConnectionAboutToBeDestroyed()
void setX11Connection(xcb_connection_t *c)
Definition main.h:212
Convenient Class which represents a wl_client.
wl_client * client() const
void installInputEventSpy(InputEventSpy *spy)
KeyboardInputRedirection * keyboard() const
Definition input.h:216
void uninstallInputEventSpy(InputEventSpy *spy)
SurfaceInterface * focusedSurface() const
Definition keyboard.cpp:252
void sendKey(quint32 key, KeyboardKeyState state)
Definition keyboard.cpp:194
XwaylandEavesdropsMode xwaylandEavesdrops() const
Definition options.h:261
void xwaylandEavesdropsChanged()
void focusedKeyboardSurfaceAboutToChange(SurfaceInterface *nextSurface)
KeyboardInterface * keyboard() const
Definition seat.cpp:963
Resource representing a wl_surface.
Definition surface.h:80
ClientConnection * client() const
Definition surface.cpp:444
SeatInterface * seat() const
ClientConnection * xWaylandConnection() const
virtual bool isLockScreen() const
Definition window.h:2007
void outputOrderChanged()
Window * activeWindow() const
Definition workspace.h:767
QList< Output * > outputOrder() const
static Extensions * self()
Definition xcbutils.cpp:346
int randrNotifyEvent() const
Definition xcbutils.cpp:529
bool event(xcb_generic_event_t *event) override
Definition xwayland.cpp:77
XrandrEventFilter(Xwayland *backend)
Definition xwayland.cpp:71
Xwayland(Application *app)
Definition xwayland.cpp:413
~Xwayland() override
Definition xwayland.cpp:422
XwaylandLauncher * xwaylandLauncher() const
Definition xwayland.cpp:439
friend class XrandrEventFilter
Definition xwayland.h:66
void setMode(XwaylandEavesdropsMode mode)
Definition xwayland.cpp:111
QHash< quint32, KeyboardKeyState > m_states
Definition xwayland.cpp:409
void keyEvent(KWin::KeyEvent *event) override
Definition xwayland.cpp:360
std::function< bool(int key, Qt::KeyboardModifiers)> m_filter
Definition xwayland.cpp:410
bool updateKey(quint32 key, KeyboardKeyState state)
Definition xwayland.cpp:395
KWayland::Client::Seat * seat
QList< KWayland::Client::Output * > outputs
uint32_t toXNative(qreal value)
Definition xcbutils.cpp:618
XwaylandEavesdropsMode
Definition options.h:36
@ All
Definition options.h:40
@ AllKeysWithModifier
Definition options.h:39
@ None
Definition options.h:37
@ NonCharacterKeys
Definition options.h:38
WaylandServer * waylandServer()
Workspace * workspace()
Definition workspace.h:830
KWIN_EXPORT xcb_connection_t * connection()
Definition xcb.h:19
Options * options
Definition main.cpp:73
InputRedirection * input()
Definition input.h:549
KeyboardKeyState
Definition seat.h:82