Bug 455339: Disable word completion widget (software keyboard bar at bottom of screen) for fennec/maemo. r=stuart
authorAntonio Gomes (tonikitoo) <tonikitoo@gmail.com>
Fri, 27 Feb 2009 21:47:40 -0400
changeset 25618 f7f62131998dbf9c3c7f8dc1d249aabafe058792
parent 25617 4d4e400e1301293ea67651c70de77030119b84ed
child 25619 f3d5f4a980a071608ea69e724f3eacb7893e988f
push id5651
push usertonikitoo@gmail.com
push dateSat, 28 Feb 2009 01:48:15 +0000
treeherdermozilla-central@f7f62131998d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersstuart
bugs455339
milestone1.9.2a1pre
Bug 455339: Disable word completion widget (software keyboard bar at bottom of screen) for fennec/maemo. r=stuart
widget/src/gtk2/Makefile.in
widget/src/gtk2/nsWindow.cpp
--- a/widget/src/gtk2/Makefile.in
+++ b/widget/src/gtk2/Makefile.in
@@ -1,9 +1,9 @@
-# 
+#
 # ***** BEGIN LICENSE BLOCK *****
 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
 #
 # The contents of this file are subject to the Mozilla Public License Version
 # 1.1 (the "License"); you may not use this file except in compliance with
 # the License. You may obtain a copy of the License at
 # http://www.mozilla.org/MPL/
 #
@@ -140,16 +140,22 @@ EXTRA_DSO_LDOPTS += \
 		$(XLIBS) \
 		$(XEXT_LIBS) \
 		$(XCOMPOSITE_LIBS) \
 		$(MOZ_GTK2_LIBS) \
 		-lthebes \
 		$(LCMS_LIBS) \
 		$(NULL)
 
+ifdef MOZ_PLATFORM_HILDON
+ifdef MOZ_ENABLE_GCONF
+EXTRA_DSO_LDOPTS += $(MOZ_GCONF_LIBS)
+endif
+endif
+
 ifdef MOZ_X11
 EXTRA_DSO_LDOPTS += -lgtkxtbin -lXrender
 endif
 
 EXPORTS		= \
                 nsGTKToolkit.h \
 		nsIImageToPixbuf.h \
 		mozdrawingarea.h \
@@ -162,26 +168,32 @@ CPPSRCS		+= nsNativeThemeGTK.cpp
 DEFINES		+= -DNATIVE_THEME_SUPPORT
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 CFLAGS          += $(MOZ_GTK2_CFLAGS) $(MOZ_STARTUP_NOTIFICATION_CFLAGS)
 CXXFLAGS        += $(MOZ_GTK2_CFLAGS) $(MOZ_STARTUP_NOTIFICATION_CFLAGS)
 
+ifdef MOZ_PLATFORM_HILDON
+ifdef MOZ_ENABLE_GCONF
+CXXFLAGS += $(MOZ_GCONF_CFLAGS)
+endif
+endif
+
 DEFINES         += -DUSE_XIM
 DEFINES		+= -DCAIRO_GFX
 
 ifdef MOZ_ENABLE_POSTSCRIPT
 DEFINES         += -DUSE_POSTSCRIPT
 EXTRA_DSO_LDOPTS += -lgfxpsshar
 endif
 
 
-DEFINES		+= 
+DEFINES		+=
 INCLUDES	+= \
 		-I$(srcdir)/../xpwidgets \
 		-I$(topsrcdir)/other-licenses/atk-1.0 \
 		$(NULL)
 
 test_container: mozdrawingarea.o mozcontainer.o test_container.c
 	$(CC) $(MOZ_GTK2_CFLAGS) -o test_container test_container.c \
 		mozdrawingarea.o mozcontainer.o \
--- a/widget/src/gtk2/nsWindow.cpp
+++ b/widget/src/gtk2/nsWindow.cpp
@@ -114,16 +114,23 @@ static const char sAccessibilityKey [] =
 #include "gfxPlatformGtk.h"
 #include "gfxContext.h"
 #include "gfxImageSurface.h"
 
 #ifdef MOZ_X11
 #include "gfxXlibSurface.h"
 #endif
 
