aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Gräßlin <[email protected]>2017-01-23 20:06:53 +0100
committerMartin Gräßlin <[email protected]>2017-01-26 18:50:49 +0100
commit6b0b4cf46871de5092e4d159cda9d0d907cacf49 (patch)
treec5bd199e2735815a4fcaea0b8e0b918b434cbf5c
parent997af81ea90e809ab79d021a56ce464a549fff15 (diff)
Support global shortcut to switch to specific layout
Summary: Our keyboard layout kcm allows to set a global shortcut to switch to a specific keyboard layout. So far KWin/Wayland did not support those shortcuts, only the switch to next layout shortcut was supported. This change introduces support for custom layout shortcuts. For that we iterate over all available layouts and check whether a shortcut is registered. If that is the case a QAction is created and passed to KGlobalAccel. As the triggering code is similar to the menu, the switchLayout lambda is split out into a dedicated method and translating the layouts is extracted into a method. Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D4256
-rw-r--r--keyboard_layout.cpp45
-rw-r--r--keyboard_layout.h5
2 files changed, 43 insertions, 7 deletions
diff --git a/keyboard_layout.cpp b/keyboard_layout.cpp
index 51d21bf..df15254 100644
--- a/keyboard_layout.cpp
+++ b/keyboard_layout.cpp
@@ -46,6 +46,11 @@ KeyboardLayout::KeyboardLayout(Xkb *xkb)
KeyboardLayout::~KeyboardLayout() = default;
+static QString translatedLayout(const QString &layout)
+{
+ return i18nd("xkeyboard-config", layout.toUtf8().constData());
+}
+
void KeyboardLayout::init()
{
QAction *switchKeyboardAction = new QAction(this);
@@ -127,6 +132,12 @@ void KeyboardLayout::switchToPreviousLayout()
checkLayoutChange();
}
+void KeyboardLayout::switchToLayout(xkb_layout_index_t index)
+{
+ m_xkb->switchToLayout(index);
+ checkLayoutChange();
+}
+
void KeyboardLayout::reconfigure()
{
m_xkb->reconfigure();
@@ -142,6 +153,30 @@ void KeyboardLayout::resetLayout()
initNotifierItem();
updateNotifier();
reinitNotifierMenu();
+ loadShortcuts();
+}
+
+void KeyboardLayout::loadShortcuts()
+{
+ qDeleteAll(m_layoutShortcuts);
+ m_layoutShortcuts.clear();
+ const auto layouts = m_xkb->layoutNames();
+ const QString componentName = QStringLiteral("KDE Keyboard Layout Switcher");
+ for (auto it = layouts.begin(); it != layouts.end(); it++) {
+ // layout name is translated in the action name in keyboard kcm!
+ const QString action = QStringLiteral("Switch keyboard layout to %1").arg(translatedLayout(it.value()));
+ const auto shortcuts = KGlobalAccel::self()->globalShortcut(componentName, action);
+ if (shortcuts.isEmpty()) {
+ continue;
+ }
+ QAction *a = new QAction(this);
+ a->setObjectName(action);
+ a->setProperty("componentName", componentName);
+ connect(a, &QAction::triggered, this,
+ std::bind(&KeyboardLayout::switchToLayout, this, it.key()));
+ KGlobalAccel::self()->setShortcut(a, shortcuts, KGlobalAccel::Autoloading);
+ m_layoutShortcuts << a;
+ }
}
void KeyboardLayout::keyEvent(KeyEvent *event)
@@ -171,7 +206,7 @@ void KeyboardLayout::notifyLayoutChange()
QStringLiteral("org.kde.osdService"),
QStringLiteral("kbdLayoutChanged"));
- msg << i18nd("xkeyboard-config", m_xkb->layoutName().toUtf8().constData());
+ msg << translatedLayout(m_xkb->layoutName());
QDBusConnection::sessionBus().asyncCall(msg);
}
@@ -181,7 +216,7 @@ void KeyboardLayout::updateNotifier()
if (!m_notifierItem) {
return;
}
- m_notifierItem->setToolTipSubTitle(i18nd("xkeyboard-config", m_xkb->layoutName().toUtf8().constData()));
+ m_notifierItem->setToolTipSubTitle(translatedLayout(m_xkb->layoutName()));
// TODO: update icon
}
@@ -193,12 +228,8 @@ void KeyboardLayout::reinitNotifierMenu()
const auto layouts = m_xkb->layoutNames();
QMenu *menu = new QMenu;
- auto switchLayout = [this] (xkb_layout_index_t index) {
- m_xkb->switchToLayout(index);
- checkLayoutChange();
- };
for (auto it = layouts.begin(); it != layouts.end(); it++) {
- menu->addAction(i18nd("xkeyboard-config", it.value().toUtf8().constData()), std::bind(switchLayout, it.key()));
+ menu->addAction(translatedLayout(it.value()), std::bind(&KeyboardLayout::switchToLayout, this, it.key()));
}
menu->addSeparator();
diff --git a/keyboard_layout.h b/keyboard_layout.h
index aa39fd7..d60ea4d 100644
--- a/keyboard_layout.h
+++ b/keyboard_layout.h
@@ -22,11 +22,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "input_event_spy.h"
#include <QObject>
+#include <QVector>
#include <KSharedConfig>
typedef uint32_t xkb_layout_index_t;
class KStatusNotifierItem;
+class QAction;
namespace KWin
{
@@ -58,12 +60,15 @@ private:
void initNotifierItem();
void switchToNextLayout();
void switchToPreviousLayout();
+ void switchToLayout(xkb_layout_index_t index);
void updateNotifier();
void reinitNotifierMenu();
+ void loadShortcuts();
Xkb *m_xkb;
xkb_layout_index_t m_layout = 0;
KStatusNotifierItem *m_notifierItem;
KSharedConfigPtr m_config;
+ QVector<QAction*> m_layoutShortcuts;
};
}