b=808873 return toplevel GtkWidget for NS_NATIVE_SHELLWIDGET and use it r=roc
authorKarl Tomlinson <karlt+@karlt.net>
Wed, 07 Nov 2012 10:50:37 +1300
changeset 112434 dfe49308dc99ea6ba5cfc84c55e87377eecc6168
parent 112433 0f45d415a22112d690ecc7aa496c208f092e02a6
child 112435 29a7fc6e3930dc9f3219406701ad163e3d813f80
push id17595
push userktomlinson@mozilla.com
push dateTue, 06 Nov 2012 21:53:47 +0000
treeherdermozilla-inbound@3523098f7911 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs808873
milestone19.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
b=808873 return toplevel GtkWidget for NS_NATIVE_SHELLWIDGET and use it r=roc
toolkit/components/remote/nsGTKRemoteService.cpp
widget/gtk2/nsFilePicker.cpp
widget/gtk2/nsPrintDialogGTK.cpp
widget/gtk2/nsWindow.cpp
widget/gtk2/nsWindow.h
widget/nsIWidget.h
--- a/toolkit/components/remote/nsGTKRemoteService.cpp
+++ b/toolkit/components/remote/nsGTKRemoteService.cpp
@@ -79,27 +79,16 @@ static nsIWidget* GetMainWidget(nsIDOMWi
 }
 
 NS_IMETHODIMP
 nsGTKRemoteService::RegisterWindow(nsIDOMWindow* aWindow)
 {
   nsIWidget* mainWidget = GetMainWidget(aWindow);
   NS_ENSURE_TRUE(mainWidget, NS_ERROR_FAILURE);
 
-  // walk up the widget tree and find the toplevel window in the
-  // hierarchy
-
-  nsIWidget* tempWidget = mainWidget->GetParent();
-
-  while (tempWidget) {
-    tempWidget = tempWidget->GetParent();
-    if (tempWidget)
-      mainWidget = tempWidget;
-  }
-
   GtkWidget* widget =
     (GtkWidget*) mainWidget->GetNativeData(NS_NATIVE_SHELLWIDGET);
   NS_ENSURE_TRUE(widget, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference(aWindow);
   NS_ENSURE_TRUE(weak, NS_ERROR_FAILURE);
 
   if (!mWindows.IsInitialized())
--- a/widget/gtk2/nsFilePicker.cpp
+++ b/widget/gtk2/nsFilePicker.cpp
@@ -38,41 +38,16 @@ template<class T> static inline gpointer
 FuncToGpointer(T aFunction)
 {
     return reinterpret_cast<gpointer>
         (reinterpret_cast<uintptr_t>
          // This cast just provides a warning if T is not a function.
          (reinterpret_cast<void (*)()>(aFunction)));
 }
 
-// XXXdholbert -- this function is duplicated in nsPrintDialogGTK.cpp
-// and needs to be unified in some generic utility class.
-static GtkWindow *
-get_gtk_window_for_nsiwidget(nsIWidget *widget)
-{
-  // Get native GdkWindow
-  GdkWindow *gdk_win = GDK_WINDOW(widget->GetNativeData(NS_NATIVE_WIDGET));
-  if (!gdk_win)
-    return NULL;
-
-  // Get the container
-  gpointer user_data = NULL;
-  gdk_window_get_user_data(gdk_win, &user_data);
-  if (!user_data)
-    return NULL;
-
-  // Make sure its really a container
-  MozContainer *parent_container = MOZ_CONTAINER(user_data);
-  if (!parent_container)
-    return NULL;
-
-  // Get its toplevel
-  return GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(parent_container)));
-}
-
 void
 nsFilePicker::Shutdown()
 {
   NS_IF_RELEASE(mPrevDisplayDirectory);
 }
 
 static GtkFileChooserAction
 GetGtkFileChooserAction(int16_t aMode)
