Last active
February 21, 2025 13:48
-
-
Save danieloneill/8ccfab375a8819c61adb5883a0cd7c97 to your computer and use it in GitHub Desktop.
CLI Keyboard tool for KDE Plasma
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Just a little keyboard layout tool for KDE Plasma. | |
I wrote this so I could swap between Dvorak and US when gaming. It isn't strictly necessary since | |
all my games run on Proton which renders via Xwayland (which you change the layout using setxkbmap), | |
but I like consistency, so I swap the layout for both Wayland and Xwayland at the same time. | |
Steam -> Launch Options: | |
setxkbmap us; kdekbtool -i 1; %command%; setxkbmap dvorak; kdekbtool -i 0 | |
Requires Qt, written/tested with Qt 6.5.2 and Plasma 5.27.5 (Qt 5.15.9) on Fedora 38 | |
Just put both files into a directory then run "qmake . && make". | |
[doneill@galena build]$ ./kdekbtool -h | |
Usage: ./kdekbtool [options] | |
KDE Plasma Keyboard Tool | |
Options: | |
-h, --help Displays help on commandline options. | |
--help-all Displays help including Qt specific options. | |
-v, --version Displays version information. | |
-q Get current keyboard layout | |
-l Get list of keyboard layouts | |
-i, --layout_id <layout_id> Set current keyboard layout to <layout_id>. | |
The layout listing format is: | |
index : layout : variant : name (user specified) | |
[doneill@galena build]$ kdekbtool -l | |
0 : us : dv : English (Dvorak) | |
1 : us : : English (US) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <QDBusInterface> | |
#include <QDBusMessage> | |
#include <QDBusReply> | |
#include <QDBusVariant> | |
#include <QDebug> | |
#include <QCommandLineOption> | |
#include <QCommandLineParser> | |
#include <QCoreApplication> | |
int getCurrentLayoutID() | |
{ | |
QDBusInterface query( "org.kde.keyboard", "/Layouts" ); | |
QDBusReply<quint32> reply = query.call("getLayout"); | |
if ( reply.isValid() ) | |
return reply.value(); | |
qInfo() << reply.error(); | |
return -1; | |
} | |
void setLayoutID(quint32 id) | |
{ | |
QDBusInterface query( "org.kde.keyboard", "/Layouts" ); | |
QDBusReply<bool> reply = query.call("setLayout", id); | |
if( !reply.isValid() ) | |
qInfo() << reply.error(); | |
} | |
QList< QMap<QString, QString> > getLayoutsList() | |
{ | |
QList< QMap<QString, QString> > result; | |
QDBusInterface query( "org.kde.keyboard", "/Layouts" ); | |
QDBusMessage msg = query.call(QDBus::AutoDetect, "getLayoutsList"); | |
if( msg.type() != QDBusMessage::ReplyMessage ) | |
{ | |
qWarning() << "Invalid Reply"; | |
return QList< QMap<QString, QString> >(); | |
} | |
QList< QVariant > args = msg.arguments(); | |
for( QVariant varg : args ) | |
{ | |
int x = 0; | |
const QDBusArgument dbusarg = varg.value<QDBusArgument>(); | |
dbusarg.beginArray(); | |
while( !dbusarg.atEnd() && x++ < 20 ) | |
{ | |
dbusarg.beginStructure(); | |
QMap<QString, QString> ent; | |
QString blarg, blorg, blag; | |
dbusarg >> blarg >> blorg >> blag; | |
dbusarg.endStructure(); | |
ent["layout"] = blarg; | |
ent["variant"] = blorg; | |
ent["name"] = blag; | |
result.append( ent ); | |
} | |
dbusarg.endArray(); | |
} | |
return result; | |
} | |
int main(int argc, char **argv) | |
{ | |
QCoreApplication app(argc, argv); | |
QCoreApplication::setApplicationName("kdekbtool"); | |
QCoreApplication::setApplicationVersion("1.0"); | |
auto connection = QDBusConnection::sessionBus(); | |
if (!connection.isConnected()) { | |
qWarning("Cannot connect to the D-Bus session bus.\n" | |
"To start it, run:\n" | |
"\teval `dbus-launch --auto-syntax`\n"); | |
return 1; | |
} | |
QCommandLineParser parser; | |
parser.setApplicationDescription("KDE Plasma Keyboard Tool"); | |
parser.addHelpOption(); | |
parser.addVersionOption(); | |
QCommandLineOption queryCurrentOption("q", QCoreApplication::translate("main", "Get current keyboard layout")); | |
parser.addOption(queryCurrentOption); | |
QCommandLineOption queryLayouts("l", QCoreApplication::translate("main", "Get list of keyboard layouts")); | |
parser.addOption(queryLayouts); | |
QCommandLineOption setLayoutOption(QStringList() << "i" << "layout_id", | |
QCoreApplication::translate("main", "Set current keyboard layout to <layout_id>."), | |
QCoreApplication::translate("main", "layout_id")); | |
parser.addOption(setLayoutOption); | |
parser.process(app); | |
if( parser.isSet(setLayoutOption) ) | |
{ | |
const QString idxOption = parser.value(setLayoutOption); | |
quint32 idx = idxOption.toInt(); | |
setLayoutID(idx); | |
} | |
if( parser.isSet(queryCurrentOption) ) | |
{ | |
int curId = getCurrentLayoutID(); | |
QList< QMap< QString, QString > > layouts = getLayoutsList(); | |
int x=0; | |
for( QMap< QString, QString > ent : layouts ) | |
{ | |
if( curId != x ) | |
{ | |
x++; | |
continue; | |
} | |
printf("%d : %s : %s : %s\n", | |
x, | |
ent["layout"].toStdString().c_str(), | |
ent["variant"].toStdString().c_str(), | |
ent["name"].toStdString().c_str()); | |
x++; | |
} | |
} | |
if( parser.isSet(queryLayouts) ) | |
{ | |
QList< QMap< QString, QString > > layouts = getLayoutsList(); | |
int x=0; | |
for( QMap< QString, QString > ent : layouts ) | |
{ | |
printf("%d : %s : %s : %s\n", | |
x++, | |
ent["layout"].toStdString().c_str(), | |
ent["variant"].toStdString().c_str(), | |
ent["name"].toStdString().c_str()); | |
} | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TARGET = kdekbtool | |
QT += core dbus | |
QT -= gui | |
SOURCES += kdekbtool.cpp |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment