init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
57
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/CMakeLists.txt
vendored
Normal file
57
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
set(FCITX5_QT_EXTRA_PLUGIN_NAME "")
|
||||
if (WITH_FCITX_PLUGIN_NAME)
|
||||
set(FCITX5_QT_EXTRA_PLUGIN_NAME "\"fcitx\",")
|
||||
endif()
|
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/fcitx5.json.in" "${CMAKE_CURRENT_BINARY_DIR}/fcitx5.json")
|
||||
|
||||
set(plugin_SRCS
|
||||
fcitx4watcher.cpp
|
||||
fcitx4inputcontextproxy.cpp
|
||||
fcitx4inputcontextproxyimpl.cpp
|
||||
fcitx4inputmethodproxy.cpp
|
||||
hybridinputcontext.cpp
|
||||
qfcitxplatforminputcontext.cpp
|
||||
fcitxcandidatewindow.cpp
|
||||
fcitxtheme.cpp
|
||||
font.cpp
|
||||
qtkey.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
||||
if (BUILD_ONLY_PLUGIN AND BUILD_STATIC_PLUGIN)
|
||||
set(plugin_SRCS ${plugin_SRCS} $<TARGET_OBJECTS:Fcitx5Qt5DBusAddons>)
|
||||
endif()
|
||||
|
||||
add_library(fcitx5platforminputcontextplugin ${PLUGIN_LIBRARY_TYPE} ${plugin_SRCS})
|
||||
set_target_properties(fcitx5platforminputcontextplugin PROPERTIES
|
||||
AUTOMOC TRUE
|
||||
)
|
||||
target_include_directories(fcitx5platforminputcontextplugin PRIVATE ${Qt5Gui_PRIVATE_INCLUDE_DIRS} "${PROJECT_SOURCE_DIR}/common")
|
||||
if (BUILD_ONLY_PLUGIN AND BUILD_STATIC_PLUGIN)
|
||||
target_compile_definitions(fcitx5platforminputcontextplugin PRIVATE "-DQT_STATICPLUGIN")
|
||||
endif()
|
||||
|
||||
target_compile_definitions(fcitx5platforminputcontextplugin PRIVATE "-DFCITX_PLUGIN_DATA_FILE_PATH=\"${CMAKE_CURRENT_BINARY_DIR}/fcitx5.json\"")
|
||||
if (WITH_FCITX_PLUGIN_NAME)
|
||||
# This is not really necessary, but can trigger a cmake rebuild.
|
||||
target_compile_definitions(fcitx5platforminputcontextplugin PRIVATE "-DFCITX5_QT_WITH_FCITX_NAME")
|
||||
endif()
|
||||
|
||||
|
||||
target_link_libraries(fcitx5platforminputcontextplugin
|
||||
Qt5::Core
|
||||
Qt5::Gui
|
||||
Qt5::DBus
|
||||
Qt5::Widgets
|
||||
Fcitx5Qt5::DBusAddons
|
||||
XKBCommon::XKBCommon
|
||||
)
|
||||
if (ENABLE_X11)
|
||||
target_link_libraries(fcitx5platforminputcontextplugin XCB::XCB)
|
||||
target_compile_definitions(fcitx5platforminputcontextplugin PRIVATE "-DENABLE_X11")
|
||||
endif()
|
||||
include(ECMQueryQmake)
|
||||
query_qmake(_QT5PLUGINDIR QT_INSTALL_PLUGINS)
|
||||
set(CMAKE_INSTALL_QT5PLUGINDIR ${_QT5PLUGINDIR} CACHE PATH "Qt5 plugin dir")
|
||||
install(TARGETS fcitx5platforminputcontextplugin DESTINATION ${CMAKE_INSTALL_QT5PLUGINDIR}/platforminputcontexts)
|
||||
86
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputcontextproxy.cpp
vendored
Normal file
86
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputcontextproxy.cpp
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2012~2023 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fcitx4inputcontextproxy_p.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusMetaType>
|
||||
#include <QFileInfo>
|
||||
#include <QTimer>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
Fcitx4InputContextProxy::Fcitx4InputContextProxy(Fcitx4Watcher *watcher,
|
||||
QObject *parent)
|
||||
: QObject(parent),
|
||||
d_ptr(new Fcitx4InputContextProxyPrivate(watcher, this)) {}
|
||||
|
||||
Fcitx4InputContextProxy::~Fcitx4InputContextProxy() { delete d_ptr; }
|
||||
|
||||
void Fcitx4InputContextProxy::setDisplay(const QString &display) {
|
||||
Q_D(Fcitx4InputContextProxy);
|
||||
d->display_ = display;
|
||||
}
|
||||
|
||||
const QString &Fcitx4InputContextProxy::display() const {
|
||||
Q_D(const Fcitx4InputContextProxy);
|
||||
return d->display_;
|
||||
}
|
||||
|
||||
bool Fcitx4InputContextProxy::isValid() const {
|
||||
Q_D(const Fcitx4InputContextProxy);
|
||||
return d->isValid();
|
||||
}
|
||||
|
||||
QDBusPendingReply<> Fcitx4InputContextProxy::focusIn() {
|
||||
Q_D(Fcitx4InputContextProxy);
|
||||
return d->icproxy_->FocusIn();
|
||||
}
|
||||
|
||||
QDBusPendingReply<> Fcitx4InputContextProxy::focusOut() {
|
||||
Q_D(Fcitx4InputContextProxy);
|
||||
return d->icproxy_->FocusOut();
|
||||
}
|
||||
|
||||
QDBusPendingReply<int> Fcitx4InputContextProxy::processKeyEvent(
|
||||
unsigned int keyval, unsigned int keycode, unsigned int state, int type,
|
||||
unsigned int time) {
|
||||
Q_D(Fcitx4InputContextProxy);
|
||||
return d->icproxy_->ProcessKeyEvent(keyval, keycode, state, type, time);
|
||||
}
|
||||
|
||||
QDBusPendingReply<> Fcitx4InputContextProxy::reset() {
|
||||
Q_D(Fcitx4InputContextProxy);
|
||||
return d->icproxy_->Reset();
|
||||
}
|
||||
|
||||
QDBusPendingReply<> Fcitx4InputContextProxy::setCapability(unsigned int caps) {
|
||||
Q_D(Fcitx4InputContextProxy);
|
||||
return d->icproxy_->SetCapacity(caps);
|
||||
}
|
||||
|
||||
QDBusPendingReply<> Fcitx4InputContextProxy::setCursorRect(int x, int y, int w,
|
||||
int h) {
|
||||
Q_D(Fcitx4InputContextProxy);
|
||||
return d->icproxy_->SetCursorRect(x, y, w, h);
|
||||
}
|
||||
|
||||
QDBusPendingReply<> Fcitx4InputContextProxy::setSurroundingText(
|
||||
const QString &text, unsigned int cursor, unsigned int anchor) {
|
||||
Q_D(Fcitx4InputContextProxy);
|
||||
return d->icproxy_->SetSurroundingText(text, cursor, anchor);
|
||||
}
|
||||
|
||||
QDBusPendingReply<>
|
||||
Fcitx4InputContextProxy::setSurroundingTextPosition(unsigned int cursor,
|
||||
unsigned int anchor) {
|
||||
Q_D(Fcitx4InputContextProxy);
|
||||
return d->icproxy_->SetSurroundingTextPosition(cursor, anchor);
|
||||
}
|
||||
|
||||
} // namespace fcitx
|
||||
67
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputcontextproxy.h
vendored
Normal file
67
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputcontextproxy.h
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2012~2023 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _FCITX4INPUTCONTEXTPROXY_H_
|
||||
#define _FCITX4INPUTCONTEXTPROXY_H_
|
||||
|
||||
#include "fcitxqtdbustypes.h"
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusPendingReply>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QObject>
|
||||
|
||||
class QDBusPendingCallWatcher;
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class Fcitx4Watcher;
|
||||
class Fcitx4InputContextProxyPrivate;
|
||||
|
||||
class Fcitx4InputContextProxy : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Fcitx4InputContextProxy(Fcitx4Watcher *watcher, QObject *parent);
|
||||
~Fcitx4InputContextProxy();
|
||||
|
||||
bool isValid() const;
|
||||
void setDisplay(const QString &display);
|
||||
const QString &display() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
QDBusPendingReply<> focusIn();
|
||||
QDBusPendingReply<> focusOut();
|
||||
QDBusPendingReply<int> processKeyEvent(unsigned int keyval,
|
||||
unsigned int keycode,
|
||||
unsigned int state, int type,
|
||||
unsigned int time);
|
||||
QDBusPendingReply<> reset();
|
||||
QDBusPendingReply<> setCapability(unsigned int caps);
|
||||
QDBusPendingReply<> setCursorRect(int x, int y, int w, int h);
|
||||
QDBusPendingReply<> setSurroundingText(const QString &text,
|
||||
unsigned int cursor,
|
||||
unsigned int anchor);
|
||||
QDBusPendingReply<> setSurroundingTextPosition(unsigned int cursor,
|
||||
unsigned int anchor);
|
||||
|
||||
Q_SIGNALS:
|
||||
void commitString(const QString &str);
|
||||
void currentIM(const QString &name, const QString &uniqueName,
|
||||
const QString &langCode);
|
||||
void deleteSurroundingText(int offset, unsigned int nchar);
|
||||
void forwardKey(unsigned int keyval, unsigned int state, bool isRelease);
|
||||
void updateFormattedPreedit(const FcitxQtFormattedPreeditList &str,
|
||||
int cursorpos);
|
||||
void inputContextCreated();
|
||||
|
||||
private:
|
||||
Fcitx4InputContextProxyPrivate *const d_ptr;
|
||||
Q_DECLARE_PRIVATE(Fcitx4InputContextProxy);
|
||||
};
|
||||
|
||||
} // namespace fcitx
|
||||
|
||||
#endif // _FCITX4INPUTCONTEXTPROXY_H_
|
||||
152
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputcontextproxy_p.h
vendored
Normal file
152
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputcontextproxy_p.h
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2012~2023 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
#ifndef _FCITX4INPUTCONTEXTPROXY_P_H_
|
||||
#define _FCITX4INPUTCONTEXTPROXY_P_H_
|
||||
|
||||
#include "fcitx4inputcontextproxy.h"
|
||||
#include "fcitx4inputcontextproxyimpl.h"
|
||||
#include "fcitx4inputmethodproxy.h"
|
||||
#include "fcitx4watcher.h"
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <cstddef>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class Fcitx4InputContextProxyPrivate {
|
||||
public:
|
||||
Fcitx4InputContextProxyPrivate(Fcitx4Watcher *watcher,
|
||||
Fcitx4InputContextProxy *q)
|
||||
: q_ptr(q), fcitxWatcher_(watcher), watcher_(q) {
|
||||
registerFcitxQtDBusTypes();
|
||||
QObject::connect(fcitxWatcher_, &Fcitx4Watcher::availabilityChanged, q,
|
||||
[this]() { availabilityChanged(); });
|
||||
watcher_.setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
|
||||
QObject::connect(&watcher_, &QDBusServiceWatcher::serviceUnregistered,
|
||||
q, [this]() {
|
||||
cleanUp();
|
||||
availabilityChanged();
|
||||
});
|
||||
availabilityChanged();
|
||||
}
|
||||
|
||||
~Fcitx4InputContextProxyPrivate() {
|
||||
if (isValid()) {
|
||||
icproxy_->DestroyIC();
|
||||
}
|
||||
cleanUp();
|
||||
}
|
||||
|
||||
bool isValid() const { return (icproxy_ && icproxy_->isValid()); }
|
||||
|
||||
void availabilityChanged() {
|
||||
QTimer::singleShot(100, q_ptr, [this]() { recheck(); });
|
||||
}
|
||||
|
||||
void recheck() {
|
||||
if (!isValid() && fcitxWatcher_->availability()) {
|
||||
createInputContext();
|
||||
}
|
||||
if (!fcitxWatcher_->availability()) {
|
||||
cleanUp();
|
||||
}
|
||||
}
|
||||
|
||||
void cleanUp() {
|
||||
auto services = watcher_.watchedServices();
|
||||
for (const auto &service : services) {
|
||||
watcher_.removeWatchedService(service);
|
||||
}
|
||||
|
||||
delete improxy_;
|
||||
improxy_ = nullptr;
|
||||
delete icproxy_;
|
||||
icproxy_ = nullptr;
|
||||
delete createInputContextWatcher_;
|
||||
createInputContextWatcher_ = nullptr;
|
||||
}
|
||||
|
||||
void createInputContext() {
|
||||
Q_Q(Fcitx4InputContextProxy);
|
||||
if (!fcitxWatcher_->availability()) {
|
||||
return;
|
||||
}
|
||||
|
||||
cleanUp();
|
||||
|
||||
auto service = fcitxWatcher_->service();
|
||||
auto connection = fcitxWatcher_->connection();
|
||||
|
||||
auto owner = connection.interface()->serviceOwner(service);
|
||||
if (!owner.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
watcher_.setConnection(connection);
|
||||
watcher_.setWatchedServices(QStringList() << owner);
|
||||
// Avoid race, query again.
|
||||
if (!connection.interface()->isServiceRegistered(owner)) {
|
||||
cleanUp();
|
||||
return;
|
||||
}
|
||||
|
||||
QFileInfo info(QCoreApplication::applicationFilePath());
|
||||
improxy_ =
|
||||
new Fcitx4InputMethodProxy(owner, "/inputmethod", connection, q);
|
||||
|
||||
auto result = improxy_->CreateICv3(info.fileName(), getpid());
|
||||
createInputContextWatcher_ = new QDBusPendingCallWatcher(result);
|
||||
QObject::connect(createInputContextWatcher_,
|
||||
&QDBusPendingCallWatcher::finished, q,
|
||||
[this]() { createInputContextFinished(); });
|
||||
}
|
||||
|
||||
void createInputContextFinished() {
|
||||
Q_Q(Fcitx4InputContextProxy);
|
||||
if (createInputContextWatcher_->isError()) {
|
||||
cleanUp();
|
||||
return;
|
||||
}
|
||||
|
||||
QDBusPendingReply<int, bool, unsigned int, unsigned int, unsigned int,
|
||||
unsigned int>
|
||||
reply(*createInputContextWatcher_);
|
||||
|
||||
QString path = QString("/inputcontext_%1").arg(reply.value());
|
||||
icproxy_ = new Fcitx4InputContextProxyImpl(improxy_->service(), path,
|
||||
improxy_->connection(), q);
|
||||
QObject::connect(icproxy_, &Fcitx4InputContextProxyImpl::CommitString,
|
||||
q, &Fcitx4InputContextProxy::commitString);
|
||||
QObject::connect(icproxy_, &Fcitx4InputContextProxyImpl::CurrentIM, q,
|
||||
&Fcitx4InputContextProxy::currentIM);
|
||||
QObject::connect(icproxy_,
|
||||
&Fcitx4InputContextProxyImpl::DeleteSurroundingText, q,
|
||||
&Fcitx4InputContextProxy::deleteSurroundingText);
|
||||
QObject::connect(icproxy_, &Fcitx4InputContextProxyImpl::ForwardKey, q,
|
||||
&Fcitx4InputContextProxy::forwardKey);
|
||||
QObject::connect(icproxy_,
|
||||
&Fcitx4InputContextProxyImpl::UpdateFormattedPreedit,
|
||||
q, &Fcitx4InputContextProxy::updateFormattedPreedit);
|
||||
|
||||
delete createInputContextWatcher_;
|
||||
createInputContextWatcher_ = nullptr;
|
||||
Q_EMIT q->inputContextCreated();
|
||||
}
|
||||
|
||||
Fcitx4InputContextProxy *q_ptr;
|
||||
Q_DECLARE_PUBLIC(Fcitx4InputContextProxy);
|
||||
|
||||
Fcitx4Watcher *fcitxWatcher_;
|
||||
QDBusServiceWatcher watcher_;
|
||||
Fcitx4InputMethodProxy *improxy_ = nullptr;
|
||||
Fcitx4InputContextProxyImpl *icproxy_ = nullptr;
|
||||
QDBusPendingCallWatcher *createInputContextWatcher_ = nullptr;
|
||||
QString display_;
|
||||
};
|
||||
} // namespace fcitx
|
||||
|
||||
#endif // _FCITX4INPUTCONTEXTPROXY_P_H_
|
||||
30
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputcontextproxyimpl.cpp
vendored
Normal file
30
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputcontextproxyimpl.cpp
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was: qdbusxml2cpp -N -p fcitx4inputcontextproxyimpl -c
|
||||
* Fcitx4InputContextProxy org.fcitx.Fcitx.InputContext.xml
|
||||
* org.fcitx.Fcitx.InputContext
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2022 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 "fcitx4inputcontextproxyimpl.h"
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
/*
|
||||
* Implementation of interface class Fcitx4InputContextProxy
|
||||
*/
|
||||
|
||||
Fcitx4InputContextProxyImpl::Fcitx4InputContextProxyImpl(
|
||||
const QString &service, const QString &path,
|
||||
const QDBusConnection &connection, QObject *parent)
|
||||
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection,
|
||||
parent) {}
|
||||
|
||||
Fcitx4InputContextProxyImpl::~Fcitx4InputContextProxyImpl() {}
|
||||
|
||||
} // namespace fcitx
|
||||
126
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputcontextproxyimpl.h
vendored
Normal file
126
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputcontextproxyimpl.h
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was: qdbusxml2cpp -N -p fcitx4inputcontextproxyimpl -c
|
||||
* Fcitx4InputContextProxyImpl org.fcitx.Fcitx.InputContext.xml
|
||||
* org.fcitx.Fcitx.InputContext
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2022 The Qt Company Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef FCITX4INPUTCONTEXTPROXYIMPL_H
|
||||
#define FCITX4INPUTCONTEXTPROXYIMPL_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.InputContext
|
||||
*/
|
||||
class Fcitx4InputContextProxyImpl : public QDBusAbstractInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static inline const char *staticInterfaceName() {
|
||||
return "org.fcitx.Fcitx.InputContext";
|
||||
}
|
||||
|
||||
public:
|
||||
Fcitx4InputContextProxyImpl(const QString &service, const QString &path,
|
||||
const QDBusConnection &connection,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
~Fcitx4InputContextProxyImpl();
|
||||
|
||||
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<int> ProcessKeyEvent(unsigned int keyval,
|
||||
unsigned int keycode,
|
||||
unsigned int state, int type,
|
||||
unsigned int 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<> SetCapacity(unsigned int caps) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(caps);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetCapacity"),
|
||||
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,
|
||||
unsigned int cursor,
|
||||
unsigned int anchor) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(text) << QVariant::fromValue(cursor)
|
||||
<< QVariant::fromValue(anchor);
|
||||
return asyncCallWithArgumentList(QStringLiteral("SetSurroundingText"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
inline QDBusPendingReply<> SetSurroundingTextPosition(unsigned int cursor,
|
||||
unsigned int 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, unsigned int nchar);
|
||||
void ForwardKey(unsigned int keyval, unsigned int state, int type);
|
||||
void UpdateFormattedPreedit(FcitxQtFormattedPreeditList str, int cursorpos);
|
||||
};
|
||||
|
||||
} // namespace fcitx
|
||||
|
||||
#endif
|
||||
29
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputmethodproxy.cpp
vendored
Normal file
29
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputmethodproxy.cpp
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was: qdbusxml2cpp -N -p fcitx4inputmethodproxy -c
|
||||
* Fcitx4InputMethodProxy org.fcitx.Fcitx.InputMethod.xml
|
||||
* org.fcitx.Fcitx.InputMethod
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2022 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 "fcitx4inputmethodproxy.h"
|
||||
|
||||
namespace fcitx {
|
||||
/*
|
||||
* Implementation of interface class Fcitx4InputMethodProxy
|
||||
*/
|
||||
|
||||
Fcitx4InputMethodProxy::Fcitx4InputMethodProxy(
|
||||
const QString &service, const QString &path,
|
||||
const QDBusConnection &connection, QObject *parent)
|
||||
: QDBusAbstractInterface(service, path, staticInterfaceName(), connection,
|
||||
parent) {}
|
||||
|
||||
Fcitx4InputMethodProxy::~Fcitx4InputMethodProxy() {}
|
||||
|
||||
} // namespace fcitx
|
||||
80
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputmethodproxy.h
vendored
Normal file
80
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4inputmethodproxy.h
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This file was generated by qdbusxml2cpp version 0.8
|
||||
* Command line was: qdbusxml2cpp -N -p fcitx4inputmethodproxy -c
|
||||
* Fcitx4InputMethodProxy org.fcitx.Fcitx.InputMethod.xml
|
||||
* org.fcitx.Fcitx.InputMethod
|
||||
*
|
||||
* qdbusxml2cpp is Copyright (C) 2022 The Qt Company Ltd.
|
||||
*
|
||||
* This is an auto-generated file.
|
||||
* Do not edit! All changes made to it will be lost.
|
||||
*/
|
||||
|
||||
#ifndef FCITX4INPUTMETHODPROXY_H
|
||||
#define FCITX4INPUTMETHODPROXY_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.InputMethod
|
||||
*/
|
||||
class Fcitx4InputMethodProxy : public QDBusAbstractInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static inline const char *staticInterfaceName() {
|
||||
return "org.fcitx.Fcitx.InputMethod";
|
||||
}
|
||||
|
||||
public:
|
||||
Fcitx4InputMethodProxy(const QString &service, const QString &path,
|
||||
const QDBusConnection &connection,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
~Fcitx4InputMethodProxy();
|
||||
|
||||
public Q_SLOTS: // METHODS
|
||||
inline QDBusPendingReply<int, bool, unsigned int, unsigned int,
|
||||
unsigned int, unsigned int>
|
||||
CreateICv3(const QString &appname, int pid) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(appname)
|
||||
<< QVariant::fromValue(pid);
|
||||
return asyncCallWithArgumentList(QStringLiteral("CreateICv3"),
|
||||
argumentList);
|
||||
}
|
||||
inline QDBusReply<int> CreateICv3(const QString &appname, int pid,
|
||||
bool &enable, unsigned int &keyval1,
|
||||
unsigned int &state1,
|
||||
unsigned int &keyval2,
|
||||
unsigned int &state2) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(appname)
|
||||
<< QVariant::fromValue(pid);
|
||||
QDBusMessage reply = callWithArgumentList(
|
||||
QDBus::Block, QStringLiteral("CreateICv3"), argumentList);
|
||||
if (reply.type() == QDBusMessage::ReplyMessage &&
|
||||
reply.arguments().count() == 6) {
|
||||
enable = qdbus_cast<bool>(reply.arguments().at(1));
|
||||
keyval1 = qdbus_cast<unsigned int>(reply.arguments().at(2));
|
||||
state1 = qdbus_cast<unsigned int>(reply.arguments().at(3));
|
||||
keyval2 = qdbus_cast<unsigned int>(reply.arguments().at(4));
|
||||
state2 = qdbus_cast<unsigned int>(reply.arguments().at(5));
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
Q_SIGNALS: // SIGNALS
|
||||
};
|
||||
|
||||
} // namespace fcitx
|
||||
|
||||
#endif
|
||||
267
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4watcher.cpp
vendored
Normal file
267
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4watcher.cpp
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2011~2023 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fcitx4watcher.h"
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// utils function in fcitx-utils and fcitx-config
|
||||
bool _pid_exists(pid_t pid) {
|
||||
if (pid <= 0)
|
||||
return 0;
|
||||
return !(kill(pid, 0) && (errno == ESRCH));
|
||||
}
|
||||
|
||||
int displayNumber() {
|
||||
QByteArray display(qgetenv("DISPLAY"));
|
||||
QByteArray displayNumber("0");
|
||||
int pos = display.indexOf(':');
|
||||
|
||||
if (pos >= 0) {
|
||||
++pos;
|
||||
int pos2 = display.indexOf('.', pos);
|
||||
if (pos2 > 0) {
|
||||
displayNumber = display.mid(pos, pos2 - pos);
|
||||
} else {
|
||||
displayNumber = display.mid(pos);
|
||||
}
|
||||
}
|
||||
|
||||
bool ok;
|
||||
int d = displayNumber.toInt(&ok);
|
||||
if (ok) {
|
||||
return d;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString socketFile() {
|
||||
QString filename =
|
||||
QString("%1-%2")
|
||||
.arg(QString::fromLatin1(QDBusConnection::localMachineId()))
|
||||
.arg(displayNumber());
|
||||
|
||||
QString home = QString::fromLocal8Bit(qgetenv("XDG_CONFIG_HOME"));
|
||||
if (home.isEmpty()) {
|
||||
home = QDir::homePath().append(QLatin1String("/.config"));
|
||||
}
|
||||
return QString("%1/fcitx/dbus/%2").arg(home).arg(filename);
|
||||
}
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
QString newUniqueConnectionName() {
|
||||
static int idx = 0;
|
||||
const auto newIdx = idx++;
|
||||
return QString("_fcitx4_%1").arg(newIdx);
|
||||
}
|
||||
|
||||
Fcitx4Watcher::Fcitx4Watcher(QDBusConnection sessionBus, QObject *parent)
|
||||
: QObject(parent), connection_(nullptr), sessionBus_(sessionBus),
|
||||
socketFile_(socketFile()),
|
||||
serviceName_(QString("org.fcitx.Fcitx-%1").arg(displayNumber())),
|
||||
availability_(false), uniqueConnectionName_(newUniqueConnectionName()) {}
|
||||
|
||||
Fcitx4Watcher::~Fcitx4Watcher() {
|
||||
cleanUpConnection();
|
||||
unwatchSocketFile();
|
||||
}
|
||||
|
||||
bool Fcitx4Watcher::availability() const { return availability_; }
|
||||
|
||||
QDBusConnection Fcitx4Watcher::connection() const {
|
||||
if (connection_) {
|
||||
return *connection_;
|
||||
}
|
||||
return sessionBus_;
|
||||
}
|
||||
|
||||
QString Fcitx4Watcher::service() const {
|
||||
if (connection_) {
|
||||
return serviceName_;
|
||||
}
|
||||
if (mainPresent_) {
|
||||
return serviceName_;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void Fcitx4Watcher::setAvailability(bool availability) {
|
||||
if (availability_ != availability) {
|
||||
availability_ = availability;
|
||||
Q_EMIT availabilityChanged(availability_);
|
||||
}
|
||||
}
|
||||
|
||||
void Fcitx4Watcher::watch() {
|
||||
if (watched_) {
|
||||
return;
|
||||
}
|
||||
|
||||
serviceWatcher_ = new QDBusServiceWatcher(this);
|
||||
connect(serviceWatcher_, &QDBusServiceWatcher::serviceOwnerChanged, this,
|
||||
&Fcitx4Watcher::imChanged);
|
||||
serviceWatcher_->setConnection(sessionBus_);
|
||||
serviceWatcher_->addWatchedService(serviceName_);
|
||||
|
||||
if (sessionBus_.interface()->isServiceRegistered(serviceName_)) {
|
||||
mainPresent_ = true;
|
||||
}
|
||||
|
||||
watchSocketFile();
|
||||
createConnection();
|
||||
updateAvailability();
|
||||
watched_ = true;
|
||||
}
|
||||
|
||||
void Fcitx4Watcher::unwatch() {
|
||||
if (!watched_) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete serviceWatcher_;
|
||||
serviceWatcher_ = nullptr;
|
||||
unwatchSocketFile();
|
||||
cleanUpConnection();
|
||||
mainPresent_ = false;
|
||||
watched_ = false;
|
||||
updateAvailability();
|
||||
}
|
||||
|
||||
QString Fcitx4Watcher::address() {
|
||||
QString addr;
|
||||
QByteArray addrVar = qgetenv("FCITX_DBUS_ADDRESS");
|
||||
if (!addrVar.isNull())
|
||||
return QString::fromLocal8Bit(addrVar);
|
||||
|
||||
QFile file(socketFile_);
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
return QString();
|
||||
|
||||
const int BUFSIZE = 1024;
|
||||
|
||||
char buffer[BUFSIZE];
|
||||
size_t sz = file.read(buffer, BUFSIZE);
|
||||
file.close();
|
||||
if (sz == 0)
|
||||
return QString();
|
||||
char *p = buffer;
|
||||
while (*p)
|
||||
p++;
|
||||
size_t addrlen = p - buffer;
|
||||
if (sz != addrlen + 2 * sizeof(pid_t) + 1)
|
||||
return QString();
|
||||
|
||||
/* skip '\0' */
|
||||
p++;
|
||||
pid_t *ppid = (pid_t *)p;
|
||||
pid_t daemonpid = ppid[0];
|
||||
pid_t fcitxpid = ppid[1];
|
||||
|
||||
if (!_pid_exists(daemonpid) || !_pid_exists(fcitxpid))
|
||||
return QString();
|
||||
|
||||
addr = QLatin1String(buffer);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void Fcitx4Watcher::cleanUpConnection() {
|
||||
QDBusConnection::disconnectFromBus(uniqueConnectionName_);
|
||||
delete connection_;
|
||||
connection_ = nullptr;
|
||||
}
|
||||
|
||||
void Fcitx4Watcher::socketFileChanged() {
|
||||
cleanUpConnection();
|
||||
createConnection();
|
||||
}
|
||||
|
||||
void Fcitx4Watcher::createConnection() {
|
||||
QString addr = address();
|
||||
if (!addr.isNull()) {
|
||||
QDBusConnection connection(
|
||||
QDBusConnection::connectToBus(addr, uniqueConnectionName_));
|
||||
if (connection.isConnected()) {
|
||||
connection_ = new QDBusConnection(connection);
|
||||
} else {
|
||||
QDBusConnection::disconnectFromBus(uniqueConnectionName_);
|
||||
}
|
||||
}
|
||||
|
||||
if (connection_) {
|
||||
connection_->connect("org.freedesktop.DBus.Local",
|
||||
"/org/freedesktop/DBus/Local",
|
||||
"org.freedesktop.DBus.Local", "Disconnected", this,
|
||||
SLOT(dbusDisconnected()));
|
||||
unwatchSocketFile();
|
||||
}
|
||||
updateAvailability();
|
||||
}
|
||||
|
||||
void Fcitx4Watcher::dbusDisconnected() {
|
||||
cleanUpConnection();
|
||||
watchSocketFile();
|
||||
// Try recreation immediately to avoid race.
|
||||
createConnection();
|
||||
}
|
||||
|
||||
void Fcitx4Watcher::watchSocketFile() {
|
||||
if (socketFile_.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QFileInfo info(socketFile_);
|
||||
QDir dir(info.path());
|
||||
if (!dir.exists()) {
|
||||
QDir rt(QDir::root());
|
||||
rt.mkpath(info.path());
|
||||
}
|
||||
fsWatcher_ = new QFileSystemWatcher(this);
|
||||
fsWatcher_->addPath(info.path());
|
||||
if (info.exists()) {
|
||||
fsWatcher_->addPath(info.filePath());
|
||||
}
|
||||
|
||||
connect(fsWatcher_, &QFileSystemWatcher::fileChanged, this,
|
||||
&Fcitx4Watcher::socketFileChanged);
|
||||
connect(fsWatcher_, &QFileSystemWatcher::directoryChanged, this,
|
||||
&Fcitx4Watcher::socketFileChanged);
|
||||
}
|
||||
|
||||
void Fcitx4Watcher::unwatchSocketFile() {
|
||||
if (fsWatcher_) {
|
||||
fsWatcher_->disconnect(this);
|
||||
fsWatcher_->deleteLater();
|
||||
fsWatcher_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Fcitx4Watcher::imChanged(const QString &service, const QString &,
|
||||
const QString &newOwner) {
|
||||
if (service == serviceName_) {
|
||||
if (!newOwner.isEmpty()) {
|
||||
mainPresent_ = true;
|
||||
} else {
|
||||
mainPresent_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
updateAvailability();
|
||||
}
|
||||
|
||||
void Fcitx4Watcher::updateAvailability() {
|
||||
setAvailability(mainPresent_ || connection_);
|
||||
}
|
||||
|
||||
} // namespace fcitx
|
||||
68
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4watcher.h
vendored
Normal file
68
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx4watcher.h
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2011~2023 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FCITXWATCHER_H_
|
||||
#define FCITXWATCHER_H_
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QObject>
|
||||
|
||||
class QFileSystemWatcher;
|
||||
class QDBusServiceWatcher;
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
// A FcitxQtConnection replacement, to implement compatibility with fcitx 5.
|
||||
// Since we have three thing to monitor, the situation becomes much more
|
||||
// complexer.
|
||||
class Fcitx4Watcher : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Fcitx4Watcher(QDBusConnection sessionBus,
|
||||
QObject *parent = nullptr);
|
||||
~Fcitx4Watcher();
|
||||
void watch();
|
||||
void unwatch();
|
||||
|
||||
bool availability() const;
|
||||
|
||||
QDBusConnection connection() const;
|
||||
QString service() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void availabilityChanged(bool);
|
||||
|
||||
private Q_SLOTS:
|
||||
void dbusDisconnected();
|
||||
void socketFileChanged();
|
||||
void imChanged(const QString &service, const QString &oldOwner,
|
||||
const QString &newOwner);
|
||||
|
||||
private:
|
||||
QString address();
|
||||
void watchSocketFile();
|
||||
void unwatchSocketFile();
|
||||
void createConnection();
|
||||
void cleanUpConnection();
|
||||
void setAvailability(bool availability);
|
||||
void updateAvailability();
|
||||
|
||||
QFileSystemWatcher *fsWatcher_ = nullptr;
|
||||
QDBusServiceWatcher *serviceWatcher_ = nullptr;
|
||||
QDBusConnection *connection_;
|
||||
QDBusConnection sessionBus_;
|
||||
QString socketFile_;
|
||||
QString serviceName_;
|
||||
bool availability_ = false;
|
||||
bool mainPresent_ = false;
|
||||
bool watched_ = false;
|
||||
QString uniqueConnectionName_;
|
||||
};
|
||||
|
||||
} // namespace fcitx
|
||||
|
||||
#endif // FCITXWATCHER_H_
|
||||
6
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx5.json.in
vendored
Normal file
6
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitx5.json.in
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"Keys": [
|
||||
@FCITX5_QT_EXTRA_PLUGIN_NAME@
|
||||
"fcitx5"
|
||||
]
|
||||
}
|
||||
791
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitxcandidatewindow.cpp
vendored
Normal file
791
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitxcandidatewindow.cpp
vendored
Normal file
@@ -0,0 +1,791 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021~2021 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
#include "fcitxcandidatewindow.h"
|
||||
#include "fcitxflags.h"
|
||||
#include "fcitxtheme.h"
|
||||
#include "qfcitxplatforminputcontext.h"
|
||||
#include <QDebug>
|
||||
#include <QExposeEvent>
|
||||
#include <QFont>
|
||||
#include <QGuiApplication>
|
||||
#include <QMouseEvent>
|
||||
#include <QPalette>
|
||||
#include <QResizeEvent>
|
||||
#include <QScreen>
|
||||
#include <QTextLayout>
|
||||
#include <QVariant>
|
||||
#include <QtMath>
|
||||
#include <utility>
|
||||
|
||||
#if defined(FCITX_ENABLE_QT6_WAYLAND_WORKAROUND) && \
|
||||
QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
|
||||
#include <QtGui/private/qhighdpiscaling_p.h>
|
||||
#include <QtWaylandClient/private/qwayland-xdg-shell.h>
|
||||
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
|
||||
#include <QtWaylandClient/private/qwaylandintegration_p.h>
|
||||
#include <QtWaylandClient/private/qwaylandwindow_p.h>
|
||||
#include <QtWaylandClient/private/wayland-xdg-shell-client-protocol.h>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#endif
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(FCITX_ENABLE_QT6_WAYLAND_WORKAROUND) && \
|
||||
QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
|
||||
class XdgWmBase : public QtWayland::xdg_wm_base {
|
||||
public:
|
||||
using xdg_wm_base::xdg_wm_base;
|
||||
|
||||
protected:
|
||||
// This is required for all xdg_wm_base bind.
|
||||
void xdg_wm_base_ping(uint32_t serial) override { pong(serial); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void doLayout(QTextLayout &layout) {
|
||||
QFontMetrics fontMetrics(layout.font());
|
||||
auto minH = fontMetrics.ascent() + fontMetrics.descent();
|
||||
layout.setCacheEnabled(true);
|
||||
layout.beginLayout();
|
||||
int height = 0;
|
||||
while (1) {
|
||||
QTextLine line = layout.createLine();
|
||||
if (!line.isValid())
|
||||
break;
|
||||
|
||||
line.setLineWidth(INT_MAX);
|
||||
line.setLeadingIncluded(true);
|
||||
|
||||
line.setPosition(
|
||||
QPoint(0, height - line.ascent() + fontMetrics.ascent()));
|
||||
height += minH;
|
||||
}
|
||||
layout.endLayout();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class MultilineText {
|
||||
public:
|
||||
MultilineText(const QFont &font, const QString &text) {
|
||||
QStringList lines = text.split("\n");
|
||||
int width = 0;
|
||||
QFontMetrics fontMetrics(font);
|
||||
fontHeight_ = fontMetrics.ascent() + fontMetrics.descent();
|
||||
for (const auto &line : lines) {
|
||||
layouts_.emplace_back(std::make_unique<QTextLayout>(line));
|
||||
layouts_.back()->setFont(font);
|
||||
doLayout(*layouts_.back());
|
||||
width = std::max(width,
|
||||
layouts_.back()->boundingRect().toRect().width());
|
||||
}
|
||||
boundingRect_.setTopLeft(QPoint(0, 0));
|
||||
boundingRect_.setSize(QSize(width, lines.size() * fontHeight_));
|
||||
}
|
||||
|
||||
bool isEmpty() const { return layouts_.empty(); }
|
||||
|
||||
void draw(QPainter *painter, QColor color, QPoint position) {
|
||||
painter->save();
|
||||
painter->setPen(color);
|
||||
int currentY = 0;
|
||||
for (const auto &layout : layouts_) {
|
||||
layout->draw(painter, position + QPoint(0, currentY));
|
||||
currentY += fontHeight_;
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QRect boundingRect() { return boundingRect_; }
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<QTextLayout>> layouts_;
|
||||
int fontHeight_;
|
||||
QRect boundingRect_;
|
||||
};
|
||||
|
||||
FcitxCandidateWindow::FcitxCandidateWindow(QWindow *window,
|
||||
QFcitxPlatformInputContext *context)
|
||||
: QRasterWindow(), context_(context), theme_(context->theme()),
|
||||
parent_(window) {
|
||||
constexpr Qt::WindowFlags commonFlags = Qt::FramelessWindowHint |
|
||||
Qt::WindowDoesNotAcceptFocus |
|
||||
Qt::NoDropShadowWindowHint;
|
||||
if (isWayland_) {
|
||||
// Qt::ToolTip ensures wayland doesn't grab focus.
|
||||
// Not using Qt::BypassWindowManagerHint ensures wayland handle
|
||||
// fractional scale.
|
||||
setFlags(Qt::ToolTip | commonFlags);
|
||||
#if defined(FCITX_ENABLE_QT6_WAYLAND_WORKAROUND) && \
|
||||
QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
|
||||
if (auto instance = QtWaylandClient::QWaylandIntegration::instance()) {
|
||||
for (QtWaylandClient::QWaylandDisplay::RegistryGlobal global :
|
||||
instance->display()->globals()) {
|
||||
if (global.interface == QLatin1String("xdg_wm_base")) {
|
||||
xdgWmBase_.reset(
|
||||
new XdgWmBase(instance->display()->wl_registry(),
|
||||
global.id, global.version));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
setProperty("_q_waylandPopupAnchor",
|
||||
QVariant::fromValue(Qt::BottomEdge | Qt::LeftEdge));
|
||||
setProperty("_q_waylandPopupGravity",
|
||||
QVariant::fromValue(Qt::BottomEdge | Qt::RightEdge));
|
||||
setProperty(
|
||||
"_q_waylandPopupConstraintAdjustment",
|
||||
static_cast<unsigned int>(
|
||||
QtWayland::xdg_positioner::constraint_adjustment_slide_x |
|
||||
QtWayland::xdg_positioner::constraint_adjustment_flip_y));
|
||||
#endif
|
||||
} else {
|
||||
// Qt::Popup ensures X11 doesn't apply tooltip animation under kwin.
|
||||
setFlags(Qt::Popup | Qt::BypassWindowManagerHint | commonFlags);
|
||||
}
|
||||
if (isWayland_) {
|
||||
setTransientParent(parent_);
|
||||
}
|
||||
QSurfaceFormat surfaceFormat = format();
|
||||
surfaceFormat.setAlphaBufferSize(8);
|
||||
setFormat(surfaceFormat);
|
||||
connect(this, &QWindow::visibleChanged, this, [this] { hoverIndex_ = -1; });
|
||||
}
|
||||
|
||||
FcitxCandidateWindow::~FcitxCandidateWindow() {}
|
||||
|
||||
bool FcitxCandidateWindow::event(QEvent *event) {
|
||||
if (event->type() == QEvent::Leave) {
|
||||
auto oldHighlight = highlight();
|
||||
hoverIndex_ = -1;
|
||||
if (highlight() != oldHighlight) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
return QRasterWindow::event(event);
|
||||
}
|
||||
|
||||
void FcitxCandidateWindow::render(QPainter *painter) {
|
||||
theme_->paint(painter, theme_->background(),
|
||||
QRect(QPoint(0, 0), actualSize_));
|
||||
auto contentMargin = theme_->contentMargin();
|
||||
|
||||
const QPoint topLeft(contentMargin.left(), contentMargin.top());
|
||||
painter->setPen(theme_->normalColor());
|
||||
auto minH =
|
||||
theme_->fontMetrics().ascent() + theme_->fontMetrics().descent();
|
||||
auto textMargin = theme_->textMargin();
|
||||
auto extraW = textMargin.left() + textMargin.right();
|
||||
auto extraH = textMargin.top() + textMargin.bottom();
|
||||
size_t currentHeight = 0;
|
||||
if (!upperLayout_.text().isEmpty()) {
|
||||
upperLayout_.draw(
|
||||
painter, topLeft + QPoint(textMargin.left(), textMargin.top()));
|
||||
// Draw cursor
|
||||
currentHeight += minH + extraH;
|
||||
if (cursor_ >= 0) {
|
||||
auto line = upperLayout_.lineForTextPosition(cursor_);
|
||||
if (line.isValid()) {
|
||||
int cursorX = line.cursorToX(cursor_);
|
||||
line.lineNumber();
|
||||
painter->save();
|
||||
QPen pen = painter->pen();
|
||||
pen.setWidth(2);
|
||||
painter->setPen(pen);
|
||||
QPoint start = topLeft + QPoint(textMargin.left() + cursorX + 1,
|
||||
textMargin.top() +
|
||||
line.lineNumber() * minH);
|
||||
painter->drawLine(start, start + QPoint(0, minH));
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!lowerLayout_.text().isEmpty()) {
|
||||
lowerLayout_.draw(painter,
|
||||
topLeft + QPoint(textMargin.left(),
|
||||
textMargin.top() + currentHeight));
|
||||
currentHeight += minH + extraH;
|
||||
}
|
||||
|
||||
bool vertical = theme_->vertical();
|
||||
if (layoutHint_ == FcitxCandidateLayoutHint::Vertical) {
|
||||
vertical = true;
|
||||
} else if (layoutHint_ == FcitxCandidateLayoutHint::Horizontal) {
|
||||
vertical = false;
|
||||
}
|
||||
|
||||
candidateRegions_.clear();
|
||||
candidateRegions_.reserve(labelLayouts_.size());
|
||||
size_t wholeW = 0, wholeH = 0;
|
||||
|
||||
// size of text = textMargin + actual text size.
|
||||
// HighLight = HighLight margin + TEXT.
|
||||
// Click region = HighLight - click
|
||||
|
||||
for (size_t i = 0; i < labelLayouts_.size(); i++) {
|
||||
int x, y;
|
||||
if (vertical) {
|
||||
x = 0;
|
||||
y = currentHeight + wholeH;
|
||||
} else {
|
||||
x = wholeW;
|
||||
y = currentHeight;
|
||||
}
|
||||
x += textMargin.left();
|
||||
y += textMargin.top();
|
||||
int labelW = 0, labelH = 0, candidateW = 0, candidateH = 0;
|
||||
if (!labelLayouts_[i]->isEmpty()) {
|
||||
auto size = labelLayouts_[i]->boundingRect();
|
||||
labelW = size.width();
|
||||
labelH = size.height();
|
||||
}
|
||||
if (!candidateLayouts_[i]->isEmpty()) {
|
||||
auto size = candidateLayouts_[i]->boundingRect();
|
||||
candidateW = size.width();
|
||||
candidateH = size.height();
|
||||
}
|
||||
int vheight;
|
||||
if (vertical) {
|
||||
vheight = std::max({minH, labelH, candidateH});
|
||||
wholeH += vheight + extraH;
|
||||
} else {
|
||||
vheight = candidatesHeight_ - extraH;
|
||||
wholeW += candidateW + labelW + extraW;
|
||||
}
|
||||
QMargins highlightMargin = theme_->highlightMargin();
|
||||
QMargins clickMargin = theme_->highlightClickMargin();
|
||||
auto highlightWidth = labelW + candidateW;
|
||||
bool fullWidthHighlight = true;
|
||||
if (fullWidthHighlight && vertical) {
|
||||
// Last candidate, fill.
|
||||
highlightWidth = actualSize_.width() - contentMargin.left() -
|
||||
contentMargin.right() - textMargin.left() -
|
||||
textMargin.right();
|
||||
}
|
||||
const int highlightIndex = highlight();
|
||||
QColor color = theme_->normalColor();
|
||||
if (highlightIndex >= 0 && i == static_cast<size_t>(highlightIndex)) {
|
||||
// Paint highlight
|
||||
theme_->paint(
|
||||
painter, theme_->highlight(),
|
||||
QRect(topLeft + QPoint(x, y) -
|
||||
QPoint(highlightMargin.left(), highlightMargin.top()),
|
||||
QSize(highlightWidth + highlightMargin.left() +
|
||||
highlightMargin.right(),
|
||||
vheight + highlightMargin.top() +
|
||||
highlightMargin.bottom())));
|
||||
color = theme_->highlightCandidateColor();
|
||||
}
|
||||
QRect candidateRegion(
|
||||
topLeft + QPoint(x, y) -
|
||||
QPoint(highlightMargin.left(), highlightMargin.right()) +
|
||||
QPoint(clickMargin.left(), clickMargin.right()),
|
||||
QSize(highlightWidth + highlightMargin.left() +
|
||||
highlightMargin.right() - clickMargin.left() -
|
||||
clickMargin.right(),
|
||||
vheight + highlightMargin.top() + highlightMargin.bottom() -
|
||||
clickMargin.top() - clickMargin.bottom()));
|
||||
candidateRegions_.push_back(candidateRegion);
|
||||
if (!labelLayouts_[i]->isEmpty()) {
|
||||
labelLayouts_[i]->draw(painter, color, topLeft + QPoint(x, y));
|
||||
}
|
||||
if (!candidateLayouts_[i]->isEmpty()) {
|
||||
candidateLayouts_[i]->draw(painter, color,
|
||||
topLeft + QPoint(x + labelW, y));
|
||||
}
|
||||
}
|
||||
prevRegion_ = QRect();
|
||||
nextRegion_ = QRect();
|
||||
if (labelLayouts_.size() && (hasPrev_ || hasNext_)) {
|
||||
if (theme_->prev().valid() && theme_->next().valid()) {
|
||||
int prevY = 0, nextY = 0;
|
||||
if (theme_->buttonAlignment() == "Top") {
|
||||
prevY = contentMargin.top();
|
||||
nextY = contentMargin.top();
|
||||
} else if (theme_->buttonAlignment() == "First Candidate") {
|
||||
prevY = candidateRegions_.front().top() +
|
||||
(candidateRegions_.front().height() -
|
||||
theme_->prev().height()) /
|
||||
2.0;
|
||||
nextY = candidateRegions_.front().top() +
|
||||
(candidateRegions_.front().height() -
|
||||
theme_->next().height()) /
|
||||
2.0;
|
||||
} else if (theme_->buttonAlignment() == "Center") {
|
||||
prevY = contentMargin.top() +
|
||||
(actualSize_.height() - contentMargin.top() -
|
||||
contentMargin.bottom() - theme_->prev().height()) /
|
||||
2.0;
|
||||
nextY = contentMargin.top() +
|
||||
(actualSize_.height() - contentMargin.top() -
|
||||
contentMargin.bottom() - theme_->next().height()) /
|
||||
2.0;
|
||||
} else if (theme_->buttonAlignment() == "Last Candidate") {
|
||||
prevY = candidateRegions_.back().top() +
|
||||
(candidateRegions_.back().height() -
|
||||
theme_->prev().height()) /
|
||||
2.0;
|
||||
nextY = candidateRegions_.back().top() +
|
||||
(candidateRegions_.back().height() -
|
||||
theme_->next().height()) /
|
||||
2.0;
|
||||
} else {
|
||||
prevY = actualSize_.height() - contentMargin.bottom() -
|
||||
theme_->prev().height();
|
||||
nextY = actualSize_.height() - contentMargin.bottom() -
|
||||
theme_->next().height();
|
||||
}
|
||||
nextRegion_ =
|
||||
QRect(QPoint(actualSize_.width() - contentMargin.right() -
|
||||
theme_->prev().width(),
|
||||
nextY),
|
||||
theme_->next().size());
|
||||
double alpha = 1.0;
|
||||
if (!hasNext_) {
|
||||
alpha = 0.3;
|
||||
} else if (nextHovered_) {
|
||||
alpha = 0.7;
|
||||
}
|
||||
theme_->paint(painter, theme_->next(), nextRegion_.topLeft(),
|
||||
alpha);
|
||||
nextRegion_ = nextRegion_.marginsRemoved(theme_->next().margin());
|
||||
prevRegion_ = QRect(
|
||||
QPoint(actualSize_.width() - contentMargin.right() -
|
||||
theme_->next().width() - theme_->prev().width(),
|
||||
prevY),
|
||||
theme_->prev().size());
|
||||
alpha = 1.0;
|
||||
if (!hasPrev_) {
|
||||
alpha = 0.3;
|
||||
} else if (prevHovered_) {
|
||||
alpha = 0.7;
|
||||
}
|
||||
theme_->paint(painter, theme_->prev(), prevRegion_.topLeft(),
|
||||
alpha);
|
||||
prevRegion_ = prevRegion_.marginsRemoved(theme_->prev().margin());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateLayout(QTextLayout &layout, const FcitxTheme &theme,
|
||||
std::initializer_list<
|
||||
std::reference_wrapper<const FcitxQtFormattedPreeditList>>
|
||||
texts) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
|
||||
layout.clearFormats();
|
||||
#endif
|
||||
layout.setFont(theme.font());
|
||||
QVector<QTextLayout::FormatRange> formats;
|
||||
QString str;
|
||||
int pos = 0;
|
||||
for (const auto &text : texts) {
|
||||
for (const auto &preedit : text.get()) {
|
||||
str += preedit.string();
|
||||
QTextCharFormat format;
|
||||
if (preedit.format() & FcitxTextFormatFlag_Underline) {
|
||||
format.setUnderlineStyle(QTextCharFormat::DashUnderline);
|
||||
}
|
||||
if (preedit.format() & FcitxTextFormatFlag_Strike) {
|
||||
format.setFontStrikeOut(true);
|
||||
}
|
||||
if (preedit.format() & FcitxTextFormatFlag_Bold) {
|
||||
format.setFontWeight(QFont::Bold);
|
||||
}
|
||||
if (preedit.format() & FcitxTextFormatFlag_Italic) {
|
||||
format.setFontItalic(true);
|
||||
}
|
||||
if (preedit.format() & FcitxTextFormatFlag_HighLight) {
|
||||
format.setBackground(theme.highlightBackgroundColor());
|
||||
format.setForeground(theme.highlightColor());
|
||||
}
|
||||
formats.append(QTextLayout::FormatRange{
|
||||
pos, static_cast<int>(preedit.string().length()), format});
|
||||
pos += preedit.string().length();
|
||||
}
|
||||
}
|
||||
layout.setText(str);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
|
||||
layout.setFormats(formats);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FcitxCandidateWindow::updateClientSideUI(
|
||||
const FcitxQtFormattedPreeditList &preedit, int cursorpos,
|
||||
const FcitxQtFormattedPreeditList &auxUp,
|
||||
const FcitxQtFormattedPreeditList &auxDown,
|
||||
const FcitxQtStringKeyValueList &candidates, int candidateIndex,
|
||||
int layoutHint, bool hasPrev, bool hasNext) {
|
||||
bool preeditVisible = !preedit.isEmpty();
|
||||
bool auxUpVisbile = !auxUp.isEmpty();
|
||||
bool auxDownVisible = !auxDown.isEmpty();
|
||||
bool candidatesVisible = !candidates.isEmpty();
|
||||
bool visible =
|
||||
preeditVisible || auxUpVisbile || auxDownVisible || candidatesVisible;
|
||||
auto window = context_->focusWindowWrapper();
|
||||
if (!theme_ || !visible || !window || window != parent_) {
|
||||
hide();
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateLayout(upperLayout_, *theme_, {auxUp, preedit});
|
||||
if (cursorpos >= 0) {
|
||||
int auxUpLength = 0;
|
||||
for (const auto &auxUpText : auxUp) {
|
||||
auxUpLength += auxUpText.string().length();
|
||||
}
|
||||
// Get the preedit part
|
||||
auto preeditString = upperLayout_.text().mid(auxUpLength).toUtf8();
|
||||
preeditString = preeditString.mid(0, cursorpos);
|
||||
cursor_ = auxUpLength + QString::fromUtf8(preeditString).length();
|
||||
} else {
|
||||
cursor_ = -1;
|
||||
}
|
||||
doLayout(upperLayout_);
|
||||
UpdateLayout(lowerLayout_, *theme_, {auxDown});
|
||||
doLayout(lowerLayout_);
|
||||
labelLayouts_.clear();
|
||||
candidateLayouts_.clear();
|
||||
for (int i = 0; i < candidates.size(); i++) {
|
||||
labelLayouts_.emplace_back(std::make_unique<MultilineText>(
|
||||
theme_->font(), candidates[i].key()));
|
||||
candidateLayouts_.emplace_back(std::make_unique<MultilineText>(
|
||||
theme_->font(), candidates[i].value()));
|
||||
}
|
||||
highlight_ = candidateIndex;
|
||||
hasPrev_ = hasPrev;
|
||||
hasNext_ = hasNext;
|
||||
layoutHint_ = static_cast<FcitxCandidateLayoutHint>(layoutHint);
|
||||
|
||||
actualSize_ = sizeHint();
|
||||
|
||||
if (actualSize_.width() <= 0 || actualSize_.height() <= 0) {
|
||||
hide();
|
||||
return;
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QSize sizeWithoutShadow = actualSize_.shrunkBy(theme_->shadowMargin());
|
||||
#else
|
||||
QSize sizeWithoutShadow =
|
||||
actualSize_ -
|
||||
QSize(theme_->shadowMargin().left() + theme_->shadowMargin().right(),
|
||||
theme_->shadowMargin().top() + theme_->shadowMargin().bottom());
|
||||
#endif
|
||||
if (sizeWithoutShadow.width() < 0) {
|
||||
sizeWithoutShadow.setWidth(0);
|
||||
}
|
||||
if (sizeWithoutShadow.height() < 0) {
|
||||
sizeWithoutShadow.setHeight(0);
|
||||
}
|
||||
|
||||
if (size() != actualSize_) {
|
||||
resize(actualSize_);
|
||||
}
|
||||
update();
|
||||
|
||||
QRect cursorRect = context_->cursorRectangleWrapper();
|
||||
QRect screenGeometry;
|
||||
|
||||
#if defined(FCITX_ENABLE_QT6_WAYLAND_WORKAROUND) && \
|
||||
QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
|
||||
if (isWayland_) {
|
||||
auto *waylandWindow =
|
||||
static_cast<QtWaylandClient::QWaylandWindow *>(window->handle());
|
||||
const auto windowMargins = waylandWindow->windowContentMargins() -
|
||||
waylandWindow->clientSideMargins();
|
||||
auto windowGeometry = waylandWindow->windowContentGeometry();
|
||||
if (!cursorRect.isValid()) {
|
||||
if (cursorRect.width() <= 0) {
|
||||
cursorRect.setWidth(1);
|
||||
}
|
||||
if (cursorRect.height() <= 0) {
|
||||
cursorRect.setHeight(1);
|
||||
}
|
||||
}
|
||||
QRect nativeCursorRect = QHighDpi::toNativePixels(cursorRect, this);
|
||||
// valid the anchor rect.
|
||||
if (!nativeCursorRect.intersects(windowGeometry)) {
|
||||
if (nativeCursorRect.right() < windowGeometry.left()) {
|
||||
nativeCursorRect.setLeft(windowGeometry.left());
|
||||
nativeCursorRect.setWidth(1);
|
||||
}
|
||||
if (nativeCursorRect.left() > windowGeometry.right()) {
|
||||
nativeCursorRect.setLeft(windowGeometry.right());
|
||||
nativeCursorRect.setWidth(1);
|
||||
}
|
||||
if (nativeCursorRect.bottom() < windowGeometry.top()) {
|
||||
nativeCursorRect.setTop(windowGeometry.top());
|
||||
nativeCursorRect.setHeight(1);
|
||||
}
|
||||
if (nativeCursorRect.top() > windowGeometry.bottom()) {
|
||||
nativeCursorRect.setTop(windowGeometry.bottom());
|
||||
nativeCursorRect.setHeight(1);
|
||||
}
|
||||
}
|
||||
bool wasVisible = isVisible();
|
||||
bool cursorRectChanged = false;
|
||||
if (property("_q_waylandPopupAnchorRect") != nativeCursorRect) {
|
||||
cursorRectChanged = true;
|
||||
setProperty("_q_waylandPopupAnchorRect", nativeCursorRect);
|
||||
}
|
||||
// This try to ensure xdg_popup is available.
|
||||
show();
|
||||
xdg_popup *xdgPopup = static_cast<xdg_popup *>(
|
||||
QGuiApplication::platformNativeInterface()->nativeResourceForWindow(
|
||||
"xdg_popup", this));
|
||||
if (xdgWmBase_ && xdgPopup &&
|
||||
xdg_popup_get_version(xdgPopup) >=
|
||||
XDG_POPUP_REPOSITION_SINCE_VERSION) {
|
||||
nativeCursorRect.translate(-windowMargins.left(),
|
||||
-windowMargins.top());
|
||||
auto *positioner =
|
||||
new QtWayland::xdg_positioner(xdgWmBase_->create_positioner());
|
||||
positioner->set_anchor_rect(
|
||||
nativeCursorRect.x(), nativeCursorRect.y(),
|
||||
nativeCursorRect.width(), nativeCursorRect.height());
|
||||
positioner->set_anchor(
|
||||
QtWayland::xdg_positioner::anchor_bottom_left);
|
||||
positioner->set_gravity(
|
||||
QtWayland::xdg_positioner::gravity_bottom_right);
|
||||
|
||||
auto *waylandCandidateWindow =
|
||||
static_cast<QtWaylandClient::QWaylandWindow *>(handle());
|
||||
QRect nativeGeometry =
|
||||
waylandCandidateWindow->windowContentGeometry();
|
||||
positioner->set_size(nativeGeometry.width(),
|
||||
nativeGeometry.height());
|
||||
positioner->set_reactive();
|
||||
positioner->set_constraint_adjustment(
|
||||
QtWayland::xdg_positioner::constraint_adjustment_slide_x |
|
||||
QtWayland::xdg_positioner::constraint_adjustment_flip_y);
|
||||
xdg_popup_reposition(xdgPopup, positioner->object(),
|
||||
repositionToken_++);
|
||||
positioner->destroy();
|
||||
return;
|
||||
}
|
||||
// Check if we need remap.
|
||||
// If it was invisible, nothing need to be done.
|
||||
// If cursor rect changed, the window must be remapped.
|
||||
// If adjustment is already happening (flip/slide), then remap.
|
||||
// If we predict adjustment may be happening, then remap.
|
||||
const auto predictGeometry =
|
||||
QRect(QPoint(cursorRect.x(), cursorRect.y() + cursorRect.height()),
|
||||
actualSize_);
|
||||
|
||||
if (wasVisible &&
|
||||
(cursorRectChanged || position() != predictGeometry.topLeft() ||
|
||||
!windowGeometry.contains(predictGeometry))) {
|
||||
hide();
|
||||
show();
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// Try to apply the screen edge detection over the window, because if we
|
||||
// intent to use this with wayland. It we have no information above screen
|
||||
// edge.
|
||||
if (isWayland_) {
|
||||
screenGeometry = window->frameGeometry();
|
||||
cursorRect.translate(window->framePosition());
|
||||
auto margins = window->frameMargins();
|
||||
cursorRect.translate(margins.left(), margins.top());
|
||||
} else {
|
||||
screenGeometry = window->screen()->geometry();
|
||||
auto pos = window->mapToGlobal(cursorRect.topLeft());
|
||||
cursorRect.moveTo(pos);
|
||||
}
|
||||
|
||||
int x = cursorRect.left();
|
||||
int y = cursorRect.bottom();
|
||||
if (cursorRect.left() + sizeWithoutShadow.width() >
|
||||
screenGeometry.right()) {
|
||||
x = screenGeometry.right() - sizeWithoutShadow.width() + 1;
|
||||
}
|
||||
|
||||
if (x < screenGeometry.left()) {
|
||||
x = screenGeometry.left();
|
||||
}
|
||||
|
||||
if (y + sizeWithoutShadow.height() > screenGeometry.bottom()) {
|
||||
if (y > screenGeometry.bottom()) {
|
||||
y = screenGeometry.bottom() - sizeWithoutShadow.height() - 40;
|
||||
} else { /* better position the window */
|
||||
y = y - sizeWithoutShadow.height() -
|
||||
((cursorRect.height() == 0) ? 40 : cursorRect.height());
|
||||
}
|
||||
}
|
||||
|
||||
if (y < screenGeometry.top()) {
|
||||
y = screenGeometry.top();
|
||||
}
|
||||
|
||||
QPoint newPosition(x, y);
|
||||
newPosition -=
|
||||
QPoint(theme_->shadowMargin().left(), theme_->shadowMargin().top());
|
||||
if (newPosition != position()) {
|
||||
if (isWayland_ && isVisible()) {
|
||||
hide();
|
||||
}
|
||||
setPosition(newPosition);
|
||||
}
|
||||
show();
|
||||
}
|
||||
|
||||
void FcitxCandidateWindow::mouseMoveEvent(QMouseEvent *event) {
|
||||
bool needRepaint = false;
|
||||
|
||||
bool prevHovered = false;
|
||||
bool nextHovered = false;
|
||||
auto oldHighlight = highlight();
|
||||
hoverIndex_ = -1;
|
||||
|
||||
prevHovered = prevRegion_.contains(event->pos());
|
||||
if (!prevHovered) {
|
||||
nextHovered = nextRegion_.contains(event->pos());
|
||||
if (!nextHovered) {
|
||||
for (int idx = 0, e = candidateRegions_.size(); idx < e; idx++) {
|
||||
if (candidateRegions_[idx].contains(event->pos())) {
|
||||
hoverIndex_ = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
needRepaint = needRepaint || prevHovered_ != prevHovered;
|
||||
prevHovered_ = prevHovered;
|
||||
|
||||
needRepaint = needRepaint || nextHovered_ != nextHovered;
|
||||
nextHovered_ = nextHovered;
|
||||
|
||||
needRepaint = needRepaint || oldHighlight != highlight();
|
||||
if (needRepaint) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void FcitxCandidateWindow::mouseReleaseEvent(QMouseEvent *event) {
|
||||
if (event->button() != Qt::LeftButton) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (prevRegion_.contains(event->pos())) {
|
||||
Q_EMIT prevClicked();
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextRegion_.contains(event->pos())) {
|
||||
Q_EMIT nextClicked();
|
||||
return;
|
||||
}
|
||||
|
||||
for (int idx = 0, e = candidateRegions_.size(); idx < e; idx++) {
|
||||
if (candidateRegions_[idx].contains(event->pos())) {
|
||||
Q_EMIT candidateSelected(idx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSize FcitxCandidateWindow::sizeHint() {
|
||||
auto minH =
|
||||
theme_->fontMetrics().ascent() + theme_->fontMetrics().descent();
|
||||
|
||||
size_t width = 0;
|
||||
size_t height = 0;
|
||||
auto updateIfLarger = [](size_t &m, size_t n) {
|
||||
if (n > m) {
|
||||
m = n;
|
||||
}
|
||||
};
|
||||
auto textMargin = theme_->textMargin();
|
||||
auto extraW = textMargin.left() + textMargin.right();
|
||||
auto extraH = textMargin.top() + textMargin.bottom();
|
||||
if (!upperLayout_.text().isEmpty()) {
|
||||
auto size = upperLayout_.boundingRect();
|
||||
height += minH + extraH;
|
||||
updateIfLarger(width, size.width() + extraW);
|
||||
}
|
||||
if (!lowerLayout_.text().isEmpty()) {
|
||||
auto size = lowerLayout_.boundingRect();
|
||||
height += minH + extraH;
|
||||
updateIfLarger(width, size.width() + extraW);
|
||||
}
|
||||
|
||||
bool vertical = theme_->vertical();
|
||||
if (layoutHint_ == FcitxCandidateLayoutHint::Vertical) {
|
||||
vertical = true;
|
||||
} else if (layoutHint_ == FcitxCandidateLayoutHint::Horizontal) {
|
||||
vertical = false;
|
||||
}
|
||||
|
||||
size_t wholeH = 0, wholeW = 0;
|
||||
for (size_t i = 0; i < labelLayouts_.size(); i++) {
|
||||
size_t candidateW = 0, candidateH = 0;
|
||||
if (!labelLayouts_[i]->isEmpty()) {
|
||||
auto size = labelLayouts_[i]->boundingRect();
|
||||
candidateW += size.width();
|
||||
updateIfLarger(candidateH,
|
||||
std::max(minH, qCeil(size.height())) + extraH);
|
||||
}
|
||||
if (!candidateLayouts_[i]->isEmpty()) {
|
||||
auto size = candidateLayouts_[i]->boundingRect();
|
||||
candidateW += size.width();
|
||||
updateIfLarger(candidateH,
|
||||
std::max(minH, qCeil(size.height())) + extraH);
|
||||
}
|
||||
candidateW += extraW;
|
||||
|
||||
if (vertical) {
|
||||
wholeH += candidateH;
|
||||
updateIfLarger(wholeW, candidateW);
|
||||
} else {
|
||||
wholeW += candidateW;
|
||||
updateIfLarger(wholeH, candidateH);
|
||||
}
|
||||
}
|
||||
updateIfLarger(width, wholeW);
|
||||
candidatesHeight_ = wholeH;
|
||||
height += wholeH;
|
||||
|
||||
auto contentMargin = theme_->contentMargin();
|
||||
width += contentMargin.left() + contentMargin.right();
|
||||
height += contentMargin.top() + contentMargin.bottom();
|
||||
|
||||
if (!labelLayouts_.empty() && (hasPrev_ || hasNext_)) {
|
||||
if (theme_->prev().valid() && theme_->next().valid()) {
|
||||
width += theme_->prev().width() + theme_->next().width();
|
||||
}
|
||||
}
|
||||
|
||||
return {static_cast<int>(width), static_cast<int>(height)};
|
||||
}
|
||||
|
||||
void FcitxCandidateWindow::wheelEvent(QWheelEvent *event) {
|
||||
if (!theme_ || !theme_->wheelForPaging()) {
|
||||
return;
|
||||
}
|
||||
accAngle_ += event->angleDelta().y();
|
||||
auto angleForClick = 120;
|
||||
while (accAngle_ >= angleForClick) {
|
||||
accAngle_ -= angleForClick;
|
||||
Q_EMIT prevClicked();
|
||||
}
|
||||
while (accAngle_ <= -angleForClick) {
|
||||
accAngle_ += angleForClick;
|
||||
Q_EMIT nextClicked();
|
||||
}
|
||||
}
|
||||
|
||||
void FcitxCandidateWindow::paintEvent(QPaintEvent *) {
|
||||
QPainter p(this);
|
||||
render(&p);
|
||||
}
|
||||
} // namespace fcitx
|
||||
105
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitxcandidatewindow.h
vendored
Normal file
105
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitxcandidatewindow.h
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021~2021 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PLATFORMINPUTCONTEXT_FCITXCANDIDATEWINDOW_H_
|
||||
#define _PLATFORMINPUTCONTEXT_FCITXCANDIDATEWINDOW_H_
|
||||
|
||||
#include "fcitxflags.h"
|
||||
#include "fcitxqtdbustypes.h"
|
||||
#include <QGuiApplication>
|
||||
#include <QPainter>
|
||||
#include <QPointer>
|
||||
#include <QRasterWindow>
|
||||
#include <QTextLayout>
|
||||
#include <memory>
|
||||
#include <qscopedpointer.h>
|
||||
#include <vector>
|
||||
|
||||
#if defined(FCITX_ENABLE_QT6_WAYLAND_WORKAROUND) && \
|
||||
QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
|
||||
#include <QtWaylandClient/private/qwayland-xdg-shell.h>
|
||||
#endif
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class FcitxTheme;
|
||||
class MultilineText;
|
||||
class QFcitxPlatformInputContext;
|
||||
|
||||
class FcitxCandidateWindow : public QRasterWindow {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FcitxCandidateWindow(QWindow *window,
|
||||
QFcitxPlatformInputContext *context);
|
||||
~FcitxCandidateWindow();
|
||||
|
||||
void render(QPainter *painter);
|
||||
|
||||
public Q_SLOTS:
|
||||
void updateClientSideUI(const FcitxQtFormattedPreeditList &preedit,
|
||||
int cursorpos,
|
||||
const FcitxQtFormattedPreeditList &auxUp,
|
||||
const FcitxQtFormattedPreeditList &auxDown,
|
||||
const FcitxQtStringKeyValueList &candidates,
|
||||
int candidateIndex, int layoutHint, bool hasPrev,
|
||||
bool hasNext);
|
||||
|
||||
QSize sizeHint();
|
||||
|
||||
Q_SIGNALS:
|
||||
void candidateSelected(int i);
|
||||
void prevClicked();
|
||||
void nextClicked();
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *) override;
|
||||
void mouseReleaseEvent(QMouseEvent *) override;
|
||||
void wheelEvent(QWheelEvent *) override;
|
||||
|
||||
int highlight() const {
|
||||
int highlightIndex = (hoverIndex_ >= 0) ? hoverIndex_ : highlight_;
|
||||
return highlightIndex;
|
||||
}
|
||||
|
||||
private:
|
||||
const bool isWayland_ =
|
||||
QGuiApplication::platformName().startsWith("wayland");
|
||||
uint32_t repositionToken_ = 0;
|
||||
QSize actualSize_;
|
||||
QPointer<QFcitxPlatformInputContext> context_;
|
||||
QPointer<FcitxTheme> theme_;
|
||||
QTextLayout upperLayout_;
|
||||
QTextLayout lowerLayout_;
|
||||
std::vector<std::unique_ptr<MultilineText>> candidateLayouts_;
|
||||
std::vector<std::unique_ptr<MultilineText>> labelLayouts_;
|
||||
int cursor_ = -1;
|
||||
int highlight_ = -1;
|
||||
int hoverIndex_ = -1;
|
||||
int accAngle_ = 0;
|
||||
bool prevHovered_ = false;
|
||||
bool nextHovered_ = false;
|
||||
bool hasPrev_ = false;
|
||||
bool hasNext_ = false;
|
||||
FcitxCandidateLayoutHint layoutHint_ = FcitxCandidateLayoutHint::NotSet;
|
||||
int candidatesHeight_ = 0;
|
||||
QRect prevRegion_;
|
||||
QRect nextRegion_;
|
||||
std::vector<QRect> candidateRegions_;
|
||||
QPointer<QWindow> parent_;
|
||||
|
||||
#if defined(FCITX_ENABLE_QT6_WAYLAND_WORKAROUND) && \
|
||||
QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
|
||||
QScopedPointer<QtWayland::xdg_wm_base> xdgWmBase_;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace fcitx
|
||||
|
||||
#endif // _PLATFORMINPUTCONTEXT_FCITXCANDIDATEWINDOW_H_
|
||||
451
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitxtheme.cpp
vendored
Normal file
451
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitxtheme.cpp
vendored
Normal file
@@ -0,0 +1,451 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021~2021 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
#include "fcitxtheme.h"
|
||||
#include "font.h"
|
||||
#include <QDebug>
|
||||
#include <QMargins>
|
||||
#include <QPixmap>
|
||||
#include <QSettings>
|
||||
#include <QStandardPaths>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
bool readBool(const QSettings &settings, const QString &name,
|
||||
bool defaultValue) {
|
||||
return settings.value(name, defaultValue ? "True" : "False").toString() ==
|
||||
"True";
|
||||
}
|
||||
|
||||
QMargins readMargin(const QSettings &settings) {
|
||||
settings.allKeys();
|
||||
return QMargins(settings.value("Left", 0).toInt(),
|
||||
settings.value("Top", 0).toInt(),
|
||||
settings.value("Right", 0).toInt(),
|
||||
settings.value("Bottom", 0).toInt());
|
||||
}
|
||||
|
||||
QColor readColor(const QSettings &settings, const QString &name,
|
||||
const QString &defaultValue) {
|
||||
QString colorString = settings.value(name, defaultValue).toString();
|
||||
QColor color(defaultValue);
|
||||
if (colorString.startsWith("#")) {
|
||||
if (colorString.size() == 7) {
|
||||
// Parse #RRGGBB
|
||||
color = QColor(colorString.toUpper());
|
||||
} else if (colorString.size() == 9) {
|
||||
// Qt accept "#AARRGGBB"
|
||||
auto newColorString =
|
||||
QString("#%1%2")
|
||||
.arg(colorString.mid(7, 2), colorString.mid(1, 6))
|
||||
.toUpper();
|
||||
color = QColor(newColorString);
|
||||
}
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
void BackgroundImage::load(const QString &name, QSettings &settings) {
|
||||
settings.allKeys();
|
||||
image_ = QPixmap();
|
||||
overlay_ = QPixmap();
|
||||
if (auto image = settings.value("Image").toString(); !image.isEmpty()) {
|
||||
auto file = QStandardPaths::locate(
|
||||
QStandardPaths::GenericDataLocation,
|
||||
QString("fcitx5/themes/%1/%2").arg(name, image));
|
||||
image_.load(file);
|
||||
}
|
||||
if (auto image = settings.value("Overlay").toString(); !image.isEmpty()) {
|
||||
auto file = QStandardPaths::locate(
|
||||
QStandardPaths::GenericDataLocation,
|
||||
QString("fcitx5/themes/%1/%2").arg(name, image));
|
||||
overlay_.load(file);
|
||||
}
|
||||
|
||||
settings.beginGroup("Margin");
|
||||
margin_ = readMargin(settings);
|
||||
settings.endGroup();
|
||||
|
||||
if (image_.isNull()) {
|
||||
QColor color = readColor(settings, "Color", "#ffffff");
|
||||
QColor borderColor = readColor(settings, "BorderColor", "#00ffffff");
|
||||
int borderWidth = settings.value("BorderWidth", 0).toInt();
|
||||
fillBackground(borderColor, color, borderWidth);
|
||||
}
|
||||
|
||||
settings.beginGroup("OverlayClipMargin");
|
||||
overlayClipMargin_ = readMargin(settings);
|
||||
settings.endGroup();
|
||||
|
||||
hideOverlayIfOversize_ =
|
||||
settings.value("HideOverlayIfOversize", "False").toString() == "True";
|
||||
overlayOffsetX_ = settings.value("OverlayOffsetX", 0).toInt();
|
||||
overlayOffsetY_ = settings.value("OverlayOffsetY", 0).toInt();
|
||||
gravity_ = settings.value("Gravity", "TopLeft").toString();
|
||||
}
|
||||
|
||||
void BackgroundImage::loadFromValue(const QColor &border,
|
||||
const QColor &background, QMargins margin,
|
||||
int borderWidth) {
|
||||
image_ = QPixmap();
|
||||
overlay_ = QPixmap();
|
||||
margin_ = margin;
|
||||
fillBackground(border, background, borderWidth);
|
||||
overlayClipMargin_ = QMargins();
|
||||
hideOverlayIfOversize_ = false;
|
||||
overlayOffsetX_ = 0;
|
||||
overlayOffsetY_ = 0;
|
||||
gravity_ = QString();
|
||||
}
|
||||
|
||||
void BackgroundImage::fillBackground(const QColor &border,
|
||||
const QColor &background,
|
||||
int borderWidth) {
|
||||
image_ = QPixmap(margin_.left() + margin_.right() + 1,
|
||||
margin_.top() + margin_.bottom() + 1);
|
||||
borderWidth = std::min({borderWidth, margin_.left(), margin_.right(),
|
||||
margin_.top(), margin_.bottom()});
|
||||
borderWidth = std::max(0, borderWidth);
|
||||
|
||||
QPainter painter;
|
||||
painter.begin(&image_);
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
if (borderWidth) {
|
||||
painter.fillRect(image_.rect(), border);
|
||||
}
|
||||
painter.fillRect(QRect(borderWidth, borderWidth,
|
||||
image_.width() - borderWidth * 2,
|
||||
image_.height() - borderWidth * 2),
|
||||
background);
|
||||
painter.end();
|
||||
}
|
||||
|
||||
void ActionImage::load(const QString &name, QSettings &settings) {
|
||||
settings.allKeys();
|
||||
image_ = QPixmap();
|
||||
valid_ = false;
|
||||
if (auto image = settings.value("Image").toString(); !image.isEmpty()) {
|
||||
auto file = QStandardPaths::locate(
|
||||
QStandardPaths::GenericDataLocation,
|
||||
QString("fcitx5/themes/%1/%2").arg(name, image));
|
||||
image_.load(file);
|
||||
valid_ = !image_.isNull();
|
||||
}
|
||||
|
||||
settings.beginGroup("ClickMargin");
|
||||
margin_ = readMargin(settings);
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
void ActionImage::reset() {
|
||||
image_ = QPixmap();
|
||||
valid_ = false;
|
||||
margin_ = QMargins(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
FcitxTheme::FcitxTheme(QObject *parent)
|
||||
: QObject(parent), configPath_(QStandardPaths::writableLocation(
|
||||
QStandardPaths::GenericConfigLocation)
|
||||
.append("/fcitx5/conf/classicui.conf")),
|
||||
watcher_(new QFileSystemWatcher) {
|
||||
connect(watcher_, &QFileSystemWatcher::fileChanged, this,
|
||||
&FcitxTheme::configChanged);
|
||||
watcher_->addPath(configPath_);
|
||||
|
||||
configChanged();
|
||||
}
|
||||
|
||||
FcitxTheme::~FcitxTheme() {}
|
||||
|
||||
void FcitxTheme::configChanged() {
|
||||
// Since fcitx is doing things like delete and move, we need to re-add the
|
||||
// path.
|
||||
watcher_->removePath(configPath_);
|
||||
watcher_->addPath(configPath_);
|
||||
QSettings settings(configPath_, QSettings::IniFormat);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
settings.setIniCodec("UTF-8");
|
||||
#endif
|
||||
settings.childGroups();
|
||||
font_ = parseFont(settings.value("Font", "Sans Serif 9").toString());
|
||||
fontMetrics_ = QFontMetrics(font_);
|
||||
vertical_ =
|
||||
settings.value("Vertical Candidate List", "False").toString() == "True";
|
||||
wheelForPaging_ =
|
||||
settings.value("WheelForPaging", "True").toString() == "True";
|
||||
theme_ = settings.value("Theme", "default").toString();
|
||||
|
||||
themeChanged();
|
||||
}
|
||||
|
||||
void FcitxTheme::themeChanged() {
|
||||
if (!themeConfigPath_.isEmpty()) {
|
||||
watcher_->removePath(themeConfigPath_);
|
||||
}
|
||||
auto themeConfig = QString("/fcitx5/themes/%1/theme.conf").arg(theme_);
|
||||
themeConfigPath_ =
|
||||
QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)
|
||||
.append(themeConfig);
|
||||
auto file = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
|
||||
themeConfig);
|
||||
if (file.isEmpty()) {
|
||||
file = QStandardPaths::locate(QStandardPaths::GenericDataLocation,
|
||||
"fcitx5/themes/default/theme.conf");
|
||||
themeConfigPath_ = QStandardPaths::writableLocation(
|
||||
QStandardPaths::GenericDataLocation)
|
||||
.append("fcitx5/themes/default/theme.conf");
|
||||
theme_ = "default";
|
||||
}
|
||||
|
||||
watcher_->addPath(themeConfigPath_);
|
||||
|
||||
// We can not locate default theme.
|
||||
if (file.isEmpty()) {
|
||||
normalColor_ = QColor("#000000");
|
||||
highlightCandidateColor_ = QColor("#ffffff");
|
||||
fullWidthHighlight_ = true;
|
||||
highlightColor_ = QColor("#ffffff");
|
||||
highlightBackgroundColor_ = QColor("#a5a5a5");
|
||||
contentMargin_ = QMargins{2, 2, 2, 2};
|
||||
textMargin_ = QMargins{5, 5, 5, 5};
|
||||
highlightClickMargin_ = QMargins{0, 0, 0, 0};
|
||||
shadowMargin_ = QMargins{0, 0, 0, 0};
|
||||
background_.loadFromValue(highlightBackgroundColor_, highlightColor_,
|
||||
contentMargin_, 2);
|
||||
highlight_.loadFromValue(highlightBackgroundColor_,
|
||||
highlightBackgroundColor_, textMargin_, 0);
|
||||
prev_.reset();
|
||||
next_.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
QSettings settings(file, QSettings::IniFormat);
|
||||
settings.childGroups();
|
||||
settings.beginGroup("InputPanel");
|
||||
normalColor_ = readColor(settings, "NormalColor", "#000000");
|
||||
highlightCandidateColor_ =
|
||||
readColor(settings, "HighlightCandidateColor", "#ffffff");
|
||||
fullWidthHighlight_ = readBool(settings, "FullWidthHighlight", true);
|
||||
highlightColor_ = readColor(settings, "HighlightColor", "#ffffff");
|
||||
highlightBackgroundColor_ =
|
||||
readColor(settings, "HighlightBackgroundColor", "#a5a5a5");
|
||||
buttonAlignment_ =
|
||||
settings.value("PageButtonAlignment", "Bottom").toString();
|
||||
|
||||
settings.beginGroup("ContentMargin");
|
||||
contentMargin_ = readMargin(settings);
|
||||
settings.endGroup();
|
||||
settings.beginGroup("TextMargin");
|
||||
textMargin_ = readMargin(settings);
|
||||
settings.endGroup();
|
||||
settings.beginGroup("ShadowMargin");
|
||||
shadowMargin_ = readMargin(settings);
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("Background");
|
||||
background_.load(theme_, settings);
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("Highlight");
|
||||
highlight_.load(theme_, settings);
|
||||
settings.beginGroup("HighlightClickMargin");
|
||||
highlightClickMargin_ = readMargin(settings);
|
||||
settings.endGroup();
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("PrevPage");
|
||||
prev_.load(theme_, settings);
|
||||
settings.endGroup();
|
||||
|
||||
settings.beginGroup("NextPage");
|
||||
next_.load(theme_, settings);
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
} // namespace fcitx
|
||||
|
||||
void fcitx::FcitxTheme::paint(QPainter *painter,
|
||||
const fcitx::BackgroundImage &image,
|
||||
QRect region) {
|
||||
auto marginTop = image.margin_.top();
|
||||
auto marginBottom = image.margin_.bottom();
|
||||
auto marginLeft = image.margin_.left();
|
||||
auto marginRight = image.margin_.right();
|
||||
int resizeHeight = image.image_.height() - marginTop - marginBottom;
|
||||
int resizeWidth = image.image_.width() - marginLeft - marginRight;
|
||||
|
||||
if (resizeHeight <= 0) {
|
||||
resizeHeight = 1;
|
||||
}
|
||||
|
||||
if (resizeWidth <= 0) {
|
||||
resizeWidth = 1;
|
||||
}
|
||||
|
||||
if (region.height() < 0) {
|
||||
region.setHeight(resizeHeight);
|
||||
}
|
||||
|
||||
if (region.width() < 0) {
|
||||
region.setWidth(resizeWidth);
|
||||
}
|
||||
|
||||
/*
|
||||
* 7 8 9
|
||||
* 4 5 6
|
||||
* 1 2 3
|
||||
*/
|
||||
|
||||
if (marginLeft && marginBottom) {
|
||||
/* part 1 */
|
||||
painter->drawPixmap(
|
||||
QRect(0, region.height() - marginBottom, marginLeft, marginBottom)
|
||||
.translated(region.topLeft()),
|
||||
image.image_,
|
||||
QRect(0, marginTop + resizeHeight, marginLeft, marginBottom));
|
||||
}
|
||||
|
||||
if (marginRight && marginBottom) {
|
||||
/* part 3 */
|
||||
painter->drawPixmap(
|
||||
QRect(region.width() - marginRight, region.height() - marginBottom,
|
||||
marginRight, marginBottom)
|
||||
.translated(region.topLeft()),
|
||||
image.image_,
|
||||
QRect(marginLeft + resizeWidth, marginTop + resizeHeight,
|
||||
marginRight, marginBottom));
|
||||
}
|
||||
|
||||
if (marginLeft && marginTop) {
|
||||
/* part 7 */
|
||||
painter->drawPixmap(
|
||||
QRect(0, 0, marginLeft, marginTop).translated(region.topLeft()),
|
||||
image.image_, QRect(0, 0, marginLeft, marginTop));
|
||||
}
|
||||
|
||||
if (marginRight && marginTop) {
|
||||
/* part 9 */
|
||||
painter->drawPixmap(
|
||||
QRect(region.width() - marginRight, 0, marginRight, marginTop)
|
||||
.translated(region.topLeft()),
|
||||
image.image_,
|
||||
QRect(marginLeft + resizeWidth, 0, marginRight, marginTop));
|
||||
}
|
||||
|
||||
/* part 2 & 8 */
|
||||
if (marginTop) {
|
||||
painter->drawPixmap(
|
||||
QRect(marginLeft, 0, region.width() - marginLeft - marginRight,
|
||||
marginTop)
|
||||
.translated(region.topLeft()),
|
||||
image.image_, QRect(marginLeft, 0, resizeWidth, marginTop));
|
||||
}
|
||||
|
||||
if (marginBottom) {
|
||||
painter->drawPixmap(QRect(marginLeft, region.height() - marginBottom,
|
||||
region.width() - marginLeft - marginRight,
|
||||
marginBottom)
|
||||
.translated(region.topLeft()),
|
||||
image.image_,
|
||||
QRect(marginLeft, marginTop + resizeHeight,
|
||||
resizeWidth, marginBottom));
|
||||
}
|
||||
|
||||
/* part 4 & 6 */
|
||||
if (marginLeft) {
|
||||
painter->drawPixmap(QRect(0, marginTop, marginLeft,
|
||||
region.height() - marginTop - marginBottom)
|
||||
.translated(region.topLeft()),
|
||||
image.image_,
|
||||
QRect(0, marginTop, marginLeft, resizeHeight));
|
||||
}
|
||||
|
||||
if (marginRight) {
|
||||
painter->drawPixmap(QRect(region.width() - marginRight, marginTop,
|
||||
marginRight,
|
||||
region.height() - marginTop - marginBottom)
|
||||
.translated(region.topLeft()),
|
||||
image.image_,
|
||||
QRect(marginLeft + resizeWidth, marginTop,
|
||||
marginRight, resizeHeight));
|
||||
}
|
||||
|
||||
/* part 5 */
|
||||
{
|
||||
painter->drawPixmap(
|
||||
QRect(marginLeft, marginTop,
|
||||
region.width() - marginLeft - marginRight,
|
||||
region.height() - marginTop - marginBottom)
|
||||
.translated(region.topLeft()),
|
||||
image.image_,
|
||||
QRect(marginLeft, marginTop, resizeWidth, resizeHeight));
|
||||
}
|
||||
|
||||
if (image.overlay_.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto clipWidth = region.width() - image.overlayClipMargin_.left() -
|
||||
image.overlayClipMargin_.right();
|
||||
auto clipHeight = region.height() - image.overlayClipMargin_.top() -
|
||||
image.overlayClipMargin_.bottom();
|
||||
if (clipWidth <= 0 || clipHeight <= 0) {
|
||||
return;
|
||||
}
|
||||
QRect clipRect(region.topLeft() + QPoint(image.overlayClipMargin_.left(),
|
||||
image.overlayClipMargin_.top()),
|
||||
QSize(clipWidth, clipHeight));
|
||||
|
||||
int x = 0, y = 0;
|
||||
if (image.gravity_ == "Top Left" || image.gravity_ == "Center Left" ||
|
||||
image.gravity_ == "Bottom Left") {
|
||||
x = image.overlayOffsetX_;
|
||||
} else if (image.gravity_ == "Top Center" || image.gravity_ == "Center" ||
|
||||
image.gravity_ == "Bottom Center") {
|
||||
x = (region.width() - image.overlay_.width()) / 2 +
|
||||
image.overlayOffsetX_;
|
||||
} else {
|
||||
x = region.width() - image.overlay_.width() - image.overlayOffsetX_;
|
||||
}
|
||||
|
||||
if (image.gravity_ == "Top Left" || image.gravity_ == "Top Center" ||
|
||||
image.gravity_ == "Top Right") {
|
||||
y = image.overlayOffsetY_;
|
||||
} else if (image.gravity_ == "Center Left" || image.gravity_ == "Center" ||
|
||||
image.gravity_ == "Center Right") {
|
||||
y = (region.height() - image.overlay_.height()) / 2 +
|
||||
image.overlayOffsetY_;
|
||||
} else {
|
||||
y = region.height() - image.overlay_.height() - image.overlayOffsetY_;
|
||||
}
|
||||
QRect rect(QPoint(x, y) + region.topLeft(), image.overlay_.size());
|
||||
QRect finalRect = rect.intersected(clipRect);
|
||||
if (finalRect.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (image.hideOverlayIfOversize_ && !clipRect.contains(rect)) {
|
||||
return;
|
||||
}
|
||||
|
||||
painter->save();
|
||||
painter->setClipRect(clipRect);
|
||||
painter->drawPixmap(rect, image.overlay_);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void fcitx::FcitxTheme::paint(QPainter *painter,
|
||||
const fcitx::ActionImage &image, QPoint position,
|
||||
float alpha) {
|
||||
painter->save();
|
||||
painter->setOpacity(alpha);
|
||||
painter->drawPixmap(position, image.image_);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QMargins fcitx::FcitxTheme::highlightMargin() const {
|
||||
return highlight_.margin_;
|
||||
}
|
||||
124
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitxtheme.h
vendored
Normal file
124
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/fcitxtheme.h
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021~2021 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
#ifndef _PLATFORMINPUTCONTEXT_FCITXTHEME_H_
|
||||
#define _PLATFORMINPUTCONTEXT_FCITXTHEME_H_
|
||||
|
||||
#include <QColor>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QFont>
|
||||
#include <QFontMetrics>
|
||||
#include <QMargins>
|
||||
#include <QObject>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QSettings>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class BackgroundImage {
|
||||
friend class FcitxTheme;
|
||||
|
||||
public:
|
||||
void load(const QString &name, QSettings &settings);
|
||||
void loadFromValue(const QColor &border, const QColor &background,
|
||||
QMargins margin, int borderWidth);
|
||||
|
||||
private:
|
||||
void fillBackground(const QColor &border, const QColor &background,
|
||||
int borderWidth);
|
||||
|
||||
QPixmap image_, overlay_;
|
||||
QMargins margin_, overlayClipMargin_;
|
||||
bool hideOverlayIfOversize_ = false;
|
||||
QString gravity_;
|
||||
int overlayOffsetX_ = 0;
|
||||
int overlayOffsetY_ = 0;
|
||||
};
|
||||
|
||||
class ActionImage {
|
||||
friend class FcitxTheme;
|
||||
|
||||
public:
|
||||
void load(const QString &name, QSettings &settings);
|
||||
void reset();
|
||||
bool valid() const { return valid_; }
|
||||
int width() const { return image_.width(); }
|
||||
int height() const { return image_.height(); }
|
||||
QSize size() const { return image_.size(); }
|
||||
const QMargins &margin() const { return margin_; }
|
||||
|
||||
private:
|
||||
bool valid_ = false;
|
||||
QPixmap image_;
|
||||
QMargins margin_;
|
||||
};
|
||||
|
||||
class FcitxTheme : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
FcitxTheme(QObject *parent = nullptr);
|
||||
~FcitxTheme();
|
||||
|
||||
void paint(QPainter *painter, const BackgroundImage &image, QRect region);
|
||||
void paint(QPainter *painter, const ActionImage &image, QPoint position,
|
||||
float alpha);
|
||||
|
||||
const auto &background() const { return background_; }
|
||||
const auto &highlight() const { return highlight_; }
|
||||
const auto &prev() const { return prev_; }
|
||||
const auto &next() const { return next_; }
|
||||
const auto &font() const { return font_; }
|
||||
const auto &fontMetrics() const { return fontMetrics_; }
|
||||
const auto &highlightBackgroundColor() const {
|
||||
return highlightBackgroundColor_;
|
||||
}
|
||||
const auto &highlightColor() const { return highlightColor_; }
|
||||
const auto &buttonAlignment() const { return buttonAlignment_; }
|
||||
auto contentMargin() const { return contentMargin_; }
|
||||
auto textMargin() const { return textMargin_; }
|
||||
auto highlightClickMargin() const { return highlightClickMargin_; }
|
||||
QMargins highlightMargin() const;
|
||||
auto shadowMargin() const { return shadowMargin_; }
|
||||
auto normalColor() const { return normalColor_; }
|
||||
auto highlightCandidateColor() const { return highlightCandidateColor_; }
|
||||
auto vertical() const { return vertical_; }
|
||||
auto wheelForPaging() const { return wheelForPaging_; }
|
||||
|
||||
private Q_SLOTS:
|
||||
void configChanged();
|
||||
void themeChanged();
|
||||
|
||||
private:
|
||||
QString configPath_;
|
||||
QString themeConfigPath_;
|
||||
QFileSystemWatcher *watcher_;
|
||||
|
||||
QFont font_;
|
||||
QFontMetrics fontMetrics_{font_};
|
||||
bool vertical_ = false;
|
||||
bool wheelForPaging_ = true;
|
||||
QString theme_ = "default";
|
||||
BackgroundImage background_;
|
||||
BackgroundImage highlight_;
|
||||
ActionImage prev_;
|
||||
ActionImage next_;
|
||||
|
||||
QColor normalColor_{Qt::black};
|
||||
QColor highlightCandidateColor_{Qt::white};
|
||||
bool fullWidthHighlight_ = true;
|
||||
QColor highlightColor_{Qt::white};
|
||||
QColor highlightBackgroundColor_{0xa5, 0xa5, 0xa5};
|
||||
QString buttonAlignment_;
|
||||
QMargins highlightClickMargin_;
|
||||
QMargins contentMargin_;
|
||||
QMargins textMargin_;
|
||||
QMargins shadowMargin_;
|
||||
};
|
||||
|
||||
} // namespace fcitx
|
||||
|
||||
#endif // _PLATFORMINPUTCONTEXT_FCITXTHEME_H_
|
||||
69
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/font.cpp
vendored
Normal file
69
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/font.cpp
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020~2020 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
*/
|
||||
#include "font.h"
|
||||
#include <QMap>
|
||||
|
||||
QFont fcitx::parseFont(const QString &string) {
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
|
||||
auto list = string.split(" ", QString::SkipEmptyParts);
|
||||
#else
|
||||
auto list = string.split(" ", Qt::SkipEmptyParts);
|
||||
#endif
|
||||
int size = 9; // Default size.
|
||||
if (!list.empty()) {
|
||||
bool ok = false;
|
||||
auto fontSize = list.back().toInt(&ok);
|
||||
if (ok) {
|
||||
if (fontSize > 0) {
|
||||
size = fontSize;
|
||||
}
|
||||
list.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
QFont::Style style = QFont::StyleNormal;
|
||||
QFont::Weight weight = QFont::Normal;
|
||||
const QMap<QString, QFont::Weight> strToWeight = {
|
||||
{"Thin", QFont::Thin},
|
||||
{"Ultra-Light", QFont::Thin},
|
||||
{"Extra-Light", QFont::ExtraLight},
|
||||
{"Light", QFont::Light},
|
||||
{"Semi-Light", QFont::Light},
|
||||
{"Demi-Light", QFont::Light},
|
||||
{"Book", QFont::Light},
|
||||
{"Regular", QFont::Normal},
|
||||
{"Medium", QFont::Medium},
|
||||
{"Semi-Bold", QFont::Medium},
|
||||
{"Demi-Bold", QFont::DemiBold},
|
||||
{"Bold", QFont::Bold},
|
||||
{"Ultra-Bold", QFont::Bold},
|
||||
{"Extra-Bold", QFont::ExtraBold},
|
||||
{"Black", QFont::Black},
|
||||
{"Ultra-Black", QFont::Black},
|
||||
{"Extra-Black", QFont::Black},
|
||||
};
|
||||
const QMap<QString, QFont::Style> strToStyle = {
|
||||
{"Italic", QFont::StyleItalic}, {"Oblique", QFont::StyleOblique}};
|
||||
while (!list.empty()) {
|
||||
if (strToWeight.contains(list.back())) {
|
||||
weight = strToWeight.value(list.back(), QFont::Normal);
|
||||
list.pop_back();
|
||||
} else if (strToStyle.contains(list.back())) {
|
||||
style = strToStyle.value(list.back(), QFont::StyleNormal);
|
||||
list.pop_back();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
QString family = list.join(" ");
|
||||
QFont font;
|
||||
font.setFamily(family);
|
||||
font.setWeight(weight);
|
||||
font.setStyle(style);
|
||||
font.setPointSize(size);
|
||||
return font;
|
||||
}
|
||||
19
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/font.h
vendored
Normal file
19
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/font.h
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020~2020 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*
|
||||
*/
|
||||
#ifndef _CONFIGLIB_FONT_H_
|
||||
#define _CONFIGLIB_FONT_H_
|
||||
|
||||
#include <QFont>
|
||||
#include <QString>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
QFont parseFont(const QString &str);
|
||||
|
||||
} // namespace fcitx
|
||||
|
||||
#endif // _CONFIGLIB_FONT_H_
|
||||
280
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/hybridinputcontext.cpp
vendored
Normal file
280
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/hybridinputcontext.cpp
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023~2023 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#include "hybridinputcontext.h"
|
||||
#include "fcitx4inputcontextproxy.h"
|
||||
#include "fcitxqtinputcontextproxy.h"
|
||||
#include "fcitxqtwatcher.h"
|
||||
#include <cstddef>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
HybridInputContext::HybridInputContext(FcitxQtWatcher *watcher,
|
||||
Fcitx4Watcher *fcitx4Watcher,
|
||||
QObject *parent)
|
||||
: QObject(parent), watcher_(watcher), fcitx4Watcher_(fcitx4Watcher) {
|
||||
// We use a timer here to avoid recheck being triggered multiple times.
|
||||
// For fcitx5, the fcitx4frontend and dbusfrontend will be initialized
|
||||
// around the same time. 50ms is specifically selected to be smaller than
|
||||
// the 100ms timer within input context.
|
||||
timer_.setInterval(50);
|
||||
timer_.setSingleShot(true);
|
||||
connect(&timer_, &QTimer::timeout, this,
|
||||
[this]() { doRecheck(/*skipFcitx5=*/false); });
|
||||
connect(watcher_, &FcitxQtWatcher::availabilityChanged, this,
|
||||
&HybridInputContext::recheck);
|
||||
connect(fcitx4Watcher_, &Fcitx4Watcher::availabilityChanged, this,
|
||||
&HybridInputContext::recheck);
|
||||
|
||||
recheck();
|
||||
}
|
||||
|
||||
void HybridInputContext::recheck() { timer_.start(); }
|
||||
|
||||
void HybridInputContext::doRecheck(bool skipFcitx5) {
|
||||
const bool fcitx5Available = !skipFcitx5 && watcher_->availability();
|
||||
if (!fcitx5Available) {
|
||||
delete proxy_;
|
||||
proxy_ = nullptr;
|
||||
}
|
||||
|
||||
if (!fcitx4Watcher_->availability()) {
|
||||
delete proxy4_;
|
||||
proxy4_ = nullptr;
|
||||
}
|
||||
|
||||
if (fcitx5Available) {
|
||||
delete proxy4_;
|
||||
proxy4_ = nullptr;
|
||||
if (!proxy_) {
|
||||
proxy_ = new FcitxQtInputContextProxy(watcher_, this);
|
||||
proxy_->setDisplay(display_);
|
||||
connect(proxy_, &FcitxQtInputContextProxy::commitString, this,
|
||||
&HybridInputContext::commitString);
|
||||
connect(proxy_, &FcitxQtInputContextProxy::currentIM, this,
|
||||
&HybridInputContext::currentIM);
|
||||
connect(proxy_, &FcitxQtInputContextProxy::deleteSurroundingText,
|
||||
this, &HybridInputContext::deleteSurroundingText);
|
||||
connect(proxy_, &FcitxQtInputContextProxy::forwardKey, this,
|
||||
&HybridInputContext::forwardKey);
|
||||
connect(proxy_, &FcitxQtInputContextProxy::updateFormattedPreedit,
|
||||
this, &HybridInputContext::updateFormattedPreedit);
|
||||
connect(proxy_, &FcitxQtInputContextProxy::updateClientSideUI, this,
|
||||
&HybridInputContext::updateClientSideUI);
|
||||
connect(proxy_, &FcitxQtInputContextProxy::inputContextCreated,
|
||||
this, &HybridInputContext::inputContextCreated);
|
||||
connect(proxy_,
|
||||
&FcitxQtInputContextProxy::inputContextCreationFailed, this,
|
||||
&HybridInputContext::inputContextCreationFailed);
|
||||
connect(proxy_, &FcitxQtInputContextProxy::notifyFocusOut, this,
|
||||
&HybridInputContext::notifyFocusOut);
|
||||
connect(proxy_,
|
||||
&FcitxQtInputContextProxy::virtualKeyboardVisibilityChanged,
|
||||
this,
|
||||
&HybridInputContext::virtualKeyboardVisibilityChanged);
|
||||
}
|
||||
} else if (fcitx4Watcher_->availability()) {
|
||||
if (!proxy4_) {
|
||||
proxy4_ = new Fcitx4InputContextProxy(fcitx4Watcher_, this);
|
||||
connect(proxy4_, &Fcitx4InputContextProxy::commitString, this,
|
||||
&HybridInputContext::commitString);
|
||||
connect(proxy4_, &Fcitx4InputContextProxy::currentIM, this,
|
||||
&HybridInputContext::currentIM);
|
||||
connect(proxy4_, &Fcitx4InputContextProxy::deleteSurroundingText,
|
||||
this, &HybridInputContext::deleteSurroundingText);
|
||||
connect(proxy4_, &Fcitx4InputContextProxy::forwardKey, this,
|
||||
&HybridInputContext::forwardKey);
|
||||
connect(
|
||||
proxy4_, &Fcitx4InputContextProxy::updateFormattedPreedit, this,
|
||||
[this](const FcitxQtFormattedPreeditList &list, int cursorpos) {
|
||||
auto newList = list;
|
||||
for (auto item : newList) {
|
||||
const qint32 underlineBit = (1 << 3);
|
||||
// revert non underline and "underline"
|
||||
item.setFormat(item.format() ^ underlineBit);
|
||||
}
|
||||
|
||||
Q_EMIT updateFormattedPreedit(newList, cursorpos);
|
||||
});
|
||||
connect(proxy4_, &Fcitx4InputContextProxy::inputContextCreated,
|
||||
this,
|
||||
[this]() { Q_EMIT inputContextCreated(QByteArray()); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::inputContextCreationFailed() {
|
||||
doRecheck(/*skipFcitx5=*/true);
|
||||
}
|
||||
|
||||
bool HybridInputContext::isValid() const {
|
||||
if (proxy_) {
|
||||
return proxy_->isValid();
|
||||
} else if (proxy4_) {
|
||||
return proxy4_->isValid();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HybridInputContext::reset() {
|
||||
if (proxy_) {
|
||||
proxy_->reset();
|
||||
} else if (proxy4_) {
|
||||
proxy4_->reset();
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::selectCandidate(int i) {
|
||||
if (proxy_) {
|
||||
proxy_->selectCandidate(i);
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::prevPage() {
|
||||
if (proxy_) {
|
||||
proxy_->prevPage();
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::nextPage() {
|
||||
if (proxy_) {
|
||||
proxy_->nextPage();
|
||||
}
|
||||
}
|
||||
|
||||
bool HybridInputContext::supportInvokeAction() const {
|
||||
if (proxy_) {
|
||||
return proxy_->supportInvokeAction();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HybridInputContext::invokeAction(unsigned int action, int cursor) {
|
||||
if (proxy_) {
|
||||
proxy_->invokeAction(action, cursor);
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::setSurroundingText(const QString &text,
|
||||
unsigned int cursor,
|
||||
unsigned int anchor) {
|
||||
if (proxy_) {
|
||||
proxy_->setSurroundingText(text, cursor, anchor);
|
||||
} else if (proxy4_) {
|
||||
proxy4_->setSurroundingText(text, cursor, anchor);
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::setSurroundingTextPosition(unsigned int cursor,
|
||||
unsigned int anchor) {
|
||||
if (proxy_) {
|
||||
proxy_->setSurroundingTextPosition(cursor, anchor);
|
||||
} else if (proxy4_) {
|
||||
proxy4_->setSurroundingTextPosition(cursor, anchor);
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::focusIn() {
|
||||
if (proxy_) {
|
||||
proxy_->focusIn();
|
||||
} else if (proxy4_) {
|
||||
proxy4_->focusIn();
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::focusOut() {
|
||||
if (proxy_) {
|
||||
proxy_->focusOut();
|
||||
} else if (proxy4_) {
|
||||
proxy4_->focusOut();
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::setCursorRectV2(int x, int y, int w, int h,
|
||||
double scale) {
|
||||
if (proxy_) {
|
||||
proxy_->setCursorRectV2(x, y, w, h, scale);
|
||||
} else if (proxy4_) {
|
||||
proxy4_->setCursorRect(x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::setCursorRect(int x, int y, int w, int h) {
|
||||
if (proxy_) {
|
||||
proxy_->setCursorRect(x, y, w, h);
|
||||
} else if (proxy4_) {
|
||||
proxy4_->setCursorRect(x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::setSupportedCapability(quint64 supported) {
|
||||
if (proxy_) {
|
||||
proxy_->setSupportedCapability(supported);
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::setCapability(quint64 capability) {
|
||||
if (proxy_) {
|
||||
proxy_->setCapability(capability);
|
||||
} else if (proxy4_) {
|
||||
proxy4_->setCapability(capability & 0xfffffffffULL);
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::showVirtualKeyboard() {
|
||||
if (proxy_) {
|
||||
proxy_->showVirtualKeyboard();
|
||||
}
|
||||
}
|
||||
|
||||
void HybridInputContext::hideVirtualKeyboard() {
|
||||
if (proxy_) {
|
||||
proxy_->hideVirtualKeyboard();
|
||||
}
|
||||
}
|
||||
|
||||
bool HybridInputContext::isVirtualKeyboardVisible() const {
|
||||
if (proxy_) {
|
||||
return proxy_->isVirtualKeyboardVisible();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HybridInputContext::setDisplay(const QString &display) {
|
||||
if (proxy_) {
|
||||
proxy_->setDisplay(display);
|
||||
}
|
||||
display_ = display;
|
||||
}
|
||||
|
||||
QDBusPendingCall HybridInputContext::processKeyEvent(unsigned int keyval,
|
||||
unsigned int keycode,
|
||||
unsigned int state,
|
||||
bool type,
|
||||
unsigned int time) {
|
||||
if (proxy_) {
|
||||
return proxy_->processKeyEvent(keyval, keycode, state, type, time);
|
||||
}
|
||||
return proxy4_->processKeyEvent(keyval, keycode, state, type ? 1 : 0, time);
|
||||
}
|
||||
|
||||
bool HybridInputContext::processKeyEventResult(const QDBusPendingCall &call) {
|
||||
if (call.isError()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (call.reply().signature() == "b") {
|
||||
QDBusPendingReply<bool> reply = call;
|
||||
return reply.value();
|
||||
} else if (call.reply().signature() == "i") {
|
||||
QDBusPendingReply<int> reply = call;
|
||||
return reply.value() > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace fcitx
|
||||
95
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/hybridinputcontext.h
vendored
Normal file
95
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/hybridinputcontext.h
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023~2023 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HYBRIDINPUTCONTEXT_H
|
||||
#define HYBRIDINPUTCONTEXT_H
|
||||
|
||||
#include "fcitx4inputcontextproxy.h"
|
||||
#include "fcitx4watcher.h"
|
||||
#include "fcitxqtdbustypes.h"
|
||||
#include "fcitxqtinputcontextproxy.h"
|
||||
#include "fcitxqtwatcher.h"
|
||||
#include <QDBusPendingReply>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class HybridInputContext : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
HybridInputContext(FcitxQtWatcher *watcher, Fcitx4Watcher *fcitx4Watcher,
|
||||
QObject *parent);
|
||||
|
||||
void focusIn();
|
||||
void focusOut();
|
||||
void setSurroundingText(const QString &text, unsigned int cursor,
|
||||
unsigned int anchor);
|
||||
void setSurroundingTextPosition(unsigned int cursor, unsigned int anchor);
|
||||
|
||||
void prevPage();
|
||||
void nextPage();
|
||||
void reset();
|
||||
void selectCandidate(int index);
|
||||
|
||||
bool supportInvokeAction() const;
|
||||
void invokeAction(unsigned int action, int cursor);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
void showVirtualKeyboard();
|
||||
void hideVirtualKeyboard();
|
||||
bool isVirtualKeyboardVisible() const;
|
||||
|
||||
void setDisplay(const QString &display);
|
||||
|
||||
void setCapability(quint64 capability);
|
||||
void setCursorRect(int x, int y, int w, int h);
|
||||
void setCursorRectV2(int x, int y, int w, int h, double scale);
|
||||
void setSupportedCapability(quint64 supported);
|
||||
QDBusPendingCall processKeyEvent(unsigned int keyval, unsigned int keycode,
|
||||
unsigned int state, bool type,
|
||||
unsigned int time);
|
||||
static bool processKeyEventResult(const QDBusPendingCall &call);
|
||||
|
||||
Q_SIGNALS:
|
||||
void commitString(const QString &str);
|
||||
void currentIM(const QString &name, const QString &uniqueName,
|
||||
const QString &langCode);
|
||||
void deleteSurroundingText(int offset, unsigned int nchar);
|
||||
void forwardKey(unsigned int keyval, unsigned int state, bool isRelease);
|
||||
void updateFormattedPreedit(const FcitxQtFormattedPreeditList &str,
|
||||
int cursorpos);
|
||||
void updateClientSideUI(const FcitxQtFormattedPreeditList &preedit,
|
||||
int cursorpos,
|
||||
const FcitxQtFormattedPreeditList &auxUp,
|
||||
const FcitxQtFormattedPreeditList &auxDown,
|
||||
const FcitxQtStringKeyValueList &candidates,
|
||||
int candidateIndex, int layoutHint, bool hasPrev,
|
||||
bool hasNext);
|
||||
void inputContextCreated(const QByteArray &uuid);
|
||||
void notifyFocusOut();
|
||||
void virtualKeyboardVisibilityChanged(bool visible);
|
||||
|
||||
private Q_SLOTS:
|
||||
void recheck();
|
||||
void doRecheck(bool skipFcitx5);
|
||||
void inputContextCreationFailed();
|
||||
|
||||
private:
|
||||
QTimer timer_;
|
||||
FcitxQtWatcher *watcher_;
|
||||
Fcitx4Watcher *fcitx4Watcher_;
|
||||
FcitxQtInputContextProxy *proxy_ = nullptr;
|
||||
Fcitx4InputContextProxy *proxy4_ = nullptr;
|
||||
QString display_;
|
||||
};
|
||||
|
||||
} // namespace fcitx
|
||||
|
||||
#endif
|
||||
21
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/main.cpp
vendored
Normal file
21
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/main.cpp
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2012~2017 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
|
||||
fcitx::QFcitxPlatformInputContext *
|
||||
QFcitx5PlatformInputContextPlugin::create(const QString &system,
|
||||
const QStringList ¶mList) {
|
||||
Q_UNUSED(paramList);
|
||||
if (system.compare(system, QStringLiteral("fcitx5"), Qt::CaseInsensitive) ==
|
||||
0 ||
|
||||
system.compare(system, QStringLiteral("fcitx"), Qt::CaseInsensitive) ==
|
||||
0) {
|
||||
return new fcitx::QFcitxPlatformInputContext;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
25
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/main.h
vendored
Normal file
25
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/main.h
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2012~2017 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
#include <QStringList>
|
||||
#include <qpa/qplatforminputcontextplugin_p.h>
|
||||
|
||||
#include "qfcitxplatforminputcontext.h"
|
||||
|
||||
class QFcitx5PlatformInputContextPlugin : public QPlatformInputContextPlugin {
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID QPlatformInputContextFactoryInterface_iid FILE
|
||||
FCITX_PLUGIN_DATA_FILE_PATH)
|
||||
public:
|
||||
fcitx::QFcitxPlatformInputContext *
|
||||
create(const QString &system, const QStringList ¶mList) override;
|
||||
};
|
||||
|
||||
#endif // MAIN_H
|
||||
1300
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/qfcitxplatforminputcontext.cpp
vendored
Normal file
1300
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/qfcitxplatforminputcontext.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
224
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/qfcitxplatforminputcontext.h
vendored
Normal file
224
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/qfcitxplatforminputcontext.h
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2012~2017 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QFCITXPLATFORMINPUTCONTEXT_H
|
||||
#define QFCITXPLATFORMINPUTCONTEXT_H
|
||||
|
||||
#include "fcitxcandidatewindow.h"
|
||||
#include "fcitxqtwatcher.h"
|
||||
#include "hybridinputcontext.h"
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusPendingCallWatcher>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QGuiApplication>
|
||||
#include <QKeyEvent>
|
||||
#include <QPointer>
|
||||
#include <QRect>
|
||||
#include <QWindow>
|
||||
#include <memory>
|
||||
#include <qpa/qplatforminputcontext.h>
|
||||
#include <unordered_map>
|
||||
#include <xkbcommon/xkbcommon-compose.h>
|
||||
|
||||
namespace fcitx {
|
||||
|
||||
class FcitxQtConnection;
|
||||
class QFcitxPlatformInputContext;
|
||||
|
||||
class FcitxQtICData : public QObject {
|
||||
public:
|
||||
FcitxQtICData(QFcitxPlatformInputContext *context, QWindow *window);
|
||||
FcitxQtICData(const FcitxQtICData &that) = delete;
|
||||
~FcitxQtICData() override;
|
||||
|
||||
FcitxCandidateWindow *candidateWindow();
|
||||
|
||||
QWindow *window() { return window_.data(); }
|
||||
|
||||
void resetCandidateWindow();
|
||||
|
||||
quint64 capability = 0;
|
||||
HybridInputContext *proxy;
|
||||
QRect rect;
|
||||
// Last key event forwarded.
|
||||
std::unique_ptr<QKeyEvent> event;
|
||||
QString surroundingText;
|
||||
int surroundingAnchor = -1;
|
||||
int surroundingCursor = -1;
|
||||
bool expectingMicroFocusChange = false;
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
|
||||
private:
|
||||
QFcitxPlatformInputContext *context_;
|
||||
QPointer<QWindow> window_;
|
||||
QPointer<FcitxCandidateWindow> candidateWindow_;
|
||||
};
|
||||
|
||||
class ProcessKeyWatcher : public QDBusPendingCallWatcher {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProcessKeyWatcher(const QKeyEvent &event, QWindow *window,
|
||||
const QDBusPendingCall &call, QObject *parent = nullptr)
|
||||
: QDBusPendingCallWatcher(call, parent),
|
||||
event_(event.type(), event.key(), event.modifiers(),
|
||||
event.nativeScanCode(), event.nativeVirtualKey(),
|
||||
event.nativeModifiers(), event.text(), event.isAutoRepeat(),
|
||||
event.count()),
|
||||
window_(window) {}
|
||||
|
||||
const QKeyEvent &keyEvent() { return event_; }
|
||||
|
||||
QWindow *window() { return window_.data(); }
|
||||
|
||||
private:
|
||||
QKeyEvent event_;
|
||||
QPointer<QWindow> window_;
|
||||
};
|
||||
|
||||
struct XkbContextDeleter {
|
||||
static inline void cleanup(struct xkb_context *pointer) {
|
||||
if (pointer) {
|
||||
xkb_context_unref(pointer);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct XkbComposeTableDeleter {
|
||||
static inline void cleanup(struct xkb_compose_table *pointer) {
|
||||
if (pointer) {
|
||||
xkb_compose_table_unref(pointer);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct XkbComposeStateDeleter {
|
||||
static inline void cleanup(struct xkb_compose_state *pointer) {
|
||||
if (pointer) {
|
||||
xkb_compose_state_unref(pointer);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class QFcitxPlatformInputContext : public QPlatformInputContext {
|
||||
Q_OBJECT
|
||||
public:
|
||||
QFcitxPlatformInputContext();
|
||||
~QFcitxPlatformInputContext() override;
|
||||
|
||||
bool isValid() const override;
|
||||
void setFocusObject(QObject *object) override;
|
||||
void invokeAction(QInputMethod::Action imAction,
|
||||
int cursorPosition) override;
|
||||
void reset() override;
|
||||
void commit() override;
|
||||
void update(Qt::InputMethodQueries queries) override;
|
||||
bool filterEvent(const QEvent *event) override;
|
||||
QLocale locale() const override;
|
||||
bool hasCapability(Capability capability) const override;
|
||||
void showInputPanel() override;
|
||||
void hideInputPanel() override;
|
||||
bool isInputPanelVisible() const override;
|
||||
|
||||
auto *watcher() { return watcher_; }
|
||||
auto *fcitx4Watcher() { return fcitx4Watcher_; }
|
||||
|
||||
// Use Wrapper as suffix to avoid upstream add function with same name.
|
||||
QObject *focusObjectWrapper() const;
|
||||
QWindow *focusWindowWrapper() const;
|
||||
QRect cursorRectangleWrapper() const;
|
||||
|
||||
// Initialize theme object on demand.
|
||||
FcitxTheme *theme();
|
||||
bool hasPreedit() const { return !preeditList_.isEmpty(); }
|
||||
|
||||
public Q_SLOTS:
|
||||
void cursorRectChanged();
|
||||
void commitString(const QString &str);
|
||||
void updateFormattedPreedit(const FcitxQtFormattedPreeditList &preeditList,
|
||||
int cursorPos);
|
||||
void deleteSurroundingText(int offset, unsigned int nchar);
|
||||
void forwardKey(unsigned int keyval, unsigned int state, bool type);
|
||||
void createInputContextFinished(const QByteArray &uuid);
|
||||
void cleanUp();
|
||||
void windowDestroyed(QObject *object);
|
||||
void updateCurrentIM(const QString &name, const QString &uniqueName,
|
||||
const QString &langCode);
|
||||
void updateClientSideUI(const FcitxQtFormattedPreeditList &preedit,
|
||||
int cursorpos,
|
||||
const FcitxQtFormattedPreeditList &auxUp,
|
||||
const FcitxQtFormattedPreeditList &auxDown,
|
||||
const FcitxQtStringKeyValueList &candidates,
|
||||
int candidateIndex, int layoutHint, bool hasPrev,
|
||||
bool hasNext);
|
||||
void serverSideFocusOut();
|
||||
bool commitPreedit(QPointer<QObject> input = qApp->focusObject());
|
||||
private Q_SLOTS:
|
||||
void processKeyEventFinished(QDBusPendingCallWatcher *);
|
||||
|
||||
private:
|
||||
bool processCompose(unsigned int keyval, unsigned int state,
|
||||
bool isRelease);
|
||||
QKeyEvent *createKeyEvent(unsigned int keyval, unsigned int state,
|
||||
bool isRelease, const QKeyEvent *event);
|
||||
void forwardEvent(QWindow *window, const QKeyEvent &event);
|
||||
|
||||
void addCapability(FcitxQtICData &data, quint64 capability,
|
||||
bool forceUpdate = false) {
|
||||
auto newcaps = data.capability | capability;
|
||||
if (data.capability != newcaps || forceUpdate) {
|
||||
data.capability = newcaps;
|
||||
updateCapability(data);
|
||||
}
|
||||
}
|
||||
|
||||
void removeCapability(FcitxQtICData &data, quint64 capability,
|
||||
bool forceUpdate = false) {
|
||||
auto newcaps = data.capability & (~capability);
|
||||
if (data.capability != newcaps || forceUpdate) {
|
||||
data.capability = newcaps;
|
||||
updateCapability(data);
|
||||
}
|
||||
}
|
||||
|
||||
void updateCapability(const FcitxQtICData &data);
|
||||
void createICData(QWindow *w);
|
||||
HybridInputContext *validIC() const;
|
||||
HybridInputContext *validICByWindow(QWindow *window) const;
|
||||
bool filterEventFallback(unsigned int keyval, unsigned int keycode,
|
||||
unsigned int state, bool isRelease);
|
||||
|
||||
void updateCursorRect();
|
||||
bool objectAcceptsInputMethod() const;
|
||||
bool shouldDisableInputMethod() const;
|
||||
|
||||
void updateInputPanelVisible();
|
||||
|
||||
FcitxQtWatcher *watcher_;
|
||||
Fcitx4Watcher *fcitx4Watcher_;
|
||||
QString preedit_;
|
||||
QString commitPreedit_;
|
||||
FcitxQtFormattedPreeditList preeditList_;
|
||||
int cursorPos_;
|
||||
bool useSurroundingText_;
|
||||
bool syncMode_;
|
||||
std::unordered_map<QWindow *, FcitxQtICData> icMap_;
|
||||
QPointer<QWindow> lastWindow_;
|
||||
QPointer<QObject> lastObject_;
|
||||
bool destroy_;
|
||||
bool virtualKeyboardVisible_;
|
||||
QScopedPointer<struct xkb_context, XkbContextDeleter> xkbContext_;
|
||||
QScopedPointer<struct xkb_compose_table, XkbComposeTableDeleter>
|
||||
xkbComposeTable_;
|
||||
QScopedPointer<struct xkb_compose_state, XkbComposeStateDeleter>
|
||||
xkbComposeState_;
|
||||
QLocale locale_;
|
||||
FcitxTheme *theme_ = nullptr;
|
||||
bool inputPanelVisible_ = false;
|
||||
};
|
||||
} // namespace fcitx
|
||||
|
||||
#endif // QFCITXPLATFORMINPUTCONTEXT_H
|
||||
364
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/qtkey.cpp
vendored
Normal file
364
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/qtkey.cpp
vendored
Normal file
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017~2017 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qtkey.h"
|
||||
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
#include <ctype.h>
|
||||
#include <qnamespace.h>
|
||||
#include <unordered_map>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
const std::unordered_map<uint32_t, int> &KeyTbl() {
|
||||
static std::unordered_map<uint32_t, int> keyTbl{
|
||||
std::make_pair(XKB_KEY_KP_Space, Qt::Key_Space),
|
||||
std::make_pair(XKB_KEY_KP_Tab, Qt::Key_Tab),
|
||||
std::make_pair(XKB_KEY_KP_Enter, Qt::Key_Enter),
|
||||
std::make_pair(XKB_KEY_KP_F1, Qt::Key_F1),
|
||||
std::make_pair(XKB_KEY_KP_F2, Qt::Key_F2),
|
||||
std::make_pair(XKB_KEY_KP_F3, Qt::Key_F3),
|
||||
std::make_pair(XKB_KEY_KP_F4, Qt::Key_F4),
|
||||
std::make_pair(XKB_KEY_KP_Home, Qt::Key_Home),
|
||||
std::make_pair(XKB_KEY_KP_Left, Qt::Key_Left),
|
||||
std::make_pair(XKB_KEY_KP_Up, Qt::Key_Up),
|
||||
std::make_pair(XKB_KEY_KP_Right, Qt::Key_Right),
|
||||
std::make_pair(XKB_KEY_KP_Down, Qt::Key_Down),
|
||||
std::make_pair(XKB_KEY_KP_Page_Up, Qt::Key_PageUp),
|
||||
std::make_pair(XKB_KEY_KP_Page_Down, Qt::Key_PageDown),
|
||||
std::make_pair(XKB_KEY_KP_End, Qt::Key_End),
|
||||
std::make_pair(XKB_KEY_KP_Begin, Qt::Key_Clear),
|
||||
std::make_pair(XKB_KEY_KP_Insert, Qt::Key_Insert),
|
||||
std::make_pair(XKB_KEY_KP_Delete, Qt::Key_Delete),
|
||||
std::make_pair(XKB_KEY_KP_Equal, Qt::Key_Equal),
|
||||
std::make_pair(XKB_KEY_KP_Multiply, Qt::Key_multiply),
|
||||
std::make_pair(XKB_KEY_KP_Add, Qt::Key_Plus),
|
||||
std::make_pair(XKB_KEY_KP_Separator, Qt::Key_Comma),
|
||||
std::make_pair(XKB_KEY_KP_Subtract, Qt::Key_Minus),
|
||||
std::make_pair(XKB_KEY_KP_Decimal, Qt::Key_Period),
|
||||
std::make_pair(XKB_KEY_KP_Divide, Qt::Key_Slash),
|
||||
|
||||
std::make_pair(XKB_KEY_KP_0, Qt::Key_0),
|
||||
std::make_pair(XKB_KEY_KP_1, Qt::Key_1),
|
||||
std::make_pair(XKB_KEY_KP_2, Qt::Key_2),
|
||||
std::make_pair(XKB_KEY_KP_3, Qt::Key_3),
|
||||
std::make_pair(XKB_KEY_KP_4, Qt::Key_4),
|
||||
std::make_pair(XKB_KEY_KP_5, Qt::Key_5),
|
||||
std::make_pair(XKB_KEY_KP_6, Qt::Key_6),
|
||||
std::make_pair(XKB_KEY_KP_7, Qt::Key_7),
|
||||
std::make_pair(XKB_KEY_KP_8, Qt::Key_8),
|
||||
std::make_pair(XKB_KEY_KP_9, Qt::Key_9),
|
||||
|
||||
std::make_pair(XKB_KEY_Escape, Qt::Key_Escape),
|
||||
std::make_pair(XKB_KEY_Tab, Qt::Key_Tab),
|
||||
std::make_pair(XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab),
|
||||
std::make_pair(XKB_KEY_BackSpace, Qt::Key_Backspace),
|
||||
std::make_pair(XKB_KEY_Return, Qt::Key_Return),
|
||||
std::make_pair(XKB_KEY_KP_Enter, Qt::Key_Enter),
|
||||
std::make_pair(XKB_KEY_Insert, Qt::Key_Insert),
|
||||
std::make_pair(XKB_KEY_Delete, Qt::Key_Delete),
|
||||
std::make_pair(XKB_KEY_Clear, Qt::Key_Delete),
|
||||
std::make_pair(XKB_KEY_Pause, Qt::Key_Pause),
|
||||
std::make_pair(XKB_KEY_Print, Qt::Key_Print),
|
||||
std::make_pair(XKB_KEY_Sys_Req, Qt::Key_SysReq),
|
||||
std::make_pair(0x1005FF60, Qt::Key_SysReq),
|
||||
std::make_pair(0x1007ff00, Qt::Key_SysReq),
|
||||
|
||||
std::make_pair(XKB_KEY_Home, Qt::Key_Home),
|
||||
std::make_pair(XKB_KEY_End, Qt::Key_End),
|
||||
std::make_pair(XKB_KEY_Left, Qt::Key_Left),
|
||||
std::make_pair(XKB_KEY_Up, Qt::Key_Up),
|
||||
std::make_pair(XKB_KEY_Right, Qt::Key_Right),
|
||||
std::make_pair(XKB_KEY_Down, Qt::Key_Down),
|
||||
std::make_pair(XKB_KEY_Page_Up, Qt::Key_PageUp),
|
||||
std::make_pair(XKB_KEY_Page_Down, Qt::Key_PageDown),
|
||||
std::make_pair(XKB_KEY_Shift_L, Qt::Key_Shift),
|
||||
std::make_pair(XKB_KEY_Shift_R, Qt::Key_Shift),
|
||||
std::make_pair(XKB_KEY_Shift_Lock, Qt::Key_Shift),
|
||||
std::make_pair(XKB_KEY_Control_L, Qt::Key_Control),
|
||||
std::make_pair(XKB_KEY_Control_R, Qt::Key_Control),
|
||||
std::make_pair(XKB_KEY_Meta_L, Qt::Key_Meta),
|
||||
std::make_pair(XKB_KEY_Meta_R, Qt::Key_Meta),
|
||||
std::make_pair(XKB_KEY_Alt_L, Qt::Key_Alt),
|
||||
std::make_pair(XKB_KEY_Alt_R, Qt::Key_Alt),
|
||||
std::make_pair(XKB_KEY_Caps_Lock, Qt::Key_CapsLock),
|
||||
std::make_pair(XKB_KEY_Num_Lock, Qt::Key_NumLock),
|
||||
std::make_pair(XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock),
|
||||
std::make_pair(XKB_KEY_F1, Qt::Key_F1),
|
||||
std::make_pair(XKB_KEY_F2, Qt::Key_F2),
|
||||
std::make_pair(XKB_KEY_F3, Qt::Key_F3),
|
||||
std::make_pair(XKB_KEY_F4, Qt::Key_F4),
|
||||
std::make_pair(XKB_KEY_F5, Qt::Key_F5),
|
||||
std::make_pair(XKB_KEY_F6, Qt::Key_F6),
|
||||
std::make_pair(XKB_KEY_F7, Qt::Key_F7),
|
||||
std::make_pair(XKB_KEY_F8, Qt::Key_F8),
|
||||
std::make_pair(XKB_KEY_F9, Qt::Key_F9),
|
||||
std::make_pair(XKB_KEY_F10, Qt::Key_F10),
|
||||
std::make_pair(XKB_KEY_F11, Qt::Key_F11),
|
||||
std::make_pair(XKB_KEY_F12, Qt::Key_F12),
|
||||
std::make_pair(XKB_KEY_F13, Qt::Key_F13),
|
||||
std::make_pair(XKB_KEY_F14, Qt::Key_F14),
|
||||
std::make_pair(XKB_KEY_F15, Qt::Key_F15),
|
||||
std::make_pair(XKB_KEY_F16, Qt::Key_F16),
|
||||
std::make_pair(XKB_KEY_F17, Qt::Key_F17),
|
||||
std::make_pair(XKB_KEY_F18, Qt::Key_F18),
|
||||
std::make_pair(XKB_KEY_F19, Qt::Key_F19),
|
||||
std::make_pair(XKB_KEY_F20, Qt::Key_F20),
|
||||
std::make_pair(XKB_KEY_F21, Qt::Key_F21),
|
||||
std::make_pair(XKB_KEY_F22, Qt::Key_F22),
|
||||
std::make_pair(XKB_KEY_F23, Qt::Key_F23),
|
||||
std::make_pair(XKB_KEY_F24, Qt::Key_F24),
|
||||
std::make_pair(XKB_KEY_F25, Qt::Key_F25),
|
||||
std::make_pair(XKB_KEY_F26, Qt::Key_F26),
|
||||
std::make_pair(XKB_KEY_F27, Qt::Key_F27),
|
||||
std::make_pair(XKB_KEY_F28, Qt::Key_F28),
|
||||
std::make_pair(XKB_KEY_F29, Qt::Key_F29),
|
||||
std::make_pair(XKB_KEY_F30, Qt::Key_F30),
|
||||
std::make_pair(XKB_KEY_F31, Qt::Key_F31),
|
||||
std::make_pair(XKB_KEY_F32, Qt::Key_F32),
|
||||
std::make_pair(XKB_KEY_F33, Qt::Key_F33),
|
||||
std::make_pair(XKB_KEY_F34, Qt::Key_F34),
|
||||
std::make_pair(XKB_KEY_F35, Qt::Key_F35),
|
||||
std::make_pair(XKB_KEY_Super_L, Qt::Key_Super_L),
|
||||
std::make_pair(XKB_KEY_Super_R, Qt::Key_Super_R),
|
||||
std::make_pair(XKB_KEY_Menu, Qt::Key_Menu),
|
||||
std::make_pair(XKB_KEY_Hyper_L, Qt::Key_Hyper_L),
|
||||
std::make_pair(XKB_KEY_Hyper_R, Qt::Key_Hyper_R),
|
||||
std::make_pair(XKB_KEY_Help, Qt::Key_Help),
|
||||
std::make_pair(XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr),
|
||||
std::make_pair(XKB_KEY_Multi_key, Qt::Key_Multi_key),
|
||||
std::make_pair(XKB_KEY_Codeinput, Qt::Key_Codeinput),
|
||||
std::make_pair(XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate),
|
||||
std::make_pair(XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate),
|
||||
std::make_pair(XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate),
|
||||
std::make_pair(XKB_KEY_Mode_switch, Qt::Key_Mode_switch),
|
||||
std::make_pair(XKB_KEY_script_switch, Qt::Key_Mode_switch),
|
||||
std::make_pair(XKB_KEY_Kanji, Qt::Key_Kanji),
|
||||
std::make_pair(XKB_KEY_Muhenkan, Qt::Key_Muhenkan),
|
||||
std::make_pair(XKB_KEY_Henkan, Qt::Key_Henkan),
|
||||
std::make_pair(XKB_KEY_Romaji, Qt::Key_Romaji),
|
||||
std::make_pair(XKB_KEY_Hiragana, Qt::Key_Hiragana),
|
||||
std::make_pair(XKB_KEY_Katakana, Qt::Key_Katakana),
|
||||
std::make_pair(XKB_KEY_Hiragana_Katakana, Qt::Key_Hiragana_Katakana),
|
||||
std::make_pair(XKB_KEY_Zenkaku, Qt::Key_Zenkaku),
|
||||
std::make_pair(XKB_KEY_Hankaku, Qt::Key_Hankaku),
|
||||
std::make_pair(XKB_KEY_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku),
|
||||
std::make_pair(XKB_KEY_Touroku, Qt::Key_Touroku),
|
||||
std::make_pair(XKB_KEY_Massyo, Qt::Key_Massyo),
|
||||
std::make_pair(XKB_KEY_Kana_Lock, Qt::Key_Kana_Lock),
|
||||
std::make_pair(XKB_KEY_Kana_Shift, Qt::Key_Kana_Shift),
|
||||
std::make_pair(XKB_KEY_Eisu_Shift, Qt::Key_Eisu_Shift),
|
||||
std::make_pair(XKB_KEY_Eisu_toggle, Qt::Key_Eisu_toggle),
|
||||
std::make_pair(XKB_KEY_Kanji_Bangou, Qt::Key_Codeinput),
|
||||
std::make_pair(XKB_KEY_Zen_Koho, Qt::Key_MultipleCandidate),
|
||||
std::make_pair(XKB_KEY_Mae_Koho, Qt::Key_PreviousCandidate),
|
||||
std::make_pair(XKB_KEY_Hangul, Qt::Key_Hangul),
|
||||
std::make_pair(XKB_KEY_Hangul_Start, Qt::Key_Hangul_Start),
|
||||
std::make_pair(XKB_KEY_Hangul_End, Qt::Key_Hangul_End),
|
||||
std::make_pair(XKB_KEY_Hangul_Hanja, Qt::Key_Hangul_Hanja),
|
||||
std::make_pair(XKB_KEY_Hangul_Jamo, Qt::Key_Hangul_Jamo),
|
||||
std::make_pair(XKB_KEY_Hangul_Romaja, Qt::Key_Hangul_Romaja),
|
||||
std::make_pair(XKB_KEY_Hangul_Codeinput, Qt::Key_Codeinput),
|
||||
std::make_pair(XKB_KEY_Hangul_Jeonja, Qt::Key_Hangul_Jeonja),
|
||||
std::make_pair(XKB_KEY_Hangul_Banja, Qt::Key_Hangul_Banja),
|
||||
std::make_pair(XKB_KEY_Hangul_PreHanja, Qt::Key_Hangul_PreHanja),
|
||||
std::make_pair(XKB_KEY_Hangul_PostHanja, Qt::Key_Hangul_PostHanja),
|
||||
std::make_pair(XKB_KEY_Hangul_SingleCandidate, Qt::Key_SingleCandidate),
|
||||
std::make_pair(XKB_KEY_Hangul_MultipleCandidate,
|
||||
Qt::Key_MultipleCandidate),
|
||||
std::make_pair(XKB_KEY_Hangul_PreviousCandidate,
|
||||
Qt::Key_PreviousCandidate),
|
||||
std::make_pair(XKB_KEY_Hangul_Special, Qt::Key_Hangul_Special),
|
||||
std::make_pair(XKB_KEY_Hangul_switch, Qt::Key_Mode_switch),
|
||||
std::make_pair(XKB_KEY_dead_grave, Qt::Key_Dead_Grave),
|
||||
std::make_pair(XKB_KEY_dead_acute, Qt::Key_Dead_Acute),
|
||||
std::make_pair(XKB_KEY_dead_circumflex, Qt::Key_Dead_Circumflex),
|
||||
std::make_pair(XKB_KEY_dead_tilde, Qt::Key_Dead_Tilde),
|
||||
std::make_pair(XKB_KEY_dead_macron, Qt::Key_Dead_Macron),
|
||||
std::make_pair(XKB_KEY_dead_breve, Qt::Key_Dead_Breve),
|
||||
std::make_pair(XKB_KEY_dead_abovedot, Qt::Key_Dead_Abovedot),
|
||||
std::make_pair(XKB_KEY_dead_diaeresis, Qt::Key_Dead_Diaeresis),
|
||||
std::make_pair(XKB_KEY_dead_abovering, Qt::Key_Dead_Abovering),
|
||||
std::make_pair(XKB_KEY_dead_doubleacute, Qt::Key_Dead_Doubleacute),
|
||||
std::make_pair(XKB_KEY_dead_caron, Qt::Key_Dead_Caron),
|
||||
std::make_pair(XKB_KEY_dead_cedilla, Qt::Key_Dead_Cedilla),
|
||||
std::make_pair(XKB_KEY_dead_ogonek, Qt::Key_Dead_Ogonek),
|
||||
std::make_pair(XKB_KEY_dead_iota, Qt::Key_Dead_Iota),
|
||||
std::make_pair(XKB_KEY_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound),
|
||||
std::make_pair(XKB_KEY_dead_semivoiced_sound,
|
||||
Qt::Key_Dead_Semivoiced_Sound),
|
||||
std::make_pair(XKB_KEY_dead_belowdot, Qt::Key_Dead_Belowdot),
|
||||
std::make_pair(XKB_KEY_dead_hook, Qt::Key_Dead_Hook),
|
||||
std::make_pair(XKB_KEY_dead_horn, Qt::Key_Dead_Horn),
|
||||
std::make_pair(XKB_KEY_XF86Back, Qt::Key_Back),
|
||||
std::make_pair(XKB_KEY_XF86Forward, Qt::Key_Forward),
|
||||
std::make_pair(XKB_KEY_XF86Stop, Qt::Key_Stop),
|
||||
std::make_pair(XKB_KEY_XF86Refresh, Qt::Key_Refresh),
|
||||
std::make_pair(XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown),
|
||||
std::make_pair(XKB_KEY_XF86AudioMute, Qt::Key_VolumeMute),
|
||||
std::make_pair(XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp),
|
||||
std::make_pair(XKB_KEY_XF86AudioPlay, Qt::Key_MediaPlay),
|
||||
std::make_pair(XKB_KEY_XF86AudioStop, Qt::Key_MediaStop),
|
||||
std::make_pair(XKB_KEY_XF86AudioPrev, Qt::Key_MediaPrevious),
|
||||
std::make_pair(XKB_KEY_XF86AudioNext, Qt::Key_MediaNext),
|
||||
std::make_pair(XKB_KEY_XF86AudioRecord, Qt::Key_MediaRecord),
|
||||
std::make_pair(XKB_KEY_XF86AudioPause, Qt::Key_MediaPause),
|
||||
std::make_pair(XKB_KEY_XF86HomePage, Qt::Key_HomePage),
|
||||
std::make_pair(XKB_KEY_XF86Favorites, Qt::Key_Favorites),
|
||||
std::make_pair(XKB_KEY_XF86Search, Qt::Key_Search),
|
||||
std::make_pair(XKB_KEY_XF86Standby, Qt::Key_Standby),
|
||||
std::make_pair(XKB_KEY_XF86OpenURL, Qt::Key_OpenUrl),
|
||||
std::make_pair(XKB_KEY_XF86Mail, Qt::Key_LaunchMail),
|
||||
std::make_pair(XKB_KEY_XF86AudioMedia, Qt::Key_LaunchMedia),
|
||||
std::make_pair(XKB_KEY_XF86MyComputer, Qt::Key_Launch0),
|
||||
std::make_pair(XKB_KEY_XF86Calculator, Qt::Key_Launch1),
|
||||
std::make_pair(XKB_KEY_XF86Launch0, Qt::Key_Launch2),
|
||||
std::make_pair(XKB_KEY_XF86Launch1, Qt::Key_Launch3),
|
||||
std::make_pair(XKB_KEY_XF86Launch2, Qt::Key_Launch4),
|
||||
std::make_pair(XKB_KEY_XF86Launch3, Qt::Key_Launch5),
|
||||
std::make_pair(XKB_KEY_XF86Launch4, Qt::Key_Launch6),
|
||||
std::make_pair(XKB_KEY_XF86Launch5, Qt::Key_Launch7),
|
||||
std::make_pair(XKB_KEY_XF86Launch6, Qt::Key_Launch8),
|
||||
std::make_pair(XKB_KEY_XF86Launch7, Qt::Key_Launch9),
|
||||
std::make_pair(XKB_KEY_XF86Launch8, Qt::Key_LaunchA),
|
||||
std::make_pair(XKB_KEY_XF86Launch9, Qt::Key_LaunchB),
|
||||
std::make_pair(XKB_KEY_XF86LaunchA, Qt::Key_LaunchC),
|
||||
std::make_pair(XKB_KEY_XF86LaunchB, Qt::Key_LaunchD),
|
||||
std::make_pair(XKB_KEY_XF86LaunchC, Qt::Key_LaunchE),
|
||||
std::make_pair(XKB_KEY_XF86LaunchD, Qt::Key_LaunchF),
|
||||
std::make_pair(XKB_KEY_XF86MonBrightnessUp, Qt::Key_MonBrightnessUp),
|
||||
std::make_pair(XKB_KEY_XF86MonBrightnessDown,
|
||||
Qt::Key_MonBrightnessDown),
|
||||
std::make_pair(XKB_KEY_XF86KbdLightOnOff, Qt::Key_KeyboardLightOnOff),
|
||||
std::make_pair(XKB_KEY_XF86KbdBrightnessUp,
|
||||
Qt::Key_KeyboardBrightnessUp),
|
||||
std::make_pair(XKB_KEY_XF86KbdBrightnessDown,
|
||||
Qt::Key_KeyboardBrightnessDown),
|
||||
std::make_pair(XKB_KEY_XF86PowerOff, Qt::Key_PowerOff),
|
||||
std::make_pair(XKB_KEY_XF86WakeUp, Qt::Key_WakeUp),
|
||||
std::make_pair(XKB_KEY_XF86Eject, Qt::Key_Eject),
|
||||
std::make_pair(XKB_KEY_XF86ScreenSaver, Qt::Key_ScreenSaver),
|
||||
std::make_pair(XKB_KEY_XF86WWW, Qt::Key_WWW),
|
||||
std::make_pair(XKB_KEY_XF86Memo, Qt::Key_Memo),
|
||||
std::make_pair(XKB_KEY_XF86LightBulb, Qt::Key_LightBulb),
|
||||
std::make_pair(XKB_KEY_XF86Shop, Qt::Key_Shop),
|
||||
std::make_pair(XKB_KEY_XF86History, Qt::Key_History),
|
||||
std::make_pair(XKB_KEY_XF86AddFavorite, Qt::Key_AddFavorite),
|
||||
std::make_pair(XKB_KEY_XF86HotLinks, Qt::Key_HotLinks),
|
||||
std::make_pair(XKB_KEY_XF86BrightnessAdjust, Qt::Key_BrightnessAdjust),
|
||||
std::make_pair(XKB_KEY_XF86Finance, Qt::Key_Finance),
|
||||
std::make_pair(XKB_KEY_XF86Community, Qt::Key_Community),
|
||||
std::make_pair(XKB_KEY_XF86AudioRewind, Qt::Key_AudioRewind),
|
||||
std::make_pair(XKB_KEY_XF86BackForward, Qt::Key_BackForward),
|
||||
std::make_pair(XKB_KEY_XF86ApplicationLeft, Qt::Key_ApplicationLeft),
|
||||
std::make_pair(XKB_KEY_XF86ApplicationRight, Qt::Key_ApplicationRight),
|
||||
std::make_pair(XKB_KEY_XF86Book, Qt::Key_Book),
|
||||
std::make_pair(XKB_KEY_XF86CD, Qt::Key_CD),
|
||||
std::make_pair(XKB_KEY_XF86Calculater, Qt::Key_Calculator),
|
||||
std::make_pair(XKB_KEY_XF86ToDoList, Qt::Key_ToDoList),
|
||||
std::make_pair(XKB_KEY_XF86ClearGrab, Qt::Key_ClearGrab),
|
||||
std::make_pair(XKB_KEY_XF86Close, Qt::Key_Close),
|
||||
std::make_pair(XKB_KEY_XF86Copy, Qt::Key_Copy),
|
||||
std::make_pair(XKB_KEY_XF86Cut, Qt::Key_Cut),
|
||||
std::make_pair(XKB_KEY_XF86Display, Qt::Key_Display),
|
||||
std::make_pair(XKB_KEY_XF86DOS, Qt::Key_DOS),
|
||||
std::make_pair(XKB_KEY_XF86Documents, Qt::Key_Documents),
|
||||
std::make_pair(XKB_KEY_XF86Excel, Qt::Key_Excel),
|
||||
std::make_pair(XKB_KEY_XF86Explorer, Qt::Key_Explorer),
|
||||
std::make_pair(XKB_KEY_XF86Game, Qt::Key_Game),
|
||||
std::make_pair(XKB_KEY_XF86Go, Qt::Key_Go),
|
||||
std::make_pair(XKB_KEY_XF86iTouch, Qt::Key_iTouch),
|
||||
std::make_pair(XKB_KEY_XF86LogOff, Qt::Key_LogOff),
|
||||
std::make_pair(XKB_KEY_XF86Market, Qt::Key_Market),
|
||||
std::make_pair(XKB_KEY_XF86Meeting, Qt::Key_Meeting),
|
||||
std::make_pair(XKB_KEY_XF86MenuKB, Qt::Key_MenuKB),
|
||||
std::make_pair(XKB_KEY_XF86MenuPB, Qt::Key_MenuPB),
|
||||
std::make_pair(XKB_KEY_XF86MySites, Qt::Key_MySites),
|
||||
std::make_pair(XKB_KEY_XF86News, Qt::Key_News),
|
||||
std::make_pair(XKB_KEY_XF86OfficeHome, Qt::Key_OfficeHome),
|
||||
std::make_pair(XKB_KEY_XF86Option, Qt::Key_Option),
|
||||
std::make_pair(XKB_KEY_XF86Paste, Qt::Key_Paste),
|
||||
std::make_pair(XKB_KEY_XF86Phone, Qt::Key_Phone),
|
||||
std::make_pair(XKB_KEY_XF86Calendar, Qt::Key_Calendar),
|
||||
std::make_pair(XKB_KEY_XF86Reply, Qt::Key_Reply),
|
||||
std::make_pair(XKB_KEY_XF86Reload, Qt::Key_Reload),
|
||||
std::make_pair(XKB_KEY_XF86RotateWindows, Qt::Key_RotateWindows),
|
||||
std::make_pair(XKB_KEY_XF86RotationPB, Qt::Key_RotationPB),
|
||||
std::make_pair(XKB_KEY_XF86RotationKB, Qt::Key_RotationKB),
|
||||
std::make_pair(XKB_KEY_XF86Save, Qt::Key_Save),
|
||||
std::make_pair(XKB_KEY_XF86Send, Qt::Key_Send),
|
||||
std::make_pair(XKB_KEY_XF86Spell, Qt::Key_Spell),
|
||||
std::make_pair(XKB_KEY_XF86SplitScreen, Qt::Key_SplitScreen),
|
||||
std::make_pair(XKB_KEY_XF86Support, Qt::Key_Support),
|
||||
std::make_pair(XKB_KEY_XF86TaskPane, Qt::Key_TaskPane),
|
||||
std::make_pair(XKB_KEY_XF86Terminal, Qt::Key_Terminal),
|
||||
std::make_pair(XKB_KEY_XF86Tools, Qt::Key_Tools),
|
||||
std::make_pair(XKB_KEY_XF86Travel, Qt::Key_Travel),
|
||||
std::make_pair(XKB_KEY_XF86Video, Qt::Key_Video),
|
||||
std::make_pair(XKB_KEY_XF86Word, Qt::Key_Word),
|
||||
std::make_pair(XKB_KEY_XF86Xfer, Qt::Key_Xfer),
|
||||
std::make_pair(XKB_KEY_XF86ZoomIn, Qt::Key_ZoomIn),
|
||||
std::make_pair(XKB_KEY_XF86ZoomOut, Qt::Key_ZoomOut),
|
||||
std::make_pair(XKB_KEY_XF86Away, Qt::Key_Away),
|
||||
std::make_pair(XKB_KEY_XF86Messenger, Qt::Key_Messenger),
|
||||
std::make_pair(XKB_KEY_XF86WebCam, Qt::Key_WebCam),
|
||||
std::make_pair(XKB_KEY_XF86MailForward, Qt::Key_MailForward),
|
||||
std::make_pair(XKB_KEY_XF86Pictures, Qt::Key_Pictures),
|
||||
std::make_pair(XKB_KEY_XF86Music, Qt::Key_Music),
|
||||
std::make_pair(XKB_KEY_XF86Battery, Qt::Key_Battery),
|
||||
std::make_pair(XKB_KEY_XF86Bluetooth, Qt::Key_Bluetooth),
|
||||
std::make_pair(XKB_KEY_XF86WLAN, Qt::Key_WLAN),
|
||||
std::make_pair(XKB_KEY_XF86UWB, Qt::Key_UWB),
|
||||
std::make_pair(XKB_KEY_XF86AudioForward, Qt::Key_AudioForward),
|
||||
std::make_pair(XKB_KEY_XF86AudioRepeat, Qt::Key_AudioRepeat),
|
||||
std::make_pair(XKB_KEY_XF86AudioRandomPlay, Qt::Key_AudioRandomPlay),
|
||||
std::make_pair(XKB_KEY_XF86Subtitle, Qt::Key_Subtitle),
|
||||
std::make_pair(XKB_KEY_XF86AudioCycleTrack, Qt::Key_AudioCycleTrack),
|
||||
std::make_pair(XKB_KEY_XF86Time, Qt::Key_Time),
|
||||
std::make_pair(XKB_KEY_XF86Hibernate, Qt::Key_Hibernate),
|
||||
std::make_pair(XKB_KEY_XF86View, Qt::Key_View),
|
||||
std::make_pair(XKB_KEY_XF86TopMenu, Qt::Key_TopMenu),
|
||||
std::make_pair(XKB_KEY_XF86PowerDown, Qt::Key_PowerDown),
|
||||
std::make_pair(XKB_KEY_XF86Suspend, Qt::Key_Suspend),
|
||||
std::make_pair(XKB_KEY_XF86ContrastAdjust, Qt::Key_ContrastAdjust),
|
||||
|
||||
std::make_pair(XKB_KEY_XF86LaunchE, Qt::Key_LaunchG),
|
||||
std::make_pair(XKB_KEY_XF86LaunchF, Qt::Key_LaunchH),
|
||||
|
||||
std::make_pair(XKB_KEY_XF86Select, Qt::Key_Select),
|
||||
std::make_pair(XKB_KEY_Cancel, Qt::Key_Cancel),
|
||||
std::make_pair(XKB_KEY_Execute, Qt::Key_Execute),
|
||||
std::make_pair(XKB_KEY_XF86Sleep, Qt::Key_Sleep),
|
||||
};
|
||||
return keyTbl;
|
||||
}
|
||||
|
||||
int keysymToQtKey(uint32_t key) {
|
||||
auto iter = KeyTbl().find(key);
|
||||
if (iter != KeyTbl().end()) {
|
||||
return iter->second;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int keysymToQtKey(uint32_t keysym, const QString &text) {
|
||||
int code = 0;
|
||||
if (keysym < 128) {
|
||||
// upper-case key, if known
|
||||
code = isprint((int)keysym) ? toupper((int)keysym) : 0;
|
||||
} else if (text.length() == 1 && text.unicode()->unicode() > 0x1f &&
|
||||
text.unicode()->unicode() != 0x7f &&
|
||||
!(keysym >= XKB_KEY_dead_grave &&
|
||||
keysym <= XKB_KEY_dead_currency)) {
|
||||
code = text.unicode()->toUpper().unicode();
|
||||
} else {
|
||||
// any other keys
|
||||
code = keysymToQtKey(keysym);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
16
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/qtkey.h
vendored
Normal file
16
Telegram/ThirdParty/fcitx5-qt/qt5/platforminputcontext/qtkey.h
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017~2017 CSSlayer <wengxt@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PLATFORMINPUTCONTEXT_QTKEY_H_
|
||||
#define _PLATFORMINPUTCONTEXT_QTKEY_H_
|
||||
|
||||
#include <QString>
|
||||
#include <cstdint>
|
||||
|
||||
int keysymToQtKey(uint32_t keysym, const QString &text);
|
||||
|
||||
#endif // _PLATFORMINPUTCONTEXT_QTKEY_H_
|
||||
Reference in New Issue
Block a user