Skip to content

Commit

Permalink
Bug 1680909 - Fix slowdown in X keyboard layout handling. r=stransky
Browse files Browse the repository at this point in the history
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
  • Loading branch information
WGH- committed Dec 7, 2020
1 parent af36035 commit 510853e
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 9 deletions.
25 changes: 16 additions & 9 deletions widget/gtk/nsGtkKeyUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down Expand Up @@ -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());

Expand Down Expand Up @@ -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));
Expand Down
3 changes: 3 additions & 0 deletions widget/gtk/nsGtkKeyUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 510853e

Please sign in to comment.