15#include <KGlobalAccel>
16#include <KLocalizedString>
18#include <QDBusConnection>
19#include <QDBusMessage>
20#include <QDBusMetaType>
21#include <QDBusPendingCall>
29 , m_configGroup(config->group(QStringLiteral(
"Layout")))
35static QString translatedLayout(
const QString &layout)
37 return i18nd(
"xkeyboard-config", layout.toUtf8().constData());
42 QAction *switchKeyboardAction =
new QAction(
this);
43 switchKeyboardAction->setObjectName(QStringLiteral(
"Switch to Next Keyboard Layout"));
44 switchKeyboardAction->setProperty(
"componentName", QStringLiteral(
"KDE Keyboard Layout Switcher"));
45 switchKeyboardAction->setProperty(
"componentDisplayName", i18n(
"Keyboard Layout Switcher"));
46 const QKeySequence sequence = QKeySequence(Qt::META | Qt::ALT | Qt::Key_K);
47 KGlobalAccel::self()->setDefaultShortcut(switchKeyboardAction, QList<QKeySequence>({sequence}));
48 KGlobalAccel::self()->setShortcut(switchKeyboardAction, QList<QKeySequence>({sequence}));
52 QAction *switchLastUsedKeyboardAction =
new QAction(
this);
53 switchLastUsedKeyboardAction->setObjectName(QStringLiteral(
"Switch to Last-Used Keyboard Layout"));
54 switchLastUsedKeyboardAction->setProperty(
"componentName", QStringLiteral(
"KDE Keyboard Layout Switcher"));
55 switchLastUsedKeyboardAction->setProperty(
"componentDisplayName", i18n(
"Keyboard Layout Switcher"));
56 const QKeySequence sequenceLastUsed = QKeySequence(Qt::META | Qt::ALT | Qt::Key_L);
57 KGlobalAccel::self()->setDefaultShortcut(switchLastUsedKeyboardAction, QList<QKeySequence>({sequenceLastUsed}));
58 KGlobalAccel::self()->setShortcut(switchLastUsedKeyboardAction, QList<QKeySequence>({sequenceLastUsed}));
62 QDBusConnection::sessionBus().connect(QString(),
63 QStringLiteral(
"/Layouts"),
64 QStringLiteral(
"org.kde.keyboard"),
65 QStringLiteral(
"reloadConfig"),
72void KeyboardLayout::initDBusInterface()
75 if (m_dbusInterface) {
76 m_dbusInterface->deleteLater();
77 m_dbusInterface =
nullptr;
81 if (m_dbusInterface) {
84 m_dbusInterface =
new KeyboardLayoutDBusInterface(m_xkb, m_configGroup,
this);
115 if (!m_lastUsedLayout.has_value() || *m_lastUsedLayout >= count) {
118 switchToLayout(*m_lastUsedLayout);
122void KeyboardLayout::reconfigure()
124 if (m_configGroup.isValid()) {
125 m_configGroup.config()->reparseConfiguration();
126 const QString policyKey = m_configGroup.readEntry(
"SwitchMode", QStringLiteral(
"Global"));
128 if (!m_policy || m_policy->name() != policyKey) {
146void KeyboardLayout::loadShortcuts()
148 qDeleteAll(m_layoutShortcuts);
149 m_layoutShortcuts.clear();
150 const QString componentName = QStringLiteral(
"KDE Keyboard Layout Switcher");
152 for (uint i = 0; i < count; ++i) {
154 const QString action = QStringLiteral(
"Switch keyboard layout to %1").arg(translatedLayout(m_xkb->
layoutName(i)));
155 const auto shortcuts = KGlobalAccel::self()->globalShortcut(componentName, action);
156 if (shortcuts.isEmpty()) {
159 QAction *a =
new QAction(
this);
160 a->setObjectName(action);
161 a->setProperty(
"componentName", componentName);
162 connect(a, &QAction::triggered,
this,
163 std::bind(&KeyboardLayout::switchToLayout,
this, i));
164 KGlobalAccel::self()->setShortcut(a, shortcuts, KGlobalAccel::Autoloading);
165 m_layoutShortcuts << a;
176 if (m_layout != currentLayout || previousLayout != currentLayout) {
177 m_lastUsedLayout = std::optional<uint>{previousLayout};
178 m_layout = currentLayout;
179 notifyLayoutChange();
184void KeyboardLayout::notifyLayoutChange()
187 QDBusMessage msg = QDBusMessage::createMethodCall(
188 QStringLiteral(
"org.kde.plasmashell"),
189 QStringLiteral(
"/org/kde/osdService"),
190 QStringLiteral(
"org.kde.osdService"),
191 QStringLiteral(
"kbdLayoutChanged"));
195 QDBusConnection::sessionBus().asyncCall(msg);
198static const QString s_keyboardService = QStringLiteral(
"org.kde.keyboard");
199static const QString s_keyboardObject = QStringLiteral(
"/Layouts");
204 , m_configGroup(configGroup)
205 , m_keyboardLayout(parent)
207 qRegisterMetaType<QList<LayoutNames>>(
"QList<LayoutNames>");
208 qDBusRegisterMetaType<LayoutNames>();
209 qDBusRegisterMetaType<QList<LayoutNames>>();
211 QDBusConnection::sessionBus().registerObject(s_keyboardObject,
this, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals);
212 QDBusConnection::sessionBus().registerService(s_keyboardService);
217 QDBusConnection::sessionBus().unregisterService(s_keyboardService);
248 const QStringList displayNames = m_configGroup.readEntry(
"DisplayNames", QStringList());
250 QList<LayoutNames> ret;
252 const int displayNamesSize = displayNames.size();
253 for (
int i = 0; i < layoutsSize; ++i) {
254 ret.append({m_xkb->
layoutShortName(i), i < displayNamesSize ? displayNames.at(i) : QString(), translatedLayout(m_xkb->
layoutName(i))});
261 argument.beginStructure();
263 argument.endStructure();
269 argument.beginStructure();
271 argument.endStructure();
277#include "moc_keyboard_layout.cpp"
void switchToPreviousLayout()
bool setLayout(uint index)
QList< LayoutNames > getLayoutsList() const
void switchToNextLayout()
KeyboardLayoutDBusInterface(Xkb *xkb, const KConfigGroup &configGroup, KeyboardLayout *parent)
~KeyboardLayoutDBusInterface() override
void layoutChanged(uint index)
void switchToPreviousLayout()
void switchToNextLayout()
void layoutChanged(uint index)
void switchToLastUsedLayout()
void checkLayoutChange(uint previousLayout)
KeyboardLayout(Xkb *xkb, const KSharedConfigPtr &config)
void layoutsReconfigured()
~KeyboardLayout() override
static std::unique_ptr< Policy > create(Xkb *xkb, KeyboardLayout *layout, const KConfigGroup &config, const QString &policy)
void switchToNextLayout()
QString layoutShortName(int index) const
QString layoutName(xkb_layout_index_t index) const
quint32 numberOfLayouts() const
quint32 currentLayout() const
void switchToPreviousLayout()
bool switchToLayout(xkb_layout_index_t layout)
QDebug & operator<<(QDebug &s, const KWin::DrmConnector *obj)
const QDBusArgument & operator>>(const QDBusArgument &argument, KeyboardLayoutDBusInterface::LayoutNames &layoutNames)