Backed out 5 changesets (bug 1930292, bug 1932600) for causing chrome failures at test_maximized_persist.xhtml on a CLOSED TREE
Backed out changeset 2418bfee53f1 (bug 1932600) Backed out changeset 3297e990715a (bug 1932600) Backed out changeset 24a670dea977 (bug 1930292) Backed out changeset 7dd9f48216dd (bug 1930292) Backed out changeset 15a85ec739dd (bug 1930292)
This commit is contained in:
@@ -120,8 +120,8 @@ addAccessibleTask(
|
|||||||
info("Showing title bar");
|
info("Showing title bar");
|
||||||
let titleBarChanged = BrowserTestUtils.waitForMutationCondition(
|
let titleBarChanged = BrowserTestUtils.waitForMutationCondition(
|
||||||
document.documentElement,
|
document.documentElement,
|
||||||
{ attributes: true, attributeFilter: ["customtitlebar"] },
|
{ attributes: true, attributeFilter: ["tabsintitlebar"] },
|
||||||
() => !document.documentElement.hasAttribute("customtitlebar")
|
() => !document.documentElement.hasAttribute("tabsintitlebar")
|
||||||
);
|
);
|
||||||
await SpecialPowers.pushPrefEnv({
|
await SpecialPowers.pushPrefEnv({
|
||||||
set: [["browser.tabs.inTitlebar", false]],
|
set: [["browser.tabs.inTitlebar", false]],
|
||||||
|
|||||||
@@ -102,13 +102,12 @@ var gBrowserInit = {
|
|||||||
toolbarMenubar.setAttribute("data-l10n-attrs", "toolbarname");
|
toolbarMenubar.setAttribute("data-l10n-attrs", "toolbarname");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run menubar initialization first, to avoid CustomTitlebar code picking
|
// Run menubar initialization first, to avoid TabsInTitlebar code picking
|
||||||
// up mutations from it and causing a reflow.
|
// up mutations from it and causing a reflow.
|
||||||
AutoHideMenubar.init();
|
AutoHideMenubar.init();
|
||||||
// Update the customtitlebar attribute so the window can be sized
|
// Update the chromemargin attribute so the window can be sized correctly.
|
||||||
// correctly.
|
|
||||||
window.TabBarVisibility.update();
|
window.TabBarVisibility.update();
|
||||||
CustomTitlebar.init();
|
TabsInTitlebar.init();
|
||||||
|
|
||||||
new LightweightThemeConsumer(document);
|
new LightweightThemeConsumer(document);
|
||||||
|
|
||||||
@@ -1025,7 +1024,7 @@ var gBrowserInit = {
|
|||||||
onUnload() {
|
onUnload() {
|
||||||
gUIDensity.uninit();
|
gUIDensity.uninit();
|
||||||
|
|
||||||
CustomTitlebar.uninit();
|
TabsInTitlebar.uninit();
|
||||||
|
|
||||||
ToolbarIconColor.uninit();
|
ToolbarIconColor.uninit();
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
var CustomTitlebar = {
|
var TabsInTitlebar = {
|
||||||
init() {
|
init() {
|
||||||
this._readPref();
|
this._readPref();
|
||||||
Services.prefs.addObserver(this._prefName, this);
|
Services.prefs.addObserver(this._prefName, this);
|
||||||
@@ -40,7 +40,7 @@ var CustomTitlebar = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
get enabled() {
|
get enabled() {
|
||||||
return document.documentElement.hasAttribute("customtitlebar");
|
return document.documentElement.getAttribute("tabsintitlebar") == "true";
|
||||||
},
|
},
|
||||||
|
|
||||||
observe(subject, topic) {
|
observe(subject, topic) {
|
||||||
@@ -67,13 +67,23 @@ var CustomTitlebar = {
|
|||||||
this.systemSupported &&
|
this.systemSupported &&
|
||||||
!window.fullScreen &&
|
!window.fullScreen &&
|
||||||
!Object.keys(this._disallowed).length;
|
!Object.keys(this._disallowed).length;
|
||||||
|
if (allowed) {
|
||||||
document.documentElement.toggleAttribute("customtitlebar", allowed);
|
document.documentElement.setAttribute("tabsintitlebar", "true");
|
||||||
if (AppConstants.platform == "macosx") {
|
if (AppConstants.platform == "macosx") {
|
||||||
document.documentElement.toggleAttribute("drawtitle", !allowed);
|
document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
|
||||||
|
document.documentElement.removeAttribute("drawtitle");
|
||||||
|
} else {
|
||||||
|
document.documentElement.setAttribute("chromemargin", "0,2,2,2");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
document.documentElement.removeAttribute("tabsintitlebar");
|
||||||
|
document.documentElement.removeAttribute("chromemargin");
|
||||||
|
if (AppConstants.platform == "macosx") {
|
||||||
|
document.documentElement.setAttribute("drawtitle", "true");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolbarIconColor.inferFromText("customtitlebar", allowed);
|
ToolbarIconColor.inferFromText("tabsintitlebar", allowed);
|
||||||
TabBarVisibility.update(true);
|
TabBarVisibility.update(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -6642,7 +6642,7 @@ var ToolbarIconColor = {
|
|||||||
_windowState: {
|
_windowState: {
|
||||||
active: false,
|
active: false,
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
customtitlebar: false,
|
tabsintitlebar: false,
|
||||||
},
|
},
|
||||||
init() {
|
init() {
|
||||||
this._initialized = true;
|
this._initialized = true;
|
||||||
@@ -6709,8 +6709,8 @@ var ToolbarIconColor = {
|
|||||||
case "toolbarvisibilitychange":
|
case "toolbarvisibilitychange":
|
||||||
// toolbar changes dont require reset of the cached color values
|
// toolbar changes dont require reset of the cached color values
|
||||||
break;
|
break;
|
||||||
case "customtitlebar":
|
case "tabsintitlebar":
|
||||||
this._windowState.customtitlebar = reasonValue;
|
this._windowState.tabsintitlebar = reasonValue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,12 @@
|
|||||||
#endif
|
#endif
|
||||||
data-l10n-args="{"content-title":"CONTENTTITLE"}"
|
data-l10n-args="{"content-title":"CONTENTTITLE"}"
|
||||||
data-l10n-attrs="data-content-title-default, data-content-title-private, data-title-default, data-title-private"
|
data-l10n-attrs="data-content-title-default, data-content-title-private, data-title-default, data-title-private"
|
||||||
customtitlebar="true"
|
#ifdef XP_WIN
|
||||||
|
chromemargin="0,2,2,2"
|
||||||
|
#else
|
||||||
|
chromemargin="0,-1,-1,-1"
|
||||||
|
#endif
|
||||||
|
tabsintitlebar="true"
|
||||||
windowtype="navigator:browser"
|
windowtype="navigator:browser"
|
||||||
macanimationtype="document"
|
macanimationtype="document"
|
||||||
macnativefullscreen="true"
|
macnativefullscreen="true"
|
||||||
@@ -113,7 +118,7 @@
|
|||||||
}
|
}
|
||||||
Services.scriptloader.loadSubScript("chrome://browser/content/browser-pageActions.js", this);
|
Services.scriptloader.loadSubScript("chrome://browser/content/browser-pageActions.js", this);
|
||||||
Services.scriptloader.loadSubScript("chrome://browser/content/sidebar/browser-sidebar.js", this);
|
Services.scriptloader.loadSubScript("chrome://browser/content/sidebar/browser-sidebar.js", this);
|
||||||
Services.scriptloader.loadSubScript("chrome://browser/content/browser-customtitlebar.js", this);
|
Services.scriptloader.loadSubScript("chrome://browser/content/browser-tabsintitlebar.js", this);
|
||||||
Services.scriptloader.loadSubScript("chrome://browser/content/browser-unified-extensions.js", this);
|
Services.scriptloader.loadSubScript("chrome://browser/content/browser-unified-extensions.js", this);
|
||||||
Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser/tab.js", this);
|
Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser/tab.js", this);
|
||||||
Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser/tabbrowser.js", this);
|
Services.scriptloader.loadSubScript("chrome://browser/content/tabbrowser/tabbrowser.js", this);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
windowtype="Browser:page-info"
|
windowtype="Browser:page-info"
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
drawtitle="true"
|
drawtitle="true"
|
||||||
customtitlebar="true"
|
chromemargin="0,0,0,0"
|
||||||
#endif
|
#endif
|
||||||
onload="onLoadPageInfo()"
|
onload="onLoadPageInfo()"
|
||||||
align="stretch"
|
align="stretch"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
id="webrtcIndicator"
|
id="webrtcIndicator"
|
||||||
windowtype="Browser:WebRTCGlobalIndicator"
|
windowtype="Browser:WebRTCGlobalIndicator"
|
||||||
customtitlebar="true"
|
chromemargin="0,0,0,0"
|
||||||
>
|
>
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="chrome://global/skin/global.css" />
|
<link rel="stylesheet" href="chrome://global/skin/global.css" />
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ browser.jar:
|
|||||||
content/browser/browser-sitePermissionPanel.js (content/browser-sitePermissionPanel.js)
|
content/browser/browser-sitePermissionPanel.js (content/browser-sitePermissionPanel.js)
|
||||||
content/browser/browser-siteProtections.js (content/browser-siteProtections.js)
|
content/browser/browser-siteProtections.js (content/browser-siteProtections.js)
|
||||||
content/browser/browser-sync.js (content/browser-sync.js)
|
content/browser/browser-sync.js (content/browser-sync.js)
|
||||||
content/browser/browser-customtitlebar.js (content/browser-customtitlebar.js)
|
content/browser/browser-tabsintitlebar.js (content/browser-tabsintitlebar.js)
|
||||||
content/browser/browser-toolbarKeyNav.js (content/browser-toolbarKeyNav.js)
|
content/browser/browser-toolbarKeyNav.js (content/browser-toolbarKeyNav.js)
|
||||||
content/browser/browser-thumbnails.js (content/browser-thumbnails.js)
|
content/browser/browser-thumbnails.js (content/browser-thumbnails.js)
|
||||||
content/browser/browser-unified-extensions.js (content/browser-unified-extensions.js)
|
content/browser/browser-unified-extensions.js (content/browser-unified-extensions.js)
|
||||||
|
|||||||
@@ -1822,7 +1822,7 @@ BrowserGlue.prototype = {
|
|||||||
// Hide the titlebar if the actual browser window will draw in it.
|
// Hide the titlebar if the actual browser window will draw in it.
|
||||||
let hiddenTitlebar = Services.appinfo.drawInTitlebar;
|
let hiddenTitlebar = Services.appinfo.drawInTitlebar;
|
||||||
if (hiddenTitlebar) {
|
if (hiddenTitlebar) {
|
||||||
win.windowUtils.setCustomTitlebar(true);
|
win.windowUtils.setChromeMargin(0, 2, 2, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
let docElt = win.document.documentElement;
|
let docElt = win.document.documentElement;
|
||||||
|
|||||||
@@ -1674,7 +1674,7 @@ CustomizeMode.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_canDrawInTitlebar() {
|
_canDrawInTitlebar() {
|
||||||
return this.window.CustomTitlebar.systemSupported;
|
return this.window.TabsInTitlebar.systemSupported;
|
||||||
},
|
},
|
||||||
|
|
||||||
_ensureCustomizationPanels() {
|
_ensureCustomizationPanels() {
|
||||||
|
|||||||
@@ -143,9 +143,9 @@ add_task(async function () {
|
|||||||
// Bug 971626 - Restore Defaults should collapse the Title Bar
|
// Bug 971626 - Restore Defaults should collapse the Title Bar
|
||||||
add_task(async function () {
|
add_task(async function () {
|
||||||
{
|
{
|
||||||
const supported = CustomTitlebar.systemSupported;
|
const supported = TabsInTitlebar.systemSupported;
|
||||||
is(typeof supported, "boolean");
|
is(typeof supported, "boolean");
|
||||||
info("CustomTitlebar support: " + supported);
|
info("TabsInTitlebar support: " + supported);
|
||||||
if (!supported) {
|
if (!supported) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ add_task(async function tabstrip_context() {
|
|||||||
// Right-click on the title bar spacer before the tabstrip should show a
|
// Right-click on the title bar spacer before the tabstrip should show a
|
||||||
// context menu without options to move it and no tab-specific options.
|
// context menu without options to move it and no tab-specific options.
|
||||||
add_task(async function titlebar_spacer_context() {
|
add_task(async function titlebar_spacer_context() {
|
||||||
if (!CustomTitlebar.enabled) {
|
if (!TabsInTitlebar.enabled) {
|
||||||
info("Skipping test that requires tabs in the title bar.");
|
info("Skipping test that requires tabs in the title bar.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
screenX="10" screenY="10"
|
screenX="10" screenY="10"
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
drawtitle="true"
|
drawtitle="true"
|
||||||
customtitlebar="true"
|
chromemargin="0,0,0,0"
|
||||||
#endif
|
#endif
|
||||||
toggletoolbar="true"
|
toggletoolbar="true"
|
||||||
persist="width height screenX screenY sizemode">
|
persist="width height screenX screenY sizemode">
|
||||||
|
|||||||
@@ -46,13 +46,13 @@ function getExpectedElements(win, tabstripOrientation = "horizontal") {
|
|||||||
const sizeMode = win.document.documentElement.getAttribute("sizemode");
|
const sizeMode = win.document.documentElement.getAttribute("sizemode");
|
||||||
let selectors;
|
let selectors;
|
||||||
|
|
||||||
// NOTE: CustomTitlebar behaviour isn't under test here. We just want to assert on
|
// NOTE: TabsInTitlebar behaviour isn't under test here. We just want to assert on
|
||||||
// the right stuff being visible whatever the case for the given window.
|
// the right stuff being visible whatever the case for the given window.
|
||||||
|
|
||||||
if (tabstripOrientation == "horizontal") {
|
if (tabstripOrientation == "horizontal") {
|
||||||
selectors = ["#TabsToolbar"];
|
selectors = ["#TabsToolbar"];
|
||||||
|
|
||||||
if (win.CustomTitlebar.enabled) {
|
if (win.TabsInTitlebar.enabled) {
|
||||||
selectors.push("#TabsToolbar .titlebar-buttonbox-container");
|
selectors.push("#TabsToolbar .titlebar-buttonbox-container");
|
||||||
if (sizeMode == "normal") {
|
if (sizeMode == "normal") {
|
||||||
selectors.push("#TabsToolbar .titlebar-spacer");
|
selectors.push("#TabsToolbar .titlebar-spacer");
|
||||||
@@ -62,7 +62,7 @@ function getExpectedElements(win, tabstripOrientation = "horizontal") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
selectors = ["#vertical-tabs"];
|
selectors = ["#vertical-tabs"];
|
||||||
if (win.CustomTitlebar.enabled) {
|
if (win.TabsInTitlebar.enabled) {
|
||||||
selectors.push("#nav-bar .titlebar-buttonbox-container");
|
selectors.push("#nav-bar .titlebar-buttonbox-container");
|
||||||
if (sizeMode == "normal") {
|
if (sizeMode == "normal") {
|
||||||
selectors.push("#nav-bar .titlebar-spacer[type='post-tabs']");
|
selectors.push("#nav-bar .titlebar-spacer[type='post-tabs']");
|
||||||
@@ -89,7 +89,7 @@ add_task(async function test_toggle_vertical_tabs() {
|
|||||||
);
|
);
|
||||||
info(`sizemode: ${document.documentElement.getAttribute("sizemode")}`);
|
info(`sizemode: ${document.documentElement.getAttribute("sizemode")}`);
|
||||||
info(
|
info(
|
||||||
`customtitlebar: ${document.documentElement.getAttribute("customtitlebar")}`
|
`tabsintitlebar: ${document.documentElement.getAttribute("tabsintitlebar")}`
|
||||||
);
|
);
|
||||||
|
|
||||||
const expectedElementsWhenHorizontal = getExpectedElements(
|
const expectedElementsWhenHorizontal = getExpectedElements(
|
||||||
|
|||||||
@@ -8089,28 +8089,28 @@ var TabBarVisibility = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nonPopupWithVerticalTabs) {
|
if (nonPopupWithVerticalTabs) {
|
||||||
// CustomTitlebar decides if we can draw within the titlebar area.
|
// TabsInTitlebar decides if we can draw within the titlebar area.
|
||||||
// In vertical tabs mode, the toolbar with the horizontal tabstrip gets hidden
|
// In vertical tabs mode, the toolbar with the horizontal tabstrip gets hidden
|
||||||
// and the navbar becomes a titlebar. This makes CustomTitlebar a bit of a misnomer.
|
// and the navbar becomes a titlebar. This makes TabsInTitlebar a bit of a misnomer.
|
||||||
// We'll fix this in Bug 1921034.
|
// We'll fix this in Bug 1921034.
|
||||||
hideTabstrip = true;
|
hideTabstrip = true;
|
||||||
CustomTitlebar.allowedBy("tabs-visible", true);
|
TabsInTitlebar.allowedBy("tabs-visible", true);
|
||||||
} else {
|
} else {
|
||||||
CustomTitlebar.allowedBy("tabs-visible", !hideTabstrip);
|
TabsInTitlebar.allowedBy("tabs-visible", !hideTabstrip);
|
||||||
}
|
}
|
||||||
|
|
||||||
gNavToolbox.toggleAttribute("tabs-hidden", hideTabstrip);
|
gNavToolbox.toggleAttribute("tabs-hidden", hideTabstrip);
|
||||||
// Should the nav-bar look and function like a titlebar?
|
// Should the nav-bar look and function like a titlebar?
|
||||||
navbar.classList.toggle(
|
navbar.classList.toggle(
|
||||||
"browser-titlebar",
|
"browser-titlebar",
|
||||||
CustomTitlebar.enabled && hideTabstrip
|
TabsInTitlebar.enabled && hideTabstrip
|
||||||
);
|
);
|
||||||
|
|
||||||
document
|
document
|
||||||
.getElementById("browser")
|
.getElementById("browser")
|
||||||
.classList.toggle(
|
.classList.toggle(
|
||||||
"browser-toolbox-background",
|
"browser-toolbox-background",
|
||||||
CustomTitlebar.enabled && nonPopupWithVerticalTabs
|
TabsInTitlebar.enabled && nonPopupWithVerticalTabs
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -344,7 +344,7 @@
|
|||||||
// When the tabbar has an unified appearance with the titlebar
|
// When the tabbar has an unified appearance with the titlebar
|
||||||
// and menubar, a double-click in it should have the same behavior
|
// and menubar, a double-click in it should have the same behavior
|
||||||
// as double-clicking the titlebar
|
// as double-clicking the titlebar
|
||||||
if (CustomTitlebar.enabled && !this.verticalMode) {
|
if (TabsInTitlebar.enabled && !this.verticalMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
* (in X11) or the compositor (in Wayland) does draw the shadow corners
|
* (in X11) or the compositor (in Wayland) does draw the shadow corners
|
||||||
* already.
|
* already.
|
||||||
*/
|
*/
|
||||||
:root[customtitlebar] {
|
:root[tabsintitlebar] {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
||||||
&[sizemode="normal"]:not([gtktiledwindow="true"]) {
|
&[sizemode="normal"]:not([gtktiledwindow="true"]) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
--toolbox-bgcolor-inactive: -moz-headerbarinactive;
|
--toolbox-bgcolor-inactive: -moz-headerbarinactive;
|
||||||
--toolbox-textcolor-inactive: -moz-headerbarinactivetext;
|
--toolbox-textcolor-inactive: -moz-headerbarinactivetext;
|
||||||
|
|
||||||
&:where([customtitlebar]) {
|
&:where([tabsintitlebar]) {
|
||||||
--toolbox-bgcolor: ActiveCaption;
|
--toolbox-bgcolor: ActiveCaption;
|
||||||
--toolbox-textcolor: CaptionText;
|
--toolbox-textcolor: CaptionText;
|
||||||
--toolbox-bgcolor-inactive: InactiveCaption;
|
--toolbox-bgcolor-inactive: InactiveCaption;
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
--toolbox-textcolor: light-dark(rgb(21, 20, 26), rgb(251, 251, 254));
|
--toolbox-textcolor: light-dark(rgb(21, 20, 26), rgb(251, 251, 254));
|
||||||
--toolbox-bgcolor-inactive: var(--toolbox-bgcolor);
|
--toolbox-bgcolor-inactive: var(--toolbox-bgcolor);
|
||||||
--toolbox-textcolor-inactive: var(--toolbox-textcolor);
|
--toolbox-textcolor-inactive: var(--toolbox-textcolor);
|
||||||
&:where([customtitlebar]) {
|
&:where([tabsintitlebar]) {
|
||||||
--toolbox-bgcolor-inactive: light-dark(rgb(235, 235, 239), rgb(31, 30, 37));
|
--toolbox-bgcolor-inactive: light-dark(rgb(235, 235, 239), rgb(31, 30, 37));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ body {
|
|||||||
@media (-moz-platform: macos) and (-moz-bool-pref: "browser.theme.native-theme") {
|
@media (-moz-platform: macos) and (-moz-bool-pref: "browser.theme.native-theme") {
|
||||||
/* Don't make the toolbox vibrant when in full-screen. macOS fullscreen has a
|
/* Don't make the toolbox vibrant when in full-screen. macOS fullscreen has a
|
||||||
* native titlebar outside of the window (revealed on hover) anyways. */
|
* native titlebar outside of the window (revealed on hover) anyways. */
|
||||||
:root[customtitlebar]:not([lwtheme], [macOSNativeFullscreen]) & {
|
:root[tabsintitlebar]:not([lwtheme], [macOSNativeFullscreen]) & {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
||||||
/* This is conceptually a background, but putting this on a
|
/* This is conceptually a background, but putting this on a
|
||||||
@@ -233,8 +233,8 @@ body {
|
|||||||
.browser-titlebar {
|
.browser-titlebar {
|
||||||
-moz-window-dragging: drag;
|
-moz-window-dragging: drag;
|
||||||
|
|
||||||
:root[customtitlebar] &,
|
:root[tabsintitlebar] &,
|
||||||
:root[customtitlebar] & #urlbar:popover-open {
|
:root[tabsintitlebar] & #urlbar:popover-open {
|
||||||
will-change: opacity;
|
will-change: opacity;
|
||||||
transition: opacity var(--inactive-window-transition);
|
transition: opacity var(--inactive-window-transition);
|
||||||
|
|
||||||
@@ -263,14 +263,14 @@ body {
|
|||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root:not([customtitlebar], [inFullscreen]) & {
|
:root:not([chromemargin], [inFullscreen]) & {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.titlebar-spacer {
|
.titlebar-spacer {
|
||||||
:root[inFullscreen] &,
|
:root[inFullscreen] &,
|
||||||
:root:not([customtitlebar]) & {
|
:root:not([tabsintitlebar]) & {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,7 +317,7 @@ body {
|
|||||||
-moz-default-appearance: -moz-window-button-box;
|
-moz-default-appearance: -moz-window-button-box;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
:root:not([customtitlebar], [sizemode=fullscreen]) & {
|
:root:not([tabsintitlebar], [sizemode=fullscreen]) & {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -332,12 +332,12 @@ body {
|
|||||||
as tall as the tab toolbar such that the window controls don't appear to move up.
|
as tall as the tab toolbar such that the window controls don't appear to move up.
|
||||||
For MacOS, autohide is never true on the menubar.
|
For MacOS, autohide is never true on the menubar.
|
||||||
*/
|
*/
|
||||||
:root[customtitlebar] #navigator-toolbox:not([tabs-hidden]) > & {
|
:root[tabsintitlebar] #navigator-toolbox:not([tabs-hidden]) > & {
|
||||||
min-height: var(--tabstrip-min-height);
|
min-height: var(--tabstrip-min-height);
|
||||||
}
|
}
|
||||||
/* adjust the height of the auto-hiding toolbar menubar when the tabstrip is
|
/* adjust the height of the auto-hiding toolbar menubar when the tabstrip is
|
||||||
hidden and we need to match the height of the nav-bar. */
|
hidden and we need to match the height of the nav-bar. */
|
||||||
:root[customtitlebar] #navigator-toolbox[tabs-hidden] > & {
|
:root[tabsintitlebar] #navigator-toolbox[tabs-hidden] > & {
|
||||||
min-height: calc(var(--urlbar-min-height) + 2 * var(--urlbar-padding-block));
|
min-height: calc(var(--urlbar-min-height) + 2 * var(--urlbar-padding-block));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (-moz-windows-accent-color-in-titlebar) or (-moz-windows-mica) {
|
@media (-moz-windows-accent-color-in-titlebar) or (-moz-windows-mica) {
|
||||||
:root[customtitlebar] {
|
:root[tabsintitlebar] {
|
||||||
@media (-moz-windows-mica) {
|
@media (-moz-windows-mica) {
|
||||||
&:not([lwtheme]) {
|
&:not([lwtheme]) {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|||||||
@@ -368,7 +368,7 @@ export var TestRunner = {
|
|||||||
|
|
||||||
this.mochitestScope.info("called " + config.name);
|
this.mochitestScope.info("called " + config.name);
|
||||||
// Add a default timeout of 700ms to avoid conflicts when configurations
|
// Add a default timeout of 700ms to avoid conflicts when configurations
|
||||||
// try to apply at the same time. e.g WindowSize and CustomTitlebar
|
// try to apply at the same time. e.g WindowSize and TabsInTitlebar
|
||||||
return Promise.race([applyPromise, timeoutPromise]).then(result => {
|
return Promise.race([applyPromise, timeoutPromise]).then(result => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
setTimeout(() => resolve(result), 700);
|
setTimeout(() => resolve(result), 700);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
const PREF_TABS_IN_TITLEBAR = "browser.tabs.inTitlebar";
|
const PREF_TABS_IN_TITLEBAR = "browser.tabs.inTitlebar";
|
||||||
|
|
||||||
export var CustomTitlebar = {
|
export var TabsInTitlebar = {
|
||||||
init() {},
|
init() {},
|
||||||
|
|
||||||
configurations: {
|
configurations: {
|
||||||
@@ -24,12 +24,12 @@ FINAL_TARGET_FILES.resources.configurations += [
|
|||||||
"configurations/Buttons.sys.mjs",
|
"configurations/Buttons.sys.mjs",
|
||||||
"configurations/ControlCenter.sys.mjs",
|
"configurations/ControlCenter.sys.mjs",
|
||||||
"configurations/CustomizeMode.sys.mjs",
|
"configurations/CustomizeMode.sys.mjs",
|
||||||
"configurations/CustomTitlebar.sys.mjs",
|
|
||||||
"configurations/DevTools.sys.mjs",
|
"configurations/DevTools.sys.mjs",
|
||||||
"configurations/LightweightThemes.sys.mjs",
|
"configurations/LightweightThemes.sys.mjs",
|
||||||
"configurations/PermissionPrompts.sys.mjs",
|
"configurations/PermissionPrompts.sys.mjs",
|
||||||
"configurations/Preferences.sys.mjs",
|
"configurations/Preferences.sys.mjs",
|
||||||
"configurations/Tabs.sys.mjs",
|
"configurations/Tabs.sys.mjs",
|
||||||
|
"configurations/TabsInTitlebar.sys.mjs",
|
||||||
"configurations/Toolbars.sys.mjs",
|
"configurations/Toolbars.sys.mjs",
|
||||||
"configurations/UIDensities.sys.mjs",
|
"configurations/UIDensities.sys.mjs",
|
||||||
"configurations/WindowSize.sys.mjs",
|
"configurations/WindowSize.sys.mjs",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ add_task(async function capture() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let sets = [
|
let sets = [
|
||||||
"CustomTitlebar",
|
"TabsInTitlebar",
|
||||||
"Tabs",
|
"Tabs",
|
||||||
"WindowSize",
|
"WindowSize",
|
||||||
"Toolbars",
|
"Toolbars",
|
||||||
|
|||||||
@@ -1819,6 +1819,50 @@ bool nsContentUtils::IsHTMLBlockLevelElement(nsIContent* aContent) {
|
|||||||
nsGkAtoms::ul, nsGkAtoms::xmp);
|
nsGkAtoms::ul, nsGkAtoms::xmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
bool nsContentUtils::ParseIntMarginValue(const nsAString& aString,
|
||||||
|
nsIntMargin& result) {
|
||||||
|
nsAutoString marginStr(aString);
|
||||||
|
marginStr.CompressWhitespace(true, true);
|
||||||
|
if (marginStr.IsEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t start = 0, end = 0;
|
||||||
|
for (int count = 0; count < 4; count++) {
|
||||||
|
if ((uint32_t)end >= marginStr.Length()) return false;
|
||||||
|
|
||||||
|
// top, right, bottom, left
|
||||||
|
if (count < 3)
|
||||||
|
end = Substring(marginStr, start).FindChar(',');
|
||||||
|
else
|
||||||
|
end = Substring(marginStr, start).Length();
|
||||||
|
|
||||||
|
if (end <= 0) return false;
|
||||||
|
|
||||||
|
nsresult ec;
|
||||||
|
int32_t val = nsString(Substring(marginStr, start, end)).ToInteger(&ec);
|
||||||
|
if (NS_FAILED(ec)) return false;
|
||||||
|
|
||||||
|
switch (count) {
|
||||||
|
case 0:
|
||||||
|
result.top = val;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
result.right = val;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result.bottom = val;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result.left = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
start += end + 1;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
int32_t nsContentUtils::ParseLegacyFontSize(const nsAString& aValue) {
|
int32_t nsContentUtils::ParseLegacyFontSize(const nsAString& aValue) {
|
||||||
nsAString::const_iterator iter, end;
|
nsAString::const_iterator iter, end;
|
||||||
|
|||||||
@@ -874,6 +874,17 @@ class nsContentUtils {
|
|||||||
ParseHTMLIntegerResultFlags* aResult);
|
ParseHTMLIntegerResultFlags* aResult);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Parse a margin string of format 'top, right, bottom, left' into
|
||||||
|
* an nsIntMargin.
|
||||||
|
*
|
||||||
|
* @param aString the string to parse
|
||||||
|
* @param aResult the resulting integer
|
||||||
|
* @return whether the value could be parsed
|
||||||
|
*/
|
||||||
|
static bool ParseIntMarginValue(const nsAString& aString,
|
||||||
|
nsIntMargin& aResult);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the value of the <font size=""> attribute according to the HTML5
|
* Parse the value of the <font size=""> attribute according to the HTML5
|
||||||
* spec as of April 16, 2012.
|
* spec as of April 16, 2012.
|
||||||
|
|||||||
@@ -4192,27 +4192,32 @@ nsDOMWindowUtils::PostRestyleSelfEvent(Element* aElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMWindowUtils::SetCustomTitlebar(bool aCustomTitlebar) {
|
nsDOMWindowUtils::SetChromeMargin(int32_t aTop, int32_t aRight, int32_t aBottom,
|
||||||
// TODO(emilio): Can't we use nsDOMWindowUtils::GetWidget()?
|
int32_t aLeft) {
|
||||||
if (nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow)) {
|
nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
|
||||||
if (nsCOMPtr<nsIBaseWindow> baseWindow =
|
if (window) {
|
||||||
do_QueryInterface(window->GetDocShell())) {
|
nsCOMPtr<nsIBaseWindow> baseWindow =
|
||||||
|
do_QueryInterface(window->GetDocShell());
|
||||||
|
if (baseWindow) {
|
||||||
nsCOMPtr<nsIWidget> widget;
|
nsCOMPtr<nsIWidget> widget;
|
||||||
baseWindow->GetMainWidget(getter_AddRefs(widget));
|
baseWindow->GetMainWidget(getter_AddRefs(widget));
|
||||||
if (widget) {
|
if (widget) {
|
||||||
widget->SetCustomTitlebar(aCustomTitlebar);
|
LayoutDeviceIntMargin margins(aTop, aRight, aBottom, aLeft);
|
||||||
|
return widget->SetNonClientMargins(margins);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMWindowUtils::SetResizeMargin(int32_t aResizeMargin) {
|
nsDOMWindowUtils::SetResizeMargin(int32_t aResizeMargin) {
|
||||||
// TODO(emilio): Can't we use nsDOMWindowUtils::GetWidget()?
|
nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
|
||||||
if (nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow)) {
|
if (window) {
|
||||||
if (nsCOMPtr<nsIBaseWindow> baseWindow =
|
nsCOMPtr<nsIBaseWindow> baseWindow =
|
||||||
do_QueryInterface(window->GetDocShell())) {
|
do_QueryInterface(window->GetDocShell());
|
||||||
|
if (baseWindow) {
|
||||||
nsCOMPtr<nsIWidget> widget;
|
nsCOMPtr<nsIWidget> widget;
|
||||||
baseWindow->GetMainWidget(getter_AddRefs(widget));
|
baseWindow->GetMainWidget(getter_AddRefs(widget));
|
||||||
if (widget) {
|
if (widget) {
|
||||||
|
|||||||
@@ -2053,11 +2053,14 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||||||
readonly attribute boolean refreshDriverHasPendingTick;
|
readonly attribute boolean refreshDriverHasPendingTick;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls whether we paint to the titlebar of the window.
|
* Controls the amount of chrome that should be visible on each side of
|
||||||
* Works like the customtitlebar xul:window attribute.
|
* the window. Works like the chromemargin xul:window attribute.
|
||||||
* This should only be used with non-XUL windows.
|
* This should only be used with non-XUL windows.
|
||||||
*/
|
*/
|
||||||
void setCustomTitlebar(in boolean aCustomTitlebar);
|
void setChromeMargin(in int32_t aTop,
|
||||||
|
in int32_t aRight,
|
||||||
|
in int32_t aBottom,
|
||||||
|
in int32_t aLeft);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the amount of space on each edge of the window that can be
|
* Controls the amount of space on each edge of the window that can be
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ void ChromeObserver::Init() {
|
|||||||
for (uint32_t i = 0; i < attributeCount; i++) {
|
for (uint32_t i = 0; i < attributeCount; i++) {
|
||||||
BorrowedAttrInfo info = rootElement->GetAttrInfoAt(i);
|
BorrowedAttrInfo info = rootElement->GetAttrInfoAt(i);
|
||||||
const nsAttrName* name = info.mName;
|
const nsAttrName* name = info.mName;
|
||||||
if (name->LocalName() == nsGkAtoms::customtitlebar) {
|
if (name->LocalName() == nsGkAtoms::chromemargin) {
|
||||||
// Some linux windows managers have an issue when the customtitlebar is
|
// Some linux windows managers have an issue when the chrome margin is
|
||||||
// applied while the browser is loading (bug 1598848). For now, skip
|
// applied while the browser is loading (bug 1598848). For now, skip
|
||||||
// applying this attribute when initializing.
|
// applying this attribute when initializing.
|
||||||
continue;
|
continue;
|
||||||
@@ -73,6 +73,43 @@ void ChromeObserver::SetDrawsTitle(bool aState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MarginSetter : public Runnable {
|
||||||
|
public:
|
||||||
|
explicit MarginSetter(nsIWidget* aWidget)
|
||||||
|
: mozilla::Runnable("MarginSetter"),
|
||||||
|
mWidget(aWidget),
|
||||||
|
mMargin(-1, -1, -1, -1) {}
|
||||||
|
MarginSetter(nsIWidget* aWidget, const LayoutDeviceIntMargin& aMargin)
|
||||||
|
: mozilla::Runnable("MarginSetter"), mWidget(aWidget), mMargin(aMargin) {}
|
||||||
|
|
||||||
|
NS_IMETHOD Run() override {
|
||||||
|
// SetNonClientMargins can dispatch native events, hence doing
|
||||||
|
// it off a script runner.
|
||||||
|
mWidget->SetNonClientMargins(mMargin);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsCOMPtr<nsIWidget> mWidget;
|
||||||
|
LayoutDeviceIntMargin mMargin;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ChromeObserver::SetChromeMargins(const nsAttrValue* aValue) {
|
||||||
|
if (!aValue) return;
|
||||||
|
|
||||||
|
nsIWidget* mainWidget = GetWindowWidget();
|
||||||
|
if (!mainWidget) return;
|
||||||
|
|
||||||
|
// top, right, bottom, left - see nsAttrValue
|
||||||
|
nsAutoString tmp;
|
||||||
|
aValue->ToString(tmp);
|
||||||
|
nsIntMargin margins;
|
||||||
|
if (nsContentUtils::ParseIntMarginValue(tmp, margins)) {
|
||||||
|
nsContentUtils::AddScriptRunner(new MarginSetter(
|
||||||
|
mainWidget, LayoutDeviceIntMargin::FromUnknownMargin(margins)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ChromeObserver::AttributeChanged(dom::Element* aElement,
|
void ChromeObserver::AttributeChanged(dom::Element* aElement,
|
||||||
int32_t aNamespaceID, nsAtom* aName,
|
int32_t aNamespaceID, nsAtom* aName,
|
||||||
int32_t aModType,
|
int32_t aModType,
|
||||||
@@ -82,25 +119,37 @@ void ChromeObserver::AttributeChanged(dom::Element* aElement,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aModType == dom::MutationEvent_Binding::ADDITION ||
|
const nsAttrValue* value = aElement->GetParsedAttr(aName, aNamespaceID);
|
||||||
aModType == dom::MutationEvent_Binding::REMOVAL) {
|
if (value) {
|
||||||
const bool added = aModType == dom::MutationEvent_Binding::ADDITION;
|
// Hide chrome if needed
|
||||||
if (aName == nsGkAtoms::hidechrome) {
|
if (aName == nsGkAtoms::hidechrome) {
|
||||||
HideWindowChrome(added);
|
HideWindowChrome(value->Equals(u"true"_ns, eCaseMatters));
|
||||||
} else if (aName == nsGkAtoms::customtitlebar) {
|
} else if (aName == nsGkAtoms::chromemargin) {
|
||||||
SetCustomTitlebar(added);
|
SetChromeMargins(value);
|
||||||
|
}
|
||||||
|
// title and drawintitlebar are settable on
|
||||||
|
// any root node (windows, dialogs, etc)
|
||||||
|
else if (aName == nsGkAtoms::title) {
|
||||||
|
mDocument->NotifyPossibleTitleChange(false);
|
||||||
} else if (aName == nsGkAtoms::drawtitle) {
|
} else if (aName == nsGkAtoms::drawtitle) {
|
||||||
SetDrawsTitle(added);
|
SetDrawsTitle(value->Equals(u"true"_ns, eCaseMatters));
|
||||||
}
|
} else if (aName == nsGkAtoms::localedir) {
|
||||||
}
|
|
||||||
if (aName == nsGkAtoms::localedir) {
|
|
||||||
// if the localedir changed on the root element, reset the document
|
// if the localedir changed on the root element, reset the document
|
||||||
// direction
|
// direction
|
||||||
mDocument->ResetDocumentDirection();
|
mDocument->ResetDocumentDirection();
|
||||||
}
|
}
|
||||||
if (aName == nsGkAtoms::title &&
|
} else {
|
||||||
aModType != dom::MutationEvent_Binding::REMOVAL) {
|
if (aName == nsGkAtoms::hidechrome) {
|
||||||
mDocument->NotifyPossibleTitleChange(false);
|
HideWindowChrome(false);
|
||||||
|
} else if (aName == nsGkAtoms::chromemargin) {
|
||||||
|
ResetChromeMargins();
|
||||||
|
} else if (aName == nsGkAtoms::localedir) {
|
||||||
|
// if the localedir changed on the root element, reset the document
|
||||||
|
// direction
|
||||||
|
mDocument->ResetDocumentDirection();
|
||||||
|
} else if (aName == nsGkAtoms::drawtitle) {
|
||||||
|
SetDrawsTitle(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,14 +157,11 @@ void ChromeObserver::NodeWillBeDestroyed(nsINode* aNode) {
|
|||||||
mDocument = nullptr;
|
mDocument = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChromeObserver::SetCustomTitlebar(bool aCustomTitlebar) {
|
void ChromeObserver::ResetChromeMargins() {
|
||||||
if (nsIWidget* mainWidget = GetWindowWidget()) {
|
nsIWidget* mainWidget = GetWindowWidget();
|
||||||
// SetCustomTitlebar can dispatch native events, hence doing it off a
|
if (!mainWidget) return;
|
||||||
// script runner
|
// See nsIWidget
|
||||||
nsContentUtils::AddScriptRunner(NewRunnableMethod<bool>(
|
nsContentUtils::AddScriptRunner(new MarginSetter(mainWidget));
|
||||||
"SetCustomTitlebar", mainWidget, &nsIWidget::SetCustomTitlebar,
|
|
||||||
aCustomTitlebar));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult ChromeObserver::HideWindowChrome(bool aShouldHide) {
|
nsresult ChromeObserver::HideWindowChrome(bool aShouldHide) {
|
||||||
|
|||||||
@@ -27,8 +27,11 @@ class ChromeObserver final : public nsStubMutationObserver {
|
|||||||
protected:
|
protected:
|
||||||
nsIWidget* GetWindowWidget();
|
nsIWidget* GetWindowWidget();
|
||||||
void SetDrawsTitle(bool aState);
|
void SetDrawsTitle(bool aState);
|
||||||
|
void SetChromeMargins(const nsAttrValue* aValue);
|
||||||
nsresult HideWindowChrome(bool aShouldHide);
|
nsresult HideWindowChrome(bool aShouldHide);
|
||||||
void SetCustomTitlebar(bool);
|
|
||||||
|
private:
|
||||||
|
void ResetChromeMargins();
|
||||||
~ChromeObserver();
|
~ChromeObserver();
|
||||||
// A weak pointer cleared when the element will be destroyed.
|
// A weak pointer cleared when the element will be destroyed.
|
||||||
Document* MOZ_NON_OWNING_REF mDocument;
|
Document* MOZ_NON_OWNING_REF mDocument;
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ static int sVerticalResizeMargin = 0;
|
|||||||
|
|
||||||
// See nsWindow::NonClientSizeMargin()
|
// See nsWindow::NonClientSizeMargin()
|
||||||
static Margin NonClientSizeMargin() {
|
static Margin NonClientSizeMargin() {
|
||||||
return Margin{sCaptionHeight + sVerticalResizeMargin - sNonClientOffset.top,
|
return Margin{sCaptionHeight - sNonClientOffset.top,
|
||||||
sHorizontalResizeMargin - sNonClientOffset.right,
|
sHorizontalResizeMargin - sNonClientOffset.right,
|
||||||
sVerticalResizeMargin - sNonClientOffset.bottom,
|
sVerticalResizeMargin - sNonClientOffset.bottom,
|
||||||
sHorizontalResizeMargin - sNonClientOffset.left};
|
sHorizontalResizeMargin - sNonClientOffset.left};
|
||||||
@@ -1365,7 +1365,7 @@ ThemeColors GetTheme(ThemeMode themeId) {
|
|||||||
theme.tabColor = 0xf9f9fb;
|
theme.tabColor = 0xf9f9fb;
|
||||||
theme.toolbarForegroundColor = 0xdddde1;
|
theme.toolbarForegroundColor = 0xdddde1;
|
||||||
theme.tabOutlineColor = 0xdddde1;
|
theme.tabOutlineColor = 0xdddde1;
|
||||||
// found in browser-aero.css ":root[customtitlebar]:not(:-moz-lwtheme)"
|
// found in browser-aero.css ":root[tabsintitlebar]:not(:-moz-lwtheme)"
|
||||||
// (set to "hsl(235,33%,19%)")
|
// (set to "hsl(235,33%,19%)")
|
||||||
theme.titlebarColor = 0xf0f0f4;
|
theme.titlebarColor = 0xf0f0f4;
|
||||||
// --chrome-content-separator-color in browser.css
|
// --chrome-content-separator-color in browser.css
|
||||||
@@ -1992,15 +1992,25 @@ static Result<Ok, PreXULSkeletonUIError> CreateAndStorePreXULSkeletonUIImpl(
|
|||||||
sGetSystemMetricsForDpi(SM_CXPADDEDBORDER, sDpi);
|
sGetSystemMetricsForDpi(SM_CXPADDEDBORDER, sDpi);
|
||||||
sVerticalResizeMargin = sGetSystemMetricsForDpi(SM_CYFRAME, sDpi) +
|
sVerticalResizeMargin = sGetSystemMetricsForDpi(SM_CYFRAME, sDpi) +
|
||||||
sGetSystemMetricsForDpi(SM_CXPADDEDBORDER, sDpi);
|
sGetSystemMetricsForDpi(SM_CXPADDEDBORDER, sDpi);
|
||||||
sCaptionHeight = sGetSystemMetricsForDpi(SM_CYCAPTION, sDpi);
|
sCaptionHeight =
|
||||||
|
sVerticalResizeMargin + sGetSystemMetricsForDpi(SM_CYCAPTION, sDpi);
|
||||||
|
|
||||||
|
// These match the margins set in browser-tabsintitlebar.js with default prefs
|
||||||
|
// on Windows. We don't use the skeleton ui if tabsInTitlebar is disabled, see
|
||||||
|
// bug 1673092.
|
||||||
|
const Margin nonClientMargin{0, 2, 2, 2};
|
||||||
|
|
||||||
// These match the offsets that we get with default prefs. We don't use the
|
|
||||||
// skeleton ui if tabsInTitlebar is disabled, see bug 1673092.
|
|
||||||
if (sMaximized) {
|
if (sMaximized) {
|
||||||
sNonClientOffset = Margin{sCaptionHeight, 0, 0, 0};
|
sNonClientOffset.top = sCaptionHeight - sVerticalResizeMargin;
|
||||||
} else {
|
} else {
|
||||||
// See nsWindow::NormalWindowNonClientOffset()
|
// See nsWindow::NormalWindowNonClientOffset()
|
||||||
sNonClientOffset = Margin{sCaptionHeight + sVerticalResizeMargin, 0, 0, 0};
|
sNonClientOffset.top = sCaptionHeight;
|
||||||
|
sNonClientOffset.bottom =
|
||||||
|
std::min(sVerticalResizeMargin, nonClientMargin.bottom);
|
||||||
|
sNonClientOffset.left =
|
||||||
|
std::min(sHorizontalResizeMargin, nonClientMargin.left);
|
||||||
|
sNonClientOffset.right =
|
||||||
|
std::min(sHorizontalResizeMargin, nonClientMargin.right);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sMaximized) {
|
if (sMaximized) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
windowtype="Toolkit:PictureInPicture"
|
windowtype="Toolkit:PictureInPicture"
|
||||||
macnativefullscreen="true"
|
macnativefullscreen="true"
|
||||||
customtitlebar="true"
|
chromemargin="0,0,0,0"
|
||||||
scrolling="false"
|
scrolling="false"
|
||||||
>
|
>
|
||||||
<head>
|
<head>
|
||||||
|
|||||||
@@ -197,9 +197,8 @@ add_task(async function test_found_resize() {
|
|||||||
info(`values: ${JSON.stringify(values)}`);
|
info(`values: ${JSON.stringify(values)}`);
|
||||||
info(`resizedValues: ${JSON.stringify(resizedValues)}`);
|
info(`resizedValues: ${JSON.stringify(resizedValues)}`);
|
||||||
isfuzzy(resizedValues[0], values[0], 2, "first value");
|
isfuzzy(resizedValues[0], values[0], 2, "first value");
|
||||||
const kSlop = 50;
|
Assert.greater(resizedValues[1] - 50, values[1], "second value");
|
||||||
Assert.greaterOrEqual(resizedValues[1] - kSlop, values[1], "second value");
|
Assert.greater(resizedValues[2] - 50, values[2], "third value");
|
||||||
Assert.greaterOrEqual(resizedValues[2] - kSlop, values[2], "third value");
|
|
||||||
|
|
||||||
endFn();
|
endFn();
|
||||||
|
|
||||||
|
|||||||
@@ -143,6 +143,10 @@ skip-if = [
|
|||||||
|
|
||||||
["test_button.xhtml"]
|
["test_button.xhtml"]
|
||||||
|
|
||||||
|
["test_chromemargin.xhtml"]
|
||||||
|
support-files = "window_chromemargin.xhtml"
|
||||||
|
skip-if = ["apple_catalina"]
|
||||||
|
|
||||||
["test_closemenu_attribute.xhtml"]
|
["test_closemenu_attribute.xhtml"]
|
||||||
|
|
||||||
["test_contextmenu_list.xhtml"]
|
["test_contextmenu_list.xhtml"]
|
||||||
|
|||||||
35
toolkit/content/tests/chrome/test_chromemargin.xhtml
Normal file
35
toolkit/content/tests/chrome/test_chromemargin.xhtml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||||
|
|
||||||
|
<window title="Custom chrome margin tests"
|
||||||
|
onload="setTimeout(runTest, 0);"
|
||||||
|
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
|
||||||
|
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
// Tests parsing of the chrome margin attrib on a window.
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
function runTest()
|
||||||
|
{
|
||||||
|
window.openDialog("window_chromemargin.xhtml", "_blank", "chrome,width=600,height=600,noopener", window);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<p id="display">
|
||||||
|
</p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</window>
|
||||||
73
toolkit/content/tests/chrome/window_chromemargin.xhtml
Normal file
73
toolkit/content/tests/chrome/window_chromemargin.xhtml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||||
|
|
||||||
|
<window id="window" title="Subframe Origin Tests"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||||
|
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
|
||||||
|
chrome margins rock!
|
||||||
|
<script>
|
||||||
|
|
||||||
|
// Tests parsing of the chrome margin attrib on a window.
|
||||||
|
|
||||||
|
function ok(condition, message) {
|
||||||
|
window.arguments[0].SimpleTest.ok(condition, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function is(a, b, message) {
|
||||||
|
window.arguments[0].SimpleTest.is(a, b, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function doSingleTest(param)
|
||||||
|
{
|
||||||
|
var exception = null;
|
||||||
|
try {
|
||||||
|
document.documentElement.removeAttribute("chromemargin");
|
||||||
|
document.documentElement.setAttribute("chromemargin", param);
|
||||||
|
is(document.
|
||||||
|
documentElement.
|
||||||
|
getAttribute("chromemargin"), param, "couldn't set/get chromemargin?");
|
||||||
|
} catch (ex) {
|
||||||
|
exception = ex;
|
||||||
|
}
|
||||||
|
ok(!exception, "failed for param:'" + param + "'");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests()
|
||||||
|
{
|
||||||
|
var doc = document.documentElement;
|
||||||
|
|
||||||
|
// make sure we can set and get
|
||||||
|
doc.setAttribute("chromemargin", "0,0,0,0");
|
||||||
|
ok(doc.getAttribute("chromemargin") == "0,0,0,0", "couldn't set/get chromemargin?");
|
||||||
|
doc.setAttribute("chromemargin", "-1,-1,-1,-1");
|
||||||
|
ok(doc.getAttribute("chromemargin") == "-1,-1,-1,-1", "couldn't set/get chromemargin?");
|
||||||
|
|
||||||
|
// test remove
|
||||||
|
doc.removeAttribute("chromemargin");
|
||||||
|
is(doc.getAttribute("chromemargin"), null, "couldn't remove chromemargin?");
|
||||||
|
|
||||||
|
// we already test these really well in a c++ test in widget
|
||||||
|
doSingleTest("1,2,3,4");
|
||||||
|
doSingleTest("-2,-2,-2,-2");
|
||||||
|
doSingleTest("1,1,1,1");
|
||||||
|
doSingleTest("");
|
||||||
|
doSingleTest("12123123");
|
||||||
|
doSingleTest("0,-1,-1,-1");
|
||||||
|
doSingleTest("-1,0,-1,-1");
|
||||||
|
doSingleTest("-1,-1,0,-1");
|
||||||
|
doSingleTest("-1,-1,-1,0");
|
||||||
|
doSingleTest("1234567890,1234567890,1234567890,1234567890");
|
||||||
|
doSingleTest("-1,-1,-1,-1");
|
||||||
|
|
||||||
|
window.arguments[0].SimpleTest.finish();
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.arguments[0].SimpleTest.waitForFocus(runTests, window);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</window>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
height="300"
|
height="300"
|
||||||
width="300"
|
width="300"
|
||||||
sizemode="normal"
|
sizemode="normal"
|
||||||
customtitlebar="true"
|
chromemargin="0,2,2,2"
|
||||||
id="window"
|
id="window"
|
||||||
persist="height width sizemode">
|
persist="height width sizemode">
|
||||||
<script type="application/javascript"><![CDATA[
|
<script type="application/javascript"><![CDATA[
|
||||||
|
|||||||
@@ -283,7 +283,8 @@ class nsCocoaWindow final : public nsBaseWidget {
|
|||||||
void SetSupportsNativeFullscreen(bool aShow) override;
|
void SetSupportsNativeFullscreen(bool aShow) override;
|
||||||
void SetWindowAnimationType(WindowAnimationType aType) override;
|
void SetWindowAnimationType(WindowAnimationType aType) override;
|
||||||
void SetDrawsTitle(bool aDrawTitle) override;
|
void SetDrawsTitle(bool aDrawTitle) override;
|
||||||
void SetCustomTitlebar(bool) override;
|
nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override;
|
||||||
|
void SetDrawsInTitlebar(bool aState);
|
||||||
void UpdateThemeGeometries(
|
void UpdateThemeGeometries(
|
||||||
const nsTArray<ThemeGeometry>& aThemeGeometries) override;
|
const nsTArray<ThemeGeometry>& aThemeGeometries) override;
|
||||||
nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
|
nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
|
||||||
|
|||||||
@@ -2464,7 +2464,18 @@ void nsCocoaWindow::SetDrawsTitle(bool aDrawTitle) {
|
|||||||
NS_OBJC_END_TRY_IGNORE_BLOCK;
|
NS_OBJC_END_TRY_IGNORE_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsCocoaWindow::SetCustomTitlebar(bool aState) {
|
nsresult nsCocoaWindow::SetNonClientMargins(
|
||||||
|
const LayoutDeviceIntMargin& margins) {
|
||||||
|
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
|
||||||
|
|
||||||
|
SetDrawsInTitlebar(margins.top == 0);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsCocoaWindow::SetDrawsInTitlebar(bool aState) {
|
||||||
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
|
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
|
||||||
|
|
||||||
if (mWindow) {
|
if (mWindow) {
|
||||||
|
|||||||
@@ -8774,6 +8774,11 @@ void nsWindow::SetCompositorWidgetDelegate(CompositorWidgetDelegate* delegate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult nsWindow::SetNonClientMargins(const LayoutDeviceIntMargin& aMargins) {
|
||||||
|
SetDrawsInTitlebar(aMargins.top == 0);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
bool nsWindow::IsAlwaysUndecoratedWindow() const {
|
bool nsWindow::IsAlwaysUndecoratedWindow() const {
|
||||||
if (mIsPIPWindow || gKioskMode) {
|
if (mIsPIPWindow || gKioskMode) {
|
||||||
return true;
|
return true;
|
||||||
@@ -8788,8 +8793,8 @@ bool nsWindow::IsAlwaysUndecoratedWindow() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsWindow::SetCustomTitlebar(bool aState) {
|
void nsWindow::SetDrawsInTitlebar(bool aState) {
|
||||||
LOG("nsWindow::SetCustomTitlebar() State %d mGtkWindowDecoration %d\n",
|
LOG("nsWindow::SetDrawsInTitlebar() State %d mGtkWindowDecoration %d\n",
|
||||||
aState, (int)mGtkWindowDecoration);
|
aState, (int)mGtkWindowDecoration);
|
||||||
|
|
||||||
if (mGtkWindowDecoration == GTK_DECORATION_NONE ||
|
if (mGtkWindowDecoration == GTK_DECORATION_NONE ||
|
||||||
|
|||||||
@@ -373,7 +373,8 @@ class nsWindow final : public nsBaseWidget {
|
|||||||
void GetCompositorWidgetInitData(
|
void GetCompositorWidgetInitData(
|
||||||
mozilla::widget::CompositorWidgetInitData* aInitData) override;
|
mozilla::widget::CompositorWidgetInitData* aInitData) override;
|
||||||
|
|
||||||
void SetCustomTitlebar(bool) override;
|
nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override;
|
||||||
|
void SetDrawsInTitlebar(bool aState);
|
||||||
mozilla::LayoutDeviceIntCoord GetTitlebarRadius();
|
mozilla::LayoutDeviceIntCoord GetTitlebarRadius();
|
||||||
void UpdateWindowDraggingRegion(
|
void UpdateWindowDraggingRegion(
|
||||||
const LayoutDeviceIntRegion& aRegion) override;
|
const LayoutDeviceIntRegion& aRegion) override;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace mozilla {
|
|||||||
enum class NativeKeyBindingsType : uint8_t;
|
enum class NativeKeyBindingsType : uint8_t;
|
||||||
namespace widget {
|
namespace widget {
|
||||||
|
|
||||||
class HeadlessWidget final : public nsBaseWidget {
|
class HeadlessWidget : public nsBaseWidget {
|
||||||
public:
|
public:
|
||||||
HeadlessWidget();
|
HeadlessWidget();
|
||||||
|
|
||||||
@@ -77,6 +77,10 @@ class HeadlessWidget final : public nsBaseWidget {
|
|||||||
// Headless widgets have no title, so just ignore it.
|
// Headless widgets have no title, so just ignore it.
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
nsresult SetNonClientMargins(const LayoutDeviceIntMargin& margins) override {
|
||||||
|
// Headless widgets have no chrome margins, so just ignore the call.
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
LayoutDeviceIntPoint WidgetToScreenOffset() override;
|
LayoutDeviceIntPoint WidgetToScreenOffset() override;
|
||||||
void SetInputContext(const InputContext& aContext,
|
void SetInputContext(const InputContext& aContext,
|
||||||
const InputContextAction& aAction) override {
|
const InputContextAction& aAction) override {
|
||||||
|
|||||||
@@ -1747,6 +1747,12 @@ LayoutDeviceIntPoint nsBaseWidget::GetClientOffset() {
|
|||||||
return LayoutDeviceIntPoint(0, 0);
|
return LayoutDeviceIntPoint(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult nsBaseWidget::SetNonClientMargins(const LayoutDeviceIntMargin&) {
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsBaseWidget::SetResizeMargin(LayoutDeviceIntCoord aResizeMargin) {}
|
||||||
|
|
||||||
uint32_t nsBaseWidget::GetMaxTouchPoints() const { return 0; }
|
uint32_t nsBaseWidget::GetMaxTouchPoints() const { return 0; }
|
||||||
|
|
||||||
bool nsBaseWidget::HasPendingInputEvent() { return false; }
|
bool nsBaseWidget::HasPendingInputEvent() { return false; }
|
||||||
|
|||||||
@@ -252,9 +252,11 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
|
|||||||
LayoutDeviceIntRect GetClientBounds() override;
|
LayoutDeviceIntRect GetClientBounds() override;
|
||||||
LayoutDeviceIntRect GetScreenBounds() override;
|
LayoutDeviceIntRect GetScreenBounds() override;
|
||||||
[[nodiscard]] nsresult GetRestoredBounds(LayoutDeviceIntRect& aRect) override;
|
[[nodiscard]] nsresult GetRestoredBounds(LayoutDeviceIntRect& aRect) override;
|
||||||
|
nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override;
|
||||||
LayoutDeviceIntPoint GetClientOffset() override;
|
LayoutDeviceIntPoint GetClientOffset() override;
|
||||||
void EnableDragDrop(bool aEnable) override {};
|
void EnableDragDrop(bool aEnable) override {};
|
||||||
nsresult AsyncEnableDragDrop(bool aEnable) override;
|
nsresult AsyncEnableDragDrop(bool aEnable) override;
|
||||||
|
void SetResizeMargin(mozilla::LayoutDeviceIntCoord aResizeMargin) override;
|
||||||
[[nodiscard]] nsresult GetAttention(int32_t aCycleCount) override {
|
[[nodiscard]] nsresult GetAttention(int32_t aCycleCount) override {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -870,15 +870,24 @@ class nsIWidget : public nsISupports {
|
|||||||
*/
|
*/
|
||||||
virtual LayoutDeviceIntRect GetClientBounds() = 0;
|
virtual LayoutDeviceIntRect GetClientBounds() = 0;
|
||||||
|
|
||||||
/** Whether to extend the client area into the titlebar. */
|
/**
|
||||||
virtual void SetCustomTitlebar(bool) {}
|
* Sets the non-client area dimensions of the window. Pass -1 to restore
|
||||||
|
* the system default frame size for that border. Pass zero to remove
|
||||||
|
* a border, or pass a specific value adjust a border. Units are in
|
||||||
|
* pixels. (DPI dependent)
|
||||||
|
*
|
||||||
|
* Platform notes:
|
||||||
|
* Windows: shrinking top non-client height will remove application
|
||||||
|
* icon and window title text. Glass desktops will refuse to set
|
||||||
|
* dimensions between zero and size < system default.
|
||||||
|
*/
|
||||||
|
virtual nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the region around the edges of the window that can be dragged to
|
* Sets the region around the edges of the window that can be dragged to
|
||||||
* resize the window. All four sides of the window will get the same margin.
|
* resize the window. All four sides of the window will get the same margin.
|
||||||
*/
|
*/
|
||||||
virtual void SetResizeMargin(mozilla::LayoutDeviceIntCoord) {}
|
virtual void SetResizeMargin(mozilla::LayoutDeviceIntCoord aResizeMargin) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the client offset from the window origin.
|
* Get the client offset from the window origin.
|
||||||
*
|
*
|
||||||
|
|||||||
130
widget/tests/TestChromeMargin.cpp
Normal file
130
widget/tests/TestChromeMargin.cpp
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
/* This tests the margin parsing functionality in nsAttrValue.cpp, which
|
||||||
|
* is accessible via nsContentUtils, and is used in setting chromemargins
|
||||||
|
* to widget windows. It's located here due to linking issues in the
|
||||||
|
* content directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This test no longer compiles now that we've removed nsIContentUtils (bug
|
||||||
|
* 647273). We need to be internal code in order to include nsContentUtils.h,
|
||||||
|
* but defining MOZILLA_INTERNAL_API is not enough to make us internal.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TestHarness.h"
|
||||||
|
|
||||||
|
#ifndef MOZILLA_INTERNAL_API
|
||||||
|
# error This test needs MOZILLA_INTERNAL_API (see bug 652123)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "nscore.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
|
||||||
|
struct DATA {
|
||||||
|
bool shouldfail;
|
||||||
|
const char* margins;
|
||||||
|
int top;
|
||||||
|
int right;
|
||||||
|
int bottom;
|
||||||
|
int left;
|
||||||
|
};
|
||||||
|
|
||||||
|
const bool SHOULD_FAIL = true;
|
||||||
|
const int SHOULD_PASS = false;
|
||||||
|
|
||||||
|
const DATA Data[] = {
|
||||||
|
{SHOULD_FAIL, "", 1, 2, 3, 4},
|
||||||
|
{SHOULD_FAIL, "1,0,0,0", 1, 2, 3, 4},
|
||||||
|
{SHOULD_FAIL, "1,2,0,0", 1, 2, 3, 4},
|
||||||
|
{SHOULD_FAIL, "1,2,3,0", 1, 2, 3, 4},
|
||||||
|
{SHOULD_FAIL, "4,3,2,1", 1, 2, 3, 4},
|
||||||
|
{SHOULD_FAIL, "azsasdasd", 0, 0, 0, 0},
|
||||||
|
{SHOULD_FAIL, ",azsasdasd", 0, 0, 0, 0},
|
||||||
|
{SHOULD_FAIL, " ", 1, 2, 3, 4},
|
||||||
|
{SHOULD_FAIL,
|
||||||
|
"azsdfsdfsdfsdfsdfsasdasd,asdasdasdasdasdasd,asdadasdasd,asdasdasdasd", 0,
|
||||||
|
0, 0, 0},
|
||||||
|
{SHOULD_FAIL, "as,as,as,as", 0, 0, 0, 0},
|
||||||
|
{SHOULD_FAIL, "0,0,0", 0, 0, 0, 0},
|
||||||
|
{SHOULD_FAIL, "0,0", 0, 0, 0, 0},
|
||||||
|
{SHOULD_FAIL, "4.6,1,1,1", 0, 0, 0, 0},
|
||||||
|
{SHOULD_FAIL, ",,,,", 0, 0, 0, 0},
|
||||||
|
{SHOULD_FAIL, "1, , , ,", 0, 0, 0, 0},
|
||||||
|
{SHOULD_FAIL, "1, , ,", 0, 0, 0, 0},
|
||||||
|
{SHOULD_FAIL, "@!@%^&^*()", 1, 2, 3, 4},
|
||||||
|
{SHOULD_PASS, "4,3,2,1", 4, 3, 2, 1},
|
||||||
|
{SHOULD_PASS, "-4,-3,-2,-1", -4, -3, -2, -1},
|
||||||
|
{SHOULD_PASS, "10000,3,2,1", 10000, 3, 2, 1},
|
||||||
|
{SHOULD_PASS, "4 , 3 , 2 , 1", 4, 3, 2, 1},
|
||||||
|
{SHOULD_PASS, "4, 3 ,2,1", 4, 3, 2, 1},
|
||||||
|
{SHOULD_FAIL, "4,3,2,10000000000000 --", 4, 3, 2, 10000000000000},
|
||||||
|
{SHOULD_PASS, "4,3,2,1000", 4, 3, 2, 1000},
|
||||||
|
{SHOULD_PASS, "2147483647,3,2,1000", 2147483647, 3, 2, 1000},
|
||||||
|
{SHOULD_PASS, "2147483647,2147483647,2147483647,2147483647", 2147483647,
|
||||||
|
2147483647, 2147483647, 2147483647},
|
||||||
|
{SHOULD_PASS, "-2147483647,3,2,1000", -2147483647, 3, 2, 1000},
|
||||||
|
{SHOULD_FAIL, "2147483648,3,2,1000", 1, 3, 2, 1000},
|
||||||
|
{0, nullptr, 0, 0, 0, 0}};
|
||||||
|
|
||||||
|
void DoAttrValueTest() {
|
||||||
|
int idx = -1;
|
||||||
|
bool didFail = false;
|
||||||
|
while (Data[++idx].margins) {
|
||||||
|
nsAutoString str;
|
||||||
|
str.AssignLiteral(Data[idx].margins);
|
||||||
|
nsIntMargin values(99, 99, 99, 99);
|
||||||
|
bool result = nsContentUtils::ParseIntMarginValue(str, values);
|
||||||
|
|
||||||
|
// if the parse fails
|
||||||
|
if (!result) {
|
||||||
|
if (Data[idx].shouldfail) continue;
|
||||||
|
fail(Data[idx].margins);
|
||||||
|
didFail = true;
|
||||||
|
printf("*1\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Data[idx].shouldfail) {
|
||||||
|
if (Data[idx].top == values.top && Data[idx].right == values.right &&
|
||||||
|
Data[idx].bottom == values.bottom && Data[idx].left == values.left) {
|
||||||
|
// not likely
|
||||||
|
fail(Data[idx].margins);
|
||||||
|
didFail = true;
|
||||||
|
printf("*2\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// good failure, parse failed and that's what we expected.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
printf("%d==%d %d==%d %d==%d %d==%d\n",
|
||||||
|
Data[idx].top, values.top,
|
||||||
|
Data[idx].right, values.right,
|
||||||
|
Data[idx].bottom, values.bottom,
|
||||||
|
Data[idx].left, values.left);
|
||||||
|
#endif
|
||||||
|
if (Data[idx].top == values.top && Data[idx].right == values.right &&
|
||||||
|
Data[idx].bottom == values.bottom && Data[idx].left == values.left) {
|
||||||
|
// good parse results
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
fail(Data[idx].margins);
|
||||||
|
didFail = true;
|
||||||
|
printf("*3\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!didFail) passed("nsAttrValue margin parsing tests passed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
ScopedXPCOM xpcom("");
|
||||||
|
if (xpcom.failed()) return 1;
|
||||||
|
DoAttrValueTest();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -16,6 +16,9 @@ with Files("unit/*macwebapputils*"):
|
|||||||
with Files("unit/*taskbar_jumplistitems*"):
|
with Files("unit/*taskbar_jumplistitems*"):
|
||||||
BUG_COMPONENT = ("Core", "Widget: Win32")
|
BUG_COMPONENT = ("Core", "Widget: Win32")
|
||||||
|
|
||||||
|
with Files("TestChromeMargin.cpp"):
|
||||||
|
BUG_COMPONENT = ("Core", "Widget: Win32")
|
||||||
|
|
||||||
with Files("*413277*"):
|
with Files("*413277*"):
|
||||||
BUG_COMPONENT = ("Core", "Widget: Cocoa")
|
BUG_COMPONENT = ("Core", "Widget: Cocoa")
|
||||||
|
|
||||||
@@ -114,3 +117,9 @@ XPCSHELL_TESTS_MANIFESTS += ["unit/xpcshell.toml"]
|
|||||||
MOCHITEST_MANIFESTS += ["mochitest.toml"]
|
MOCHITEST_MANIFESTS += ["mochitest.toml"]
|
||||||
MOCHITEST_CHROME_MANIFESTS += ["chrome.toml"]
|
MOCHITEST_CHROME_MANIFESTS += ["chrome.toml"]
|
||||||
BROWSER_CHROME_MANIFESTS += ["browser/browser.toml"]
|
BROWSER_CHROME_MANIFESTS += ["browser/browser.toml"]
|
||||||
|
|
||||||
|
# if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||||
|
#
|
||||||
|
# Test disabled because it requires the internal API. Re-enabling this test
|
||||||
|
# is bug 652123.
|
||||||
|
# CPP_UNIT_TESTS += ['TestChromeMargin']
|
||||||
|
|||||||
@@ -43,13 +43,13 @@ async function start() {
|
|||||||
await waitForEvent(window, "focus");
|
await waitForEvent(window, "focus");
|
||||||
var oldOuterWidth = window.outerWidth, oldOuterHeight = window.outerHeight;
|
var oldOuterWidth = window.outerWidth, oldOuterHeight = window.outerHeight;
|
||||||
var oldInnerWidth = window.innerWidth, oldInnerHeight = window.innerHeight;
|
var oldInnerWidth = window.innerWidth, oldInnerHeight = window.innerHeight;
|
||||||
document.documentElement.setAttribute("customtitlebar", "true");
|
document.documentElement.setAttribute("chromemargin", "0,0,0,0");
|
||||||
|
|
||||||
await executeSoon();
|
await executeSoon();
|
||||||
is(window.outerWidth, oldOuterWidth, "customtitlebar shouldn't change the window's outerWidth");
|
is(window.outerWidth, oldOuterWidth, "chromemargin shouldn't change the window's outerWidth");
|
||||||
is(window.outerHeight, oldOuterHeight, "customtitlebar shouldn't change the window's outerHeight");
|
is(window.outerHeight, oldOuterHeight, "chromemargin shouldn't change the window's outerHeight");
|
||||||
is(window.innerWidth, oldOuterWidth, "if customtitlebar is set, innerWidth and outerWidth should be the same");
|
is(window.innerWidth, oldOuterWidth, "if chromemargin is set, innerWidth and outerWidth should be the same");
|
||||||
is(window.innerHeight, oldOuterHeight, "if customtitlebar is set, innerHeight and outerHeight should be the same");
|
is(window.innerHeight, oldOuterHeight, "if chromemargin is set, innerHeight and outerHeight should be the same");
|
||||||
|
|
||||||
// Wait for going full screen and back.
|
// Wait for going full screen and back.
|
||||||
let sizemodeChange = waitForEvent(window, "sizemodechange");
|
let sizemodeChange = waitForEvent(window, "sizemodechange");
|
||||||
@@ -62,13 +62,13 @@ async function start() {
|
|||||||
is(window.outerHeight, oldOuterHeight, "wrong outerHeight after fullscreen mode");
|
is(window.outerHeight, oldOuterHeight, "wrong outerHeight after fullscreen mode");
|
||||||
is(window.innerWidth, oldOuterWidth, "wrong innerWidth after fullscreen mode");
|
is(window.innerWidth, oldOuterWidth, "wrong innerWidth after fullscreen mode");
|
||||||
is(window.innerHeight, oldOuterHeight, "wrong innerHeight after fullscreen mode");
|
is(window.innerHeight, oldOuterHeight, "wrong innerHeight after fullscreen mode");
|
||||||
document.documentElement.removeAttribute("customtitlebar");
|
document.documentElement.removeAttribute("chromemargin");
|
||||||
|
|
||||||
await executeSoon();
|
await executeSoon();
|
||||||
is(window.outerWidth, oldOuterWidth, "wrong outerWidth after removing customtitlebar");
|
is(window.outerWidth, oldOuterWidth, "wrong outerWidth after removing chromemargin");
|
||||||
is(window.outerHeight, oldOuterHeight, "wrong outerHeight after removing customtitlebar");
|
is(window.outerHeight, oldOuterHeight, "wrong outerHeight after removing chromemargin");
|
||||||
is(window.innerWidth, oldInnerWidth, "wrong innerWidth after removing customtitlebar");
|
is(window.innerWidth, oldInnerWidth, "wrong innerWidth after removing chromemargin");
|
||||||
is(window.innerHeight, oldInnerHeight, "wrong innerHeight after removing customtitlebar");
|
is(window.innerHeight, oldInnerHeight, "wrong innerHeight after removing chromemargin");
|
||||||
window.arguments[0].SimpleTest.finish();
|
window.arguments[0].SimpleTest.finish();
|
||||||
window.close();
|
window.close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -940,8 +940,10 @@ nsresult nsWindow::Create(nsIWidget* aParent, const LayoutDeviceIntRect& aRect,
|
|||||||
DesktopIntRect::Round(LayoutDeviceRect(GetBounds()) / scale)
|
DesktopIntRect::Round(LayoutDeviceRect(GetBounds()) / scale)
|
||||||
.ToUnknownRect());
|
.ToUnknownRect());
|
||||||
|
|
||||||
// Skeleton ui is disabled when custom titlebar is off, see bug 1673092.
|
// These match the margins set in browser-tabsintitlebar.js with
|
||||||
SetCustomTitlebar(true);
|
// default prefs on Windows. Bug 1673092 tracks lining this up with
|
||||||
|
// that more correctly instead of hard-coding it.
|
||||||
|
SetNonClientMargins(LayoutDeviceIntMargin(0, 2, 2, 2));
|
||||||
// The skeleton UI already painted over the NC area, so there's no need
|
// The skeleton UI already painted over the NC area, so there's no need
|
||||||
// to do that again; the effective non-client margins haven't changed.
|
// to do that again; the effective non-client margins haven't changed.
|
||||||
mNeedsNCAreaClear = false;
|
mNeedsNCAreaClear = false;
|
||||||
@@ -2335,7 +2337,7 @@ void nsWindow::SetFocus(Raise aRaise, mozilla::dom::CallerType aCallerType) {
|
|||||||
* SECTION: Bounds
|
* SECTION: Bounds
|
||||||
*
|
*
|
||||||
* GetBounds, GetClientBounds, GetScreenBounds,
|
* GetBounds, GetClientBounds, GetScreenBounds,
|
||||||
* GetRestoredBounds, GetClientOffset, SetCustomTitlebar
|
* GetRestoredBounds, GetClientOffset, SetNonClientMargins
|
||||||
*
|
*
|
||||||
* Bound calculations.
|
* Bound calculations.
|
||||||
*
|
*
|
||||||
@@ -2521,17 +2523,49 @@ void nsWindow::SetColorScheme(const Maybe<ColorScheme>& aScheme) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LayoutDeviceIntMargin nsWindow::NormalWindowNonClientOffset() const {
|
LayoutDeviceIntMargin nsWindow::NormalWindowNonClientOffset() const {
|
||||||
MOZ_ASSERT(mCustomNonClient);
|
LayoutDeviceIntMargin nonClientOffset;
|
||||||
|
|
||||||
// We're dealing with a "normal" window (not maximized, minimized, or
|
// We're dealing with a "normal" window (not maximized, minimized, or
|
||||||
// fullscreen), so set `mNonClientOffset` accordingly.
|
// fullscreen), so process `mNonClientMargins` and set `mNonClientOffset`
|
||||||
|
// accordingly.
|
||||||
//
|
//
|
||||||
// Setting `mNonClientOffset` to 0 has the effect of leaving the default
|
// Setting `mNonClientOffset` to 0 has the effect of leaving the default
|
||||||
// frame intact. Setting it to a value greater than 0 reduces the frame
|
// frame intact. Setting it to a value greater than 0 reduces the frame
|
||||||
// size by that amount.
|
// size by that amount.
|
||||||
//
|
|
||||||
// When using custom titlebar, we hide the titlebar and leave the default
|
if (mNonClientMargins.top > 0) {
|
||||||
// frame on the other sides.
|
nonClientOffset.top = std::min(mCaptionHeight, mNonClientMargins.top);
|
||||||
return LayoutDeviceIntMargin(mCaptionHeight + mVertResizeMargin, 0, 0, 0);
|
} else if (mNonClientMargins.top == 0) {
|
||||||
|
nonClientOffset.top = mCaptionHeight;
|
||||||
|
} else {
|
||||||
|
nonClientOffset.top = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNonClientMargins.bottom > 0) {
|
||||||
|
nonClientOffset.bottom =
|
||||||
|
std::min(mVertResizeMargin, mNonClientMargins.bottom);
|
||||||
|
} else if (mNonClientMargins.bottom == 0) {
|
||||||
|
nonClientOffset.bottom = mVertResizeMargin;
|
||||||
|
} else {
|
||||||
|
nonClientOffset.bottom = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNonClientMargins.left > 0) {
|
||||||
|
nonClientOffset.left = std::min(mHorResizeMargin, mNonClientMargins.left);
|
||||||
|
} else if (mNonClientMargins.left == 0) {
|
||||||
|
nonClientOffset.left = mHorResizeMargin;
|
||||||
|
} else {
|
||||||
|
nonClientOffset.left = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNonClientMargins.right > 0) {
|
||||||
|
nonClientOffset.right = std::min(mHorResizeMargin, mNonClientMargins.right);
|
||||||
|
} else if (mNonClientMargins.right == 0) {
|
||||||
|
nonClientOffset.right = mHorResizeMargin;
|
||||||
|
} else {
|
||||||
|
nonClientOffset.right = 0;
|
||||||
|
}
|
||||||
|
return nonClientOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2540,14 +2574,24 @@ LayoutDeviceIntMargin nsWindow::NormalWindowNonClientOffset() const {
|
|||||||
* margins and fires off a frame changed event, which triggers an nc calc
|
* margins and fires off a frame changed event, which triggers an nc calc
|
||||||
* size windows event, kicking the changes in.
|
* size windows event, kicking the changes in.
|
||||||
*
|
*
|
||||||
|
* The offsets calculated here are based on the value of `mNonClientMargins`
|
||||||
|
* which is specified in the "chromemargins" attribute of the window. For
|
||||||
|
* each margin, the value specified has the following meaning:
|
||||||
|
* -1 - leave the default frame in place
|
||||||
|
* 0 - remove the frame
|
||||||
|
* >0 - frame size equals min(0, (default frame size - margin value))
|
||||||
|
*
|
||||||
* This function calculates and populates `mNonClientOffset`.
|
* This function calculates and populates `mNonClientOffset`.
|
||||||
* In our processing of `WM_NCCALCSIZE`, the frame size will be calculated
|
* In our processing of `WM_NCCALCSIZE`, the frame size will be calculated
|
||||||
* as (default frame size - offset). For example, if the left frame should
|
* as (default frame size - offset). For example, if the left frame should
|
||||||
* be 1 pixel narrower than the default frame size, `mNonClientOffset.left`
|
* be 1 pixel narrower than the default frame size, `mNonClientOffset.left`
|
||||||
* will equal 1.
|
* will equal 1.
|
||||||
*
|
*
|
||||||
* For maximized, fullscreen, and minimized windows special processing takes
|
* For maximized, fullscreen, and minimized windows, the values stored in
|
||||||
* place.
|
* `mNonClientMargins` are ignored, and special processing takes place.
|
||||||
|
*
|
||||||
|
* For non-glass windows, we only allow frames to be their default size
|
||||||
|
* or removed entirely.
|
||||||
*/
|
*/
|
||||||
bool nsWindow::UpdateNonClientMargins(bool aReflowWindow) {
|
bool nsWindow::UpdateNonClientMargins(bool aReflowWindow) {
|
||||||
if (!mCustomNonClient) {
|
if (!mCustomNonClient) {
|
||||||
@@ -2556,12 +2600,29 @@ bool nsWindow::UpdateNonClientMargins(bool aReflowWindow) {
|
|||||||
|
|
||||||
const nsSizeMode sizeMode = mFrameState->GetSizeMode();
|
const nsSizeMode sizeMode = mFrameState->GetSizeMode();
|
||||||
|
|
||||||
const bool hasCaption =
|
bool hasCaption =
|
||||||
bool(mBorderStyle & (BorderStyle::All | BorderStyle::Title |
|
bool(mBorderStyle & (BorderStyle::All | BorderStyle::Title |
|
||||||
BorderStyle::Menu | BorderStyle::Default));
|
BorderStyle::Menu | BorderStyle::Default));
|
||||||
|
|
||||||
float dpi = GetDPI();
|
float dpi = GetDPI();
|
||||||
|
|
||||||
|
// mCaptionHeight is the default size of the NC area at
|
||||||
|
// the top of the window. If the window has a caption,
|
||||||
|
// the size is calculated as the sum of:
|
||||||
|
// SM_CYFRAME - The thickness of the sizing border
|
||||||
|
// around a resizable window
|
||||||
|
// SM_CXPADDEDBORDER - The amount of border padding
|
||||||
|
// for captioned windows
|
||||||
|
// SM_CYCAPTION - The height of the caption area
|
||||||
|
//
|
||||||
|
// If the window does not have a caption, mCaptionHeight will be equal to
|
||||||
|
// `WinUtils::GetSystemMetricsForDpi(SM_CYFRAME, dpi)`
|
||||||
|
mCaptionHeight =
|
||||||
|
WinUtils::GetSystemMetricsForDpi(SM_CYFRAME, dpi) +
|
||||||
|
(hasCaption ? WinUtils::GetSystemMetricsForDpi(SM_CYCAPTION, dpi) +
|
||||||
|
WinUtils::GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi)
|
||||||
|
: 0);
|
||||||
|
if (!mUseResizeMarginOverrides) {
|
||||||
// mHorResizeMargin is the size of the default NC areas on the
|
// mHorResizeMargin is the size of the default NC areas on the
|
||||||
// left and right sides of our window. It is calculated as
|
// left and right sides of our window. It is calculated as
|
||||||
// the sum of:
|
// the sum of:
|
||||||
@@ -2588,12 +2649,7 @@ bool nsWindow::UpdateNonClientMargins(bool aReflowWindow) {
|
|||||||
WinUtils::GetSystemMetricsForDpi(SM_CYFRAME, dpi) +
|
WinUtils::GetSystemMetricsForDpi(SM_CYFRAME, dpi) +
|
||||||
(hasCaption ? WinUtils::GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi)
|
(hasCaption ? WinUtils::GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi)
|
||||||
: 0);
|
: 0);
|
||||||
|
}
|
||||||
// mCaptionHeight is the default size of the caption. You need to include
|
|
||||||
// mVertResizeMargin if you want the whole size of the default NC area at the
|
|
||||||
// top of the window.
|
|
||||||
mCaptionHeight =
|
|
||||||
hasCaption ? WinUtils::GetSystemMetricsForDpi(SM_CYCAPTION, dpi) : 0;
|
|
||||||
|
|
||||||
if (sizeMode == nsSizeMode_Minimized) {
|
if (sizeMode == nsSizeMode_Minimized) {
|
||||||
// Use default frame size for minimized windows
|
// Use default frame size for minimized windows
|
||||||
@@ -2606,13 +2662,7 @@ bool nsWindow::UpdateNonClientMargins(bool aReflowWindow) {
|
|||||||
// makes the whole caption part of our client area, allowing us to draw
|
// makes the whole caption part of our client area, allowing us to draw
|
||||||
// in the whole caption area. Additionally remove the default frame from
|
// in the whole caption area. Additionally remove the default frame from
|
||||||
// the left, right, and bottom.
|
// the left, right, and bottom.
|
||||||
//
|
mNonClientOffset.top = mCaptionHeight;
|
||||||
// NOTE(emilio): Fullscreen windows have completely different window styles
|
|
||||||
// because of HideWindowChrome(), so we actually need to apply the offsets
|
|
||||||
// and extend into the frame. It might be worth investigating if we can
|
|
||||||
// make fullscreen work without messing with window styles (like
|
|
||||||
// maximized windows work).
|
|
||||||
mNonClientOffset.top = mVertResizeMargin + mCaptionHeight;
|
|
||||||
mNonClientOffset.bottom = mVertResizeMargin;
|
mNonClientOffset.bottom = mVertResizeMargin;
|
||||||
mNonClientOffset.left = mHorResizeMargin;
|
mNonClientOffset.left = mHorResizeMargin;
|
||||||
mNonClientOffset.right = mHorResizeMargin;
|
mNonClientOffset.right = mHorResizeMargin;
|
||||||
@@ -2620,7 +2670,12 @@ bool nsWindow::UpdateNonClientMargins(bool aReflowWindow) {
|
|||||||
// We make the entire frame part of the client area. We leave the default
|
// We make the entire frame part of the client area. We leave the default
|
||||||
// frame sizes for left, right and bottom since Windows will automagically
|
// frame sizes for left, right and bottom since Windows will automagically
|
||||||
// position the edges "offscreen" for maximized windows.
|
// position the edges "offscreen" for maximized windows.
|
||||||
mNonClientOffset.top = mCaptionHeight;
|
int verticalResize =
|
||||||
|
WinUtils::GetSystemMetricsForDpi(SM_CYFRAME, dpi) +
|
||||||
|
(hasCaption ? WinUtils::GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi)
|
||||||
|
: 0);
|
||||||
|
|
||||||
|
mNonClientOffset.top = mCaptionHeight - verticalResize;
|
||||||
mNonClientOffset.bottom = 0;
|
mNonClientOffset.bottom = 0;
|
||||||
mNonClientOffset.left = 0;
|
mNonClientOffset.left = 0;
|
||||||
mNonClientOffset.right = 0;
|
mNonClientOffset.right = 0;
|
||||||
@@ -2653,23 +2708,26 @@ bool nsWindow::UpdateNonClientMargins(bool aReflowWindow) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsWindow::SetCustomTitlebar(bool aCustomTitlebar) {
|
nsresult nsWindow::SetNonClientMargins(const LayoutDeviceIntMargin& margins) {
|
||||||
if (!IsTopLevelWidget() || mBorderStyle == BorderStyle::None) {
|
if (!IsTopLevelWidget() || mBorderStyle == BorderStyle::None) {
|
||||||
return;
|
return NS_ERROR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCustomNonClient == aCustomTitlebar) {
|
if (mNonClientMargins == margins) {
|
||||||
return;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mHideChrome) {
|
if (mHideChrome) {
|
||||||
mCustomTitlebarOnceChromeShows = Some(aCustomTitlebar);
|
mFutureMarginsOnceChromeShows = margins;
|
||||||
return;
|
mFutureMarginsToUse = true;
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCustomTitlebarOnceChromeShows.reset();
|
mFutureMarginsToUse = false;
|
||||||
|
|
||||||
mCustomNonClient = aCustomTitlebar;
|
// -1 margins request a reset
|
||||||
|
mCustomNonClient = margins != LayoutDeviceIntMargin(-1, -1, -1, -1);
|
||||||
|
mNonClientMargins = margins;
|
||||||
|
|
||||||
// Force a reflow of content based on the new client dimensions.
|
// Force a reflow of content based on the new client dimensions.
|
||||||
if (mCustomNonClient) {
|
if (mCustomNonClient) {
|
||||||
@@ -2677,10 +2735,15 @@ void nsWindow::SetCustomTitlebar(bool aCustomTitlebar) {
|
|||||||
} else {
|
} else {
|
||||||
ResetLayout();
|
ResetLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsWindow::SetResizeMargin(mozilla::LayoutDeviceIntCoord aResizeMargin) {
|
void nsWindow::SetResizeMargin(mozilla::LayoutDeviceIntCoord aResizeMargin) {
|
||||||
mCustomResizeMargin = aResizeMargin;
|
mUseResizeMarginOverrides = true;
|
||||||
|
mHorResizeMargin = aResizeMargin;
|
||||||
|
mVertResizeMargin = aResizeMargin;
|
||||||
|
UpdateNonClientMargins();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoRegion nsWindow::ComputeNonClientHRGN() {
|
nsAutoRegion nsWindow::ComputeNonClientHRGN() {
|
||||||
@@ -2705,7 +2768,7 @@ nsAutoRegion nsWindow::ComputeNonClientHRGN() {
|
|||||||
// windows non-client chrome and app non-client chrome
|
// windows non-client chrome and app non-client chrome
|
||||||
// in winRgn.
|
// in winRgn.
|
||||||
::GetWindowRect(mWnd, &rect);
|
::GetWindowRect(mWnd, &rect);
|
||||||
rect.top += mCaptionHeight + mVertResizeMargin;
|
rect.top += mCaptionHeight;
|
||||||
rect.right -= mHorResizeMargin;
|
rect.right -= mHorResizeMargin;
|
||||||
rect.bottom -= mVertResizeMargin;
|
rect.bottom -= mVertResizeMargin;
|
||||||
rect.left += mHorResizeMargin;
|
rect.left += mHorResizeMargin;
|
||||||
@@ -2975,9 +3038,8 @@ void nsWindow::HideWindowChrome(bool aShouldHide) {
|
|||||||
// if there's nothing to "restore" it to, just use what's there now
|
// if there's nothing to "restore" it to, just use what's there now
|
||||||
oldChrome = mOldStyles.refOr(currentChrome);
|
oldChrome = mOldStyles.refOr(currentChrome);
|
||||||
newChrome = oldChrome;
|
newChrome = oldChrome;
|
||||||
if (mCustomTitlebarOnceChromeShows) {
|
if (mFutureMarginsToUse) {
|
||||||
SetCustomTitlebar(mCustomTitlebarOnceChromeShows.extract());
|
SetNonClientMargins(mFutureMarginsOnceChromeShows);
|
||||||
MOZ_ASSERT(!mCustomTitlebarOnceChromeShows);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4922,9 +4984,8 @@ bool nsWindow::ProcessMessageInternal(UINT msg, WPARAM& wParam, LPARAM& lParam,
|
|||||||
* sending the message with an updated title
|
* sending the message with an updated title
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (mSendingSetText || !mCustomNonClient) {
|
if (mSendingSetText || !mCustomNonClient || mNonClientMargins.top == -1)
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// From msdn, the way around this is to disable the visible state
|
// From msdn, the way around this is to disable the visible state
|
||||||
@@ -5867,8 +5928,7 @@ void nsWindow::FinishLiveResizing(ResizeState aNewState) {
|
|||||||
|
|
||||||
LayoutDeviceIntMargin nsWindow::NonClientSizeMargin(
|
LayoutDeviceIntMargin nsWindow::NonClientSizeMargin(
|
||||||
const LayoutDeviceIntMargin& aNonClientOffset) const {
|
const LayoutDeviceIntMargin& aNonClientOffset) const {
|
||||||
return LayoutDeviceIntMargin(
|
return LayoutDeviceIntMargin(mCaptionHeight - aNonClientOffset.top,
|
||||||
mCaptionHeight + mVertResizeMargin - aNonClientOffset.top,
|
|
||||||
mHorResizeMargin - aNonClientOffset.right,
|
mHorResizeMargin - aNonClientOffset.right,
|
||||||
mVertResizeMargin - aNonClientOffset.bottom,
|
mVertResizeMargin - aNonClientOffset.bottom,
|
||||||
mHorResizeMargin - aNonClientOffset.left);
|
mHorResizeMargin - aNonClientOffset.left);
|
||||||
@@ -5924,12 +5984,6 @@ int32_t nsWindow::ClientMarginHitTestPoint(int32_t aX, int32_t aY) {
|
|||||||
borderSize.EnsureAtLeast(
|
borderSize.EnsureAtLeast(
|
||||||
LayoutDeviceIntMargin(mVertResizeMargin, mHorResizeMargin,
|
LayoutDeviceIntMargin(mVertResizeMargin, mHorResizeMargin,
|
||||||
mVertResizeMargin, mHorResizeMargin));
|
mVertResizeMargin, mHorResizeMargin));
|
||||||
// If we have a custom resize margin, check for it too.
|
|
||||||
if (mCustomResizeMargin) {
|
|
||||||
borderSize.EnsureAtLeast(
|
|
||||||
LayoutDeviceIntMargin(mCustomResizeMargin, mCustomResizeMargin,
|
|
||||||
mCustomResizeMargin, mCustomResizeMargin));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool top = false;
|
bool top = false;
|
||||||
bool bottom = false;
|
bool bottom = false;
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ class nsWindow final : public nsBaseWidget {
|
|||||||
TextEventDispatcherListener* GetNativeTextEventDispatcherListener() override;
|
TextEventDispatcherListener* GetNativeTextEventDispatcherListener() override;
|
||||||
void SetTransparencyMode(TransparencyMode aMode) override;
|
void SetTransparencyMode(TransparencyMode aMode) override;
|
||||||
TransparencyMode GetTransparencyMode() override;
|
TransparencyMode GetTransparencyMode() override;
|
||||||
void SetCustomTitlebar(bool) override;
|
nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override;
|
||||||
void SetResizeMargin(mozilla::LayoutDeviceIntCoord aResizeMargin) override;
|
void SetResizeMargin(mozilla::LayoutDeviceIntCoord aResizeMargin) override;
|
||||||
void UpdateWindowDraggingRegion(
|
void UpdateWindowDraggingRegion(
|
||||||
const LayoutDeviceIntRegion& aRegion) override;
|
const LayoutDeviceIntRegion& aRegion) override;
|
||||||
@@ -802,20 +802,23 @@ class nsWindow final : public nsBaseWidget {
|
|||||||
// Non-client margin settings
|
// Non-client margin settings
|
||||||
// Pre-calculated outward offset applied to default frames
|
// Pre-calculated outward offset applied to default frames
|
||||||
LayoutDeviceIntMargin mNonClientOffset;
|
LayoutDeviceIntMargin mNonClientOffset;
|
||||||
|
// Margins set by the owner
|
||||||
|
LayoutDeviceIntMargin mNonClientMargins{-1, -1, -1, -1};
|
||||||
|
// Margins we'd like to set once chrome is reshown:
|
||||||
|
LayoutDeviceIntMargin mFutureMarginsOnceChromeShows;
|
||||||
|
// Indicates we need to apply margins once toggling chrome into showing:
|
||||||
|
bool mFutureMarginsToUse = false;
|
||||||
|
|
||||||
// Indicates the custom titlebar is enabled.
|
// Indicates custom frames are enabled
|
||||||
bool mCustomNonClient = false;
|
bool mCustomNonClient = false;
|
||||||
// Whether we want to draw to the titlebar once the chrome shows. (Always
|
// Indicates custom resize margins are in effect
|
||||||
// Nothing if mHideChrome is false).
|
bool mUseResizeMarginOverrides = false;
|
||||||
mozilla::Maybe<bool> mCustomTitlebarOnceChromeShows;
|
|
||||||
// Width of the left and right portions of the resize region
|
// Width of the left and right portions of the resize region
|
||||||
mozilla::LayoutDeviceIntCoord mHorResizeMargin;
|
mozilla::LayoutDeviceIntCoord mHorResizeMargin;
|
||||||
// Height of the top and bottom portions of the resize region
|
// Height of the top and bottom portions of the resize region
|
||||||
mozilla::LayoutDeviceIntCoord mVertResizeMargin;
|
mozilla::LayoutDeviceIntCoord mVertResizeMargin;
|
||||||
// Height of the caption plus border
|
// Height of the caption plus border
|
||||||
mozilla::LayoutDeviceIntCoord mCaptionHeight;
|
mozilla::LayoutDeviceIntCoord mCaptionHeight;
|
||||||
// Custom extra resize margin width.
|
|
||||||
mozilla::LayoutDeviceIntCoord mCustomResizeMargin{0};
|
|
||||||
|
|
||||||
// not yet set, will be calculated on first use
|
// not yet set, will be calculated on first use
|
||||||
double mDefaultScale = -1.0;
|
double mDefaultScale = -1.0;
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ STATIC_ATOMS = [
|
|||||||
Atom("childList", "childList"),
|
Atom("childList", "childList"),
|
||||||
Atom("child_item_count", "child-item-count"),
|
Atom("child_item_count", "child-item-count"),
|
||||||
Atom("choose", "choose"),
|
Atom("choose", "choose"),
|
||||||
Atom("customtitlebar", "customtitlebar"),
|
Atom("chromemargin", "chromemargin"),
|
||||||
Atom("exposeToUntrustedContent", "exposeToUntrustedContent"),
|
Atom("exposeToUntrustedContent", "exposeToUntrustedContent"),
|
||||||
Atom("circ", "circ"),
|
Atom("circ", "circ"),
|
||||||
Atom("circle", "circle"),
|
Atom("circle", "circle"),
|
||||||
|
|||||||
@@ -1501,7 +1501,7 @@ void AppWindow::SyncAttributesToWidget() {
|
|||||||
|
|
||||||
nsAutoString attr;
|
nsAutoString attr;
|
||||||
|
|
||||||
// Some attributes can change the client size (e.g. customtitlebar on Windows
|
// Some attributes can change the client size (e.g. chromemargin on Windows
|
||||||
// and MacOS). But we might want to keep it.
|
// and MacOS). But we might want to keep it.
|
||||||
const LayoutDeviceIntSize oldClientSize = mWindow->GetClientSize();
|
const LayoutDeviceIntSize oldClientSize = mWindow->GetClientSize();
|
||||||
// We have to check now whether we want to restore the client size, as any
|
// We have to check now whether we want to restore the client size, as any
|
||||||
@@ -1509,16 +1509,19 @@ void AppWindow::SyncAttributesToWidget() {
|
|||||||
bool maintainClientSize = mDominantClientSize;
|
bool maintainClientSize = mDominantClientSize;
|
||||||
|
|
||||||
// "hidechrome" attribute
|
// "hidechrome" attribute
|
||||||
mWindow->HideWindowChrome(windowElement->GetBoolAttr(nsGkAtoms::hidechrome));
|
if (windowElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidechrome,
|
||||||
|
nsGkAtoms::_true, eCaseMatters)) {
|
||||||
|
mWindow->HideWindowChrome(true);
|
||||||
|
}
|
||||||
|
|
||||||
NS_ENSURE_TRUE_VOID(mWindow);
|
NS_ENSURE_TRUE_VOID(mWindow);
|
||||||
|
|
||||||
// "customtitlebar" attribute
|
// "chromemargin" attribute
|
||||||
// FIXME(emilio): This should arguably be
|
nsIntMargin margins;
|
||||||
// SetCustomTitlebar(windowElement->GetBoolAttr(...)), but that breaks with
|
windowElement->GetAttribute(u"chromemargin"_ns, attr);
|
||||||
// the early blank window which sets the custom titlebar via
|
if (nsContentUtils::ParseIntMarginValue(attr, margins)) {
|
||||||
// nsIDOMWindowUtils...
|
mWindow->SetNonClientMargins(
|
||||||
if (windowElement->GetBoolAttr(nsGkAtoms::customtitlebar)) {
|
LayoutDeviceIntMargin::FromUnknownMargin(margins));
|
||||||
mWindow->SetCustomTitlebar(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ENSURE_TRUE_VOID(mWindow);
|
NS_ENSURE_TRUE_VOID(mWindow);
|
||||||
@@ -1547,17 +1550,18 @@ void AppWindow::SyncAttributesToWidget() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// "drawtitle" attribute
|
// "drawtitle" attribute
|
||||||
mWindow->SetDrawsTitle(windowElement->GetBoolAttr(nsGkAtoms::drawtitle));
|
windowElement->GetAttribute(u"drawtitle"_ns, attr);
|
||||||
|
mWindow->SetDrawsTitle(attr.LowerCaseEqualsLiteral("true"));
|
||||||
NS_ENSURE_TRUE_VOID(mWindow);
|
NS_ENSURE_TRUE_VOID(mWindow);
|
||||||
|
|
||||||
// "toggletoolbar" attribute
|
// "toggletoolbar" attribute
|
||||||
mWindow->SetShowsToolbarButton(
|
windowElement->GetAttribute(u"toggletoolbar"_ns, attr);
|
||||||
windowElement->HasAttribute(u"toggletoolbar"_ns));
|
mWindow->SetShowsToolbarButton(attr.LowerCaseEqualsLiteral("true"));
|
||||||
NS_ENSURE_TRUE_VOID(mWindow);
|
NS_ENSURE_TRUE_VOID(mWindow);
|
||||||
|
|
||||||
// "macnativefullscreen" attribute
|
// "macnativefullscreen" attribute
|
||||||
mWindow->SetSupportsNativeFullscreen(
|
windowElement->GetAttribute(u"macnativefullscreen"_ns, attr);
|
||||||
windowElement->HasAttribute(u"macnativefullscreen"_ns));
|
mWindow->SetSupportsNativeFullscreen(attr.LowerCaseEqualsLiteral("true"));
|
||||||
NS_ENSURE_TRUE_VOID(mWindow);
|
NS_ENSURE_TRUE_VOID(mWindow);
|
||||||
|
|
||||||
// "macanimationtype" attribute
|
// "macanimationtype" attribute
|
||||||
@@ -2342,7 +2346,7 @@ NS_IMETHODIMP
|
|||||||
AppWindow::BeforeStartLayout() {
|
AppWindow::BeforeStartLayout() {
|
||||||
ApplyChromeFlags();
|
ApplyChromeFlags();
|
||||||
// Ordering here is important, loading width/height values in
|
// Ordering here is important, loading width/height values in
|
||||||
// LoadPersistentWindowState() depends on the customtitlebar attribute (since
|
// LoadPersistentWindowState() depends on the chromemargin attribute (since
|
||||||
// we need to translate outer to inner sizes).
|
// we need to translate outer to inner sizes).
|
||||||
SyncAttributesToWidget();
|
SyncAttributesToWidget();
|
||||||
LoadPersistentWindowState();
|
LoadPersistentWindowState();
|
||||||
|
|||||||
Reference in New Issue
Block a user