Bug 1186661 - Use monitors-changed signal to update screen manager on GTK. r=karlt
authorAndrew Comminos <acomminos@mozilla.com>
Sat, 25 Jul 2015 19:07:00 -0400
changeset 286639 e3d7d24ebf13fc5dd54eccd81108b6830b48d39e
parent 286638 36c3eece4b1a5c2d8ec52da4e815a0f56e09021d
child 286640 8a8ffb4d31b5bb726c8e0b2aa60cc3086207c5eb
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt
bugs1186661
milestone42.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
Bug 1186661 - Use monitors-changed signal to update screen manager on GTK. r=karlt
widget/gtk/nsScreenManagerGtk.cpp
--- a/widget/gtk/nsScreenManagerGtk.cpp
+++ b/widget/gtk/nsScreenManagerGtk.cpp
@@ -3,42 +3,46 @@
  * 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 "nsScreenManagerGtk.h"
 #include "nsScreenGtk.h"
 #include "nsIComponentManager.h"
 #include "nsRect.h"
 #include "nsAutoPtr.h"
+#include "nsGtkUtils.h"
 
 #define SCREEN_MANAGER_LIBRARY_LOAD_FAILED ((PRLibrary*)1)
 
 #ifdef MOZ_X11
 #include <gdk/gdkx.h>
 // prototypes from Xinerama.h
 typedef Bool (*_XnrmIsActive_fn)(Display *dpy);
 typedef XineramaScreenInfo* (*_XnrmQueryScreens_fn)(Display *dpy, int *number);
 #endif
 
 #include <gtk/gtk.h>
 
+void
+monitors_changed(GdkScreen* aScreen, gpointer aClosure)
+{
+  nsScreenManagerGtk *manager = static_cast<nsScreenManagerGtk*>(aClosure);
+  manager->Init();
+}
 
 static GdkFilterReturn
 root_window_event_filter(GdkXEvent *aGdkXEvent, GdkEvent *aGdkEvent,
                          gpointer aClosure)
 {
   nsScreenManagerGtk *manager = static_cast<nsScreenManagerGtk*>(aClosure);
 #ifdef MOZ_X11
   XEvent *xevent = static_cast<XEvent*>(aGdkXEvent);
 
   // See comments in nsScreenGtk::Init below.
   switch (xevent->type) {
-    case ConfigureNotify:
-      manager->Init();
-      break;
     case PropertyNotify:
       {
         XPropertyEvent *propertyEvent = &xevent->xproperty;
         if (propertyEvent->atom == manager->NetWorkareaAtom()) {
           manager->Init();
         }
       }
       break;
@@ -58,16 +62,20 @@ nsScreenManagerGtk :: nsScreenManagerGtk
   // nothing else to do. I guess we could cache a bunch of information
   // here, but we want to ask the device at runtime in case anything
   // has changed.
 }
 
 
 nsScreenManagerGtk :: ~nsScreenManagerGtk()
 {
+  g_signal_handlers_disconnect_by_func(gdk_screen_get_default(),
+                                       FuncToGpointer(monitors_changed),
+                                       this);
+
   if (mRootWindow) {
     gdk_window_remove_filter(mRootWindow, root_window_event_filter, this);
     g_object_unref(mRootWindow);
     mRootWindow = nullptr;
   }
 
   /* XineramaIsActive() registers a callback function close_display()
    * in X, which is to be called in XCloseDisplay(). This is the case
@@ -88,24 +96,25 @@ nsresult
 nsScreenManagerGtk :: EnsureInit()
 {
   if (mCachedScreenArray.Count() > 0)
     return NS_OK;
 
   mRootWindow = gdk_get_default_root_window();
   g_object_ref(mRootWindow);
 
-  // GDK_STRUCTURE_MASK ==> StructureNotifyMask, for ConfigureNotify
   // GDK_PROPERTY_CHANGE_MASK ==> PropertyChangeMask, for PropertyNotify
   gdk_window_set_events(mRootWindow,
                         GdkEventMask(gdk_window_get_events(mRootWindow) |
-                                     GDK_STRUCTURE_MASK |
                                      GDK_PROPERTY_CHANGE_MASK));
+
+  g_signal_connect(gdk_screen_get_default(), "monitors-changed",
+                   G_CALLBACK(monitors_changed), this);
+#ifdef MOZ_X11
   gdk_window_add_filter(mRootWindow, root_window_event_filter, this);
-#ifdef MOZ_X11
   if (GDK_IS_X11_DISPLAY(gdk_display_get_default()))
       mNetWorkareaAtom =
         XInternAtom(GDK_WINDOW_XDISPLAY(mRootWindow), "_NET_WORKAREA", False);
 #endif
 
   return Init();
 }