From 8417492781d0b61a9badf2ecfc93e01eb87592bb Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Fri, 9 Sep 2022 00:18:12 +0200 Subject: [PATCH] Include org.freedesktop.locale1 support Makes it possible to follow the dbus service for locale configuration, making it possible to have third parties integrate with Plasma. This is done opt-in for now, it can be adopted generally in the future, if necessary. --- autotests/CMakeLists.txt | 1 + src/CMakeLists.txt | 1 + src/main.h | 9 ++++++ src/main_wayland.cpp | 7 +++++ src/org.freedesktop.DBus.Properties.xml | 27 ++++++++++++++++++ src/xkb.cpp | 37 ++++++++++++++++++++++++- src/xkb.h | 8 +++++- 7 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 src/org.freedesktop.DBus.Properties.xml diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index d63c61fbf9..f3b5a36752 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -206,6 +206,7 @@ set(testXkb_SRCS ../src/xkb.cpp test_xkb.cpp ) +qt_add_dbus_interface(testXkb_SRCS ${CMAKE_SOURCE_DIR}/src/org.freedesktop.DBus.Properties.xml dbusproperties_interface) add_executable(testXkb ${testXkb_SRCS}) target_link_libraries(testXkb kwin diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0b7da29723..b33b10a399 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -238,6 +238,7 @@ qt_add_dbus_adaptor(kwin_dbus_SRCS ${kwin_effects_dbus_xml} effects.h KWin::Effe qt_add_dbus_adaptor(kwin_dbus_SRCS org.kde.KWin.VirtualDesktopManager.xml dbusinterface.h KWin::VirtualDesktopManagerDBusInterface) qt_add_dbus_adaptor(kwin_dbus_SRCS org.kde.KWin.Session.xml sm.h KWin::SessionManager) qt_add_dbus_adaptor(kwin_dbus_SRCS org.kde.KWin.Plugins.xml dbusinterface.h KWin::PluginManagerDBusInterface) +qt_add_dbus_interface(kwin_dbus_SRCS org.freedesktop.DBus.Properties.xml dbusproperties_interface) if (KWIN_BUILD_SCREENLOCKER) qt_add_dbus_interface(kwin_dbus_SRCS ${KSCREENLOCKER_DBUS_INTERFACES_DIR}/kf5_org.freedesktop.ScreenSaver.xml screenlocker_interface) diff --git a/src/main.h b/src/main.h index c24a003d1b..a2a2a0859e 100644 --- a/src/main.h +++ b/src/main.h @@ -225,6 +225,14 @@ public: return m_session.get(); } void setSession(std::unique_ptr &&session); + void setFollowLocale1(bool follow) + { + m_followLocale1 = follow; + } + bool followLocale1() const + { + return m_followLocale1; + } bool isTerminating() const { @@ -289,6 +297,7 @@ private: QList> m_eventFilters; QList> m_genericEventFilters; std::unique_ptr m_eventFilter; + bool m_followLocale1 = false; bool m_configLock; KSharedConfigPtr m_config; KSharedConfigPtr m_kxkbConfig; diff --git a/src/main_wayland.cpp b/src/main_wayland.cpp index e462c1e4b5..6102c735dd 100644 --- a/src/main_wayland.cpp +++ b/src/main_wayland.cpp @@ -47,6 +47,7 @@ #include #include +#include "keyboard_input.h" #include #include @@ -365,6 +366,7 @@ int main(int argc, char *argv[]) i18n("Exits this instance so it can be restarted by kwin_wayland_wrapper.")); QCommandLineOption drmOption(QStringLiteral("drm"), i18n("Render through drm node.")); + QCommandLineOption locale1Option(QStringLiteral("locale1"), i18n("Extract locale information from locale1 rather than the user's configuration")); QCommandLineParser parser; a.setupCommandLine(&parser); @@ -383,6 +385,7 @@ int main(int argc, char *argv[]) parser.addOption(scaleOption); parser.addOption(outputCountOption); parser.addOption(drmOption); + parser.addOption(locale1Option); QCommandLineOption inputMethodOption(QStringLiteral("inputmethod"), i18n("Input method that KWin starts."), @@ -476,6 +479,10 @@ int main(int argc, char *argv[]) } } + if (parser.isSet(locale1Option)) { + a.setFollowLocale1(true); + } + bool ok = false; const int width = parser.value(widthOption).toInt(&ok); if (!ok) { diff --git a/src/org.freedesktop.DBus.Properties.xml b/src/org.freedesktop.DBus.Properties.xml new file mode 100644 index 0000000000..0967d899b3 --- /dev/null +++ b/src/org.freedesktop.DBus.Properties.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/xkb.cpp b/src/xkb.cpp index 27c45ee457..9f1553121d 100644 --- a/src/xkb.cpp +++ b/src/xkb.cpp @@ -7,6 +7,7 @@ SPDX-License-Identifier: GPL-2.0-or-later */ #include "xkb.h" +#include "dbusproperties_interface.h" #include "utils/c_ptr.h" #include "utils/common.h" #include "wayland/keyboard_interface.h" @@ -25,6 +26,7 @@ #include #include // system +#include "main.h" #include #include #include @@ -35,6 +37,7 @@ Q_LOGGING_CATEGORY(KWIN_XKB, "kwin_xkbcommon", QtWarningMsg) /* The offset between KEY_* numbering, and keycodes in the XKB evdev * dataset. */ static const int EVDEV_OFFSET = 8; +static const char *s_locale1Interface = "org.freedesktop.locale1"; namespace KWin { @@ -86,6 +89,7 @@ Xkb::Xkb(QObject *parent) , m_consumedModifiers(Qt::NoModifier) , m_keysym(XKB_KEY_NoSymbol) , m_leds() + , m_followLocale1(kwinApp()->followLocale1()) { qRegisterMetaType(); if (!m_context) { @@ -112,6 +116,16 @@ Xkb::Xkb(QObject *parent) m_compose.state = xkb_compose_state_new(m_compose.table, XKB_COMPOSE_STATE_NO_FLAGS); } } + + if (m_followLocale1) { + bool connected = QDBusConnection::systemBus().connect(s_locale1Interface, "/org/freedesktop/locale1", QStringLiteral("org.freedesktop.DBus.Properties"), + QStringLiteral("PropertiesChanged"), + this, + SLOT(reconfigure())); + if (!connected) { + qCWarning(KWIN_XKB) << "Could not connect to org.freedesktop.locale1"; + } + } } Xkb::~Xkb() @@ -141,7 +155,11 @@ void Xkb::reconfigure() xkb_keymap *keymap = nullptr; if (!qEnvironmentVariableIsSet("KWIN_XKB_DEFAULT_KEYMAP")) { - keymap = loadKeymapFromConfig(); + if (m_followLocale1) { + keymap = loadKeymapFromLocale1(); + } else { + keymap = loadKeymapFromConfig(); + } } if (!keymap) { qCDebug(KWIN_XKB) << "Could not create xkb keymap from configuration"; @@ -222,6 +240,23 @@ xkb_keymap *Xkb::loadDefaultKeymap() return xkb_keymap_new_from_names(m_context, &ruleNames, XKB_KEYMAP_COMPILE_NO_FLAGS); } +xkb_keymap *Xkb::loadKeymapFromLocale1() +{ + OrgFreedesktopDBusPropertiesInterface locale1Properties(s_locale1Interface, "/org/freedesktop/locale1", QDBusConnection::systemBus(), this); + const QVariantMap properties = locale1Properties.GetAll(s_locale1Interface); + const QString layouts = properties["X11Layout"].toString(); + xkb_rule_names ruleNames = { + nullptr, + qPrintable(properties["X11Model"].toString()), + qPrintable(layouts), + qPrintable(properties["X11Variant"].toString()), + qPrintable(properties["X11Options"].toString()), + }; + applyEnvironmentRules(ruleNames); + m_layoutList = layouts.split(QLatin1Char(',')); + return xkb_keymap_new_from_names(m_context, &ruleNames, XKB_KEYMAP_COMPILE_NO_FLAGS); +} + void Xkb::installKeymap(int fd, uint32_t size) { if (!m_context) { diff --git a/src/xkb.h b/src/xkb.h index 853fff93b1..572f1654dc 100644 --- a/src/xkb.h +++ b/src/xkb.h @@ -47,7 +47,6 @@ public: ~Xkb() override; void setConfig(const KSharedConfigPtr &config); void setNumLockConfig(const KSharedConfigPtr &config); - void reconfigure(); void installKeymap(int fd, uint32_t size); void updateModifiers(uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group); @@ -109,6 +108,11 @@ public: std::optional keycodeFromKeysym(xkb_keysym_t keysym); + void setFollowLocale1(bool follow); + +public Q_SLOTS: + void reconfigure(); + Q_SIGNALS: void ledsChanged(const LEDs &leds); void modifierStateChanged(); @@ -117,6 +121,7 @@ private: void applyEnvironmentRules(xkb_rule_names &); xkb_keymap *loadKeymapFromConfig(); xkb_keymap *loadDefaultKeymap(); + xkb_keymap *loadKeymapFromLocale1(); void updateKeymap(xkb_keymap *keymap); void createKeymapFile(); void updateModifiers(); @@ -162,6 +167,7 @@ private: Ownership m_ownership = Ownership::Server; QPointer m_seat; + const bool m_followLocale1; }; inline Qt::KeyboardModifiers Xkb::modifiers() const