Skip to content

Commit

Permalink
feat: 添加虚拟键盘监视
Browse files Browse the repository at this point in the history
添加虚拟键盘服务监视连接,
防止虚拟键盘服务在应用程序后启动,
无法Hook虚拟键盘函数

Log: 防止虚拟键盘在程序后启动虚拟键盘无法显示
Change-Id: I671ab9fdd73fb08ef0ac1e230cff12cfa4d79add
  • Loading branch information
Wang Peng committed Aug 10, 2021
1 parent e762179 commit 692ea66
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 21 deletions.
82 changes: 82 additions & 0 deletions misc/org.freedesktop.DBus.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<interface name="org.freedesktop.DBus">
<method name="Hello">
<arg direction="out" type="s"/>
</method>
<method name="RequestName">
<arg direction="in" type="s"/>
<arg direction="in" type="u"/>
<arg direction="out" type="u"/>
</method>
<method name="ReleaseName">
<arg direction="in" type="s"/>
<arg direction="out" type="u"/>
</method>
<method name="StartServiceByName">
<arg direction="in" type="s"/>
<arg direction="in" type="u"/>
<arg direction="out" type="u"/>
</method>
<!--method name="UpdateActivationEnvironment">
<arg direction="in" type="a{ss}"/>
</method-->
<method name="NameHasOwner">
<arg direction="in" type="s"/>
<arg direction="out" type="b"/>
</method>
<method name="ListNames">
<arg direction="out" type="as"/>
</method>
<method name="ListActivatableNames">
<arg direction="out" type="as"/>
</method>
<method name="AddMatch">
<arg direction="in" type="s"/>
</method>
<method name="RemoveMatch">
<arg direction="in" type="s"/>
</method>
<method name="GetNameOwner">
<arg direction="in" type="s"/>
<arg direction="out" type="s"/>
</method>
<method name="ListQueuedOwners">
<arg direction="in" type="s"/>
<arg direction="out" type="as"/>
</method>
<method name="GetConnectionUnixUser">
<arg direction="in" type="s"/>
<arg direction="out" type="u"/>
</method>
<method name="GetConnectionUnixProcessID">
<arg direction="in" type="s"/>
<arg direction="out" type="u"/>
</method>
<method name="GetAdtAuditSessionData">
<arg direction="in" type="s"/>
<arg direction="out" type="ay"/>
</method>
<method name="GetConnectionSELinuxSecurityContext">
<arg direction="in" type="s"/>
<arg direction="out" type="ay"/>
</method>
<method name="ReloadConfig">
</method>
<method name="GetId">
<arg direction="out" type="s"/>
</method>
<!--method name="GetConnectionCredentials">
<arg direction="in" type="s"/>
<arg direction="out" type="a{sv}"/>
</method-->
<signal name="NameOwnerChanged">
<arg type="s"/>
<arg type="s"/>
<arg type="s"/>
</signal>
<signal name="NameLost">
<arg type="s"/>
</signal>
<signal name="NameAcquired">
<arg type="s"/>
</signal>
</interface>
65 changes: 44 additions & 21 deletions xcb/dplatformintegration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
#include <private/qpaintengine_raster_p.h>

#include "im_interface.h"
#include "dbus_interface.h"

// https://www.freedesktop.org/wiki/Specifications/XSettingsRegistry/
#define XSETTINGS_CURSOR_BLINK QByteArrayLiteral("Net/CursorBlink")
Expand Down Expand Up @@ -1029,27 +1030,6 @@ void DPlatformIntegration::initialize()
QSurfaceFormat::setDefaultFormat(format);
}

// 适配虚拟键盘
if (DPlatformInputContextHook::instance()->isValid()) {
VtableHook::overrideVfptrFun(inputContext(),
&QPlatformInputContext::showInputPanel,
&DPlatformInputContextHook::showInputPanel);
VtableHook::overrideVfptrFun(inputContext(),
&QPlatformInputContext::hideInputPanel,
&DPlatformInputContextHook::hideInputPanel);
VtableHook::overrideVfptrFun(inputContext(),
&QPlatformInputContext::isInputPanelVisible,
&DPlatformInputContextHook::isInputPanelVisible);
VtableHook::overrideVfptrFun(inputContext(),
&QPlatformInputContext::keyboardRect,
&DPlatformInputContextHook::keyboardRect);

QObject::connect(DPlatformInputContextHook::instance(), &ComDeepinImInterface::geometryChanged,
inputContext(), &QPlatformInputContext::emitKeyboardRectChanged);
QObject::connect(DPlatformInputContextHook::instance(), &ComDeepinImInterface::imActiveChanged,
inputContext(), &QPlatformInputContext::emitInputPanelVisibleChanged);
}

