From d40c8b77831d85c23b1437ff43207f0caf238bcb Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Thu, 19 Dec 2019 04:15:44 +0000 Subject: [PATCH] Bug 1596317 - Implement SetPrefersReducedMotionOverrideForTest backend for GTK. r=emilio On GTK changing gtk-enable-animation in a process doesn't affect in different processes for some reasons. So we take the same approach as what we did for OSX[1] that is when SetPrefersReducedMotionOverrideForTest is called we set the given value as a cache in the parent process and send a notification to system as if the value changed thus the notification kicks PBroser.ThemeChanged to update the cache in the content process, thus we can use the cache value on querying the corresponding value in the content process. [1] https://hg.mozilla.org/mozilla-central/rev/67a5acf7363d Differential Revision: https://phabricator.services.mozilla.com/D57260 --- dom/interfaces/base/nsIDOMWindowUtils.idl | 2 +- layout/style/test/mochitest.ini | 2 +- widget/gtk/nsLookAndFeel.cpp | 36 ++++++++++++++++------- widget/gtk/nsLookAndFeel.h | 2 ++ widget/gtk/nsWindow.cpp | 25 ++++++++++++++++ widget/gtk/nsWindow.h | 3 ++ 6 files changed, 58 insertions(+), 12 deletions(-) diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl index e8cd6b31aaeab..66186817c1a37 100644 --- a/dom/interfaces/base/nsIDOMWindowUtils.idl +++ b/dom/interfaces/base/nsIDOMWindowUtils.idl @@ -1976,7 +1976,7 @@ interface nsIDOMWindowUtils : nsISupports { * Simulate the system setting corresponding to 'prefers-reduced-motion' * media queries feature is changed to 'on' or 'off'. * - * Currently this function is available only on MacOSX. + * This function doesn't work on Windows. */ void setPrefersReducedMotionOverrideForTest(in boolean aValue); /** diff --git a/layout/style/test/mochitest.ini b/layout/style/test/mochitest.ini index 1813ef46dfd7a..f39b4eac10cc0 100644 --- a/layout/style/test/mochitest.ini +++ b/layout/style/test/mochitest.ini @@ -276,7 +276,7 @@ skip-if = verify [test_mq_any_hover_and_any_pointer.html] [test_mq_hover_and_pointer.html] [test_mq_prefers_reduced_motion_dynamic.html] -run-if = (os == 'mac' || toolkit == 'android') +run-if = !headless && (os == 'mac' || toolkit == 'android' || toolkit == 'gtk') [test_moz_device_pixel_ratio.html] [test_moz_prefixed_cursor.html] [test_namespace_rule.html] diff --git a/widget/gtk/nsLookAndFeel.cpp b/widget/gtk/nsLookAndFeel.cpp index 73e7af547b773..84474a55a6eb1 100644 --- a/widget/gtk/nsLookAndFeel.cpp +++ b/widget/gtk/nsLookAndFeel.cpp @@ -263,6 +263,10 @@ nsresult nsLookAndFeel::InitCellHighlightColors() { void nsLookAndFeel::NativeInit() { EnsureInit(); } void nsLookAndFeel::RefreshImpl() { + if (mShouldRetainCacheForTest) { + return; + } + nsXPLookAndFeel::RefreshImpl(); moz_gtk_refresh(); @@ -270,6 +274,9 @@ void nsLookAndFeel::RefreshImpl() { mButtonFontCached = false; mFieldFontCached = false; mMenuFontCached = false; + if (XRE_IsParentProcess()) { + mPrefersReducedMotionCached = false; + } mInitialized = false; } @@ -278,11 +285,15 @@ nsTArray nsLookAndFeel::GetIntCacheImpl() { nsTArray lookAndFeelIntCache = nsXPLookAndFeel::GetIntCacheImpl(); - LookAndFeelInt lafInt; - lafInt.id = eIntID_SystemUsesDarkTheme; - lafInt.value = GetInt(eIntID_SystemUsesDarkTheme); + LookAndFeelInt lafInt{.id = eIntID_SystemUsesDarkTheme, + .value = GetInt(eIntID_SystemUsesDarkTheme)}; lookAndFeelIntCache.AppendElement(lafInt); + LookAndFeelInt prefersReducedMotion{ + .id = eIntID_PrefersReducedMotion, + .value = GetInt(eIntID_PrefersReducedMotion)}; + lookAndFeelIntCache.AppendElement(prefersReducedMotion); + return lookAndFeelIntCache; } @@ -293,6 +304,10 @@ void nsLookAndFeel::SetIntCacheImpl( case eIntID_SystemUsesDarkTheme: mSystemUsesDarkTheme = entry.value; break; + case eIntID_PrefersReducedMotion: + mPrefersReducedMotion = entry.value; + mPrefersReducedMotionCached = true; + break; } } } @@ -725,13 +740,14 @@ nsresult nsLookAndFeel::GetIntImpl(IntID aID, int32_t& aResult) { aResult = mCSDReversedPlacement; break; case eIntID_PrefersReducedMotion: { - GtkSettings* settings; - gboolean enableAnimations; - - settings = gtk_settings_get_default(); - g_object_get(settings, "gtk-enable-animations", &enableAnimations, - nullptr); - aResult = enableAnimations ? 0 : 1; + if (!mPrefersReducedMotionCached && XRE_IsParentProcess()) { + gboolean enableAnimations; + GtkSettings* settings = gtk_settings_get_default(); + g_object_get(settings, "gtk-enable-animations", &enableAnimations, + nullptr); + mPrefersReducedMotion = enableAnimations ? 0 : 1; + } + aResult = mPrefersReducedMotion; break; } case eIntID_SystemUsesDarkTheme: { diff --git a/widget/gtk/nsLookAndFeel.h b/widget/gtk/nsLookAndFeel.h index 19501505ce442..5d6d060667272 100644 --- a/widget/gtk/nsLookAndFeel.h +++ b/widget/gtk/nsLookAndFeel.h @@ -92,6 +92,7 @@ class nsLookAndFeel final : public nsXPLookAndFeel { char16_t mInvisibleCharacter = 0; float mCaretRatio = 0.0f; int32_t mCaretBlinkTime = 0; + int32_t mPrefersReducedMotion = -1; bool mMenuSupportsDrag = false; bool mCSDAvailable = false; bool mCSDHideTitlebarByDefault = false; @@ -101,6 +102,7 @@ class nsLookAndFeel final : public nsXPLookAndFeel { bool mCSDReversedPlacement = false; bool mSystemUsesDarkTheme = false; bool mInitialized = false; + bool mPrefersReducedMotionCached = false; void EnsureInit(); diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 5413d80e9edea..a6d3a616a20c0 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -38,6 +38,7 @@ #include "SystemTimeConverter.h" #include "nsViewManager.h" #include "nsMenuPopupFrame.h" +#include "nsXPLookAndFeel.h" #include "nsGtkKeyUtils.h" #include "nsGtkCursors.h" @@ -7693,6 +7694,30 @@ void nsWindow::LockAspectRatio(bool aShouldLock) { ApplySizeConstraints(); } +nsresult nsWindow::SetPrefersReducedMotionOverrideForTest(bool aValue) { + LookAndFeel::SetShouldRetainCacheForTest(true); + + LookAndFeelInt prefersReducedMotion{ + .id = LookAndFeel::eIntID_PrefersReducedMotion, .value = aValue ? 1 : 0}; + + AutoTArray lookAndFeelCache; + lookAndFeelCache.AppendElement(prefersReducedMotion); + + LookAndFeel::SetIntCache(lookAndFeelCache); + + // Notify as if the corresponding setting changed. + g_object_notify(G_OBJECT(gtk_settings_get_default()), + "gtk-enable-animations"); + + return NS_OK; +} + +nsresult nsWindow::ResetPrefersReducedMotionOverrideForTest() { + LookAndFeel::SetShouldRetainCacheForTest(false); + + return NS_OK; +} + #ifdef MOZ_WAYLAND void nsWindow::SetEGLNativeWindowSize( const LayoutDeviceIntSize& aEGLWindowSize) { diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index 49c5c5f3aa1f9..2c287ea0738c1 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -392,6 +392,9 @@ class nsWindow final : public nsBaseWidget { nsresult SetSystemFont(const nsCString& aFontName) override; nsresult GetSystemFont(nsCString& aFontName) override; + nsresult SetPrefersReducedMotionOverrideForTest(bool aValue) final; + nsresult ResetPrefersReducedMotionOverrideForTest() final; + typedef enum { CSD_SUPPORT_SYSTEM, // CSD including shadows CSD_SUPPORT_CLIENT, // CSD without shadows