+#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_ENABLE_GCONF)
+#include "gconf/gconf-client.h"
+static PRBool gWidgetCompletionEnabled = PR_FALSE;
+static const char sWidgetCompletionGConfPref [] =
+    "/apps/osso/inputmethod/hildon-im-languages/en_GB/word-completion";
+#endif
+
 #ifdef MOZ_DFB
 extern "C" {
 #ifdef MOZ_DIRECT_DEBUG
 #define DIRECT_ENABLE_DEBUG
 #endif
 
 #include <direct/debug.h>
 
@@ -420,17 +427,17 @@ nsWindow::nsWindow()
     mDFBCursorY     = 0;
 
     mDFBCursorCount = 0;
 
     mDFB            = NULL;
     mDFBLayer       = NULL;
 #endif
 
-    
+
     if (gUseBufferPixmap) {
         if (gBufferPixmapMaxSize.width == 0) {
             gBufferPixmapMaxSize.width = gdk_screen_width();
             gBufferPixmapMaxSize.height = gdk_screen_height();
         }
 
         gBufferPixmapUsageCount++;
     }
@@ -445,17 +452,17 @@ nsWindow::~nsWindow()
     }
 
     delete[] mTransparencyBitmap;
     mTransparencyBitmap = nsnull;
 
 #ifdef MOZ_DFB
     if (mDFBLayer)
          mDFBLayer->Release( mDFBLayer );
-         
+
     if (mDFB)
          mDFB->Release( mDFB );
 #endif
 
     Destroy();
 }
 
 /* static */ void
@@ -525,17 +532,17 @@ nsWindow::DispatchResizeEvent(nsIntRect 
 
     event.windowSize = &aRect;
     event.refPoint.x = aRect.x;
     event.refPoint.y = aRect.y;
     event.mWinWidth = aRect.width;
     event.mWinHeight = aRect.height;
 
     nsEventStatus status;
-    DispatchEvent(&event, status); 
+    DispatchEvent(&event, status);
 }
 
 void
 nsWindow::DispatchActivateEvent(void)
 {
 #ifdef ACCESSIBILITY
     DispatchActivateEventAccessible();
 #endif //ACCESSIBILITY
@@ -1029,17 +1036,17 @@ nsWindow::Resize(PRInt32 aX, PRInt32 aY,
 }
 
 NS_IMETHODIMP
 nsWindow::GetPreferredSize(PRInt32 &aWidth,
                                  PRInt32 &aHeight)
 {
     aWidth  = mPreferredWidth;
     aHeight = mPreferredHeight;
-    return (mPreferredWidth != 0 && mPreferredHeight != 0) ? 
+    return (mPreferredWidth != 0 && mPreferredHeight != 0) ?
         NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsWindow::SetPreferredSize(PRInt32 aWidth,
                                  PRInt32 aHeight)
 {
     mPreferredWidth  = aWidth;
@@ -1122,17 +1129,17 @@ nsWindow::SetZIndex(PRInt32 aZIndex)
     // We skip the nsWindows that don't have mDrawingareas.
     // These are probably in the process of being destroyed.
 
     if (!GetNextSibling()) {
         // We're to be on top.
         if (mDrawingarea)
             gdk_window_raise(mDrawingarea->clip_window);
     } else {
-        // All the siblings before us need to be below our widget. 
+        // All the siblings before us need to be below our widget.
         for (nsWindow* w = this; w;
              w = static_cast<nsWindow*>(w->GetPrevSibling())) {
             if (w->mDrawingarea)
                 gdk_window_lower(w->mDrawingarea->clip_window);
         }
     }
     return NS_OK;
 }
@@ -1197,17 +1204,17 @@ SetUserTimeAndStartupIDForActivatedWindo
         // that triggered it.
         PRUint32 timestamp = GTKToolkit->GetFocusTimestamp();
         if (timestamp) {
             gdk_window_focus(aWindow->window, timestamp);
             GTKToolkit->SetFocusTimestamp(0);
         }
         return;
     }
- 
+
 #ifdef MOZ_ENABLE_STARTUP_NOTIFICATION
     GdkDrawable* drawable = GDK_DRAWABLE(aWindow->window);
     GtkWindow* win = GTK_WINDOW(aWindow);
     if (!win) {
         NS_WARNING("Passed in widget was not a GdkWindow!");
         return;
     }
     GdkScreen* screen = gtk_window_get_screen(win);
@@ -1234,19 +1241,19 @@ SetUserTimeAndStartupIDForActivatedWindo
     }
 
     sn_launchee_context_setup_window(ctx, gdk_x11_drawable_get_xid(drawable));
     sn_launchee_context_complete(ctx);
 
     sn_launchee_context_unref(ctx);
     sn_display_unref(snd);
 #endif
