Bug 1331932 - Suppress window animations while we're restoring window dimension. r=mikedeboer,jimm,mstange

This commit is contained in:
Beekill95 2017-06-22 14:27:05 +07:00
parent 441d70f009
commit 4b50ba3fad
8 changed files with 88 additions and 36 deletions

View File

@ -3898,6 +3898,8 @@ var SessionStoreInternal = {
var _this = this;
function win_(aName) { return _this._getWindowDimension(win, aName); }
const dwu = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
// find available space on the screen where this window is being placed
let screen = gScreenManager.screenForRect(aLeft, aTop, aWidth, aHeight);
if (screen) {
@ -3945,38 +3947,47 @@ var SessionStoreInternal = {
aHeight = bottom - aTop;
}
// only modify those aspects which aren't correct yet
if (!isNaN(aLeft) && !isNaN(aTop) && (aLeft != win_("screenX") || aTop != win_("screenY"))) {
aWindow.moveTo(aLeft, aTop);
}
if (aWidth && aHeight && (aWidth != win_("width") || aHeight != win_("height")) && !gResistFingerprintingEnabled) {
// Don't resize the window if it's currently maximized and we would
// maximize it again shortly after.
if (aSizeMode != "maximized" || win_("sizemode") != "maximized") {
aWindow.resizeTo(aWidth, aHeight);
// Suppress animations.
dwu.suppressAnimation(true);
// We want to make sure users will get their animations back in case an exception is thrown.
try {
// only modify those aspects which aren't correct yet
if (!isNaN(aLeft) && !isNaN(aTop) && (aLeft != win_("screenX") || aTop != win_("screenY"))) {
aWindow.moveTo(aLeft, aTop);
}
}
if (aSizeMode && win_("sizemode") != aSizeMode && !gResistFingerprintingEnabled) {
switch (aSizeMode) {
case "maximized":
aWindow.maximize();
break;
case "minimized":
aWindow.minimize();
break;
case "normal":
aWindow.restore();
break;
if (aWidth && aHeight && (aWidth != win_("width") || aHeight != win_("height")) && !gResistFingerprintingEnabled) {
// Don't resize the window if it's currently maximized and we would
// maximize it again shortly after.
if (aSizeMode != "maximized" || win_("sizemode") != "maximized") {
aWindow.resizeTo(aWidth, aHeight);
}
}
}
var sidebar = aWindow.document.getElementById("sidebar-box");
if (sidebar.getAttribute("sidebarcommand") != aSidebar) {
aWindow.SidebarUI.show(aSidebar);
}
// since resizing/moving a window brings it to the foreground,
// we might want to re-focus the last focused window
if (this.windowToFocus) {
this.windowToFocus.focus();
if (aSizeMode && win_("sizemode") != aSizeMode && !gResistFingerprintingEnabled) {
switch (aSizeMode) {
case "maximized":
aWindow.maximize();
break;
case "minimized":
aWindow.minimize();
break;
case "normal":
aWindow.restore();
break;
}
}
var sidebar = aWindow.document.getElementById("sidebar-box");
if (sidebar.getAttribute("sidebarcommand") != aSidebar) {
aWindow.SidebarUI.show(aSidebar);
}
// since resizing/moving a window brings it to the foreground,
// we might want to re-focus the last focused window
if (this.windowToFocus) {
this.windowToFocus.focus();
}
} finally {
// Enable animations.
dwu.suppressAnimation(false);
}
},

View File

@ -1280,6 +1280,16 @@ nsDOMWindowUtils::SendNativeTouchTap(int32_t aScreenX,
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::SuppressAnimation(bool aSuppress)
{
nsIWidget* widget = GetWidget();
if (widget) {
widget->SuppressAnimation(aSuppress);
}
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::ClearNativeTouchSequence(nsIObserver* aObserver)
{

View File

@ -637,6 +637,12 @@ interface nsIDOMWindowUtils : nsISupports {
in nsIDOMElement aElement,
[optional] in nsIObserver aObserver);
/**
* Suppress animations that are applied to a window by OS when
* resizing, moving, changing size mode, ...
*/
void suppressAnimation(in boolean aSuppress);
/**
* The values for sendNativeMouseScrollEvent's aAdditionalFlags.
*/

View File

@ -253,6 +253,7 @@ public:
virtual void SetSizeConstraints(const SizeConstraints& aConstraints) override;
virtual void Move(double aX, double aY) override;
virtual void SetSizeMode(nsSizeMode aMode) override;
virtual void SuppressAnimation(bool aSuppress) override;
virtual void HideWindowChrome(bool aShouldHide) override;
void EnteredFullScreen(bool aFullScreen, bool aNativeMode = true);
@ -420,6 +421,7 @@ protected:
int32_t mNumModalDescendents;
InputContext mInputContext;
NSWindowAnimationBehavior mWindowAnimationBehavior;
};
#endif // nsCocoaWindow_h_

View File

@ -894,6 +894,7 @@ nsCocoaWindow::Show(bool bState)
}
}
[mWindow setAnimationBehavior:behavior];
mWindowAnimationBehavior = behavior;
}
[mWindow makeKeyAndOrderFront:nil];
NS_OBJC_END_TRY_ABORT_BLOCK;
@ -1299,6 +1300,18 @@ nsCocoaWindow::SetSizeMode(nsSizeMode aMode)
NS_OBJC_END_TRY_ABORT_BLOCK;
}
void
nsCocoaWindow::SuppressAnimation(bool aSuppress)
{
if ([mWindow respondsToSelector:@selector(setAnimationBehavior:)]) {
if (aSuppress) {
[mWindow setAnimationBehavior:NSWindowAnimationBehaviorNone];
} else {
[mWindow setAnimationBehavior:mWindowAnimationBehavior];
}
}
}
// This has to preserve the window's frame bounds.
// This method requires (as does the Windows impl.) that you call Resize shortly
// after calling HideWindowChrome. See bug 498835 for fixing this.

View File

@ -834,6 +834,11 @@ class nsIWidget : public nsISupports
*/
virtual void SetSizeMode(nsSizeMode aMode) = 0;
/**
* Suppress animations that are applied to a window by OS.
*/
virtual void SuppressAnimation(bool aSuppress) {}
/**
* Return size mode (minimized, maximized, normalized).
* Returns a value from nsSizeMode (see nsIWidgetListener.h)

View File

@ -859,9 +859,7 @@ nsWindow::Create(nsIWidget* aParent,
}
if (mOpeningAnimationSuppressed) {
DWORD dwAttribute = TRUE;
DwmSetWindowAttribute(mWnd, DWMWA_TRANSITIONS_FORCEDISABLED,
&dwAttribute, sizeof dwAttribute);
SuppressAnimation(true);
}
if (!IsPlugin() &&
@ -1648,9 +1646,7 @@ nsWindow::Show(bool bState)
#endif
if (mOpeningAnimationSuppressed) {
DWORD dwAttribute = FALSE;
DwmSetWindowAttribute(mWnd, DWMWA_TRANSITIONS_FORCEDISABLED,
&dwAttribute, sizeof dwAttribute);
SuppressAnimation(false);
}
}
@ -2132,6 +2128,14 @@ nsWindow::SetSizeMode(nsSizeMode aMode)
}
}
void
nsWindow::SuppressAnimation(bool aSuppress)
{
DWORD dwAttribute = aSuppress ? TRUE : FALSE;
DwmSetWindowAttribute(mWnd, DWMWA_TRANSITIONS_FORCEDISABLED,
&dwAttribute, sizeof dwAttribute);
}
// Constrain a potential move to fit onscreen
// Position (aX, aY) is specified in Windows screen (logical) pixels,
// except when using per-monitor DPI, in which case it's device pixels.

View File

@ -133,6 +133,7 @@ public:
int32_t aVertical) override;
virtual void PlaceBehind(nsTopLevelWidgetZPlacement aPlacement, nsIWidget *aWidget, bool aActivate) override;
virtual void SetSizeMode(nsSizeMode aMode) override;
virtual void SuppressAnimation(bool aSuppress) override;
virtual void Enable(bool aState) override;
virtual bool IsEnabled() const override;
virtual nsresult SetFocus(bool aRaise) override;