From 07f3fbcbe4742304f9f2d6317f9fd0fc81f00788 Mon Sep 17 00:00:00 2001 From: Slava Aseev Date: Mon, 25 Jul 2022 17:41:29 +0300 Subject: [PATCH] kcms/keyboard: Handle /etc/X11/xinit/Xkbmap Re-set arguments from /etc/X11/xinit/Xkbmap if layout is not managed by kde (if the 'Use' value is disabled in kxkbrc [Layout]) or if 'ResetOldOptions' is disabled. --- kcms/keyboard/xkb_helper.cpp | 69 +++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/kcms/keyboard/xkb_helper.cpp b/kcms/keyboard/xkb_helper.cpp --- a/kcms/keyboard/xkb_helper.cpp +++ b/kcms/keyboard/xkb_helper.cpp @@ -35,6 +35,8 @@ static QString xmodmapExe; static const QString COMMAND_OPTIONS_SEPARATOR(QStringLiteral(",")); +static const auto ETC_X11_XINIT_XKBMAP = QStringLiteral("/etc/X11/xinit/Xkbmap"); + static QString getSetxkbmapExe() { if (setxkbmapNotFound) @@ -109,6 +111,70 @@ bool XkbHelper::runConfigLayoutCommand(c return true; } +class XkbMapArguments { +public: + XkbMapArguments() = default; + + XkbMapArguments(const QString &textArgs) + { + static const auto whitespace = QRegExp(QStringLiteral("\\s+")); + args = textArgs.split(whitespace, Qt::SkipEmptyParts); + } + + static XkbMapArguments fromConfig(const QString& configPath) + { + QFile file{configPath}; + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + return {}; + + return {QString::fromLatin1(file.readAll())}; + } + + QStringList get(const QString &optionName) const + { + auto argIdx = args.indexOf(optionName); + if (argIdx == -1 || argIdx == args.size() - 1) + return {}; + + return args.at(argIdx + 1).split(COMMAND_OPTIONS_SEPARATOR, Qt::SkipEmptyParts); + } + + void appendSomeTo(QStringList &destination, const QString &optionName, const QStringList &additionalOptions, bool joinWithComma) const + { + QStringList options = get(optionName); + if( options.size() < 1 ) { + return; + } + for (auto& additionalOpt : additionalOptions) + if (!options.contains(additionalOpt)) + options.append(additionalOpt); + + if (joinWithComma) { + destination.append(optionName); + destination.append(options.join(COMMAND_OPTIONS_SEPARATOR)); + } + else { + for (auto& option : options) { + destination.append(optionName); + destination.append(option); + } + } + } + + void appendOptionsTo(QStringList &destination, const QStringList &additionalOptions) const + { + appendSomeTo(destination, QStringLiteral("-option"), additionalOptions, false); + } + + void appendLayoutsTo(QStringList &destination, const QStringList &additionalLayouts) const + { + appendSomeTo(destination, QStringLiteral("-layout"), additionalLayouts, true); + } + +private: + QStringList args; +}; + bool XkbHelper::initializeKeyboardLayouts(const QList &layoutUnits) { QStringList layouts; @@ -132,6 +198,8 @@ bool XkbHelper::initializeKeyboardLayout bool XkbHelper::initializeKeyboardLayouts(KeyboardConfig &config) { QStringList setxkbmapCommandArguments; + bool xinitArgsResetRequired = !(config.configureLayouts() && config.resetOldXkbOptions()); + auto xkbMapArgs = xinitArgsResetRequired ? XkbMapArguments::fromConfig(ETC_X11_XINIT_XKBMAP) : XkbMapArguments(); if (!config.keyboardModel().isEmpty()) { XkbConfig xkbConfig; X11Helper::getGroupNames(QX11Info::display(), &xkbConfig, X11Helper::MODEL_ONLY); @@ -155,11 +223,15 @@ bool XkbHelper::initializeKeyboardLayout setxkbmapCommandArguments.append(QStringLiteral("-variant")); setxkbmapCommandArguments.append(variants.join(COMMAND_OPTIONS_SEPARATOR)); } + } else { + xkbMapArgs.appendLayoutsTo(setxkbmapCommandArguments, {}); } if (config.resetOldXkbOptions()) { // Pass -option "" to clear previously set options setxkbmapCommandArguments.append(QStringLiteral("-option")); setxkbmapCommandArguments.append(QStringLiteral("")); + } else { + xkbMapArgs.appendOptionsTo(setxkbmapCommandArguments, config.xkbOptions()); } const QStringList xkbOpts = config.xkbOptions(); for (const auto &option : xkbOpts) { -- 2.33.4