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
This commit is contained in:
parent
997af81ea9
commit
6b0b4cf468
2 changed files with 43 additions and 7 deletions
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue