Reinitialize bidi keyboard when installed keyboard layouts change. Bug 817508, r=karlt, sr=roc
authorSimon Montagu <smontagu@smontagu.org>
Wed, 10 Jul 2013 10:57:33 +0300
changeset 150241 1adc72e64db00ee68a106b878251e11f4433c05a
parent 150240 edd376cd77bfe3d0670939c5fbdac6e18bb123a6
child 150242 e1eea117b2b05cdb2031f0fb56efe55ce07148c1
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt, roc
bugs817508
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Reinitialize bidi keyboard when installed keyboard layouts change. Bug 817508, r=karlt, sr=roc
widget/cocoa/nsBidiKeyboard.mm
widget/gtk2/nsBidiKeyboard.cpp
widget/gtk2/nsGtkKeyUtils.cpp
widget/nsIBidiKeyboard.idl
widget/os2/nsBidiKeyboard.cpp
widget/qt/nsBidiKeyboard.cpp
widget/windows/nsBidiKeyboard.cpp
--- a/widget/cocoa/nsBidiKeyboard.mm
+++ b/widget/cocoa/nsBidiKeyboard.mm
@@ -12,22 +12,28 @@
 #include "nsObjCExceptions.h"
 
 using namespace mozilla::widget;
 
 NS_IMPL_ISUPPORTS1(nsBidiKeyboard, nsIBidiKeyboard)
 
 nsBidiKeyboard::nsBidiKeyboard() : nsIBidiKeyboard()
 {
+  Reset();
 }
 
 nsBidiKeyboard::~nsBidiKeyboard()
 {
 }
 
