/* * Copyright (C) 2022 Tianjin KYLIN Information Technology Co., Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * **/ #include "plasma-shell-manager.h" #include #include #include #include #include #include #include static PlasmaShellManager* global_instance = nullptr; PlasmaShellManager *PlasmaShellManager::getInstance() { if(QString(qgetenv("XDG_SESSION_TYPE")) != "wayland" || QX11Info::isPlatformX11()){ return nullptr; } if (!global_instance) { global_instance = new PlasmaShellManager; qDebug() << "Here create instance..."; } qDebug() << "Return instance"; return global_instance; } bool PlasmaShellManager::setAppWindowActive() { if (!supportPlasmaWindowManagement()) return false; m_appWindow->requestActivate(); return true; } bool PlasmaShellManager::setAppWindowKeepAbove(bool keep) { if (!supportPlasmaWindowManagement()) { qDebug() << "false"; return false; } if(keep != m_appWindow->isKeepAbove()) { qDebug() << "to keep above"; m_appWindow->requestToggleKeepAbove(); } return true; } bool PlasmaShellManager::setMaximized(QWindow *window) { if (!supportShell()) return false; auto surface = KWayland::Client::Surface::fromWindow(window); if (!surface) return false; auto shellSurface = m_shell->createSurface(surface, window); if (!shellSurface) return false; shellSurface->setMaximized(); return true; } bool PlasmaShellManager::setRole(QWindow *window, KWayland::Client::PlasmaShellSurface::Role role) { if (!supportPlasmaShell()) return false; auto surface = KWayland::Client::Surface::fromWindow(window); if (!surface) return false; auto plasmaShellSurface = m_plasmaShell->createSurface(surface, window); if (!plasmaShellSurface) return false; plasmaShellSurface->setRole(role); return true; } bool PlasmaShellManager::setPos(QWindow *window, const QPoint &pos) { if (!supportPlasmaShell()) return false; auto surface = KWayland::Client::Surface::fromWindow(window); if (!surface) return false; auto plasmaShellSurface = m_plasmaShell->createSurface(surface, window); if (!plasmaShellSurface) return false; plasmaShellSurface->setPosition(pos); return true; } bool PlasmaShellManager::supportPlasmaShell() { return m_plasmaShell; } bool PlasmaShellManager::supportShell() { return m_shell; } bool PlasmaShellManager::supportPlasmaWindowManagement() { return m_windowManager && m_appWindow; } bool PlasmaShellManager::supportFakeInput() { return m_fakeInput; } bool PlasmaShellManager::supportKeyState() { return m_keyState; } KWayland::Client::Keystate::State PlasmaShellManager::getKeyState(KWayland::Client::Keystate::Key key) { if(!supportKeyState()){ return KWayland::Client::Keystate::Unlocked; } return m_keyStateMap[key]; } void PlasmaShellManager::setKeyPressed(quint32 key) { if(!supportFakeInput()) return ; m_fakeInput->requestKeyboardKeyPress(key); m_fakeInput->requestKeyboardKeyRelease(key); } PlasmaShellManager::PlasmaShellManager(QObject *parent) : QObject(parent) { m_keyStateMap.insert(KWayland::Client::Keystate::Key::CapsLock,KWayland::Client::Keystate::Unlocked); m_keyStateMap.insert(KWayland::Client::Keystate::Key::NumLock,KWayland::Client::Keystate::Unlocked); m_keyStateMap.insert(KWayland::Client::Keystate::Key::ScrollLock,KWayland::Client::Keystate::Unlocked); auto connection = KWayland::Client::ConnectionThread::fromApplication(qApp); auto registry = new KWayland::Client::Registry(this); registry->create(connection->display()); connect(registry, &KWayland::Client::Registry::plasmaShellAnnounced, this, [=](){ qDebug() << "plasmaShellAnnounced..."; const auto interface = registry->interface(KWayland::Client::Registry::Interface::PlasmaShell); if (interface.name != 0) { qDebug() << "createPlasmaShell..."; m_plasmaShell = registry->createPlasmaShell(interface.name, interface.version, this); } }); connect(registry, &KWayland::Client::Registry::plasmaWindowManagementAnnounced, this, [=](){ qDebug() << "plasmaWindowManagementAnnounced"; const auto interface = registry->interface(KWayland::Client::Registry::Interface::PlasmaWindowManagement); if (interface.name != 0) { qDebug() << "createPlasmaWindowManagement"; m_windowManager = registry->createPlasmaWindowManagement(interface.name, interface.version, this); } if(m_windowManager) { connect(m_windowManager, &KWayland::Client::PlasmaWindowManagement::windowCreated, [this](KWayland::Client::PlasmaWindow *window) { qDebug()<< "PlasmaWindow..."; if (window->pid() == getpid()) { if(isFirstCreate) { isFirstCreate = false; m_appWindow = window; connect(m_appWindow, &KWayland::Client::PlasmaWindow::activeChanged, [this]() { this->setAppWindowKeepAbove(true); this->setAppWindowActive(); }); connect(m_appWindow, &KWayland::Client::PlasmaWindow::keepAboveChanged, [this]() { this->setAppWindowKeepAbove(true); this->setAppWindowActive(); }); } } }); } }); connect(registry, &KWayland::Client::Registry::shellAnnounced, this, [=](){ const auto interface = registry->interface(KWayland::Client::Registry::Interface::Shell); if (interface.name != 0) { m_shell = registry->createShell(interface.name, interface.version, this); } }); connect(registry, &KWayland::Client::Registry::fakeInputAnnounced, this, [=](){ qDebug()<<"fakeInputAnnounced"; const auto interface = registry->interface(KWayland::Client::Registry::Interface::FakeInput); if (interface.name != 0) { qDebug()<<"createFakeInput"; m_fakeInput = registry->createFakeInput(interface.name, interface.version); m_fakeInput->authenticate("ukui-screensaver-dialog","virual keyboard"); } }); connect(registry, &KWayland::Client::Registry::keystateAnnounced, this, [=](){ qDebug()<<"keystateAnnounced"; const auto interface = registry->interface(KWayland::Client::Registry::Interface::Keystate); if (interface.name != 0) { qDebug()<<"createKeyState"; m_keyState = registry->createKeystate(interface.name, interface.version); if(m_keyState){ connect(m_keyState, &KWayland::Client::Keystate::stateChanged, [this](KWayland::Client::Keystate::Key key,KWayland::Client::Keystate::State state) { qDebug()<<"key = "<fetchStates(); } } }); registry->setup(); connection->roundtrip(); }