Bug 1026803 part 7 - Store the CurrentX11TimeGetter as a member object on nsWindow; r=karlt
authorBrian Birtles <birtles@gmail.com>
Tue, 11 Aug 2015 17:13:44 +0900
changeset 258998 f11af0ae18111d530cc620d3bb3f95f57a8b4f68
parent 258997 1bf77ab3474c1e81197cb41763037f920aad61a1
child 258999 3e9a0b5dad97dedfb8f60a635c2d79916942071d
push id29268
push userryanvm@gmail.com
push dateTue, 25 Aug 2015 00:37:23 +0000
treeherdermozilla-central@08015770c9d6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
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 1026803 part 7 - Store the CurrentX11TimeGetter as a member object on nsWindow; r=karlt In preparation for making CurrentX11TimeGetter capable of performing an asynchronous request of the current time, this patch revises the lifetime of such objects so that they are stored on nsWindow.
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -265,32 +265,34 @@ static guint32 sRetryGrabTime;
 static SystemTimeConverter<guint32>&
 TimeConverter() {
     static SystemTimeConverter<guint32> sTimeConverterSingleton;
     return sTimeConverterSingleton;
 namespace mozilla {
-class MOZ_STACK_CLASS CurrentX11TimeGetter
+class CurrentX11TimeGetter
     CurrentX11TimeGetter(GdkWindow* aWindow) : mWindow(aWindow) { }
     guint32 GetCurrentTime() const
         return gdk_x11_get_server_time(mWindow);
     void GetTimeAsyncForPossibleBackwardsSkew(const TimeStamp& aNow)
         // FIXME: Get time async
+    // This is safe because this class is stored as a member of mWindow and
+    // won't outlive it.
     GdkWindow* mWindow;
 } // namespace mozilla
 // The window from which the focus manager asks us to dispatch key events.
@@ -2899,19 +2901,30 @@ nsWindow::GetEventTimeStamp(guint32 aEve
         return TimeStamp::Now();
     if (aEventTime == 0) {
         // Some X11 and GDK events may be received with a time of 0 to indicate
         // that they are synthetic events. Some input method editors do this.
         // In this case too, just return the current timestamp.
         return TimeStamp::Now();
-    CurrentX11TimeGetter getCurrentTime = CurrentX11TimeGetter(mGdkWindow);
+    CurrentX11TimeGetter* getCurrentTime = GetCurrentTimeGetter();
+    MOZ_ASSERT(getCurrentTime,
+               "Null current time getter despite having a window");
     return TimeConverter().GetTimeStampFromSystemTime(aEventTime,
-                                                      getCurrentTime);
+                                                      *getCurrentTime);
+nsWindow::GetCurrentTimeGetter() {
+    MOZ_ASSERT(mGdkWindow, "Expected mGdkWindow to be set");
+    if (MOZ_UNLIKELY(!mCurrentTimeGetter)) {
+        mCurrentTimeGetter = new CurrentX11TimeGetter(mGdkWindow);
+    }
+    return mCurrentTimeGetter;
 nsWindow::OnKeyPressEvent(GdkEventKey *aEvent)
     LOGFOCUS(("OnKeyPressEvent [%p]\n", (void *)this));
     // if we are in the middle of composing text, XIM gets to see it
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -64,16 +64,17 @@ class gfxPattern;
 class nsPluginNativeWindowGtk;
 #if defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV)
 class nsShmImage;
 namespace mozilla {
 class TimeStamp;
+class CurrentX11TimeGetter;
 class nsWindow : public nsBaseWidget
     static void ReleaseGlobals();
@@ -263,16 +264,17 @@ public:
                                          guint aTime);
     static void        UpdateDragStatus (GdkDragContext *aDragContext,
                                          nsIDragService *aDragService);
     // If this dispatched the keydown event actually, this returns TRUE,
     // otherwise, FALSE.
     bool               DispatchKeyDownEvent(GdkEventKey *aEvent,
                                             bool *aIsCancelled);
     mozilla::TimeStamp GetEventTimeStamp(guint32 aEventTime);
+    mozilla::CurrentX11TimeGetter* GetCurrentTimeGetter();
     NS_IMETHOD_(void) SetInputContext(const InputContext& aContext,
                                       const InputContextAction& aAction) override;
     NS_IMETHOD_(InputContext) GetInputContext() override;
     virtual nsIMEUpdatePreference GetIMEUpdatePreference() override;
     bool ExecuteNativeKeyBindingRemapped(
                         NativeKeyBindingsType aType,
                         const mozilla::WidgetKeyboardEvent& aEvent,
@@ -494,16 +496,18 @@ private:
      * the widget is destroyed, it's released.  All child windows refer its
      * ancestor widget's instance.  So, one set of IM contexts is created for
      * all windows in a hierarchy.  If the children are released after the top
      * level window is released, the children still have a valid pointer,
      * however, IME doesn't work at that time.
     nsRefPtr<mozilla::widget::IMContextWrapper> mIMContext;
+    nsAutoPtr<mozilla::CurrentX11TimeGetter> mCurrentTimeGetter;
     // HiDPI scale conversion
     gint GdkScaleFactor();
     // To GDK
     gint DevicePixelsToGdkCoordRoundUp(int pixels);
     gint DevicePixelsToGdkCoordRoundDown(int pixels);
     GdkPoint DevicePixelsToGdkPointRoundDown(nsIntPoint point);
     GdkRectangle DevicePixelsToGdkSizeRoundUp(nsIntSize pixelSize);