- 
+
     GTKToolkit->SetDesktopStartupID(EmptyCString());
-} 
+}
 
 NS_IMETHODIMP
 nsWindow::SetFocus(PRBool aRaise)
 {
     // Make sure that our owning widget has focus.  If it doesn't try to
     // grab it.  Note that we don't set our focus flag in this case.
 
     LOGFOCUS(("  SetFocus [%p]\n", (void *)this));
@@ -1274,23 +1281,23 @@ nsWindow::SetFocus(PRBool aRaise)
 
     nsRefPtr<nsWindow> owningWindow = get_window_for_gtk_widget(owningWidget);
     if (!owningWindow)
         return NS_ERROR_FAILURE;
 
     if (!GTK_WIDGET_HAS_FOCUS(owningWidget)) {
         LOGFOCUS(("  grabbing focus for the toplevel [%p]\n", (void *)this));
         owningWindow->mContainerBlockFocus = PR_TRUE;
-        
+
         // Set focus to the window
         if (gRaiseWindows && aRaise && toplevelWidget &&
             !GTK_WIDGET_HAS_FOCUS(toplevelWidget) &&
             owningWindow->mIsShown && GTK_IS_WINDOW(owningWindow->mShell))
           gtk_window_present(GTK_WINDOW(owningWindow->mShell));
-        
+
         gtk_widget_grab_focus(owningWidget);
         owningWindow->mContainerBlockFocus = PR_FALSE;
 
         DispatchGotFocusEvent();
 
         // unset the activate flag
         if (owningWindow->mActivatePending) {
             owningWindow->mActivatePending = PR_FALSE;
@@ -1403,17 +1410,17 @@ nsWindow::SetCursor(nsCursor aCursor)
 
 
 static
 PRUint8* Data32BitTo1Bit(PRUint8* aImageData,
                          PRUint32 aImageBytesPerRow,
                          PRUint32 aWidth, PRUint32 aHeight)
 {
   PRUint32 outBpr = (aWidth + 7) / 8;
-  
+
   PRUint8* outData = new PRUint8[outBpr * aHeight];
   if (!outData)
       return NULL;
 
   PRUint8 *outRow = outData,
           *imageRow = aImageData;
 
   for (PRUint32 curRow = 0; curRow < aHeight; curRow++) {
@@ -2041,36 +2048,36 @@ gdk_window_flash(GdkWindow *    aGdkWind
 
   gc = gdk_gc_new(GDK_ROOT_PARENT());
 
   white.pixel = WhitePixel(gdk_display,DefaultScreen(gdk_display));
 
   gdk_gc_set_foreground(gc,&white);
   gdk_gc_set_function(gc,GDK_XOR);
   gdk_gc_set_subwindow(gc,GDK_INCLUDE_INFERIORS);
-  
+
   gdk_region_offset(aRegion, x, y);
   gdk_gc_set_clip_region(gc, aRegion);
 
   /*
-   * Need to do this twice so that the XOR effect can replace 
+   * Need to do this twice so that the XOR effect can replace
    * the original window contents.
    */
   for (i = 0; i < aTimes * 2; i++)
   {
     gdk_draw_rectangle(GDK_ROOT_PARENT(),
                        gc,
                        TRUE,
                        x,
                        y,
                        width,
                        height);
 
     gdk_flush();
-    
+
     PR_Sleep(PR_MillisecondsToInterval(aInterval));
   }
 
   gdk_gc_destroy(gc);
 
   gdk_region_offset(aRegion, -x, -y);
 }
 #endif /* MOZ_X11 */
@@ -2242,17 +2249,17 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
             bufferPixmapSurface = GetSurfaceForGdkDrawable(GDK_DRAWABLE(bufferPixmap),
                                                            nsIntSize(bufferPixmapSize.width, bufferPixmapSize.height));
 
             if (bufferPixmapSurface && bufferPixmapSurface->CairoStatus()) {
                 bufferPixmapSurface = nsnull;
             }
             if (bufferPixmapSurface) {
                 gfxPlatformGtk::GetPlatform()->SetGdkDrawable(
-                        static_cast<gfxASurface *>(bufferPixmapSurface), 
+                        static_cast<gfxASurface *>(bufferPixmapSurface),
                         GDK_DRAWABLE(bufferPixmap));
 
                 bufferPixmapSurface->SetDeviceOffset(gfxPoint(-boundsRect.x, -boundsRect.y));
                 nsCOMPtr<nsIRenderingContext> newRC;
                 nsresult rv = GetDeviceContext()->
                     CreateRenderingContextInstance(*getter_AddRefs(newRC));
                 if (NS_FAILED(rv)) {
                     bufferPixmapSurface = nsnull;
@@ -2301,17 +2308,17 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
                 ctx->SetPattern(pattern);
                 ctx->Paint();
 
                 nsRefPtr<gfxImageSurface> img =
                     new gfxImageSurface(gfxIntSize(boundsRect.width, boundsRect.height),
                                         gfxImageSurface::ImageFormatA8);
                 if (img && !img->CairoStatus()) {
                     img->SetDeviceOffset(gfxPoint(-boundsRect.x, -boundsRect.y));
-            
+
                     nsRefPtr<gfxContext> imgCtx = new gfxContext(img);
                     if (imgCtx) {
                         imgCtx->SetPattern(pattern);
                         imgCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
                         imgCtx->Paint();
                     }
 
                     UpdateTranslucentWindowAlphaInternal(nsIntRect(boundsRect.x, boundsRect.y,
@@ -2808,19 +2815,43 @@ nsWindow::OnContainerFocusInEvent(GtkWid
     // Return if someone has blocked events for this widget.  This will
     // happen if someone has called gtk_widget_grab_focus() from
     // nsWindow::SetFocus() and will prevent recursion.
     if (mContainerBlockFocus) {
         LOGFOCUS(("Container focus is blocked [%p]\n", (void *)this));
         return;
     }
 
-    if (mIsTopLevel)
+    if (mIsTopLevel) {
         mActivatePending = PR_TRUE;
-
+#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_ENABLE_GCONF)
+        // For mobile/maemo, it is desired to disable the word completion widget
+        // at the bottom of the screen for some reasons: it interacts badly with
+        // keyboard events sometimes and disabling it will give more screen space
+        // for web content. So whenever a topLevel mobile window gets the focus we
+        // verify what is the current state of the widget-completion through query
+        // the proper gconf property. If it is enabled, we store the property value
+        // and disable it. Where the toplevel window loses the focus we restore the
+        // previous state of the widget completion property so other applications in
+        // the system do not get affected. See 'OnContainerFocusOutEvent'.
+        if (mWindowType == eWindowType_toplevel)
+            if (GConfClient *gConfClient = gconf_client_get_default()) {
+                GError* error = nsnull;
+                gWidgetCompletionEnabled = gconf_client_get_bool(gConfClient,
+                                                                 sWidgetCompletionGConfPref,
+                                                                 &error);
+                if (error)
+                    g_error_free(error);
+                else if (gWidgetCompletionEnabled)
+                    gconf_client_set_bool(gConfClient, sWidgetCompletionGConfPref,
+                                          PR_FALSE, nsnull);
+                g_object_unref(gConfClient);
+            }
+#endif
+    }
     // Unset the urgency hint, if possible
     GtkWidget* top_window = nsnull;
     GetToplevelWidget(&top_window);
     if (top_window && (GTK_WIDGET_VISIBLE(top_window)))
         SetUrgencyHint(top_window, PR_FALSE);
 
     // dispatch a got focus event
     DispatchGotFocusEvent();
@@ -2849,16 +2880,26 @@ nsWindow::OnContainerFocusOutEvent(GtkWi
     }
 #endif /* MOZ_X11 */
 
     // Figure out if the focus widget is the child of this window.  If
     // it is, send a focus out and deactivate event for it.
     if (!gFocusWindow)
         return;
 
+#if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_ENABLE_GCONF)
+    if (mIsTopLevel && mWindowType == eWindowType_toplevel)
+        if(GConfClient *gConfClient = gconf_client_get_default()) {
+            GError* error = nsnull;
+            gconf_client_set_bool(gConfClient, sWidgetCompletionGConfPref, gWidgetCompletionEnabled, &error);
+            if (error)
+                g_error_free(error);
+            g_object_unref(gConfClient);
+        }
+#endif
     GdkWindow *tmpWindow;
     tmpWindow = (GdkWindow *)gFocusWindow->GetNativeData(NS_NATIVE_WINDOW);
     nsWindow *tmpnsWindow = get_window_for_gdk_window(tmpWindow);
 
     while (tmpWindow && tmpnsWindow) {
         // found it!
         if (tmpnsWindow == this)
             goto foundit;
@@ -2971,17 +3012,17 @@ nsWindow::OnKeyPressEvent(GtkWidget *aWi
 
     // If the key down flag isn't set then set it so we don't send
     // another key down event on the next key press -- DOM events are
     // key down, key press and key up.  X only has key press and key
     // release.  gtk2 already filters the extra key release events for
     // us.
 
     PRBool isKeyDownCancelled = PR_FALSE;
-    
+
     PRUint32 domVirtualKeyCode = GdkKeyCodeToDOMKeyCode(aEvent->keyval);
 
     if (!IsKeyDown(domVirtualKeyCode)) {
         SetKeyDownFlag(domVirtualKeyCode);
 
         // send the key down event
         nsKeyEvent downEvent(PR_TRUE, NS_KEY_DOWN, this);
         InitKeyEvent(downEvent, aEvent);
@@ -3610,17 +3651,17 @@ nsWindow::OnDragEnter(nscoord aX, nscoor
 
     nsEventStatus status;
     DispatchEvent(&event, status);
 }
 
 static void
 GetBrandName(nsXPIDLString& brandName)
 {
-    nsCOMPtr<nsIStringBundleService> bundleService = 
+    nsCOMPtr<nsIStringBundleService> bundleService =
         do_GetService(NS_STRINGBUNDLE_CONTRACTID);
 
     nsCOMPtr<nsIStringBundle> bundle;
     if (bundleService)
         bundleService->CreateBundle(
             "chrome://branding/locale/brand.properties",
             getter_AddRefs(bundle));
 
@@ -6108,26 +6149,26 @@ nsWindow::IMEReleaseData(void)
     mIMEData = nsnull;
 }
 
 // Work around gtk bug http://bugzilla.gnome.org/show_bug.cgi?id=483223:
 // (and the similar issue of GTK+ IIIM)
 // The GTK+ XIM and IIIM modules register handlers for the "closed" signal
 // on the display, but:
 //  * The signal handlers are not disconnected when the module is unloaded.
-// 
-// The GTK+ XIM module has another problem: 
+//
+// The GTK+ XIM module has another problem:
 //  * When the signal handler is run (with the module loaded) it tries
 //    XFree (and fails) on a pointer that did not come from Xmalloc.
 //
 // To prevent these modules from being unloaded, use static variables to
 // hold ref of GtkIMContext class.
 // For GTK+ XIM module, to prevent the signal handler from being run,
 // find the signal handlers and remove them.
-//  
+//
 // GtkIMContextXIMs share XOpenIM connections and display closed signal
 // handlers (where possible).
 
 static void workaround_gtk_im_display_closed(GtkWidget *aGtkWidget,
                                              GtkIMContext *aContext)
 {
     GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (aContext);
     GtkIMContext *slave = multicontext->slave;
@@ -6579,17 +6620,17 @@ nsWindow::SetIMEEnabled(PRUint32 aState)
             g_object_set (G_OBJECT(focusedIm), "hildon-input-mode", (HildonGtkInputMode)mode, NULL);
             gIMEVirtualKeyboardOpened = PR_TRUE;
             hildon_gtk_im_context_show (focusedIm);
         } else {
             gIMEVirtualKeyboardOpened = PR_FALSE;
             hildon_gtk_im_context_hide (focusedIm);
         }
 #endif
-        
+
     } else {
         if (IsIMEEditableState(mIMEData->mEnabled))
             ResetInputState();
         mIMEData->mEnabled = aState;
     }
 
     return NS_OK;
 }
@@ -7009,17 +7050,17 @@ nsWindow::BeginResizeDrag(nsGUIEvent* aE
     NS_ENSURE_ARG_POINTER(aEvent);
 
     if (aEvent->eventStructType != NS_MOUSE_EVENT) {
       // you can only begin a resize drag with a mouse event
       return NS_ERROR_INVALID_ARG;
     }
 
     nsMouseEvent* mouse_event = static_cast<nsMouseEvent*>(aEvent);
-    
+
     if (mouse_event->button != nsMouseEvent::eLeftButton) {
       // you can only begin a resize drag with the left mouse button
       return NS_ERROR_INVALID_ARG;
     }
 
     // work out what GdkWindowEdge we're talking about
     GdkWindowEdge window_edge;
     if (aVertical < 0) {