mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-04 09:23:03 +00:00
feat: keyboard layout indicator adjust
when fcitx is running, keyboard indicator show fcitx current lang code, disbale system keyboard switch switch shotcut and hide system keyboard layout in dde-control-center. resume those after fcitx stopped. Log: keyboard layout indicator adjust Influence: plugins/keyboard-layout Task: https://pms.uniontech.com/task-view-115107.html Change-Id: Id717a681b4c0d21154602c7494900fc47f3a3a98
This commit is contained in:
parent
1cff0b8600
commit
623dc8c764
@ -20,6 +20,7 @@
|
||||
*/
|
||||
#ifndef UTILS
|
||||
#define UTILS
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QImageReader>
|
||||
#include <QApplication>
|
||||
|
@ -16,8 +16,18 @@ find_package(DFrameworkdbus REQUIRED)
|
||||
pkg_check_modules(DFrameworkDBus REQUIRED dframeworkdbus)
|
||||
pkg_check_modules(QGSettings REQUIRED gsettings-qt)
|
||||
|
||||
set_source_files_properties(
|
||||
org.fcitx.Fcitx.xml
|
||||
PROPERTIES INCLUDE fcitxinputmethoditem.h
|
||||
CLASSNAME FcitxInputMethodProxy
|
||||
)
|
||||
|
||||
qt5_add_dbus_interfaces(DBUS_INTERFACES
|
||||
org.fcitx.Fcitx.xml
|
||||
)
|
||||
|
||||
add_definitions("${QT_DEFINITIONS} -DQT_PLUGIN")
|
||||
add_library(${PLUGIN_NAME} SHARED ${SRCS})
|
||||
add_library(${PLUGIN_NAME} SHARED ${SRCS} ${DBUS_INTERFACES})
|
||||
set_target_properties(${PLUGIN_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../)
|
||||
target_include_directories(${PLUGIN_NAME} PUBLIC ${DtkWidget_INCLUDE_DIRS}
|
||||
${DFrameworkDBus_INCLUDE_DIRS}
|
||||
|
@ -19,23 +19,40 @@
|
||||
|
||||
#include "utils.h"
|
||||
#include "dbusadaptors.h"
|
||||
#include "fcitxinputmethoditem.h"
|
||||
|
||||
#include <DDBusSender>
|
||||
#include <DSysInfo>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtDBus/QDBusConnection>
|
||||
|
||||
// switch kdb layout key in gsettings
|
||||
const QString KDB_LAYOUT_KEYBINDING_KEY = "switchNextKbdLayout";
|
||||
|
||||
// dcc keyboard layout key in gsettings
|
||||
const QString KDB_LAYOUT_DCC_NAME = "keyboardLayout";
|
||||
|
||||
// because not allowd to use libfcitx-qt, use org.fcitx.Fcitx to
|
||||
// get fcitx status and data
|
||||
const QString FCITX_ADDRESSS = "org.fcitx.Fcitx";
|
||||
|
||||
DBusAdaptors::DBusAdaptors(QObject *parent)
|
||||
: QDBusAbstractAdaptor(parent),
|
||||
m_keyboard(new Keyboard("com.deepin.daemon.InputDevices",
|
||||
"/com/deepin/daemon/InputDevice/Keyboard",
|
||||
QDBusConnection::sessionBus(), this)),
|
||||
m_menu(new QMenu()),
|
||||
m_gsettings(Utils::ModuleSettingsPtr("keyboard", QByteArray(), this))
|
||||
m_menu(new QMenu()),
|
||||
m_gsettings(Utils::ModuleSettingsPtr("keyboard", QByteArray(), this)),
|
||||
m_keybingEnabled(Utils::SettingsPtr("com.deepin.dde.keybinding.system.enable", QByteArray(), this)),
|
||||
m_dccSettings(Utils::SettingsPtr("com.deepin.dde.control-center", QByteArray(), this)),
|
||||
m_fcitxRunning(false),
|
||||
m_inputmethod(nullptr)
|
||||
{
|
||||
m_keyboard->setSync(false);
|
||||
|
||||
connect(m_keyboard, &Keyboard::CurrentLayoutChanged, this, &DBusAdaptors::onCurrentLayoutChanged);
|
||||
connect(m_keyboard, &Keyboard::UserLayoutListChanged, this, &DBusAdaptors::onUserLayoutListChanged);
|
||||
|
||||
connect(m_menu, &QMenu::triggered, this, &DBusAdaptors::handleActionTriggered);
|
||||
|
||||
// init data
|
||||
@ -45,6 +62,12 @@ DBusAdaptors::DBusAdaptors(QObject *parent)
|
||||
|
||||
if (m_gsettings)
|
||||
connect(m_gsettings, &QGSettings::changed, this, &DBusAdaptors::onGSettingsChanged);
|
||||
|
||||
// deepin show fcitx lang code,while fcitx is running
|
||||
if (Dtk::Core::DSysInfo::isCommunityEdition()) {
|
||||
initFcitxWatcher();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DBusAdaptors::~DBusAdaptors()
|
||||
@ -93,7 +116,7 @@ void DBusAdaptors::onClicked(int button, int x, int y)
|
||||
|
||||
Q_UNUSED(button);
|
||||
|
||||
if (m_menu && m_userLayoutList.size() >= 2) {
|
||||
if (m_menu && m_userLayoutList.size() >= 2 && !m_fcitxRunning) {
|
||||
m_menu->exec(QPoint(x, y));
|
||||
}
|
||||
}
|
||||
@ -215,3 +238,143 @@ QString DBusAdaptors::duplicateCheck(const QString &kb)
|
||||
|
||||
return kblayout + (list.count() > 1 ? QString::number(list.indexOf(kb) + 1) : "");
|
||||
}
|
||||
|
||||
void DBusAdaptors::onFcitxConnected(const QString &service)
|
||||
{
|
||||
Q_UNUSED(service)
|
||||
if (m_fcitxRunning)
|
||||
return;
|
||||
|
||||
// fcitx from closed to running
|
||||
m_fcitxRunning = true;
|
||||
setKeyboardLayoutGsettings();
|
||||
if (m_inputmethod) {
|
||||
delete m_inputmethod;
|
||||
m_inputmethod = nullptr;
|
||||
}
|
||||
// fcitx from off to on will create this, free it on fcitx closing.
|
||||
m_inputmethod = new FcitxInputMethodProxy(
|
||||
FCITX_ADDRESSS,
|
||||
"/inputmethod",
|
||||
QDBusConnection::sessionBus(),
|
||||
this);
|
||||
|
||||
if (QDBusConnection::sessionBus().connect(FCITX_ADDRESSS, "/inputmethod",
|
||||
"org.freedesktop.DBus.Properties", "PropertiesChanged", this,
|
||||
SLOT(onPropertyChanged(QString, QVariantMap, QStringList)))) {
|
||||
} else {
|
||||
qWarning() << "fcitx's PropertiesChanged signal connection was not successful";
|
||||
}
|
||||
|
||||
Q_EMIT(fcitxStatusChanged(m_fcitxRunning));
|
||||
|
||||
}
|
||||
|
||||
void DBusAdaptors::onFcitxDisconnected(const QString &service)
|
||||
{
|
||||
Q_UNUSED(service)
|
||||
if (!m_fcitxRunning)
|
||||
return;
|
||||
|
||||
// fcitx from running to close
|
||||
m_fcitxRunning = false;
|
||||
setKeyboardLayoutGsettings();
|
||||
QDBusConnection::sessionBus().disconnect(FCITX_ADDRESSS, "/inputmethod",
|
||||
"org.freedesktop.DBus.Properties", "PropertiesChanged", this,
|
||||
SLOT(onPropertyChanged(QString, QVariantMap, QStringList)));
|
||||
// fcitx is closing, free it.
|
||||
if (m_inputmethod) {
|
||||
delete m_inputmethod;
|
||||
m_inputmethod = nullptr;
|
||||
}
|
||||
|
||||
Q_EMIT(fcitxStatusChanged(m_fcitxRunning));
|
||||
|
||||
}
|
||||
|
||||
void DBusAdaptors::onPropertyChanged(QString name, QVariantMap map, QStringList list)
|
||||
{
|
||||
// fcitx uniquename start with fcitx-keyboard- which contains keyboard layout.
|
||||
QString fcitxUniqueName("fcitx-keyboard-");
|
||||
qDebug() << QString("properties of interface %1 changed").arg(name);
|
||||
|
||||
if (list.isEmpty() || "CurrentIM" != list[0])
|
||||
return;
|
||||
|
||||
if (m_inputmethod == nullptr)
|
||||
return;
|
||||
|
||||
QString currentIM = m_inputmethod ->GetCurrentIM();
|
||||
if (currentIM.startsWith(fcitxUniqueName)) {
|
||||
// fcitx uniquename contains keyboard layout, keyboard is after fcitx-keyboard-
|
||||
// such as fcitx-keyboard-ara-uga, keyboard layout is ara;uga
|
||||
// fcitx-keyboard-us keyboard is us;
|
||||
// fcitx-keyboard-am-phonetic-alt keyboard layout is am;phonetic-alt
|
||||
QString layout = currentIM.right(currentIM.size() - fcitxUniqueName.size());
|
||||
int splitLoc = layout.indexOf('-');
|
||||
if (splitLoc > 0) {
|
||||
layout = layout.replace(splitLoc, 1, ';');
|
||||
} else {
|
||||
layout.append(';');
|
||||
}
|
||||
m_keyboard->setCurrentLayout(layout);
|
||||
qDebug() << (m_keyboard->currentLayout() == layout);
|
||||
} else {
|
||||
// sunpinyin sogounpinyin uniquename not contains keyboard-layout. using lang code only for display.
|
||||
FcitxQtInputMethodItemList lists = m_inputmethod -> iMList();
|
||||
for (FcitxQtInputMethodItem item : lists) {
|
||||
if (currentIM == item.uniqueName()) {
|
||||
// zh_CN display as cn
|
||||
if (0 == QString::compare("zh_CN", item.langCode())) {
|
||||
item.setLangCode("cn");
|
||||
}
|
||||
QString layout = item.langCode();
|
||||
layout.append(';');
|
||||
m_keyboard->setCurrentLayout(layout);
|
||||
qDebug() << (m_keyboard->currentLayout() == layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DBusAdaptors::setKeyboardLayoutGsettings()
|
||||
{
|
||||
// while fcitx is running, disable keyboard switch shortcut, enable it after fcitx stopped
|
||||
if (m_keybingEnabled && m_keybingEnabled->keys().contains(KDB_LAYOUT_KEYBINDING_KEY)) {
|
||||
m_keybingEnabled->set(KDB_LAYOUT_KEYBINDING_KEY, QVariant(!m_fcitxRunning));
|
||||
}
|
||||
|
||||
// hide keyboard layout setttings in dde-control-center, resume it after fcitx stopped
|
||||
if (m_dccSettings && m_dccSettings->keys().contains(KDB_LAYOUT_DCC_NAME)) {
|
||||
m_dccSettings->set(KDB_LAYOUT_DCC_NAME, QVariant(!m_fcitxRunning));
|
||||
}
|
||||
}
|
||||
|
||||
bool DBusAdaptors::isFcitxRunning() const
|
||||
{
|
||||
return m_fcitxRunning;
|
||||
}
|
||||
|
||||
void DBusAdaptors::initFcitxWatcher()
|
||||
{
|
||||
qDebug() << "init fcitx status watcher";
|
||||
FcitxQtInputMethodItem::registerMetaType();
|
||||
// init dbusSewrviceWatcher to see fcitx status
|
||||
m_fcitxWatcher = new QDBusServiceWatcher(this);
|
||||
m_fcitxWatcher->setConnection(QDBusConnection::sessionBus());
|
||||
m_fcitxWatcher->addWatchedService(FCITX_ADDRESSS);
|
||||
// send fcitx on or off signal, when fcitx is starting or closing.
|
||||
connect(m_fcitxWatcher, SIGNAL(serviceRegistered(QString)), this, SLOT(onFcitxConnected(QString)));
|
||||
connect(m_fcitxWatcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(onFcitxDisconnected(QString)));
|
||||
|
||||
// get fcitx current status
|
||||
QDBusReply<bool> registered = m_fcitxWatcher ->connection().interface()->isServiceRegistered(FCITX_ADDRESSS);
|
||||
|
||||
if (registered.isValid() && registered.value()) {
|
||||
// fcitx is alerdy running,
|
||||
onFcitxConnected(QString());
|
||||
}
|
||||
setKeyboardLayoutGsettings();
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,11 @@
|
||||
#ifndef DBUSADAPTORS_H
|
||||
#define DBUSADAPTORS_H
|
||||
|
||||
#include "fcitxinterface.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
#include <com_deepin_daemon_inputdevice_keyboard.h>
|
||||
|
||||
using Keyboard = com::deepin::daemon::inputdevice::Keyboard;
|
||||
@ -46,8 +49,10 @@ public:
|
||||
|
||||
public:
|
||||
Q_PROPERTY(QString layout READ layout WRITE setLayout NOTIFY layoutChanged)
|
||||
Q_PROPERTY(bool fcitxRunning READ isFcitxRunning NOTIFY fcitxStatusChanged)
|
||||
QString layout() const;
|
||||
void setLayout(const QString &str);
|
||||
bool isFcitxRunning() const;
|
||||
|
||||
Keyboard *getCurrentKeyboard();
|
||||
|
||||
@ -56,6 +61,7 @@ public slots:
|
||||
|
||||
signals:
|
||||
void layoutChanged(QString text);
|
||||
void fcitxStatusChanged(bool running);
|
||||
|
||||
private slots:
|
||||
void onCurrentLayoutChanged(const QString & value);
|
||||
@ -67,12 +73,22 @@ private slots:
|
||||
|
||||
private slots:
|
||||
void onGSettingsChanged(const QString &key);
|
||||
void onFcitxConnected(const QString &service);
|
||||
void onFcitxDisconnected(const QString &service);
|
||||
void onPropertyChanged(QString name, QVariantMap map, QStringList list);
|
||||
|
||||
private:
|
||||
QString duplicateCheck(const QString &kb);
|
||||
void setKeyboardLayoutGsettings();
|
||||
void initFcitxWatcher();
|
||||
|
||||
private:
|
||||
Keyboard *m_keyboard;
|
||||
bool m_fcitxRunning;
|
||||
FcitxInputMethodProxy *m_inputmethod;
|
||||
QDBusServiceWatcher *m_fcitxWatcher;
|
||||
QGSettings *m_keybingEnabled;
|
||||
QGSettings *m_dccSettings;
|
||||
QMenu *m_menu;
|
||||
QAction *m_addLayoutAction;
|
||||
|
||||
|
79
plugins/keyboard-layout/fcitxinputmethoditem.cpp
Normal file
79
plugins/keyboard-layout/fcitxinputmethoditem.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include "fcitxinputmethoditem.h"
|
||||
|
||||
#include <QDBusArgument>
|
||||
#include <QDBusMetaType>
|
||||
|
||||
bool FcitxQtInputMethodItem::enabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
const QString& FcitxQtInputMethodItem::langCode() const
|
||||
{
|
||||
return m_langCode;
|
||||
}
|
||||
|
||||
const QString& FcitxQtInputMethodItem::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const QString& FcitxQtInputMethodItem::uniqueName() const
|
||||
{
|
||||
return m_uniqueName;
|
||||
}
|
||||
|
||||
void FcitxQtInputMethodItem::setEnabled(bool enable)
|
||||
{
|
||||
m_enabled = enable;
|
||||
}
|
||||
|
||||
void FcitxQtInputMethodItem::setLangCode(const QString& lang)
|
||||
{
|
||||
m_langCode = lang;
|
||||
}
|
||||
|
||||
void FcitxQtInputMethodItem::setName(const QString& name)
|
||||
{
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
void FcitxQtInputMethodItem::setUniqueName(const QString& name)
|
||||
{
|
||||
m_uniqueName = name;
|
||||
}
|
||||
|
||||
void FcitxQtInputMethodItem::registerMetaType()
|
||||
{
|
||||
qRegisterMetaType<FcitxQtInputMethodItem>("FcitxQtInputMethodItem");
|
||||
qDBusRegisterMetaType<FcitxQtInputMethodItem>();
|
||||
qRegisterMetaType<FcitxQtInputMethodItemList>("FcitxQtInputMethodItemList");
|
||||
qDBusRegisterMetaType<FcitxQtInputMethodItemList>();
|
||||
}
|
||||
|
||||
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtInputMethodItem& im)
|
||||
{
|
||||
argument.beginStructure();
|
||||
argument << im.name();
|
||||
argument << im.uniqueName();
|
||||
argument << im.langCode();
|
||||
argument << im.enabled();
|
||||
argument.endStructure();
|
||||
return argument;
|
||||
}
|
||||
|
||||
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtInputMethodItem& im)
|
||||
{
|
||||
QString name;
|
||||
QString uniqueName;
|
||||
QString langCode;
|
||||
bool enabled;
|
||||
argument.beginStructure();
|
||||
argument >> name >> uniqueName >> langCode >> enabled;
|
||||
argument.endStructure();
|
||||
im.setName(name);
|
||||
im.setUniqueName(uniqueName);
|
||||
im.setLangCode(langCode);
|
||||
im.setEnabled(enabled);
|
||||
return argument;
|
||||
}
|
43
plugins/keyboard-layout/fcitxinputmethoditem.h
Normal file
43
plugins/keyboard-layout/fcitxinputmethoditem.h
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
#ifndef FCITX_QT_INPUT_METHOD_ITEM_H
|
||||
#define FCITX_QT_INPUT_METHOD_ITEM_H
|
||||
|
||||
// Qt
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QMetaType>
|
||||
#include <QtDBus/QDBusArgument>
|
||||
|
||||
class FcitxQtInputMethodItem
|
||||
{
|
||||
public:
|
||||
const QString& name() const;
|
||||
const QString& uniqueName() const;
|
||||
const QString& langCode() const;
|
||||
bool enabled() const;
|
||||
|
||||
void setName(const QString& name);
|
||||
void setUniqueName(const QString& name);
|
||||
void setLangCode(const QString& name);
|
||||
void setEnabled(bool name);
|
||||
static void registerMetaType();
|
||||
|
||||
inline bool operator < (const FcitxQtInputMethodItem& im) const {
|
||||
return (m_enabled && !im.m_enabled);
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
QString m_uniqueName;
|
||||
QString m_langCode;
|
||||
bool m_enabled;
|
||||
};
|
||||
|
||||
typedef QList<FcitxQtInputMethodItem> FcitxQtInputMethodItemList;
|
||||
|
||||
QDBusArgument& operator<<(QDBusArgument& argument, const FcitxQtInputMethodItem& im);
|
||||
const QDBusArgument& operator>>(const QDBusArgument& argument, FcitxQtInputMethodItem& im);
|
||||
|
||||
Q_DECLARE_METATYPE(FcitxQtInputMethodItem)
|
||||
Q_DECLARE_METATYPE(FcitxQtInputMethodItemList)
|
||||
|
||||
#endif
|
78
plugins/keyboard-layout/org.fcitx.Fcitx.xml
Normal file
78
plugins/keyboard-layout/org.fcitx.Fcitx.xml
Normal file
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||
<node>
|
||||
<interface name="org.fcitx.Fcitx.InputMethod">
|
||||
<method name="CreateIC">
|
||||
<arg name="icid" direction="out" type="i"/>
|
||||
<arg name="keyval1" direction="out" type="u"/>
|
||||
<arg name="state1" direction="out" type="u"/>
|
||||
<arg name="keyval2" direction="out" type="u"/>
|
||||
<arg name="state2" direction="out" type="u"/>
|
||||
</method>
|
||||
<method name="CreateICv2">
|
||||
<arg name="appname" direction="in" type="s"/>
|
||||
<arg name="icid" direction="out" type="i"/>
|
||||
<arg name="enable" direction="out" type="b"/>
|
||||
<arg name="keyval1" direction="out" type="u"/>
|
||||
<arg name="state1" direction="out" type="u"/>
|
||||
<arg name="keyval2" direction="out" type="u"/>
|
||||
<arg name="state2" direction="out" type="u"/>
|
||||
</method>
|
||||
<method name="CreateICv3">
|
||||
<arg name="appname" direction="in" type="s"/>
|
||||
<arg name="pid" direction="in" type="i"/>
|
||||
<arg name="icid" direction="out" type="i"/>
|
||||
<arg name="enable" direction="out" type="b"/>
|
||||
<arg name="keyval1" direction="out" type="u"/>
|
||||
<arg name="state1" direction="out" type="u"/>
|
||||
<arg name="keyval2" direction="out" type="u"/>
|
||||
<arg name="state2" direction="out" type="u"/>
|
||||
</method>
|
||||
<method name="Exit"></method>
|
||||
<method name="GetCurrentIM">
|
||||
<arg name="im" direction="out" type="s"/>
|
||||
</method>
|
||||
<method name="GetIMByIndex">
|
||||
<arg name="index" direction="in" type="i"/>
|
||||
<arg name="im" direction="out" type="s"/>
|
||||
</method>
|
||||
<method name="SetCurrentIM">
|
||||
<arg name="im" direction="in" type="s"/>
|
||||
</method>
|
||||
<method name="ReloadConfig"></method>
|
||||
<method name="ReloadAddonConfig">
|
||||
<arg name="addon" direction="in" type="s"/>
|
||||
</method>
|
||||
<method name="Restart"></method>
|
||||
<method name="Configure"></method>
|
||||
<method name="ConfigureAddon">
|
||||
<arg name="addon" direction="in" type="s"/>
|
||||
</method>
|
||||
<method name="ConfigureIM">
|
||||
<arg name="im" direction="in" type="s"/>
|
||||
</method>
|
||||
<method name="GetCurrentUI">
|
||||
<arg name="addon" direction="out" type="s"/>
|
||||
</method>
|
||||
<method name="GetIMAddon">
|
||||
<arg name="im" direction="in" type="s"/>
|
||||
<arg name="addon" direction="out" type="s"/>
|
||||
</method>
|
||||
<method name="ActivateIM"></method>
|
||||
<method name="InactivateIM"></method>
|
||||
<method name="ToggleIM"></method>
|
||||
<method name="SwitchIM"></method>
|
||||
<method name="ResetIMList"></method>
|
||||
<method name="GetCurrentState">
|
||||
<arg name="state" direction="out" type="i"/>
|
||||
</method>
|
||||
<signal name="ReloadConfigUI"></signal>
|
||||
<property access="readwrite" type="a(sssb)" name="IMList">
|
||||
<annotation name="org.qtproject.QtDBus.QtTypeName" value="FcitxQtInputMethodItemList"/>
|
||||
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/>
|
||||
</property>
|
||||
<property access="readwrite" type="s" name="CurrentIM">
|
||||
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/>
|
||||
</property>
|
||||
</interface>
|
||||
</node>
|
Loading…
x
Reference in New Issue
Block a user