diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -667,7 +667,7 @@ install(TARGETS kdeinit_kwin_x11 ${INSTALL_TARGETS_DEFAULT_ARGS} ) install(TARGETS kwin_x11 ${INSTALL_TARGETS_DEFAULT_ARGS} ) -add_executable(kwin_wayland main_wayland.cpp) +add_executable(kwin_wayland tabletmodemanager.cpp main_wayland.cpp) target_link_libraries(kwin_wayland kwin) if (HAVE_LIBCAP) target_link_libraries(kwin_wayland ${Libcap_LIBRARIES}) diff --git a/main_wayland.cpp b/main_wayland.cpp --- a/main_wayland.cpp +++ b/main_wayland.cpp @@ -25,6 +25,7 @@ // kwin #include "platform.h" #include "effects.h" +#include "tabletmodemanager.h" #include "wayland_server.h" #include "xcbutils.h" @@ -168,6 +169,7 @@ VirtualKeyboard::create(this); createBackend(); + TabletModeManager::create(this); } void ApplicationWayland::createBackend() diff --git a/tabletmodemanager.h b/tabletmodemanager.h new file mode 100644 --- /dev/null +++ b/tabletmodemanager.h @@ -0,0 +1,53 @@ +/* + * 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") + Q_PROPERTY(bool tabletMode READ isTablet NOTIFY tabletModeChanged) + +public: + ~TabletModeManager(); + 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,103 @@ +/* + * 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() +{ + delete m_spy; +} + +bool TabletModeManager::isTablet() const +{ + return m_isTabletMode; +} + +void TabletModeManager::setIsTablet(bool tablet) +{ + if (m_isTabletMode == tablet) { + return; + } + + m_isTabletMode = tablet; + emit tabletModeChanged(tablet); +}