fix: keyboard layout applet: no flag if Display Name is set
If user set custom name for the layout, country flag is not displayed. Instead, Display Name is shown in the applet. This reveals shortcomings in current DBus API design. We need more data to pass over DBus to fix this. Then, multiple improvements are possible: - fix aforementioned bug - add flags to context menu - display correct translated Layout Name in the context menu - simpler, cleaner DBus API and applet implementation - etc.
This commit is contained in:
parent
d425e78cab
commit
d2da79cb8d
5 changed files with 83 additions and 55 deletions
|
@ -106,8 +106,7 @@ void KeyboardInputRedirection::init()
|
|||
m_input->installInputEventSpy(new KeyStateChangedSpy(m_input));
|
||||
m_modifiersChangedSpy = new ModifiersChangedSpy(m_input);
|
||||
m_input->installInputEventSpy(m_modifiersChangedSpy);
|
||||
m_keyboardLayout = new KeyboardLayout(m_xkb.data());
|
||||
m_keyboardLayout->setConfig(config);
|
||||
m_keyboardLayout = new KeyboardLayout(m_xkb.data(), config);
|
||||
m_keyboardLayout->init();
|
||||
m_input->installInputEventSpy(m_keyboardLayout);
|
||||
|
||||
|
|
|
@ -13,20 +13,21 @@
|
|||
#include "main.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include <KConfigGroup>
|
||||
#include <KGlobalAccel>
|
||||
#include <KLocalizedString>
|
||||
#include <QAction>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusPendingCall>
|
||||
#include <QDBusMetaType>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
KeyboardLayout::KeyboardLayout(Xkb *xkb)
|
||||
KeyboardLayout::KeyboardLayout(Xkb *xkb, const KSharedConfigPtr &config)
|
||||
: QObject()
|
||||
, m_xkb(xkb)
|
||||
, m_configGroup(config->group("Layout"))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -70,7 +71,7 @@ void KeyboardLayout::initDBusInterface()
|
|||
if (m_dbusInterface) {
|
||||
return;
|
||||
}
|
||||
m_dbusInterface = new KeyboardLayoutDBusInterface(m_xkb, this);
|
||||
m_dbusInterface = new KeyboardLayoutDBusInterface(m_xkb, m_configGroup, this);
|
||||
connect(this, &KeyboardLayout::layoutChanged, m_dbusInterface,
|
||||
[this] {
|
||||
emit m_dbusInterface->layoutChanged(m_xkb->layoutName());
|
||||
|
@ -103,14 +104,13 @@ void KeyboardLayout::switchToLayout(xkb_layout_index_t index)
|
|||
|
||||
void KeyboardLayout::reconfigure()
|
||||
{
|
||||
if (m_config) {
|
||||
m_config->reparseConfiguration();
|
||||
const KConfigGroup layoutGroup = m_config->group("Layout");
|
||||
const QString policyKey = layoutGroup.readEntry("SwitchMode", QStringLiteral("Global"));
|
||||
if (m_configGroup.isValid()) {
|
||||
m_configGroup.config()->reparseConfiguration();
|
||||
const QString policyKey = m_configGroup.readEntry("SwitchMode", QStringLiteral("Global"));
|
||||
m_xkb->reconfigure();
|
||||
if (!m_policy || m_policy->name() != policyKey) {
|
||||
delete m_policy;
|
||||
m_policy = KeyboardLayoutSwitching::Policy::create(m_xkb, this, layoutGroup, policyKey);
|
||||
m_policy = KeyboardLayoutSwitching::Policy::create(m_xkb, this, m_configGroup, policyKey);
|
||||
}
|
||||
} else {
|
||||
m_xkb->reconfigure();
|
||||
|
@ -181,11 +181,16 @@ void KeyboardLayout::notifyLayoutChange()
|
|||
static const QString s_keyboardService = QStringLiteral("org.kde.keyboard");
|
||||
static const QString s_keyboardObject = QStringLiteral("/Layouts");
|
||||
|
||||
KeyboardLayoutDBusInterface::KeyboardLayoutDBusInterface(Xkb *xkb, KeyboardLayout *parent)
|
||||
KeyboardLayoutDBusInterface::KeyboardLayoutDBusInterface(Xkb *xkb, const KConfigGroup &configGroup, KeyboardLayout *parent)
|
||||
: QObject(parent)
|
||||
, m_xkb(xkb)
|
||||
, m_configGroup(configGroup)
|
||||
, m_keyboardLayout(parent)
|
||||
{
|
||||
qRegisterMetaType<QVector<LayoutNames>>("QVector<LayoutNames>");
|
||||
qDBusRegisterMetaType<LayoutNames>();
|
||||
qDBusRegisterMetaType<QVector<LayoutNames>>();
|
||||
|
||||
QDBusConnection::sessionBus().registerService(s_keyboardService);
|
||||
QDBusConnection::sessionBus().registerObject(s_keyboardObject, this, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals);
|
||||
}
|
||||
|
@ -228,24 +233,43 @@ QString KeyboardLayoutDBusInterface::getLayout() const
|
|||
return m_xkb->layoutName();
|
||||
}
|
||||
|
||||
QString KeyboardLayoutDBusInterface::getLayoutDisplayName() const
|
||||
{
|
||||
return m_xkb->layoutShortName();
|
||||
}
|
||||
|
||||
QString KeyboardLayoutDBusInterface::getLayoutLongName() const
|
||||
{
|
||||
return translatedLayout(m_xkb->layoutName());
|
||||
}
|
||||
|
||||
QStringList KeyboardLayoutDBusInterface::getLayoutsList() const
|
||||
QVector<KeyboardLayoutDBusInterface::LayoutNames> KeyboardLayoutDBusInterface::getLayoutsList() const
|
||||
{
|
||||
const auto layouts = m_xkb->layoutNames();
|
||||
QStringList ret;
|
||||
for (auto it = layouts.begin(); it != layouts.end(); it++) {
|
||||
ret << it.value();
|
||||
const QStringList &shortNames = m_xkb->layoutShortNames();
|
||||
|
||||
// TODO: - should be handled by layout applet itself, it has nothing to do with KWin
|
||||
const QStringList displayNames = m_configGroup.readEntry("DisplayNames", QStringList());
|
||||
|
||||
QVector<LayoutNames> ret;
|
||||
const int layoutsSize = layouts.size();
|
||||
const int displayNamesSize = displayNames.size();
|
||||
for (int i = 0; i < layoutsSize; ++i) {
|
||||
const QString &id = layouts[i];
|
||||
ret.append( {id, shortNames.at(i), i < displayNamesSize ? displayNames.at(i) : QString(), translatedLayout(id)} );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QDBusArgument &operator<<(QDBusArgument &argument, const KeyboardLayoutDBusInterface::LayoutNames &layoutNames)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument << layoutNames.id << layoutNames.shortName << layoutNames.displayName << layoutNames.longName;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
const QDBusArgument &operator>>(const QDBusArgument &argument, KeyboardLayoutDBusInterface::LayoutNames &layoutNames)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument >> layoutNames.id >> layoutNames.shortName >> layoutNames.displayName >> layoutNames.longName;
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,9 +14,11 @@
|
|||
#include <QVector>
|
||||
|
||||
#include <KSharedConfig>
|
||||
#include <KConfigGroup>
|
||||
typedef uint32_t xkb_layout_index_t;
|
||||
|
||||
class QAction;
|
||||
class QDBusArgument;
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -32,12 +34,9 @@ class KeyboardLayout : public QObject, public InputEventSpy
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit KeyboardLayout(Xkb *xkb);
|
||||
~KeyboardLayout() override;
|
||||
explicit KeyboardLayout(Xkb *xkb, const KSharedConfigPtr &config);
|
||||
|
||||
void setConfig(KSharedConfigPtr config) {
|
||||
m_config = config;
|
||||
}
|
||||
~KeyboardLayout() override;
|
||||
|
||||
void init();
|
||||
|
||||
|
@ -60,7 +59,7 @@ private:
|
|||
void loadShortcuts();
|
||||
Xkb *m_xkb;
|
||||
xkb_layout_index_t m_layout = 0;
|
||||
KSharedConfigPtr m_config;
|
||||
KConfigGroup m_configGroup;
|
||||
QVector<QAction*> m_layoutShortcuts;
|
||||
KeyboardLayoutDBusInterface *m_dbusInterface = nullptr;
|
||||
KeyboardLayoutSwitching::Policy *m_policy = nullptr;
|
||||
|
@ -72,17 +71,24 @@ class KeyboardLayoutDBusInterface : public QObject
|
|||
Q_CLASSINFO("D-Bus Interface", "org.kde.KeyboardLayouts")
|
||||
|
||||
public:
|
||||
explicit KeyboardLayoutDBusInterface(Xkb *xkb, KeyboardLayout *parent);
|
||||
explicit KeyboardLayoutDBusInterface(Xkb *xkb, const KConfigGroup &configGroup, KeyboardLayout *parent);
|
||||
~KeyboardLayoutDBusInterface() override;
|
||||
|
||||
struct LayoutNames
|
||||
{
|
||||
QString id;
|
||||
QString shortName;
|
||||
QString displayName;
|
||||
QString longName;
|
||||
};
|
||||
|
||||
public Q_SLOTS:
|
||||
void switchToNextLayout();
|
||||
void switchToPreviousLayout();
|
||||
bool setLayout(const QString &layout);
|
||||
QString getLayout() const;
|
||||
QString getLayoutDisplayName() const;
|
||||
QString getLayoutLongName() const;
|
||||
QStringList getLayoutsList() const;
|
||||
QVector<LayoutNames> getLayoutsList() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void layoutChanged(QString layout);
|
||||
|
@ -90,9 +96,14 @@ Q_SIGNALS:
|
|||
|
||||
private:
|
||||
Xkb *m_xkb;
|
||||
const KConfigGroup &m_configGroup;
|
||||
KeyboardLayout *m_keyboardLayout;
|
||||
};
|
||||
|
||||
QDBusArgument &operator<<(QDBusArgument &argument, const KeyboardLayoutDBusInterface::LayoutNames &layoutNames);
|
||||
const QDBusArgument &operator>>(const QDBusArgument &argument, KeyboardLayoutDBusInterface::LayoutNames &layoutNames);
|
||||
|
||||
}
|
||||
Q_DECLARE_METATYPE(KWin::KeyboardLayoutDBusInterface::LayoutNames)
|
||||
|
||||
#endif
|
||||
|
|
32
xkb.cpp
32
xkb.cpp
|
@ -113,6 +113,14 @@ Xkb::~Xkb()
|
|||
xkb_context_unref(m_context);
|
||||
}
|
||||
|
||||
void Xkb::setConfig(const KSharedConfigPtr &config) {
|
||||
m_configGroup = config->group("Layout");
|
||||
}
|
||||
|
||||
void Xkb::setNumLockConfig(const KSharedConfigPtr &config) {
|
||||
m_numLockConfig = config;
|
||||
}
|
||||
|
||||
void Xkb::reconfigure()
|
||||
{
|
||||
if (!m_context) {
|
||||
|
@ -169,14 +177,13 @@ void Xkb::applyEnvironmentRules(xkb_rule_names &ruleNames)
|
|||
xkb_keymap *Xkb::loadKeymapFromConfig()
|
||||
{
|
||||
// load config
|
||||
if (!m_config) {
|
||||
if (!m_configGroup.isValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
const KConfigGroup config = m_config->group("Layout");
|
||||
const QByteArray model = config.readEntry("Model", "pc104").toLocal8Bit();
|
||||
const QByteArray layout = config.readEntry("LayoutList", "").toLocal8Bit();
|
||||
const QByteArray variant = config.readEntry("VariantList").toLatin1();
|
||||
const QByteArray options = config.readEntry("Options", "").toLocal8Bit();
|
||||
const QByteArray model = m_configGroup.readEntry("Model", "pc104").toLatin1();
|
||||
const QByteArray layout = m_configGroup.readEntry("LayoutList").toLatin1();
|
||||
const QByteArray variant = m_configGroup.readEntry("VariantList").toLatin1();
|
||||
const QByteArray options = m_configGroup.readEntry("Options").toLatin1();
|
||||
|
||||
xkb_rule_names ruleNames = {
|
||||
.rules = nullptr,
|
||||
|
@ -187,15 +194,6 @@ xkb_keymap *Xkb::loadKeymapFromConfig()
|
|||
};
|
||||
applyEnvironmentRules(ruleNames);
|
||||
|
||||
const QStringList displayNames = config.readEntry("DisplayNames", QStringList());
|
||||
const int range = qMin(m_layoutList.size(), displayNames.size());
|
||||
for (int i = 0; i < range; ++i) {
|
||||
const QString &displayName = displayNames.at(i);
|
||||
if ( !displayName.isEmpty() ) {
|
||||
m_layoutList.replace(i, displayName);
|
||||
}
|
||||
}
|
||||
|
||||
return xkb_keymap_new_from_names(m_context, &ruleNames, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
}
|
||||
|
||||
|
@ -397,9 +395,9 @@ QString Xkb::layoutName() const
|
|||
return layoutName(m_currentLayout);
|
||||
}
|
||||
|
||||
const QString &Xkb::layoutShortName() const
|
||||
const QStringList &Xkb::layoutShortNames() const
|
||||
{
|
||||
return m_layoutList.at(m_currentLayout);
|
||||
return m_layoutList;
|
||||
}
|
||||
|
||||
QString Xkb::layoutName(xkb_layout_index_t layout) const
|
||||
|
|
14
xkb.h
14
xkb.h
|
@ -13,7 +13,7 @@
|
|||
|
||||
#include <kwin_export.h>
|
||||
|
||||
#include <KSharedConfig>
|
||||
#include <KConfigGroup>
|
||||
|
||||
#include <QLoggingCategory>
|
||||
Q_DECLARE_LOGGING_CATEGORY(KWIN_XKB)
|
||||
|
@ -42,12 +42,8 @@ class KWIN_EXPORT Xkb : public QObject
|
|||
public:
|
||||
Xkb(QObject *parent = nullptr);
|
||||
~Xkb() override;
|
||||
void setConfig(KSharedConfigPtr config) {
|
||||
m_config = std::move(config);
|
||||
}
|
||||
void setNumLockConfig(KSharedConfigPtr config) {
|
||||
m_numLockConfig = std::move(config);
|
||||
}
|
||||
void setConfig(const KSharedConfigPtr &config);
|
||||
void setNumLockConfig(const KSharedConfigPtr &config);
|
||||
void reconfigure();
|
||||
|
||||
void installKeymap(int fd, uint32_t size);
|
||||
|
@ -91,7 +87,7 @@ public:
|
|||
return m_currentLayout;
|
||||
}
|
||||
QString layoutName() const;
|
||||
const QString &layoutShortName() const;
|
||||
const QStringList &layoutShortNames() const;
|
||||
QMap<xkb_layout_index_t, QString> layoutNames() const;
|
||||
quint32 numberOfLayouts() const;
|
||||
|
||||
|
@ -137,7 +133,7 @@ private:
|
|||
xkb_compose_state *state = nullptr;
|
||||
} m_compose;
|
||||
LEDs m_leds;
|
||||
KSharedConfigPtr m_config;
|
||||
KConfigGroup m_configGroup;
|
||||
KSharedConfigPtr m_numLockConfig;
|
||||
|
||||
struct {
|
||||
|
|
Loading…
Reference in a new issue