forked from mirrors/gecko-dev
Bug 1712669 - Make Windows tooltip margin depend on cursor size. r=yjuglaret,win-reviewers,desktop-theme-reviewers,dao
I think we should start off with this. Other platforms can implement this too, but exposing this to content seems like quite the rabbit hole. Differential Revision: https://phabricator.services.mozilla.com/D203405
This commit is contained in:
parent
50bd75fa63
commit
ade0599fdf
8 changed files with 49 additions and 10 deletions
|
|
@ -2186,6 +2186,12 @@ nsMargin nsMenuPopupFrame::GetMargin() const {
|
||||||
margin.left += auOffset.x;
|
margin.left += auOffset.x;
|
||||||
margin.right += auOffset.x;
|
margin.right += auOffset.x;
|
||||||
}
|
}
|
||||||
|
if (mPopupType == PopupType::Tooltip) {
|
||||||
|
const auto auOffset =
|
||||||
|
CSSPixel::ToAppUnits(LookAndFeel::TooltipOffsetVertical());
|
||||||
|
margin.top += auOffset;
|
||||||
|
margin.bottom += auOffset;
|
||||||
|
}
|
||||||
return margin;
|
return margin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ var gOriginalWidth = -1;
|
||||||
var gOriginalHeight = -1;
|
var gOriginalHeight = -1;
|
||||||
var gButton = null;
|
var gButton = null;
|
||||||
|
|
||||||
|
const kTooltipOffsetVertical = 10;
|
||||||
|
|
||||||
function runTest()
|
function runTest()
|
||||||
{
|
{
|
||||||
startPopupTests(popupTests);
|
startPopupTests(popupTests);
|
||||||
|
|
@ -112,7 +114,7 @@ var popupTests = [
|
||||||
Math.round(buttonrect.left + parseFloat(popupstyle.marginLeft) + 6),
|
Math.round(buttonrect.left + parseFloat(popupstyle.marginLeft) + 6),
|
||||||
testname + " left position of tooltip");
|
testname + " left position of tooltip");
|
||||||
is(Math.round(rect.top),
|
is(Math.round(rect.top),
|
||||||
Math.round(buttonrect.top + parseFloat(popupstyle.marginTop) + 6),
|
Math.round(buttonrect.top + parseFloat(popupstyle.marginTop) + 6 + kTooltipOffsetVertical),
|
||||||
testname + " top position of tooltip");
|
testname + " top position of tooltip");
|
||||||
|
|
||||||
var labelrect = document.getElementById("label").getBoundingClientRect();
|
var labelrect = document.getElementById("label").getBoundingClientRect();
|
||||||
|
|
@ -159,7 +161,7 @@ var popupTests = [
|
||||||
Math.round(buttonrect.left + parseFloat(popupstyle.marginLeft) + 4),
|
Math.round(buttonrect.left + parseFloat(popupstyle.marginLeft) + 4),
|
||||||
testname + " left position of tooltip");
|
testname + " left position of tooltip");
|
||||||
is(Math.round(rect.top),
|
is(Math.round(rect.top),
|
||||||
Math.round(buttonrect.top + parseFloat(popupstyle.marginTop) + 4),
|
Math.round(buttonrect.top + parseFloat(popupstyle.marginTop) + 4 + kTooltipOffsetVertical),
|
||||||
testname + " top position of tooltip");
|
testname + " top position of tooltip");
|
||||||
|
|
||||||
var labelrect = document.getElementById("label").getBoundingClientRect();
|
var labelrect = document.getElementById("label").getBoundingClientRect();
|
||||||
|
|
@ -204,7 +206,7 @@ var popupTests = [
|
||||||
Math.round(buttonrect.left + parseFloat(popupstyle.marginLeft) + 6),
|
Math.round(buttonrect.left + parseFloat(popupstyle.marginLeft) + 6),
|
||||||
testname + " left position of tooltip");
|
testname + " left position of tooltip");
|
||||||
is(Math.round(rect.top),
|
is(Math.round(rect.top),
|
||||||
Math.round(buttonrect.top + parseFloat(popupstyle.marginTop) + 6),
|
Math.round(buttonrect.top + parseFloat(popupstyle.marginTop) + 6 + kTooltipOffsetVertical),
|
||||||
testname + " top position of tooltip");
|
testname + " top position of tooltip");
|
||||||
|
|
||||||
var labelrect = document.getElementById("label").getBoundingClientRect();
|
var labelrect = document.getElementById("label").getBoundingClientRect();
|
||||||
|
|
@ -359,7 +361,14 @@ function moveWindowTo(x, y, callback, arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.arguments[0].SimpleTest.waitForFocus(runTest, window);
|
(async function() {
|
||||||
|
let parent = window.arguments[0];
|
||||||
|
await Promise.all([
|
||||||
|
parent.SimpleTest.promiseFocus(window),
|
||||||
|
parent.SpecialPowers.pushPrefEnv({set: [["ui.tooltipOffsetVertical", kTooltipOffsetVertical]]}),
|
||||||
|
]);
|
||||||
|
runTest();
|
||||||
|
})();
|
||||||
]]>
|
]]>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -389,10 +389,6 @@ tooltip {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
tooltip:not([position]) {
|
|
||||||
margin-top: 21px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It's important that these styles are in a UA sheet, because the default
|
* It's important that these styles are in a UA sheet, because the default
|
||||||
* tooltip is native anonymous content
|
* tooltip is native anonymous content
|
||||||
|
|
|
||||||
|
|
@ -186,6 +186,7 @@ class LookAndFeel {
|
||||||
*/
|
*/
|
||||||
ContextMenuOffsetVertical,
|
ContextMenuOffsetVertical,
|
||||||
ContextMenuOffsetHorizontal,
|
ContextMenuOffsetHorizontal,
|
||||||
|
TooltipOffsetVertical,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A boolean value indicating whether client-side decorations are
|
* A boolean value indicating whether client-side decorations are
|
||||||
|
|
@ -321,6 +322,11 @@ class LookAndFeel {
|
||||||
return GetInt(IntID::UseOverlayScrollbars);
|
return GetInt(IntID::UseOverlayScrollbars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr int32_t kDefaultTooltipOffset = 21;
|
||||||
|
static int32_t TooltipOffsetVertical() {
|
||||||
|
return GetInt(IntID::TooltipOffsetVertical, kDefaultTooltipOffset);
|
||||||
|
}
|
||||||
|
|
||||||
// Returns keyCode value of a modifier key which is used for accesskey.
|
// Returns keyCode value of a modifier key which is used for accesskey.
|
||||||
// Returns 0 if the platform doesn't support access key.
|
// Returns 0 if the platform doesn't support access key.
|
||||||
static uint32_t GetMenuAccessKey();
|
static uint32_t GetMenuAccessKey();
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,7 @@ static const char sIntPrefs[][45] = {
|
||||||
"ui.scrollbarFadeDuration",
|
"ui.scrollbarFadeDuration",
|
||||||
"ui.contextMenuOffsetVertical",
|
"ui.contextMenuOffsetVertical",
|
||||||
"ui.contextMenuOffsetHorizontal",
|
"ui.contextMenuOffsetHorizontal",
|
||||||
|
"ui.tooltipOffsetVertical",
|
||||||
"ui.GtkCSDAvailable",
|
"ui.GtkCSDAvailable",
|
||||||
"ui.GtkCSDMinimizeButton",
|
"ui.GtkCSDMinimizeButton",
|
||||||
"ui.GtkCSDMaximizeButton",
|
"ui.GtkCSDMaximizeButton",
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,17 @@ static int32_t GetSystemParam(long flag, int32_t def) {
|
||||||
return ::SystemParametersInfo(flag, 0, &value, 0) ? value : def;
|
return ::SystemParametersInfo(flag, 0, &value, 0) ? value : def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t GetTooltipOffsetVertical() {
|
||||||
|
static constexpr DWORD kDefaultCursorSize = 32;
|
||||||
|
const DWORD cursorSize =
|
||||||
|
GetSystemParam(MOZ_SPI_CURSORSIZE, kDefaultCursorSize);
|
||||||
|
if (cursorSize == kDefaultCursorSize) {
|
||||||
|
return LookAndFeel::kDefaultTooltipOffset;
|
||||||
|
}
|
||||||
|
return std::ceilf(float(LookAndFeel::kDefaultTooltipOffset) *
|
||||||
|
float(cursorSize) / float(kDefaultCursorSize));
|
||||||
|
}
|
||||||
|
|
||||||
static bool SystemWantsDarkTheme() {
|
static bool SystemWantsDarkTheme() {
|
||||||
if (nsUXThemeData::IsHighContrastOn()) {
|
if (nsUXThemeData::IsHighContrastOn()) {
|
||||||
return LookAndFeel::IsDarkColor(
|
return LookAndFeel::IsDarkColor(
|
||||||
|
|
@ -523,6 +534,9 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
|
||||||
case IntID::ContextMenuOffsetHorizontal:
|
case IntID::ContextMenuOffsetHorizontal:
|
||||||
aResult = 2;
|
aResult = 2;
|
||||||
break;
|
break;
|
||||||
|
case IntID::TooltipOffsetVertical:
|
||||||
|
aResult = GetTooltipOffsetVertical();
|
||||||
|
break;
|
||||||
case IntID::SystemUsesDarkTheme:
|
case IntID::SystemUsesDarkTheme:
|
||||||
aResult = SystemWantsDarkTheme();
|
aResult = SystemWantsDarkTheme();
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,10 @@
|
||||||
#define SYS_COLOR_MAX 30
|
#define SYS_COLOR_MAX 30
|
||||||
#define SYS_COLOR_COUNT (SYS_COLOR_MAX - SYS_COLOR_MIN + 1)
|
#define SYS_COLOR_COUNT (SYS_COLOR_MAX - SYS_COLOR_MIN + 1)
|
||||||
|
|
||||||
|
// Undocumented SPI, see bug 1712669 comment 4.
|
||||||
|
#define MOZ_SPI_CURSORSIZE 0x2028
|
||||||
|
#define MOZ_SPI_SETCURSORSIZE 0x2029
|
||||||
|
|
||||||
namespace mozilla::widget::WinRegistry {
|
namespace mozilla::widget::WinRegistry {
|
||||||
class KeyWatcher;
|
class KeyWatcher;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#include "mozilla/widget/WinMessages.h"
|
#include "mozilla/widget/WinMessages.h"
|
||||||
|
#include "nsLookAndFeel.h"
|
||||||
#include "nsWindow.h"
|
#include "nsWindow.h"
|
||||||
#include "nsWindowTaskbarConcealer.h"
|
#include "nsWindowTaskbarConcealer.h"
|
||||||
#include "nsAppRunner.h"
|
#include "nsAppRunner.h"
|
||||||
|
|
@ -4939,10 +4940,12 @@ bool nsWindow::ProcessMessageInternal(UINT msg, WPARAM& wParam, LPARAM& lParam,
|
||||||
|
|
||||||
case WM_SETTINGCHANGE: {
|
case WM_SETTINGCHANGE: {
|
||||||
if (wParam == SPI_SETCLIENTAREAANIMATION ||
|
if (wParam == SPI_SETCLIENTAREAANIMATION ||
|
||||||
wParam == SPI_SETKEYBOARDDELAY || wParam == SPI_SETMOUSEVANISH) {
|
wParam == SPI_SETKEYBOARDDELAY || wParam == SPI_SETMOUSEVANISH ||
|
||||||
|
wParam == MOZ_SPI_SETCURSORSIZE) {
|
||||||
// These need to update LookAndFeel cached values.
|
// These need to update LookAndFeel cached values.
|
||||||
// They affect reduced motion settings / caret blink count / show
|
// They affect reduced motion settings / caret blink count / show
|
||||||
// pointer while typing, so no need to invalidate style / layout.
|
// pointer while typing / tooltip offset, so no need to invalidate style
|
||||||
|
// / layout.
|
||||||
NotifyThemeChanged(widget::ThemeChangeKind::MediaQueriesOnly);
|
NotifyThemeChanged(widget::ThemeChangeKind::MediaQueriesOnly);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue