use new fcitxwatcher based implementation for proxy.
This commit is contained in:
parent
16972ee69c
commit
a44e118ff3
|
@ -22,15 +22,16 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fcitx5qt4dbusaddons_version.h
|
|||
DESTINATION ${Fcitx5Qt4_INCLUDE_INSTALL_DIR} COMPONENT Devel )
|
||||
|
||||
set(dbusaddons_SOURCES
|
||||
fcitxqtconnection.cpp
|
||||
fcitxqtwatcher.cpp
|
||||
fcitxqtdbustypes.cpp
|
||||
fcitxqtinputcontextproxy.cpp
|
||||
fcitxqtinputcontextproxyimpl.cpp
|
||||
fcitxqtinputmethodproxy.cpp
|
||||
fcitxqtcontrollerproxy.cpp
|
||||
)
|
||||
|
||||
set(dbusaddons_HEADERS
|
||||
fcitxqtconnection.h
|
||||
fcitxqtwatcher.h
|
||||
fcitxqtdbustypes.h
|
||||
fcitxqtinputcontextproxy.h
|
||||
fcitxqtinputmethodproxy.h
|
||||
|
|
|
@ -1,188 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2012~2017 by CSSlayer
|
||||
* wengxt@gmail.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 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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "fcitxqtconnection_p.h"
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusReply>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QTimer>
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
FcitxQtConnection::FcitxQtConnection(QObject *parent)
|
||||
: QObject(parent), d_ptr(new FcitxQtConnectionPrivate(this)) {}
|
||||
|
||||
void FcitxQtConnection::startConnection() {
|
||||
Q_D(FcitxQtConnection);
|
||||
if (!d->m_initialized) {
|
||||
d->initialize();
|
||||
d->createConnection();
|
||||
}
|
||||
}
|
||||
|
||||
void FcitxQtConnection::endConnection() {
|
||||
Q_D(FcitxQtConnection);
|
||||
d->cleanUp();
|
||||
d->finalize();
|
||||
d->m_connectedOnce = false;
|
||||
}
|
||||
|
||||
bool FcitxQtConnection::autoReconnect() {
|
||||
Q_D(FcitxQtConnection);
|
||||
return d->m_autoReconnect;
|
||||
}
|
||||
|
||||
void FcitxQtConnection::setAutoReconnect(bool a) {
|
||||
Q_D(FcitxQtConnection);
|
||||
d->m_autoReconnect = a;
|
||||
}
|
||||
|
||||
QDBusConnection *FcitxQtConnection::connection() {
|
||||
Q_D(FcitxQtConnection);
|
||||
return d->m_connection;
|
||||
}
|
||||
|
||||
const QString &FcitxQtConnection::serviceName() {
|
||||
Q_D(FcitxQtConnection);
|
||||
return d->m_serviceName;
|
||||
}
|
||||
|
||||
bool FcitxQtConnection::isConnected() {
|
||||
Q_D(FcitxQtConnection);
|
||||
return d->isConnected();
|
||||
}
|
||||
|
||||
FcitxQtConnection::~FcitxQtConnection() {}
|
||||
|
||||
FcitxQtConnectionPrivate::FcitxQtConnectionPrivate(FcitxQtConnection *conn)
|
||||
: QObject(conn), q_ptr(conn), m_serviceName("org.fcitx.Fcitx5"),
|
||||
m_connection(nullptr), m_serviceWatcher(new QDBusServiceWatcher(this)),
|
||||
m_autoReconnect(true), m_connectedOnce(false), m_initialized(false) {}
|
||||
|
||||
FcitxQtConnectionPrivate::~FcitxQtConnectionPrivate() {
|
||||
if (m_connection)
|
||||
delete m_connection;
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::initialize() {
|
||||
m_serviceWatcher->setConnection(QDBusConnection::sessionBus());
|
||||
m_serviceWatcher->addWatchedService(m_serviceName);
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::finalize() {
|
||||
m_serviceWatcher->removeWatchedService(m_serviceName);
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::createConnection() {
|
||||
if (m_connectedOnce && !m_autoReconnect) {
|
||||
return;
|
||||
}
|
||||
|
||||
disconnect(m_serviceWatcher,
|
||||
SIGNAL(serviceOwnerChanged(QString, QString, QString)), this,
|
||||
SLOT(imChanged(QString, QString, QString)));
|
||||
if (!m_connection) {
|
||||
QDBusConnection *connection =
|
||||
new QDBusConnection(QDBusConnection::sessionBus());
|
||||
connect(m_serviceWatcher,
|
||||
SIGNAL(serviceOwnerChanged(QString, QString, QString)), this,
|
||||
SLOT(imChanged(QString, QString, QString)));
|
||||
QDBusReply<bool> registered =
|
||||
connection->interface()->isServiceRegistered(m_serviceName);
|
||||
if (!registered.isValid() || !registered.value()) {
|
||||
delete connection;
|
||||
} else {
|
||||
m_connection = connection;
|
||||
}
|
||||
}
|
||||
|
||||
Q_Q(FcitxQtConnection);
|
||||
if (m_connection) {
|
||||
|
||||
m_connection->connect("org.freedesktop.DBus.Local",
|
||||
"/org/freedesktop/DBus/Local",
|
||||
"org.freedesktop.DBus.Local", "Disconnected",
|
||||
this, SLOT(dbusDisconnected()));
|
||||
m_connectedOnce = true;
|
||||
emit q->connected();
|
||||
}
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::dbusDisconnected() {
|
||||
cleanUp();
|
||||
|
||||
createConnection();
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::imChanged(const QString &service,
|
||||
const QString &oldowner,
|
||||
const QString &newowner) {
|
||||
if (service == m_serviceName) {
|
||||
/* old die */
|
||||
if (oldowner.length() > 0 || newowner.length() > 0)
|
||||
cleanUp();
|
||||
|
||||
/* new rise */
|
||||
if (newowner.length() > 0) {
|
||||
QTimer::singleShot(100, this, SLOT(newServiceAppear()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::cleanUp() {
|
||||
Q_Q(FcitxQtConnection);
|
||||
bool doemit = false;
|
||||
if (m_connection) {
|
||||
delete m_connection;
|
||||
m_connection = nullptr;
|
||||
doemit = true;
|
||||
}
|
||||
|
||||
if (!m_autoReconnect && m_connectedOnce)
|
||||
finalize();
|
||||
|
||||
/* we want m_connection and finalize being called before the signal
|
||||
* thus isConnected will return false in slot
|
||||
* and startConnection can be called in slot
|
||||
*/
|
||||
if (doemit)
|
||||
emit q->disconnected();
|
||||
}
|
||||
|
||||
bool FcitxQtConnectionPrivate::isConnected() {
|
||||
return m_connection && m_connection->isConnected();
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::newServiceAppear() {
|
||||
if (!isConnected()) {
|
||||
cleanUp();
|
||||
|
||||
createConnection();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2012~2017 by CSSlayer
|
||||
* wengxt@gmail.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 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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DBUSADDONS_FCITXQTCONNECTION_H_
|
||||
#define _DBUSADDONS_FCITXQTCONNECTION_H_
|
||||
|
||||
#include "fcitx5qt4dbusaddons_export.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QDBusConnection;
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class FcitxQtConnectionPrivate;
|
||||
|
||||
/**
|
||||
* dbus connection to fcitx
|
||||
**/
|
||||
class FCITX5QT4DBUSADDONS_EXPORT FcitxQtConnection : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool autoReconnect READ autoReconnect WRITE setAutoReconnect)
|
||||
Q_PROPERTY(bool connected READ isConnected)
|
||||
Q_PROPERTY(QDBusConnection *connection READ connection)
|
||||
Q_PROPERTY(QString serviceName READ serviceName)
|
||||
public:
|
||||
/**
|
||||
* create a new connection
|
||||
*
|
||||
* @param parent
|
||||
**/
|
||||
explicit FcitxQtConnection(QObject *parent = 0);
|
||||
|
||||
/**
|
||||
* destroy the connection
|
||||
**/
|
||||
virtual ~FcitxQtConnection();
|
||||
|
||||
/**
|
||||
* the connection will not start to work until you call this function
|
||||
* you may want to connect to the signal before you call this function
|
||||
**/
|
||||
void startConnection();
|
||||
void endConnection();
|
||||
/**
|
||||
* automatically reconnect if fcitx disappeared
|
||||
*
|
||||
* @param a ...
|
||||
* @return void
|
||||
**/
|
||||
void setAutoReconnect(bool a);
|
||||
|
||||
/**
|
||||
* check this connection is doing automatical reconnect or not
|
||||
*
|
||||
* default value is true
|
||||
**/
|
||||
bool autoReconnect();
|
||||
|
||||
/**
|
||||
* return the current dbus connection to fcitx, notice, the object return
|
||||
* by this function might be deteled if fcitx disappear, or might return 0
|
||||
* if fcitx is not running
|
||||
*
|
||||
* @return QDBusConnection*
|
||||
**/
|
||||
QDBusConnection *connection();
|
||||
/**
|
||||
* current fcitx dbus service name, can be used for create DBus proxy
|
||||
*
|
||||
* @return service name
|
||||
**/
|
||||
const QString &serviceName();
|
||||
/**
|
||||
* check its connected or not
|
||||
**/
|
||||
bool isConnected();
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* this signal will be emitted upon fcitx appears
|
||||
**/
|
||||
void connected();
|
||||
/**
|
||||
* this signal will be emitted upon fcitx disappears
|
||||
*
|
||||
* it will come with connected in pair
|
||||
**/
|
||||
void disconnected();
|
||||
|
||||
private:
|
||||
FcitxQtConnectionPrivate *const d_ptr;
|
||||
Q_DECLARE_PRIVATE(FcitxQtConnection);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _DBUSADDONS_FCITXQTCONNECTION_H_
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017~2017 by CSSlayer
|
||||
* wengxt@gmail.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 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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DBUSADDONS_FCITXQTCONNECTION_P_H_
|
||||
#define _DBUSADDONS_FCITXQTCONNECTION_P_H_
|
||||
|
||||
#include "fcitxqtconnection.h"
|
||||
|
||||
class QDBusConnection;
|
||||
class QDBusServiceWatcher;
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class FcitxQtConnectionPrivate : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FcitxQtConnectionPrivate(FcitxQtConnection *conn);
|
||||
virtual ~FcitxQtConnectionPrivate();
|
||||
FcitxQtConnection *const q_ptr;
|
||||
Q_DECLARE_PUBLIC(FcitxQtConnection);
|
||||
|
||||
private Q_SLOTS:
|
||||
void imChanged(const QString &service, const QString &oldowner,
|
||||
const QString &newowner);
|
||||
void dbusDisconnected();
|
||||
void cleanUp();
|
||||
void newServiceAppear();
|
||||
|
||||
private:
|
||||
bool isConnected();
|
||||
void createConnection();
|
||||
void initialize();
|
||||
void finalize();
|
||||
|
||||
QString m_serviceName;
|
||||
QDBusConnection *m_connection;
|
||||
QDBusServiceWatcher *m_serviceWatcher;
|
||||
QString m_socketFile;
|
||||
bool m_autoReconnect;
|
||||
bool m_connectedOnce;
|
||||
bool m_initialized;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _DBUSADDONS_FCITXQTCONNECTION_P_H_
|
|
@ -1,29 +1,112 @@
|
|||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.7
|
||||
* Command line was: qdbusxml2cpp -N -p fcitxqtinputcontextproxy -c FcitxQtInputContextProxy interfaces/org.fcitx.Fcitx.InputContext1.xml -i fcitxqtdbustypes.h -i fcitx5qt4dbusaddons_export.h
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2015 The Qt Company Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
* Copyright (C) 2017~2017 by CSSlayer
|
||||
* wengxt@gmail.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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "fcitxqtinputcontextproxy.h"
|
||||
#include "fcitxqtinputcontextproxy_p.h"
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusMetaType>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QFileInfo>
|
||||
#include <QCoreApplication>
|
||||
#include <QTimer>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
/*
|
||||
* Implementation of interface class FcitxQtInputContextProxy
|
||||
*/
|
||||
|
||||
FcitxQtInputContextProxy::FcitxQtInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
FcitxQtInputContextProxy::FcitxQtInputContextProxy(FcitxQtWatcher *watcher, QObject *parent) : QObject(parent),
|
||||
d_ptr(new FcitxQtInputContextProxyPrivate(watcher, this))
|
||||
{
|
||||
}
|
||||
|
||||
FcitxQtInputContextProxy::~FcitxQtInputContextProxy()
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
if (isValid()) {
|
||||
d->m_icproxy->DestroyIC();
|
||||
}
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void FcitxQtInputContextProxy::setDisplay(const QString& display)
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
d->m_display = display;
|
||||
}
|
||||
|
||||
const QString &FcitxQtInputContextProxy::display() const
|
||||
{
|
||||
Q_D(const FcitxQtInputContextProxy);
|
||||
return d->m_display;
|
||||
}
|
||||
|
||||
bool FcitxQtInputContextProxy::isValid() const
|
||||
{
|
||||
Q_D(const FcitxQtInputContextProxy);
|
||||
return d->isValid();
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::focusIn()
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->FocusIn();
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::focusOut()
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->FocusOut();
|
||||
}
|
||||
|
||||
QDBusPendingReply<bool> FcitxQtInputContextProxy::processKeyEvent(uint keyval, uint keycode, uint state, bool type, uint time)
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->ProcessKeyEvent(keyval, keycode, state, type, time);
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::reset()
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->Reset();
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::setCapability(qulonglong caps)
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->SetCapability(caps);
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::setCursorRect(int x, int y, int w, int h)
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->SetCursorRect(x, y, w, h);
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::setSurroundingText(const QString &text, uint cursor, uint anchor)
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->SetSurroundingText(text, cursor, anchor);
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::setSurroundingTextPosition(uint cursor, uint anchor)
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->SetSurroundingTextPosition(cursor, anchor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "moc_fcitxqtinputcontextproxy.cpp"
|
||||
|
|
|
@ -1,112 +1,77 @@
|
|||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.7
|
||||
* Command line was: qdbusxml2cpp -N -p fcitxqtinputcontextproxy -c FcitxQtInputContextProxy interfaces/org.fcitx.Fcitx.InputContext1.xml -i fcitxqtdbustypes.h -i fcitx5qt4dbusaddons_export.h
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2015 The Qt Company Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
* Copyright (C) 2017~2017 by CSSlayer
|
||||
* wengxt@gmail.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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DBUSADDONS_FCITXQTINPUTCONTEXTPROXY_H_
|
||||
#define _DBUSADDONS_FCITXQTINPUTCONTEXTPROXY_H_
|
||||
|
||||
#ifndef FCITXQTINPUTCONTEXTPROXY_H_1495144859
|
||||
#define FCITXQTINPUTCONTEXTPROXY_H_1495144859
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtDBus/QtDBus>
|
||||
#include "fcitxqtdbustypes.h"
|
||||
#include "fcitx5qt4dbusaddons_export.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusPendingReply>
|
||||
#include "fcitxqtdbustypes.h"
|
||||
|
||||
class QDBusPendingCallWatcher;
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
/*
|
||||
* Proxy class for interface org.fcitx.Fcitx.InputContext1
|
||||
*/
|
||||
class FCITX5QT4DBUSADDONS_EXPORT FcitxQtInputContextProxy: public QDBusAbstractInterface
|
||||
{
|
||||
class FcitxQtWatcher;
|
||||
class FcitxQtInputContextProxyPrivate;
|
||||
|
||||
class FCITX5QT4DBUSADDONS_EXPORT FcitxQtInputContextProxy : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "org.fcitx.Fcitx.InputContext1"; }
|
||||
|
||||
public:
|
||||
FcitxQtInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
FcitxQtInputContextProxy(FcitxQtWatcher *watcher, QObject *parent);
|
||||
~FcitxQtInputContextProxy();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<> DestroyIC()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("DestroyIC"), argumentList);
|
||||
}
|
||||
bool isValid() const;
|
||||
void setDisplay(const QString &display);
|
||||
const QString &display() const;
|
||||
|
||||
inline QDBusPendingReply<> FocusIn()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("FocusIn"), argumentList);
|
||||
}
|
||||
public slots:
|
||||
QDBusPendingReply<> focusIn();
|
||||
QDBusPendingReply<> focusOut();
|
||||
QDBusPendingReply<bool> processKeyEvent(uint keyval, uint keycode, uint state, bool type, uint time);
|
||||
QDBusPendingReply<> reset();
|
||||
QDBusPendingReply<> setCapability(qulonglong caps);
|
||||
QDBusPendingReply<> setCursorRect(int x, int y, int w, int h);
|
||||
QDBusPendingReply<> setSurroundingText(const QString &text, uint cursor, uint anchor);
|
||||
QDBusPendingReply<> setSurroundingTextPosition(uint cursor, uint anchor);
|
||||
|
||||
inline QDBusPendingReply<> FocusOut()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("FocusOut"), argumentList);
|
||||
}
|
||||
signals:
|
||||
void commitString(const QString &str);
|
||||
void currentIM(const QString &name, const QString &uniqueName, const QString &langCode);
|
||||
void deleteSurroundingText(int offset, uint nchar);
|
||||
void forwardKey(uint keyval, uint state, bool isRelease);
|
||||
void updateFormattedPreedit(const FcitxQtFormattedPreeditList &str, int cursorpos);
|
||||
void inputContextCreated(const QByteArray &uuid);
|
||||
|
||||
inline QDBusPendingReply<bool> ProcessKeyEvent(uint keyval, uint keycode, uint state, bool type, uint time)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(keyval) << QVariant::fromValue(keycode) << QVariant::fromValue(state) << QVariant::fromValue(type) << QVariant::fromValue(time);
|
||||
return asyncCallWithArgumentList(QLatin1String("ProcessKeyEvent"), argumentList);
|
||||
}
|
||||
private:
|
||||
Q_PRIVATE_SLOT(d_func(), void availabilityChanged());
|
||||
Q_PRIVATE_SLOT(d_func(), void recheck());
|
||||
Q_PRIVATE_SLOT(d_func(), void cleanUp());
|
||||
Q_PRIVATE_SLOT(d_func(), void createInputContextFinished());
|
||||
|
||||
inline QDBusPendingReply<> Reset()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("Reset"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetCapability(qulonglong caps)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(caps);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetCapability"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetCursorRect(int x, int y, int w, int h)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(x) << QVariant::fromValue(y) << QVariant::fromValue(w) << QVariant::fromValue(h);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetCursorRect"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetSurroundingText(const QString &text, uint cursor, uint anchor)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(text) << QVariant::fromValue(cursor) << QVariant::fromValue(anchor);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetSurroundingText"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetSurroundingTextPosition(uint cursor, uint anchor)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(cursor) << QVariant::fromValue(anchor);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetSurroundingTextPosition"), argumentList);
|
||||
}
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void CommitString(const QString &str);
|
||||
void CurrentIM(const QString &name, const QString &uniqueName, const QString &langCode);
|
||||
void DeleteSurroundingText(int offset, uint nchar);
|
||||
void ForwardKey(uint keyval, uint state, bool type);
|
||||
void UpdateFormattedPreedit(FcitxQtFormattedPreeditList str, int cursorpos);
|
||||
FcitxQtInputContextProxyPrivate *const d_ptr;
|
||||
Q_DECLARE_PRIVATE(FcitxQtInputContextProxy);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // _DBUSADDONS_FCITXQTINPUTCONTEXTPROXY_H_
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright (C) 2017~2017 by CSSlayer
|
||||
* wengxt@gmail.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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DBUSADDONS_FCITXQTINPUTCONTEXTPROXY_P_H_
|
||||
#define _DBUSADDONS_FCITXQTINPUTCONTEXTPROXY_P_H_
|
||||
|
||||
#include "fcitxqtinputcontextproxy.h"
|
||||
#include "fcitxqtinputcontextproxyimpl.h"
|
||||
#include "fcitxqtinputmethodproxy.h"
|
||||
#include "fcitxqtwatcher.h"
|
||||
#include <QDBusServiceWatcher>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class FcitxQtInputContextProxyPrivate {
|
||||
public:
|
||||
FcitxQtInputContextProxyPrivate(FcitxQtWatcher *watcher,
|
||||
FcitxQtInputContextProxy *q)
|
||||
: q_ptr(q), m_fcitxWatcher(watcher), m_watcher(q) {
|
||||
FcitxQtFormattedPreedit::registerMetaType();
|
||||
FcitxQtInputContextArgument::registerMetaType();
|
||||
QObject::connect(m_fcitxWatcher, SIGNAL(availibilityChanged(bool)), q,
|
||||
SLOT(availabilityChanged()));
|
||||
m_watcher.setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
|
||||
QObject::connect(&m_watcher, SIGNAL(serviceUnregistered(QString)), q,
|
||||
SLOT(availabilityChanged()));
|
||||
availabilityChanged();
|
||||
}
|
||||
|
||||
~FcitxQtInputContextProxyPrivate() {
|
||||
if (isValid()) {
|
||||
m_icproxy->DestroyIC();
|
||||
}
|
||||
}
|
||||
|
||||
bool isValid() const { return (m_icproxy && m_icproxy->isValid()); }
|
||||
|
||||
void availabilityChanged() {
|
||||
QTimer::singleShot(100, q_ptr, SLOT(recheck()));
|
||||
}
|
||||
|
||||
void recheck() {
|
||||
if (!isValid() && m_fcitxWatcher->availability()) {
|
||||
createInputContext();
|
||||
}
|
||||
if (!m_fcitxWatcher->availability()) {
|
||||
cleanUp();
|
||||
}
|
||||
}
|
||||
|
||||
void cleanUp() {
|
||||
auto services = m_watcher.watchedServices();
|
||||
for (const auto &service : services) {
|
||||
m_watcher.removeWatchedService(service);
|
||||
}
|
||||
|
||||
delete m_improxy;
|
||||
m_improxy = nullptr;
|
||||
delete m_icproxy;
|
||||
m_icproxy = nullptr;
|
||||
delete m_createInputContextWatcher;
|
||||
m_createInputContextWatcher = nullptr;
|
||||
}
|
||||
|
||||
void createInputContext() {
|
||||
Q_Q(FcitxQtInputContextProxy);
|
||||
if (!m_fcitxWatcher->availability()) {
|
||||
return;
|
||||
}
|
||||
|
||||
cleanUp();
|
||||
|
||||
auto service = m_fcitxWatcher->serviceName();
|
||||
auto connection = m_fcitxWatcher->connection();
|
||||
|
||||
auto owner = connection.interface()->serviceOwner(service);
|
||||
if (!owner.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_watcher.setConnection(connection);
|
||||
m_watcher.setWatchedServices(QStringList() << owner);
|
||||
// Avoid race, query again.
|
||||
if (!connection.interface()->isServiceRegistered(owner)) {
|
||||
cleanUp();
|
||||
return;
|
||||
}
|
||||
|
||||
QFileInfo info(QCoreApplication::applicationFilePath());
|
||||
m_portal = true;
|
||||
m_improxy =
|
||||
new FcitxQtInputMethodProxy(owner, "/inputmethod", connection, q);
|
||||
FcitxQtInputContextArgumentList list;
|
||||
FcitxQtInputContextArgument arg;
|
||||
arg.setName("program");
|
||||
arg.setValue(info.fileName());
|
||||
list << arg;
|
||||
if (!m_display.isEmpty()) {
|
||||
FcitxQtInputContextArgument arg2;
|
||||
arg2.setName("display");
|
||||
arg2.setValue(m_display);
|
||||
list << arg2;
|
||||
}
|
||||
|
||||
auto result = m_improxy->CreateInputContext(list);
|
||||
m_createInputContextWatcher = new QDBusPendingCallWatcher(result);
|
||||
QObject::connect(m_createInputContextWatcher,
|
||||
SIGNAL(finished(QDBusPendingCallWatcher *)), q,
|
||||
SLOT(createInputContextFinished()));
|
||||
}
|
||||
|
||||
void createInputContextFinished() {
|
||||
Q_Q(FcitxQtInputContextProxy);
|
||||
if (m_createInputContextWatcher->isError()) {
|
||||
cleanUp();
|
||||
return;
|
||||
}
|
||||
|
||||
QDBusPendingReply<QDBusObjectPath, QByteArray> reply(
|
||||
*m_createInputContextWatcher);
|
||||
m_icproxy = new FcitxQtInputContextProxyImpl(
|
||||
m_improxy->service(), reply.value().path(), m_improxy->connection(),
|
||||
q);
|
||||
QObject::connect(m_icproxy, SIGNAL(CommitString(QString)), q,
|
||||
SIGNAL(commitString(QString)));
|
||||
QObject::connect(m_icproxy,
|
||||
SIGNAL(CurrentIM(QString, QString, QString)), q,
|
||||
SIGNAL(currentIM(QString, QString, QString)));
|
||||
QObject::connect(m_icproxy, SIGNAL(ForwardKey(uint, uint, bool)), q,
|
||||
SIGNAL(forwardKey(uint, uint, bool)));
|
||||
QObject::connect(
|
||||
m_icproxy,
|
||||
SIGNAL(UpdateFormattedPreedit(FcitxFormattedPreeditList, int)), q,
|
||||
SIGNAL(updateFormattedPreedit(FcitxFormattedPreeditList, int)));
|
||||
QObject::connect(m_icproxy, SIGNAL(DeleteSurroundingText(int, uint)), q,
|
||||
SLOT(deleteSurroundingText(int, uint)));
|
||||
|
||||
delete m_createInputContextWatcher;
|
||||
m_createInputContextWatcher = nullptr;
|
||||
emit q->inputContextCreated(reply.argumentAt<1>());
|
||||
}
|
||||
|
||||
FcitxQtInputContextProxy *q_ptr;
|
||||
Q_DECLARE_PUBLIC(FcitxQtInputContextProxy);
|
||||
|
||||
FcitxQtWatcher *m_fcitxWatcher;
|
||||
QDBusServiceWatcher m_watcher;
|
||||
FcitxQtInputMethodProxy *m_improxy = nullptr;
|
||||
FcitxQtInputContextProxyImpl *m_icproxy = nullptr;
|
||||
QDBusPendingCallWatcher *m_createInputContextWatcher = nullptr;
|
||||
QString m_display;
|
||||
bool m_portal;
|
||||
qulonglong m_capability;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _DBUSADDONS_FCITXQTINPUTCONTEXTPROXY_P_H_
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.7
|
||||
* Command line was: qdbusxml2cpp -N -p fcitxqtinputcontextproxyimpl -c
|
||||
* FcitxQtInputContextProxyImpl interfaces/org.fcitx.Fcitx.InputContext1.xml -i
|
||||
* fcitxqtdbustypes.h -i fcitx5qt4dbusaddons_export.h
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2015 The Qt Company Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "fcitxqtinputcontextproxyimpl.h"
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
/*
|
||||
* Implementation of interface class FcitxQtInputContextProxyImpl
|
||||
*/
|
||||
|
||||
FcitxQtInputContextProxyImpl::FcitxQtInputContextProxyImpl(
|
||||
const QString &service, const QString &path,
|
||||
const QDBusConnection &connection, QObject *parent)
|
||||
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection,
|
||||
parent) {}
|
||||
|
||||
FcitxQtInputContextProxyImpl::~FcitxQtInputContextProxyImpl() {}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.7
|
||||
* Command line was: qdbusxml2cpp -N -p fcitxqtinputcontextproxyimpl -c
|
||||
* FcitxQtInputContextProxyImpl interfaces/org.fcitx.Fcitx.InputContext1.xml -i
|
||||
* fcitxqtdbustypes.h -i fcitx5qt4dbusaddons_export.h
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2015 The Qt Company Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef FCITXQTINPUTCONTEXTPROXYIMPL_H_1508138556
|
||||
#define FCITXQTINPUTCONTEXTPROXYIMPL_H_1508138556
|
||||
|
||||
#include "fcitx5qt4dbusaddons_export.h"
|
||||
#include "fcitxqtdbustypes.h"
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
/*
|
||||
* Proxy class for interface org.fcitx.Fcitx.InputContext1
|
||||
*/
|
||||
class FcitxQtInputContextProxyImpl : public QDBusAbstractInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static inline const char *staticInterfaceName() {
|
||||
return "org.fcitx.Fcitx.InputContext1";
|
||||
}
|
||||
|
||||
public:
|
||||
FcitxQtInputContextProxyImpl(const QString &service, const QString &path,
|
||||
const QDBusConnection &connection,
|
||||
QObject *parent = 0);
|
||||
|
||||
~FcitxQtInputContextProxyImpl();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<> DestroyIC() {
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("DestroyIC"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> FocusIn() {
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("FocusIn"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> FocusOut() {
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("FocusOut"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<bool> ProcessKeyEvent(uint keyval, uint keycode,
|
||||
uint state, bool type,
|
||||
uint time) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(keyval)
|
||||
<< QVariant::fromValue(keycode)
|
||||
<< QVariant::fromValue(state) << QVariant::fromValue(type)
|
||||
<< QVariant::fromValue(time);
|
||||
return asyncCallWithArgumentList(QLatin1String("ProcessKeyEvent"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> Reset() {
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QLatin1String("Reset"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetCapability(qulonglong caps) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(caps);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetCapability"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetCursorRect(int x, int y, int w, int h) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(x) << QVariant::fromValue(y)
|
||||
<< QVariant::fromValue(w) << QVariant::fromValue(h);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetCursorRect"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetSurroundingText(const QString &text,
|
||||
uint cursor, uint anchor) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(text) << QVariant::fromValue(cursor)
|
||||
<< QVariant::fromValue(anchor);
|
||||
return asyncCallWithArgumentList(QLatin1String("SetSurroundingText"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetSurroundingTextPosition(uint cursor,
|
||||
uint anchor) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(cursor)
|
||||
<< QVariant::fromValue(anchor);
|
||||
return asyncCallWithArgumentList(
|
||||
QLatin1String("SetSurroundingTextPosition"), argumentList);
|
||||
}
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void CommitString(const QString &str);
|
||||
void CurrentIM(const QString &name, const QString &uniqueName,
|
||||
const QString &langCode);
|
||||
void DeleteSurroundingText(int offset, uint nchar);
|
||||
void ForwardKey(uint keyval, uint state, bool type);
|
||||
void UpdateFormattedPreedit(FcitxQtFormattedPreeditList str, int cursorpos);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,151 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011~2012 by CSSlayer *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program 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 General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "fcitxqtwatcher_p.h"
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QDir>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
FcitxQtWatcher::FcitxQtWatcher(QObject *parent)
|
||||
: QObject(parent), d_ptr(new FcitxQtWatcherPrivate(this)) {}
|
||||
|
||||
FcitxQtWatcher::FcitxQtWatcher(const QDBusConnection &connection,
|
||||
QObject *parent)
|
||||
: FcitxQtWatcher(parent) {
|
||||
setConnection(connection);
|
||||
}
|
||||
|
||||
FcitxQtWatcher::~FcitxQtWatcher() { delete d_ptr; }
|
||||
|
||||
bool FcitxQtWatcher::availability() const {
|
||||
Q_D(const FcitxQtWatcher);
|
||||
return d->m_availability;
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::setConnection(const QDBusConnection &connection) {
|
||||
Q_D(FcitxQtWatcher);
|
||||
return d->m_serviceWatcher.setConnection(connection);
|
||||
}
|
||||
|
||||
QDBusConnection FcitxQtWatcher::connection() const {
|
||||
Q_D(const FcitxQtWatcher);
|
||||
return d->m_serviceWatcher.connection();
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::setWatchPortal(bool portal) {
|
||||
Q_D(FcitxQtWatcher);
|
||||
d->m_watchPortal = portal;
|
||||
}
|
||||
|
||||
bool FcitxQtWatcher::watchPortal() const {
|
||||
Q_D(const FcitxQtWatcher);
|
||||
return d->m_watchPortal;
|
||||
}
|
||||
|
||||
QString FcitxQtWatcher::serviceName() const {
|
||||
Q_D(const FcitxQtWatcher);
|
||||
if (d->m_mainPresent) {
|
||||
return FCITX_MAIN_SERVICE_NAME;
|
||||
}
|
||||
if (d->m_portalPresent) {
|
||||
return FCITX_PORTAL_SERVICE_NAME;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::setAvailability(bool availability) {
|
||||
Q_D(FcitxQtWatcher);
|
||||
if (d->m_availability != availability) {
|
||||
d->m_availability = availability;
|
||||
emit availibilityChanged(d->m_availability);
|
||||
}
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::watch() {
|
||||
Q_D(FcitxQtWatcher);
|
||||
if (d->m_watched) {
|
||||
return;
|
||||
}
|
||||
|
||||
connect(&d->m_serviceWatcher,
|
||||
SIGNAL(serviceOwnerChanged(QString, QString, QString)), this,
|
||||
SLOT(imChanged(QString, QString, QString)));
|
||||
d->m_serviceWatcher.addWatchedService(FCITX_MAIN_SERVICE_NAME);
|
||||
if (d->m_watchPortal) {
|
||||
d->m_serviceWatcher.addWatchedService(FCITX_PORTAL_SERVICE_NAME);
|
||||
}
|
||||
|
||||
if (QDBusConnection::sessionBus().interface()->isServiceRegistered(
|
||||
FCITX_MAIN_SERVICE_NAME)) {
|
||||
d->m_mainPresent = true;
|
||||
}
|
||||
if (d->m_watchPortal &&
|
||||
QDBusConnection::sessionBus().interface()->isServiceRegistered(
|
||||
FCITX_PORTAL_SERVICE_NAME)) {
|
||||
d->m_portalPresent = true;
|
||||
}
|
||||
|
||||
updateAvailbility();
|
||||
|
||||
d->m_watched = true;
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::unwatch() {
|
||||
Q_D(FcitxQtWatcher);
|
||||
if (!d->m_watched) {
|
||||
return;
|
||||
}
|
||||
disconnect(&d->m_serviceWatcher,
|
||||
SIGNAL(serviceOwnerChanged(QString, QString, QString)), this,
|
||||
SLOT(imChanged(QString, QString, QString)));
|
||||
}
|
||||
|
||||
bool FcitxQtWatcher::isWatching() const {
|
||||
Q_D(const FcitxQtWatcher);
|
||||
return d->m_watched;
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::imChanged(const QString &service, const QString &,
|
||||
const QString &newOwner) {
|
||||
Q_D(FcitxQtWatcher);
|
||||
if (service == FCITX_MAIN_SERVICE_NAME) {
|
||||
if (!newOwner.isEmpty()) {
|
||||
d->m_mainPresent = true;
|
||||
} else {
|
||||
d->m_mainPresent = false;
|
||||
}
|
||||
} else if (service == FCITX_PORTAL_SERVICE_NAME) {
|
||||
if (!newOwner.isEmpty()) {
|
||||
d->m_portalPresent = true;
|
||||
} else {
|
||||
d->m_portalPresent = false;
|
||||
}
|
||||
}
|
||||
|
||||
updateAvailbility();
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::updateAvailbility() {
|
||||
Q_D(FcitxQtWatcher);
|
||||
setAvailability(d->m_mainPresent || d->m_portalPresent);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (C) 2017~2017 by CSSlayer
|
||||
* wengxt@gmail.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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DBUSADDONS_FCITXQTWATCHER_H_
|
||||
#define _DBUSADDONS_FCITXQTWATCHER_H_
|
||||
|
||||
#include "fcitx5qt4dbusaddons_export.h"
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QObject>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class FcitxQtWatcherPrivate;
|
||||
|
||||
class FCITX5QT4DBUSADDONS_EXPORT FcitxQtWatcher : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FcitxQtWatcher(QObject *parent = nullptr);
|
||||
explicit FcitxQtWatcher(const QDBusConnection &connection,
|
||||
QObject *parent = nullptr);
|
||||
~FcitxQtWatcher();
|
||||
void watch();
|
||||
void unwatch();
|
||||
void setConnection(const QDBusConnection &connection);
|
||||
QDBusConnection connection() const;
|
||||
void setWatchPortal(bool portal);
|
||||
bool watchPortal() const;
|
||||
bool isWatching() const;
|
||||
bool availability() const;
|
||||
|
||||
QString serviceName() const;
|
||||
|
||||
signals:
|
||||
void availibilityChanged(bool);
|
||||
|
||||
private slots:
|
||||
void imChanged(const QString &service, const QString &oldOwner,
|
||||
const QString &newOwner);
|
||||
|
||||
private:
|
||||
void setAvailability(bool availability);
|
||||
void updateAvailbility();
|
||||
|
||||
FcitxQtWatcherPrivate *const d_ptr;
|
||||
Q_DECLARE_PRIVATE(FcitxQtWatcher);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _DBUSADDONS_FCITXQTWATCHER_H_
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2017~2017 by CSSlayer
|
||||
* wengxt@gmail.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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DBUSADDONS_FCITXQTWATCHER_P_H_
|
||||
#define _DBUSADDONS_FCITXQTWATCHER_P_H_
|
||||
|
||||
#include "fcitxqtwatcher.h"
|
||||
#include <QDBusServiceWatcher>
|
||||
|
||||
#define FCITX_MAIN_SERVICE_NAME "org.fcitx.Fcitx5"
|
||||
#define FCITX_PORTAL_SERVICE_NAME "org.freedesktop.portal.Fcitx"
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class FcitxQtWatcherPrivate {
|
||||
public:
|
||||
FcitxQtWatcherPrivate(FcitxQtWatcher *q) : m_serviceWatcher(q) {}
|
||||
|
||||
QDBusServiceWatcher m_serviceWatcher;
|
||||
bool m_watchPortal = false;
|
||||
bool m_availability = false;
|
||||
bool m_mainPresent = false;
|
||||
bool m_portalPresent = false;
|
||||
bool m_watched = false;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _DBUSADDONS_FCITXQTWATCHER_P_H_
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
qdbusxml2cpp -N -p fcitxqtinputcontextproxy -c FcitxQtInputContextProxy interfaces/org.fcitx.Fcitx.InputContext1.xml -i fcitxqtdbustypes.h -i fcitx5qt4dbusaddons_export.h
|
||||
qdbusxml2cpp -N -p fcitxqtinputcontextproxyimpl -c FcitxQtInputContextProxyImpl interfaces/org.fcitx.Fcitx.InputContext1.xml -i fcitxqtdbustypes.h -i fcitx5qt4dbusaddons_export.h
|
||||
qdbusxml2cpp -N -p fcitxqtinputmethodproxy -c FcitxQtInputMethodProxy interfaces/org.fcitx.Fcitx.InputMethod1.xml -i fcitxqtdbustypes.h -i fcitx5qt4dbusaddons_export.h
|
||||
qdbusxml2cpp -N -p fcitxqtcontrollerproxy -c FcitxQtControllerProxy interfaces/org.fcitx.Fcitx.Controller1.xml -i fcitxqtdbustypes.h -i fcitx5qt4dbusaddons_export.h
|
||||
|
|
|
@ -19,9 +19,11 @@
|
|||
|
||||
#include <QApplication>
|
||||
#include <QDBusConnection>
|
||||
#include <QDateTime>
|
||||
#include <QKeyEvent>
|
||||
#include <QPalette>
|
||||
#include <QTextCharFormat>
|
||||
#include <QTextCodec>
|
||||
#include <QWidget>
|
||||
#include <QX11Info>
|
||||
|
||||
|
@ -31,9 +33,8 @@
|
|||
|
||||
#include "qtkey.h"
|
||||
|
||||
#include "fcitxqtconnection.h"
|
||||
#include "fcitxqtinputcontextproxy.h"
|
||||
#include "fcitxqtinputmethodproxy.h"
|
||||
#include "fcitxqtwatcher.h"
|
||||
#include "qfcitxinputcontext.h"
|
||||
|
||||
#include <fcitx-utils/key.h>
|
||||
|
@ -118,7 +119,7 @@ struct xkb_context *_xkb_context_new_helper() {
|
|||
}
|
||||
|
||||
QFcitxInputContext::QFcitxInputContext()
|
||||
: m_connection(new FcitxQtConnection(this)), m_improxy(nullptr),
|
||||
: m_watcher(new FcitxQtWatcher(QDBusConnection::sessionBus(), this)),
|
||||
m_cursorPos(0), m_useSurroundingText(false),
|
||||
m_syncMode(get_boolean_env("FCITX_QT_USE_SYNC", false)), m_destroy(false),
|
||||
m_xkbContext(_xkb_context_new_helper()),
|
||||
|
@ -132,44 +133,20 @@ QFcitxInputContext::QFcitxInputContext()
|
|||
: 0) {
|
||||
FcitxQtFormattedPreedit::registerMetaType();
|
||||
FcitxQtInputContextArgument::registerMetaType();
|
||||
|
||||
connect(m_connection, SIGNAL(connected()), this, SLOT(connected()));
|
||||
connect(m_connection, SIGNAL(disconnected()), this, SLOT(cleanUp()));
|
||||
|
||||
m_connection->startConnection();
|
||||
m_watcher->setWatchPortal(true);
|
||||
m_watcher->watch();
|
||||
}
|
||||
|
||||
QFcitxInputContext::~QFcitxInputContext() {
|
||||
m_destroy = true;
|
||||
m_watcher->unwatch();
|
||||
cleanUp();
|
||||
}
|
||||
|
||||
void QFcitxInputContext::connected() {
|
||||
if (!m_connection->isConnected())
|
||||
return;
|
||||
|
||||
// qDebug() << "create Input Context" << m_connection->name();
|
||||
if (m_improxy) {
|
||||
delete m_improxy;
|
||||
m_improxy = nullptr;
|
||||
}
|
||||
m_improxy = new FcitxQtInputMethodProxy(m_connection->serviceName(),
|
||||
QLatin1String("/inputmethod"),
|
||||
*m_connection->connection(), this);
|
||||
|
||||
QWidget *w = qApp->focusWidget();
|
||||
if (w)
|
||||
createICData(w);
|
||||
delete m_watcher;
|
||||
}
|
||||
|
||||
void QFcitxInputContext::cleanUp() {
|
||||
m_icMap.clear();
|
||||
|
||||
if (m_improxy) {
|
||||
delete m_improxy;
|
||||
m_improxy = nullptr;
|
||||
}
|
||||
|
||||
if (!m_destroy) {
|
||||
commitPreedit();
|
||||
}
|
||||
|
@ -183,8 +160,7 @@ void QFcitxInputContext::mouseHandler(int cursorPosition, QMouseEvent *event) {
|
|||
}
|
||||
}
|
||||
|
||||
void QFcitxInputContext::commitPreedit() {
|
||||
QWidget *input = qApp->focusWidget();
|
||||
void QFcitxInputContext::commitPreedit(QPointer<QWidget> input) {
|
||||
if (!input)
|
||||
return;
|
||||
if (m_commitPreedit.length() <= 0)
|
||||
|
@ -207,9 +183,9 @@ bool checkUtf8(const QByteArray &byteArray) {
|
|||
|
||||
void QFcitxInputContext::reset() {
|
||||
commitPreedit();
|
||||
FcitxQtInputContextProxy *proxy = validIC();
|
||||
if (proxy)
|
||||
proxy->Reset();
|
||||
if (FcitxQtInputContextProxy *proxy = validIC()) {
|
||||
proxy->reset();
|
||||
}
|
||||
if (m_xkbComposeState) {
|
||||
xkb_compose_state_reset(m_xkbComposeState.data());
|
||||
}
|
||||
|
@ -221,7 +197,8 @@ void QFcitxInputContext::update() {
|
|||
if (!proxy)
|
||||
return;
|
||||
|
||||
auto &data = m_icMap[window];
|
||||
FcitxQtICData &data = *static_cast<FcitxQtICData *>(
|
||||
proxy->property("icData").value<void *>());
|
||||
|
||||
QWidget *input = qApp->focusWidget();
|
||||
if (!input)
|
||||
|
@ -283,11 +260,11 @@ void QFcitxInputContext::update() {
|
|||
anchor = tempUCS4.size();
|
||||
if (data.surroundingText != text) {
|
||||
data.surroundingText = text;
|
||||
proxy->SetSurroundingText(text, cursor, anchor);
|
||||
proxy->setSurroundingText(text, cursor, anchor);
|
||||
} else {
|
||||
if (data.surroundingAnchor != anchor ||
|
||||
data.surroundingCursor != cursor)
|
||||
proxy->SetSurroundingTextPosition(cursor, anchor);
|
||||
proxy->setSurroundingTextPosition(cursor, anchor);
|
||||
}
|
||||
data.surroundingCursor = cursor;
|
||||
data.surroundingAnchor = anchor;
|
||||
|
@ -307,7 +284,7 @@ void QFcitxInputContext::setFocusWidget(QWidget *object) {
|
|||
Q_UNUSED(object);
|
||||
FcitxQtInputContextProxy *proxy = validICByWindow(m_lastWindow);
|
||||
if (proxy) {
|
||||
proxy->FocusOut();
|
||||
proxy->focusOut();
|
||||
}
|
||||
|
||||
QWidget *window = qApp->focusWidget();
|
||||
|
@ -317,7 +294,7 @@ void QFcitxInputContext::setFocusWidget(QWidget *object) {
|
|||
}
|
||||
proxy = validICByWindow(window);
|
||||
if (proxy)
|
||||
proxy->FocusIn();
|
||||
proxy->focusIn();
|
||||
else {
|
||||
createICData(window);
|
||||
}
|
||||
|
@ -344,7 +321,8 @@ void QFcitxInputContext::cursorRectChanged() {
|
|||
if (!proxy)
|
||||
return;
|
||||
|
||||
auto &data = m_icMap[inputWindow];
|
||||
FcitxQtICData &data = *static_cast<FcitxQtICData *>(
|
||||
proxy->property("icData").value<void *>());
|
||||
|
||||
QRect r = inputWindow->inputMethodQuery(Qt::ImMicroFocus).toRect();
|
||||
|
||||
|
@ -353,107 +331,49 @@ void QFcitxInputContext::cursorRectChanged() {
|
|||
|
||||
if (data.rect != newRect) {
|
||||
data.rect = newRect;
|
||||
proxy->SetCursorRect(newRect.x(), newRect.y(), newRect.width(),
|
||||
proxy->setCursorRect(newRect.x(), newRect.y(), newRect.width(),
|
||||
newRect.height());
|
||||
}
|
||||
}
|
||||
|
||||
void QFcitxInputContext::createInputContext(QWidget *w) {
|
||||
if (!m_connection->isConnected())
|
||||
void QFcitxInputContext::createInputContextFinished(const QByteArray &uuid) {
|
||||
auto proxy = qobject_cast<FcitxQtInputContextProxy *>(sender());
|
||||
if (!proxy) {
|
||||
return;
|
||||
|
||||
// qDebug() << "create Input Context" << m_connection->connection()->name();
|
||||
|
||||
if (!m_improxy) {
|
||||
m_improxy = new FcitxQtInputMethodProxy(
|
||||
m_connection->serviceName(), QLatin1String("/inputmethod"),
|
||||
*m_connection->connection(), this);
|
||||
}
|
||||
|
||||
if (!m_improxy->isValid())
|
||||
return;
|
||||
|
||||
QFileInfo info(QCoreApplication::applicationFilePath());
|
||||
FcitxQtInputContextArgumentList args;
|
||||
args << FcitxQtInputContextArgument("program", info.fileName());
|
||||
args << FcitxQtInputContextArgument("display", "x11:");
|
||||
auto result = m_improxy->CreateInputContext(args);
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result);
|
||||
watcher->setProperty("wid", qVariantFromValue(static_cast<void *>(w)));
|
||||
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)), this,
|
||||
SLOT(createInputContextFinished(QDBusPendingCallWatcher *)));
|
||||
}
|
||||
|
||||
void QFcitxInputContext::createInputContextFinished(
|
||||
QDBusPendingCallWatcher *watcher) {
|
||||
auto w =
|
||||
reinterpret_cast<QWidget *>(watcher->property("wid").value<void *>());
|
||||
auto iter = m_icMap.find(w);
|
||||
if (iter == m_icMap.end()) {
|
||||
return;
|
||||
reinterpret_cast<QWidget *>(proxy->property("wid").value<void *>());
|
||||
FcitxQtICData *data =
|
||||
static_cast<FcitxQtICData *>(proxy->property("icData").value<void *>());
|
||||
data->rect = QRect();
|
||||
|
||||
if (proxy->isValid()) {
|
||||
QWidget *window = qApp->focusWidget();
|
||||
if (window && window == w) {
|
||||
proxy->focusIn();
|
||||
cursorRectChanged();
|
||||
}
|
||||
setFocusGroupForX11(uuid);
|
||||
}
|
||||
|
||||
auto &data = iter->second;
|
||||
fcitx::CapabilityFlags flag;
|
||||
flag |= fcitx::CapabilityFlag::Preedit;
|
||||
flag |= fcitx::CapabilityFlag::FormattedPreedit;
|
||||
flag |= fcitx::CapabilityFlag::ClientUnfocusCommit;
|
||||
flag |= fcitx::CapabilityFlag::GetIMInfoOnFocus;
|
||||
m_useSurroundingText =
|
||||
get_boolean_env("FCITX_QT_ENABLE_SURROUNDING_TEXT", true);
|
||||
if (m_useSurroundingText)
|
||||
flag |= fcitx::CapabilityFlag::SurroundingText;
|
||||
|
||||
QDBusPendingReply<QDBusObjectPath, QByteArray> result = *watcher;
|
||||
|
||||
do {
|
||||
if (result.isError()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!m_connection->isConnected())
|
||||
break;
|
||||
|
||||
auto objectPath = result.argumentAt<0>();
|
||||
if (data.proxy) {
|
||||
delete data.proxy;
|
||||
}
|
||||
data.proxy = new FcitxQtInputContextProxy(
|
||||
m_connection->serviceName(), objectPath.path(),
|
||||
*m_connection->connection(), this);
|
||||
data.proxy->setProperty("icData",
|
||||
qVariantFromValue(static_cast<void *>(&data)));
|
||||
connect(data.proxy, SIGNAL(CommitString(QString)), this,
|
||||
SLOT(commitString(QString)));
|
||||
connect(data.proxy, SIGNAL(ForwardKey(uint, uint, bool)), this,
|
||||
SLOT(forwardKey(uint, uint, bool)));
|
||||
connect(data.proxy, SIGNAL(UpdateFormattedPreedit(
|
||||
FcitxQtFormattedPreeditList, int)),
|
||||
this,
|
||||
SLOT(updateFormattedPreedit(FcitxQtFormattedPreeditList, int)));
|
||||
connect(data.proxy, SIGNAL(DeleteSurroundingText(int, uint)), this,
|
||||
SLOT(deleteSurroundingText(int, uint)));
|
||||
|
||||
if (data.proxy->isValid()) {
|
||||
QWidget *window = qApp->focusWidget();
|
||||
if (window && window == w)
|
||||
data.proxy->FocusIn();
|
||||
}
|
||||
|
||||
setFocusGroupForX11(result.argumentAt<1>());
|
||||
|
||||
fcitx::CapabilityFlags flag;
|
||||
flag |= fcitx::CapabilityFlag::Preedit;
|
||||
flag |= fcitx::CapabilityFlag::FormattedPreedit;
|
||||
flag |= fcitx::CapabilityFlag::ClientUnfocusCommit;
|
||||
flag |= fcitx::CapabilityFlag::GetIMInfoOnFocus;
|
||||
m_useSurroundingText =
|
||||
get_boolean_env("FCITX_QT_ENABLE_SURROUNDING_TEXT", true);
|
||||
if (m_useSurroundingText)
|
||||
flag |= fcitx::CapabilityFlag::SurroundingText;
|
||||
|
||||
addCapability(data, flag, true);
|
||||
} while (0);
|
||||
delete watcher;
|
||||
addCapability(*data, flag, true);
|
||||
}
|
||||
|
||||
void QFcitxInputContext::updateCapability(const FcitxQtICData &data) {
|
||||
if (!data.proxy || !data.proxy->isValid())
|
||||
return;
|
||||
|
||||
QDBusPendingReply<void> result =
|
||||
data.proxy->SetCapability((uint)data.capability);
|
||||
QDBusPendingReply<void> result = data.proxy->setCapability(data.capability);
|
||||
}
|
||||
|
||||
void QFcitxInputContext::commitString(const QString &str) {
|
||||
|
@ -604,12 +524,30 @@ void QFcitxInputContext::forwardKey(uint keyval, uint state, bool type) {
|
|||
void QFcitxInputContext::createICData(QWidget *w) {
|
||||
auto iter = m_icMap.find(w);
|
||||
if (iter == m_icMap.end()) {
|
||||
m_icMap.emplace(std::piecewise_construct, std::forward_as_tuple(w),
|
||||
std::forward_as_tuple());
|
||||
connect(w, SIGNAL(destroyed(QObject *)), this,
|
||||
SLOT(windowDestroyed(QObject *)));
|
||||
auto result =
|
||||
m_icMap.emplace(std::piecewise_construct, std::forward_as_tuple(w),
|
||||
std::forward_as_tuple(m_watcher));
|
||||
iter = result.first;
|
||||
auto &data = iter->second;
|
||||
|
||||
data.proxy->setDisplay("x11:");
|
||||
data.proxy->setProperty("wid",
|
||||
qVariantFromValue(static_cast<void *>(w)));
|
||||
data.proxy->setProperty("icData",
|
||||
qVariantFromValue(static_cast<void *>(&data)));
|
||||
connect(data.proxy, SIGNAL(inputContextCreated(QByteArray)), this,
|
||||
SLOT(createInputContextFinished(QByteArray)));
|
||||
connect(data.proxy, SIGNAL(commitString(QString)), this,
|
||||
SLOT(commitString(QString)));
|
||||
connect(data.proxy, SIGNAL(forwardKey(uint, uint, bool)), this,
|
||||
SLOT(forwardKey(uint, uint, bool)));
|
||||
connect(data.proxy, SIGNAL(updateFormattedPreedit(
|
||||
FcitxQtFormattedPreeditList, int)),
|
||||
this,
|
||||
SLOT(updateFormattedPreedit(FcitxQtFormattedPreeditList, int)));
|
||||
connect(data.proxy, SIGNAL(deleteSurroundingText(int, uint)), this,
|
||||
SLOT(deleteSurroundingText(int, uint)));
|
||||
}
|
||||
createInputContext(w);
|
||||
}
|
||||
|
||||
QKeyEvent *QFcitxInputContext::createKeyEvent(uint keyval, uint _state,
|
||||
|
@ -644,7 +582,7 @@ QKeyEvent *QFcitxInputContext::createKeyEvent(uint keyval, uint _state,
|
|||
|
||||
QKeyEvent *keyevent =
|
||||
new QKeyEvent(isRelease ? (QEvent::KeyRelease) : (QEvent::KeyPress),
|
||||
key, qstate, QString(), false, count);
|
||||
key, qstate, text, false, count);
|
||||
|
||||
return keyevent;
|
||||
}
|
||||
|
@ -682,17 +620,16 @@ bool QFcitxInputContext::filterEvent(const QEvent *event) {
|
|||
}
|
||||
}
|
||||
|
||||
proxy->FocusIn();
|
||||
proxy->focusIn();
|
||||
|
||||
auto reply =
|
||||
proxy->ProcessKeyEvent(keyval, keycode, state, isRelease,
|
||||
proxy->processKeyEvent(keyval, keycode, state, isRelease,
|
||||
QDateTime::currentDateTime().toTime_t());
|
||||
|
||||
if (Q_UNLIKELY(m_syncMode)) {
|
||||
reply.waitForFinished();
|
||||
|
||||
if (!m_connection->isConnected() || !reply.isFinished() ||
|
||||
reply.isError() || !reply.value()) {
|
||||
if (reply.isError() || !reply.value()) {
|
||||
if (filterEventFallback(keyval, keycode, state, isRelease)) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -704,7 +641,7 @@ bool QFcitxInputContext::filterEvent(const QEvent *event) {
|
|||
}
|
||||
} else {
|
||||
ProcessKeyWatcher *watcher = new ProcessKeyWatcher(
|
||||
*keyEvent, qApp->focusWidget(), reply, this);
|
||||
*keyEvent, qApp->focusWidget(), reply, proxy);
|
||||
connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher *)), this,
|
||||
SLOT(processKeyEventFinished(QDBusPendingCallWatcher *)));
|
||||
return true;
|
||||
|
@ -721,6 +658,7 @@ void QFcitxInputContext::processKeyEventFinished(QDBusPendingCallWatcher *w) {
|
|||
QWidget *window = watcher->window();
|
||||
// if window is already destroyed, we can only throw this event away.
|
||||
if (!window) {
|
||||
delete watcher;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -740,7 +678,7 @@ void QFcitxInputContext::processKeyEventFinished(QDBusPendingCallWatcher *w) {
|
|||
filtered = true;
|
||||
}
|
||||
|
||||
if (!result.isError()) {
|
||||
if (!watcher->isError()) {
|
||||
update();
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#define QFCITXINPUTCONTEXT_H
|
||||
|
||||
#include "fcitxqtinputcontextproxy.h"
|
||||
#include "fcitxqtwatcher.h"
|
||||
#include <QApplication>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QInputContext>
|
||||
|
@ -37,17 +39,11 @@ namespace fcitx {
|
|||
class FcitxQtConnection;
|
||||
|
||||
struct FcitxQtICData {
|
||||
FcitxQtICData()
|
||||
: proxy(nullptr), surroundingAnchor(-1), surroundingCursor(-1) {}
|
||||
FcitxQtICData(FcitxQtWatcher *watcher)
|
||||
: proxy(new FcitxQtInputContextProxy(watcher, watcher)),
|
||||
surroundingAnchor(-1), surroundingCursor(-1) {}
|
||||
FcitxQtICData(const FcitxQtICData &that) = delete;
|
||||
~FcitxQtICData() {
|
||||
if (proxy) {
|
||||
if (proxy->isValid()) {
|
||||
proxy->DestroyIC();
|
||||
}
|
||||
delete proxy;
|
||||
}
|
||||
}
|
||||
~FcitxQtICData() { delete proxy; }
|
||||
fcitx::CapabilityFlags capability;
|
||||
FcitxQtInputContextProxy *proxy;
|
||||
QRect rect;
|
||||
|
@ -128,13 +124,11 @@ public Q_SLOTS:
|
|||
int cursorPos);
|
||||
void deleteSurroundingText(int offset, uint nchar);
|
||||
void forwardKey(uint keyval, uint state, bool type);
|
||||
void createInputContextFinished(QDBusPendingCallWatcher *watcher);
|
||||
void connected();
|
||||
void createInputContextFinished(const QByteArray &uuid);
|
||||
void cleanUp();
|
||||
void windowDestroyed(QObject *object);
|
||||
|
||||
private:
|
||||
void createInputContext(QWidget *w);
|
||||
bool processCompose(uint keyval, uint state, bool isRelaese);
|
||||
QKeyEvent *createKeyEvent(uint keyval, uint state, bool isRelaese);
|
||||
|
||||
|
@ -158,15 +152,14 @@ private:
|
|||
}
|
||||
|
||||
void updateCapability(const FcitxQtICData &data);
|
||||
void commitPreedit();
|
||||
void commitPreedit(QPointer<QWidget> input = qApp->focusWidget());
|
||||
void createICData(QWidget *w);
|
||||
FcitxQtInputContextProxy *validIC();
|
||||
FcitxQtInputContextProxy *validICByWindow(QWidget *window);
|
||||
bool filterEventFallback(uint keyval, uint keycode, uint state,
|
||||
bool isRelaese);
|
||||
|
||||
FcitxQtConnection *m_connection;
|
||||
FcitxQtInputMethodProxy *m_improxy;
|
||||
FcitxQtWatcher *m_watcher;
|
||||
QString m_preedit;
|
||||
QString m_commitPreedit;
|
||||
FcitxQtFormattedPreeditList m_preeditList;
|
||||
|
@ -184,7 +177,6 @@ private:
|
|||
m_xkbComposeTable;
|
||||
QScopedPointer<struct xkb_compose_state, XkbComposeStateDeleter>
|
||||
m_xkbComposeState;
|
||||
QLocale m_locale;
|
||||
private slots:
|
||||
void processKeyEventFinished(QDBusPendingCallWatcher *);
|
||||
};
|
||||
|
|
|
@ -22,15 +22,16 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/fcitx5qt5dbusaddons_version.h
|
|||
DESTINATION ${Fcitx5Qt5_INCLUDE_INSTALL_DIR} COMPONENT Devel )
|
||||
|
||||
set(dbusaddons_SOURCES
|
||||
fcitxqtconnection.cpp
|
||||
fcitxqtwatcher.cpp
|
||||
fcitxqtdbustypes.cpp
|
||||
fcitxqtinputcontextproxyimpl.cpp
|
||||
fcitxqtinputcontextproxy.cpp
|
||||
fcitxqtinputmethodproxy.cpp
|
||||
fcitxqtcontrollerproxy.cpp
|
||||
)
|
||||
|
||||
set(dbusaddons_HEADERS
|
||||
fcitxqtconnection.h
|
||||
fcitxqtwatcher.h
|
||||
fcitxqtdbustypes.h
|
||||
fcitxqtinputcontextproxy.h
|
||||
fcitxqtinputmethodproxy.h
|
||||
|
|
|
@ -1,187 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2012~2017 by CSSlayer
|
||||
* wengxt@gmail.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 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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "fcitxqtconnection_p.h"
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusReply>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QTimer>
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
FcitxQtConnection::FcitxQtConnection(QObject *parent)
|
||||
: QObject(parent), d_ptr(new FcitxQtConnectionPrivate(this)) {}
|
||||
|
||||
void FcitxQtConnection::startConnection() {
|
||||
Q_D(FcitxQtConnection);
|
||||
if (!d->m_initialized) {
|
||||
d->initialize();
|
||||
d->createConnection();
|
||||
}
|
||||
}
|
||||
|
||||
void FcitxQtConnection::endConnection() {
|
||||
Q_D(FcitxQtConnection);
|
||||
d->cleanUp();
|
||||
d->finalize();
|
||||
d->m_connectedOnce = false;
|
||||
}
|
||||
|
||||
bool FcitxQtConnection::autoReconnect() {
|
||||
Q_D(FcitxQtConnection);
|
||||
return d->m_autoReconnect;
|
||||
}
|
||||
|
||||
void FcitxQtConnection::setAutoReconnect(bool a) {
|
||||
Q_D(FcitxQtConnection);
|
||||
d->m_autoReconnect = a;
|
||||
}
|
||||
|
||||
QDBusConnection *FcitxQtConnection::connection() {
|
||||
Q_D(FcitxQtConnection);
|
||||
return d->m_connection;
|
||||
}
|
||||
|
||||
const QString &FcitxQtConnection::serviceName() {
|
||||
Q_D(FcitxQtConnection);
|
||||
return d->m_serviceName;
|
||||
}
|
||||
|
||||
bool FcitxQtConnection::isConnected() {
|
||||
Q_D(FcitxQtConnection);
|
||||
return d->isConnected();
|
||||
}
|
||||
|
||||
FcitxQtConnection::~FcitxQtConnection() {}
|
||||
|
||||
FcitxQtConnectionPrivate::FcitxQtConnectionPrivate(FcitxQtConnection *conn)
|
||||
: QObject(conn), q_ptr(conn), m_serviceName("org.fcitx.Fcitx5"),
|
||||
m_connection(nullptr), m_serviceWatcher(new QDBusServiceWatcher(this)),
|
||||
m_autoReconnect(true), m_connectedOnce(false), m_initialized(false) {}
|
||||
|
||||
FcitxQtConnectionPrivate::~FcitxQtConnectionPrivate() {
|
||||
if (m_connection)
|
||||
delete m_connection;
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::initialize() {
|
||||
m_serviceWatcher->setConnection(QDBusConnection::sessionBus());
|
||||
m_serviceWatcher->addWatchedService(m_serviceName);
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::finalize() {
|
||||
m_serviceWatcher->removeWatchedService(m_serviceName);
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::createConnection() {
|
||||
if (m_connectedOnce && !m_autoReconnect) {
|
||||
return;
|
||||
}
|
||||
|
||||
disconnect(m_serviceWatcher, &QDBusServiceWatcher::serviceOwnerChanged,
|
||||
this, &FcitxQtConnectionPrivate::imChanged);
|
||||
if (!m_connection) {
|
||||
QDBusConnection *connection =
|
||||
new QDBusConnection(QDBusConnection::sessionBus());
|
||||
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceOwnerChanged,
|
||||
this, &FcitxQtConnectionPrivate::imChanged);
|
||||
QDBusReply<bool> registered =
|
||||
connection->interface()->isServiceRegistered(m_serviceName);
|
||||
if (!registered.isValid() || !registered.value()) {
|
||||
delete connection;
|
||||
} else {
|
||||
m_connection = connection;
|
||||
}
|
||||
}
|
||||
|
||||
Q_Q(FcitxQtConnection);
|
||||
if (m_connection) {
|
||||
|
||||
m_connection->connect("org.freedesktop.DBus.Local",
|
||||
"/org/freedesktop/DBus/Local",
|
||||
"org.freedesktop.DBus.Local", "Disconnected",
|
||||
this, SLOT(dbusDisconnected()));
|
||||
m_connectedOnce = true;
|
||||
emit q->connected();
|
||||
}
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::dbusDisconnected() {
|
||||
cleanUp();
|
||||
|
||||
createConnection();
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::imChanged(const QString &service,
|
||||
const QString &oldowner,
|
||||
const QString &newowner) {
|
||||
if (service == m_serviceName) {
|
||||
/* old die */
|
||||
if (oldowner.length() > 0 || newowner.length() > 0)
|
||||
cleanUp();
|
||||
|
||||
/* new rise */
|
||||
if (newowner.length() > 0) {
|
||||
QTimer::singleShot(100, this,
|
||||
&FcitxQtConnectionPrivate::newServiceAppear);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::cleanUp() {
|
||||
Q_Q(FcitxQtConnection);
|
||||
bool doemit = false;
|
||||
if (m_connection) {
|
||||
delete m_connection;
|
||||
m_connection = nullptr;
|
||||
doemit = true;
|
||||
}
|
||||
|
||||
if (!m_autoReconnect && m_connectedOnce)
|
||||
finalize();
|
||||
|
||||
/* we want m_connection and finalize being called before the signal
|
||||
* thus isConnected will return false in slot
|
||||
* and startConnection can be called in slot
|
||||
*/
|
||||
if (doemit)
|
||||
emit q->disconnected();
|
||||
}
|
||||
|
||||
bool FcitxQtConnectionPrivate::isConnected() {
|
||||
return m_connection && m_connection->isConnected();
|
||||
}
|
||||
|
||||
void FcitxQtConnectionPrivate::newServiceAppear() {
|
||||
if (!isConnected()) {
|
||||
cleanUp();
|
||||
|
||||
createConnection();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2012~2017 by CSSlayer
|
||||
* wengxt@gmail.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 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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DBUSADDONS_FCITXQTCONNECTION_H_
|
||||
#define _DBUSADDONS_FCITXQTCONNECTION_H_
|
||||
|
||||
#include "fcitx5qt5dbusaddons_export.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QDBusConnection;
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class FcitxQtConnectionPrivate;
|
||||
|
||||
/**
|
||||
* dbus connection to fcitx
|
||||
**/
|
||||
class FCITX5QT5DBUSADDONS_EXPORT FcitxQtConnection : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool autoReconnect READ autoReconnect WRITE setAutoReconnect)
|
||||
Q_PROPERTY(bool connected READ isConnected)
|
||||
Q_PROPERTY(QDBusConnection *connection READ connection)
|
||||
Q_PROPERTY(QString serviceName READ serviceName)
|
||||
public:
|
||||
/**
|
||||
* create a new connection
|
||||
*
|
||||
* @param parent
|
||||
**/
|
||||
explicit FcitxQtConnection(QObject *parent = 0);
|
||||
|
||||
/**
|
||||
* destroy the connection
|
||||
**/
|
||||
virtual ~FcitxQtConnection();
|
||||
|
||||
/**
|
||||
* the connection will not start to work until you call this function
|
||||
* you may want to connect to the signal before you call this function
|
||||
**/
|
||||
void startConnection();
|
||||
void endConnection();
|
||||
/**
|
||||
* automatically reconnect if fcitx disappeared
|
||||
*
|
||||
* @param a ...
|
||||
* @return void
|
||||
**/
|
||||
void setAutoReconnect(bool a);
|
||||
|
||||
/**
|
||||
* check this connection is doing automatical reconnect or not
|
||||
*
|
||||
* default value is true
|
||||
**/
|
||||
bool autoReconnect();
|
||||
|
||||
/**
|
||||
* return the current dbus connection to fcitx, notice, the object return
|
||||
* by this function might be deteled if fcitx disappear, or might return 0
|
||||
* if fcitx is not running
|
||||
*
|
||||
* @return QDBusConnection*
|
||||
**/
|
||||
QDBusConnection *connection();
|
||||
/**
|
||||
* current fcitx dbus service name, can be used for create DBus proxy
|
||||
*
|
||||
* @return service name
|
||||
**/
|
||||
const QString &serviceName();
|
||||
/**
|
||||
* check its connected or not
|
||||
**/
|
||||
bool isConnected();
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* this signal will be emitted upon fcitx appears
|
||||
**/
|
||||
void connected();
|
||||
/**
|
||||
* this signal will be emitted upon fcitx disappears
|
||||
*
|
||||
* it will come with connected in pair
|
||||
**/
|
||||
void disconnected();
|
||||
|
||||
private:
|
||||
FcitxQtConnectionPrivate *const d_ptr;
|
||||
Q_DECLARE_PRIVATE(FcitxQtConnection);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _DBUSADDONS_FCITXQTCONNECTION_H_
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017~2017 by CSSlayer
|
||||
* wengxt@gmail.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 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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DBUSADDONS_FCITXQTCONNECTION_P_H_
|
||||
#define _DBUSADDONS_FCITXQTCONNECTION_P_H_
|
||||
|
||||
#include "fcitxqtconnection.h"
|
||||
|
||||
class QDBusConnection;
|
||||
class QDBusServiceWatcher;
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class FcitxQtConnectionPrivate : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FcitxQtConnectionPrivate(FcitxQtConnection *conn);
|
||||
virtual ~FcitxQtConnectionPrivate();
|
||||
FcitxQtConnection *const q_ptr;
|
||||
Q_DECLARE_PUBLIC(FcitxQtConnection);
|
||||
|
||||
private Q_SLOTS:
|
||||
void imChanged(const QString &service, const QString &oldowner,
|
||||
const QString &newowner);
|
||||
void dbusDisconnected();
|
||||
void cleanUp();
|
||||
void newServiceAppear();
|
||||
|
||||
private:
|
||||
bool isConnected();
|
||||
void createConnection();
|
||||
void initialize();
|
||||
void finalize();
|
||||
|
||||
QString m_serviceName;
|
||||
QDBusConnection *m_connection;
|
||||
QDBusServiceWatcher *m_serviceWatcher;
|
||||
QString m_socketFile;
|
||||
bool m_autoReconnect;
|
||||
bool m_connectedOnce;
|
||||
bool m_initialized;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _DBUSADDONS_FCITXQTCONNECTION_P_H_
|
|
@ -1,29 +1,106 @@
|
|||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was:
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
* Copyright (C) 2017~2017 by CSSlayer
|
||||
* wengxt@gmail.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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "fcitxqtinputcontextproxy.h"
|
||||
#include "fcitxqtinputcontextproxy_p.h"
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusMetaType>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QFileInfo>
|
||||
#include <QCoreApplication>
|
||||
#include <QTimer>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
/*
|
||||
* Implementation of interface class FcitxQtInputContextProxy
|
||||
*/
|
||||
|
||||
FcitxQtInputContextProxy::FcitxQtInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
|
||||
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
|
||||
FcitxQtInputContextProxy::FcitxQtInputContextProxy(FcitxQtWatcher *watcher, QObject *parent) : QObject(parent),
|
||||
d_ptr(new FcitxQtInputContextProxyPrivate(watcher, this))
|
||||
{
|
||||
}
|
||||
|
||||
FcitxQtInputContextProxy::~FcitxQtInputContextProxy()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void FcitxQtInputContextProxy::setDisplay(const QString& display)
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
d->m_display = display;
|
||||
}
|
||||
|
||||
const QString &FcitxQtInputContextProxy::display() const
|
||||
{
|
||||
Q_D(const FcitxQtInputContextProxy);
|
||||
return d->m_display;
|
||||
}
|
||||
|
||||
bool FcitxQtInputContextProxy::isValid() const
|
||||
{
|
||||
Q_D(const FcitxQtInputContextProxy);
|
||||
return d->isValid();
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::focusIn()
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->FocusIn();
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::focusOut()
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->FocusOut();
|
||||
}
|
||||
|
||||
QDBusPendingReply<bool> FcitxQtInputContextProxy::processKeyEvent(uint keyval, uint keycode, uint state, bool type, uint time)
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->ProcessKeyEvent(keyval, keycode, state, type, time);
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::reset()
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->Reset();
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::setCapability(qulonglong caps)
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->SetCapability(caps);
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::setCursorRect(int x, int y, int w, int h)
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->SetCursorRect(x, y, w, h);
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::setSurroundingText(const QString &text, uint cursor, uint anchor)
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->SetSurroundingText(text, cursor, anchor);
|
||||
}
|
||||
|
||||
QDBusPendingReply<> FcitxQtInputContextProxy::setSurroundingTextPosition(uint cursor, uint anchor)
|
||||
{
|
||||
Q_D(FcitxQtInputContextProxy);
|
||||
return d->m_icproxy->SetSurroundingTextPosition(cursor, anchor);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,112 +1,73 @@
|
|||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was:
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
* Copyright (C) 2017~2017 by CSSlayer
|
||||
* wengxt@gmail.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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DBUSADDONS_FCITXQTINPUTCONTEXTPROXY_H_
|
||||
#define _DBUSADDONS_FCITXQTINPUTCONTEXTPROXY_H_
|
||||
|
||||
#ifndef FCITXQTINPUTCONTEXTPROXY_H
|
||||
#define FCITXQTINPUTCONTEXTPROXY_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtDBus/QtDBus>
|
||||
#include "fcitxqtdbustypes.h"
|
||||
#include "fcitx5qt5dbusaddons_export.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusPendingReply>
|
||||
#include "fcitxqtdbustypes.h"
|
||||
|
||||
class QDBusPendingCallWatcher;
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
/*
|
||||
* Proxy class for interface org.fcitx.Fcitx.InputContext1
|
||||
*/
|
||||
class FCITX5QT5DBUSADDONS_EXPORT FcitxQtInputContextProxy: public QDBusAbstractInterface
|
||||
{
|
||||
class FcitxQtWatcher;
|
||||
class FcitxQtInputContextProxyPrivate;
|
||||
|
||||
class FCITX5QT5DBUSADDONS_EXPORT FcitxQtInputContextProxy : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static inline const char *staticInterfaceName()
|
||||
{ return "org.fcitx.Fcitx.InputContext1"; }
|
||||
|
||||
public:
|
||||
FcitxQtInputContextProxy(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0);
|
||||
|
||||
FcitxQtInputContextProxy(FcitxQtWatcher *watcher, QObject *parent);
|
||||
~FcitxQtInputContextProxy();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<> DestroyIC()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("DestroyIC"), argumentList);
|
||||
}
|
||||
bool isValid() const;
|
||||
void setDisplay(const QString &display);
|
||||
const QString &display() const;
|
||||
|
||||
inline QDBusPendingReply<> FocusIn()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("FocusIn"), argumentList);
|
||||
}
|
||||
public slots:
|
||||
QDBusPendingReply<> focusIn();
|
||||
QDBusPendingReply<> focusOut();
|
||||
QDBusPendingReply<bool> processKeyEvent(uint keyval, uint keycode, uint state, bool type, uint time);
|
||||
QDBusPendingReply<> reset();
|
||||
QDBusPendingReply<> setCapability(qulonglong caps);
|
||||
QDBusPendingReply<> setCursorRect(int x, int y, int w, int h);
|
||||
QDBusPendingReply<> setSurroundingText(const QString &text, uint cursor, uint anchor);
|
||||
QDBusPendingReply<> setSurroundingTextPosition(uint cursor, uint anchor);
|
||||
|
||||
inline QDBusPendingReply<> FocusOut()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("FocusOut"), argumentList);
|
||||
}
|
||||
signals:
|
||||
void commitString(const QString &str);
|
||||
void currentIM(const QString &name, const QString &uniqueName, const QString &langCode);
|
||||
void deleteSurroundingText(int offset, uint nchar);
|
||||
void forwardKey(uint keyval, uint state, bool isRelease);
|
||||
void updateFormattedPreedit(const FcitxQtFormattedPreeditList &str, int cursorpos);
|
||||
void inputContextCreated(const QByteArray &uuid);
|
||||
|
||||
inline QDBusPendingReply<bool> ProcessKeyEvent(uint keyval, uint keycode, uint state, bool type, uint time)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(keyval) << QVariant::fromValue(keycode) << QVariant::fromValue(state) << QVariant::fromValue(type) << QVariant::fromValue(time);
|
||||
return asyncCallWithArgumentList(QStringLiteral("ProcessKeyEvent"), argumentList);
|
||||
}
|
||||
private:
|
||||
|
||||
inline QDBusPendingReply<> Reset()
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("Reset"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetCapability(qulonglong caps)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(caps);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetCapability"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetCursorRect(int x, int y, int w, int h)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(x) << QVariant::fromValue(y) << QVariant::fromValue(w) << QVariant::fromValue(h);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetCursorRect"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetSurroundingText(const QString &text, uint cursor, uint anchor)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(text) << QVariant::fromValue(cursor) << QVariant::fromValue(anchor);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetSurroundingText"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetSurroundingTextPosition(uint cursor, uint anchor)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(cursor) << QVariant::fromValue(anchor);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetSurroundingTextPosition"), argumentList);
|
||||
}
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void CommitString(const QString &str);
|
||||
void CurrentIM(const QString &name, const QString &uniqueName, const QString &langCode);
|
||||
void DeleteSurroundingText(int offset, uint nchar);
|
||||
void ForwardKey(uint keyval, uint state, bool type);
|
||||
void UpdateFormattedPreedit(FcitxQtFormattedPreeditList str, int cursorpos);
|
||||
FcitxQtInputContextProxyPrivate *const d_ptr;
|
||||
Q_DECLARE_PRIVATE(FcitxQtInputContextProxy);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // _DBUSADDONS_FCITXQTINPUTCONTEXTPROXY_H_
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright (C) 2017~2017 by CSSlayer
|
||||
* wengxt@gmail.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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DBUSADDONS_FCITXQTINPUTCONTEXTPROXY_P_H_
|
||||
#define _DBUSADDONS_FCITXQTINPUTCONTEXTPROXY_P_H_
|
||||
|
||||
#include "fcitxqtinputcontextproxy.h"
|
||||
#include "fcitxqtinputcontextproxyimpl.h"
|
||||
#include "fcitxqtinputmethodproxy.h"
|
||||
#include "fcitxqtwatcher.h"
|
||||
#include <QDBusServiceWatcher>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class FcitxQtInputContextProxyPrivate {
|
||||
public:
|
||||
FcitxQtInputContextProxyPrivate(FcitxQtWatcher *watcher,
|
||||
FcitxQtInputContextProxy *q)
|
||||
: q_ptr(q), m_fcitxWatcher(watcher), m_watcher(q) {
|
||||
FcitxQtFormattedPreedit::registerMetaType();
|
||||
FcitxQtInputContextArgument::registerMetaType();
|
||||
QObject::connect(m_fcitxWatcher, &FcitxQtWatcher::availibilityChanged,
|
||||
q, [this]() { availibilityChanged(); });
|
||||
m_watcher.setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
|
||||
QObject::connect(&m_watcher, &QDBusServiceWatcher::serviceUnregistered,
|
||||
q, [this]() { availibilityChanged(); });
|
||||
availibilityChanged();
|
||||
}
|
||||
|
||||
~FcitxQtInputContextProxyPrivate() {
|
||||
if (isValid()) {
|
||||
m_icproxy->DestroyIC();
|
||||
}
|
||||
}
|
||||
|
||||
bool isValid() const { return (m_icproxy && m_icproxy->isValid()); }
|
||||
|
||||
void availibilityChanged() {
|
||||
QTimer::singleShot(100, q_ptr, [this]() { recheck(); });
|
||||
}
|
||||
|
||||
void recheck() {
|
||||
if (!isValid() && m_fcitxWatcher->availability()) {
|
||||
createInputContext();
|
||||
}
|
||||
if (!m_fcitxWatcher->availability()) {
|
||||
cleanUp();
|
||||
}
|
||||
}
|
||||
|
||||
void cleanUp() {
|
||||
auto services = m_watcher.watchedServices();
|
||||
for (const auto &service : services) {
|
||||
m_watcher.removeWatchedService(service);
|
||||
}
|
||||
|
||||
delete m_improxy;
|
||||
m_improxy = nullptr;
|
||||
delete m_icproxy;
|
||||
m_icproxy = nullptr;
|
||||
delete m_createInputContextWatcher;
|
||||
m_createInputContextWatcher = nullptr;
|
||||
}
|
||||
|
||||
void createInputContext() {
|
||||
Q_Q(FcitxQtInputContextProxy);
|
||||
if (!m_fcitxWatcher->availability()) {
|
||||
return;
|
||||
}
|
||||
|
||||
cleanUp();
|
||||
|
||||
auto service = m_fcitxWatcher->serviceName();
|
||||
auto connection = m_fcitxWatcher->connection();
|
||||
|
||||
auto owner = connection.interface()->serviceOwner(service);
|
||||
if (!owner.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_watcher.setConnection(connection);
|
||||
m_watcher.setWatchedServices(QStringList() << owner);
|
||||
// Avoid race, query again.
|
||||
if (!connection.interface()->isServiceRegistered(owner)) {
|
||||
cleanUp();
|
||||
return;
|
||||
}
|
||||
|
||||
QFileInfo info(QCoreApplication::applicationFilePath());
|
||||
m_portal = true;
|
||||
m_improxy =
|
||||
new FcitxQtInputMethodProxy(owner, "/inputmethod", connection, q);
|
||||
FcitxQtInputContextArgumentList list;
|
||||
FcitxQtInputContextArgument arg;
|
||||
arg.setName("program");
|
||||
arg.setValue(info.fileName());
|
||||
list << arg;
|
||||
if (!m_display.isEmpty()) {
|
||||
FcitxQtInputContextArgument arg2;
|
||||
arg2.setName("display");
|
||||
arg2.setValue(m_display);
|
||||
list << arg2;
|
||||
}
|
||||
|
||||
auto result = m_improxy->CreateInputContext(list);
|
||||
m_createInputContextWatcher = new QDBusPendingCallWatcher(result);
|
||||
QObject::connect(m_createInputContextWatcher,
|
||||
&QDBusPendingCallWatcher::finished, q,
|
||||
[this]() { createInputContextFinished(); });
|
||||
}
|
||||
|
||||
void createInputContextFinished() {
|
||||
Q_Q(FcitxQtInputContextProxy);
|
||||
if (m_createInputContextWatcher->isError()) {
|
||||
cleanUp();
|
||||
return;
|
||||
}
|
||||
|
||||
QDBusPendingReply<QDBusObjectPath, QByteArray> reply(
|
||||
*m_createInputContextWatcher);
|
||||
m_icproxy = new FcitxQtInputContextProxyImpl(
|
||||
m_improxy->service(), reply.value().path(), m_improxy->connection(),
|
||||
q);
|
||||
QObject::connect(m_icproxy, &FcitxQtInputContextProxyImpl::CommitString,
|
||||
q, &FcitxQtInputContextProxy::commitString);
|
||||
QObject::connect(m_icproxy, &FcitxQtInputContextProxyImpl::CurrentIM, q,
|
||||
&FcitxQtInputContextProxy::currentIM);
|
||||
QObject::connect(m_icproxy,
|
||||
&FcitxQtInputContextProxyImpl::DeleteSurroundingText,
|
||||
q, &FcitxQtInputContextProxy::deleteSurroundingText);
|
||||
QObject::connect(m_icproxy, &FcitxQtInputContextProxyImpl::ForwardKey,
|
||||
q, &FcitxQtInputContextProxy::forwardKey);
|
||||
QObject::connect(m_icproxy,
|
||||
&FcitxQtInputContextProxyImpl::UpdateFormattedPreedit,
|
||||
q, &FcitxQtInputContextProxy::updateFormattedPreedit);
|
||||
|
||||
delete m_createInputContextWatcher;
|
||||
m_createInputContextWatcher = nullptr;
|
||||
emit q->inputContextCreated(reply.argumentAt<1>());
|
||||
}
|
||||
|
||||
FcitxQtInputContextProxy *q_ptr;
|
||||
Q_DECLARE_PUBLIC(FcitxQtInputContextProxy);
|
||||
|
||||
FcitxQtWatcher *m_fcitxWatcher;
|
||||
QDBusServiceWatcher m_watcher;
|
||||
FcitxQtInputMethodProxy *m_improxy = nullptr;
|
||||
FcitxQtInputContextProxyImpl *m_icproxy = nullptr;
|
||||
QDBusPendingCallWatcher *m_createInputContextWatcher = nullptr;
|
||||
QString m_display;
|
||||
bool m_portal;
|
||||
qulonglong m_capability;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _DBUSADDONS_FCITXQTINPUTCONTEXTPROXY_P_H_
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was:
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||
* before re-generating it.
|
||||
*/
|
||||
|
||||
#include "fcitxqtinputcontextproxyimpl.h"
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
/*
|
||||
* Implementation of interface class FcitxQtInputContextProxyImpl
|
||||
*/
|
||||
|
||||
FcitxQtInputContextProxyImpl::FcitxQtInputContextProxyImpl(
|
||||
const QString &service, const QString &path,
|
||||
const QDBusConnection &connection, QObject *parent)
|
||||
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection,
|
||||
parent) {}
|
||||
|
||||
FcitxQtInputContextProxyImpl::~FcitxQtInputContextProxyImpl() {}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was:
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2016 The Qt Company Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef FCITXQTINPUTCONTEXTPROXYIMPL_H
|
||||
#define FCITXQTINPUTCONTEXTPROXYIMPL_H
|
||||
|
||||
#include "fcitx5qt5dbusaddons_export.h"
|
||||
#include "fcitxqtdbustypes.h"
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
/*
|
||||
* Proxy class for interface org.fcitx.Fcitx.InputContext1
|
||||
*/
|
||||
class FcitxQtInputContextProxyImpl : public QDBusAbstractInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static inline const char *staticInterfaceName() {
|
||||
return "org.fcitx.Fcitx.InputContext1";
|
||||
}
|
||||
|
||||
public:
|
||||
FcitxQtInputContextProxyImpl(const QString &service, const QString &path,
|
||||
const QDBusConnection &connection,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
~FcitxQtInputContextProxyImpl();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<> DestroyIC() {
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("DestroyIC"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> FocusIn() {
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("FocusIn"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> FocusOut() {
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("FocusOut"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<bool> ProcessKeyEvent(uint keyval, uint keycode,
|
||||
uint state, bool type,
|
||||
uint time) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(keyval)
|
||||
<< QVariant::fromValue(keycode)
|
||||
<< QVariant::fromValue(state) << QVariant::fromValue(type)
|
||||
<< QVariant::fromValue(time);
|
||||
return asyncCallWithArgumentList(QStringLiteral("ProcessKeyEvent"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> Reset() {
|
||||
QList<QVariant> argumentList;
|
||||
return asyncCallWithArgumentList(QStringLiteral("Reset"), argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetCapability(qulonglong caps) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(caps);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetCapability"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetCursorRect(int x, int y, int w, int h) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(x) << QVariant::fromValue(y)
|
||||
<< QVariant::fromValue(w) << QVariant::fromValue(h);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetCursorRect"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetSurroundingText(const QString &text,
|
||||
uint cursor, uint anchor) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(text) << QVariant::fromValue(cursor)
|
||||
<< QVariant::fromValue(anchor);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetSurroundingText"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetSurroundingTextPosition(uint cursor,
|
||||
uint anchor) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(cursor)
|
||||
<< QVariant::fromValue(anchor);
|
||||
return asyncCallWithArgumentList(
|
||||
QStringLiteral("SetSurroundingTextPosition"), argumentList);
|
||||
}
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
void CommitString(const QString &str);
|
||||
void CurrentIM(const QString &name, const QString &uniqueName,
|
||||
const QString &langCode);
|
||||
void DeleteSurroundingText(int offset, uint nchar);
|
||||
void ForwardKey(uint keyval, uint state, bool type);
|
||||
void UpdateFormattedPreedit(FcitxQtFormattedPreeditList str, int cursorpos);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,149 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2011~2012 by CSSlayer *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program 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 General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "fcitxqtwatcher_p.h"
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QDir>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
FcitxQtWatcher::FcitxQtWatcher(QObject *parent)
|
||||
: QObject(parent), d_ptr(new FcitxQtWatcherPrivate(this)) {}
|
||||
|
||||
FcitxQtWatcher::FcitxQtWatcher(const QDBusConnection &connection,
|
||||
QObject *parent)
|
||||
: FcitxQtWatcher(parent) {
|
||||
setConnection(connection);
|
||||
}
|
||||
|
||||
FcitxQtWatcher::~FcitxQtWatcher() { delete d_ptr; }
|
||||
|
||||
bool FcitxQtWatcher::availability() const {
|
||||
Q_D(const FcitxQtWatcher);
|
||||
return d->m_availability;
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::setConnection(const QDBusConnection &connection) {
|
||||
Q_D(FcitxQtWatcher);
|
||||
return d->m_serviceWatcher.setConnection(connection);
|
||||
}
|
||||
|
||||
QDBusConnection FcitxQtWatcher::connection() const {
|
||||
Q_D(const FcitxQtWatcher);
|
||||
return d->m_serviceWatcher.connection();
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::setWatchPortal(bool portal) {
|
||||
Q_D(FcitxQtWatcher);
|
||||
d->m_watchPortal = portal;
|
||||
}
|
||||
|
||||
bool FcitxQtWatcher::watchPortal() const {
|
||||
Q_D(const FcitxQtWatcher);
|
||||
return d->m_watchPortal;
|
||||
}
|
||||
|
||||
QString FcitxQtWatcher::serviceName() const {
|
||||
Q_D(const FcitxQtWatcher);
|
||||
if (d->m_mainPresent) {
|
||||
return FCITX_MAIN_SERVICE_NAME;
|
||||
}
|
||||
if (d->m_portalPresent) {
|
||||
return FCITX_PORTAL_SERVICE_NAME;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::setAvailability(bool availability) {
|
||||
Q_D(FcitxQtWatcher);
|
||||
if (d->m_availability != availability) {
|
||||
d->m_availability = availability;
|
||||
emit availibilityChanged(d->m_availability);
|
||||
}
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::watch() {
|
||||
Q_D(FcitxQtWatcher);
|
||||
if (d->m_watched) {
|
||||
return;
|
||||
}
|
||||
|
||||
connect(&d->m_serviceWatcher, &QDBusServiceWatcher::serviceOwnerChanged,
|
||||
this, &FcitxQtWatcher::imChanged);
|
||||
d->m_serviceWatcher.addWatchedService(FCITX_MAIN_SERVICE_NAME);
|
||||
if (d->m_watchPortal) {
|
||||
d->m_serviceWatcher.addWatchedService(FCITX_PORTAL_SERVICE_NAME);
|
||||
}
|
||||
|
||||
if (QDBusConnection::sessionBus().interface()->isServiceRegistered(
|
||||
FCITX_MAIN_SERVICE_NAME)) {
|
||||
d->m_mainPresent = true;
|
||||
}
|
||||
if (d->m_watchPortal &&
|
||||
QDBusConnection::sessionBus().interface()->isServiceRegistered(
|
||||
FCITX_PORTAL_SERVICE_NAME)) {
|
||||
d->m_portalPresent = true;
|
||||
}
|
||||
|
||||
updateAvailbility();
|
||||
|
||||
d->m_watched = true;
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::unwatch() {
|
||||
Q_D(FcitxQtWatcher);
|
||||
if (!d->m_watched) {
|
||||
return;
|
||||
}
|
||||
disconnect(&d->m_serviceWatcher, &QDBusServiceWatcher::serviceOwnerChanged,
|
||||
this, &FcitxQtWatcher::imChanged);
|
||||
}
|
||||
|
||||
bool FcitxQtWatcher::isWatching() const {
|
||||
Q_D(const FcitxQtWatcher);
|
||||
return d->m_watched;
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::imChanged(const QString &service, const QString &,
|
||||
const QString &newOwner) {
|
||||
Q_D(FcitxQtWatcher);
|
||||
if (service == FCITX_MAIN_SERVICE_NAME) {
|
||||
if (!newOwner.isEmpty()) {
|
||||
d->m_mainPresent = true;
|
||||
} else {
|
||||
d->m_mainPresent = false;
|
||||
}
|
||||
} else if (service == FCITX_PORTAL_SERVICE_NAME) {
|
||||
if (!newOwner.isEmpty()) {
|
||||
d->m_portalPresent = true;
|
||||
} else {
|
||||
d->m_portalPresent = false;
|
||||
}
|
||||
}
|
||||
|
||||
updateAvailbility();
|
||||
}
|
||||
|
||||
void FcitxQtWatcher::updateAvailbility() {
|
||||
Q_D(FcitxQtWatcher);
|
||||
setAvailability(d->m_mainPresent || d->m_portalPresent);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (C) 2017~2017 by CSSlayer
|
||||
* wengxt@gmail.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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DBUSADDONS_FCITXQTWATCHER_H_
|
||||
#define _DBUSADDONS_FCITXQTWATCHER_H_
|
||||
|
||||
#include "fcitx5qt5dbusaddons_export.h"
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QObject>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class FcitxQtWatcherPrivate;
|
||||
|
||||
class FCITX5QT5DBUSADDONS_EXPORT FcitxQtWatcher : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FcitxQtWatcher(QObject *parent = nullptr);
|
||||
explicit FcitxQtWatcher(const QDBusConnection &connection,
|
||||
QObject *parent = nullptr);
|
||||
~FcitxQtWatcher();
|
||||
void watch();
|
||||
void unwatch();
|
||||
void setConnection(const QDBusConnection &connection);
|
||||
QDBusConnection connection() const;
|
||||
void setWatchPortal(bool portal);
|
||||
bool watchPortal() const;
|
||||
bool isWatching() const;
|
||||
bool availability() const;
|
||||
|
||||
QString serviceName() const;
|
||||
|
||||
signals:
|
||||
void availibilityChanged(bool);
|
||||
|
||||
private slots:
|
||||
void imChanged(const QString &service, const QString &oldOwner,
|
||||
const QString &newOwner);
|
||||
|
||||
private:
|
||||
void setAvailability(bool availability);
|
||||
void updateAvailbility();
|
||||
|
||||
FcitxQtWatcherPrivate *const d_ptr;
|
||||
Q_DECLARE_PRIVATE(FcitxQtWatcher);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _DBUSADDONS_FCITXQTWATCHER_H_
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2017~2017 by CSSlayer
|
||||
* wengxt@gmail.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; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DBUSADDONS_FCITXQTWATCHER_P_H_
|
||||
#define _DBUSADDONS_FCITXQTWATCHER_P_H_
|
||||
|
||||
#include "fcitxqtwatcher.h"
|
||||
#include <QDBusServiceWatcher>
|
||||
|
||||
#define FCITX_MAIN_SERVICE_NAME "org.fcitx.Fcitx5"
|
||||
#define FCITX_PORTAL_SERVICE_NAME "org.freedesktop.portal.Fcitx"
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class FcitxQtWatcherPrivate {
|
||||
public:
|
||||
FcitxQtWatcherPrivate(FcitxQtWatcher *q) : m_serviceWatcher(q) {}
|
||||
|
||||
QDBusServiceWatcher m_serviceWatcher;
|
||||
bool m_watchPortal = false;
|
||||
bool m_availability = false;
|
||||
bool m_mainPresent = false;
|
||||
bool m_portalPresent = false;
|
||||
bool m_watched = false;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _DBUSADDONS_FCITXQTWATCHER_P_H_
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/sh
|
||||
|
||||
qdbusxml2cpp-qt5 -N -p fcitxqtinputcontextproxy -c FcitxQtInputContextProxy interfaces/org.fcitx.Fcitx.InputContext1.xml -i fcitxqtdbustypes.h -i fcitx5qt5dbusaddons_export.h
|
||||
qdbusxml2cpp-qt5 -N -p fcitxqtinputcontextproxyimpl -c FcitxQtInputContextProxyImpl interfaces/org.fcitx.Fcitx.InputContext1.xml -i fcitxqtdbustypes.h -i fcitx5qt5dbusaddons_export.h
|
||||
qdbusxml2cpp-qt5 -N -p fcitxqtinputmethodproxy -c FcitxQtInputMethodProxy interfaces/org.fcitx.Fcitx.InputMethod1.xml -i fcitxqtdbustypes.h -i fcitx5qt5dbusaddons_export.h
|
||||
qdbusxml2cpp-qt5 -N -p fcitxqtcontrollerproxy -c FcitxQtControllerProxy interfaces/org.fcitx.Fcitx.Controller1.xml -i fcitxqtdbustypes.h -i fcitx5qt5dbusaddons_export.h
|
||||
|
|
|
@ -26,16 +26,17 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "fcitxqtconfiguifactory.h"
|
||||
#include "fcitxqtconnection.h"
|
||||
#include "fcitxqtcontrollerproxy.h"
|
||||
#include "fcitxqtwatcher.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
MainWindow::MainWindow(FcitxQtConfigUIWidget *pluginWidget, QWidget *parent)
|
||||
: QMainWindow(parent), m_ui(new Ui::MainWindow),
|
||||
m_connection(new FcitxQtConnection(this)), m_pluginWidget(pluginWidget),
|
||||
m_watcher(new FcitxQtWatcher(this)), m_pluginWidget(pluginWidget),
|
||||
m_proxy(0) {
|
||||
m_watcher->setConnection(QDBusConnection::sessionBus());
|
||||
m_ui->setupUi(this);
|
||||
m_ui->verticalLayout->insertWidget(0, m_pluginWidget);
|
||||
m_ui->buttonBox->button(QDialogButtonBox::Save)->setText(_("&Save"));
|
||||
|
@ -52,18 +53,22 @@ MainWindow::MainWindow(FcitxQtConfigUIWidget *pluginWidget, QWidget *parent)
|
|||
SLOT(saveFinished()));
|
||||
connect(m_ui->buttonBox, SIGNAL(clicked(QAbstractButton *)), this,
|
||||
SLOT(clicked(QAbstractButton *)));
|
||||
connect(m_connection, SIGNAL(connected()), this, SLOT(connected()));
|
||||
connect(m_watcher, &FcitxQtWatcher::availibilityChanged, this,
|
||||
&MainWindow::availibilityChanged);
|
||||
|
||||
m_connection->startConnection();
|
||||
m_watcher->watch();
|
||||
}
|
||||
|
||||
void MainWindow::connected() {
|
||||
void MainWindow::availibilityChanged(bool avail) {
|
||||
if (!avail) {
|
||||
return;
|
||||
}
|
||||
if (m_proxy) {
|
||||
delete m_proxy;
|
||||
}
|
||||
m_proxy = new FcitxQtControllerProxy(m_connection->serviceName(),
|
||||
m_proxy = new FcitxQtControllerProxy(m_watcher->serviceName(),
|
||||
QLatin1String("/controller"),
|
||||
*m_connection->connection(), this);
|
||||
m_watcher->connection(), this);
|
||||
}
|
||||
|
||||
void MainWindow::clicked(QAbstractButton *button) {
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
namespace fcitx {
|
||||
|
||||
class FcitxQtControllerProxy;
|
||||
class FcitxQtConnection;
|
||||
class FcitxQtWatcher;
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -40,12 +40,12 @@ public:
|
|||
public slots:
|
||||
void changed(bool changed);
|
||||
void clicked(QAbstractButton *button);
|
||||
void connected();
|
||||
void availibilityChanged(bool avail);
|
||||
void saveFinished();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *m_ui;
|
||||
FcitxQtConnection *m_connection;
|
||||
FcitxQtWatcher *m_watcher;
|
||||
FcitxQtConfigUIWidget *m_pluginWidget;
|
||||
FcitxQtControllerProxy *m_proxy;
|
||||
};
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <QDebug>
|
||||
|
||||
#include "fcitxqtconfiguifactory.h"
|
||||
#include "fcitxqtconnection.h"
|
||||
#include "mainwindow.h"
|
||||
#include "wrapperapp.h"
|
||||
#include <fcitx-utils/standardpath.h>
|
||||
|
|
|
@ -36,9 +36,7 @@
|
|||
|
||||
#include "qtkey.h"
|
||||
|
||||
#include "fcitxqtconnection.h"
|
||||
#include "fcitxqtinputcontextproxy.h"
|
||||
#include "fcitxqtinputmethodproxy.h"
|
||||
#include "qfcitxplatforminputcontext.h"
|
||||
|
||||
#include <fcitx-utils/key.h>
|
||||
|
@ -147,7 +145,7 @@ struct xkb_context *_xkb_context_new_helper() {
|
|||
}
|
||||
|
||||
QFcitxPlatformInputContext::QFcitxPlatformInputContext()
|
||||
: m_connection(new FcitxQtConnection(this)), m_improxy(nullptr),
|
||||
: m_watcher(new FcitxQtWatcher(QDBusConnection::sessionBus(), this)),
|
||||
m_cursorPos(0), m_useSurroundingText(false),
|
||||
m_syncMode(get_boolean_env("FCITX_QT_USE_SYNC", false)), m_destroy(false),
|
||||
m_xkbContext(_xkb_context_new_helper()),
|
||||
|
@ -161,46 +159,20 @@ QFcitxPlatformInputContext::QFcitxPlatformInputContext()
|
|||
: 0) {
|
||||
FcitxQtFormattedPreedit::registerMetaType();
|
||||
FcitxQtInputContextArgument::registerMetaType();
|
||||
|
||||
connect(m_connection, &FcitxQtConnection::connected, this,
|
||||
&QFcitxPlatformInputContext::connected);
|
||||
connect(m_connection, &FcitxQtConnection::disconnected, this,
|
||||
&QFcitxPlatformInputContext::cleanUp);
|
||||
|
||||
m_connection->startConnection();
|
||||
m_watcher->setWatchPortal(true);
|
||||
m_watcher->watch();
|
||||
}
|
||||
|
||||
QFcitxPlatformInputContext::~QFcitxPlatformInputContext() {
|
||||
m_destroy = true;
|
||||
m_watcher->unwatch();
|
||||
cleanUp();
|
||||
}
|
||||
|
||||
void QFcitxPlatformInputContext::connected() {
|
||||
if (!m_connection->isConnected())
|
||||
return;
|
||||
|
||||
// qDebug() << "create Input Context" << m_connection->name();
|
||||
if (m_improxy) {
|
||||
delete m_improxy;
|
||||
m_improxy = nullptr;
|
||||
}
|
||||
m_improxy = new FcitxQtInputMethodProxy(m_connection->serviceName(),
|
||||
QLatin1String("/inputmethod"),
|
||||
*m_connection->connection(), this);
|
||||
|
||||
QWindow *w = qApp->focusWindow();
|
||||
if (w)
|
||||
createICData(w);
|
||||
delete m_watcher;
|
||||
}
|
||||
|
||||
void QFcitxPlatformInputContext::cleanUp() {
|
||||
m_icMap.clear();
|
||||
|
||||
if (m_improxy) {
|
||||
delete m_improxy;
|
||||
m_improxy = nullptr;
|
||||
}
|
||||
|
||||
if (!m_destroy) {
|
||||
commitPreedit();
|
||||
}
|
||||
|
@ -226,7 +198,6 @@ void QFcitxPlatformInputContext::commitPreedit(QPointer<QObject> input) {
|
|||
e.setCommitString(m_commitPreedit);
|
||||
QCoreApplication::sendEvent(input, &e);
|
||||
m_commitPreedit.clear();
|
||||
|
||||
m_preeditList.clear();
|
||||
}
|
||||
|
||||
|
@ -240,9 +211,9 @@ bool checkUtf8(const QByteArray &byteArray) {
|
|||
|
||||
void QFcitxPlatformInputContext::reset() {
|
||||
commitPreedit();
|
||||
FcitxQtInputContextProxy *proxy = validIC();
|
||||
if (proxy)
|
||||
proxy->Reset();
|
||||
if (FcitxQtInputContextProxy *proxy = validIC()) {
|
||||
proxy->reset();
|
||||
}
|
||||
if (m_xkbComposeState) {
|
||||
xkb_compose_state_reset(m_xkbComposeState.data());
|
||||
}
|
||||
|
@ -255,7 +226,8 @@ void QFcitxPlatformInputContext::update(Qt::InputMethodQueries queries) {
|
|||
if (!proxy)
|
||||
return;
|
||||
|
||||
auto &data = m_icMap[window];
|
||||
FcitxQtICData &data = *static_cast<FcitxQtICData *>(
|
||||
proxy->property("icData").value<void *>());
|
||||
|
||||
QObject *input = qApp->focusObject();
|
||||
if (!input)
|
||||
|
@ -326,11 +298,11 @@ void QFcitxPlatformInputContext::update(Qt::InputMethodQueries queries) {
|
|||
anchor = tempUCS4.size();
|
||||
if (data.surroundingText != text) {
|
||||
data.surroundingText = text;
|
||||
proxy->SetSurroundingText(text, cursor, anchor);
|
||||
proxy->setSurroundingText(text, cursor, anchor);
|
||||
} else {
|
||||
if (data.surroundingAnchor != anchor ||
|
||||
data.surroundingCursor != cursor)
|
||||
proxy->SetSurroundingTextPosition(cursor, anchor);
|
||||
proxy->setSurroundingTextPosition(cursor, anchor);
|
||||
}
|
||||
data.surroundingCursor = cursor;
|
||||
data.surroundingAnchor = anchor;
|
||||
|
@ -353,7 +325,7 @@ void QFcitxPlatformInputContext::setFocusObject(QObject *object) {
|
|||
FcitxQtInputContextProxy *proxy = validICByWindow(m_lastWindow);
|
||||
commitPreedit(m_lastObject);
|
||||
if (proxy) {
|
||||
proxy->FocusOut();
|
||||
proxy->focusOut();
|
||||
}
|
||||
|
||||
QWindow *window = qApp->focusWindow();
|
||||
|
@ -364,7 +336,7 @@ void QFcitxPlatformInputContext::setFocusObject(QObject *object) {
|
|||
}
|
||||
proxy = validICByWindow(window);
|
||||
if (proxy)
|
||||
proxy->FocusIn();
|
||||
proxy->focusIn();
|
||||
else {
|
||||
createICData(window);
|
||||
}
|
||||
|
@ -384,7 +356,8 @@ void QFcitxPlatformInputContext::cursorRectChanged() {
|
|||
if (!proxy)
|
||||
return;
|
||||
|
||||
auto &data = m_icMap[inputWindow];
|
||||
FcitxQtICData &data = *static_cast<FcitxQtICData *>(
|
||||
proxy->property("icData").value<void *>());
|
||||
|
||||
QRect r = qApp->inputMethod()->cursorRectangle().toRect();
|
||||
if (!r.isValid())
|
||||
|
@ -404,111 +377,50 @@ void QFcitxPlatformInputContext::cursorRectChanged() {
|
|||
|
||||
if (data.rect != newRect) {
|
||||
data.rect = newRect;
|
||||
proxy->SetCursorRect(newRect.x(), newRect.y(), newRect.width(),
|
||||
proxy->setCursorRect(newRect.x(), newRect.y(), newRect.width(),
|
||||
newRect.height());
|
||||
}
|
||||
}
|
||||
|
||||
void QFcitxPlatformInputContext::createInputContext(QWindow *w) {
|
||||
if (!m_connection->isConnected())
|
||||
return;
|
||||
|
||||
// qDebug() << "create Input Context" << m_connection->connection()->name();
|
||||
|
||||
if (!m_improxy) {
|
||||
m_improxy = new FcitxQtInputMethodProxy(
|
||||
m_connection->serviceName(), QLatin1String("/inputmethod"),
|
||||
*m_connection->connection(), this);
|
||||
}
|
||||
|
||||
if (!m_improxy->isValid())
|
||||
return;
|
||||
|
||||
QFileInfo info(QCoreApplication::applicationFilePath());
|
||||
FcitxQtInputContextArgumentList args;
|
||||
args << FcitxQtInputContextArgument("program", info.fileName());
|
||||
if (QGuiApplication::platformName() == QLatin1String("xcb")) {
|
||||
args << FcitxQtInputContextArgument("display", "x11:");
|
||||
} else if (QGuiApplication::platformName() == QLatin1String("wayland")) {
|
||||
args << FcitxQtInputContextArgument("display", "wayland:");
|
||||
}
|
||||
auto result = m_improxy->CreateInputContext(args);
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result);
|
||||
watcher->setProperty("wid", qVariantFromValue(static_cast<void *>(w)));
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this,
|
||||
&QFcitxPlatformInputContext::createInputContextFinished);
|
||||
}
|
||||
|
||||
void QFcitxPlatformInputContext::createInputContextFinished(
|
||||
QDBusPendingCallWatcher *watcher) {
|
||||
auto w =
|
||||
reinterpret_cast<QWindow *>(watcher->property("wid").value<void *>());
|
||||
auto iter = m_icMap.find(w);
|
||||
if (iter == m_icMap.end()) {
|
||||
const QByteArray &uuid) {
|
||||
auto proxy = qobject_cast<FcitxQtInputContextProxy *>(sender());
|
||||
if (!proxy) {
|
||||
return;
|
||||
}
|
||||
auto w =
|
||||
reinterpret_cast<QWindow *>(proxy->property("wid").value<void *>());
|
||||
FcitxQtICData *data =
|
||||
static_cast<FcitxQtICData *>(proxy->property("icData").value<void *>());
|
||||
data->rect = QRect();
|
||||
|
||||
auto &data = iter->second;
|
||||
|
||||
QDBusPendingReply<QDBusObjectPath, QByteArray> result = *watcher;
|
||||
|
||||
do {
|
||||
if (result.isError()) {
|
||||
break;
|
||||
if (proxy->isValid()) {
|
||||
QWindow *window = qApp->focusWindow();
|
||||
if (window && window == w) {
|
||||
proxy->focusIn();
|
||||
cursorRectChanged();
|
||||
}
|
||||
setFocusGroupForX11(uuid);
|
||||
}
|
||||
|
||||
if (!m_connection->isConnected())
|
||||
break;
|
||||
fcitx::CapabilityFlags flag;
|
||||
flag |= fcitx::CapabilityFlag::Preedit;
|
||||
flag |= fcitx::CapabilityFlag::FormattedPreedit;
|
||||
flag |= fcitx::CapabilityFlag::ClientUnfocusCommit;
|
||||
flag |= fcitx::CapabilityFlag::GetIMInfoOnFocus;
|
||||
m_useSurroundingText =
|
||||
get_boolean_env("FCITX_QT_ENABLE_SURROUNDING_TEXT", true);
|
||||
if (m_useSurroundingText)
|
||||
flag |= fcitx::CapabilityFlag::SurroundingText;
|
||||
|
||||
auto objectPath = result.argumentAt<0>();
|
||||
if (data.proxy) {
|
||||
delete data.proxy;
|
||||
}
|
||||
data.proxy = new FcitxQtInputContextProxy(
|
||||
m_connection->serviceName(), objectPath.path(),
|
||||
*m_connection->connection(), this);
|
||||
data.proxy->setProperty("icData",
|
||||
qVariantFromValue(static_cast<void *>(&data)));
|
||||
connect(data.proxy, &FcitxQtInputContextProxy::CommitString, this,
|
||||
&QFcitxPlatformInputContext::commitString);
|
||||
connect(data.proxy, &FcitxQtInputContextProxy::ForwardKey, this,
|
||||
&QFcitxPlatformInputContext::forwardKey);
|
||||
connect(data.proxy, &FcitxQtInputContextProxy::UpdateFormattedPreedit,
|
||||
this, &QFcitxPlatformInputContext::updateFormattedPreedit);
|
||||
connect(data.proxy, &FcitxQtInputContextProxy::DeleteSurroundingText,
|
||||
this, &QFcitxPlatformInputContext::deleteSurroundingText);
|
||||
connect(data.proxy, &FcitxQtInputContextProxy::CurrentIM, this,
|
||||
&QFcitxPlatformInputContext::updateCurrentIM);
|
||||
|
||||
if (data.proxy->isValid()) {
|
||||
QWindow *window = qApp->focusWindow();
|
||||
if (window && window == w)
|
||||
data.proxy->FocusIn();
|
||||
}
|
||||
|
||||
setFocusGroupForX11(result.argumentAt<1>());
|
||||
|
||||
fcitx::CapabilityFlags flag;
|
||||
flag |= fcitx::CapabilityFlag::Preedit;
|
||||
flag |= fcitx::CapabilityFlag::FormattedPreedit;
|
||||
flag |= fcitx::CapabilityFlag::ClientUnfocusCommit;
|
||||
flag |= fcitx::CapabilityFlag::GetIMInfoOnFocus;
|
||||
m_useSurroundingText =
|
||||
get_boolean_env("FCITX_QT_ENABLE_SURROUNDING_TEXT", true);
|
||||
if (m_useSurroundingText)
|
||||
flag |= fcitx::CapabilityFlag::SurroundingText;
|
||||
|
||||
addCapability(data, flag, true);
|
||||
} while (0);
|
||||
delete watcher;
|
||||
addCapability(*data, flag, true);
|
||||
}
|
||||
|
||||
void QFcitxPlatformInputContext::updateCapability(const FcitxQtICData &data) {
|
||||
if (!data.proxy || !data.proxy->isValid())
|
||||
return;
|
||||
|
||||
QDBusPendingReply<void> result =
|
||||
data.proxy->SetCapability((uint)data.capability);
|
||||
QDBusPendingReply<void> result = data.proxy->setCapability(data.capability);
|
||||
}
|
||||
|
||||
void QFcitxPlatformInputContext::commitString(const QString &str) {
|
||||
|
@ -676,12 +588,37 @@ QLocale QFcitxPlatformInputContext::locale() const { return m_locale; }
|
|||
void QFcitxPlatformInputContext::createICData(QWindow *w) {
|
||||
auto iter = m_icMap.find(w);
|
||||
if (iter == m_icMap.end()) {
|
||||
m_icMap.emplace(std::piecewise_construct, std::forward_as_tuple(w),
|
||||
std::forward_as_tuple());
|
||||
auto result =
|
||||
m_icMap.emplace(std::piecewise_construct, std::forward_as_tuple(w),
|
||||
std::forward_as_tuple(m_watcher));
|
||||
connect(w, &QObject::destroyed, this,
|
||||
&QFcitxPlatformInputContext::windowDestroyed);
|
||||
iter = result.first;
|
||||
auto &data = iter->second;
|
||||
|
||||
if (QGuiApplication::platformName() == QLatin1String("xcb")) {
|
||||
data.proxy->setDisplay("x11:");
|
||||
} else if (QGuiApplication::platformName() ==
|
||||
QLatin1String("wayland")) {
|
||||
data.proxy->setDisplay("wayland:");
|
||||
}
|
||||
data.proxy->setProperty("wid",
|
||||
qVariantFromValue(static_cast<void *>(w)));
|
||||
data.proxy->setProperty("icData",
|
||||
qVariantFromValue(static_cast<void *>(&data)));
|
||||
connect(data.proxy, &FcitxQtInputContextProxy::inputContextCreated,
|
||||
this, &QFcitxPlatformInputContext::createInputContextFinished);
|
||||
connect(data.proxy, &FcitxQtInputContextProxy::commitString, this,
|
||||
&QFcitxPlatformInputContext::commitString);
|
||||
connect(data.proxy, &FcitxQtInputContextProxy::forwardKey, this,
|
||||
&QFcitxPlatformInputContext::forwardKey);
|
||||
connect(data.proxy, &FcitxQtInputContextProxy::updateFormattedPreedit,
|
||||
this, &QFcitxPlatformInputContext::updateFormattedPreedit);
|
||||
connect(data.proxy, &FcitxQtInputContextProxy::deleteSurroundingText,
|
||||
this, &QFcitxPlatformInputContext::deleteSurroundingText);
|
||||
connect(data.proxy, &FcitxQtInputContextProxy::currentIM, this,
|
||||
&QFcitxPlatformInputContext::updateCurrentIM);
|
||||
}
|
||||
createInputContext(w);
|
||||
}
|
||||
|
||||
QKeyEvent *QFcitxPlatformInputContext::createKeyEvent(uint keyval, uint _state,
|
||||
|
@ -714,9 +651,9 @@ QKeyEvent *QFcitxPlatformInputContext::createKeyEvent(uint keyval, uint _state,
|
|||
|
||||
int key = keysymToQtKey(keyval, text);
|
||||
|
||||
QKeyEvent *keyevent = new QKeyEvent(
|
||||
isRelease ? (QEvent::KeyRelease) : (QEvent::KeyPress), key, qstate, 0,
|
||||
keyval, _state, text, false, count);
|
||||
QKeyEvent *keyevent =
|
||||
new QKeyEvent(isRelease ? (QEvent::KeyRelease) : (QEvent::KeyPress),
|
||||
key, qstate, 0, keyval, _state, text, false, count);
|
||||
|
||||
return keyevent;
|
||||
}
|
||||
|
@ -757,17 +694,16 @@ bool QFcitxPlatformInputContext::filterEvent(const QEvent *event) {
|
|||
}
|
||||
}
|
||||
|
||||
proxy->FocusIn();
|
||||
proxy->focusIn();
|
||||
|
||||
auto reply =
|
||||
proxy->ProcessKeyEvent(keyval, keycode, state, isRelease,
|
||||
proxy->processKeyEvent(keyval, keycode, state, isRelease,
|
||||
QDateTime::currentDateTime().toTime_t());
|
||||
|
||||
if (Q_UNLIKELY(m_syncMode)) {
|
||||
reply.waitForFinished();
|
||||
|
||||
if (!m_connection->isConnected() || !reply.isFinished() ||
|
||||
reply.isError() || !reply.value()) {
|
||||
if (reply.isError() || !reply.value()) {
|
||||
if (filterEventFallback(keyval, keycode, state, isRelease)) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -779,7 +715,7 @@ bool QFcitxPlatformInputContext::filterEvent(const QEvent *event) {
|
|||
}
|
||||
} else {
|
||||
ProcessKeyWatcher *watcher = new ProcessKeyWatcher(
|
||||
*keyEvent, qApp->focusWindow(), reply, this);
|
||||
*keyEvent, qApp->focusWindow(), reply, proxy);
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this,
|
||||
&QFcitxPlatformInputContext::processKeyEventFinished);
|
||||
return true;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define QFCITXPLATFORMINPUTCONTEXT_H
|
||||
|
||||
#include "fcitxqtinputcontextproxy.h"
|
||||
#include "fcitxqtwatcher.h"
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QGuiApplication>
|
||||
|
@ -38,17 +39,11 @@ namespace fcitx {
|
|||
class FcitxQtConnection;
|
||||
|
||||
struct FcitxQtICData {
|
||||
FcitxQtICData()
|
||||
: proxy(nullptr), surroundingAnchor(-1), surroundingCursor(-1) {}
|
||||
FcitxQtICData(FcitxQtWatcher *watcher)
|
||||
: proxy(new FcitxQtInputContextProxy(watcher, watcher)),
|
||||
surroundingAnchor(-1), surroundingCursor(-1) {}
|
||||
FcitxQtICData(const FcitxQtICData &that) = delete;
|
||||
~FcitxQtICData() {
|
||||
if (proxy) {
|
||||
if (proxy->isValid()) {
|
||||
proxy->DestroyIC();
|
||||
}
|
||||
delete proxy;
|
||||
}
|
||||
}
|
||||
~FcitxQtICData() { delete proxy; }
|
||||
fcitx::CapabilityFlags capability;
|
||||
FcitxQtInputContextProxy *proxy;
|
||||
QRect rect;
|
||||
|
@ -101,8 +96,6 @@ struct XkbComposeStateDeleter {
|
|||
}
|
||||
};
|
||||
|
||||
class FcitxQtInputMethodProxy;
|
||||
|
||||
class QFcitxPlatformInputContext : public QPlatformInputContext {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -126,15 +119,13 @@ public Q_SLOTS:
|
|||
int cursorPos);
|
||||
void deleteSurroundingText(int offset, uint nchar);
|
||||
void forwardKey(uint keyval, uint state, bool type);
|
||||
void createInputContextFinished(QDBusPendingCallWatcher *watcher);
|
||||
void connected();
|
||||
void createInputContextFinished(const QByteArray &uuid);
|
||||
void cleanUp();
|
||||
void windowDestroyed(QObject *object);
|
||||
void updateCurrentIM(const QString &name, const QString &uniqueName,
|
||||
const QString &langCode);
|
||||
|
||||
private:
|
||||
void createInputContext(QWindow *w);
|
||||
bool processCompose(uint keyval, uint state, bool isRelaese);
|
||||
QKeyEvent *createKeyEvent(uint keyval, uint state, bool isRelaese);
|
||||
|
||||
|
@ -165,8 +156,7 @@ private:
|
|||
bool filterEventFallback(uint keyval, uint keycode, uint state,
|
||||
bool isRelaese);
|
||||
|
||||
FcitxQtConnection *m_connection;
|
||||
FcitxQtInputMethodProxy *m_improxy;
|
||||
FcitxQtWatcher *m_watcher;
|
||||
QString m_preedit;
|
||||
QString m_commitPreedit;
|
||||
FcitxQtFormattedPreeditList m_preeditList;
|
||||
|
|
Loading…
Reference in New Issue