diff --git a/backends/kwayland/CMakeLists.txt b/backends/kwayland/CMakeLists.txt
--- a/backends/kwayland/CMakeLists.txt
+++ b/backends/kwayland/CMakeLists.txt
@@ -6,12 +6,14 @@
waylandscreen.cpp
../utils.cpp
)
+qt5_add_dbus_interface(wayland_SRCS org.kde.KWin.TabletModeManager.xml tabletmodemanager_interface)
add_library(KSC_KWayland MODULE ${wayland_SRCS})
set_target_properties(KSC_KWayland PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kscreen")
set_target_properties(KSC_KWayland PROPERTIES PREFIX "")
target_link_libraries(KSC_KWayland Qt5::Core
+ Qt5::DBus
Qt5::Gui
KF5::Screen
KF5::WaylandClient
diff --git a/backends/kwayland/org.kde.KWin.TabletModeManager.xml b/backends/kwayland/org.kde.KWin.TabletModeManager.xml
new file mode 100644
--- /dev/null
+++ b/backends/kwayland/org.kde.KWin.TabletModeManager.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/backends/kwayland/waylandconfig.h b/backends/kwayland/waylandconfig.h
--- a/backends/kwayland/waylandconfig.h
+++ b/backends/kwayland/waylandconfig.h
@@ -80,6 +80,7 @@
void checkInitialized();
void disconnected();
+ void initKWinTabletMode();
void initConnection();
void addOutput(quint32 name, quint32 version);
@@ -109,6 +110,9 @@
KScreen::ConfigPtr m_kscreenConfig;
KScreen::ConfigPtr m_kscreenPendingConfig;
WaylandScreen *m_screen;
+
+ bool m_tabletModeAvailable;
+ bool m_tabletModeEngaged;
};
}
diff --git a/backends/kwayland/waylandconfig.cpp b/backends/kwayland/waylandconfig.cpp
--- a/backends/kwayland/waylandconfig.cpp
+++ b/backends/kwayland/waylandconfig.cpp
@@ -22,6 +22,8 @@
#include "waylandoutput.h"
#include "waylandscreen.h"
+#include "tabletmodemanager_interface.h"
+
#include
#include
@@ -43,6 +45,8 @@
, m_kscreenConfig(new Config)
, m_kscreenPendingConfig(nullptr)
, m_screen(new WaylandScreen(this))
+ , m_tabletModeAvailable(false)
+ , m_tabletModeEngaged(false)
{
connect(this, &WaylandConfig::initialized, &m_syncLoop, &QEventLoop::quit);
@@ -56,6 +60,7 @@
}
});
+ initKWinTabletMode();
initConnection();
m_syncLoop.exec();
}
@@ -67,6 +72,43 @@
m_syncLoop.quit();
}
+void WaylandConfig::initKWinTabletMode()
+{
+ auto *interface = new OrgKdeKWinTabletModeManagerInterface(QStringLiteral("org.kde.KWin"),
+ QStringLiteral("/org/kde/KWin"),
+ QDBusConnection::sessionBus(), this);
+ if (!interface->isValid()) {
+ m_tabletModeAvailable = false;
+ m_tabletModeEngaged = false;
+ return;
+ }
+
+ m_tabletModeAvailable = interface->tabletModeAvailable();
+ m_tabletModeEngaged = interface->tabletMode();
+
+ connect(interface, &OrgKdeKWinTabletModeManagerInterface::tabletModeChanged,
+ this, [this](bool tabletMode) {
+ if (m_tabletModeEngaged == tabletMode) {
+ return;
+ }
+ m_tabletModeEngaged = tabletMode;
+ if (!m_blockSignals && m_initializingOutputs.empty()) {
+ Q_EMIT configChanged();
+ }
+ }
+ );
+ connect(interface, &OrgKdeKWinTabletModeManagerInterface::tabletModeAvailableChanged,
+ this, [this](bool available) {
+ if (m_tabletModeAvailable == available) {
+ return;
+ }
+ m_tabletModeAvailable = available;
+ if (!m_blockSignals && m_initializingOutputs.empty()) {
+ Q_EMIT configChanged();
+ }
+ });
+}
+
void WaylandConfig::initConnection()
{
m_thread = new QThread(this);
@@ -227,6 +269,9 @@
m_kscreenConfig->setScreen(m_screen->toKScreenScreen(m_kscreenConfig));
auto features = Config::Feature::Writable | Config::Feature::PerOutputScaling;
+ // TODO: enable new features when all patches have landed
+// const auto features = Config::Feature::Writable | Config::Feature::PerOutputScaling
+// | Config::Feature::AutoRotation | Config::Feature::TabletMode;
m_kscreenConfig->setSupportedFeatures(features);
m_kscreenConfig->setValid(m_connection->display());
@@ -258,6 +303,9 @@
}
m_kscreenConfig->setOutputs(kscreenOutputs);
+ m_kscreenConfig->setTabletModeAvailable(m_tabletModeAvailable);
+ m_kscreenConfig->setTabletModeEngaged(m_tabletModeEngaged);
+
return m_kscreenConfig;
}
diff --git a/src/config.h b/src/config.h
--- a/src/config.h
+++ b/src/config.h
@@ -67,6 +67,8 @@
Writable = 1 << 1, ///< The backend supports setting the config, it's not read-only.
PerOutputScaling = 1 << 2, ///< The backend supports scaling each output individually.
OutputReplication = 1 << 3, ///< The backend supports replication of outputs.
+ AutoRotation = 1 << 4, ///< The backend supports automatic rotation of outputs.
+ TabletMode = 1 << 5, ///< The backend supports querying if a device is in tablet mode.
};
Q_DECLARE_FLAGS(Features, Feature)
@@ -165,6 +167,42 @@
*/
void setSupportedFeatures(const Features &features);
+ /**
+ * Indicates that the device supports switching between a default and a tablet mode. This is
+ * common for convertibles.
+ *
+ * @return true when tablet mode is available, otherwise false
+ * @see setTabletModeAvailable
+ * @since 5.18
+ */
+ bool tabletModeAvailable() const;
+
+ /** Sets if the device supports a tablet mode. This should not be called by the
+ * user, but by the backend.
+ *
+ * @see tabletModeAvailable
+ * @since 5.18
+ */
+ void setTabletModeAvailable(bool available);
+
+ /**
+ * Indicates that the device is currently in tablet mode.
+ *
+ * @return true when in tablet mode, otherwise false
+ * @see setTabletModeEngaged
+ * @since 5.18
+ */
+ bool tabletModeEngaged() const;
+
+ /**
+ * Sets if the device is currently in tablet mode. This should not be called by the
+ * user, but by the backend.
+ *
+ * @see tabletModeEngaged
+ * @since 5.18
+ */
+ void setTabletModeEngaged(bool engaged);
+
Q_SIGNALS:
void outputAdded(const KScreen::OutputPtr &output);
void outputRemoved(int outputId);
diff --git a/src/config.cpp b/src/config.cpp
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -38,6 +38,8 @@
: QObject(parent)
, valid(true)
, supportedFeatures(Config::Feature::None)
+ , tabletModeAvailable(false)
+ , tabletModeEngaged(false)
, q(parent)
{ }
@@ -90,6 +92,8 @@
OutputPtr primaryOutput;
OutputList outputs;
Features supportedFeatures;
+ bool tabletModeAvailable;
+ bool tabletModeEngaged;
private:
Config *q;
@@ -260,6 +264,26 @@
d->supportedFeatures = features;
}
+bool Config::tabletModeAvailable() const
+{
+ return d->tabletModeAvailable;
+}
+
+void Config::setTabletModeAvailable(bool available)
+{
+ d->tabletModeAvailable = available;
+}
+
+bool Config::tabletModeEngaged() const
+{
+ return d->tabletModeEngaged;
+}
+
+void Config::setTabletModeEngaged(bool engaged)
+{
+ d->tabletModeEngaged = engaged;
+}
+
OutputList Config::outputs() const
{
return d->outputs;