diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -432,6 +432,7 @@ geometry.cpp rules.cpp composite.cpp + tabletmodemanager.cpp toplevel.cpp unmanaged.cpp scene.cpp diff --git a/tabletmodemanager.h b/tabletmodemanager.h new file mode 100644 --- /dev/null +++ b/tabletmodemanager.h @@ -0,0 +1,55 @@ +/* + * Copyright 2018 Marco Martin + * + * 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 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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 . + * + */ + +#ifndef KWIN_TABLETMODEMANAGER_H +#define KWIN_TABLETMODEMANAGER_H + +#include +#include + +namespace KWin { + +class TabletModeInputEventSpy; + +class TabletModeManager : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.KWin.TabletModeManager") + //FIXME: the setter will not be exported in dbus in the final version + Q_PROPERTY(bool tabletMode READ isTablet WRITE setIsTablet NOTIFY tabletModeChanged) + +public: + //explicit TabletModeManager(QObject *parent = nullptr); + ~TabletModeManager() override; + bool isTablet() const; + void setIsTablet(bool tablet); + +Q_SIGNALS: + void tabletModeChanged(bool tabletMode); + +private: + bool m_isTabletMode = false; + TabletModeInputEventSpy *m_spy; + KWIN_SINGLETON_VARIABLE(TabletModeManager, s_manager) +}; +} + +#endif // KWIN_TABLETMODEMANAGER_H diff --git a/tabletmodemanager.cpp b/tabletmodemanager.cpp new file mode 100644 --- /dev/null +++ b/tabletmodemanager.cpp @@ -0,0 +1,106 @@ +/* + * Copyright 2018 Marco Martin + * + * 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 2 of + * the License or (at your option) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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 "tabletmodemanager.h" +#include "input.h" +#include "input_event.h" +#include "input_event_spy.h" + +#if HAVE_INPUT +#include "libinput/device.h" +#endif + +#include + +using namespace KWin; + +KWIN_SINGLETON_FACTORY_VARIABLE(TabletModeManager, s_manager) + +class KWin::TabletModeInputEventSpy : public InputEventSpy +{ +public: + explicit TabletModeInputEventSpy(TabletModeManager *parent); + + void switchEvent(SwitchEvent *event) override; +private: + TabletModeManager *m_parent; +}; + +TabletModeInputEventSpy::TabletModeInputEventSpy(TabletModeManager *parent) + : m_parent(parent) +{ +} + +void TabletModeInputEventSpy::switchEvent(SwitchEvent *event) +{ + if (!event->device()->isTabletModeSwitch()) { + return; + } + + switch (event->state()) { + case SwitchEvent::State::Off: + m_parent->setIsTablet(false); + break; + case SwitchEvent::State::On: + m_parent->setIsTablet(true); + break; + default: + Q_UNREACHABLE(); + } +} + + + +TabletModeManager::TabletModeManager(QObject *parent) + : QObject(parent) +{ + m_spy = new TabletModeInputEventSpy(this); + input()->installInputEventSpy(m_spy); + + QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/KWin"), + QStringLiteral("org.kde.KWin.TabletModeManager"), + this, + QDBusConnection::ExportAllProperties | QDBusConnection::ExportAllSignals + ); +} + +TabletModeManager::~TabletModeManager() +{ +} + +bool TabletModeManager::isTablet() const +{ + return m_isTabletMode; +} + +void TabletModeManager::setIsTablet(bool tablet) +{ + if (m_isTabletMode == tablet) { + return; + } + + m_isTabletMode = tablet; + emit tabletModeChanged(tablet); +} + + + +#include "tabletmodemanager.moc" diff --git a/workspace.cpp b/workspace.cpp --- a/workspace.cpp +++ b/workspace.cpp @@ -51,6 +51,7 @@ #ifdef KWIN_BUILD_TABBOX #include "tabbox.h" #endif +#include "tabletmodemanager.h" #include "unmanaged.h" #include "useractions.h" #include "virtualdesktops.h" @@ -179,6 +180,8 @@ connect(this, &Workspace::currentDesktopChanged, m_compositor, &Compositor::addRepaintFull); connect(m_compositor, &QObject::destroyed, this, [this] { m_compositor = nullptr; }); + TabletModeManager::create(this); + auto decorationBridge = Decoration::DecorationBridge::create(this); decorationBridge->init(); connect(this, &Workspace::configChanged, decorationBridge, &Decoration::DecorationBridge::reconfigure);