Bug 1930292 - Turn chromemargin into a boolean attribute. r=win-reviewers,desktop-theme-reviewers,pip-reviewers,firefox-desktop-core-reviewers ,dao,mconley,rkraesig
There are probably other simplifications that can be done after this on the windows side of things, but I tried to keep this minimal. Differential Revision: https://phabricator.services.mozilla.com/D229765
This commit is contained in:
@@ -105,7 +105,8 @@ var gBrowserInit = {
|
|||||||
// Run menubar initialization first, to avoid TabsInTitlebar 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 chromemargin attribute so the window can be sized correctly.
|
// Update the customtitlebar attribute so the window can be sized
|
||||||
|
// correctly.
|
||||||
window.TabBarVisibility.update();
|
window.TabBarVisibility.update();
|
||||||
TabsInTitlebar.init();
|
TabsInTitlebar.init();
|
||||||
|
|
||||||
|
|||||||
@@ -69,13 +69,13 @@ var TabsInTitlebar = {
|
|||||||
!Object.keys(this._disallowed).length;
|
!Object.keys(this._disallowed).length;
|
||||||
if (allowed) {
|
if (allowed) {
|
||||||
document.documentElement.setAttribute("tabsintitlebar", "true");
|
document.documentElement.setAttribute("tabsintitlebar", "true");
|
||||||
document.documentElement.setAttribute("chromemargin", "0,0,0,0");
|
document.documentElement.setAttribute("customtitlebar", "true");
|
||||||
if (AppConstants.platform == "macosx") {
|
if (AppConstants.platform == "macosx") {
|
||||||
document.documentElement.removeAttribute("drawtitle");
|
document.documentElement.removeAttribute("drawtitle");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
document.documentElement.removeAttribute("tabsintitlebar");
|
document.documentElement.removeAttribute("tabsintitlebar");
|
||||||
document.documentElement.removeAttribute("chromemargin");
|
document.documentElement.removeAttribute("customtitlebar");
|
||||||
if (AppConstants.platform == "macosx") {
|
if (AppConstants.platform == "macosx") {
|
||||||
document.documentElement.setAttribute("drawtitle", "true");
|
document.documentElement.setAttribute("drawtitle", "true");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
#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"
|
||||||
chromemargin="0,0,0,0"
|
customtitlebar="true"
|
||||||
tabsintitlebar="true"
|
tabsintitlebar="true"
|
||||||
windowtype="navigator:browser"
|
windowtype="navigator:browser"
|
||||||
macanimationtype="document"
|
macanimationtype="document"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
windowtype="Browser:page-info"
|
windowtype="Browser:page-info"
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
drawtitle="true"
|
drawtitle="true"
|
||||||
chromemargin="0,0,0,0"
|
customtitlebar="true"
|
||||||
#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"
|
||||||
chromemargin="0,0,0,0"
|
customtitlebar="true"
|
||||||
>
|
>
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="chrome://global/skin/global.css" />
|
<link rel="stylesheet" href="chrome://global/skin/global.css" />
|
||||||
|
|||||||
@@ -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.setChromeMargin(0, 0, 0, 0);
|
win.windowUtils.setCustomTitlebar(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
let docElt = win.document.documentElement;
|
let docElt = win.document.documentElement;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
screenX="10" screenY="10"
|
screenX="10" screenY="10"
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
drawtitle="true"
|
drawtitle="true"
|
||||||
chromemargin="0,0,0,0"
|
customtitlebar="true"
|
||||||
#endif
|
#endif
|
||||||
toggletoolbar="true"
|
toggletoolbar="true"
|
||||||
persist="width height screenX screenY sizemode">
|
persist="width height screenX screenY sizemode">
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ body {
|
|||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root:not([chromemargin], [inFullscreen]) & {
|
:root:not([customtitlebar], [inFullscreen]) & {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1819,50 +1819,6 @@ 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,17 +874,6 @@ 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,32 +4192,27 @@ nsDOMWindowUtils::PostRestyleSelfEvent(Element* aElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMWindowUtils::SetChromeMargin(int32_t aTop, int32_t aRight, int32_t aBottom,
|
nsDOMWindowUtils::SetCustomTitlebar(bool aCustomTitlebar) {
|
||||||
int32_t aLeft) {
|
// 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) {
|
||||||
LayoutDeviceIntMargin margins(aTop, aRight, aBottom, aLeft);
|
widget->SetCustomTitlebar(aCustomTitlebar);
|
||||||
return widget->SetNonClientMargins(margins);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMWindowUtils::SetResizeMargin(int32_t aResizeMargin) {
|
nsDOMWindowUtils::SetResizeMargin(int32_t aResizeMargin) {
|
||||||
nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
|
// TODO(emilio): Can't we use nsDOMWindowUtils::GetWidget()?
|
||||||
if (window) {
|
if (nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow)) {
|
||||||
nsCOMPtr<nsIBaseWindow> baseWindow =
|
if (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,14 +2053,11 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||||||
readonly attribute boolean refreshDriverHasPendingTick;
|
readonly attribute boolean refreshDriverHasPendingTick;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the amount of chrome that should be visible on each side of
|
* Controls whether we paint to the titlebar of the window.
|
||||||
* the window. Works like the chromemargin xul:window attribute.
|
* Works like the customtitlebar xul:window attribute.
|
||||||
* This should only be used with non-XUL windows.
|
* This should only be used with non-XUL windows.
|
||||||
*/
|
*/
|
||||||
void setChromeMargin(in int32_t aTop,
|
void setCustomTitlebar(in boolean aCustomTitlebar);
|
||||||
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::chromemargin) {
|
if (name->LocalName() == nsGkAtoms::customtitlebar) {
|
||||||
// Some linux windows managers have an issue when the chrome margin is
|
// Some linux windows managers have an issue when the customtitlebar 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,43 +73,6 @@ 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,
|
||||||
@@ -124,8 +87,8 @@ void ChromeObserver::AttributeChanged(dom::Element* aElement,
|
|||||||
// Hide chrome if needed
|
// Hide chrome if needed
|
||||||
if (aName == nsGkAtoms::hidechrome) {
|
if (aName == nsGkAtoms::hidechrome) {
|
||||||
HideWindowChrome(value->Equals(u"true"_ns, eCaseMatters));
|
HideWindowChrome(value->Equals(u"true"_ns, eCaseMatters));
|
||||||
} else if (aName == nsGkAtoms::chromemargin) {
|
} else if (aName == nsGkAtoms::customtitlebar) {
|
||||||
SetChromeMargins(value);
|
SetCustomTitlebar(true);
|
||||||
}
|
}
|
||||||
// title and drawintitlebar are settable on
|
// title and drawintitlebar are settable on
|
||||||
// any root node (windows, dialogs, etc)
|
// any root node (windows, dialogs, etc)
|
||||||
@@ -141,8 +104,8 @@ void ChromeObserver::AttributeChanged(dom::Element* aElement,
|
|||||||
} else {
|
} else {
|
||||||
if (aName == nsGkAtoms::hidechrome) {
|
if (aName == nsGkAtoms::hidechrome) {
|
||||||
HideWindowChrome(false);
|
HideWindowChrome(false);
|
||||||
} else if (aName == nsGkAtoms::chromemargin) {
|
} else if (aName == nsGkAtoms::customtitlebar) {
|
||||||
ResetChromeMargins();
|
SetCustomTitlebar(false);
|
||||||
} else if (aName == nsGkAtoms::localedir) {
|
} else 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
|
||||||
@@ -157,11 +120,14 @@ void ChromeObserver::NodeWillBeDestroyed(nsINode* aNode) {
|
|||||||
mDocument = nullptr;
|
mDocument = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChromeObserver::ResetChromeMargins() {
|
void ChromeObserver::SetCustomTitlebar(bool aCustomTitlebar) {
|
||||||
nsIWidget* mainWidget = GetWindowWidget();
|
if (nsIWidget* mainWidget = GetWindowWidget()) {
|
||||||
if (!mainWidget) return;
|
// SetCustomTitlebar can dispatch native events, hence doing it off a
|
||||||
// See nsIWidget
|
// script runner
|
||||||
nsContentUtils::AddScriptRunner(new MarginSetter(mainWidget));
|
nsContentUtils::AddScriptRunner(NewRunnableMethod<bool>(
|
||||||
|
"SetCustomTitlebar", mainWidget, &nsIWidget::SetCustomTitlebar,
|
||||||
|
aCustomTitlebar));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult ChromeObserver::HideWindowChrome(bool aShouldHide) {
|
nsresult ChromeObserver::HideWindowChrome(bool aShouldHide) {
|
||||||
|
|||||||
@@ -27,11 +27,8 @@ 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;
|
||||||
|
|||||||
@@ -1997,13 +1997,10 @@ static Result<Ok, PreXULSkeletonUIError> CreateAndStorePreXULSkeletonUIImpl(
|
|||||||
// These match the offsets that we get with default prefs. We don't use the
|
// These match the offsets that we get with default prefs. We don't use the
|
||||||
// skeleton ui if tabsInTitlebar is disabled, see bug 1673092.
|
// skeleton ui if tabsInTitlebar is disabled, see bug 1673092.
|
||||||
if (sMaximized) {
|
if (sMaximized) {
|
||||||
sNonClientOffset.top = sCaptionHeight;
|
sNonClientOffset = Margin{sCaptionHeight, 0, 0, 0};
|
||||||
} else {
|
} else {
|
||||||
// See nsWindow::NormalWindowNonClientOffset()
|
// See nsWindow::NormalWindowNonClientOffset()
|
||||||
sNonClientOffset.top = sCaptionHeight + sVerticalResizeMargin;
|
sNonClientOffset = Margin{sCaptionHeight + sVerticalResizeMargin, 0, 0, 0};
|
||||||
sNonClientOffset.bottom = 0;
|
|
||||||
sNonClientOffset.left = 0;
|
|
||||||
sNonClientOffset.right = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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"
|
||||||
chromemargin="0,0,0,0"
|
customtitlebar="true"
|
||||||
scrolling="false"
|
scrolling="false"
|
||||||
>
|
>
|
||||||
<head>
|
<head>
|
||||||
|
|||||||
@@ -143,10 +143,6 @@ 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"]
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
<?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>
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
<?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"
|
||||||
chromemargin="0,0,0,0"
|
customtitlebar="true"
|
||||||
id="window"
|
id="window"
|
||||||
persist="height width sizemode">
|
persist="height width sizemode">
|
||||||
<script type="application/javascript"><![CDATA[
|
<script type="application/javascript"><![CDATA[
|
||||||
|
|||||||
@@ -283,8 +283,7 @@ 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;
|
||||||
nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override;
|
void SetCustomTitlebar(bool) 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,18 +2464,7 @@ void nsCocoaWindow::SetDrawsTitle(bool aDrawTitle) {
|
|||||||
NS_OBJC_END_TRY_IGNORE_BLOCK;
|
NS_OBJC_END_TRY_IGNORE_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsCocoaWindow::SetNonClientMargins(
|
void nsCocoaWindow::SetCustomTitlebar(bool aState) {
|
||||||
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,11 +8774,6 @@ 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;
|
||||||
@@ -8793,8 +8788,8 @@ bool nsWindow::IsAlwaysUndecoratedWindow() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsWindow::SetDrawsInTitlebar(bool aState) {
|
void nsWindow::SetCustomTitlebar(bool aState) {
|
||||||
LOG("nsWindow::SetDrawsInTitlebar() State %d mGtkWindowDecoration %d\n",
|
LOG("nsWindow::SetCustomTitlebar() State %d mGtkWindowDecoration %d\n",
|
||||||
aState, (int)mGtkWindowDecoration);
|
aState, (int)mGtkWindowDecoration);
|
||||||
|
|
||||||
if (mGtkWindowDecoration == GTK_DECORATION_NONE ||
|
if (mGtkWindowDecoration == GTK_DECORATION_NONE ||
|
||||||
|
|||||||
@@ -373,8 +373,7 @@ class nsWindow final : public nsBaseWidget {
|
|||||||
void GetCompositorWidgetInitData(
|
void GetCompositorWidgetInitData(
|
||||||
mozilla::widget::CompositorWidgetInitData* aInitData) override;
|
mozilla::widget::CompositorWidgetInitData* aInitData) override;
|
||||||
|
|
||||||
nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override;
|
void SetCustomTitlebar(bool) 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 : public nsBaseWidget {
|
class HeadlessWidget final : public nsBaseWidget {
|
||||||
public:
|
public:
|
||||||
HeadlessWidget();
|
HeadlessWidget();
|
||||||
|
|
||||||
@@ -77,10 +77,6 @@ class HeadlessWidget : 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,12 +1747,6 @@ 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,11 +252,9 @@ 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,24 +870,15 @@ class nsIWidget : public nsISupports {
|
|||||||
*/
|
*/
|
||||||
virtual LayoutDeviceIntRect GetClientBounds() = 0;
|
virtual LayoutDeviceIntRect GetClientBounds() = 0;
|
||||||
|
|
||||||
/**
|
/** Whether to extend the client area into the titlebar. */
|
||||||
* Sets the non-client area dimensions of the window. Pass -1 to restore
|
virtual void SetCustomTitlebar(bool) {}
|
||||||
* 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 aResizeMargin) = 0;
|
virtual void SetResizeMargin(mozilla::LayoutDeviceIntCoord) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the client offset from the window origin.
|
* Get the client offset from the window origin.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,130 +0,0 @@
|
|||||||
/* -*- 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,9 +16,6 @@ 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")
|
||||||
|
|
||||||
@@ -117,9 +114,3 @@ 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("chromemargin", "0,0,0,0");
|
document.documentElement.setAttribute("customtitlebar", "true");
|
||||||
|
|
||||||
await executeSoon();
|
await executeSoon();
|
||||||
is(window.outerWidth, oldOuterWidth, "chromemargin shouldn't change the window's outerWidth");
|
is(window.outerWidth, oldOuterWidth, "customtitlebar shouldn't change the window's outerWidth");
|
||||||
is(window.outerHeight, oldOuterHeight, "chromemargin shouldn't change the window's outerHeight");
|
is(window.outerHeight, oldOuterHeight, "customtitlebar shouldn't change the window's outerHeight");
|
||||||
is(window.innerWidth, oldOuterWidth, "if chromemargin is set, innerWidth and outerWidth should be the same");
|
is(window.innerWidth, oldOuterWidth, "if customtitlebar is set, innerWidth and outerWidth should be the same");
|
||||||
is(window.innerHeight, oldOuterHeight, "if chromemargin is set, innerHeight and outerHeight should be the same");
|
is(window.innerHeight, oldOuterHeight, "if customtitlebar 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("chromemargin");
|
document.documentElement.removeAttribute("customtitlebar");
|
||||||
|
|
||||||
await executeSoon();
|
await executeSoon();
|
||||||
is(window.outerWidth, oldOuterWidth, "wrong outerWidth after removing chromemargin");
|
is(window.outerWidth, oldOuterWidth, "wrong outerWidth after removing customtitlebar");
|
||||||
is(window.outerHeight, oldOuterHeight, "wrong outerHeight after removing chromemargin");
|
is(window.outerHeight, oldOuterHeight, "wrong outerHeight after removing customtitlebar");
|
||||||
is(window.innerWidth, oldInnerWidth, "wrong innerWidth after removing chromemargin");
|
is(window.innerWidth, oldInnerWidth, "wrong innerWidth after removing customtitlebar");
|
||||||
is(window.innerHeight, oldInnerHeight, "wrong innerHeight after removing chromemargin");
|
is(window.innerHeight, oldInnerHeight, "wrong innerHeight after removing customtitlebar");
|
||||||
window.arguments[0].SimpleTest.finish();
|
window.arguments[0].SimpleTest.finish();
|
||||||
window.close();
|
window.close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -940,10 +940,8 @@ nsresult nsWindow::Create(nsIWidget* aParent, const LayoutDeviceIntRect& aRect,
|
|||||||
DesktopIntRect::Round(LayoutDeviceRect(GetBounds()) / scale)
|
DesktopIntRect::Round(LayoutDeviceRect(GetBounds()) / scale)
|
||||||
.ToUnknownRect());
|
.ToUnknownRect());
|
||||||
|
|
||||||
// These match the margins set in browser-tabsintitlebar.js with
|
// Skeleton ui is disabled when custom titlebar is off, see bug 1673092.
|
||||||
// default prefs on Windows. Bug 1673092 tracks lining this up with
|
SetCustomTitlebar(true);
|
||||||
// that more correctly instead of hard-coding it.
|
|
||||||
SetNonClientMargins(LayoutDeviceIntMargin());
|
|
||||||
// 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;
|
||||||
@@ -2337,7 +2335,7 @@ void nsWindow::SetFocus(Raise aRaise, mozilla::dom::CallerType aCallerType) {
|
|||||||
* SECTION: Bounds
|
* SECTION: Bounds
|
||||||
*
|
*
|
||||||
* GetBounds, GetClientBounds, GetScreenBounds,
|
* GetBounds, GetClientBounds, GetScreenBounds,
|
||||||
* GetRestoredBounds, GetClientOffset, SetNonClientMargins
|
* GetRestoredBounds, GetClientOffset, SetCustomTitlebar
|
||||||
*
|
*
|
||||||
* Bound calculations.
|
* Bound calculations.
|
||||||
*
|
*
|
||||||
@@ -2523,31 +2521,17 @@ void nsWindow::SetColorScheme(const Maybe<ColorScheme>& aScheme) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LayoutDeviceIntMargin nsWindow::NormalWindowNonClientOffset() const {
|
LayoutDeviceIntMargin nsWindow::NormalWindowNonClientOffset() const {
|
||||||
LayoutDeviceIntMargin nonClientOffset;
|
MOZ_ASSERT(mCustomNonClient);
|
||||||
|
|
||||||
// We're dealing with a "normal" window (not maximized, minimized, or
|
// We're dealing with a "normal" window (not maximized, minimized, or
|
||||||
// fullscreen), so process `mNonClientMargins` and set `mNonClientOffset`
|
// fullscreen), so set `mNonClientOffset` accordingly.
|
||||||
// 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.
|
||||||
constexpr LayoutDeviceIntCoord kZero(0);
|
//
|
||||||
if (mNonClientMargins.top == 0) {
|
// When using custom titlebar, we hide the titlebar and leave the default
|
||||||
// Top is a bit special, because we rely on 0 removing the caption entirely.
|
// frame on the other sides.
|
||||||
nonClientOffset.top = mCaptionHeight + mVertResizeMargin;
|
return LayoutDeviceIntMargin(mCaptionHeight + mVertResizeMargin, 0, 0, 0);
|
||||||
} else {
|
|
||||||
nonClientOffset.top =
|
|
||||||
std::clamp(mNonClientMargins.top, kZero, mVertResizeMargin);
|
|
||||||
}
|
|
||||||
nonClientOffset.bottom =
|
|
||||||
std::clamp(mNonClientMargins.bottom, kZero, mVertResizeMargin);
|
|
||||||
nonClientOffset.left =
|
|
||||||
std::clamp(mNonClientMargins.left, kZero, mHorResizeMargin);
|
|
||||||
nonClientOffset.right =
|
|
||||||
std::clamp(mNonClientMargins.right, kZero, mHorResizeMargin);
|
|
||||||
|
|
||||||
return nonClientOffset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2556,23 +2540,14 @@ 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 - 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, the values stored in
|
* For maximized, fullscreen, and minimized windows special processing takes
|
||||||
* `mNonClientMargins` are ignored, and special processing takes place.
|
* 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) {
|
||||||
@@ -2678,26 +2653,23 @@ bool nsWindow::UpdateNonClientMargins(bool aReflowWindow) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsWindow::SetNonClientMargins(const LayoutDeviceIntMargin& margins) {
|
void nsWindow::SetCustomTitlebar(bool aCustomTitlebar) {
|
||||||
if (!IsTopLevelWidget() || mBorderStyle == BorderStyle::None) {
|
if (!IsTopLevelWidget() || mBorderStyle == BorderStyle::None) {
|
||||||
return NS_ERROR_INVALID_ARG;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mNonClientMargins == margins) {
|
if (mCustomNonClient == aCustomTitlebar) {
|
||||||
return NS_OK;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mHideChrome) {
|
if (mHideChrome) {
|
||||||
mFutureMarginsOnceChromeShows = margins;
|
mCustomTitlebarOnceChromeShows = Some(aCustomTitlebar);
|
||||||
mFutureMarginsToUse = true;
|
return;
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mFutureMarginsToUse = false;
|
mCustomTitlebarOnceChromeShows.reset();
|
||||||
|
|
||||||
// -1 margins request a reset
|
mCustomNonClient = aCustomTitlebar;
|
||||||
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) {
|
||||||
@@ -2705,8 +2677,6 @@ nsresult nsWindow::SetNonClientMargins(const LayoutDeviceIntMargin& margins) {
|
|||||||
} else {
|
} else {
|
||||||
ResetLayout();
|
ResetLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsWindow::SetResizeMargin(mozilla::LayoutDeviceIntCoord aResizeMargin) {
|
void nsWindow::SetResizeMargin(mozilla::LayoutDeviceIntCoord aResizeMargin) {
|
||||||
@@ -3005,8 +2975,9 @@ 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 (mFutureMarginsToUse) {
|
if (mCustomTitlebarOnceChromeShows) {
|
||||||
SetNonClientMargins(mFutureMarginsOnceChromeShows);
|
SetCustomTitlebar(mCustomTitlebarOnceChromeShows.extract());
|
||||||
|
MOZ_ASSERT(!mCustomTitlebarOnceChromeShows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4951,8 +4922,9 @@ 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 || mNonClientMargins.top == -1)
|
if (mSendingSetText || !mCustomNonClient) {
|
||||||
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
|
||||||
|
|||||||
@@ -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;
|
||||||
nsresult SetNonClientMargins(const LayoutDeviceIntMargin&) override;
|
void SetCustomTitlebar(bool) 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,15 +802,12 @@ 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 custom frames are enabled
|
// Indicates the custom titlebar is enabled.
|
||||||
bool mCustomNonClient = false;
|
bool mCustomNonClient = false;
|
||||||
|
// Whether we want to draw to the titlebar once the chrome shows. (Always
|
||||||
|
// Nothing if mHideChrome is 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
|
||||||
|
|||||||
@@ -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("chromemargin", "chromemargin"),
|
Atom("customtitlebar", "customtitlebar"),
|
||||||
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. chromemargin on Windows
|
// Some attributes can change the client size (e.g. customtitlebar 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
|
||||||
@@ -1516,12 +1516,13 @@ void AppWindow::SyncAttributesToWidget() {
|
|||||||
|
|
||||||
NS_ENSURE_TRUE_VOID(mWindow);
|
NS_ENSURE_TRUE_VOID(mWindow);
|
||||||
|
|
||||||
// "chromemargin" attribute
|
// "customtitlebar" attribute
|
||||||
nsIntMargin margins;
|
// FIXME(emilio): This should arguably be
|
||||||
windowElement->GetAttribute(u"chromemargin"_ns, attr);
|
// SetCustomTitlebar(windowElement->GetBoolAttr(...)), but that breaks with
|
||||||
if (nsContentUtils::ParseIntMarginValue(attr, margins)) {
|
// the early blank window which sets the custom titlebar via
|
||||||
mWindow->SetNonClientMargins(
|
// nsIDOMWindowUtils...
|
||||||
LayoutDeviceIntMargin::FromUnknownMargin(margins));
|
if (windowElement->GetBoolAttr(nsGkAtoms::customtitlebar)) {
|
||||||
|
mWindow->SetCustomTitlebar(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ENSURE_TRUE_VOID(mWindow);
|
NS_ENSURE_TRUE_VOID(mWindow);
|
||||||
@@ -2346,7 +2347,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 chromemargin attribute (since
|
// LoadPersistentWindowState() depends on the customtitlebar 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