Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Feb 2018 18:56:14 +0000 (UTC)
From:      Jan Beich <jbeich@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r463037 - in head/www/waterfox: . files
Message-ID:  <201802261856.w1QIuEma014704@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jbeich
Date: Mon Feb 26 18:56:14 2018
New Revision: 463037
URL: https://svnweb.freebsd.org/changeset/ports/463037

Log:
  www/waterfox: apply FF57 widget/ fixes

Added:
  head/www/waterfox/files/patch-bug1036008   (contents, props changed)
  head/www/waterfox/files/patch-bug1134077   (contents, props changed)
  head/www/waterfox/files/patch-bug1314928   (contents, props changed)
  head/www/waterfox/files/patch-bug1360278   (contents, props changed)
  head/www/waterfox/files/patch-bug1381815   (contents, props changed)
  head/www/waterfox/files/patch-bug1387170   (contents, props changed)
  head/www/waterfox/files/patch-bug1396722   (contents, props changed)
  head/www/waterfox/files/patch-bug1398539   (contents, props changed)
  head/www/waterfox/files/patch-bug1399336   (contents, props changed)
  head/www/waterfox/files/patch-bug1400238   (contents, props changed)
  head/www/waterfox/files/patch-bug1400839   (contents, props changed)
  head/www/waterfox/files/patch-bug1401063   (contents, props changed)
  head/www/waterfox/files/patch-bug1407001   (contents, props changed)
  head/www/waterfox/files/patch-bug1417751   (contents, props changed)
  head/www/waterfox/files/patch-bug1425878   (contents, props changed)
Modified:
  head/www/waterfox/Makefile   (contents, props changed)

Modified: head/www/waterfox/Makefile
==============================================================================
--- head/www/waterfox/Makefile	Mon Feb 26 18:50:27 2018	(r463036)
+++ head/www/waterfox/Makefile	Mon Feb 26 18:56:14 2018	(r463037)
@@ -3,7 +3,7 @@
 PORTNAME=	waterfox
 DISTVERSION=	56.0.4-20
 DISTVERSIONSUFFIX=	-ge03e284b083d
-PORTREVISION=	1
+PORTREVISION=	2
 CATEGORIES=	www ipv6
 
 MAINTAINER=	jbeich@FreeBSD.org

Added: head/www/waterfox/files/patch-bug1036008
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/waterfox/files/patch-bug1036008	Mon Feb 26 18:56:14 2018	(r463037)
@@ -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));

Added: head/www/waterfox/files/patch-bug1134077
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/waterfox/files/patch-bug1134077	Mon Feb 26 18:56:14 2018	(r463037)
@@ -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;
+ 

Added: head/www/waterfox/files/patch-bug1314928
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/waterfox/files/patch-bug1314928	Mon Feb 26 18:56:14 2018	(r463037)
@@ -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

Added: head/www/waterfox/files/patch-bug1360278
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/waterfox/files/patch-bug1360278	Mon Feb 26 18:56:14 2018	(r463037)
@@ -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

Added: head/www/waterfox/files/patch-bug1381815
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/waterfox/files/patch-bug1381815	Mon Feb 26 18:56:14 2018	(r463037)
@@ -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 {

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802261856.w1QIuEma014704>