widget/nsXPLookAndFeel.h
author Hiroyuki Ikezoe <hikezoe@mozilla.com>
Sat, 15 Sep 2018 01:00:07 +0000
changeset 492584 b84a0e018ea893cef8c43fdcf8577870bc1e5bcd
parent 432980 b049c00f7a8f9310c4e9855a668c9d67fd9ebd49
child 508163 6f3709b3878117466168c40affa7bca0b60cf75b
permissions -rw-r--r--
Bug 1486971 - Test for dynamically change of the prefers-reduced-motion setting on MacOSX. r=froydnj,mstange a=pascalc The framework to simulate the setting change works as following; - nsIDOMWindowUtils.setPrefersReducedMotion() calls an IPC function which ends up calling nsChildView::SetPrefersReducedMotion() in the parent process - nsChildView::SetPrefersReducedMotion() sets the given value into nsLookAndFeel::mPrefersReducedMotionCached just like we set the value queried via NSWorkspace.accessibilityDisplayShouldReduceMotion in the parent process and send a notification which is the same notification MacOSX sends when the system setting changed - Normally the cached value is cleared before quering new values since the cache value is stale, but in this case the value is up-to-date one, so nsChildView::SetPrefersReducedMotion() tells that we don't need to clear the cache, and nsIDOMWindowUtils.resetPrefersReducedMotion() resets that state of 'we don't need to clear the cache' There are two test cases with the framework in this commit, one is just setting the value and checking the value queried by window.matchMedia. The other one is receiving 'change' event and checking the value of the event target. Note that to make this test works the patch for bug 1478212 is necessary since the test runs in an iframe. Depends on D5003 Differential Revision: https://phabricator.services.mozilla.com/D5004

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * 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/. */

#ifndef __nsXPLookAndFeel
#define __nsXPLookAndFeel

#include "mozilla/LookAndFeel.h"
#include "nsTArray.h"

class nsLookAndFeel;

struct nsLookAndFeelIntPref
{
  const char* name;
  mozilla::LookAndFeel::IntID id;
  bool isSet;
  int32_t intVar;
};

struct nsLookAndFeelFloatPref
{
  const char* name;
  mozilla::LookAndFeel::FloatID id;
  bool isSet;
  float floatVar;
};

#define CACHE_BLOCK(x)     ((x) >> 5)
#define CACHE_BIT(x)       (1 << ((x) & 31))

#define COLOR_CACHE_SIZE   (CACHE_BLOCK(LookAndFeel::eColorID_LAST_COLOR) + 1)
#define IS_COLOR_CACHED(x) (CACHE_BIT(x) & nsXPLookAndFeel::sCachedColorBits[CACHE_BLOCK(x)])
#define CLEAR_COLOR_CACHE(x) nsXPLookAndFeel::sCachedColors[(x)] =0; \
              nsXPLookAndFeel::sCachedColorBits[CACHE_BLOCK(x)] &= ~(CACHE_BIT(x));
#define CACHE_COLOR(x, y)  nsXPLookAndFeel::sCachedColors[(x)] = y; \
              nsXPLookAndFeel::sCachedColorBits[CACHE_BLOCK(x)] |= CACHE_BIT(x);

class nsXPLookAndFeel: public mozilla::LookAndFeel
{
public:
  virtual ~nsXPLookAndFeel();

  static nsXPLookAndFeel* GetInstance();
  static void Shutdown();

  void Init();

  //
  // All these routines will return NS_OK if they have a value,
  // in which case the nsLookAndFeel should use that value;
  // otherwise we'll return NS_ERROR_NOT_AVAILABLE, in which case, the
  // platform-specific nsLookAndFeel should use its own values instead.
  //
  nsresult GetColorImpl(ColorID aID, bool aUseStandinsForNativeColors,
                        nscolor &aResult);
  virtual nsresult GetIntImpl(IntID aID, int32_t &aResult);
  virtual nsresult GetFloatImpl(FloatID aID, float &aResult);

  // This one is different: there are no override prefs (fixme?), so
  // there is no XP implementation, only per-system impls.
  virtual bool GetFontImpl(FontID aID, nsString& aName,
                           gfxFontStyle& aStyle,
                           float aDevPixPerCSSPixel) = 0;

  virtual void RefreshImpl();

  virtual char16_t GetPasswordCharacterImpl()
  {
    return char16_t('*');
  }

  virtual bool GetEchoPasswordImpl()
  {
    return false;
  }

  virtual uint32_t GetPasswordMaskDelayImpl()
  {
    return 600;
  }

  virtual nsTArray<LookAndFeelInt> GetIntCacheImpl();
  virtual void SetIntCacheImpl(const nsTArray<LookAndFeelInt>& aLookAndFeelIntCache) {}
  void SetShouldRetainCacheImplForTest(bool aValue)
  {
    mShouldRetainCacheForTest = aValue;
  }

  virtual void NativeInit() = 0;

protected:
  nsXPLookAndFeel();

  static void IntPrefChanged(nsLookAndFeelIntPref *data);
  static void FloatPrefChanged(nsLookAndFeelFloatPref *data);
  static void ColorPrefChanged(unsigned int index, const char *prefName);
  void InitFromPref(nsLookAndFeelIntPref* aPref);
  void InitFromPref(nsLookAndFeelFloatPref* aPref);
  void InitColorFromPref(int32_t aIndex);
  virtual nsresult NativeGetColor(ColorID aID, nscolor &aResult) = 0;
  bool IsSpecialColor(ColorID aID, nscolor &aColor);
  bool ColorIsNotCSSAccessible(ColorID aID);
  nscolor GetStandinForNativeColor(ColorID aID);

  static void OnPrefChanged(const char* aPref, void* aClosure);

  static bool sInitialized;
  static nsLookAndFeelIntPref sIntPrefs[];
  static nsLookAndFeelFloatPref sFloatPrefs[];
  /* this length must not be shorter than the length of the longest string in the array
   * see nsXPLookAndFeel.cpp
   */
  static const char sColorPrefs[][41];
  static int32_t sCachedColors[LookAndFeel::eColorID_LAST_COLOR];
  static int32_t sCachedColorBits[COLOR_CACHE_SIZE];
  static bool sUseNativeColors;
  static bool sUseStandinsForNativeColors;
  static bool sFindbarModalHighlight;

  static nsXPLookAndFeel* sInstance;
  static bool sShutdown;

  // True if we shouldn't clear the cache value in RefreshImpl().
  // NOTE: This should be used only for testing.
  bool mShouldRetainCacheForTest;
};

#endif