configurable way to force tabletmode on or off

The user may want to never have it, or may be needed to enable
or disable it for debugging purposes
This commit is contained in:
Marco Martin 2022-05-12 09:47:16 +00:00
parent 654313d460
commit 796e1cf5bf
4 changed files with 91 additions and 15 deletions

View file

@ -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

View file

@ -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)

View file

@ -12,6 +12,8 @@
#include "input_event.h"
#include "input_event_spy.h"
#include "inputdevice.h"
#include "main.h"
#include "wayland_server.h"
#include <QDBusConnection>
@ -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

View file

@ -8,39 +8,54 @@
#ifndef KWIN_TABLETMODEMANAGER_H
#define KWIN_TABLETMODEMANAGER_H
#include <KConfigWatcher>
#include <QObject>
#include <config-kwin.h>
#include <kwin_export.h>
#include <kwinglobals.h>
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)
};
}