Bug 1033483 - Send bidi keyboard Information on direction-changed signal. r=karlt

Using direction-changed signal, we detect keyboard change for bidi.

When system uses fcitx's IM and ibus's arabic keyboard layout, this signal might fire often when switing layout and gdk_keymap_get_direction might return invalid bidi infromation.  But I think that this is rare issue.  Most users don't use Firefox Arabic version (it means that bidi.browser.ui = true) with ibus arabic layout and fcitx CJK IM.  Since there is no GTK3 API to get current IM module, I cannot find workaround for this.

MozReview-Commit-ID: DL8uUXJFWYz

--HG--
extra : rebase_source : 18b7d5c84f48acd62fa14e21a67b711106fb7d63
This commit is contained in:
Makoto Kato 2016-07-08 16:18:40 +09:00
Родитель 9183b4e1bd
Коммит c220f608ad
3 изменённых файлов: 39 добавлений и 9 удалений

Просмотреть файл

@ -8,6 +8,7 @@
#include "prlink.h"
#include "nsBidiKeyboard.h"
#include "WidgetUtils.h"
#include <gtk/gtk.h>
NS_IMPL_ISUPPORTS(nsBidiKeyboard, nsIBidiKeyboard)
@ -30,6 +31,7 @@ nsBidiKeyboard::Reset()
GdkKeymap *keymap = gdk_keymap_get_for_display(display);
mHaveBidiKeyboards = keymap && gdk_keymap_have_bidi_layouts(keymap);
mozilla::widget::WidgetUtils::SendBidiKeyboardInfoToContent();
return NS_OK;
}

Просмотреть файл

@ -19,6 +19,7 @@
#include <X11/XKBlib.h>
#include "WidgetUtils.h"
#include "keysym2ucs.h"
#include "nsContentUtils.h"
#include "nsGtkUtils.h"
#include "nsIBidiKeyboard.h"
#include "nsServiceManagerUtils.h"
@ -41,7 +42,6 @@ KeymapWrapper* KeymapWrapper::sInstance = nullptr;
guint KeymapWrapper::sLastRepeatableHardwareKeyCode = 0;
KeymapWrapper::RepeatState KeymapWrapper::sRepeatState =
KeymapWrapper::NOT_PRESSED;
nsIBidiKeyboard* sBidiKeyboard = nullptr;
static const char* GetBoolName(bool aBool)
{
@ -170,6 +170,8 @@ KeymapWrapper::KeymapWrapper() :
g_object_ref(mGdkKeymap);
g_signal_connect(mGdkKeymap, "keys-changed",
(GCallback)OnKeysChanged, this);
g_signal_connect(mGdkKeymap, "direction-changed",
(GCallback)OnDirectionChanged, this);
if (GDK_IS_X11_DISPLAY(gdk_display_get_default()))
InitXKBExtension();
@ -442,8 +444,9 @@ KeymapWrapper::~KeymapWrapper()
gdk_window_remove_filter(nullptr, FilterEvents, this);
g_signal_handlers_disconnect_by_func(mGdkKeymap,
FuncToGpointer(OnKeysChanged), this);
g_signal_handlers_disconnect_by_func(mGdkKeymap,
FuncToGpointer(OnDirectionChanged), this);
g_object_unref(mGdkKeymap);
NS_IF_RELEASE(sBidiKeyboard);
MOZ_LOG(gKeymapWrapperLog, LogLevel::Info,
("%p Destructor", this));
}
@ -519,6 +522,16 @@ KeymapWrapper::FilterEvents(GdkXEvent* aXEvent,
return GDK_FILTER_CONTINUE;
}
static void
ResetBidiKeyboard()
{
// Reset the bidi keyboard settings for the new GdkKeymap
nsCOMPtr<nsIBidiKeyboard> bidiKeyboard = nsContentUtils::GetBidiKeyboard();
if (bidiKeyboard) {
bidiKeyboard->Reset();
}
}
/* static */ void
KeymapWrapper::OnKeysChanged(GdkKeymap *aGdkKeymap,
KeymapWrapper* aKeymapWrapper)
@ -533,14 +546,27 @@ KeymapWrapper::OnKeysChanged(GdkKeymap *aGdkKeymap,
// We cannot reintialize here becasue we don't have GdkWindow which is using
// the GdkKeymap. We'll reinitialize it when next GetInstance() is called.
sInstance->mInitialized = false;
ResetBidiKeyboard();
}
// Reset the bidi keyboard settings for the new GdkKeymap
if (!sBidiKeyboard) {
CallGetService("@mozilla.org/widget/bidikeyboard;1", &sBidiKeyboard);
}
if (sBidiKeyboard) {
sBidiKeyboard->Reset();
}
// static
void
KeymapWrapper::OnDirectionChanged(GdkKeymap *aGdkKeymap,
KeymapWrapper* aKeymapWrapper)
{
// XXX
// A lot of diretion-changed signal might be fired on switching bidi
// keyboard when using both ibus (with arabic layout) and fcitx (with IME).
// See https://github.com/fcitx/fcitx/issues/257
//
// Also, when using ibus, switching to IM might not cause this signal.
// See https://github.com/ibus/ibus/issues/1848
MOZ_LOG(gKeymapWrapperLog, LogLevel::Info,
("OnDirectionChanged, aGdkKeymap=%p, aKeymapWrapper=%p",
aGdkKeymap, aKeymapWrapper));
ResetBidiKeyboard();
}
/* static */ guint

Просмотреть файл

@ -257,6 +257,8 @@ protected:
* Signal handlers.
*/
static void OnKeysChanged(GdkKeymap* aKeymap, KeymapWrapper* aKeymapWrapper);
static void OnDirectionChanged(GdkKeymap *aGdkKeymap,
KeymapWrapper* aKeymapWrapper);
/**
* GetCharCodeFor() Computes what character is inputted by the key event