www/waterfox: apply FF57 widget/ fixes

This commit is contained in:
Jan Beich 2018-02-26 18:56:14 +00:00
parent 7f8e3cc038
commit acf84331b4
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=463037
16 changed files with 3698 additions and 1 deletions

View File

@ -3,7 +3,7 @@
PORTNAME= waterfox
DISTVERSION= 56.0.4-20
DISTVERSIONSUFFIX= -ge03e284b083d
PORTREVISION= 1
PORTREVISION= 2
CATEGORIES= www ipv6
MAINTAINER= jbeich@FreeBSD.org

View File

@ -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));

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View File

@ -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, "_");

View File

@ -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;
}

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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:

View File

@ -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);