Bug 1373739 - Make headless widgets hidden by default, matching other platforms. r?bdahl
It seems that my reworking of how the z-index events are sent in the patch
pertaining to active window tracking made it so that we can have headless
widgets default to being invisible again, which matches the behavior on all
other platforms. This then allows us to avoid applying size mode change side
effects while a window/widget is invisible, matching the behavior on Windows and
allowing the relevant web platform tests to pass despite the low screen
resolution with which we run Windows VMs in testing (eg.
open-features-non-integer-height.html).
MozReview-Commit-ID: 3xnaEn7RImP
--- a/widget/headless/HeadlessWidget.cpp
+++ b/widget/headless/HeadlessWidget.cpp
@@ -50,17 +50,17 @@ HeadlessWidget::Create(nsIWidget* aParen
nsWidgetInitData* aInitData)
{
MOZ_ASSERT(!aNativeParent, "No native parents for headless widgets.");
BaseCreate(nullptr, aInitData);
mBounds = aRect;
mRestoreBounds = aRect;
- mVisible = true;
+ mVisible = false;
mEnabled = true;
if (aParent) {
mTopLevel = aParent->GetTopLevelWidget();
} else {
mTopLevel = this;
}
@@ -126,16 +126,18 @@ HeadlessWidget::RaiseWindow()
void
HeadlessWidget::Show(bool aState)
{
mVisible = aState;
// Top-level windows are activated/raised when shown.
if (aState && mTopLevel == this)
RaiseWindow();
+
+ ApplySizeModeSideEffects();
}
bool
HeadlessWidget::IsVisible() const
{
return mVisible;
}
@@ -241,28 +243,39 @@ HeadlessWidget::Resize(double aX,
}
void
HeadlessWidget::SetSizeMode(nsSizeMode aMode)
{
if (aMode == mSizeMode) {
return;
}
- if (mSizeMode == nsSizeMode_Normal) {
- // Store the last normal size bounds so it can be restored when entering
- // normal mode again.
- mRestoreBounds = mBounds;
- }
nsBaseWidget::SetSizeMode(aMode);
// Normally in real widget backends a window event would be triggered that
// would cause the window manager to handle resizing the window. In headless
// the window must manually be resized.
- switch(aMode) {
+ ApplySizeModeSideEffects();
+}
+
+void
+HeadlessWidget::ApplySizeModeSideEffects()
+{
+ if (!mVisible || mEffectiveSizeMode == mSizeMode) {
+ return;
+ }
+
+ if (mEffectiveSizeMode == nsSizeMode_Normal) {
+ // Store the last normal size bounds so it can be restored when entering
+ // normal mode again.
+ mRestoreBounds = mBounds;
+ }
+
+ switch(mSizeMode) {
case nsSizeMode_Normal: {
Resize(mRestoreBounds.x, mRestoreBounds.y, mRestoreBounds.width, mRestoreBounds.height, false);
break;
}
case nsSizeMode_Minimized:
break;
case nsSizeMode_Maximized: {
nsCOMPtr<nsIScreen> screen = GetWidgetScreen();
@@ -276,16 +289,18 @@ HeadlessWidget::SetSizeMode(nsSizeMode a
}
case nsSizeMode_Fullscreen:
// This will take care of resizing the window.
nsBaseWidget::InfallibleMakeFullScreen(true);
break;
default:
break;
}
+
+ mEffectiveSizeMode = mSizeMode;
}
nsresult
HeadlessWidget::MakeFullScreen(bool aFullScreen, nsIScreen* aTargetScreen)
{
// Directly update the size mode here so a later call SetSizeMode does
// nothing.
if (aFullScreen) {
--- a/widget/headless/HeadlessWidget.h
+++ b/widget/headless/HeadlessWidget.h
@@ -11,17 +11,17 @@
#include "nsBaseWidget.h"
namespace mozilla {
namespace widget {
class HeadlessWidget : public nsBaseWidget
{
public:
- HeadlessWidget() {}
+ HeadlessWidget() : mEffectiveSizeMode(nsSizeMode_Normal) {}
NS_DECL_ISUPPORTS_INHERITED
void* GetNativeData(uint32_t aDataType) override
{
// Headless widgets have no native data.
return nullptr;
}
@@ -90,20 +90,23 @@ public:
private:
~HeadlessWidget();
bool mEnabled;
bool mVisible;
nsIWidget* mTopLevel;
// The size mode before entering fullscreen mode.
nsSizeMode mLastSizeMode;
+ // The last size mode set while the window was visible.
+ nsSizeMode mEffectiveSizeMode;
InputContext mInputContext;
// In headless there is no window manager to track window bounds
// across size mode changes, so we must track it to emulate.
LayoutDeviceIntRect mRestoreBounds;
+ void ApplySizeModeSideEffects();
// Similarly, we must track the active window ourselves in order
// to dispatch (de)activation events properly.
void RaiseWindow();
static HeadlessWidget* sActiveWindow;
};
} // namespace widget
} // namespace mozilla