diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 471a1f7eba..b9898ad908 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -134,6 +134,7 @@ target_sources(kwin PRIVATE surfaceitem_x11.cpp syncalarmx11filter.cpp tablet_input.cpp + tabletmodemanager.cpp hide_cursor_spy.cpp touch_input.cpp udev.cpp @@ -296,10 +297,8 @@ kcoreaddons_target_static_plugins(kwin_x11 "kwin/effects/plugins") install(TARGETS kwin ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} LIBRARY NAMELINK_SKIP) install(TARGETS kwin_x11 ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) -add_executable(kwin_wayland - main_wayland.cpp - tabletmodemanager.cpp -) +add_executable(kwin_wayland main_wayland.cpp) + target_link_libraries(kwin_wayland kwin KF5::Crash diff --git a/src/main_x11.cpp b/src/main_x11.cpp index 01ca4a1762..fb87efca8c 100644 --- a/src/main_x11.cpp +++ b/src/main_x11.cpp @@ -14,6 +14,7 @@ #include "platform.h" #include "sm.h" +#include "tabletmodemanager.h" #include "utils/xcbutils.h" #include "workspace.h" @@ -274,6 +275,8 @@ void ApplicationX11::performStartup() owner->claim(m_replace || wasCrash(), true); createAtoms(); + + TabletModeManager::create(this); } bool ApplicationX11::notify(QObject *o, QEvent *e) diff --git a/src/tabletmodemanager.cpp b/src/tabletmodemanager.cpp index 48e04b2c78..6fa204748e 100644 --- a/src/tabletmodemanager.cpp +++ b/src/tabletmodemanager.cpp @@ -12,6 +12,8 @@ #include "input_event.h" #include "input_event_spy.h" #include "inputdevice.h" +#include "main.h" +#include "wayland_server.h" #include @@ -107,18 +109,48 @@ private: TabletModeManager::TabletModeManager(QObject *parent) : QObject(parent) { - if (input()->hasTabletModeSwitch()) { - input()->installInputEventSpy(new TabletModeSwitchEventSpy(this)); - } else { - hasTabletModeInputChanged(false); + if (waylandServer()) { + if (input()->hasTabletModeSwitch()) { + input()->installInputEventSpy(new TabletModeSwitchEventSpy(this)); + } else { + hasTabletModeInputChanged(false); + } } + KSharedConfig::Ptr kwinSettings = kwinApp()->config(); + m_settingsWatcher = KConfigWatcher::create(kwinSettings); + connect(m_settingsWatcher.data(), &KConfigWatcher::configChanged, this, &KWin::TabletModeManager::refreshSettings); + refreshSettings(); + QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/KWin"), QStringLiteral("org.kde.KWin.TabletModeManager"), this, QDBusConnection::ExportAllProperties | QDBusConnection::ExportAllSignals); - connect(input(), &InputRedirection::hasTabletModeSwitchChanged, this, &TabletModeManager::hasTabletModeInputChanged); + if (waylandServer()) { + connect(input(), &InputRedirection::hasTabletModeSwitchChanged, this, &TabletModeManager::hasTabletModeInputChanged); + } +} + +void KWin::TabletModeManager::refreshSettings() +{ + KSharedConfig::Ptr kwinSettings = kwinApp()->config(); + KConfigGroup cg = kwinSettings->group("Input"); + const QString tabletModeConfig = cg.readPathEntry("TabletMode", QStringLiteral("auto")); + const bool oldEffectiveTabletMode = effectiveTabletMode(); + if (tabletModeConfig == QStringLiteral("on")) { + m_configuredMode = ConfiguredMode::On; + if (!m_detecting) { + Q_EMIT tabletModeAvailableChanged(true); + } + Q_EMIT tabletModeChanged(true); + } else if (tabletModeConfig == QStringLiteral("off")) { + m_configuredMode = ConfiguredMode::Off; + Q_EMIT tabletModeChanged(false); + } else { + m_configuredMode = ConfiguredMode::Auto; + Q_EMIT tabletModeChanged(effectiveTabletMode()); + } } void KWin::TabletModeManager::hasTabletModeInputChanged(bool set) @@ -141,6 +173,23 @@ bool TabletModeManager::isTabletModeAvailable() const return m_detecting; } +bool TabletModeManager::effectiveTabletMode() const +{ + switch (m_configuredMode) { + case ConfiguredMode::Off: + return false; + case ConfiguredMode::On: + return true; + case ConfiguredMode::Auto: + default: + if (!waylandServer()) { + return false; + } else { + return m_isTabletMode; + } + } +} + bool TabletModeManager::isTablet() const { return m_isTabletMode; @@ -152,16 +201,26 @@ void TabletModeManager::setIsTablet(bool tablet) return; } + const bool oldTabletMode = effectiveTabletMode(); m_isTabletMode = tablet; - Q_EMIT tabletModeChanged(tablet); + if (effectiveTabletMode() != oldTabletMode) { + Q_EMIT tabletModeChanged(effectiveTabletMode()); + } } void KWin::TabletModeManager::setTabletModeAvailable(bool detecting) { - if (m_detecting != detecting) { - m_detecting = detecting; - Q_EMIT tabletModeAvailableChanged(detecting); + if (m_detecting == detecting) { + return; } + + m_detecting = detecting; + Q_EMIT tabletModeAvailableChanged(isTabletModeAvailable()); +} + +KWin::TabletModeManager::ConfiguredMode KWin::TabletModeManager::configuredMode() const +{ + return m_configuredMode; } } // namespace KWin diff --git a/src/tabletmodemanager.h b/src/tabletmodemanager.h index 17c26f8cae..06a9657196 100644 --- a/src/tabletmodemanager.h +++ b/src/tabletmodemanager.h @@ -8,39 +8,54 @@ #ifndef KWIN_TABLETMODEMANAGER_H #define KWIN_TABLETMODEMANAGER_H +#include #include +#include +#include #include namespace KWin { -class TabletModeManager : public QObject +class KWIN_EXPORT TabletModeManager : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.KWin.TabletModeManager") // assuming such a switch is not pluggable for now Q_PROPERTY(bool tabletModeAvailable READ isTabletModeAvailable NOTIFY tabletModeAvailableChanged) - Q_PROPERTY(bool tabletMode READ isTablet NOTIFY tabletModeChanged) + Q_PROPERTY(bool tabletMode READ effectiveTabletMode NOTIFY tabletModeChanged) public: + enum class ConfiguredMode { + Auto, + Off, + On + }; + ~TabletModeManager() override = default; void setTabletModeAvailable(bool detecting); bool isTabletModeAvailable() const; + bool effectiveTabletMode() const; bool isTablet() const; void setIsTablet(bool tablet); + ConfiguredMode configuredMode() const; + Q_SIGNALS: void tabletModeAvailableChanged(bool available); void tabletModeChanged(bool tabletMode); private: void hasTabletModeInputChanged(bool set); + void refreshSettings(); + KConfigWatcher::Ptr m_settingsWatcher; bool m_tabletModeAvailable = false; bool m_isTabletMode = false; bool m_detecting = false; + ConfiguredMode m_configuredMode = ConfiguredMode::Auto; KWIN_SINGLETON_VARIABLE(TabletModeManager, s_manager) }; }