+NS_IMETHODIMP nsBidiKeyboard::Reset()
+{
+  return NS_OK;
+}
+
 NS_IMETHODIMP nsBidiKeyboard::IsLangRTL(bool *aIsRTL)
 {
   *aIsRTL = TISInputSourceWrapper::CurrentInputSource().IsForRTLLanguage();
   return NS_OK;
 }
 
 NS_IMETHODIMP nsBidiKeyboard::SetLangFromBidiLevel(uint8_t aLevel)
 {
--- a/widget/gtk2/nsBidiKeyboard.cpp
+++ b/widget/gtk2/nsBidiKeyboard.cpp
@@ -14,16 +14,22 @@
 typedef gboolean (*GdkKeymapHaveBidiLayoutsType)(GdkKeymap *keymap);
 static GdkKeymapHaveBidiLayoutsType GdkKeymapHaveBidiLayouts = nullptr;
 #endif
 
 NS_IMPL_ISUPPORTS1(nsBidiKeyboard, nsIBidiKeyboard)
 
 nsBidiKeyboard::nsBidiKeyboard()
 {
+    Reset();
+}
+
+NS_IMETHODIMP
+nsBidiKeyboard::Reset()
+{
 #if (MOZ_WIDGET_GTK == 2)
     PRLibrary *gtklib = nullptr;
 #if defined(MOZ_X11)
     if (!GdkKeymapHaveBidiLayouts) {
         GdkKeymapHaveBidiLayouts = (GdkKeymapHaveBidiLayoutsType) 
             PR_FindFunctionSymbolAndLibrary("gdk_keymap_have_bidi_layouts",
                                             &gtklib);
         if (gtklib)
@@ -32,16 +38,17 @@ nsBidiKeyboard::nsBidiKeyboard()
 #endif
 
     mHaveBidiKeyboards = false;
     if (GdkKeymapHaveBidiLayouts)
         mHaveBidiKeyboards = (*GdkKeymapHaveBidiLayouts)(NULL);
 #else
     mHaveBidiKeyboards = gdk_keymap_have_bidi_layouts(gdk_keymap_get_default());
 #endif
+    return NS_OK;
 }
 
 nsBidiKeyboard::~nsBidiKeyboard()
 {
 #if (MOZ_WIDGET_GTK == 2)
     GdkKeymapHaveBidiLayouts = nullptr;
 #endif
 }
--- a/widget/gtk2/nsGtkKeyUtils.cpp
+++ b/widget/gtk2/nsGtkKeyUtils.cpp
@@ -16,16 +16,18 @@
 #include <gdk/gdkx.h>
 #endif /* MOZ_X11 */
 #if (MOZ_WIDGET_GTK == 3)
 #include <gdk/gdkkeysyms-compat.h>
 #endif
 #include "nsGUIEvent.h"
 #include "WidgetUtils.h"
 #include "keysym2ucs.h"
+#include "nsIBidiKeyboard.h"
+#include "nsServiceManagerUtils.h"
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gKeymapWrapperLog = nullptr;
 #endif // PR_LOGGING
 
 #include "mozilla/Util.h"
 
 namespace mozilla {
@@ -175,16 +177,17 @@ static const KeyPair kKeyPairs[] = {
 static const KeyPair kSunKeyPairs[] = {
     {NS_VK_F11, 0x1005ff10 }, //Sun F11 key generates SunF36(0x1005ff10) keysym
     {NS_VK_F12, 0x1005ff11 }  //Sun F12 key generates SunF37(0x1005ff11) keysym
 };
 
 #define MOZ_MODIFIER_KEYS "MozKeymapWrapper"
 
 KeymapWrapper* KeymapWrapper::sInstance = nullptr;
+nsIBidiKeyboard* sBidiKeyboard = nullptr;
 
 #ifdef PR_LOGGING
 
 static const char* GetBoolName(bool aBool)
 {
     return aBool ? "TRUE" : "FALSE";
 }
 
@@ -506,16 +509,17 @@ KeymapWrapper::InitBySystemSettings()
     }
 
     XFreeModifiermap(xmodmap);
     XFree(xkeymap);
 }
 
 KeymapWrapper::~KeymapWrapper()
 {
+    NS_IF_RELEASE(sBidiKeyboard);
     PR_LOG(gKeymapWrapperLog, PR_LOG_ALWAYS,
         ("KeymapWrapper(%p): Destructor", this));
 }
 
 /* static */ void
 KeymapWrapper::OnDestroyKeymap(KeymapWrapper* aKeymapWrapper,
                                GdkKeymap *aGdkKeymap)
 {
@@ -537,16 +541,24 @@ KeymapWrapper::OnKeysChanged(GdkKeymap *
          aGdkKeymap, aKeymapWrapper));
 
     MOZ_ASSERT(sInstance == aKeymapWrapper,
                "This instance must be the singleton instance");
 
     // 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;
+
+    // Reset the bidi keyboard settings for the new GdkKeymap
+    if (!sBidiKeyboard) {
+        nsresult rv = CallGetService("@mozilla.org/widget/bidikeyboard;1", &sBidiKeyboard);
+    }
+    if (sBidiKeyboard) {
+        sBidiKeyboard->Reset();
+    }
 }
 
 /* static */ guint
 KeymapWrapper::GetCurrentModifierState()
 {
     GdkModifierType modifiers;
     gdk_display_get_pointer(gdk_display_get_default(),
                             NULL, NULL, NULL, &modifiers);
--- a/widget/nsIBidiKeyboard.idl
+++ b/widget/nsIBidiKeyboard.idl
@@ -1,20 +1,25 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
-[scriptable, uuid(99957506-f21b-4a61-ad64-5b641cf508e2)]
+[scriptable, uuid(44d9ef13-83be-4ab9-a2a1-95d9cbd96acd)]
 interface nsIBidiKeyboard : nsISupports
 {
   /**
+   * Inspects the installed keyboards and resets the bidi keyboard state
+   */
+  void reset();
+
+  /**
    * Determines if the current keyboard language is right-to-left
    * @throws NS_ERROR_FAILURE if no right-to-left keyboards are installed
    */
   boolean isLangRTL();
 
   /**
    * Sets the keyboard language to left-to-right or right-to-left
    * @param aLevel - if odd set the keyboard to RTL, if even set LTR 
--- a/widget/os2/nsBidiKeyboard.cpp
+++ b/widget/os2/nsBidiKeyboard.cpp
@@ -5,22 +5,28 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsBidiKeyboard.h"
 
 NS_IMPL_ISUPPORTS1(nsBidiKeyboard, nsIBidiKeyboard)
 
 nsBidiKeyboard::nsBidiKeyboard() : nsIBidiKeyboard()
 {
+  Reset();
 }
 
 nsBidiKeyboard::~nsBidiKeyboard()
 {
 }
 
+NS_IMETHODIMP nsBidiKeyboard::Reset()
+{
+  return NS_OK;
+}
+
 NS_IMETHODIMP nsBidiKeyboard::IsLangRTL(bool *aIsRTL)
 {
   *aIsRTL = false;
   // XXX Insert platform specific code to determine keyboard direction
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP nsBidiKeyboard::SetLangFromBidiLevel(uint8_t aLevel)
--- a/widget/qt/nsBidiKeyboard.cpp
+++ b/widget/qt/nsBidiKeyboard.cpp
@@ -9,22 +9,28 @@
 #include <QApplication>
 
 #include "nsBidiKeyboard.h"
 
 NS_IMPL_ISUPPORTS1(nsBidiKeyboard, nsIBidiKeyboard)
 
 nsBidiKeyboard::nsBidiKeyboard() : nsIBidiKeyboard()
 {
+  Reset();
 }
 
 nsBidiKeyboard::~nsBidiKeyboard()
 {
 }
 
+NS_IMETHODIMP nsBidiKeyboard::Reset()
+{
+  return NS_OK;
+}
+
 NS_IMETHODIMP nsBidiKeyboard::IsLangRTL(bool *aIsRTL)
 {
     *aIsRTL = false;
 
 #if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
     Qt::LayoutDirection layoutDir = QApplication::keyboardInputDirection();
 #else
     QInputMethod* input = qApp->inputMethod();
--- a/widget/windows/nsBidiKeyboard.cpp
+++ b/widget/windows/nsBidiKeyboard.cpp
@@ -8,25 +8,31 @@
 #include "nsBidiKeyboard.h"
 #include "prmem.h"
 #include <tchar.h>
 
 NS_IMPL_ISUPPORTS1(nsBidiKeyboard, nsIBidiKeyboard)
 
 nsBidiKeyboard::nsBidiKeyboard() : nsIBidiKeyboard()
 {
+  Reset();
+}
+
+nsBidiKeyboard::~nsBidiKeyboard()
+{
+}
+
+NS_IMETHODIMP nsBidiKeyboard::Reset()
+{
   mInitialized = false;
   mHaveBidiKeyboards = false;
   mLTRKeyboard[0] = '\0';
   mRTLKeyboard[0] = '\0';
   mCurrentLocaleName[0] = '\0';
-}
-
-nsBidiKeyboard::~nsBidiKeyboard()
-{
+  return NS_OK;
 }
 
 NS_IMETHODIMP nsBidiKeyboard::SetLangFromBidiLevel(uint8_t aLevel)
 {
   nsresult result = SetupBidiKeyboards();
   if (NS_FAILED(result))
     return result;