#ifdef Q_OS_LINUX
m_eventFilter = new XcbNativeEventFilter(defaultConnection());
qApp->installNativeEventFilter(m_eventFilter);
Expand Down Expand Up @@ -1121,6 +1101,26 @@ void DPlatformIntegration::initialize()
m_pDesktopInputSelectionControl->setApplicationEventMonitor(m_pApplicationEventMonitor.data());
}
});

// 适配虚拟键盘
if (DPlatformInputContextHook::instance()->isValid()) {
inputContextHookFunc();
} else {
// 虚拟键盘服务未启动时,开始监听DBUS
// 待虚拟键盘启动后 Hook QPlatformInputContext函数
// 该连接将一直存在防止使用中虚拟键盘服务重启
OrgFreedesktopDBusInterface *interface = new OrgFreedesktopDBusInterface("org.freedesktop.DBus", "/org/freedesktop/DBus", QDBusConnection::sessionBus(), qApp);
QObject::connect(interface, &OrgFreedesktopDBusInterface::NameOwnerChanged, qApp, [ = ](const QString &in0, const QString &in1, const QString &in2){
Q_UNUSED(in1)
Q_UNUSED(in2)

if (in0 == "com.deepin.im") {
inputContextHookFunc();
QObject::disconnect(interface, &OrgFreedesktopDBusInterface::NameOwnerChanged, nullptr, nullptr);
interface->deleteLater();
}
});
}
}
}

Expand Down Expand Up @@ -1195,4 +1195,27 @@ bool DPlatformIntegration::isWindowBlockedHandle(QWindow *window, QWindow **bloc
return VtableHook::callOriginalFun(qApp->d_func(), &QGuiApplicationPrivate::isWindowBlocked, window, blockingWindow);
}

void DPlatformIntegration::inputContextHookFunc()
{
// if (!VtableHook::hasVtable(inputContext())) {
VtableHook::overrideVfptrFun(inputContext(),
&QPlatformInputContext::showInputPanel,
&DPlatformInputContextHook::showInputPanel);
VtableHook::overrideVfptrFun(inputContext(),
&QPlatformInputContext::hideInputPanel,
&DPlatformInputContextHook::hideInputPanel);
VtableHook::overrideVfptrFun(inputContext(),
&QPlatformInputContext::isInputPanelVisible,
&DPlatformInputContextHook::isInputPanelVisible);
VtableHook::overrideVfptrFun(inputContext(),
&QPlatformInputContext::keyboardRect,
&DPlatformInputContextHook::keyboardRect);

QObject::connect(DPlatformInputContextHook::instance(), &ComDeepinImInterface::geometryChanged,
inputContext(), &QPlatformInputContext::emitKeyboardRectChanged);
QObject::connect(DPlatformInputContextHook::instance(), &ComDeepinImInterface::imActiveChanged,
inputContext(), &QPlatformInputContext::emitInputPanelVisibleChanged);
// }
}

DPP_END_NAMESPACE
1 change: 1 addition & 0 deletions xcb/dplatformintegration.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class DPlatformIntegration : public DPlatformIntegrationParent
private:
// handle the DFrameWindow modal blocked state
bool isWindowBlockedHandle(QWindow *window, QWindow **blockingWindow);
void inputContextHookFunc();

DPlatformBackingStoreHelper *m_storeHelper;
DPlatformOpenGLContextHelper *m_contextHelper;
Expand Down
1 change: 1 addition & 0 deletions xcb/xcb.pro
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ isEmpty(INSTALL_PATH) {
}

DBUS_INTERFACES += ../misc/com.deepin.im.xml
DBUS_INTERFACES += ../misc/org.freedesktop.DBus.xml

message($$target.path)

Expand Down

0 comments on commit 692ea66

Please sign in to comment.