Commit 98bd08df authored by WGH's avatar WGH
Browse files

Bug 1680909 - Fix slowdown in X keyboard layout handling. r=stransky, a=RyanVM

When ibus input method is changed, Firefox reinitializes the KeymapWrapper
object, causing duplicate calls to g_signal_connect. If Firefox is running
long enough, duplicate handlers accumulate, and Firefox starts to barrage the
X server with XkbGetUpdatedMap/XkbGetControls calls, slowing the X server and
itself down.

A symptom of this problem is that after switching the input methods, Firefox
ignores the input for a while (up to several seconds).

Differential Revision: https://phabricator.services.mozilla.com/D98847
parent 9b25a652
......@@ -340,7 +340,9 @@ void KeymapWrapper::Shutdown() {
KeymapWrapper::KeymapWrapper()
: mInitialized(false),
mGdkKeymap(gdk_keymap_get_default()),
mXKBBaseEventCode(0) {
mXKBBaseEventCode(0),
mOnKeysChangedSignalHandle(0),
mOnDirectionChangedSignalHandle(0) {
MOZ_LOG(gKeymapWrapperLog, LogLevel::Info,
("%p Constructor, mGdkKeymap=%p", this, mGdkKeymap));
......@@ -452,9 +454,14 @@ void KeymapWrapper::InitBySystemSettingsX11() {
MOZ_LOG(gKeymapWrapperLog, LogLevel::Info,
("%p InitBySystemSettingsX11, mGdkKeymap=%p", this, mGdkKeymap));
g_signal_connect(mGdkKeymap, "keys-changed", (GCallback)OnKeysChanged, this);
g_signal_connect(mGdkKeymap, "direction-changed",
(GCallback)OnDirectionChanged, this);
if (!mOnKeysChangedSignalHandle) {
mOnKeysChangedSignalHandle = g_signal_connect(
mGdkKeymap, "keys-changed", (GCallback)OnKeysChanged, this);
}
if (!mOnDirectionChangedSignalHandle) {
mOnDirectionChangedSignalHandle = g_signal_connect(
mGdkKeymap, "direction-changed", (GCallback)OnDirectionChanged, this);
}
Display* display = gdk_x11_display_get_xdisplay(gdk_display_get_default());
......@@ -772,11 +779,11 @@ void KeymapWrapper::InitBySystemSettingsWayland() {
KeymapWrapper::~KeymapWrapper() {
gdk_window_remove_filter(nullptr, FilterEvents, this);
if (gfxPlatformGtk::GetPlatform()->IsX11Display()) {
g_signal_handlers_disconnect_by_func(mGdkKeymap,
FuncToGpointer(OnKeysChanged), this);
g_signal_handlers_disconnect_by_func(
mGdkKeymap, FuncToGpointer(OnDirectionChanged), this);
if (mOnKeysChangedSignalHandle) {
g_signal_handler_disconnect(mGdkKeymap, mOnKeysChangedSignalHandle);
}
if (mOnDirectionChangedSignalHandle) {
g_signal_handler_disconnect(mGdkKeymap, mOnDirectionChangedSignalHandle);
}
g_object_unref(mGdkKeymap);
MOZ_LOG(gKeymapWrapperLog, LogLevel::Info, ("%p Destructor", this));
......
......@@ -335,6 +335,9 @@ class KeymapWrapper {
static void OnDirectionChanged(GdkKeymap* aGdkKeymap,
KeymapWrapper* aKeymapWrapper);
gulong mOnKeysChangedSignalHandle;
gulong mOnDirectionChangedSignalHandle;
/**
* GetCharCodeFor() Computes what character is inputted by the key event
* with aModifierState and aGroup.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment