Changeset View
Changeset View
Standalone View
Standalone View
wayland_server.cpp
Show First 20 Lines • Show All 86 Lines • ▼ Show 20 Line(s) | |||||
87 | KWIN_SINGLETON_FACTORY(WaylandServer) | 87 | KWIN_SINGLETON_FACTORY(WaylandServer) | ||
88 | 88 | | |||
89 | WaylandServer::WaylandServer(QObject *parent) | 89 | WaylandServer::WaylandServer(QObject *parent) | ||
90 | : QObject(parent) | 90 | : QObject(parent) | ||
91 | { | 91 | { | ||
92 | qRegisterMetaType<KWayland::Server::OutputInterface::DpmsMode>(); | 92 | qRegisterMetaType<KWayland::Server::OutputInterface::DpmsMode>(); | ||
93 | 93 | | |||
94 | connect(kwinApp(), &Application::screensCreated, this, &WaylandServer::initOutputs); | 94 | connect(kwinApp(), &Application::screensCreated, this, &WaylandServer::initOutputs); | ||
95 | // connect(kwinApp(), &Application::x11ConnectionChanged, this, &WaylandServer::setupX11ClipboardSync); | | |||
96 | } | 95 | } | ||
97 | 96 | | |||
98 | WaylandServer::~WaylandServer() | 97 | WaylandServer::~WaylandServer() | ||
99 | { | 98 | { | ||
100 | destroyInputMethodConnection(); | 99 | destroyInputMethodConnection(); | ||
101 | } | 100 | } | ||
102 | 101 | | |||
103 | void WaylandServer::destroyInternalConnection() | 102 | void WaylandServer::destroyInternalConnection() | ||
▲ Show 20 Lines • Show All 146 Lines • ▼ Show 20 Line(s) | 190 | { | |||
250 | 249 | | |||
251 | m_display->createShm(); | 250 | m_display->createShm(); | ||
252 | m_seat = m_display->createSeat(m_display); | 251 | m_seat = m_display->createSeat(m_display); | ||
253 | m_seat->create(); | 252 | m_seat->create(); | ||
254 | m_display->createPointerGestures(PointerGesturesInterfaceVersion::UnstableV1, m_display)->create(); | 253 | m_display->createPointerGestures(PointerGesturesInterfaceVersion::UnstableV1, m_display)->create(); | ||
255 | m_display->createPointerConstraints(PointerConstraintsInterfaceVersion::UnstableV1, m_display)->create(); | 254 | m_display->createPointerConstraints(PointerConstraintsInterfaceVersion::UnstableV1, m_display)->create(); | ||
256 | m_dataDeviceManager = m_display->createDataDeviceManager(m_display); | 255 | m_dataDeviceManager = m_display->createDataDeviceManager(m_display); | ||
257 | m_dataDeviceManager->create(); | 256 | m_dataDeviceManager->create(); | ||
258 | connect(m_dataDeviceManager, &DataDeviceManagerInterface::dataDeviceCreated, this, | | |||
259 | [this] (DataDeviceInterface *ddi) { | | |||
260 | if (ddi->client() == m_xclipbaordSync.client && m_xclipbaordSync.client != nullptr) { | | |||
261 | m_xclipbaordSync.ddi = QPointer<DataDeviceInterface>(ddi); | | |||
262 | emit xclipboardSyncDataDeviceCreated(); | | |||
263 | connect(m_xclipbaordSync.ddi.data(), &DataDeviceInterface::selectionChanged, this, | | |||
264 | [this] { | | |||
265 | // testing whether the active client inherits Client | | |||
266 | // it would be better to test for the keyboard focus, but we might get a clipboard update | | |||
267 | // when the Client is already active, but no Surface is created yet. | | |||
268 | if (workspace()->activeClient() && workspace()->activeClient()->inherits("KWin::Client")) { | | |||
269 | m_seat->setSelection(m_xclipbaordSync.ddi.data()); | | |||
270 | } | | |||
271 | } | | |||
272 | ); | | |||
273 | } | | |||
274 | } | | |||
275 | ); | | |||
276 | m_idle = m_display->createIdle(m_display); | 257 | m_idle = m_display->createIdle(m_display); | ||
277 | m_idle->create(); | 258 | m_idle->create(); | ||
278 | auto idleInhibition = new IdleInhibition(m_idle); | 259 | auto idleInhibition = new IdleInhibition(m_idle); | ||
279 | connect(this, &WaylandServer::shellClientAdded, idleInhibition, &IdleInhibition::registerShellClient); | 260 | connect(this, &WaylandServer::shellClientAdded, idleInhibition, &IdleInhibition::registerShellClient); | ||
280 | m_display->createIdleInhibitManager(IdleInhibitManagerInterfaceVersion::UnstableV1, m_display)->create(); | 261 | m_display->createIdleInhibitManager(IdleInhibitManagerInterfaceVersion::UnstableV1, m_display)->create(); | ||
281 | m_plasmaShell = m_display->createPlasmaShell(m_display); | 262 | m_plasmaShell = m_display->createPlasmaShell(m_display); | ||
282 | m_plasmaShell->create(); | 263 | m_plasmaShell->create(); | ||
283 | connect(m_plasmaShell, &PlasmaShellInterface::surfaceCreated, | 264 | connect(m_plasmaShell, &PlasmaShellInterface::surfaceCreated, | ||
▲ Show 20 Lines • Show All 248 Lines • ▼ Show 20 Line(s) | 502 | { | |||
532 | return socket.fd; | 513 | return socket.fd; | ||
533 | } | 514 | } | ||
534 | 515 | | |||
535 | void WaylandServer::destroyXWaylandConnection() | 516 | void WaylandServer::destroyXWaylandConnection() | ||
536 | { | 517 | { | ||
537 | if (!m_xwayland.client) { | 518 | if (!m_xwayland.client) { | ||
538 | return; | 519 | return; | ||
539 | } | 520 | } | ||
540 | // first terminate the clipboard sync | | |||
541 | if (m_xclipbaordSync.process) { | | |||
542 | m_xclipbaordSync.process->terminate(); | | |||
543 | } | | |||
544 | disconnect(m_xwayland.destroyConnection); | 521 | disconnect(m_xwayland.destroyConnection); | ||
545 | m_xwayland.client->destroy(); | 522 | m_xwayland.client->destroy(); | ||
546 | m_xwayland.client = nullptr; | 523 | m_xwayland.client = nullptr; | ||
547 | } | 524 | } | ||
548 | 525 | | |||
549 | int WaylandServer::createInputMethodConnection() | 526 | int WaylandServer::createInputMethodConnection() | ||
550 | { | 527 | { | ||
551 | const auto socket = createConnection(); | 528 | const auto socket = createConnection(); | ||
552 | if (!socket.connection) { | 529 | if (!socket.connection) { | ||
553 | return -1; | 530 | return -1; | ||
554 | } | 531 | } | ||
555 | m_inputMethodServerConnection = socket.connection; | 532 | m_inputMethodServerConnection = socket.connection; | ||
556 | return socket.fd; | 533 | return socket.fd; | ||
557 | } | 534 | } | ||
558 | 535 | | |||
559 | void WaylandServer::destroyInputMethodConnection() | 536 | void WaylandServer::destroyInputMethodConnection() | ||
560 | { | 537 | { | ||
561 | if (!m_inputMethodServerConnection) { | 538 | if (!m_inputMethodServerConnection) { | ||
562 | return; | 539 | return; | ||
563 | } | 540 | } | ||
564 | m_inputMethodServerConnection->destroy(); | 541 | m_inputMethodServerConnection->destroy(); | ||
565 | m_inputMethodServerConnection = nullptr; | 542 | m_inputMethodServerConnection = nullptr; | ||
566 | } | 543 | } | ||
567 | 544 | | |||
568 | int WaylandServer::createXclipboardSyncConnection() | | |||
569 | { | | |||
570 | const auto socket = createConnection(); | | |||
571 | if (!socket.connection) { | | |||
572 | return -1; | | |||
573 | } | | |||
574 | m_xclipbaordSync.client = socket.connection; | | |||
575 | return socket.fd; | | |||
576 | } | | |||
577 | | ||||
578 | void WaylandServer::setupX11ClipboardSync() | | |||
579 | { | | |||
580 | if (m_xclipbaordSync.process) { | | |||
581 | qCWarning(KWIN_CORE) << "Tried to start x clipboard syncer although process already started"; | | |||
582 | return; | | |||
583 | } | | |||
584 | | ||||
585 | int socket = dup(createXclipboardSyncConnection()); | | |||
586 | if (socket == -1) { | | |||
587 | delete m_xclipbaordSync.client; | | |||
588 | m_xclipbaordSync.client = nullptr; | | |||
589 | qCWarning(KWIN_CORE) << "Could not create wayland socket for x clipboard syncer"; | | |||
590 | return; | | |||
591 | } | | |||
592 | if (socket >= 0) { | | |||
593 | QProcessEnvironment environment = kwinApp()->processStartupEnvironment(); | | |||
594 | environment.insert(QStringLiteral("WAYLAND_SOCKET"), QByteArray::number(socket)); | | |||
595 | environment.insert(QStringLiteral("DISPLAY"), QString::fromUtf8(qgetenv("DISPLAY"))); | | |||
596 | environment.remove("WAYLAND_DISPLAY"); | | |||
597 | m_xclipbaordSync.process = new Process(this); | | |||
598 | m_xclipbaordSync.process->setProcessChannelMode(QProcess::ForwardedChannels); | | |||
599 | auto finishedSignal = static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished); | | |||
600 | connect(m_xclipbaordSync.process, finishedSignal, this, | | |||
601 | [this] { | | |||
602 | qCDebug(KWIN_CORE) << "X clipboard syncer process finished"; | | |||
603 | m_xclipbaordSync.process->deleteLater(); | | |||
604 | m_xclipbaordSync.process = nullptr; | | |||
605 | m_xclipbaordSync.ddi.clear(); | | |||
606 | m_xclipbaordSync.client->destroy(); | | |||
607 | m_xclipbaordSync.client = nullptr; | | |||
608 | // TODO: restart | | |||
609 | } | | |||
610 | ); | | |||
611 | m_xclipbaordSync.process->setProcessEnvironment(environment); | | |||
612 | // start from build directory if executable is available there (e.g. autotests), otherwise start libexec executable | | |||
613 | const QFileInfo clipboardSync{QDir{QCoreApplication::applicationDirPath()}, QStringLiteral("org_kde_kwin_xclipboard_syncer")}; | | |||
614 | if (clipboardSync.exists()) { | | |||
615 | qCDebug(KWIN_CORE) << "Starting" << clipboardSync.absoluteFilePath(); | | |||
616 | m_xclipbaordSync.process->start(clipboardSync.absoluteFilePath()); | | |||
617 | } else { | | |||
618 | qCDebug(KWIN_CORE) << "Starting" << KWIN_XCLIPBOARD_SYNC_BIN; | | |||
619 | m_xclipbaordSync.process->start(QStringLiteral(KWIN_XCLIPBOARD_SYNC_BIN)); | | |||
620 | } | | |||
621 | } | | |||
622 | } | | |||
623 | | ||||
624 | void WaylandServer::createInternalConnection() | 545 | void WaylandServer::createInternalConnection() | ||
625 | { | 546 | { | ||
626 | const auto socket = createConnection(); | 547 | const auto socket = createConnection(); | ||
627 | if (!socket.connection) { | 548 | if (!socket.connection) { | ||
628 | return; | 549 | return; | ||
629 | } | 550 | } | ||
630 | m_internalConnection.server = socket.connection; | 551 | m_internalConnection.server = socket.connection; | ||
631 | using namespace KWayland::Client; | 552 | using namespace KWayland::Client; | ||
▲ Show 20 Lines • Show All 201 Lines • Show Last 20 Lines |