@@ -388,17 +363,18 @@ nsFilePicker::Open(nsIFilePickerShownCal
 {
   // Can't show two dialogs concurrently with the same filepicker
   if (mRunning)
     return NS_ERROR_NOT_AVAILABLE;
 
   nsXPIDLCString title;
   title.Adopt(ToNewUTF8String(mTitle));
 
-  GtkWindow *parent_widget = get_gtk_window_for_nsiwidget(mParentWidget);
+  GtkWindow *parent_widget =
+    GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET));
 
   GtkFileChooserAction action = GetGtkFileChooserAction(mMode);
   const gchar *accept_button = (action == GTK_FILE_CHOOSER_ACTION_SAVE)
                                ? GTK_STOCK_SAVE : GTK_STOCK_OPEN;
 #if (MOZ_PLATFORM_MAEMO == 5)
   GtkWidget *file_chooser =
     hildon_file_chooser_dialog_new_with_properties(parent_widget,
                                                    "action", action,
--- a/widget/gtk2/nsPrintDialogGTK.cpp
+++ b/widget/gtk2/nsPrintDialogGTK.cpp
@@ -33,39 +33,20 @@
 
 using namespace mozilla;
 using namespace mozilla::widget;
 
 static const char header_footer_tags[][4] =  {"", "&T", "&U", "&D", "&P", "&PT"};
 
 #define CUSTOM_VALUE_INDEX ArrayLength(header_footer_tags)
 
-// XXXdholbert Duplicated from widget/gtk2/nsFilePicker.cpp
-// Needs to be unified in some generic utility class.
 static GtkWindow *
 get_gtk_window_for_nsiwidget(nsIWidget *widget)
 {
-  // Get native GdkWindow
-  GdkWindow *gdk_win = GDK_WINDOW(widget->GetNativeData(NS_NATIVE_WIDGET));
-  if (!gdk_win)
-    return NULL;
-
-  // Get the container
-  gpointer user_data = NULL;
-  gdk_window_get_user_data(gdk_win, &user_data);
-  if (!user_data)
-    return NULL;
-
-  // Make sure its really a container
-  MozContainer *parent_container = MOZ_CONTAINER(user_data);
-  if (!parent_container)
-    return NULL;
-
-  // Get its toplevel
-  return GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(parent_container)));
+  return GTK_WINDOW(widget->GetNativeData(NS_NATIVE_SHELLWIDGET));
 }
 
 static void
 ShowCustomDialog(GtkComboBox *changed_box, gpointer user_data)
 {
   if (gtk_combo_box_get_active(changed_box) != CUSTOM_VALUE_INDEX) {
     g_object_set_data(G_OBJECT(changed_box), "previous-active", GINT_TO_POINTER(gtk_combo_box_get_active(changed_box)));
     return;
--- a/widget/gtk2/nsWindow.cpp
+++ b/widget/gtk2/nsWindow.cpp
@@ -1382,18 +1382,17 @@ nsWindow::SetFocus(bool aRaise)
 
     // Raise the window if someone passed in true and the prefs are
     // set properly.
     GtkWidget *toplevelWidget = gtk_widget_get_toplevel(owningWidget);
 
     if (gRaiseWindows && aRaise && toplevelWidget &&
         !gtk_widget_has_focus(owningWidget) &&
         !gtk_widget_has_focus(toplevelWidget)) {
-        GtkWidget* top_window = nullptr;
-        GetToplevelWidget(&top_window);
+        GtkWidget* top_window = GetToplevelWidget();
         if (top_window && (gtk_widget_get_visible(top_window)))
         {
             gdk_window_show_unraised(gtk_widget_get_window(top_window));
             // Unset the urgency hint if possible.
             SetUrgencyHint(top_window, false);
         }
     }
 
@@ -1684,17 +1683,17 @@ nsWindow::GetNativeData(uint32_t aDataTy
 #ifdef MOZ_X11
         return GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
 #else
         return nullptr;
 #endif /* MOZ_X11 */
         break;
 
     case NS_NATIVE_SHELLWIDGET:
-        return (void *) mShell;
+        return GetToplevelWidget();
 
     case NS_NATIVE_SHAREABLE_WINDOW:
         return (void *) GDK_WINDOW_XID(gdk_window_get_toplevel(mGdkWindow));
 
     default:
         NS_WARNING("nsWindow::GetNativeData called with bad value");
         return nullptr;
     }
@@ -1868,21 +1867,19 @@ nsWindow::CaptureRollupEvents(nsIRollupL
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::GetAttention(int32_t aCycleCount)
 {
     LOG(("nsWindow::GetAttention [%p]\n", (void *)this));
 
-    GtkWidget* top_window = nullptr;
-    GtkWidget* top_focused_window = nullptr;
-    GetToplevelWidget(&top_window);
-    if (gFocusWindow)
-        gFocusWindow->GetToplevelWidget(&top_focused_window);
+    GtkWidget* top_window = GetToplevelWidget();
+    GtkWidget* top_focused_window =
+        gFocusWindow->GetToplevelWidget();
 
     // Don't get attention if the window is focused anyway.
     if (top_window && (gtk_widget_get_visible(top_window)) &&
         top_window != top_focused_window) {
         SetUrgencyHint(top_window, true);
     }
 
     return NS_OK;
@@ -2785,18 +2782,17 @@ void
 nsWindow::OnContainerFocusInEvent(GdkEventFocus *aEvent)
 {
     NS_ASSERTION(mWindowType != eWindowType_popup,
                  "Unexpected focus on a popup window");
 
     LOGFOCUS(("OnContainerFocusInEvent [%p]\n", (void *)this));
 
     // Unset the urgency hint, if possible
-    GtkWidget* top_window = nullptr;
-    GetToplevelWidget(&top_window);
+    GtkWidget* top_window = GetToplevelWidget();
     if (top_window && (gtk_widget_get_visible(top_window)))
         SetUrgencyHint(top_window, false);
 
     // Return if being called within SetFocus because the focus manager
     // already knows that the window is active.
     if (gBlockActivateEvent) {
         LOGFOCUS(("activated notification is blocked [%p]\n", (void *)this));
         return;
@@ -4023,18 +4019,17 @@ nsWindow::CleanLayerManagerRecursive(voi
     }
 }
 
 void
 nsWindow::SetTransparencyMode(nsTransparencyMode aMode)
 {
     if (!mShell) {
         // Pass the request to the toplevel window
-        GtkWidget *topWidget = nullptr;
-        GetToplevelWidget(&topWidget);
+        GtkWidget *topWidget = GetToplevelWidget();
         if (!topWidget)
             return;
 
         nsWindow *topWindow = get_window_for_gtk_widget(topWidget);
         if (!topWindow)
             return;
 
         topWindow->SetTransparencyMode(aMode);
@@ -4057,18 +4052,17 @@ nsWindow::SetTransparencyMode(nsTranspar
     CleanLayerManagerRecursive();
 }
 
 nsTransparencyMode
 nsWindow::GetTransparencyMode()
 {
     if (!mShell) {
         // Pass the request to the toplevel window
-        GtkWidget *topWidget = nullptr;
-        GetToplevelWidget(&topWidget);
+        GtkWidget *topWidget = GetToplevelWidget();
         if (!topWidget) {
             return eTransparencyOpaque;
         }
 
         nsWindow *topWindow = get_window_for_gtk_widget(topWidget);
         if (!topWindow) {
             return eTransparencyOpaque;
         }
@@ -4373,18 +4367,17 @@ nsWindow::ClearTransparencyBitmap()
 }
 
 nsresult
 nsWindow::UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect,
                                                uint8_t* aAlphas, int32_t aStride)
 {
     if (!mShell) {
         // Pass the request to the toplevel window
-        GtkWidget *topWidget = nullptr;
-        GetToplevelWidget(&topWidget);
+        GtkWidget *topWidget = GetToplevelWidget();
         if (!topWidget)
             return NS_ERROR_FAILURE;
 
         nsWindow *topWindow = get_window_for_gtk_widget(topWidget);
         if (!topWindow)
             return NS_ERROR_FAILURE;
 
         return topWindow->UpdateTranslucentWindowAlphaInternal(aRect, aAlphas, aStride);
@@ -4469,31 +4462,28 @@ void
 nsWindow::ReleaseGrabs(void)
 {
     LOG(("ReleaseGrabs\n"));
 
     mRetryPointerGrab = false;
     gdk_pointer_ungrab(GDK_CURRENT_TIME);
 }
 
-void
-nsWindow::GetToplevelWidget(GtkWidget **aWidget)
-{
-    *aWidget = nullptr;
-
+GtkWidget *
+nsWindow::GetToplevelWidget()
+{
     if (mShell) {
-        *aWidget = mShell;
-        return;
+        return mShell;
     }
 
     GtkWidget *widget = GetMozContainerWidget();
     if (!widget)
-        return;
-
-    *aWidget = gtk_widget_get_toplevel(widget);
+        return nullptr;
+
+    return gtk_widget_get_toplevel(widget);
 }
 
 GtkWidget *
 nsWindow::GetMozContainerWidget()
 {
     if (!mGdkWindow)
         return NULL;
 
@@ -4719,18 +4709,17 @@ nsWindow::MakeFullScreen(bool aFullScree
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::HideWindowChrome(bool aShouldHide)
 {
     if (!mShell) {
         // Pass the request to the toplevel window
-        GtkWidget *topWidget = nullptr;
-        GetToplevelWidget(&topWidget);
+        GtkWidget *topWidget = GetToplevelWidget();
         if (!topWidget)
             return NS_ERROR_FAILURE;
 
         nsWindow *topWindow = get_window_for_gtk_widget(topWidget);
         if (!topWindow)
             return NS_ERROR_FAILURE;
 
         return topWindow->HideWindowChrome(aShouldHide);
--- a/widget/gtk2/nsWindow.h
+++ b/widget/gtk2/nsWindow.h
@@ -321,17 +321,17 @@ protected:
     bool                mNeedsShow;
     // is this widget enabled?
     bool                mEnabled;
     // has the native window for this been created yet?
     bool                mCreated;
 
 private:
     void               DestroyChildWindows();
-    void               GetToplevelWidget(GtkWidget **aWidget);
+    GtkWidget         *GetToplevelWidget();
     nsWindow          *GetContainerWindow();
     void               SetUrgencyHint(GtkWidget *top_window, bool state);
     void              *SetupPluginPort(void);
     void               SetDefaultIcon(void);
     void               InitButtonEvent(nsMouseEvent &aEvent, GdkEventButton *aGdkEvent);
     bool               DispatchCommandEvent(nsIAtom* aCommand);
     bool               DispatchContentCommandEvent(int32_t aMsg);
     void               SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -69,17 +69,18 @@ typedef nsEventStatus (* EVENT_CALLBACK)
 #define NS_NATIVE_TMP_WINDOW  2
 #define NS_NATIVE_WIDGET      3
 #define NS_NATIVE_DISPLAY     4
 #define NS_NATIVE_REGION      5
 #define NS_NATIVE_OFFSETX     6
 #define NS_NATIVE_OFFSETY     7
 #define NS_NATIVE_PLUGIN_PORT 8
 #define NS_NATIVE_SCREEN      9
-#define NS_NATIVE_SHELLWIDGET 10      // Get the shell GtkWidget
+// The toplevel GtkWidget containing this nsIWidget:
+#define NS_NATIVE_SHELLWIDGET 10
 // Has to match to NPNVnetscapeWindow, and shareable across processes
 // HWND on Windows and XID on X11
 #define NS_NATIVE_SHAREABLE_WINDOW 11
 #ifdef XP_MACOSX
 #define NS_NATIVE_PLUGIN_PORT_QD    100
 #define NS_NATIVE_PLUGIN_PORT_CG    101
 #endif
 #ifdef XP_WIN