Commit 2fb63d85 authored by Andrey Butirsky's avatar Andrey Butirsky

Keyboard Layout plugin: passthrough Short Name from compositor to QML applet

When layout changes, the country code (or short layout name) should be passed via DBus
from compositor to this C++ QML plugin, and then to a keyboard applet for
indication

CCBUG: 390079
KWin commit: "feat: expose keyboard layout Short Name via DBus"
parent adae2455
......@@ -19,14 +19,9 @@
*/
#include "keyboardlayout.h"
#include "keyboard_layout_interface.h"
#include <QDBusInterface>
#include <QDBusReply>
#include <QDebug>
#include "debug.h"
#include "keyboard_layout_interface.h"
KeyboardLayout::KeyboardLayout(QObject* parent)
: QObject(parent)
......@@ -45,128 +40,43 @@ KeyboardLayout::KeyboardLayout(QObject* parent)
connect(mIface, &OrgKdeKeyboardLayoutsInterface::currentLayoutChanged,
this, &KeyboardLayout::onCurrentLayoutChanged);
connect(mIface, &OrgKdeKeyboardLayoutsInterface::layoutListChanged,
this, &KeyboardLayout::requestLayoutsList);
requestCurrentLayout();
requestLayoutsList();
this, &KeyboardLayout::onLayoutListChanged);
mCurrentLayout = callDBus(mIface->getCurrentLayout());
mLayouts = callDBus(mIface->getLayoutsList());
}
KeyboardLayout::~KeyboardLayout()
{
}
void KeyboardLayout::requestCurrentLayout()
{
if (!mIface) {
return;
}
QDBusPendingReply<QString> pendingLayout = mIface->getCurrentLayout();
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingLayout, this);
connect(watcher, &QDBusPendingCallWatcher::finished,
this, &KeyboardLayout::onCurrentLayoutReceived);
}
void KeyboardLayout::onCurrentLayoutReceived(QDBusPendingCallWatcher *watcher)
{
QDBusPendingReply<QString> reply = *watcher;
if (reply.isError()) {
qCWarning(KEYBOARD_LAYOUT) << reply.error().message();
} else {
mCurrentLayout = reply.value();
requestCurrentLayoutDisplayName();
Q_EMIT currentLayoutChanged(mCurrentLayout);
}
watcher->deleteLater();
}
void KeyboardLayout::requestCurrentLayoutDisplayName()
{
QDBusPendingReply<QString> pendingDisplayName = mIface->getLayoutDisplayName(mCurrentLayout);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingDisplayName, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this, &KeyboardLayout::onCurrentLayoutDisplayNameReceived);
}
void KeyboardLayout::onCurrentLayoutDisplayNameReceived(QDBusPendingCallWatcher *watcher)
{
QDBusPendingReply<QString> reply = *watcher;
if (reply.isError()) {
qCWarning(KEYBOARD_LAYOUT) << reply.error().message();
} else {
mCurrentLayoutDisplayName = reply.value();
Q_EMIT currentLayoutDisplayNameChanged(mCurrentLayoutDisplayName);
}
watcher->deleteLater();
}
QString KeyboardLayout::currentLayoutDisplayName() const
{
return mCurrentLayoutDisplayName;
}
void KeyboardLayout::requestLayoutsList()
void KeyboardLayout::onCurrentLayoutChanged(const QString &newLayout)
{
if (!mIface) {
return;
}
QDBusPendingReply<QStringList> pendingLayout = mIface->getLayoutsList();
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingLayout, this);
connect(watcher, &QDBusPendingCallWatcher::finished,
this, &KeyboardLayout::onLayoutsListReceived);
mCurrentLayout = newLayout;
Q_EMIT currentLayoutChanged();
}
void KeyboardLayout::onLayoutsListReceived(QDBusPendingCallWatcher *watcher)
void KeyboardLayout::onLayoutListChanged()
{
QDBusPendingReply<QStringList> reply = *watcher;
if (reply.isError()) {
qCWarning(KEYBOARD_LAYOUT) << reply.error().message();
} else {
mLayouts = reply.value();
qCDebug(KEYBOARD_LAYOUT) << "Layouts list changed: " << mLayouts;
if (mIface) {
mLayouts = callDBus(mIface->getLayoutsList());
Q_EMIT layoutsChanged();
}
watcher->deleteLater();
}
QString KeyboardLayout::currentLayout() const
QString KeyboardLayout::currentLayoutShortName() const
{
return mCurrentLayout;
return mIface ? callDBus(mIface->getCurrentLayoutShortName()) : QString();
}
bool KeyboardLayout::onCurrentLayoutChanged(const QString &layout)
QString KeyboardLayout::currentLayoutDisplayName() const
{
if (!mIface) {
return false;
}
if (mCurrentLayout == layout) {
return false;
}
if (!mLayouts.contains(layout)) {
qCWarning(KEYBOARD_LAYOUT) << "No such layout" << layout;
return false;
}
mCurrentLayout = layout;
requestCurrentLayoutDisplayName();
Q_EMIT currentLayoutChanged(layout);
return true;
return mIface ? callDBus(mIface->getLayoutDisplayName(mCurrentLayout)) : QString();
}
void KeyboardLayout::setCurrentLayout(const QString &layout)
{
if (onCurrentLayoutChanged(layout)) {
if (mIface) {
mIface->setLayout(layout);
}
}
QStringList KeyboardLayout::layouts() const
{
return mLayouts;
}
/*
* Copyright (C) 2014 Daniel Vratil <dvratil@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* SPDX-FileCopyrightText: 2014 Daniel Vrátil <dvratil@redhat.com>
* SPDX-FileCopyrightText: 2020 Andrey Butirsky <butirsky@gmail.com>
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#ifndef KEYBOARDLAYOUT_H
#define KEYBOARDLAYOUT_H
#include <QObject>
#include <QStringList>
#include <QDBusReply>
#include "debug.h"
class OrgKdeKeyboardLayoutsInterface;
class QDBusPendingCallWatcher;
......@@ -31,51 +19,55 @@ class KeyboardLayout : public QObject
Q_OBJECT
Q_PROPERTY(QString currentLayout
READ currentLayout
WRITE setCurrentLayout
NOTIFY currentLayoutChanged)
MEMBER mCurrentLayout
WRITE setCurrentLayout)
Q_PROPERTY(QString currentLayoutDisplayName
READ currentLayoutDisplayName
NOTIFY currentLayoutDisplayNameChanged)
NOTIFY currentLayoutChanged)
Q_PROPERTY(QString currentLayoutShortName
READ currentLayoutShortName
NOTIFY currentLayoutChanged)
Q_PROPERTY(QStringList layouts
READ layouts
MEMBER mLayouts
NOTIFY layoutsChanged)
public:
explicit KeyboardLayout(QObject *parent = nullptr);
~KeyboardLayout() override;
QString currentLayout() const;
QString currentLayoutDisplayName() const;
QStringList layouts() const;
public Q_SLOTS:
void setCurrentLayout(const QString &layout);
Q_SIGNALS:
void currentLayoutChanged(const QString &newLayout);
void currentLayoutDisplayNameChanged(const QString &newLayout);
void currentLayoutChanged();
void layoutsChanged();
private Q_SLOTS:
void requestCurrentLayout();
void requestCurrentLayoutDisplayName();
void requestLayoutsList();
private:
void onCurrentLayoutChanged(const QString &newLayout);
void onLayoutListChanged();
QString currentLayoutShortName() const;
QString currentLayoutDisplayName() const;
void setCurrentLayout(const QString &layout);
bool onCurrentLayoutChanged(const QString &newLayout);
void onCurrentLayoutReceived(QDBusPendingCallWatcher *watcher);
void onCurrentLayoutDisplayNameReceived(QDBusPendingCallWatcher *watcher);
void onLayoutsListReceived(QDBusPendingCallWatcher *watcher);
template<class T>
static T callDBus(QDBusPendingReply<T> pendingReply);
private:
QStringList mLayouts;
QString mCurrentLayout;
QString mCurrentLayoutDisplayName;
OrgKdeKeyboardLayoutsInterface *mIface;
};
template<class T>
T KeyboardLayout::callDBus(QDBusPendingReply<T> pendingReply)
{
pendingReply.waitForFinished();
if (pendingReply.isError()) {
qCWarning(KEYBOARD_LAYOUT) << pendingReply.error().message();
return {};
} else {
return pendingReply.value();
}
}
#endif // KEYBOARDLAYOUT_H
......@@ -14,6 +14,9 @@
<method name="getCurrentLayout">
<arg type="s" direction="out"/>
</method>
<method name="getCurrentLayoutShortName">
<arg type="s" direction="out"/>
</method>
<method name="getLayoutsList">
<arg type="as" direction="out"/>
</method>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment