aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjbeich <jbeich@FreeBSD.org>2018-02-27 02:56:14 +0800
committerjbeich <jbeich@FreeBSD.org>2018-02-27 02:56:14 +0800
commiteab437f6b85cb7ee80817f7d4525d7d40444ad93 (patch)
tree791bd08bdb9f32cdb272c21b90e4aba161552bb1
parent32d8c8ff487d361ed69e2cd21c37c9e4ad732bf1 (diff)
downloadfreebsd-ports-gnome-eab437f6b85cb7ee80817f7d4525d7d40444ad93.tar.gz
freebsd-ports-gnome-eab437f6b85cb7ee80817f7d4525d7d40444ad93.tar.zst
freebsd-ports-gnome-eab437f6b85cb7ee80817f7d4525d7d40444ad93.zip
www/waterfox: apply FF57 widget/ fixes
-rw-r--r--www/waterfox/Makefile2
-rw-r--r--www/waterfox/files/patch-bug1036008523
-rw-r--r--www/waterfox/files/patch-bug113407765
-rw-r--r--www/waterfox/files/patch-bug131492864
-rw-r--r--www/waterfox/files/patch-bug1360278184
-rw-r--r--www/waterfox/files/patch-bug1381815278
-rw-r--r--www/waterfox/files/patch-bug1387170148
-rw-r--r--www/waterfox/files/patch-bug13967221426
-rw-r--r--www/waterfox/files/patch-bug1398539159
-rw-r--r--www/waterfox/files/patch-bug1399336153
-rw-r--r--www/waterfox/files/patch-bug140023830
-rw-r--r--www/waterfox/files/patch-bug140083949
-rw-r--r--www/waterfox/files/patch-bug1401063160
-rw-r--r--www/waterfox/files/patch-bug140700133
-rw-r--r--www/waterfox/files/patch-bug1417751379
-rw-r--r--www/waterfox/files/patch-bug142587846
16 files changed, 3698 insertions, 1 deletions
diff --git a/www/waterfox/Makefile b/www/waterfox/Makefile
index c659950c854b..4a7a4c09d181 100644
--- a/www/waterfox/Makefile
+++ b/www/waterfox/Makefile
@@ -3,7 +3,7 @@
PORTNAME= waterfox
DISTVERSION= 56.0.4-20
DISTVERSIONSUFFIX= -ge03e284b083d
-PORTREVISION= 1
+PORTREVISION= 2
CATEGORIES= www ipv6
MAINTAINER= jbeich@FreeBSD.org
diff --git a/www/waterfox/files/patch-bug1036008 b/www/waterfox/files/patch-bug1036008
new file mode 100644
index 000000000000..7f50b456c30d
--- /dev/null
+++ b/www/waterfox/files/patch-bug1036008
@@ -0,0 +1,523 @@
+commit ed18f146242b
+Author: Masayuki Nakano <masayuki@d-toybox.com>
+Date: Fri Feb 16 15:54:07 2018 +0900
+
+ Bug 1036008 - Use alternative ASCII capable keyboard layout information to decide keyCode even if the key produces an ASCII punctuation character r=smaug
+
+ Gecko decides keyCode from an ASCII character which is produced by the key
+ by itself or with Shift on active keyboard layout or alternative ASCII capable
+ keyboard layout if active keyboard layout isn't ASCII capable. However, we've
+ ignored alternative ASCII capable keyboard layout's character if both the
+ key itself and with Shift don't produce ASCII alphabet nor ASCII numeral,
+ i.e., ASCII punctuation characters are not used in alternative ASCII capable
+ keyboard layout because of avoiding mapping a keyCode value to 2 or more keys.
+
+ However, setting 0 to keyCode value makes Firefox unusable with some web
+ applications which are aware of neither KeyboardEvent.key nor
+ KeyboardEvent.code. So, even if we map same keyCode value to a key, we should
+ avoid setting keyCode value to 0 as far as possible.
+
+ This patch's approach is, we behave same keyCode value as the alternative ASCII
+ capable keyCode is selected when computed keyCode value of active keyboard
+ layout is 0. This means that we will make some language users whose keyboard
+ layout for their language is not ASCII capable can use global web services
+ which support US keyboard layout of Firefox since the new keyCode values
+ are mostly computed with US layout on Windows or actual alternative ASCII
+ capable keyboard layout on macOS and Linux. In other words, we cannot improve
+ compatibility with web applications which don't support Firefox by this patch
+ since our keyCode values are really different from Chrome's. So, unfortunately,
+ if we'd use exactly same keyCode computation as Chromium, we'd break
+ compatibility with existing web applications which are aware of Firefox since
+ it's necessary to check UA name or something before using keyCode values.
+
+ Note that the most important difference between Windows and the others is,
+ such keyCode value is computed with alternative ASCII capable keyboard
+ layout on macOS and Linux but only on Windows, it's computed with OEM virtual
+ keycode. This means that only on Windows, the keyCode value may be different
+ from actual alternative ASCII capable keyboard layout's keyCode.
+
+ MozReview-Commit-ID: As289r9wp6i
+
+ --HG--
+ extra : rebase_source : 66181403dbe8ca8dab893edc8f4eec1991d544d0
+---
+ widget/TextEvents.h | 11 ++++++
+ widget/WidgetEventImpl.cpp | 36 ++++++++++++++++++++
+ widget/cocoa/TextInputHandler.mm | 43 ++++++++++++++----------
+ widget/gtk/nsGtkKeyUtils.cpp | 64 ++++++++++++++++++++++++++---------
+ widget/gtk/nsGtkKeyUtils.h | 10 ++++++
+ widget/tests/test_keycodes.xul | 41 ++++++++++++-----------
+ widget/windows/KeyboardLayout.cpp | 70 ++++++++++++++++++++++++++++++++++++++-
+ 7 files changed, 223 insertions(+), 52 deletions(-)
+
+diff --git widget/TextEvents.h widget/TextEvents.h
+index f1a67ecfdf3d..015331e8287d 100644
+--- widget/TextEvents.h
++++ widget/TextEvents.h
+@@ -459,6 +459,17 @@ public:
+ GetDOMCodeName(mCodeNameIndex, aCodeName);
+ }
+
++ /**
++ * GetFallbackKeyCodeOfPunctuationKey() returns a DOM keyCode value for
++ * aCodeNameIndex. This is keyCode value of the key when active keyboard
++ * layout is ANSI (US), JIS or ABNT keyboard layout (the latter 2 layouts
++ * are used only when ANSI doesn't have the key). The result is useful
++ * if the key doesn't produce ASCII character with active keyboard layout
++ * nor with alternative ASCII capable keyboard layout.
++ */
++ static uint32_t
++ GetFallbackKeyCodeOfPunctuationKey(CodeNameIndex aCodeNameIndex);
++
+ bool IsModifierKeyEvent() const
+ {
+ return GetModifierForKeyName(mKeyNameIndex) != MODIFIER_NONE;
+diff --git widget/WidgetEventImpl.cpp widget/WidgetEventImpl.cpp
+index 5415d9889be9..c379e7301b21 100644
+--- widget/WidgetEventImpl.cpp
++++ widget/WidgetEventImpl.cpp
+@@ -1183,6 +1183,42 @@ WidgetKeyboardEvent::GetCodeNameIndex(const nsAString& aCodeValue)
+ return result;
+ }
+
++/* static */ uint32_t
++WidgetKeyboardEvent::GetFallbackKeyCodeOfPunctuationKey(
++ CodeNameIndex aCodeNameIndex)
++{
++ switch (aCodeNameIndex) {
++ case CODE_NAME_INDEX_Semicolon: // VK_OEM_1 on Windows
++ return nsIDOMKeyEvent::DOM_VK_SEMICOLON;
++ case CODE_NAME_INDEX_Equal: // VK_OEM_PLUS on Windows
++ return nsIDOMKeyEvent::DOM_VK_EQUALS;
++ case CODE_NAME_INDEX_Comma: // VK_OEM_COMMA on Windows
++ return nsIDOMKeyEvent::DOM_VK_COMMA;
++ case CODE_NAME_INDEX_Minus: // VK_OEM_MINUS on Windows
++ return nsIDOMKeyEvent::DOM_VK_HYPHEN_MINUS;
++ case CODE_NAME_INDEX_Period: // VK_OEM_PERIOD on Windows
++ return nsIDOMKeyEvent::DOM_VK_PERIOD;
++ case CODE_NAME_INDEX_Slash: // VK_OEM_2 on Windows
++ return nsIDOMKeyEvent::DOM_VK_SLASH;
++ case CODE_NAME_INDEX_Backquote: // VK_OEM_3 on Windows
++ return nsIDOMKeyEvent::DOM_VK_BACK_QUOTE;
++ case CODE_NAME_INDEX_BracketLeft: // VK_OEM_4 on Windows
++ return nsIDOMKeyEvent::DOM_VK_OPEN_BRACKET;
++ case CODE_NAME_INDEX_Backslash: // VK_OEM_5 on Windows
++ return nsIDOMKeyEvent::DOM_VK_BACK_SLASH;
++ case CODE_NAME_INDEX_BracketRight: // VK_OEM_6 on Windows
++ return nsIDOMKeyEvent::DOM_VK_CLOSE_BRACKET;
++ case CODE_NAME_INDEX_Quote: // VK_OEM_7 on Windows
++ return nsIDOMKeyEvent::DOM_VK_QUOTE;
++ case CODE_NAME_INDEX_IntlBackslash: // VK_OEM_5 on Windows (ABNT, etc)
++ case CODE_NAME_INDEX_IntlYen: // VK_OEM_5 on Windows (JIS)
++ case CODE_NAME_INDEX_IntlRo: // VK_OEM_102 on Windows
++ return nsIDOMKeyEvent::DOM_VK_BACK_SLASH;
++ default:
++ return 0;
++ }
++}
++
+ /* static */ const char*
+ WidgetKeyboardEvent::GetCommandStr(Command aCommand)
+ {
+diff --git widget/cocoa/TextInputHandler.mm widget/cocoa/TextInputHandler.mm
+index 437d8222ab3b..106ef0e91f52 100644
+--- widget/cocoa/TextInputHandler.mm
++++ widget/cocoa/TextInputHandler.mm
+@@ -1410,25 +1410,34 @@ TISInputSourceWrapper::ComputeGeckoKeyCode(UInt32 aNativeKeyCode,
+ return keyCode;
+ }
+
+- // If this is ASCII capable, give up to compute it.
+- if (IsASCIICapable()) {
+- return 0;
++ if (!IsASCIICapable()) {
++ // Retry with ASCII capable keyboard layout.
++ TISInputSourceWrapper currentKeyboardLayout;
++ currentKeyboardLayout.InitByCurrentASCIICapableKeyboardLayout();
++ NS_ENSURE_TRUE(mInputSource != currentKeyboardLayout.mInputSource, 0);
++ keyCode = currentKeyboardLayout.ComputeGeckoKeyCode(aNativeKeyCode, aKbType,
++ aCmdIsPressed);
++ // We've returned 0 for long time if keyCode isn't for an alphabet keys or
++ // a numeric key even in alternative ASCII capable keyboard layout because
++ // we decided that we should avoid setting same keyCode value to 2 or
++ // more keys since active keyboard layout may have a key to input the
++ // punctuation with different key. However, setting keyCode to 0 makes
++ // some web applications which are aware of neither KeyboardEvent.key nor
++ // KeyboardEvent.code not work with Firefox when user selects non-ASCII
++ // capable keyboard layout such as Russian and Thai. So, if alternative
++ // ASCII capable keyboard layout has keyCode value for the key, we should
++ // use it. In other words, this behavior does that non-ASCII capable
++ // keyboard layout overrides some keys' keyCode value only if the key
++ // produces ASCII character by itself or with Shift key.
++ if (keyCode) {
++ return keyCode;
++ }
+ }
+
+- // Retry with ASCII capable keyboard layout.
+- TISInputSourceWrapper currentKeyboardLayout;
+- currentKeyboardLayout.InitByCurrentASCIICapableKeyboardLayout();
+- NS_ENSURE_TRUE(mInputSource != currentKeyboardLayout.mInputSource, 0);
+- keyCode = currentKeyboardLayout.ComputeGeckoKeyCode(aNativeKeyCode, aKbType,
+- aCmdIsPressed);
+-
+- // However, if keyCode isn't for an alphabet keys or a numeric key, we should
+- // ignore it. For example, comma key of Thai layout is same as close-square-
+- // bracket key of US layout and an unicode character key of Thai layout is
+- // same as comma key of US layout. If we return NS_VK_COMMA for latter key,
+- // web application developers cannot distinguish with the former key.
+- return ((keyCode >= NS_VK_A && keyCode <= NS_VK_Z) ||
+- (keyCode >= NS_VK_0 && keyCode <= NS_VK_9)) ? keyCode : 0;
++ // Otherwise, let's decide keyCode value from the native virtual keycode
++ // value on major keyboard layout.
++ CodeNameIndex code = ComputeGeckoCodeNameIndex(aNativeKeyCode, aKbType);
++ return WidgetKeyboardEvent::GetFallbackKeyCodeOfPunctuationKey(code);
+ }
+
+ // static
+diff --git widget/gtk/nsGtkKeyUtils.cpp widget/gtk/nsGtkKeyUtils.cpp
+index bda2c2920248..a336c1ad6c92 100644
+--- widget/gtk/nsGtkKeyUtils.cpp
++++ widget/gtk/nsGtkKeyUtils.cpp
+@@ -795,7 +795,7 @@ KeymapWrapper::ComputeDOMKeyCode(const GdkEventKey* aGdkKeyEvent)
+
+ // If the unmodified character is not an ASCII character, that means we
+ // couldn't find the hint. We should reset it.
+- if (unmodifiedChar > 0x7F) {
++ if (!IsPrintableASCIICharacter(unmodifiedChar)) {
+ unmodifiedChar = 0;
+ }
+
+@@ -814,7 +814,7 @@ KeymapWrapper::ComputeDOMKeyCode(const GdkEventKey* aGdkKeyEvent)
+
+ // If the shifted unmodified character isn't an ASCII character, we should
+ // discard it too.
+- if (shiftedChar > 0x7F) {
++ if (!IsPrintableASCIICharacter(shiftedChar)) {
+ shiftedChar = 0;
+ }
+
+@@ -822,14 +822,12 @@ KeymapWrapper::ComputeDOMKeyCode(const GdkEventKey* aGdkKeyEvent)
+ // look for ASCII alphabet inputtable keyboard layout. If the key
+ // inputs an ASCII alphabet or an ASCII numeric, we should use it
+ // for deciding our keyCode.
+- // Note that it's important not to use alternative keyboard layout for ASCII
+- // alphabet inputabble keyboard layout because the keycode for the key with
+- // alternative keyboard layout may conflict with another key on current
+- // keyboard layout.
++ uint32_t unmodCharLatin = 0;
++ uint32_t shiftedCharLatin = 0;
+ if (!keymapWrapper->IsLatinGroup(aGdkKeyEvent->group)) {
+ gint minGroup = keymapWrapper->GetFirstLatinGroup();
+ if (minGroup >= 0) {
+- uint32_t unmodCharLatin =
++ unmodCharLatin =
+ keymapWrapper->GetCharCodeFor(aGdkKeyEvent, baseState,
+ minGroup);
+ if (IsBasicLatinLetterOrNumeral(unmodCharLatin)) {
+@@ -837,7 +835,13 @@ KeymapWrapper::ComputeDOMKeyCode(const GdkEventKey* aGdkKeyEvent)
+ // an ASCII numeric, we should use it for the keyCode.
+ return WidgetUtils::ComputeKeyCodeFromChar(unmodCharLatin);
+ }
+- uint32_t shiftedCharLatin =
++ // If the unmodified character in the alternative ASCII capable
++ // keyboard layout isn't an ASCII character, that means we couldn't
++ // find the hint. We should reset it.
++ if (!IsPrintableASCIICharacter(unmodCharLatin)) {
++ unmodCharLatin = 0;
++ }
++ shiftedCharLatin =
+ keymapWrapper->GetCharCodeFor(aGdkKeyEvent, shiftState,
+ minGroup);
+ if (IsBasicLatinLetterOrNumeral(shiftedCharLatin)) {
+@@ -845,16 +849,46 @@ KeymapWrapper::ComputeDOMKeyCode(const GdkEventKey* aGdkKeyEvent)
+ // numeric, we should use it for the keyCode.
+ return WidgetUtils::ComputeKeyCodeFromChar(shiftedCharLatin);
+ }
++ // If the shifted unmodified character in the alternative ASCII
++ // capable keyboard layout isn't an ASCII character, we should
++ // discard it too.
++ if (!IsPrintableASCIICharacter(shiftedCharLatin)) {
++ shiftedCharLatin = 0;
++ }
+ }
+ }
+
+- // If unmodified character is in ASCII range, use it. Otherwise, use
+- // shifted character.
+- if (!unmodifiedChar && !shiftedChar) {
+- return 0;
+- }
+- return WidgetUtils::ComputeKeyCodeFromChar(
+- unmodifiedChar ? unmodifiedChar : shiftedChar);
++ // If the key itself or with Shift state on active keyboard layout produces
++ // an ASCII punctuation character, we should decide keyCode value with it.
++ if (unmodifiedChar || shiftedChar) {
++ return WidgetUtils::ComputeKeyCodeFromChar(
++ unmodifiedChar ? unmodifiedChar : shiftedChar);
++ }
++
++ // If the key itself or with Shift state on alternative ASCII capable
++ // keyboard layout produces an ASCII punctuation character, we should
++ // decide keyCode value with it. Note that We've returned 0 for long
++ // time if keyCode isn't for an alphabet keys or a numeric key even in
++ // alternative ASCII capable keyboard layout because we decided that we
++ // should avoid setting same keyCode value to 2 or more keys since active
++ // keyboard layout may have a key to input the punctuation with different
++ // key. However, setting keyCode to 0 makes some web applications which
++ // are aware of neither KeyboardEvent.key nor KeyboardEvent.code not work
++ // with Firefox when user selects non-ASCII capable keyboard layout such
++ // as Russian and Thai. So, if alternative ASCII capable keyboard layout
++ // has keyCode value for the key, we should use it. In other words, this
++ // behavior means that non-ASCII capable keyboard layout overrides some
++ // keys' keyCode value only if the key produces ASCII character by itself
++ // or with Shift key.
++ if (unmodCharLatin || shiftedCharLatin) {
++ return WidgetUtils::ComputeKeyCodeFromChar(
++ unmodCharLatin ? unmodCharLatin : shiftedCharLatin);
++ }
++
++ // Otherwise, let's decide keyCode value from the hardware_keycode
++ // value on major keyboard layout.
++ CodeNameIndex code = ComputeDOMCodeNameIndex(aGdkKeyEvent);
++ return WidgetKeyboardEvent::GetFallbackKeyCodeOfPunctuationKey(code);
+ }
+
+ KeyNameIndex
+diff --git widget/gtk/nsGtkKeyUtils.h widget/gtk/nsGtkKeyUtils.h
+index 480d02322752..3dc8a4f6a936 100644
+--- widget/gtk/nsGtkKeyUtils.h
++++ widget/gtk/nsGtkKeyUtils.h
+@@ -337,6 +337,16 @@ protected:
+ */
+ static bool IsBasicLatinLetterOrNumeral(uint32_t aCharCode);
+
++ /**
++ * IsPrintableASCIICharacter() checks whether the aCharCode is a printable
++ * ASCII character. I.e., returns false if aCharCode is a control
++ * character even in an ASCII character.
++ */
++ static bool IsPrintableASCIICharacter(uint32_t aCharCode)
++ {
++ return aCharCode >= 0x20 && aCharCode <= 0x7E;
++ }
++
+ /**
+ * GetGDKKeyvalWithoutModifier() returns the keyval for aGdkKeyEvent when
+ * ignoring the modifier state except NumLock. (NumLock is a key to change
+diff --git widget/tests/test_keycodes.xul widget/tests/test_keycodes.xul
+index 8a935e74a7f4..db789e8be367 100644
+--- widget/tests/test_keycodes.xul
++++ widget/tests/test_keycodes.xul
+@@ -494,7 +494,7 @@ function* runKeyEventTests()
+ "a", "KeyA", nsIDOMKeyEvent.DOM_VK_A, "a", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_GERMAN, keyCode:MAC_VK_ANSI_LeftBracket,
+ modifiers: {}, chars:"\u00fc", unmodifiedChars:"\u00fc"},
+- "\u00fc", "BracketLeft", 0, "\u00fc", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "\u00fc", "BracketLeft", nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET, "\u00fc", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_GERMAN, keyCode:MAC_VK_ANSI_Minus,
+ modifiers: {}, chars:"\u00df", unmodifiedChars:"\u00df"},
+ "\u00df", "Minus", nsIDOMKeyEvent.DOM_VK_QUESTION_MARK, "\u00df", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+@@ -2737,10 +2737,9 @@ function* runKeyEventTests()
+ yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_Quote,
+ modifiers:{}, chars:"\u0E07", unmodifiedChars:"\u0E07"},
+ "\u0E07", "Quote", nsIDOMKeyEvent.DOM_VK_PERIOD, "\u0E07", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+- // keycode should be zero if the character of the key on the latest ASCII capable keyboard layout isn't for alphabet
+ yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_Period,
+ modifiers:{}, chars:"\u0E43", unmodifiedChars:"\u0E43"},
+- "\u0E43", "Period", 0, "\u0E43", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "\u0E43", "Period", nsIDOMKeyEvent.DOM_VK_PERIOD, "\u0E43", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ // keycode should be DOM_VK_[0-9] if the key on the latest ASCII capable keyboard layout is for numeric
+ yield testKey({layout:KEYBOARD_LAYOUT_THAI, keyCode:MAC_VK_ANSI_1,
+ modifiers:{}, chars:"\u0E45", unmodifiedChars:"\u0E45"},
+@@ -4129,12 +4128,14 @@ function* runKeyEventTests()
+ "\u00E7", "Digit9", nsIDOMKeyEvent.DOM_VK_9, "\u00E7", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+
+ // OEM keys
++ // If the key doesn't cause ASCII character even with or without Shift key, keyCode value should be same as
++ // the key which causes the virtual keycode on ANSI keyboard layout.
+ yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_7,
+ modifiers:{}, chars:"\u00B2"},
+- "\u00B2", "Backquote", 0, "\u00B2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "\u00B2", "Backquote", nsIDOMKeyEvent.DOM_VK_QUOTE, "\u00B2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_7,
+ modifiers:{shiftKey:1}, chars:""},
+- "", "Backquote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "", "Backquote", nsIDOMKeyEvent.DOM_VK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_4,
+ modifiers:{}, chars:")"},
+ ")", "Minus", nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, ")", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+@@ -4205,10 +4206,10 @@ function* runKeyEventTests()
+ // OEM keys with ShiftLock
+ yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_7,
+ modifiers:{capsLockKey:1}, chars:"\u00B2"},
+- "\u00B2", "Backquote", 0, "\u00B2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "\u00B2", "Backquote", nsIDOMKeyEvent.DOM_VK_QUOTE, "\u00B2", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_7,
+ modifiers:{capsLockKey:1, shiftKey:1}, chars:""},
+- "", "Backquote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "", "Backquote", nsIDOMKeyEvent.DOM_VK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_4,
+ modifiers:{capsLockKey:1}, chars:"\u00B0"},
+ "\u00B0", "Minus", nsIDOMKeyEvent.DOM_VK_CLOSE_PAREN, "\u00B0", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+@@ -4223,10 +4224,10 @@ function* runKeyEventTests()
+ "=", "Equal", nsIDOMKeyEvent.DOM_VK_EQUALS, "=", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ //yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6,
+ // modifiers:{capsLockKey:1}, chars:""},
+- // "Dead", "BracketLeft", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key
++ // "Dead", "BracketLeft", nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key
+ //yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_6,
+ // modifiers:{capsLockKey:1, shiftKey:1}, chars:""},
+- // ["\u00A8\u00A8", "\u00A8", "\u00A8", "\u00A8"], "BracketLeft", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key
++ // ["\u00A8\u00A8", "\u00A8", "\u00A8", "\u00A8"], "BracketLeft", nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD); // Dead-key
+ yield testKey({layout:KEYBOARD_LAYOUT_FRENCH, keyCode:WIN_VK_OEM_1,
+ modifiers:{capsLockKey:1}, chars:"\u00A3"},
+ "\u00A3", "BracketRight", nsIDOMKeyEvent.DOM_VK_DOLLAR, "\u00A3", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+@@ -4496,56 +4497,56 @@ function* runKeyEventTests()
+
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7,
+ modifiers:{}, chars:""},
+- "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "Dead", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7,
+ modifiers:{}, chars:"\u00B4\u00B4"},
+- ["\u00B4\u00B4", "\u00B4", "\u00B4", "\u00B4"], "Quote", 0, "\u00B4\u00B4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ ["\u00B4\u00B4", "\u00B4", "\u00B4", "\u00B4"], "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "\u00B4\u00B4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7,
+ modifiers:{}, chars:""},
+- "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "Dead", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_A,
+ modifiers:{}, chars:"\u00E1"},
+ ["\u00E1", "\u00E1", "a"], "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00E1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7,
+ modifiers:{}, chars:""},
+- "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "Dead", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_A,
+ modifiers:{shiftKey:1}, chars:"\u00C1"},
+ ["\u00C1", "\u00C1", "A"], "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00C1", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7,
+ modifiers:{}, chars:""},
+- "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "Dead", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_Q,
+ modifiers:{}, chars:"\u00B4q"},
+ ["\u00B4q", "\u00B4", "q", "q"], "KeyQ", nsIDOMKeyEvent.DOM_VK_Q, "\u00B4q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7,
+ modifiers:{shiftKey:1}, chars:""},
+- "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "Dead", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7,
+ modifiers:{shiftKey:1}, chars:"\u00A8\u00A8"},
+- ["\u00A8\u00A8", "\u00A8", "\u00A8", "\u00A8"], "Quote", 0, "\u00A8\u00A8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ ["\u00A8\u00A8", "\u00A8", "\u00A8", "\u00A8"], "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "\u00A8\u00A8", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7,
+ modifiers:{shiftKey:1}, chars:""},
+- "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "Dead", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_A,
+ modifiers:{shiftKey:1}, chars:"\u00C4"},
+ ["\u00C4", "\u00C4", "A"], "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00C4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7,
+ modifiers:{shiftKey:1}, chars:""},
+- "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "Dead", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_A,
+ modifiers:{}, chars:"\u00E4"},
+ ["\u00E4", "\u00E4", "a"], "KeyA", nsIDOMKeyEvent.DOM_VK_A, "\u00E4", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_OEM_7,
+ modifiers:{shiftKey:1}, chars:""},
+- "Dead", "Quote", 0, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
++ "Dead", "Quote", nsIDOMKeyEvent.DOM_VK_QUOTE, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+ yield testKey({layout:KEYBOARD_LAYOUT_SPANISH, keyCode:WIN_VK_Q,
+ modifiers:{shiftKey:1}, chars:"\u00A8Q"},
+ ["\u00A8Q", "\u00A8", "Q", "Q"], "KeyQ", nsIDOMKeyEvent.DOM_VK_Q, "\u00A8Q", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+diff --git widget/windows/KeyboardLayout.cpp widget/windows/KeyboardLayout.cpp
+index e29c0b0655d9..947e914e4bef 100644
+--- widget/windows/KeyboardLayout.cpp
++++ widget/windows/KeyboardLayout.cpp
+@@ -4721,7 +4721,75 @@ KeyboardLayout::ConvertNativeKeyCodeToDOMKeyCode(UINT aNativeKeyCode) const
+ uniChars = GetUniCharsAndModifiers(aNativeKeyCode, modKeyState);
+ if (uniChars.Length() != 1 ||
+ uniChars.CharAt(0) < ' ' || uniChars.CharAt(0) > 0x7F) {
+- return 0;
++ // In this case, we've returned 0 in this case for long time because
++ // we decided that we should avoid setting same keyCode value to 2 or
++ // more keys since active keyboard layout may have a key to input the
++ // punctuation with different key. However, setting keyCode to 0
++ // makes some web applications which are aware of neither
++ // KeyboardEvent.key nor KeyboardEvent.code not work with Firefox
++ // when user selects non-ASCII capable keyboard layout such as
++ // Russian and Thai layout. So, let's decide keyCode value with
++ // major keyboard layout's key which causes the OEM keycode.
++ // Actually, this maps same keyCode value to 2 keys on Russian
++ // keyboard layout. "Period" key causes VK_OEM_PERIOD but inputs
++ // Yu of Cyrillic and "Slash" key causes VK_OEM_2 (same as US
++ // keyboard layout) but inputs "." (period of ASCII). Therefore,
++ // we return DOM_VK_PERIOD which is same as VK_OEM_PERIOD for
++ // "Period" key. On the other hand, we use same keyCode value for
++ // "Slash" key too because it inputs ".".
++ CodeNameIndex code;
++ switch (aNativeKeyCode) {
++ case VK_OEM_1:
++ code = CODE_NAME_INDEX_Semicolon;
++ break;
++ case VK_OEM_PLUS:
++ code = CODE_NAME_INDEX_Equal;
++ break;
++ case VK_OEM_COMMA:
++ code = CODE_NAME_INDEX_Comma;
++ break;
++ case VK_OEM_MINUS:
++ code = CODE_NAME_INDEX_Minus;
++ break;
++ case VK_OEM_PERIOD:
++ code = CODE_NAME_INDEX_Period;
++ break;
++ case VK_OEM_2:
++ code = CODE_NAME_INDEX_Slash;
++ break;
++ case VK_OEM_3:
++ code = CODE_NAME_INDEX_Backquote;
++ break;
++ case VK_OEM_4:
++ code = CODE_NAME_INDEX_BracketLeft;
++ break;
++ case VK_OEM_5:
++ code = CODE_NAME_INDEX_Backslash;
++ break;
++ case VK_OEM_6:
++ code = CODE_NAME_INDEX_BracketRight;
++ break;
++ case VK_OEM_7:
++ code = CODE_NAME_INDEX_Quote;
++ break;
++ case VK_OEM_8:
++ // Use keyCode value for "Backquote" key on UK keyboard layout.
++ code = CODE_NAME_INDEX_Backquote;
++ break;
++ case VK_OEM_102:
++ // Use keyCode value for "IntlBackslash" key.
++ code = CODE_NAME_INDEX_IntlBackslash;
++ break;
++ case VK_ABNT_C1: // "/" of ABNT.
++ // Use keyCode value for "IntlBackslash" key on ABNT keyboard
++ // layout.
++ code = CODE_NAME_INDEX_IntlBackslash;
++ break;
++ default:
++ MOZ_ASSERT_UNREACHABLE("Handle all OEM keycode values");
++ return 0;
++ }
++ return WidgetKeyboardEvent::GetFallbackKeyCodeOfPunctuationKey(code);
+ }
+ }
+ return WidgetUtils::ComputeKeyCodeFromChar(uniChars.CharAt(0));
diff --git a/www/waterfox/files/patch-bug1134077 b/www/waterfox/files/patch-bug1134077
new file mode 100644
index 000000000000..ba8b29523d64
--- /dev/null
+++ b/www/waterfox/files/patch-bug1134077
@@ -0,0 +1,65 @@
+commit a67756af6ac4
+Author: decltype <mozilla@decltype.org>
+Date: Fri Feb 2 18:39:37 2018 +0100
+
+ Bug 1134077 - X11: Set EWMH property to keep top-level nsWindows composited. r=karlt
+
+ Some compositors such as GNOME mutter use heuristics to unredirect fullscreen
+ windows in an effort to reduce output latency. This works fine for applications
+ that take the proper steps to ensure all framebuffer updates happen in the
+ vblank interval. Since this is not currently the case for Firefox, bypassing
+ the compositor will lead to frame tearing.
+
+ Set _NET_WM_BYPASS_COMPOSITOR to 2 to opt out of fullscreen unredirection.
+
+ MozReview-Commit-ID: 1xW2VAnbiJw
+
+ --HG--
+ extra : rebase_source : 77c4ae490413057d8d9dadf9b155c86ddbbcb4b5
+---
+ widget/gtk/mozgtk/mozgtk.c | 1 +
+ widget/gtk/nsWindow.cpp | 19 +++++++++++++++++++
+ 2 files changed, 20 insertions(+)
+
+diff --git widget/gtk/mozgtk/mozgtk.c widget/gtk/mozgtk/mozgtk.c
+index a182d9b278e7..023cd192d522 100644
+--- widget/gtk/mozgtk/mozgtk.c
++++ widget/gtk/mozgtk/mozgtk.c
+@@ -52,6 +52,7 @@ STUB(gdk_keyval_to_unicode)
+ STUB(gdk_pango_context_get)
+ STUB(gdk_pointer_grab)
+ STUB(gdk_pointer_ungrab)
++STUB(gdk_property_change)
+ STUB(gdk_property_get)
+ STUB(gdk_screen_get_default)
+ STUB(gdk_screen_get_display)
+diff --git widget/gtk/nsWindow.cpp widget/gtk/nsWindow.cpp
+index 0e75cc8c5968..b59ac05dd3c4 100644
+--- widget/gtk/nsWindow.cpp
++++ widget/gtk/nsWindow.cpp
+@@ -3803,6 +3803,25 @@ nsWindow::Create(nsIWidget* aParent,
+ cairo_region_destroy(region);
+ }
+ }
++
++#ifdef MOZ_X11
++ // Set window manager hint to keep fullscreen windows composited.
++ //
++ // If the window were to get unredirected, there could be visible
++ // tearing because Gecko does not align its framebuffer updates with
++ // vblank.
++ if (mIsX11Display) {
++ gulong value = 2; // Opt out of unredirection
++ GdkAtom cardinal_atom = gdk_x11_xatom_to_atom(XA_CARDINAL);
++ gdk_property_change(gtk_widget_get_window(mShell),
++ gdk_atom_intern("_NET_WM_BYPASS_COMPOSITOR", FALSE),
++ cardinal_atom,
++ 32, // format
++ GDK_PROP_MODE_REPLACE,
++ (guchar*)&value,
++ 1);
++ }
++#endif
+ }
+ break;
+
diff --git a/www/waterfox/files/patch-bug1314928 b/www/waterfox/files/patch-bug1314928
new file mode 100644
index 000000000000..22309cf26ea7
--- /dev/null
+++ b/www/waterfox/files/patch-bug1314928
@@ -0,0 +1,64 @@
+commit 4cb65b680138
+Author: Martin Stransky <stransky@redhat.com>
+Date: Fri Aug 25 10:30:28 2017 +0200
+
+ Bug 1314928 - get link text color by GTK_STATE_FLAG_LINK on Gtk3 >= 3.12, r=karlt
+
+ MozReview-Commit-ID: BPR2AgoUx5H
+
+ --HG--
+ extra : rebase_source : c4670cd6b7df84dd00a4d04c3bfc582f917795da
+---
+ widget/gtk/nsLookAndFeel.cpp | 32 ++++++++++++++++++++++++--------
+ 1 file changed, 24 insertions(+), 8 deletions(-)
+
+diff --git widget/gtk/nsLookAndFeel.cpp widget/gtk/nsLookAndFeel.cpp
+index 7cd8e8dcc163..6bb3e27c6653 100644
+--- widget/gtk/nsLookAndFeel.cpp
++++ widget/gtk/nsLookAndFeel.cpp
+@@ -43,6 +43,10 @@ using mozilla::LookAndFeel;
+ ((nscolor) NS_RGBA((int)((c).red*255), (int)((c).green*255), \
+ (int)((c).blue*255), (int)((c).alpha*255)))
+
++#if !GTK_CHECK_VERSION(3,12,0)
++#define GTK_STATE_FLAG_LINK (static_cast<GtkStateFlags>(1 << 9))
++#endif
++
+ nsLookAndFeel::nsLookAndFeel()
+ : nsXPLookAndFeel(),
+ #if (MOZ_WIDGET_GTK == 2)
+@@ -1457,14 +1461,26 @@ nsLookAndFeel::EnsureInit()
+ }
+ sMenuSupportsDrag = supports_menubar_drag;
+
+- colorValuePtr = nullptr;
+- gtk_widget_style_get(linkButton, "link-color", &colorValuePtr, nullptr);
+- if (colorValuePtr) {
+- colorValue = *colorValuePtr; // we can't pass deref pointers to GDK_COLOR_TO_NS_RGB
+- sNativeHyperLinkText = GDK_COLOR_TO_NS_RGB(colorValue);
+- gdk_color_free(colorValuePtr);
+- } else {
+- sNativeHyperLinkText = NS_RGB(0x00,0x00,0xEE);
++#if (MOZ_WIDGET_GTK == 3)
++ if (gtk_check_version(3, 12, 0) == nullptr) {
++ // TODO: It returns wrong color for themes which
++ // sets link color for GtkLabel only as we query
++ // GtkLinkButton style here.
++ style = gtk_widget_get_style_context(linkButton);
++ gtk_style_context_get_color(style, GTK_STATE_FLAG_LINK, &color);
++ sNativeHyperLinkText = GDK_RGBA_TO_NS_RGBA(color);
++ } else
++#endif
++ {
++ colorValuePtr = nullptr;
++ gtk_widget_style_get(linkButton, "link-color", &colorValuePtr, nullptr);
++ if (colorValuePtr) {
++ colorValue = *colorValuePtr; // we can't pass deref pointers to GDK_COLOR_TO_NS_RGB
++ sNativeHyperLinkText = GDK_COLOR_TO_NS_RGB(colorValue);
++ gdk_color_free(colorValuePtr);
++ } else {
++ sNativeHyperLinkText = NS_RGB(0x00,0x00,0xEE);
++ }
+ }
+
+ // invisible character styles
diff --git a/www/waterfox/files/patch-bug1360278 b/www/waterfox/files/patch-bug1360278
new file mode 100644
index 000000000000..75e49f92f346
--- /dev/null
+++ b/www/waterfox/files/patch-bug1360278
@@ -0,0 +1,184 @@
+commit 5d127ad3bd50
+Author: Robin Grenet <robin.grenet@wanadoo.fr>
+Date: Thu Nov 16 13:35:58 2017 +0100
+
+ Bug 1360278 - Add preference to trigger context menu on mouse up for GTK+ and macOS, r=mstange,smaug a=gchang
+
+ MozReview-Commit-ID: Bg60bD8jIg6
+
+ --HG--
+ extra : source : f540f9e801cb2e0be5259baea13dfce953ccb520
+---
+ modules/libpref/init/all.js | 4 ++++
+ widget/cocoa/nsChildView.mm | 23 +++++++++++++++++++++--
+ widget/gtk/nsWindow.cpp | 27 ++++++++++++++++++++-------
+ widget/gtk/nsWindow.h | 2 ++
+ widget/nsBaseWidget.cpp | 16 ++++++++++++++++
+ widget/nsBaseWidget.h | 6 ++++++
+ 6 files changed, 69 insertions(+), 9 deletions(-)
+
+diff --git modules/libpref/init/all.js modules/libpref/init/all.js
+index f9402630cf27..97ece9f13467 100644
+--- modules/libpref/init/all.js
++++ modules/libpref/init/all.js
+@@ -234,6 +234,10 @@ pref("browser.sessionhistory.max_total_viewers", -1);
+
+ pref("ui.use_native_colors", true);
+ pref("ui.click_hold_context_menus", false);
++
++// Pop up context menu on mouseup instead of mousedown, if that's the OS default.
++// Note: ignored on Windows (context menus always use mouseup)
++pref("ui.context_menus.after_mouseup", false);
+ // Duration of timeout of incremental search in menus (ms). 0 means infinite.
+ pref("ui.menu.incremental_search.timeout", 1000);
+ // If true, all popups won't hide automatically on blur
+diff --git widget/cocoa/nsChildView.mm widget/cocoa/nsChildView.mm
+index cac897327a19..bf42b4f8c095 100644
+--- widget/cocoa/nsChildView.mm
++++ widget/cocoa/nsChildView.mm
+@@ -4700,8 +4700,10 @@ NSEvent* gLastDragMouseDownEvent = nil;
+ if (!mGeckoChild)
+ return;
+
+- // Let the superclass do the context menu stuff.
+- [super rightMouseDown:theEvent];
++ if (!nsBaseWidget::ShowContextMenuAfterMouseUp()) {
++ // Let the superclass do the context menu stuff.
++ [super rightMouseDown:theEvent];
++ }
+
+ NS_OBJC_END_TRY_ABORT_BLOCK;
+ }
+@@ -4724,6 +4726,23 @@ NSEvent* gLastDragMouseDownEvent = nil;
+
+ nsAutoRetainCocoaObject kungFuDeathGrip(self);
+ mGeckoChild->DispatchInputEvent(&geckoEvent);
++ if (!mGeckoChild)
++ return;
++
++ if (nsBaseWidget::ShowContextMenuAfterMouseUp()) {
++ // Let the superclass do the context menu stuff, but pretend it's rightMouseDown.
++ NSEvent *dupeEvent = [NSEvent mouseEventWithType:NSRightMouseDown
++ location:theEvent.locationInWindow
++ modifierFlags:theEvent.modifierFlags
++ timestamp:theEvent.timestamp
++ windowNumber:theEvent.windowNumber
++ context:theEvent.context
++ eventNumber:theEvent.eventNumber
++ clickCount:theEvent.clickCount
++ pressure:theEvent.pressure];
++
++ [super rightMouseDown:dupeEvent];
++ }
+
+ NS_OBJC_END_TRY_ABORT_BLOCK;
+ }
+diff --git widget/gtk/nsWindow.cpp widget/gtk/nsWindow.cpp
+index c3da6dc00b0c..c220d0bb2192 100644
+--- widget/gtk/nsWindow.cpp
++++ widget/gtk/nsWindow.cpp
+@@ -2737,6 +2737,19 @@ static guint ButtonMaskFromGDKButton(guint button)
+ return GDK_BUTTON1_MASK << (button - 1);
+ }
+
++void
++nsWindow::DispatchContextMenuEventFromMouseEvent(uint16_t domButton,
++ GdkEventButton *aEvent)
++{
++ if (domButton == WidgetMouseEvent::eRightButton && MOZ_LIKELY(!mIsDestroyed)) {
++ WidgetMouseEvent contextMenuEvent(true, eContextMenu, this,
++ WidgetMouseEvent::eReal);
++ InitButtonEvent(contextMenuEvent, aEvent);
++ contextMenuEvent.pressure = mLastMotionPressure;
++ DispatchInputEvent(&contextMenuEvent);
++ }
++}
++
+ void
+ nsWindow::OnButtonPressEvent(GdkEventButton *aEvent)
+ {
+@@ -2806,13 +2819,8 @@ nsWindow::OnButtonPressEvent(GdkEventButton *aEvent)
+ DispatchInputEvent(&event);
+
+ // right menu click on linux should also pop up a context menu
+- if (domButton == WidgetMouseEvent::eRightButton &&
+- MOZ_LIKELY(!mIsDestroyed)) {
+- WidgetMouseEvent contextMenuEvent(true, eContextMenu, this,
+- WidgetMouseEvent::eReal);
+- InitButtonEvent(contextMenuEvent, aEvent);
+- contextMenuEvent.pressure = mLastMotionPressure;
+- DispatchInputEvent(&contextMenuEvent);
++ if (!nsBaseWidget::ShowContextMenuAfterMouseUp()) {
++ DispatchContextMenuEventFromMouseEvent(domButton, aEvent);
+ }
+ }
+
+@@ -2848,6 +2856,11 @@ nsWindow::OnButtonReleaseEvent(GdkEventButton *aEvent)
+
+ DispatchInputEvent(&event);
+ mLastMotionPressure = pressure;
++
++ // right menu click on linux should also pop up a context menu
++ if (nsBaseWidget::ShowContextMenuAfterMouseUp()) {
++ DispatchContextMenuEventFromMouseEvent(domButton, aEvent);
++ }
+ }
+
+ void
+diff --git widget/gtk/nsWindow.h widget/gtk/nsWindow.h
+index 0fafc8994579..7a28e3260c0f 100644
+--- widget/gtk/nsWindow.h
++++ widget/gtk/nsWindow.h
+@@ -245,6 +245,8 @@ private:
+
+ void UpdateClientOffset();
+
++ void DispatchContextMenuEventFromMouseEvent(uint16_t domButton,
++ GdkEventButton *aEvent);
+ public:
+ void ThemeChanged(void);
+ void OnDPIChanged(void);
+diff --git widget/nsBaseWidget.cpp widget/nsBaseWidget.cpp
+index c0694714c69d..4a1320fe23d5 100644
+--- widget/nsBaseWidget.cpp
++++ widget/nsBaseWidget.cpp
+@@ -1218,6 +1218,22 @@ nsBaseWidget::DispatchEventToAPZOnly(mozilla::WidgetInputEvent* aEvent)
+ }
+ }
+
++// static
++bool
++nsBaseWidget::ShowContextMenuAfterMouseUp()
++{
++ static bool gContextMenuAfterMouseUp = false;
++ static bool gContextMenuAfterMouseUpCached = false;
++ if (!gContextMenuAfterMouseUpCached) {
++ Preferences::AddBoolVarCache(&gContextMenuAfterMouseUp,
++ "ui.context_menus.after_mouseup",
++ false);
++
++ gContextMenuAfterMouseUpCached = true;
++ }
++ return gContextMenuAfterMouseUp;
++}
++
+ nsIDocument*
+ nsBaseWidget::GetDocument() const
+ {
+diff --git widget/nsBaseWidget.h widget/nsBaseWidget.h
+index f4e8e3d78330..3cb56f38b6ce 100644
+--- widget/nsBaseWidget.h
++++ widget/nsBaseWidget.h
+@@ -417,6 +417,12 @@ public:
+ void RecvScreenPixels(mozilla::ipc::Shmem&& aMem, const ScreenIntSize& aSize) override {};
+ #endif
+
++ /**
++ * Whether context menus should only appear on mouseup instead of mousedown,
++ * on OSes where they normally appear on mousedown (macOS, *nix).
++ */
++ static bool ShowContextMenuAfterMouseUp();
++
+ protected:
+ // These are methods for CompositorWidgetWrapper, and should only be
+ // accessed from that class. Derived widgets can choose which methods to
diff --git a/www/waterfox/files/patch-bug1381815 b/www/waterfox/files/patch-bug1381815
new file mode 100644
index 000000000000..5681303ce451
--- /dev/null
+++ b/www/waterfox/files/patch-bug1381815
@@ -0,0 +1,278 @@
+commit 165fab2f8596
+Author: Jan Horak <jhorak@redhat.com>
+Date: Tue Oct 10 13:35:56 2017 +0200
+
+ Bug 1381815 - fixing dimensions of radio and checkbox for GTK 3.20+; r=karlt
+
+ In the GTK < 3.20 the size of radio and checkbox toggle is determined by indicator
+ spacing and indicator size. By GTK 3.20+ it is replaced by standard box model
+ (padding, margin, border). The patch fixes that while keeping the functionality
+ for older GTK. The values are also cached by similar way as scrollbar metrics
+ are cached now.
+
+ The focus is no longer rendered by GTK but by Mozilla code, so the extra
+ size for toggles has been removed from GetExtraSizeForWidget and toggles
+ no longer render focus indicator.
+
+ MozReview-Commit-ID: 1Wg5AgHy1Vz
+
+ --HG--
+ extra : rebase_source : 81437f45b7d32555942d21fccc9de4a561d85111
+---
+ widget/gtk/gtk3drawing.cpp | 121 ++++++++++++++++++++++++++++++----------
+ widget/gtk/gtkdrawing.h | 14 +++++
+ widget/gtk/nsNativeThemeGTK.cpp | 32 +----------
+ 3 files changed, 107 insertions(+), 60 deletions(-)
+
+diff --git widget/gtk/gtk3drawing.cpp widget/gtk/gtk3drawing.cpp
+index 4c562b380095..7968aef920f6 100644
+--- widget/gtk/gtk3drawing.cpp
++++ widget/gtk/gtk3drawing.cpp
+@@ -22,6 +22,8 @@ static gboolean checkbox_check_state;
+ static gboolean notebook_has_tab_gap;
+
+ static ScrollbarGTKMetrics sScrollbarMetrics[2];
++static ToggleGTKMetrics sCheckboxMetrics;
++static ToggleGTKMetrics sRadioMetrics;
+
+ #define ARROW_UP 0
+ #define ARROW_DOWN G_PI
+@@ -110,6 +112,8 @@ moz_gtk_refresh()
+
+ sScrollbarMetrics[GTK_ORIENTATION_HORIZONTAL].initialized = false;
+ sScrollbarMetrics[GTK_ORIENTATION_VERTICAL].initialized = false;
++ sCheckboxMetrics.initialized = false;
++ sRadioMetrics.initialized = false;
+ }
+
+ gint
+@@ -308,33 +312,21 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRectangle* rect,
+ gboolean isradio, GtkTextDirection direction)
+ {
+ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+- gint indicator_size, indicator_spacing;
+ gint x, y, width, height;
+- gint focus_x, focus_y, focus_width, focus_height;
+ GtkStyleContext *style;
+
+- GtkWidget *widget = GetWidget(isradio ? MOZ_GTK_RADIOBUTTON_CONTAINER :
+- MOZ_GTK_CHECKBUTTON_CONTAINER);
+- gtk_widget_style_get(widget,
+- "indicator_size", &indicator_size,
+- "indicator_spacing", &indicator_spacing,
+- nullptr);
++ const ToggleGTKMetrics* metrics = GetToggleMetrics(isradio);
+
+ // XXX we should assert rect->height >= indicator_size too
+ // after bug 369581 is fixed.
+- MOZ_ASSERT(rect->width >= indicator_size,
++ MOZ_ASSERT(rect->width >= metrics->minSizeWithBorder.width,
+ "GetMinimumWidgetSize was ignored");
+
+ // Paint it center aligned in the rect.
+- x = rect->x + (rect->width - indicator_size) / 2;
+- y = rect->y + (rect->height - indicator_size) / 2;
+- width = indicator_size;
+- height = indicator_size;
+-
+- focus_x = x - indicator_spacing;
+- focus_y = y - indicator_spacing;
+- focus_width = width + 2 * indicator_spacing;
+- focus_height = height + 2 * indicator_spacing;
++ width = metrics->minSizeWithBorder.width;
++ height = metrics->minSizeWithBorder.height;
++ x = rect->x + (rect->width - width) / 2;
++ y = rect->y + (rect->height - height) / 2;
+
+ if (selected)
+ state_flags = static_cast<GtkStateFlags>(state_flags|checkbox_check_state);
+@@ -348,20 +340,25 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRectangle* rect,
+ if (gtk_check_version(3, 20, 0) == nullptr) {
+ gtk_render_background(style, cr, x, y, width, height);
+ gtk_render_frame(style, cr, x, y, width, height);
+- }
+-
+- if (isradio) {
+- gtk_render_option(style, cr, x, y, width, height);
+- if (state->focused) {
+- gtk_render_focus(style, cr, focus_x, focus_y,
+- focus_width, focus_height);
++ // Indicator is inset by the toggle's padding and border.
++ gint indicator_x = x + metrics->borderAndPadding.left;
++ gint indicator_y = y + metrics->borderAndPadding.top;
++ gint indicator_width = metrics->minSizeWithBorder.width -
++ metrics->borderAndPadding.left - metrics->borderAndPadding.right;
++ gint indicator_height = metrics->minSizeWithBorder.height -
++ metrics->borderAndPadding.top - metrics->borderAndPadding.bottom;
++ if (isradio) {
++ gtk_render_option(style, cr, indicator_x, indicator_y,
++ indicator_width, indicator_height);
++ } else {
++ gtk_render_check(style, cr, indicator_x, indicator_y,
++ indicator_width, indicator_height);
+ }
+- }
+- else {
+- gtk_render_check(style, cr, x, y, width, height);
+- if (state->focused) {
+- gtk_render_focus(style, cr,
+- focus_x, focus_y, focus_width, focus_height);
++ } else {
++ if (isradio) {
++ gtk_render_option(style, cr, x, y, width, height);
++ } else {
++ gtk_render_check(style, cr, x, y, width, height);
+ }
+ }
+
+@@ -2514,6 +2511,68 @@ SizeFromLengthAndBreadth(GtkOrientation aOrientation,
+ MozGtkSize({aLength, aBreadth}) : MozGtkSize({aBreadth, aLength});
+ }
+
++const ToggleGTKMetrics*
++GetToggleMetrics(bool isRadio)
++{
++ ToggleGTKMetrics* metrics;
++ if (isRadio) {
++ metrics = &sRadioMetrics;
++ } else {
++ metrics = &sCheckboxMetrics;
++ }
++ if (metrics->initialized)
++ return metrics;
++
++ metrics->initialized = true;
++ if (gtk_check_version(3,20,0) == nullptr) {
++ GtkStyleContext* style;
++ if (isRadio) {
++ style = GetStyleContext(MOZ_GTK_RADIOBUTTON);
++ } else {
++ style = GetStyleContext(MOZ_GTK_CHECKBUTTON);
++ }
++ GtkStateFlags state_flags = gtk_style_context_get_state(style);
++ gtk_style_context_get(style, state_flags,
++ "min-height",&(metrics->minSizeWithBorder.height),
++ "min-width", &(metrics->minSizeWithBorder.width),
++ nullptr);
++ // Fallback to indicator size if min dimensions are zero
++ if (metrics->minSizeWithBorder.height == 0 ||
++ metrics->minSizeWithBorder.width == 0) {
++ gint indicator_size;
++ gtk_widget_style_get(GetWidget(MOZ_GTK_CHECKBUTTON_CONTAINER),
++ "indicator_size", &indicator_size, nullptr);
++ if (metrics->minSizeWithBorder.height == 0) {
++ metrics->minSizeWithBorder.height = indicator_size;
++ }
++ if (metrics->minSizeWithBorder.width == 0) {
++ metrics->minSizeWithBorder.width = indicator_size;
++ }
++ }
++
++ GtkBorder border, padding;
++ gtk_style_context_get_border(style, state_flags, &border);
++ gtk_style_context_get_padding(style, state_flags, &padding);
++ metrics->borderAndPadding.left = border.left + padding.left;
++ metrics->borderAndPadding.right = border.right + padding.right;
++ metrics->borderAndPadding.top = border.top + padding.top;
++ metrics->borderAndPadding.bottom = border.bottom + padding.bottom;
++ metrics->minSizeWithBorder.width += metrics->borderAndPadding.left +
++ metrics->borderAndPadding.right;
++ metrics->minSizeWithBorder.height += metrics->borderAndPadding.top +
++ metrics->borderAndPadding.bottom;
++ } else {
++ gint indicator_size, indicator_spacing;
++ gtk_widget_style_get(GetWidget(MOZ_GTK_CHECKBUTTON_CONTAINER),
++ "indicator_size", &indicator_size,
++ "indicator_spacing", &indicator_spacing,
++ nullptr);
++ metrics->minSizeWithBorder.width =
++ metrics->minSizeWithBorder.height = indicator_size;
++ }
++ return metrics;
++}
++
+ const ScrollbarGTKMetrics*
+ GetScrollbarMetrics(GtkOrientation aOrientation)
+ {
+diff --git widget/gtk/gtkdrawing.h widget/gtk/gtkdrawing.h
+index 42dbf8287499..909c18f7f525 100644
+--- widget/gtk/gtkdrawing.h
++++ widget/gtk/gtkdrawing.h
+@@ -83,6 +83,12 @@ typedef struct {
+ } border;
+ } ScrollbarGTKMetrics;
+
++typedef struct {
++ bool initialized;
++ MozGtkSize minSizeWithBorder;
++ GtkBorder borderAndPadding;
++} ToggleGTKMetrics;
++
+ typedef enum {
+ MOZ_GTK_STEPPER_DOWN = 1 << 0,
+ MOZ_GTK_STEPPER_BOTTOM = 1 << 1,
+@@ -391,6 +397,14 @@ moz_gtk_get_tab_border(gint* left, gint* top, gint* right, gint* bottom,
+ gint
+ moz_gtk_checkbox_get_metrics(gint* indicator_size, gint* indicator_spacing);
+
++/**
++ * Get metrics of the toggle (radio or checkbox)
++ * isRadio: [IN] true when requesting metrics for the radio button
++ * returns: pointer to ToggleGTKMetrics struct
++ */
++const ToggleGTKMetrics*
++GetToggleMetrics(bool isRadio);
++
+ /**
+ * Get the desired size of a GtkRadioButton
+ * indicator_size: [OUT] the indicator size
+diff --git widget/gtk/nsNativeThemeGTK.cpp widget/gtk/nsNativeThemeGTK.cpp
+index 06e62efbcda8..da3eaa71a6b4 100644
+--- widget/gtk/nsNativeThemeGTK.cpp
++++ widget/gtk/nsNativeThemeGTK.cpp
+@@ -1020,24 +1020,6 @@ nsNativeThemeGTK::GetExtraSizeForWidget(nsIFrame* aFrame, uint8_t aWidgetType,
+ aExtra->left = aExtra->right = 1;
+ break;
+
+- // Include the indicator spacing (the padding around the control).
+- case NS_THEME_CHECKBOX:
+- case NS_THEME_RADIO:
+- {
+- gint indicator_size, indicator_spacing;
+-
+- if (aWidgetType == NS_THEME_CHECKBOX) {
+- moz_gtk_checkbox_get_metrics(&indicator_size, &indicator_spacing);
+- } else {
+- moz_gtk_radio_get_metrics(&indicator_size, &indicator_spacing);
+- }
+-
+- aExtra->top = indicator_spacing;
+- aExtra->right = indicator_spacing;
+- aExtra->bottom = indicator_spacing;
+- aExtra->left = indicator_spacing;
+- break;
+- }
+ case NS_THEME_BUTTON :
+ {
+ if (IsDefaultButton(aFrame)) {
+@@ -1595,17 +1577,9 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
+ case NS_THEME_CHECKBOX:
+ case NS_THEME_RADIO:
+ {
+- gint indicator_size, indicator_spacing;
+-
+- if (aWidgetType == NS_THEME_CHECKBOX) {
+- moz_gtk_checkbox_get_metrics(&indicator_size, &indicator_spacing);
+- } else {
+- moz_gtk_radio_get_metrics(&indicator_size, &indicator_spacing);
+- }
+-
+- // Include space for the indicator and the padding around it.
+- aResult->width = indicator_size;
+- aResult->height = indicator_size;
++ const ToggleGTKMetrics* metrics = GetToggleMetrics(aWidgetType == NS_THEME_RADIO);
++ aResult->width = metrics->minSizeWithBorder.width;
++ aResult->height = metrics->minSizeWithBorder.height;
+ }
+ break;
+ case NS_THEME_TOOLBARBUTTON_DROPDOWN:
diff --git a/www/waterfox/files/patch-bug1387170 b/www/waterfox/files/patch-bug1387170
new file mode 100644
index 000000000000..fae4b65e028b
--- /dev/null
+++ b/www/waterfox/files/patch-bug1387170
@@ -0,0 +1,148 @@
+commit 02dc1567cd7d
+Author: Brendan Dahl <brendan.dahl@gmail.com>
+Date: Thu Aug 3 15:08:16 2017 -0700
+
+ Bug 1387170 - Use custom clipboard constructor instead of singleton. r=jrmuizel
+
+ This allows instances of the clipboard to be created (like it
+ was pre-headless).
+---
+ widget/gtk/nsClipboard.cpp | 31 -------------------------------
+ widget/gtk/nsClipboard.h | 2 --
+ widget/gtk/nsWidgetFactory.cpp | 26 ++++++++++++++++++++++++--
+ 3 files changed, 24 insertions(+), 35 deletions(-)
+
+diff --git widget/gtk/nsClipboard.cpp widget/gtk/nsClipboard.cpp
+index 6972715a72df..d07d5baeede3 100644
+--- widget/gtk/nsClipboard.cpp
++++ widget/gtk/nsClipboard.cpp
+@@ -9,7 +9,6 @@
+
+ #include "nsArrayUtils.h"
+ #include "nsClipboard.h"
+-#include "HeadlessClipboard.h"
+ #include "nsSupportsPrimitives.h"
+ #include "nsString.h"
+ #include "nsReadableUtils.h"
+@@ -21,7 +20,6 @@
+ #include "nsIObserverService.h"
+ #include "mozilla/Services.h"
+ #include "mozilla/RefPtr.h"
+-#include "mozilla/ClearOnShutdown.h"
+ #include "mozilla/TimeStamp.h"
+
+ #include "imgIContainer.h"
+@@ -39,7 +37,6 @@
+
+ #include "mozilla/Encoding.h"
+
+-#include "gfxPlatform.h"
+
+ using namespace mozilla;
+
+@@ -81,34 +78,6 @@ selection_request_filter (GdkXEvent *gdk_xevent,
+ GdkEvent *event,
+ gpointer data);
+
+-namespace mozilla {
+-namespace clipboard {
+-StaticRefPtr<nsIClipboard> sInstance;
+-}
+-}
+-/* static */ already_AddRefed<nsIClipboard>
+-nsClipboard::GetInstance()
+-{
+- using namespace mozilla::clipboard;
+-
+- if (!sInstance) {
+- if (gfxPlatform::IsHeadless()) {
+- sInstance = new widget::HeadlessClipboard();
+- } else {
+- RefPtr<nsClipboard> clipboard = new nsClipboard();
+- nsresult rv = clipboard->Init();
+- if (NS_FAILED(rv)) {
+- return nullptr;
+- }
+- sInstance = clipboard.forget();
+- }
+- ClearOnShutdown(&sInstance);
+- }
+-
+- RefPtr<nsIClipboard> service = sInstance.get();
+- return service.forget();
+-}
+-
+ nsClipboard::nsClipboard()
+ {
+ }
+diff --git widget/gtk/nsClipboard.h widget/gtk/nsClipboard.h
+index 725bcdce846a..70c866a013c9 100644
+--- widget/gtk/nsClipboard.h
++++ widget/gtk/nsClipboard.h
+@@ -23,8 +23,6 @@ public:
+ NS_DECL_NSICLIPBOARD
+ NS_DECL_NSIOBSERVER
+
+- static already_AddRefed<nsIClipboard> GetInstance();
+-
+ // Make sure we are initialized, called from the factory
+ // constructor
+ nsresult Init (void);
+diff --git widget/gtk/nsWidgetFactory.cpp widget/gtk/nsWidgetFactory.cpp
+index 3c8bc02ebbb5..86b9cdab77e7 100644
+--- widget/gtk/nsWidgetFactory.cpp
++++ widget/gtk/nsWidgetFactory.cpp
+@@ -17,6 +17,7 @@
+ #include "nsWindow.h"
+ #include "nsTransferable.h"
+ #include "nsHTMLFormatConverter.h"
++#include "HeadlessClipboard.h"
+ #ifdef MOZ_X11
+ #include "nsClipboardHelper.h"
+ #include "nsClipboard.h"
+@@ -72,7 +73,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
+ #ifdef MOZ_X11
+ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIdleServiceGTK, nsIdleServiceGTK::GetInstance)
+ NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
+-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIClipboard, nsClipboard::GetInstance)
+ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsDragService, nsDragService::GetInstance)
+ #endif
+ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsISound, nsSound::GetInstance)
+@@ -194,6 +194,28 @@ nsColorPickerConstructor(nsISupports *aOuter, REFNSIID aIID,
+ return picker->QueryInterface(aIID, aResult);
+ }
+
++static nsresult
++nsClipboardConstructor(nsISupports *aOuter, REFNSIID aIID,
++ void **aResult)
++{
++ *aResult = nullptr;
++ if (aOuter != nullptr) {
++ return NS_ERROR_NO_AGGREGATION;
++ }
++
++ nsCOMPtr<nsIClipboard> inst;
++ if (gfxPlatform::IsHeadless()) {
++ inst = new HeadlessClipboard();
++ } else {
++ RefPtr<nsClipboard> clipboard = new nsClipboard();
++ nsresult rv = clipboard->Init();
++ NS_ENSURE_SUCCESS(rv, rv);
++ inst = clipboard;
++ }
++
++ return inst->QueryInterface(aIID, aResult);
++}
++
+ NS_DEFINE_NAMED_CID(NS_WINDOW_CID);
+ NS_DEFINE_NAMED_CID(NS_CHILD_CID);
+ NS_DEFINE_NAMED_CID(NS_APPSHELL_CID);
+@@ -239,7 +261,7 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
+ { &kNS_SOUND_CID, false, nullptr, nsISoundConstructor, Module::MAIN_PROCESS_ONLY },
+ { &kNS_TRANSFERABLE_CID, false, nullptr, nsTransferableConstructor },
+ #ifdef MOZ_X11
+- { &kNS_CLIPBOARD_CID, false, nullptr, nsIClipboardConstructor, Module::MAIN_PROCESS_ONLY },
++ { &kNS_CLIPBOARD_CID, false, nullptr, nsClipboardConstructor, Module::MAIN_PROCESS_ONLY },
+ { &kNS_CLIPBOARDHELPER_CID, false, nullptr, nsClipboardHelperConstructor },
+ { &kNS_DRAGSERVICE_CID, false, nullptr, nsDragServiceConstructor, Module::MAIN_PROCESS_ONLY },
+ #endif
diff --git a/www/waterfox/files/patch-bug1396722 b/www/waterfox/files/patch-bug1396722
new file mode 100644
index 000000000000..55e085860e96
--- /dev/null
+++ b/www/waterfox/files/patch-bug1396722
@@ -0,0 +1,1426 @@
+commit 00beb3311073
+Author: Karl Tomlinson <karlt+@karlt.net>
+Date: Tue Sep 5 09:16:01 2017 +1200
+
+ bug 1396722 remove no-op ReleaseStyleContext() r=stransky+263117
+
+ MozReview-Commit-ID: DgKM0wrStrk
+
+ --HG--
+ extra : rebase_source : a26fdc5e5d6c63e21bb98a19ee7bf58042f9b3ba
+---
+ widget/gtk/WidgetStyleCache.cpp | 9 +-
+ widget/gtk/WidgetStyleCache.h | 15 +-
+ widget/gtk/gtk3drawing.cpp | 306 +++++++++++++++-------------------------
+ widget/gtk/nsLookAndFeel.cpp | 63 +++------
+ 4 files changed, 142 insertions(+), 251 deletions(-)
+
+diff --git widget/gtk/WidgetStyleCache.cpp widget/gtk/WidgetStyleCache.cpp
+index bf0c2d080c17..39b7893df3bd 100644
+--- widget/gtk/WidgetStyleCache.cpp
++++ widget/gtk/WidgetStyleCache.cpp
+@@ -1220,8 +1220,8 @@ ResetWidgetCache(void)
+ }
+
+ GtkStyleContext*
+-ClaimStyleContext(WidgetNodeType aNodeType, GtkTextDirection aDirection,
+- GtkStateFlags aStateFlags, StyleFlags aFlags)
++GetStyleContext(WidgetNodeType aNodeType, GtkTextDirection aDirection,
++ GtkStateFlags aStateFlags, StyleFlags aFlags)
+ {
+ GtkStyleContext* style;
+ if (gtk_check_version(3, 20, 0) != nullptr) {
+@@ -1276,8 +1276,3 @@ ClaimStyleContext(WidgetNodeType aNodeType, GtkTextDirection aDirection,
+ }
+ return style;
+ }
+-
+-void
+-ReleaseStyleContext(GtkStyleContext* aStyleContext)
+-{
+-}
+diff --git widget/gtk/WidgetStyleCache.h widget/gtk/WidgetStyleCache.h
+index 2cbb5f96076f..6cce492de2b6 100644
+--- widget/gtk/WidgetStyleCache.h
++++ widget/gtk/WidgetStyleCache.h
+@@ -33,14 +33,15 @@ CreateCSSNode(const char* aName,
+ GtkStyleContext* aParentStyle,
+ GType aType = G_TYPE_NONE);
+
+-// Callers must call ReleaseStyleContext() on the returned context.
++/*
++ * Returns a pointer to a style context for the specified node and state.
++ * The context is owned by WidgetStyleCache. Do not unref.
++ */
+ GtkStyleContext*
+-ClaimStyleContext(WidgetNodeType aNodeType,
+- GtkTextDirection aDirection = GTK_TEXT_DIR_NONE,
+- GtkStateFlags aStateFlags = GTK_STATE_FLAG_NORMAL,
+- StyleFlags aFlags = NO_STYLE_FLAGS);
+-void
+-ReleaseStyleContext(GtkStyleContext* style);
++GetStyleContext(WidgetNodeType aNodeType,
++ GtkTextDirection aDirection = GTK_TEXT_DIR_NONE,
++ GtkStateFlags aStateFlags = GTK_STATE_FLAG_NORMAL,
++ StyleFlags aFlags = NO_STYLE_FLAGS);
+
+ void
+ ResetWidgetCache(void);
+diff --git widget/gtk/gtk3drawing.cpp widget/gtk/gtk3drawing.cpp
+index 73bd1987fd39..4c562b380095 100644
+--- widget/gtk/gtk3drawing.cpp
++++ widget/gtk/gtk3drawing.cpp
+@@ -100,10 +100,9 @@ moz_gtk_refresh()
+ gtk_check_version(3, 20, 0) != nullptr)
+ {
+ // Deprecated for Gtk >= 3.20+
+- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_TAB_TOP);
++ GtkStyleContext *style = GetStyleContext(MOZ_GTK_TAB_TOP);
+ gtk_style_context_get_style(style,
+ "has-tab-gap", &notebook_has_tab_gap, NULL);
+- ReleaseStyleContext(style);
+ }
+ else {
+ notebook_has_tab_gap = true;
+@@ -149,31 +148,28 @@ moz_gtk_get_focus_outline_size(GtkStyleContext* style,
+ gint
+ moz_gtk_get_focus_outline_size(gint* focus_h_width, gint* focus_v_width)
+ {
+- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_ENTRY);
++ GtkStyleContext *style = GetStyleContext(MOZ_GTK_ENTRY);
+ moz_gtk_get_focus_outline_size(style, focus_h_width, focus_v_width);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+ gint
+ moz_gtk_menuitem_get_horizontal_padding(gint* horizontal_padding)
+ {
+- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_MENUITEM);
++ GtkStyleContext *style = GetStyleContext(MOZ_GTK_MENUITEM);
+ gtk_style_context_get_style(style,
+ "horizontal-padding", horizontal_padding,
+ nullptr);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+ gint
+ moz_gtk_checkmenuitem_get_horizontal_padding(gint* horizontal_padding)
+ {
+- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_CHECKMENUITEM);
++ GtkStyleContext *style = GetStyleContext(MOZ_GTK_CHECKMENUITEM);
+ gtk_style_context_get_style(style,
+ "horizontal-padding", horizontal_padding,
+ nullptr);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -183,11 +179,10 @@ moz_gtk_button_get_default_overflow(gint* border_top, gint* border_left,
+ {
+ GtkBorder* default_outside_border;
+
+- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
++ GtkStyleContext *style = GetStyleContext(MOZ_GTK_BUTTON);
+ gtk_style_context_get_style(style,
+ "default-outside-border", &default_outside_border,
+ NULL);
+- ReleaseStyleContext(style);
+
+ if (default_outside_border) {
+ *border_top = default_outside_border->top;
+@@ -207,11 +202,10 @@ moz_gtk_button_get_default_border(gint* border_top, gint* border_left,
+ {
+ GtkBorder* default_border;
+
+- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
++ GtkStyleContext *style = GetStyleContext(MOZ_GTK_BUTTON);
+ gtk_style_context_get_style(style,
+ "default-border", &default_border,
+ NULL);
+- ReleaseStyleContext(style);
+
+ if (default_border) {
+ *border_top = default_border->top;
+@@ -231,12 +225,11 @@ moz_gtk_splitter_get_metrics(gint orientation, gint* size)
+ {
+ GtkStyleContext *style;
+ if (orientation == GTK_ORIENTATION_HORIZONTAL) {
+- style = ClaimStyleContext(MOZ_GTK_SPLITTER_HORIZONTAL);
++ style = GetStyleContext(MOZ_GTK_SPLITTER_HORIZONTAL);
+ } else {
+- style = ClaimStyleContext(MOZ_GTK_SPLITTER_VERTICAL);
++ style = GetStyleContext(MOZ_GTK_SPLITTER_VERTICAL);
+ }
+ gtk_style_context_get_style(style, "handle_size", size, NULL);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -244,15 +237,13 @@ static gint
+ moz_gtk_window_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkTextDirection direction)
+ {
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW, direction);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_WINDOW, direction);
+
+ gtk_style_context_save(style);
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
+ gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+ gtk_style_context_restore(style);
+
+- ReleaseStyleContext(style);
+-
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -351,9 +342,8 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRectangle* rect,
+ if (inconsistent)
+ state_flags = static_cast<GtkStateFlags>(state_flags|GTK_STATE_FLAG_INCONSISTENT);
+
+- style = ClaimStyleContext(isradio ? MOZ_GTK_RADIOBUTTON :
+- MOZ_GTK_CHECKBUTTON,
+- direction, state_flags);
++ style = GetStyleContext(isradio ? MOZ_GTK_RADIOBUTTON : MOZ_GTK_CHECKBUTTON,
++ direction, state_flags);
+
+ if (gtk_check_version(3, 20, 0) == nullptr) {
+ gtk_render_background(style, cr, x, y, width, height);
+@@ -375,8 +365,6 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRectangle* rect,
+ }
+ }
+
+- ReleaseStyleContext(style);
+-
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -460,7 +448,7 @@ static void
+ moz_gtk_get_widget_min_size(WidgetNodeType aGtkWidgetType, int* width,
+ int* height)
+ {
+- GtkStyleContext* style = ClaimStyleContext(aGtkWidgetType);
++ GtkStyleContext* style = GetStyleContext(aGtkWidgetType);
+ GtkStateFlags state_flags = gtk_style_context_get_state(style);
+ gtk_style_context_get(style, state_flags,
+ "min-height", height,
+@@ -471,7 +459,6 @@ moz_gtk_get_widget_min_size(WidgetNodeType aGtkWidgetType, int* width,
+ gtk_style_context_get_border(style, state_flags, &border);
+ gtk_style_context_get_padding(style, state_flags, &padding);
+ gtk_style_context_get_margin(style, state_flags, &margin);
+- ReleaseStyleContext(style);
+
+ *width += border.left + border.right + margin.left + margin.right +
+ padding.left + padding.right;
+@@ -666,7 +653,7 @@ moz_gtk_scrollbar_trough_paint(WidgetNodeType widget,
+ MOZ_GTK_SCROLLBAR_THUMB_VERTICAL :
+ MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL;
+ MozGtkSize thumbSize = GetMinMarginBox(thumb);
+- style = ClaimStyleContext(widget, direction);
++ style = GetStyleContext(widget, direction);
+ MozGtkSize trackSize = GetMinContentBox(style);
+ trackSize.Include(thumbSize);
+ trackSize += GetMarginBorderPadding(style);
+@@ -681,11 +668,10 @@ moz_gtk_scrollbar_trough_paint(WidgetNodeType widget,
+ rect.height = trackSize.height;
+ }
+ } else {
+- style = ClaimStyleContext(widget, direction);
++ style = GetStyleContext(widget, direction);
+ }
+
+ moz_gtk_draw_styled_frame(style, cr, &rect, state->focused);
+- ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -696,18 +682,16 @@ moz_gtk_scrollbar_paint(WidgetNodeType widget,
+ GtkWidgetState* state,
+ GtkTextDirection direction)
+ {
+- GtkStyleContext* style = ClaimStyleContext(widget, direction);
++ GtkStyleContext* style = GetStyleContext(widget, direction);
+ moz_gtk_update_scrollbar_style(style, widget, direction);
+
+ moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
+
+- ReleaseStyleContext(style);
+- style = ClaimStyleContext((widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) ?
+- MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL :
+- MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL,
+- direction);
++ style = GetStyleContext((widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) ?
++ MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL :
++ MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL,
++ direction);
+ moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
+- ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -721,7 +705,7 @@ moz_gtk_scrollbar_thumb_paint(WidgetNodeType widget,
+ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+
+ GdkRectangle rect = *aRect;
+- GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags);
++ GtkStyleContext* style = GetStyleContext(widget, direction, state_flags);
+ InsetByMargin(&rect, style);
+
+ gtk_render_slider(style, cr,
+@@ -732,7 +716,6 @@ moz_gtk_scrollbar_thumb_paint(WidgetNodeType widget,
+ (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) ?
+ GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
+
+- ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -741,10 +724,9 @@ static gint
+ moz_gtk_spin_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkTextDirection direction)
+ {
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SPINBUTTON, direction);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_SPINBUTTON, direction);
+ gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+ gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -753,7 +735,7 @@ moz_gtk_spin_updown_paint(cairo_t *cr, GdkRectangle* rect,
+ gboolean isDown, GtkWidgetState* state,
+ GtkTextDirection direction)
+ {
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SPINBUTTON, direction,
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_SPINBUTTON, direction,
+ GetStateFlagsFromGtkWidgetState(state));
+
+ gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+@@ -772,7 +754,6 @@ moz_gtk_spin_updown_paint(cairo_t *cr, GdkRectangle* rect,
+ arrow_rect.x, arrow_rect.y,
+ arrow_rect.width);
+
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -793,7 +774,7 @@ moz_gtk_scale_paint(cairo_t *cr, GdkRectangle* rect,
+ WidgetNodeType widget = (flags == GTK_ORIENTATION_HORIZONTAL) ?
+ MOZ_GTK_SCALE_TROUGH_HORIZONTAL :
+ MOZ_GTK_SCALE_TROUGH_VERTICAL;
+- style = ClaimStyleContext(widget, direction, state_flags);
++ style = GetStyleContext(widget, direction, state_flags);
+ gtk_style_context_get_margin(style, state_flags, &margin);
+
+ // Clamp the dimension perpendicular to the direction that the slider crosses
+@@ -817,7 +798,6 @@ moz_gtk_scale_paint(cairo_t *cr, GdkRectangle* rect,
+ gtk_render_focus(style, cr,
+ rect->x, rect->y, rect->width, rect->height);
+
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -846,9 +826,8 @@ moz_gtk_scale_thumb_paint(cairo_t *cr, GdkRectangle* rect,
+ WidgetNodeType widget = (flags == GTK_ORIENTATION_HORIZONTAL) ?
+ MOZ_GTK_SCALE_THUMB_HORIZONTAL :
+ MOZ_GTK_SCALE_THUMB_VERTICAL;
+- style = ClaimStyleContext(widget, direction, state_flags);
++ style = GetStyleContext(widget, direction, state_flags);
+ gtk_render_slider(style, cr, x, y, thumb_width, thumb_height, flags);
+- ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -859,11 +838,10 @@ moz_gtk_gripper_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkTextDirection direction)
+ {
+ GtkStyleContext* style =
+- ClaimStyleContext(MOZ_GTK_GRIPPER, direction,
+- GetStateFlagsFromGtkWidgetState(state));
++ GetStyleContext(MOZ_GTK_GRIPPER, direction,
++ GetStateFlagsFromGtkWidgetState(state));
+ gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+ gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -872,12 +850,11 @@ moz_gtk_hpaned_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkWidgetState* state)
+ {
+ GtkStyleContext* style =
+- ClaimStyleContext(MOZ_GTK_SPLITTER_SEPARATOR_HORIZONTAL,
+- GTK_TEXT_DIR_LTR,
+- GetStateFlagsFromGtkWidgetState(state));
++ GetStyleContext(MOZ_GTK_SPLITTER_SEPARATOR_HORIZONTAL,
++ GTK_TEXT_DIR_LTR,
++ GetStateFlagsFromGtkWidgetState(state));
+ gtk_render_handle(style, cr,
+ rect->x, rect->y, rect->width, rect->height);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -886,12 +863,11 @@ moz_gtk_vpaned_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkWidgetState* state)
+ {
+ GtkStyleContext* style =
+- ClaimStyleContext(MOZ_GTK_SPLITTER_SEPARATOR_VERTICAL,
+- GTK_TEXT_DIR_LTR,
+- GetStateFlagsFromGtkWidgetState(state));
++ GetStyleContext(MOZ_GTK_SPLITTER_SEPARATOR_VERTICAL,
++ GTK_TEXT_DIR_LTR,
++ GetStateFlagsFromGtkWidgetState(state));
+ gtk_render_handle(style, cr,
+ rect->x, rect->y, rect->width, rect->height);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -939,26 +915,22 @@ moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* aRect,
+ GTK_STATE_FLAG_NORMAL;
+
+ GtkStyleContext* style_frame =
+- ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction, state_flags);
++ GetStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction, state_flags);
+ gtk_render_frame(style_frame, cr,
+ aRect->x, aRect->y, aRect->width, aRect->height);
+
+ GdkRectangle rect = *aRect;
+ InsetByBorderPadding(&rect, style_frame);
+
+- ReleaseStyleContext(style_frame);
+-
+ GtkStyleContext* style =
+- ClaimStyleContext(MOZ_GTK_TEXT_VIEW, direction, state_flags);
++ GetStyleContext(MOZ_GTK_TEXT_VIEW, direction, state_flags);
+ gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
+- ReleaseStyleContext(style);
+ // There is a separate "text" window, which usually provides the
+ // background behind the text. However, this is transparent in Ambiance
+ // for GTK 3.20, in which case the MOZ_GTK_TEXT_VIEW background is
+ // visible.
+- style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW_TEXT, direction, state_flags);
++ style = GetStyleContext(MOZ_GTK_TEXT_VIEW_TEXT, direction, state_flags);
+ gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
+- ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -978,23 +950,20 @@ moz_gtk_treeview_paint(cairo_t *cr, GdkRectangle* rect,
+ * area will be painted differently with other states */
+ state_flags = state->disabled ? GTK_STATE_FLAG_INSENSITIVE : GTK_STATE_FLAG_NORMAL;
+
+- style = ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction);
++ style = GetStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction);
+ gtk_style_context_get_border(style, state_flags, &border);
+ xthickness = border.left;
+ ythickness = border.top;
+- ReleaseStyleContext(style);
+
+- style_tree = ClaimStyleContext(MOZ_GTK_TREEVIEW_VIEW, direction);
++ style_tree = GetStyleContext(MOZ_GTK_TREEVIEW_VIEW, direction);
+ gtk_render_background(style_tree, cr,
+ rect->x + xthickness, rect->y + ythickness,
+ rect->width - 2 * xthickness,
+ rect->height - 2 * ythickness);
+- ReleaseStyleContext(style_tree);
+
+- style = ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction);
++ style = GetStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction);
+ gtk_render_frame(style, cr,
+ rect->x, rect->y, rect->width, rect->height);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -1022,8 +991,8 @@ moz_gtk_tree_header_sort_arrow_paint(cairo_t *cr, GdkRectangle* rect,
+ arrow_rect.height = 11;
+ arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2;
+ arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2;
+- style = ClaimStyleContext(MOZ_GTK_TREE_HEADER_SORTARROW, direction,
+- GetStateFlagsFromGtkWidgetState(state));
++ style = GetStyleContext(MOZ_GTK_TREE_HEADER_SORTARROW, direction,
++ GetStateFlagsFromGtkWidgetState(state));
+ switch (arrow_type) {
+ case GTK_ARROW_LEFT:
+ arrow_angle = ARROW_LEFT;
+@@ -1042,7 +1011,6 @@ moz_gtk_tree_header_sort_arrow_paint(cairo_t *cr, GdkRectangle* rect,
+ gtk_render_arrow(style, cr, arrow_angle,
+ arrow_rect.x, arrow_rect.y,
+ arrow_rect.width);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -1067,15 +1035,14 @@ moz_gtk_treeview_expander_paint(cairo_t *cr, GdkRectangle* rect,
+ else
+ state_flags = static_cast<GtkStateFlags>(state_flags&~(checkbox_check_state));
+
+- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_TREEVIEW_EXPANDER,
+- direction, state_flags);
++ GtkStyleContext *style = GetStyleContext(MOZ_GTK_TREEVIEW_EXPANDER,
++ direction, state_flags);
+ gtk_render_expander(style, cr,
+ rect->x,
+ rect->y,
+ rect->width,
+ rect->height);
+
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -1112,11 +1079,10 @@ moz_gtk_combo_box_paint(cairo_t *cr, GdkRectangle* rect,
+ calculate_arrow_rect(comboBoxArrow,
+ &arrow_rect, &real_arrow_rect, direction);
+
+- style = ClaimStyleContext(MOZ_GTK_COMBOBOX_ARROW);
++ style = GetStyleContext(MOZ_GTK_COMBOBOX_ARROW);
+ gtk_render_arrow(style, cr, ARROW_DOWN,
+ real_arrow_rect.x, real_arrow_rect.y,
+ real_arrow_rect.width);
+- ReleaseStyleContext(style);
+
+ /* If there is no separator in the theme, there's nothing left to do. */
+ GtkWidget* widget = GetWidget(MOZ_GTK_COMBOBOX_SEPARATOR);
+@@ -1187,11 +1153,10 @@ moz_gtk_arrow_paint(cairo_t *cr, GdkRectangle* rect,
+ calculate_arrow_rect(GetWidget(MOZ_GTK_BUTTON_ARROW), rect, &arrow_rect,
+ direction);
+ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_BUTTON_ARROW,
+- direction, state_flags);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_BUTTON_ARROW,
++ direction, state_flags);
+ gtk_render_arrow(style, cr, arrow_angle,
+ arrow_rect.x, arrow_rect.y, arrow_rect.width);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -1224,11 +1189,10 @@ moz_gtk_combo_box_entry_button_paint(cairo_t *cr, GdkRectangle* rect,
+ calculate_arrow_rect(GetWidget(MOZ_GTK_COMBOBOX_ENTRY_ARROW),
+ &arrow_rect, &real_arrow_rect, direction);
+
+- style = ClaimStyleContext(MOZ_GTK_COMBOBOX_ENTRY_ARROW);
++ style = GetStyleContext(MOZ_GTK_COMBOBOX_ENTRY_ARROW);
+ gtk_render_arrow(style, cr, ARROW_DOWN,
+ real_arrow_rect.x, real_arrow_rect.y,
+ real_arrow_rect.width);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -1239,15 +1203,14 @@ moz_gtk_container_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkTextDirection direction)
+ {
+ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+- GtkStyleContext* style = ClaimStyleContext(widget_type, direction,
+- state_flags);
++ GtkStyleContext* style = GetStyleContext(widget_type, direction,
++ state_flags);
+ /* this is for drawing a prelight box */
+ if (state_flags & GTK_STATE_FLAG_PRELIGHT) {
+ gtk_render_background(style, cr,
+ rect->x, rect->y, rect->width, rect->height);
+ }
+
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -1260,15 +1223,13 @@ moz_gtk_toggle_label_paint(cairo_t *cr, GdkRectangle* rect,
+ return MOZ_GTK_SUCCESS;
+
+ GtkStyleContext *style =
+- ClaimStyleContext(isradio ? MOZ_GTK_RADIOBUTTON_CONTAINER :
+- MOZ_GTK_CHECKBUTTON_CONTAINER,
+- direction,
+- GetStateFlagsFromGtkWidgetState(state));
++ GetStyleContext(isradio ? MOZ_GTK_RADIOBUTTON_CONTAINER :
++ MOZ_GTK_CHECKBUTTON_CONTAINER,
++ direction,
++ GetStateFlagsFromGtkWidgetState(state));
+ gtk_render_focus(style, cr,
+ rect->x, rect->y, rect->width, rect->height);
+
+- ReleaseStyleContext(style);
+-
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -1276,10 +1237,9 @@ static gint
+ moz_gtk_toolbar_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkTextDirection direction)
+ {
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLBAR, direction);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_TOOLBAR, direction);
+ gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+ gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -1297,14 +1257,13 @@ moz_gtk_toolbar_separator_paint(cairo_t *cr, GdkRectangle* rect,
+ const double start_fraction = 0.2;
+ const double end_fraction = 0.8;
+
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLBAR);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_TOOLBAR);
+ gtk_style_context_get_style(style,
+ "wide-separators", &wide_separators,
+ "separator-width", &separator_width,
+ NULL);
+- ReleaseStyleContext(style);
+
+- style = ClaimStyleContext(MOZ_GTK_TOOLBAR_SEPARATOR, direction);
++ style = GetStyleContext(MOZ_GTK_TOOLBAR_SEPARATOR, direction);
+ if (wide_separators) {
+ if (separator_width > rect->width)
+ separator_width = rect->width;
+@@ -1328,7 +1287,6 @@ moz_gtk_toolbar_separator_paint(cairo_t *cr, GdkRectangle* rect,
+ rect->x + (rect->width - paint_width) / 2,
+ rect->y + rect->height * end_fraction);
+ }
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -1345,11 +1303,10 @@ moz_gtk_tooltip_paint(cairo_t *cr, const GdkRectangle* aRect,
+ // We have to draw all elements with appropriate offset and right dimensions.
+
+ // Tooltip drawing
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLTIP, direction);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_TOOLTIP, direction);
+ GdkRectangle rect = *aRect;
+ gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
+ gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height);
+- ReleaseStyleContext(style);
+
+ // Horizontal Box drawing
+ //
+@@ -1359,7 +1316,7 @@ moz_gtk_tooltip_paint(cairo_t *cr, const GdkRectangle* aRect,
+ // 6px margin.
+ // For drawing Horizontal Box we have to inset drawing area by that 6px
+ // plus its CSS margin.
+- GtkStyleContext* boxStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX, direction);
++ GtkStyleContext* boxStyle = GetStyleContext(MOZ_GTK_TOOLTIP_BOX, direction);
+
+ rect.x += 6;
+ rect.y += 6;
+@@ -1372,12 +1329,10 @@ moz_gtk_tooltip_paint(cairo_t *cr, const GdkRectangle* aRect,
+
+ // Label drawing
+ InsetByBorderPadding(&rect, boxStyle);
+- ReleaseStyleContext(boxStyle);
+
+ GtkStyleContext* labelStyle =
+- ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL, direction);
++ GetStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL, direction);
+ moz_gtk_draw_styled_frame(labelStyle, cr, &rect, false);
+- ReleaseStyleContext(labelStyle);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -1388,8 +1343,8 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkTextDirection direction)
+ {
+ GtkStyleContext* style =
+- ClaimStyleContext(MOZ_GTK_RESIZER, GTK_TEXT_DIR_LTR,
+- GetStateFlagsFromGtkWidgetState(state));
++ GetStyleContext(MOZ_GTK_RESIZER, GTK_TEXT_DIR_LTR,
++ GetStateFlagsFromGtkWidgetState(state));
+
+ // Workaround unico not respecting the text direction for resizers.
+ // See bug 1174248.
+@@ -1403,7 +1358,6 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRectangle* rect,
+
+ gtk_render_handle(style, cr, rect->x, rect->y, rect->width, rect->height);
+ cairo_restore(cr);
+- ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -1412,9 +1366,8 @@ static gint
+ moz_gtk_frame_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkTextDirection direction)
+ {
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_FRAME, direction);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_FRAME, direction);
+ gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -1422,11 +1375,10 @@ static gint
+ moz_gtk_progressbar_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkTextDirection direction)
+ {
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_PROGRESS_TROUGH,
+- direction);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_PROGRESS_TROUGH,
++ direction);
+ gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+ gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+- ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -1437,7 +1389,7 @@ moz_gtk_progress_chunk_paint(cairo_t *cr, GdkRectangle* rect,
+ WidgetNodeType widget)
+ {
+ GtkStyleContext* style =
+- ClaimStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction);
++ GetStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction);
+
+ if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE ||
+ widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) {
+@@ -1481,7 +1433,6 @@ moz_gtk_progress_chunk_paint(cairo_t *cr, GdkRectangle* rect,
+ } else {
+ gtk_render_activity(style, cr, rect->x, rect->y, rect->width, rect->height);
+ }
+- ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -1503,9 +1454,8 @@ moz_gtk_get_tab_thickness(GtkStyleContext *style)
+ gint
+ moz_gtk_get_tab_thickness(WidgetNodeType aNodeType)
+ {
+- GtkStyleContext *style = ClaimStyleContext(aNodeType);
++ GtkStyleContext *style = GetStyleContext(aNodeType);
+ int thickness = moz_gtk_get_tab_thickness(style);
+- ReleaseStyleContext(style);
+ return thickness;
+ }
+
+@@ -1528,8 +1478,8 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectangle* rect,
+ int initial_gap = 0;
+ bool isBottomTab = (widget == MOZ_GTK_TAB_BOTTOM);
+
+- style = ClaimStyleContext(widget, direction,
+- GetStateFlagsFromGtkTabFlags(flags));
++ style = GetStyleContext(widget, direction,
++ GetStateFlagsFromGtkTabFlags(flags));
+ tabRect = *rect;
+
+ if (flags & MOZ_GTK_TAB_FIRST) {
+@@ -1606,7 +1556,7 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectangle* rect,
+ }
+
+ GtkStyleContext* panelStyle =
+- ClaimStyleContext(MOZ_GTK_TABPANELS, direction);
++ GetStyleContext(MOZ_GTK_TABPANELS, direction);
+
+ if (isBottomTab) {
+ /* Draw the tab on bottom */
+@@ -1681,7 +1631,6 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectangle* rect,
+ gtk_render_focus(style, cr,
+ focusRect.x, focusRect.y, focusRect.width, focusRect.height);
+ }
+- ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -1691,7 +1640,7 @@ static gint
+ moz_gtk_tabpanels_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkTextDirection direction)
+ {
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TABPANELS, direction);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_TABPANELS, direction);
+ gtk_render_background(style, cr, rect->x, rect->y,
+ rect->width, rect->height);
+ /*
+@@ -1728,7 +1677,6 @@ moz_gtk_tabpanels_paint(cairo_t *cr, GdkRectangle* rect,
+ GTK_POS_TOP, 0, 1);
+ cairo_restore(cr);
+
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -1763,11 +1711,10 @@ moz_gtk_tab_scroll_arrow_paint(cairo_t *cr, GdkRectangle* rect,
+ break;
+ }
+ if (arrow_type != GTK_ARROW_NONE) {
+- style = ClaimStyleContext(MOZ_GTK_TAB_SCROLLARROW, direction,
+- GetStateFlagsFromGtkWidgetState(state));
++ style = GetStyleContext(MOZ_GTK_TAB_SCROLLARROW, direction,
++ GetStateFlagsFromGtkWidgetState(state));
+ gtk_render_arrow(style, cr, arrow_angle,
+ x, y, arrow_size);
+- ReleaseStyleContext(style);
+ }
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -1833,7 +1780,7 @@ moz_gtk_menu_separator_paint(cairo_t *cr, GdkRectangle* rect,
+ gint x, y, w;
+ GtkBorder padding;
+
+- style = ClaimStyleContext(MOZ_GTK_MENUSEPARATOR, direction);
++ style = GetStyleContext(MOZ_GTK_MENUSEPARATOR, direction);
+ gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
+
+ x = rect->x;
+@@ -1863,7 +1810,6 @@ moz_gtk_menu_separator_paint(cairo_t *cr, GdkRectangle* rect,
+ }
+
+ gtk_style_context_restore(style);
+- ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -1883,7 +1829,7 @@ moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
+ !(state_flags & GTK_STATE_FLAG_PRELIGHT)))
+ return MOZ_GTK_SUCCESS;
+
+- GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags);
++ GtkStyleContext* style = GetStyleContext(widget, direction, state_flags);
+
+ if (minorVersion < 6) {
+ // GTK+ 3.4 saves the style context and adds the menubar class to
+@@ -1906,7 +1852,6 @@ moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
+ if (minorVersion < 6) {
+ gtk_style_context_restore(style);
+ }
+- ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -1917,12 +1862,11 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkTextDirection direction)
+ {
+ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_MENUITEM,
+- direction, state_flags);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_MENUITEM,
++ direction, state_flags);
+ gtk_render_arrow(style, cr,
+ (direction == GTK_TEXT_DIR_LTR) ? ARROW_RIGHT : ARROW_LEFT,
+ rect->x, rect->y, rect->width);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -1947,7 +1891,7 @@ moz_gtk_check_menu_item_paint(WidgetNodeType widgetType,
+
+ bool pre_3_20 = gtk_get_minor_version() < 20;
+ gint offset;
+- style = ClaimStyleContext(widgetType, direction);
++ style = GetStyleContext(widgetType, direction);
+ gtk_style_context_get_style(style,
+ "indicator-size", &indicator_size,
+ "horizontal-padding", &horizontal_padding,
+@@ -1962,12 +1906,11 @@ moz_gtk_check_menu_item_paint(WidgetNodeType widgetType,
+ InsetByBorderPadding(&r, style);
+ offset = r.x;
+ }
+- ReleaseStyleContext(style);
+
+ bool isRadio = (widgetType == MOZ_GTK_RADIOMENUITEM);
+ WidgetNodeType indicatorType = isRadio ? MOZ_GTK_RADIOMENUITEM_INDICATOR
+ : MOZ_GTK_CHECKMENUITEM_INDICATOR;
+- style = ClaimStyleContext(indicatorType, direction, state_flags);
++ style = GetStyleContext(indicatorType, direction, state_flags);
+
+ if (direction == GTK_TEXT_DIR_RTL) {
+ x = rect->width - indicator_size - offset;
+@@ -1987,7 +1930,6 @@ moz_gtk_check_menu_item_paint(WidgetNodeType widgetType,
+ } else {
+ gtk_render_check(style, cr, x, y, indicator_size, indicator_size);
+ }
+- ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -1997,12 +1939,11 @@ moz_gtk_info_bar_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkWidgetState* state)
+ {
+ GtkStyleContext *style =
+- ClaimStyleContext(MOZ_GTK_INFO_BAR, GTK_TEXT_DIR_LTR,
+- GetStateFlagsFromGtkWidgetState(state));
++ GetStyleContext(MOZ_GTK_INFO_BAR, GTK_TEXT_DIR_LTR,
++ GetStateFlagsFromGtkWidgetState(state));
+ gtk_render_background(style, cr, rect->x, rect->y, rect->width,
+ rect->height);
+ gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+- ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -2087,7 +2028,7 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
+ case MOZ_GTK_BUTTON:
+ case MOZ_GTK_TOOLBAR_BUTTON:
+ {
+- style = ClaimStyleContext(MOZ_GTK_BUTTON);
++ style = GetStyleContext(MOZ_GTK_BUTTON);
+
+ *left = *top = *right = *bottom =
+ gtk_container_get_border_width(GTK_CONTAINER(GetWidget(MOZ_GTK_BUTTON)));
+@@ -2104,12 +2045,11 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
+
+ moz_gtk_add_style_border(style, left, top, right, bottom);
+
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+ case MOZ_GTK_ENTRY:
+ {
+- style = ClaimStyleContext(MOZ_GTK_ENTRY);
++ style = GetStyleContext(MOZ_GTK_ENTRY);
+
+ // XXX: Subtract 1 pixel from the padding to account for the default
+ // padding in forms.css. See bug 1187385.
+@@ -2117,15 +2057,13 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
+ moz_gtk_add_style_padding(style, left, top, right, bottom);
+ moz_gtk_add_style_border(style, left, top, right, bottom);
+
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+ case MOZ_GTK_TEXT_VIEW:
+ case MOZ_GTK_TREEVIEW:
+ {
+- style = ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW);
++ style = GetStyleContext(MOZ_GTK_SCROLLED_WINDOW);
+ moz_gtk_add_style_border(style, left, top, right, bottom);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+ case MOZ_GTK_TREE_HEADER_CELL:
+@@ -2139,10 +2077,9 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
+ gtk_container_get_border_width(GTK_CONTAINER(
+ GetWidget(MOZ_GTK_TREE_HEADER_CELL)));
+
+- style = ClaimStyleContext(MOZ_GTK_TREE_HEADER_CELL);
++ style = GetStyleContext(MOZ_GTK_TREE_HEADER_CELL);
+ moz_gtk_add_style_border(style, left, top, right, bottom);
+ moz_gtk_add_style_padding(style, left, top, right, bottom);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+ case MOZ_GTK_TREE_HEADER_SORTARROW:
+@@ -2167,10 +2104,9 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
+ *left = *top = *right = *bottom =
+ gtk_container_get_border_width(GTK_CONTAINER(
+ GetWidget(MOZ_GTK_COMBOBOX_BUTTON)));
+- style = ClaimStyleContext(MOZ_GTK_COMBOBOX_BUTTON);
++ style = GetStyleContext(MOZ_GTK_COMBOBOX_BUTTON);
+ moz_gtk_add_style_padding(style, left, top, right, bottom);
+ moz_gtk_add_style_border(style, left, top, right, bottom);
+- ReleaseStyleContext(style);
+
+ /* If there is no separator, don't try to count its width. */
+ separator_width = 0;
+@@ -2241,7 +2177,7 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
+ // Bug 1274143 for MOZ_GTK_MENUBARITEM
+ WidgetNodeType type =
+ widget == MOZ_GTK_MENUBARITEM ? MOZ_GTK_MENUITEM : widget;
+- style = ClaimStyleContext(type);
++ style = GetStyleContext(type);
+
+ if (gtk_get_minor_version() < 20) {
+ moz_gtk_add_style_padding(style, left, top, right, bottom);
+@@ -2249,7 +2185,6 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
+ moz_gtk_add_margin_border_padding(style,
+ left, top, right, bottom);
+ }
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+ case MOZ_GTK_INFO_BAR:
+@@ -2265,15 +2200,13 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
+ // We also need to add margin/padding/borders from Tooltip content.
+ // Tooltip contains horizontal box, where icon and label is put.
+ // We ignore icon as long as we don't have support for it.
+- GtkStyleContext* boxStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX);
++ GtkStyleContext* boxStyle = GetStyleContext(MOZ_GTK_TOOLTIP_BOX);
+ moz_gtk_add_margin_border_padding(boxStyle,
+ left, top, right, bottom);
+- ReleaseStyleContext(boxStyle);
+
+- GtkStyleContext* labelStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL);
++ GtkStyleContext* labelStyle = GetStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL);
+ moz_gtk_add_margin_border_padding(labelStyle,
+ left, top, right, bottom);
+- ReleaseStyleContext(labelStyle);
+
+ return MOZ_GTK_SUCCESS;
+ }
+@@ -2324,7 +2257,7 @@ moz_gtk_get_tab_border(gint* left, gint* top, gint* right, gint* bottom,
+ GtkTextDirection direction, GtkTabFlags flags,
+ WidgetNodeType widget)
+ {
+- GtkStyleContext* style = ClaimStyleContext(widget, direction,
++ GtkStyleContext* style = GetStyleContext(widget, direction,
+ GetStateFlagsFromGtkTabFlags(flags));
+
+ *left = *top = *right = *bottom = 0;
+@@ -2354,15 +2287,13 @@ moz_gtk_get_tab_border(gint* left, gint* top, gint* right, gint* bottom,
+ *right += margin.right;
+
+ if (flags & MOZ_GTK_TAB_FIRST) {
+- ReleaseStyleContext(style);
+- style = ClaimStyleContext(MOZ_GTK_NOTEBOOK_HEADER, direction);
++ style = GetStyleContext(MOZ_GTK_NOTEBOOK_HEADER, direction);
+ gtk_style_context_get_margin(style, GTK_STATE_FLAG_NORMAL, &margin);
+ *left += margin.left;
+ *right += margin.right;
+ }
+ }
+
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -2389,11 +2320,10 @@ moz_gtk_get_tab_scroll_arrow_size(gint* width, gint* height)
+ {
+ gint arrow_size;
+
+- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_TABPANELS);
++ GtkStyleContext *style = GetStyleContext(MOZ_GTK_TABPANELS);
+ gtk_style_context_get_style(style,
+ "scroll-arrow-hlength", &arrow_size,
+ NULL);
+- ReleaseStyleContext(style);
+
+ *height = *width = arrow_size;
+
+@@ -2426,7 +2356,7 @@ moz_gtk_get_toolbar_separator_width(gint* size)
+ gint separator_width;
+ GtkBorder border;
+
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLBAR);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_TOOLBAR);
+ gtk_style_context_get_style(style,
+ "space-size", size,
+ "wide-separators", &wide_separators,
+@@ -2435,27 +2365,24 @@ moz_gtk_get_toolbar_separator_width(gint* size)
+ /* Just in case... */
+ gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
+ *size = MAX(*size, (wide_separators ? separator_width : border.left));
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+ gint
+ moz_gtk_get_expander_size(gint* size)
+ {
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_EXPANDER);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_EXPANDER);
+ gtk_style_context_get_style(style,
+ "expander-size", size,
+ NULL);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+ gint
+ moz_gtk_get_treeview_expander_size(gint* size)
+ {
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TREEVIEW);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_TREEVIEW);
+ gtk_style_context_get_style(style, "expander-size", size, NULL);
+- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+ }
+
+@@ -2466,7 +2393,7 @@ moz_gtk_get_menu_separator_height(gint *size)
+ gboolean wide_separators;
+ gint separator_height;
+ GtkBorder padding;
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_MENUSEPARATOR);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_MENUSEPARATOR);
+ gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
+
+ gtk_style_context_save(style);
+@@ -2478,7 +2405,6 @@ moz_gtk_get_menu_separator_height(gint *size)
+ NULL);
+
+ gtk_style_context_restore(style);
+- ReleaseStyleContext(style);
+
+ *size = padding.top + padding.bottom;
+ *size += (wide_separators) ? separator_height : 1;
+@@ -2489,7 +2415,7 @@ moz_gtk_get_menu_separator_height(gint *size)
+ void
+ moz_gtk_get_entry_min_height(gint* height)
+ {
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_ENTRY);
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_ENTRY);
+ if (!gtk_check_version(3, 20, 0)) {
+ gtk_style_context_get(style, gtk_style_context_get_state(style),
+ "min-height", height,
+@@ -2504,7 +2430,6 @@ moz_gtk_get_entry_min_height(gint* height)
+ gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
+
+ *height += (border.top + border.bottom + padding.top + padding.bottom);
+- ReleaseStyleContext(style);
+ }
+
+ void
+@@ -2519,7 +2444,7 @@ moz_gtk_get_scale_metrics(GtkOrientation orient, gint* scale_width,
+ gint thumb_length, thumb_height, trough_border;
+ moz_gtk_get_scalethumb_metrics(orient, &thumb_length, &thumb_height);
+
+- GtkStyleContext* style = ClaimStyleContext(widget);
++ GtkStyleContext* style = GetStyleContext(widget);
+ gtk_style_context_get_style(style, "trough-border", &trough_border, NULL);
+
+ if (orient == GTK_ORIENTATION_HORIZONTAL) {
+@@ -2529,7 +2454,6 @@ moz_gtk_get_scale_metrics(GtkOrientation orient, gint* scale_width,
+ *scale_width = thumb_height + trough_border * 2;
+ *scale_height = thumb_length + trough_border * 2;
+ }
+- ReleaseStyleContext(style);
+ } else {
+ WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ?
+ MOZ_GTK_SCALE_TROUGH_HORIZONTAL :
+@@ -2546,17 +2470,16 @@ moz_gtk_get_scalethumb_metrics(GtkOrientation orient, gint* thumb_length, gint*
+ WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ?
+ MOZ_GTK_SCALE_HORIZONTAL:
+ MOZ_GTK_SCALE_VERTICAL;
+- GtkStyleContext* style = ClaimStyleContext(widget);
++ GtkStyleContext* style = GetStyleContext(widget);
+ gtk_style_context_get_style(style,
+ "slider_length", thumb_length,
+ "slider_width", thumb_height,
+ NULL);
+- ReleaseStyleContext(style);
+ } else {
+ WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ?
+ MOZ_GTK_SCALE_THUMB_HORIZONTAL:
+ MOZ_GTK_SCALE_THUMB_VERTICAL;
+- GtkStyleContext* style = ClaimStyleContext(widget);
++ GtkStyleContext* style = GetStyleContext(widget);
+
+ gint min_width, min_height;
+ GtkStateFlags state = gtk_style_context_get_state(style);
+@@ -2578,8 +2501,6 @@ moz_gtk_get_scalethumb_metrics(GtkOrientation orient, gint* thumb_length, gint*
+
+ *thumb_length = min_width;
+ *thumb_height = min_height;
+-
+- ReleaseStyleContext(style);
+ }
+
+ return MOZ_GTK_SUCCESS;
+@@ -2606,7 +2527,7 @@ GetScrollbarMetrics(GtkOrientation aOrientation)
+ MOZ_GTK_SCROLLBAR_HORIZONTAL : MOZ_GTK_SCROLLBAR_VERTICAL;
+
+ gboolean backward, forward, secondary_backward, secondary_forward;
+- GtkStyleContext* style = ClaimStyleContext(scrollbar);
++ GtkStyleContext* style = GetStyleContext(scrollbar);
+ gtk_style_context_get_style(style,
+ "has-backward-stepper", &backward,
+ "has-forward-stepper", &forward,
+@@ -2626,7 +2547,6 @@ GetScrollbarMetrics(GtkOrientation aOrientation)
+ "stepper-size", &stepper_size,
+ "min-slider-length", &min_slider_size,
+ nullptr);
+- ReleaseStyleContext(style);
+
+ metrics->size.thumb =
+ SizeFromLengthAndBreadth(aOrientation, min_slider_size, slider_width);
+@@ -2663,7 +2583,6 @@ GetScrollbarMetrics(GtkOrientation aOrientation)
+ // GTK version > 3.20
+ // scrollbar
+ metrics->border.scrollbar = GetMarginBorderPadding(style);
+- ReleaseStyleContext(style);
+
+ WidgetNodeType contents, track, thumb;
+ if (aOrientation == GTK_ORIENTATION_HORIZONTAL) {
+@@ -2678,10 +2597,9 @@ GetScrollbarMetrics(GtkOrientation aOrientation)
+ // thumb
+ metrics->size.thumb = GetMinMarginBox(thumb);
+ // track
+- style = ClaimStyleContext(track);
++ style = GetStyleContext(track);
+ metrics->border.track = GetMarginBorderPadding(style);
+ MozGtkSize trackMinSize = GetMinContentBox(style) + metrics->border.track;
+- ReleaseStyleContext(style);
+ MozGtkSize trackSizeForThumb = metrics->size.thumb + metrics->border.track;
+ // button
+ if (hasButtons) {
+@@ -2719,9 +2637,8 @@ GetScrollbarMetrics(GtkOrientation aOrientation)
+ }
+ }
+
+- style = ClaimStyleContext(contents);
++ style = GetStyleContext(contents);
+ GtkBorder contentsBorder = GetMarginBorderPadding(style);
+- ReleaseStyleContext(style);
+
+ metrics->size.scrollbar =
+ trackSizeForThumb + contentsBorder + metrics->border.scrollbar;
+@@ -2771,10 +2688,9 @@ moz_gtk_widget_paint(WidgetNodeType widget, cairo_t *cr,
+ case MOZ_GTK_SCROLLBAR_VERTICAL:
+ if (flags & MOZ_GTK_TRACK_OPAQUE) {
+ GtkStyleContext* style =
+- ClaimStyleContext(MOZ_GTK_WINDOW, direction);
++ GetStyleContext(MOZ_GTK_WINDOW, direction);
+ gtk_render_background(style, cr,
+ rect->x, rect->y, rect->width, rect->height);
+- ReleaseStyleContext(style);
+ }
+ if (gtk_check_version(3,20,0) == nullptr) {
+ return moz_gtk_scrollbar_paint(widget, cr, rect, state, direction);
+@@ -2818,10 +2734,10 @@ moz_gtk_widget_paint(WidgetNodeType widget, cairo_t *cr,
+ break;
+ case MOZ_GTK_SPINBUTTON_ENTRY:
+ {
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SPINBUTTON_ENTRY,
+- direction, GetStateFlagsFromGtkWidgetState(state));
++ GtkStyleContext* style =
++ GetStyleContext(MOZ_GTK_SPINBUTTON_ENTRY, direction,
++ GetStateFlagsFromGtkWidgetState(state));
+ gint ret = moz_gtk_entry_paint(cr, rect, state, style);
+- ReleaseStyleContext(style);
+ return ret;
+ }
+ break;
+@@ -2849,10 +2765,10 @@ moz_gtk_widget_paint(WidgetNodeType widget, cairo_t *cr,
+ break;
+ case MOZ_GTK_ENTRY:
+ {
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_ENTRY,
+- direction, GetStateFlagsFromGtkWidgetState(state));
++ GtkStyleContext* style =
++ GetStyleContext(MOZ_GTK_ENTRY, direction,
++ GetStateFlagsFromGtkWidgetState(state));
+ gint ret = moz_gtk_entry_paint(cr, rect, state, style);
+- ReleaseStyleContext(style);
+ return ret;
+ }
+ case MOZ_GTK_TEXT_VIEW:
+@@ -2867,10 +2783,10 @@ moz_gtk_widget_paint(WidgetNodeType widget, cairo_t *cr,
+ break;
+ case MOZ_GTK_DROPDOWN_ENTRY:
+ {
+- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA,
+- direction, GetStateFlagsFromGtkWidgetState(state));
++ GtkStyleContext* style =
++ GetStyleContext(MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA, direction,
++ GetStateFlagsFromGtkWidgetState(state));
+ gint ret = moz_gtk_entry_paint(cr, rect, state, style);
+- ReleaseStyleContext(style);
+ return ret;
+ }
+ break;
+diff --git widget/gtk/nsLookAndFeel.cpp widget/gtk/nsLookAndFeel.cpp
+index f4c35d82200a..9a2684412ee8 100644
+--- widget/gtk/nsLookAndFeel.cpp
++++ widget/gtk/nsLookAndFeel.cpp
+@@ -300,21 +300,19 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
+ // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
+ case eColorID_activeborder: {
+ // active window border
+- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW);
++ GtkStyleContext *style = GetStyleContext(MOZ_GTK_WINDOW);
+ gtk_style_context_get_border_color(style,
+ GTK_STATE_FLAG_NORMAL, &gdk_color);
+ aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+- ReleaseStyleContext(style);
+ break;
+ }
+ case eColorID_inactiveborder: {
+ // inactive window border
+- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW);
++ GtkStyleContext *style = GetStyleContext(MOZ_GTK_WINDOW);
+ gtk_style_context_get_border_color(style,
+ GTK_STATE_FLAG_INSENSITIVE,
+ &gdk_color);
+ aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+- ReleaseStyleContext(style);
+ break;
+ }
+ case eColorID_graytext: // disabled text in windows, menus, etc.
+@@ -323,12 +321,11 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
+ break;
+ case eColorID_inactivecaption: {
+ // inactive window caption
+- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW);
++ GtkStyleContext *style = GetStyleContext(MOZ_GTK_WINDOW);
+ gtk_style_context_get_background_color(style,
+ GTK_STATE_FLAG_INSENSITIVE,
+ &gdk_color);
+ aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+- ReleaseStyleContext(style);
+ break;
+ }
+ case eColorID_infobackground:
+@@ -394,20 +391,18 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
+ break;
+ case eColorID__moz_buttondefault: {
+ // default button border color
+- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
++ GtkStyleContext *style = GetStyleContext(MOZ_GTK_BUTTON);
+ gtk_style_context_get_border_color(style,
+ GTK_STATE_FLAG_NORMAL, &gdk_color);
+ aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+- ReleaseStyleContext(style);
+ break;
+ }
+ case eColorID__moz_buttonhoverface: {
+- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
++ GtkStyleContext *style = GetStyleContext(MOZ_GTK_BUTTON);
+ gtk_style_context_get_background_color(style,
+ GTK_STATE_FLAG_PRELIGHT,
+ &gdk_color);
+ aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+- ReleaseStyleContext(style);
+ break;
+ }
+ case eColorID__moz_buttonhovertext:
+@@ -858,38 +853,33 @@ nsLookAndFeel::EnsureInit()
+ g_object_ref_sink(labelWidget);
+
+ // Scrollbar colors
+- style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL);
++ style = GetStyleContext(MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL);
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
+ sMozScrollbar = GDK_RGBA_TO_NS_RGBA(color);
+- ReleaseStyleContext(style);
+
+ // Window colors
+- style = ClaimStyleContext(MOZ_GTK_WINDOW);
++ style = GetStyleContext(MOZ_GTK_WINDOW);
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
+ sMozWindowBackground = GDK_RGBA_TO_NS_RGBA(color);
+ gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
+ sMozWindowText = GDK_RGBA_TO_NS_RGBA(color);
+- ReleaseStyleContext(style);
+- style = ClaimStyleContext(MOZ_GTK_WINDOW_CONTAINER);
++ style = GetStyleContext(MOZ_GTK_WINDOW_CONTAINER);
+ {
+ GtkStyleContext* labelStyle = CreateStyleForWidget(labelWidget, style);
+ GetSystemFontInfo(labelStyle, &mDefaultFontName, &mDefaultFontStyle);
+ g_object_unref(labelStyle);
+ }
+- ReleaseStyleContext(style);
+
+ // tooltip foreground and background
+- style = ClaimStyleContext(MOZ_GTK_TOOLTIP);
++ style = GetStyleContext(MOZ_GTK_TOOLTIP);
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
+ sInfoBackground = GDK_RGBA_TO_NS_RGBA(color);
+- ReleaseStyleContext(style);
+
+- style = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL);
++ style = GetStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL);
+ gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
+ sInfoText = GDK_RGBA_TO_NS_RGBA(color);
+- ReleaseStyleContext(style);
+
+- style = ClaimStyleContext(MOZ_GTK_MENUITEM);
++ style = GetStyleContext(MOZ_GTK_MENUITEM);
+ {
+ GtkStyleContext* accelStyle =
+ CreateStyleForWidget(gtk_accel_label_new("M"), style);
+@@ -902,19 +892,16 @@ nsLookAndFeel::EnsureInit()
+ sMenuTextInactive = GDK_RGBA_TO_NS_RGBA(color);
+ g_object_unref(accelStyle);
+ }
+- ReleaseStyleContext(style);
+
+- style = ClaimStyleContext(MOZ_GTK_MENUPOPUP);
++ style = GetStyleContext(MOZ_GTK_MENUPOPUP);
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
+ sMenuBackground = GDK_RGBA_TO_NS_RGBA(color);
+- ReleaseStyleContext(style);
+
+- style = ClaimStyleContext(MOZ_GTK_MENUITEM);
++ style = GetStyleContext(MOZ_GTK_MENUITEM);
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
+ sMenuHover = GDK_RGBA_TO_NS_RGBA(color);
+ gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
+ sMenuHoverText = GDK_RGBA_TO_NS_RGBA(color);
+- ReleaseStyleContext(style);
+
+ GtkWidget *parent = gtk_fixed_new();
+ GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
+@@ -937,12 +924,11 @@ nsLookAndFeel::EnsureInit()
+ GdkRGBA bgColor;
+ // If the text window background is translucent, then the background of
+ // the textview root node is visible.
+- style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW);
++ style = GetStyleContext(MOZ_GTK_TEXT_VIEW);
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
+ &bgColor);
+- ReleaseStyleContext(style);
+
+- style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW_TEXT);
++ style = GetStyleContext(MOZ_GTK_TEXT_VIEW_TEXT);
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
+ &color);
+ ApplyColorOver(color, &bgColor);
+@@ -959,10 +945,9 @@ nsLookAndFeel::EnsureInit()
+ static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED),
+ &color);
+ sTextSelectedText = GDK_RGBA_TO_NS_RGBA(color);
+- ReleaseStyleContext(style);
+
+ // Button text color
+- style = ClaimStyleContext(MOZ_GTK_BUTTON);
++ style = GetStyleContext(MOZ_GTK_BUTTON);
+ {
+ GtkStyleContext* labelStyle = CreateStyleForWidget(labelWidget, style);
+
+@@ -974,21 +959,18 @@ nsLookAndFeel::EnsureInit()
+ sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color);
+ g_object_unref(labelStyle);
+ }
+- ReleaseStyleContext(style);
+
+ // Combobox text color
+- style = ClaimStyleContext(MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA);
++ style = GetStyleContext(MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA);
+ gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
+ sComboBoxText = GDK_RGBA_TO_NS_RGBA(color);
+- ReleaseStyleContext(style);
+
+ // Menubar text and hover text colors
+- style = ClaimStyleContext(MOZ_GTK_MENUBARITEM);
++ style = GetStyleContext(MOZ_GTK_MENUBARITEM);
+ gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
+ sMenuBarText = GDK_RGBA_TO_NS_RGBA(color);
+ gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
+ sMenuBarHoverText = GDK_RGBA_TO_NS_RGBA(color);
+- ReleaseStyleContext(style);
+
+ // GTK's guide to fancy odd row background colors:
+ // 1) Check if a theme explicitly defines an odd row color
+@@ -996,7 +978,7 @@ nsLookAndFeel::EnsureInit()
+ // slightly by a hardcoded value (gtkstyle.c)
+ // 3) If neither are defined, take the base background color and
+ // darken that by a hardcoded value
+- style = ClaimStyleContext(MOZ_GTK_TREEVIEW);
++ style = GetStyleContext(MOZ_GTK_TREEVIEW);
+
+ // Get odd row background color
+ gtk_style_context_save(style);
+@@ -1004,20 +986,17 @@ nsLookAndFeel::EnsureInit()
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
+ sOddCellBackground = GDK_RGBA_TO_NS_RGBA(color);
+ gtk_style_context_restore(style);
+- ReleaseStyleContext(style);
+
+ // GtkFrame has a "border" subnode on which Adwaita draws the border.
+ // Some themes do not draw on this node but draw a border on the widget
+ // root node, so check the root node if no border is found on the border
+ // node.
+- style = ClaimStyleContext(MOZ_GTK_FRAME_BORDER);
++ style = GetStyleContext(MOZ_GTK_FRAME_BORDER);
+ bool themeUsesColors =
+ GetBorderColors(style, &sFrameOuterLightBorder, &sFrameInnerDarkBorder);
+- ReleaseStyleContext(style);
+ if (!themeUsesColors) {
+- style = ClaimStyleContext(MOZ_GTK_FRAME);
++ style = GetStyleContext(MOZ_GTK_FRAME);
+ GetBorderColors(style, &sFrameOuterLightBorder, &sFrameInnerDarkBorder);
+- ReleaseStyleContext(style);
+ }
+
+ // GtkInfoBar
diff --git a/www/waterfox/files/patch-bug1398539 b/www/waterfox/files/patch-bug1398539
new file mode 100644
index 000000000000..1ae235da8b41
--- /dev/null
+++ b/www/waterfox/files/patch-bug1398539
@@ -0,0 +1,159 @@
+commit 8b33a0a29e7e
+Author: Lee Bousfield <ljbousfield@gmail.com>
+Date: Wed Sep 13 18:28:51 2017 -0600
+
+ Bug 1398539: Inhibit screensaver with XScreenSaverSuspend r=karlt
+
+ MozReview-Commit-ID: LhhpaDaPdaO
+
+ --HG--
+ extra : rebase_source : 6d53031ea8669b15cdf6fad4c55c58624bd54c38
+---
+ widget/gtk/WakeLockListener.cpp | 91 ++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 90 insertions(+), 1 deletion(-)
+
+diff --git widget/gtk/WakeLockListener.cpp widget/gtk/WakeLockListener.cpp
+index 3c6d7fb186a3..93d2c5a16208 100644
+--- widget/gtk/WakeLockListener.cpp
++++ widget/gtk/WakeLockListener.cpp
+@@ -15,6 +15,10 @@
+ #include "mozilla/ipc/DBusMessageRefPtr.h"
+ #include "mozilla/ipc/DBusPendingCallRefPtr.h"
+
++#if defined(MOZ_X11)
++#include "prlink.h"
++#endif
++
+ #define FREEDESKTOP_SCREENSAVER_TARGET "org.freedesktop.ScreenSaver"
+ #define FREEDESKTOP_SCREENSAVER_OBJECT "/ScreenSaver"
+ #define FREEDESKTOP_SCREENSAVER_INTERFACE "org.freedesktop.ScreenSaver"
+@@ -32,6 +36,9 @@ StaticRefPtr<WakeLockListener> WakeLockListener::sSingleton;
+ enum DesktopEnvironment {
+ FreeDesktop,
+ GNOME,
++#if defined(MOZ_X11)
++ XScreenSaver,
++#endif
+ Unsupported,
+ };
+
+@@ -59,6 +66,11 @@ private:
+ bool SendGNOMEInhibitMessage();
+ bool SendMessage(DBusMessage* aMessage);
+
++#if defined(MOZ_X11)
++ static bool CheckXScreenSaverSupport();
++ static bool InhibitXScreenSaver(bool inhibit);
++#endif
++
+ static void ReceiveInhibitReply(DBusPendingCall* aPending, void* aUserData);
+ void InhibitFailed();
+ void InhibitSucceeded(uint32_t aInhibitRequest);
+@@ -143,6 +155,71 @@ WakeLockTopic::SendGNOMEInhibitMessage()
+ }
+
+
++#if defined(MOZ_X11)
++
++typedef Bool (*_XScreenSaverQueryExtension_fn)(Display* dpy, int* event_base,
++ int* error_base);
++typedef Bool (*_XScreenSaverQueryVersion_fn)(Display* dpy, int* major,
++ int* minor);
++typedef void (*_XScreenSaverSuspend_fn)(Display* dpy, Bool suspend);
++
++static PRLibrary* sXssLib = nullptr;
++static _XScreenSaverQueryExtension_fn _XSSQueryExtension = nullptr;
++static _XScreenSaverQueryVersion_fn _XSSQueryVersion = nullptr;
++static _XScreenSaverSuspend_fn _XSSSuspend = nullptr;
++
++/* static */ bool
++WakeLockTopic::CheckXScreenSaverSupport()
++{
++ if (!sXssLib) {
++ sXssLib = PR_LoadLibrary("libXss.so.1");
++ if (!sXssLib) {
++ return false;
++ }
++ }
++
++ _XSSQueryExtension = (_XScreenSaverQueryExtension_fn)
++ PR_FindFunctionSymbol(sXssLib, "XScreenSaverQueryExtension");
++ _XSSQueryVersion = (_XScreenSaverQueryVersion_fn)
++ PR_FindFunctionSymbol(sXssLib, "XScreenSaverQueryVersion");
++ _XSSSuspend = (_XScreenSaverSuspend_fn)
++ PR_FindFunctionSymbol(sXssLib, "XScreenSaverSuspend");
++ if (!_XSSQueryExtension || !_XSSQueryVersion || !_XSSSuspend) {
++ return false;
++ }
++
++ GdkDisplay* gDisplay = gdk_display_get_default();
++ if (!GDK_IS_X11_DISPLAY(gDisplay)) return false;
++ Display* display = GDK_DISPLAY_XDISPLAY(gDisplay);
++
++ int throwaway;
++ if (!_XSSQueryExtension(display, &throwaway, &throwaway)) return false;
++
++ int major, minor;
++ if (!_XSSQueryVersion(display, &major, &minor)) return false;
++ // Needs to be compatible with version 1.1
++ if (major != 1) return false;
++ if (minor < 1) return false;
++
++ return true;
++}
++
++/* static */ bool
++WakeLockTopic::InhibitXScreenSaver(bool inhibit)
++{
++ // Should only be called if CheckXScreenSaverSupport returns true.
++ // There's a couple of safety checks here nonetheless.
++ if (!_XSSSuspend) return false;
++ GdkDisplay* gDisplay = gdk_display_get_default();
++ if (!GDK_IS_X11_DISPLAY(gDisplay)) return false;
++ Display* display = GDK_DISPLAY_XDISPLAY(gDisplay);
++ _XSSSuspend(display, inhibit);
++ return true;
++}
++
++#endif
++
++
+ bool
+ WakeLockTopic::SendInhibit()
+ {
+@@ -156,6 +233,10 @@ WakeLockTopic::SendInhibit()
+ case GNOME:
+ sendOk = SendGNOMEInhibitMessage();
+ break;
++#if defined(MOZ_X11)
++ case XScreenSaver:
++ return InhibitXScreenSaver(true);
++#endif
+ case Unsupported:
+ return false;
+ }
+@@ -185,6 +266,11 @@ WakeLockTopic::SendUninhibit()
+ SESSION_MANAGER_INTERFACE,
+ "Uninhibit"));
+ }
++#if defined(MOZ_X11)
++ else if (mDesktopEnvironment == XScreenSaver) {
++ return InhibitXScreenSaver(false);
++ }
++#endif
+
+ if (!message) {
+ return false;
+@@ -249,8 +335,11 @@ WakeLockTopic::InhibitFailed()
+
+ if (mDesktopEnvironment == FreeDesktop) {
+ mDesktopEnvironment = GNOME;
++#if defined(MOZ_X11)
++ } else if (mDesktopEnvironment == GNOME && CheckXScreenSaverSupport()) {
++ mDesktopEnvironment = XScreenSaver;
++#endif
+ } else {
+- NS_ASSERTION(mDesktopEnvironment == GNOME, "Unknown desktop environment");
+ mDesktopEnvironment = Unsupported;
+ mShouldInhibit = false;
+ }
diff --git a/www/waterfox/files/patch-bug1399336 b/www/waterfox/files/patch-bug1399336
new file mode 100644
index 000000000000..cdd53e791954
--- /dev/null
+++ b/www/waterfox/files/patch-bug1399336
@@ -0,0 +1,153 @@
+commit 355019fdeca4
+Author: Mantaroh Yoshinaga <mantaroh@gmail.com>
+Date: Wed Sep 13 14:23:59 2017 +0900
+
+ Bug 1399336 - Memory leak of char16_t internal variables of widget/nsPrintOptionsImpl.cpp r=m_kato
+
+ A nsPrintOptionsImpl has char16_t internal variables, and gecko will not release
+ these allocated variable. So we should use nsString instead of char16_t.
+
+ MozReview-Commit-ID: 4ZMtUKoVCcR
+
+ --HG--
+ extra : rebase_source : 1720483301b900f8135c3d5f8f32d7051191aa8f
+---
+ widget/nsPrintOptionsImpl.cpp | 46 ++++++++++++++++++++-----------------------
+ 1 file changed, 21 insertions(+), 25 deletions(-)
+
+diff --git widget/nsPrintOptionsImpl.cpp widget/nsPrintOptionsImpl.cpp
+index c36b5be3e8a7..c2b5e113612e 100644
+--- widget/nsPrintOptionsImpl.cpp
++++ widget/nsPrintOptionsImpl.cpp
+@@ -765,13 +765,13 @@ nsPrintOptions::WritePrefs(nsIPrintSettings *aPS, const nsAString& aPrinterName,
+ if (aFlags & nsIPrintSettings::kInitSavePaperSize) {
+ int16_t sizeUnit;
+ double width, height;
+- char16_t *name;
++ nsString name;
+
+ if (
+ NS_SUCCEEDED(aPS->GetPaperSizeUnit(&sizeUnit)) &&
+ NS_SUCCEEDED(aPS->GetPaperWidth(&width)) &&
+ NS_SUCCEEDED(aPS->GetPaperHeight(&height)) &&
+- NS_SUCCEEDED(aPS->GetPaperName(&name))
++ NS_SUCCEEDED(aPS->GetPaperName(getter_Copies(name)))
+ ) {
+ DUMP_INT(kWriteStr, kPrintPaperSizeUnit, sizeUnit);
+ Preferences::SetInt(GetPrefName(kPrintPaperSizeUnit, aPrinterName),
+@@ -780,7 +780,7 @@ nsPrintOptions::WritePrefs(nsIPrintSettings *aPS, const nsAString& aPrinterName,
+ WritePrefDouble(GetPrefName(kPrintPaperWidth, aPrinterName), width);
+ DUMP_DBL(kWriteStr, kPrintPaperHeight, height);
+ WritePrefDouble(GetPrefName(kPrintPaperHeight, aPrinterName), height);
+- DUMP_STR(kWriteStr, kPrintPaperName, name);
++ DUMP_STR(kWriteStr, kPrintPaperName, name.get());
+ Preferences::SetString(GetPrefName(kPrintPaperName, aPrinterName), name);
+ #if defined(XP_WIN)
+ // If the height and width are -1 then this might be a save triggered by
+@@ -800,7 +800,7 @@ nsPrintOptions::WritePrefs(nsIPrintSettings *aPS, const nsAString& aPrinterName,
+ }
+
+ bool b;
+- char16_t* uStr;
++ nsString uStr;
+ int32_t iVal;
+ int16_t iVal16;
+ double dbl;
+@@ -822,48 +822,48 @@ nsPrintOptions::WritePrefs(nsIPrintSettings *aPS, const nsAString& aPrinterName,
+ }
+
+ if (aFlags & nsIPrintSettings::kInitSaveHeaderLeft) {
+- if (NS_SUCCEEDED(aPS->GetHeaderStrLeft(&uStr))) {
+- DUMP_STR(kWriteStr, kPrintHeaderStrLeft, uStr);
++ if (NS_SUCCEEDED(aPS->GetHeaderStrLeft(getter_Copies(uStr)))) {
++ DUMP_STR(kWriteStr, kPrintHeaderStrLeft, uStr.get());
+ Preferences::SetString(GetPrefName(kPrintHeaderStrLeft, aPrinterName),
+ uStr);
+ }
+ }
+
+ if (aFlags & nsIPrintSettings::kInitSaveHeaderCenter) {
+- if (NS_SUCCEEDED(aPS->GetHeaderStrCenter(&uStr))) {
+- DUMP_STR(kWriteStr, kPrintHeaderStrCenter, uStr);
++ if (NS_SUCCEEDED(aPS->GetHeaderStrCenter(getter_Copies(uStr)))) {
++ DUMP_STR(kWriteStr, kPrintHeaderStrCenter, uStr.get());
+ Preferences::SetString(GetPrefName(kPrintHeaderStrCenter, aPrinterName),
+ uStr);
+ }
+ }
+
+ if (aFlags & nsIPrintSettings::kInitSaveHeaderRight) {
+- if (NS_SUCCEEDED(aPS->GetHeaderStrRight(&uStr))) {
+- DUMP_STR(kWriteStr, kPrintHeaderStrRight, uStr);
++ if (NS_SUCCEEDED(aPS->GetHeaderStrRight(getter_Copies(uStr)))) {
++ DUMP_STR(kWriteStr, kPrintHeaderStrRight, uStr.get());
+ Preferences::SetString(GetPrefName(kPrintHeaderStrRight, aPrinterName),
+ uStr);
+ }
+ }
+
+ if (aFlags & nsIPrintSettings::kInitSaveFooterLeft) {
+- if (NS_SUCCEEDED(aPS->GetFooterStrLeft(&uStr))) {
+- DUMP_STR(kWriteStr, kPrintFooterStrLeft, uStr);
++ if (NS_SUCCEEDED(aPS->GetFooterStrLeft(getter_Copies(uStr)))) {
++ DUMP_STR(kWriteStr, kPrintFooterStrLeft, uStr.get());
+ Preferences::SetString(GetPrefName(kPrintFooterStrLeft, aPrinterName),
+ uStr);
+ }
+ }
+
+ if (aFlags & nsIPrintSettings::kInitSaveFooterCenter) {
+- if (NS_SUCCEEDED(aPS->GetFooterStrCenter(&uStr))) {
+- DUMP_STR(kWriteStr, kPrintFooterStrCenter, uStr);
++ if (NS_SUCCEEDED(aPS->GetFooterStrCenter(getter_Copies(uStr)))) {
++ DUMP_STR(kWriteStr, kPrintFooterStrCenter, uStr.get());
+ Preferences::SetString(GetPrefName(kPrintFooterStrCenter, aPrinterName),
+ uStr);
+ }
+ }
+
+ if (aFlags & nsIPrintSettings::kInitSaveFooterRight) {
+- if (NS_SUCCEEDED(aPS->GetFooterStrRight(&uStr))) {
+- DUMP_STR(kWriteStr, kPrintFooterStrRight, uStr);
++ if (NS_SUCCEEDED(aPS->GetFooterStrRight(getter_Copies(uStr)))) {
++ DUMP_STR(kWriteStr, kPrintFooterStrRight, uStr.get());
+ Preferences::SetString(GetPrefName(kPrintFooterStrRight, aPrinterName),
+ uStr);
+ }
+@@ -915,8 +915,8 @@ nsPrintOptions::WritePrefs(nsIPrintSettings *aPS, const nsAString& aPrinterName,
+ // Only the general version of this pref is saved
+ if ((aFlags & nsIPrintSettings::kInitSavePrinterName)
+ && aPrinterName.IsEmpty()) {
+- if (NS_SUCCEEDED(aPS->GetPrinterName(&uStr))) {
+- DUMP_STR(kWriteStr, kPrinterName, uStr);
++ if (NS_SUCCEEDED(aPS->GetPrinterName(getter_Copies(uStr)))) {
++ DUMP_STR(kWriteStr, kPrinterName, uStr.get());
+ Preferences::SetString(kPrinterName, uStr);
+ }
+ }
+@@ -929,8 +929,8 @@ nsPrintOptions::WritePrefs(nsIPrintSettings *aPS, const nsAString& aPrinterName,
+ }
+
+ if (aFlags & nsIPrintSettings::kInitSaveToFileName) {
+- if (NS_SUCCEEDED(aPS->GetToFileName(&uStr))) {
+- DUMP_STR(kWriteStr, kPrintToFileName, uStr);
++ if (NS_SUCCEEDED(aPS->GetToFileName(getter_Copies(uStr)))) {
++ DUMP_STR(kWriteStr, kPrintToFileName, uStr.get());
+ Preferences::SetString(GetPrefName(kPrintToFileName, aPrinterName), uStr);
+ }
+ }
+@@ -1105,13 +1105,9 @@ GetAdjustedPrinterName(nsIPrintSettings* aPS, bool aUsePNP,
+
+ // Get the Printer Name from the PrintSettings
+ // to use as a prefix for Pref Names
+- char16_t* prtName = nullptr;
+-
+- nsresult rv = aPS->GetPrinterName(&prtName);
++ nsresult rv = aPS->GetPrinterName(getter_Copies(aPrinterName));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+- aPrinterName = nsDependentString(prtName);
+-
+ // Convert any whitespaces, carriage returns or newlines to _
+ // The below algorithm is supposedly faster than using iterators
+ NS_NAMED_LITERAL_STRING(replSubstr, "_");
diff --git a/www/waterfox/files/patch-bug1400238 b/www/waterfox/files/patch-bug1400238
new file mode 100644
index 000000000000..efc0314ff24c
--- /dev/null
+++ b/www/waterfox/files/patch-bug1400238
@@ -0,0 +1,30 @@
+commit 02ae35c9e105
+Author: Botond Ballo <botond@mozilla.com>
+Date: Wed Oct 18 13:29:47 2017 -0400
+
+ Bug 1400238 - Notify TabParent when the GTK client offset changes. r=karlt
+
+ MozReview-Commit-ID: 1TacAhl6c2M
+
+ --HG--
+ extra : rebase_source : 5641d417a6245cc2f8027fd91032119f1b36d461
+---
+ widget/gtk/nsWindow.cpp | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git widget/gtk/nsWindow.cpp widget/gtk/nsWindow.cpp
+index 955327297ac9..e58f3dcb59d5 100644
+--- widget/gtk/nsWindow.cpp
++++ widget/gtk/nsWindow.cpp
+@@ -1567,6 +1567,11 @@ nsWindow::OnPropertyNotifyEvent(GtkWidget* aWidget, GdkEventProperty* aEvent)
+ {
+ if (aEvent->atom == gdk_atom_intern("_NET_FRAME_EXTENTS", FALSE)) {
+ UpdateClientOffset();
++
++ // Send a WindowMoved notification. This ensures that TabParent
++ // picks up the new client offset and sends it to the child process
++ // if appropriate.
++ NotifyWindowMoved(mBounds.x, mBounds.y);
+ return FALSE;
+ }
+
diff --git a/www/waterfox/files/patch-bug1400839 b/www/waterfox/files/patch-bug1400839
new file mode 100644
index 000000000000..88f5d88c2e16
--- /dev/null
+++ b/www/waterfox/files/patch-bug1400839
@@ -0,0 +1,49 @@
+commit a0bf5a4eff67
+Author: sebastian@ifyouwantblood.de <sebastian@ifyouwantblood.de>
+Date: Tue Sep 19 11:47:12 2017 +1200
+
+ bug 1400839 use -1 instead of 0 to indicate absent glxtest_pipe fd r=karlt
+
+ Englightenment closes fd 0 on child processes and so pipe() can return a zero fd.
+
+ MozReview-Commit-ID: 5d9xQXgwgfv
+
+ --HG--
+ extra : rebase_source : c31aa7ce731ba325993f463b79b446ae67c932dd
+---
+ widget/GfxInfoX11.cpp | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git widget/GfxInfoX11.cpp widget/GfxInfoX11.cpp
+index bf99367d084b..8bb54a99136f 100644
+--- widget/GfxInfoX11.cpp
++++ widget/GfxInfoX11.cpp
+@@ -28,7 +28,7 @@ NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug)
+ #endif
+
+ // these global variables will be set when firing the glxtest process
+-int glxtest_pipe = 0;
++int glxtest_pipe = -1;
+ pid_t glxtest_pid = 0;
+
+ nsresult
+@@ -55,8 +55,8 @@ GfxInfo::GetData()
+ // to understand this function, see bug 639842. We retrieve the OpenGL driver information in a
+ // separate process to protect against bad drivers.
+
+- // if glxtest_pipe == 0, that means that we already read the information
+- if (!glxtest_pipe)
++ // if glxtest_pipe == -1, that means that we already read the information
++ if (glxtest_pipe == -1)
+ return;
+
+ enum { buf_size = 1024 };
+@@ -65,7 +65,7 @@ GfxInfo::GetData()
+ &buf,
+ buf_size-1); // -1 because we'll append a zero
+ close(glxtest_pipe);
+- glxtest_pipe = 0;
++ glxtest_pipe = -1;
+
+ // bytesread < 0 would mean that the above read() call failed.
+ // This should never happen. If it did, the outcome would be to blacklist anyway.
diff --git a/www/waterfox/files/patch-bug1401063 b/www/waterfox/files/patch-bug1401063
new file mode 100644
index 000000000000..d151a96dfd6e
--- /dev/null
+++ b/www/waterfox/files/patch-bug1401063
@@ -0,0 +1,160 @@
+commit fb488ded4b64
+Author: Brad Werth <bwerth@mozilla.com>
+Date: Tue Sep 19 13:00:28 2017 -0700
+
+ Bug 1401063: Cache remaining gtk window and button colors to eliminate on-demand gtk calls in ::NativeGetColor. r=karlt
+
+ MozReview-Commit-ID: HbZqBUG0w7y
+
+ --HG--
+ extra : rebase_source : 0b26c22113c2cda49129006fe933f20719b7a679
+---
+ widget/gtk/nsLookAndFeel.cpp | 62 +++++++++++++++++++-------------------------
+ widget/gtk/nsLookAndFeel.h | 5 ++++
+ 2 files changed, 31 insertions(+), 36 deletions(-)
+
+diff --git widget/gtk/nsLookAndFeel.cpp widget/gtk/nsLookAndFeel.cpp
+index 9a2684412ee8..e02bf10fe87f 100644
+--- widget/gtk/nsLookAndFeel.cpp
++++ widget/gtk/nsLookAndFeel.cpp
+@@ -225,7 +225,6 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
+ {
+ EnsureInit();
+
+- GdkRGBA gdk_color;
+ nsresult res = NS_OK;
+
+ switch (aID) {
+@@ -294,40 +293,26 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
+ aColor = NS_TRANSPARENT;
+ break;
+ case eColorID_SpellCheckerUnderline:
+- aColor = NS_RGB(0xff, 0, 0);
+- break;
++ aColor = NS_RGB(0xff, 0, 0);
++ break;
+
+ // css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
+- case eColorID_activeborder: {
++ case eColorID_activeborder:
+ // active window border
+- GtkStyleContext *style = GetStyleContext(MOZ_GTK_WINDOW);
+- gtk_style_context_get_border_color(style,
+- GTK_STATE_FLAG_NORMAL, &gdk_color);
+- aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
++ aColor = sMozWindowActiveBorder;
+ break;
+- }
+- case eColorID_inactiveborder: {
++ case eColorID_inactiveborder:
+ // inactive window border
+- GtkStyleContext *style = GetStyleContext(MOZ_GTK_WINDOW);
+- gtk_style_context_get_border_color(style,
+- GTK_STATE_FLAG_INSENSITIVE,
+- &gdk_color);
+- aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
++ aColor = sMozWindowInactiveBorder;
+ break;
+- }
+ case eColorID_graytext: // disabled text in windows, menus, etc.
+ case eColorID_inactivecaptiontext: // text in inactive window caption
+ aColor = sMenuTextInactive;
+ break;
+- case eColorID_inactivecaption: {
++ case eColorID_inactivecaption:
+ // inactive window caption
+- GtkStyleContext *style = GetStyleContext(MOZ_GTK_WINDOW);
+- gtk_style_context_get_background_color(style,
+- GTK_STATE_FLAG_INSENSITIVE,
+- &gdk_color);
+- aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
++ aColor = sMozWindowInactiveCaption;
+ break;
+- }
+ case eColorID_infobackground:
+ // tooltip background color
+ aColor = sInfoBackground;
+@@ -389,22 +374,13 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
+ case eColorID__moz_fieldtext:
+ aColor = sMozFieldText;
+ break;
+- case eColorID__moz_buttondefault: {
++ case eColorID__moz_buttondefault:
+ // default button border color
+- GtkStyleContext *style = GetStyleContext(MOZ_GTK_BUTTON);
+- gtk_style_context_get_border_color(style,
+- GTK_STATE_FLAG_NORMAL, &gdk_color);
+- aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
++ aColor = sButtonDefault;
+ break;
+- }
+- case eColorID__moz_buttonhoverface: {
+- GtkStyleContext *style = GetStyleContext(MOZ_GTK_BUTTON);
+- gtk_style_context_get_background_color(style,
+- GTK_STATE_FLAG_PRELIGHT,
+- &gdk_color);
+- aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
++ case eColorID__moz_buttonhoverface:
++ aColor = sButtonHoverFace;
+ break;
+- }
+ case eColorID__moz_buttonhovertext:
+ aColor = sButtonHoverText;
+ break;
+@@ -863,6 +839,15 @@ nsLookAndFeel::EnsureInit()
+ sMozWindowBackground = GDK_RGBA_TO_NS_RGBA(color);
+ gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
+ sMozWindowText = GDK_RGBA_TO_NS_RGBA(color);
++ gtk_style_context_get_border_color(style, GTK_STATE_FLAG_NORMAL, &color);
++ sMozWindowActiveBorder = GDK_RGBA_TO_NS_RGBA(color);
++ gtk_style_context_get_border_color(style, GTK_STATE_FLAG_INSENSITIVE,
++ &color);
++ sMozWindowInactiveBorder = GDK_RGBA_TO_NS_RGBA(color);
++ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_INSENSITIVE,
++ &color);
++ sMozWindowInactiveCaption = GDK_RGBA_TO_NS_RGBA(color);
++
+ style = GetStyleContext(MOZ_GTK_WINDOW_CONTAINER);
+ {
+ GtkStyleContext* labelStyle = CreateStyleForWidget(labelWidget, style);
+@@ -953,10 +938,15 @@ nsLookAndFeel::EnsureInit()
+
+ GetSystemFontInfo(labelStyle, &mButtonFontName, &mButtonFontStyle);
+
++ gtk_style_context_get_border_color(style, GTK_STATE_FLAG_NORMAL, &color);
++ sButtonDefault = GDK_RGBA_TO_NS_RGBA(color);
+ gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_NORMAL, &color);
+ sButtonText = GDK_RGBA_TO_NS_RGBA(color);
+ gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_PRELIGHT, &color);
+ sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color);
++ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT,
++ &color);
++ sButtonHoverFace = GDK_RGBA_TO_NS_RGBA(color);
+ g_object_unref(labelStyle);
+ }
+
+diff --git widget/gtk/nsLookAndFeel.h widget/gtk/nsLookAndFeel.h
+index 38cd51c056d6..177d069f6567 100644
+--- widget/gtk/nsLookAndFeel.h
++++ widget/gtk/nsLookAndFeel.h
+@@ -58,8 +58,10 @@ protected:
+ nscolor sMenuTextInactive;
+ nscolor sMenuHover;
+ nscolor sMenuHoverText;
++ nscolor sButtonDefault;
+ nscolor sButtonText;
+ nscolor sButtonHoverText;
++ nscolor sButtonHoverFace;
+ nscolor sFrameOuterLightBorder;
+ nscolor sFrameInnerDarkBorder;
+ nscolor sOddCellBackground;
+@@ -70,6 +72,9 @@ protected:
+ nscolor sMozFieldBackground;
+ nscolor sMozWindowText;
+ nscolor sMozWindowBackground;
++ nscolor sMozWindowActiveBorder;
++ nscolor sMozWindowInactiveBorder;
++ nscolor sMozWindowInactiveCaption;
+ nscolor sTextSelectedText;
+ nscolor sTextSelectedBackground;
+ nscolor sMozScrollbar;
diff --git a/www/waterfox/files/patch-bug1407001 b/www/waterfox/files/patch-bug1407001
new file mode 100644
index 000000000000..577193e4a362
--- /dev/null
+++ b/www/waterfox/files/patch-bug1407001
@@ -0,0 +1,33 @@
+commit 979b5671a61f
+Author: Ryan Hunt <rhunt@eqrion.net>
+Date: Mon Oct 9 12:49:53 2017 -0500
+
+ Bug 1407001 - Don't reset compositors for composited changed callback when GPUProcessManager is null. r=lsalzman
+
+ MozReview-Commit-ID: 4E31bt3Rzkz
+
+ --HG--
+ extra : rebase_source : 84a18ffcc77f37220284679c1dbb916a25524d31
+---
+ widget/gtk/nsWindow.cpp | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git widget/gtk/nsWindow.cpp widget/gtk/nsWindow.cpp
+index 575dc83d964c..eb2f0e5e95cd 100644
+--- widget/gtk/nsWindow.cpp
++++ widget/gtk/nsWindow.cpp
+@@ -5923,7 +5923,13 @@ check_resize_cb (GtkContainer* container, gpointer user_data)
+ static void
+ screen_composited_changed_cb (GdkScreen* screen, gpointer user_data)
+ {
+- GPUProcessManager::Get()->ResetCompositors();
++ // This callback can run before gfxPlatform::Init() in rare
++ // cases involving the profile manager. When this happens,
++ // we have no reason to reset any compositors as graphics
++ // hasn't been initialized yet.
++ if (GPUProcessManager::Get()) {
++ GPUProcessManager::Get()->ResetCompositors();
++ }
+ }
+
+ static void
diff --git a/www/waterfox/files/patch-bug1417751 b/www/waterfox/files/patch-bug1417751
new file mode 100644
index 000000000000..aea1eddf0f5b
--- /dev/null
+++ b/www/waterfox/files/patch-bug1417751
@@ -0,0 +1,379 @@
+commit e889dbe68557
+Author: lochang <lochang@mozilla.com>
+Date: Wed Nov 29 10:43:13 2017 +0800
+
+ Bug 1417751 - Implement a new value inner-spin-button to -moz-appearance on all platforms except Android. r=mats
+
+ MozReview-Commit-ID: 7jpLCOWZA2x
+
+ --HG--
+ extra : rebase_source : d2a4d160d26e6f6996ed1cb3a673576236b8ef23
+---
+ devtools/shared/css/generated/properties-db.js | 2 ++
+ gfx/src/nsThemeConstants.h | 3 ++
+ layout/style/nsCSSKeywordList.h | 1 +
+ layout/style/nsCSSProps.cpp | 1 +
+ widget/cocoa/nsNativeThemeCocoa.mm | 9 +++--
+ widget/gtk/gtk2drawing.c | 49 ++++++++++++++++++++++++++
+ widget/gtk/gtk3drawing.cpp | 38 ++++++++++++++++++++
+ widget/gtk/gtkdrawing.h | 1 +
+ widget/gtk/nsNativeThemeGTK.cpp | 5 +++
+ widget/headless/HeadlessThemeGTK.cpp | 2 ++
+ widget/windows/nsNativeThemeWin.cpp | 9 +++++
+ 11 files changed, 118 insertions(+), 2 deletions(-)
+
+diff --git devtools/shared/css/generated/properties-db.js devtools/shared/css/generated/properties-db.js
+index 6d12ca38f14d..b87366998a16 100644
+--- devtools/shared/css/generated/properties-db.js
++++ devtools/shared/css/generated/properties-db.js
+@@ -236,6 +236,7 @@ exports.CSS_PROPERTIES = {
+ "groupbox",
+ "inherit",
+ "initial",
++ "inner-spin-button",
+ "listbox",
+ "listitem",
+ "menuarrow",
+@@ -3458,6 +3459,7 @@ exports.CSS_PROPERTIES = {
+ "inline-grid",
+ "inline-start",
+ "inline-table",
++ "inner-spin-button",
+ "inset",
+ "inside",
+ "inter-character",
+diff --git gfx/src/nsThemeConstants.h gfx/src/nsThemeConstants.h
+index 439ada6e80a6..0688222ef7ea 100644
+--- gfx/src/nsThemeConstants.h
++++ gfx/src/nsThemeConstants.h
+@@ -135,6 +135,9 @@ enum ThemeWidgetType : uint8_t {
+ // A tooltip
+ NS_THEME_TOOLTIP,
+
++ // A inner-spin control
++ NS_THEME_INNER_SPIN_BUTTON,
++
+ // A spin control (up/down control for time/date pickers)
+ NS_THEME_SPINNER,
+
+diff --git layout/style/nsCSSKeywordList.h layout/style/nsCSSKeywordList.h
+index f184592ad7c6..ff448c87b761 100644
+--- layout/style/nsCSSKeywordList.h
++++ layout/style/nsCSSKeywordList.h
+@@ -683,6 +683,7 @@ CSS_KEY(tabpanel, tabpanel)
+ CSS_KEY(tab-scroll-arrow-back, tab_scroll_arrow_back)
+ CSS_KEY(tab-scroll-arrow-forward, tab_scroll_arrow_forward)
+ CSS_KEY(tooltip, tooltip)
++CSS_KEY(inner-spin-button, inner_spin_button)
+ CSS_KEY(spinner, spinner)
+ CSS_KEY(spinner-upbutton, spinner_upbutton)
+ CSS_KEY(spinner-downbutton, spinner_downbutton)
+diff --git layout/style/nsCSSProps.cpp layout/style/nsCSSProps.cpp
+index b7815699afa6..5c1ab8e8aae3 100644
+--- layout/style/nsCSSProps.cpp
++++ layout/style/nsCSSProps.cpp
+@@ -786,6 +786,7 @@ const KTableEntry nsCSSProps::kAppearanceKTable[] = {
+ { eCSSKeyword_tab_scroll_arrow_back, NS_THEME_TAB_SCROLL_ARROW_BACK },
+ { eCSSKeyword_tab_scroll_arrow_forward, NS_THEME_TAB_SCROLL_ARROW_FORWARD },
+ { eCSSKeyword_tooltip, NS_THEME_TOOLTIP },
++ { eCSSKeyword_inner_spin_button, NS_THEME_INNER_SPIN_BUTTON },
+ { eCSSKeyword_spinner, NS_THEME_SPINNER },
+ { eCSSKeyword_spinner_upbutton, NS_THEME_SPINNER_UPBUTTON },
+ { eCSSKeyword_spinner_downbutton, NS_THEME_SPINNER_DOWNBUTTON },
+diff --git widget/cocoa/nsNativeThemeCocoa.mm widget/cocoa/nsNativeThemeCocoa.mm
+index 760279b3a972..a4066b030897 100644
+--- widget/cocoa/nsNativeThemeCocoa.mm
++++ widget/cocoa/nsNativeThemeCocoa.mm
+@@ -2551,9 +2551,11 @@ nsNativeThemeCocoa::DrawWidgetBackground(gfxContext* aContext,
+ eventState, aFrame);
+ break;
+
+- case NS_THEME_SPINNER: {
++ case NS_THEME_INNER_SPIN_BUTTON: {
++ case NS_THEME_SPINNER:
++ bool isSpinner = (aWidgetType == NS_THEME_SPINNER);
+ nsIContent* content = aFrame->GetContent();
+- if (content->IsHTMLElement()) {
++ if (isSpinner && content->IsHTMLElement()) {
+ // In HTML the theming for the spin buttons is drawn individually into
+ // their own backgrounds instead of being drawn into the background of
+ // their spinner parent as it is for XUL.
+@@ -3454,6 +3456,7 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsPresContext* aPresContext,
+ break;
+ }
+
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER:
+ case NS_THEME_SPINNER_UPBUTTON:
+ case NS_THEME_SPINNER_DOWNBUTTON:
+@@ -3838,6 +3841,7 @@ nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* a
+ case NS_THEME_BUTTON_ARROW_DOWN:
+ case NS_THEME_BUTTON_BEVEL:
+ case NS_THEME_TOOLBARBUTTON:
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER:
+ case NS_THEME_SPINNER_UPBUTTON:
+ case NS_THEME_SPINNER_DOWNBUTTON:
+@@ -3978,6 +3982,7 @@ nsNativeThemeCocoa::WidgetAppearanceDependsOnWindowFocus(uint8_t aWidgetType)
+ case NS_THEME_MENUITEM:
+ case NS_THEME_MENUSEPARATOR:
+ case NS_THEME_TOOLTIP:
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER:
+ case NS_THEME_SPINNER_UPBUTTON:
+ case NS_THEME_SPINNER_DOWNBUTTON:
+diff --git widget/gtk/gtk2drawing.c widget/gtk/gtk2drawing.c
+index 9b523c8f893e..e7f9d32a4d1c 100644
+--- widget/gtk/gtk2drawing.c
++++ widget/gtk/gtk2drawing.c
+@@ -1365,6 +1365,51 @@ moz_gtk_scrollbar_thumb_paint(WidgetNodeType widget,
+ return MOZ_GTK_SUCCESS;
+ }
+
++static gint
++moz_gtk_inner_spin_paint(GdkDrawable* drawable, GdkRectangle* rect,
++ GtkWidgetState* state,
++ GtkTextDirection direction)
++{
++ GdkRectangle arrow_rect;
++ GtkStateType state_type = ConvertGtkState(state);
++ GtkShadowType shadow_type = state_type == GTK_STATE_ACTIVE ?
++ GTK_SHADOW_IN : GTK_SHADOW_OUT;
++ GtkStyle* style;
++
++ ensure_spin_widget();
++ style = gSpinWidget->style;
++ gtk_widget_set_direction(gSpinWidget, direction);
++
++ TSOffsetStyleGCs(style, rect->x, rect->y);
++ gtk_paint_box(style, drawable, state_type, shadow_type, NULL, gSpinWidget,
++ "spinbutton", rect->x, rect->y, rect->width, rect->height);
++
++ /* hard code these values */
++ arrow_rect.width = 6;
++ arrow_rect.height = 6;
++
++ // align spin to the left
++ arrow_rect.x = rect->x;
++
++ // up button
++ arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2 - 3;
++ gtk_paint_arrow(style, drawable, state_type, shadow_type, NULL,
++ gSpinWidget, "spinbutton",
++ GTK_ARROW_UP, TRUE,
++ arrow_rect.x, arrow_rect.y,
++ arrow_rect.width, arrow_rect.height);
++
++ // down button
++ arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2 + 3;
++ gtk_paint_arrow(style, drawable, state_type, shadow_type, NULL,
++ gSpinWidget, "spinbutton",
++ GTK_ARROW_DOWN,
++ arrow_rect.x, arrow_rect.y,
++ arrow_rect.width, arrow_rect.height);
++
++ return MOZ_GTK_SUCCESS;
++}
++
+ static gint
+ moz_gtk_spin_paint(GdkDrawable* drawable, GdkRectangle* rect,
+ GtkTextDirection direction)
+@@ -2984,6 +3029,7 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
+ case MOZ_GTK_TOOLBAR_SEPARATOR:
+ case MOZ_GTK_MENUSEPARATOR:
+ /* These widgets have no borders.*/
++ case MOZ_GTK_INNER_SPIN_BUTTON:
+ case MOZ_GTK_SPINBUTTON:
+ case MOZ_GTK_WINDOW:
+ case MOZ_GTK_RESIZER:
+@@ -3247,6 +3293,9 @@ moz_gtk_widget_paint(WidgetNodeType widget, GdkDrawable* drawable,
+ return moz_gtk_scale_thumb_paint(drawable, rect, cliprect, state,
+ (GtkOrientation) flags, direction);
+ break;
++ case MOZ_GTK_INNER_SPIN_BUTTON:
++ return moz_gtk_inner_spin_paint(drawable, rect, state, direction);
++ break;
+ case MOZ_GTK_SPINBUTTON:
+ return moz_gtk_spin_paint(drawable, rect, direction);
+ break;
+diff --git widget/gtk/gtk3drawing.cpp widget/gtk/gtk3drawing.cpp
+index 2969be818e96..a3a1478bfe85 100644
+--- widget/gtk/gtk3drawing.cpp
++++ widget/gtk/gtk3drawing.cpp
+@@ -797,6 +797,40 @@ moz_gtk_scrollbar_thumb_paint(WidgetNodeType widget,
+ return MOZ_GTK_SUCCESS;
+ }
+
++static gint
++moz_gtk_inner_spin_paint(cairo_t *cr, GdkRectangle* rect,
++ GtkWidgetState* state,
++ GtkTextDirection direction)
++{
++ GtkStyleContext* style = GetStyleContext(MOZ_GTK_SPINBUTTON, direction,
++ GetStateFlagsFromGtkWidgetState(state));
++
++ gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
++ gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
++
++ /* hard code these values */
++ GdkRectangle arrow_rect;
++ arrow_rect.width = 6;
++ arrow_rect.height = 6;
++
++ // align spin to the left
++ arrow_rect.x = rect->x;
++
++ // up button
++ arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2 - 3;
++ gtk_render_arrow(style, cr, ARROW_UP,
++ arrow_rect.x, arrow_rect.y,
++ arrow_rect.width);
++
++ // down button
++ arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2 + 3;
++ gtk_render_arrow(style, cr, ARROW_DOWN,
++ arrow_rect.x, arrow_rect.y,
++ arrow_rect.width);
++
++ return MOZ_GTK_SUCCESS;
++}
++
+ static gint
+ moz_gtk_spin_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkTextDirection direction)
+@@ -2283,6 +2317,7 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
+ case MOZ_GTK_TOOLBAR_SEPARATOR:
+ case MOZ_GTK_MENUSEPARATOR:
+ /* These widgets have no borders.*/
++ case MOZ_GTK_INNER_SPIN_BUTTON:
+ case MOZ_GTK_SPINBUTTON:
+ case MOZ_GTK_WINDOW:
+ case MOZ_GTK_RESIZER:
+@@ -2845,6 +2880,9 @@ moz_gtk_widget_paint(WidgetNodeType widget, cairo_t *cr,
+ return moz_gtk_scale_thumb_paint(cr, rect, state,
+ (GtkOrientation) flags, direction);
+ break;
++ case MOZ_GTK_INNER_SPIN_BUTTON:
++ return moz_gtk_inner_spin_paint(cr, rect, state, direction);
++ break;
+ case MOZ_GTK_SPINBUTTON:
+ return moz_gtk_spin_paint(cr, rect, direction);
+ break;
+diff --git widget/gtk/gtkdrawing.h widget/gtk/gtkdrawing.h
+index 59fd1256e22d..4e796d0237d9 100644
+--- widget/gtk/gtkdrawing.h
++++ widget/gtk/gtkdrawing.h
+@@ -175,6 +175,7 @@ typedef enum {
+ MOZ_GTK_SCALE_THUMB_HORIZONTAL,
+ MOZ_GTK_SCALE_THUMB_VERTICAL,
+ /* Paints a GtkSpinButton */
++ MOZ_GTK_INNER_SPIN_BUTTON,
+ MOZ_GTK_SPINBUTTON,
+ MOZ_GTK_SPINBUTTON_UP,
+ MOZ_GTK_SPINBUTTON_DOWN,
+diff --git widget/gtk/nsNativeThemeGTK.cpp widget/gtk/nsNativeThemeGTK.cpp
+index c38c9e1eed3d..953aead6cdd4 100644
+--- widget/gtk/nsNativeThemeGTK.cpp
++++ widget/gtk/nsNativeThemeGTK.cpp
+@@ -439,6 +439,9 @@ nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame,
+ case NS_THEME_SCROLLBARTHUMB_HORIZONTAL:
+ aGtkWidgetType = MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL;
+ break;
++ case NS_THEME_INNER_SPIN_BUTTON:
++ aGtkWidgetType = MOZ_GTK_INNER_SPIN_BUTTON;
++ break;
+ case NS_THEME_SPINNER:
+ aGtkWidgetType = MOZ_GTK_SPINBUTTON;
+ break;
+@@ -1657,6 +1660,7 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
+ aResult->width = separator_width;
+ }
+ break;
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER:
+ // hard code these sizes
+ aResult->width = 14;
+@@ -1844,6 +1848,7 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
+ case NS_THEME_TAB_SCROLL_ARROW_BACK:
+ case NS_THEME_TAB_SCROLL_ARROW_FORWARD:
+ case NS_THEME_TOOLTIP:
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER:
+ case NS_THEME_SPINNER_UPBUTTON:
+ case NS_THEME_SPINNER_DOWNBUTTON:
+diff --git widget/windows/nsNativeThemeWin.cpp widget/windows/nsNativeThemeWin.cpp
+index 5bbdc3aacc1e..bd6f76ca3e52 100644
+--- widget/windows/nsNativeThemeWin.cpp
++++ widget/windows/nsNativeThemeWin.cpp
+@@ -682,6 +682,7 @@ nsresult nsNativeThemeWin::GetCachedMinimumWidgetSize(nsIFrame * aFrame, HANDLE
+ aResult->height = sz.cy;
+
+ switch (aWidgetType) {
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER_UPBUTTON:
+ case NS_THEME_SPINNER_DOWNBUTTON:
+ aResult->width++;
+@@ -766,6 +767,7 @@ mozilla::Maybe<nsUXThemeClass> nsNativeThemeWin::GetThemeClass(uint8_t aWidgetTy
+ case NS_THEME_SCALETHUMB_HORIZONTAL:
+ case NS_THEME_SCALETHUMB_VERTICAL:
+ return Some(eUXTrackbar);
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER_UPBUTTON:
+ case NS_THEME_SPINNER_DOWNBUTTON:
+ return Some(eUXSpin);
+@@ -1143,6 +1145,7 @@ nsNativeThemeWin::GetThemePartAndState(nsIFrame* aFrame, uint8_t aWidgetType,
+ }
+ return NS_OK;
+ }
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER_UPBUTTON:
+ case NS_THEME_SPINNER_DOWNBUTTON: {
+ aPart = (aWidgetType == NS_THEME_SPINNER_UPBUTTON) ?
+@@ -2718,6 +2721,7 @@ nsNativeThemeWin::ClassicThemeSupportsWidget(nsIFrame* aFrame,
+ case NS_THEME_SCALETHUMB_HORIZONTAL:
+ case NS_THEME_SCALETHUMB_VERTICAL:
+ case NS_THEME_MENULIST_BUTTON:
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER_UPBUTTON:
+ case NS_THEME_SPINNER_DOWNBUTTON:
+ case NS_THEME_LISTBOX:
+@@ -2873,6 +2877,7 @@ nsNativeThemeWin::ClassicGetMinimumWidgetSize(nsIFrame* aFrame,
+ (*aResult).width = ::GetSystemMetrics(SM_CXMENUCHECK);
+ (*aResult).height = ::GetSystemMetrics(SM_CYMENUCHECK);
+ break;
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER_UPBUTTON:
+ case NS_THEME_SPINNER_DOWNBUTTON:
+ (*aResult).width = ::GetSystemMetrics(SM_CXVSCROLL);
+@@ -3274,6 +3279,7 @@ nsresult nsNativeThemeWin::ClassicGetThemePartAndState(nsIFrame* aFrame, uint8_t
+
+ return NS_OK;
+ }
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER_UPBUTTON:
+ case NS_THEME_SPINNER_DOWNBUTTON: {
+ EventStates contentState = GetContentState(aFrame, aWidgetType);
+@@ -3283,6 +3289,7 @@ nsresult nsNativeThemeWin::ClassicGetThemePartAndState(nsIFrame* aFrame, uint8_t
+ case NS_THEME_SPINNER_UPBUTTON:
+ aState = DFCS_SCROLLUP;
+ break;
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER_DOWNBUTTON:
+ aState = DFCS_SCROLLDOWN;
+ break;
+@@ -3583,6 +3590,7 @@ RENDER_AGAIN:
+ case NS_THEME_SCROLLBARBUTTON_DOWN:
+ case NS_THEME_SCROLLBARBUTTON_LEFT:
+ case NS_THEME_SCROLLBARBUTTON_RIGHT:
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER_UPBUTTON:
+ case NS_THEME_SPINNER_DOWNBUTTON:
+ case NS_THEME_MENULIST_BUTTON:
+@@ -3987,6 +3995,7 @@ nsNativeThemeWin::GetWidgetNativeDrawingFlags(uint8_t aWidgetType)
+ case NS_THEME_SCALE_VERTICAL:
+ case NS_THEME_SCALETHUMB_HORIZONTAL:
+ case NS_THEME_SCALETHUMB_VERTICAL:
++ case NS_THEME_INNER_SPIN_BUTTON:
+ case NS_THEME_SPINNER_UPBUTTON:
+ case NS_THEME_SPINNER_DOWNBUTTON:
+ case NS_THEME_LISTBOX:
diff --git a/www/waterfox/files/patch-bug1425878 b/www/waterfox/files/patch-bug1425878
new file mode 100644
index 000000000000..df6ee9a62de0
--- /dev/null
+++ b/www/waterfox/files/patch-bug1425878
@@ -0,0 +1,46 @@
+commit 2aaf6edd31d6
+Author: Kartikaya Gupta <kgupta@mozilla.com>
+Date: Mon Dec 18 13:33:56 2017 -0500
+
+ Bug 1425878 - Don't expose raw pointers to refcounted vsync dispatcher object. r=sotaro
+
+ MozReview-Commit-ID: 5ywkZqfY8uZ
+
+ --HG--
+ extra : rebase_source : 3a887a5765fb0f7c2b5acdc8be94f3ea84199081
+---
+ widget/nsBaseWidget.cpp | 5 +++--
+ widget/nsBaseWidget.h | 2 +-
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git widget/nsBaseWidget.cpp widget/nsBaseWidget.cpp
+index e4ca5e011894..da7b7b259d8d 100644
+--- widget/nsBaseWidget.cpp
++++ widget/nsBaseWidget.cpp
+@@ -1255,10 +1255,11 @@ void nsBaseWidget::CreateCompositorVsyncDispatcher()
+ }
+ }
+
+-CompositorVsyncDispatcher*
++already_AddRefed<CompositorVsyncDispatcher>
+ nsBaseWidget::GetCompositorVsyncDispatcher()
+ {
+- return mCompositorVsyncDispatcher;
++ RefPtr<CompositorVsyncDispatcher> dispatcher = mCompositorVsyncDispatcher;
++ return dispatcher.forget();
+ }
+
+ already_AddRefed<LayerManager>
+diff --git widget/nsBaseWidget.h widget/nsBaseWidget.h
+index 3cb56f38b6ce..a7b648806bcc 100644
+--- widget/nsBaseWidget.h
++++ widget/nsBaseWidget.h
+@@ -209,7 +209,7 @@ public:
+ // returned.
+ void NotifyCompositorSessionLost(mozilla::layers::CompositorSession* aSession);
+
+- mozilla::CompositorVsyncDispatcher* GetCompositorVsyncDispatcher();
++ already_AddRefed<mozilla::CompositorVsyncDispatcher> GetCompositorVsyncDispatcher();
+ void CreateCompositorVsyncDispatcher();
+ virtual void CreateCompositor();
+ virtual void CreateCompositor(int aWidth, int aHeight);