From 64f3815bd780c5ad3dc0d7c56d2274a1fa069041 Mon Sep 17 00:00:00 2001 From: Nigel Babu Date: Sat, 11 Jul 2015 10:49:25 +0530 Subject: [PATCH] Backed out 4 changesets (bug 1160014) for M2 bustages CLOSED TREE Backed out changeset 87b00a9dac95 (bug 1160014) Backed out changeset d4fa5c794e08 (bug 1160014) Backed out changeset fca26897d534 (bug 1160014) Backed out changeset b0b7f4f09ed2 (bug 1160014) --- browser/base/content/browser-fullScreen.js | 5 - browser/base/content/tab-content.js | 12 - .../browser_domFullscreen_fullscreenMode.js | 4 - .../test/general/test_contextmenu.html | 2 - dom/base/nsGlobalWindow.cpp | 213 +----------------- dom/base/nsGlobalWindow.h | 3 - dom/html/test/test_fullscreen-api.html | 8 +- .../chrome/test_MozDomFullscreen_event.xul | 8 +- .../pointerlock/test_pointerlock-api.html | 17 +- modules/libpref/init/all.js | 3 - widget/cocoa/nsCocoaWindow.h | 2 +- widget/cocoa/nsCocoaWindow.mm | 4 +- widget/nsBaseWidget.cpp | 76 +++---- widget/nsBaseWidget.h | 13 +- widget/nsIWidget.h | 40 +--- widget/windows/nsWindow.cpp | 195 ++-------------- widget/windows/nsWindow.h | 6 - widget/windows/nsWindowDefs.h | 13 +- 18 files changed, 86 insertions(+), 538 deletions(-) diff --git a/browser/base/content/browser-fullScreen.js b/browser/base/content/browser-fullScreen.js index fb3f776aac10..8dea4a869824 100644 --- a/browser/base/content/browser-fullScreen.js +++ b/browser/base/content/browser-fullScreen.js @@ -8,7 +8,6 @@ var FullScreen = { "DOMFullscreen:Request", "DOMFullscreen:NewOrigin", "DOMFullscreen:Exit", - "DOMFullscreen:Painted", ], init: function() { @@ -167,10 +166,6 @@ var FullScreen = { this._windowUtils.remoteFrameFullscreenReverted(); break; } - case "DOMFullscreen:Painted": { - Services.obs.notifyObservers(window, "fullscreen-painted", ""); - break; - } } }, diff --git a/browser/base/content/tab-content.js b/browser/base/content/tab-content.js index 2249aaa001d2..2316b34b4a1e 100644 --- a/browser/base/content/tab-content.js +++ b/browser/base/content/tab-content.js @@ -624,10 +624,8 @@ let DOMFullscreenHandler = { addMessageListener("DOMFullscreen:Approved", this); addMessageListener("DOMFullscreen:CleanUp", this); addEventListener("MozDOMFullscreen:Request", this); - addEventListener("MozDOMFullscreen:Entered", this); addEventListener("MozDOMFullscreen:NewOrigin", this); addEventListener("MozDOMFullscreen:Exit", this); - addEventListener("MozDOMFullscreen:Exited", this); }, get _windowUtils() { @@ -680,16 +678,6 @@ let DOMFullscreenHandler = { sendAsyncMessage("DOMFullscreen:Exit"); break; } - case "MozDOMFullscreen:Entered": - case "MozDOMFullscreen:Exited": { - addEventListener("MozAfterPaint", this); - break; - } - case "MozAfterPaint": { - removeEventListener("MozAfterPaint", this); - sendAsyncMessage("DOMFullscreen:Painted"); - break; - } } } }; diff --git a/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js b/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js index 24e8a0570b89..7ca92c8c3abd 100644 --- a/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js +++ b/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js @@ -121,10 +121,6 @@ let gTests = [ ]; add_task(function* () { - yield pushPrefs( - ["full-screen-api.transition-duration.enter", "0 0"], - ["full-screen-api.transition-duration.leave", "0 0"]); - let tab = gBrowser.addTab("about:robots"); let browser = tab.linkedBrowser; gBrowser.selectedTab = tab; diff --git a/browser/base/content/test/general/test_contextmenu.html b/browser/base/content/test/general/test_contextmenu.html index 5e9dd35f7092..450231af4016 100644 --- a/browser/base/content/test/general/test_contextmenu.html +++ b/browser/base/content/test/general/test_contextmenu.html @@ -507,8 +507,6 @@ function runTest(testNum) { subwindow.addEventListener("mozfullscreenchange", openDomFullScreen, false); SpecialPowers.setBoolPref("full-screen-api.approval-required", false); SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", false); - SpecialPowers.setCharPref("full-screen-api.transition-duration.enter", "0 0"); - SpecialPowers.setCharPref("full-screen-api.transition-duration.leave", "0 0"); full_screen_element.mozRequestFullScreen(); }, diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 50968c7881e4..25679f0e7965 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -6030,205 +6030,6 @@ FinishDOMFullscreenChange(nsIDocument* aDoc, bool aInDOMFullscreen) } } -struct FullscreenTransitionDuration -{ - // The unit of the durations is millisecond - uint16_t mFadeIn = 0; - uint16_t mFadeOut = 0; - bool IsSuppressed() const - { - return mFadeIn == 0 && mFadeOut == 0; - } -}; - -static void -GetFullscreenTransitionDuration(bool aEnterFullscreen, - FullscreenTransitionDuration* aDuration) -{ - const char* pref = aEnterFullscreen ? - "full-screen-api.transition-duration.enter" : - "full-screen-api.transition-duration.leave"; - nsAdoptingCString prefValue = Preferences::GetCString(pref); - if (!prefValue.IsEmpty()) { - sscanf(prefValue.get(), "%hu%hu", - &aDuration->mFadeIn, &aDuration->mFadeOut); - } -} - -class FullscreenTransitionTask : public nsRunnable -{ -public: - FullscreenTransitionTask(const FullscreenTransitionDuration& aDuration, - nsGlobalWindow* aWindow, bool aFullscreen, - nsIWidget* aWidget, nsIScreen* aScreen, - nsISupports* aTransitionData) - : mWindow(aWindow) - , mWidget(aWidget) - , mScreen(aScreen) - , mTransitionData(aTransitionData) - , mDuration(aDuration) - , mStage(eBeforeToggle) - , mFullscreen(aFullscreen) - {} - - NS_IMETHOD Run() override; - -private: - enum Stage { - // BeforeToggle stage happens before we enter or leave fullscreen - // state. In this stage, the task triggers the pre-toggle fullscreen - // transition on the widget. - eBeforeToggle, - // ToggleFullscreen stage actually executes the fullscreen toggle, - // and wait for the next paint on the content to continue. - eToggleFullscreen, - // AfterToggle stage happens after we toggle the fullscreen state. - // In this stage, the task triggers the post-toggle fullscreen - // transition on the widget. - eAfterToggle - }; - - class Observer final : public nsIObserver - { - public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - - explicit Observer(FullscreenTransitionTask* aTask) - : mTask(aTask) { } - - private: - ~Observer() {} - - nsRefPtr mTask; - }; - - static const uint32_t kNextPaintTimeout = 1000; // ms - static const char* const kPaintedTopic; - - nsRefPtr mWindow; - nsCOMPtr mWidget; - nsCOMPtr mScreen; - nsCOMPtr mTimer; - nsCOMPtr mTransitionData; - - FullscreenTransitionDuration mDuration; - Stage mStage; - bool mFullscreen; -}; - -const char* const -FullscreenTransitionTask::kPaintedTopic = "fullscreen-painted"; - -NS_IMETHODIMP -FullscreenTransitionTask::Run() -{ - Stage stage = mStage; - mStage = Stage(mStage + 1); - if (stage == eBeforeToggle) { - mWidget->PerformFullscreenTransition(nsIWidget::eBeforeFullscreenToggle, - mDuration.mFadeIn, mTransitionData, - this); - } else if (stage == eToggleFullscreen) { - if (MOZ_UNLIKELY(mWindow->mFullScreen != mFullscreen)) { - // This could happen in theory if several fullscreen requests in - // different direction happen continuously in a short time. We - // need to ensure the fullscreen state matches our target here, - // otherwise the widget would change the window state as if we - // toggle for Fullscreen Mode instead of Fullscreen API. - NS_WARNING("The fullscreen state of the window does not match"); - mWindow->mFullScreen = mFullscreen; - } - // Toggle the fullscreen state on the widget - mWidget->MakeFullScreen(mFullscreen, mScreen); - // Set observer for the next content paint. - nsCOMPtr observer = new Observer(this); - nsCOMPtr obs = mozilla::services::GetObserverService(); - obs->AddObserver(observer, kPaintedTopic, false); - // There are several edge cases where we may never get the paint - // notification, including: - // 1. the window/tab is closed before the next paint; - // 2. the user has switched to another tab before we get here. - // Completely fixing those cases seems to be tricky, and since they - // should rarely happen, it probably isn't worth to fix. Hence we - // simply add a timeout here to ensure we never hang forever. - mTimer = do_CreateInstance(NS_TIMER_CONTRACTID); - mTimer->Init(observer, kNextPaintTimeout, nsITimer::TYPE_ONE_SHOT); - } else if (stage == eAfterToggle) { - mWidget->PerformFullscreenTransition(nsIWidget::eAfterFullscreenToggle, - mDuration.mFadeOut, mTransitionData, - this); - } - return NS_OK; -} - -NS_IMPL_ISUPPORTS(FullscreenTransitionTask::Observer, nsIObserver) - -NS_IMETHODIMP -FullscreenTransitionTask::Observer::Observe(nsISupports* aSubject, - const char* aTopic, - const char16_t* aData) -{ - bool shouldContinue = false; - if (strcmp(aTopic, FullscreenTransitionTask::kPaintedTopic) == 0) { - nsCOMPtr win(do_QueryInterface(aSubject)); - nsCOMPtr widget = win ? - static_cast(win.get())->GetMainWidget() : nullptr; - if (widget == mTask->mWidget) { - // The paint notification arrives first. Cancel the timer. - mTask->mTimer->Cancel(); - shouldContinue = true; - } - } else { -#ifdef DEBUG - MOZ_ASSERT(strcmp(aTopic, NS_TIMER_CALLBACK_TOPIC) == 0, - "Should only get fullscreen-painted or timer-callback"); - nsCOMPtr timer(do_QueryInterface(aSubject)); - MOZ_ASSERT(timer && timer == mTask->mTimer, - "Should only trigger this with the timer the task created"); -#endif - shouldContinue = true; - } - if (shouldContinue) { - nsCOMPtr obs = mozilla::services::GetObserverService(); - obs->RemoveObserver(this, kPaintedTopic); - mTask->mTimer = nullptr; - mTask->Run(); - } - return NS_OK; -} - -static bool -MakeWidgetFullscreen(nsGlobalWindow* aWindow, gfx::VRHMDInfo* aHMD, - nsPIDOMWindow::FullscreenReason aReason, bool aFullscreen) -{ - nsCOMPtr widget = aWindow->GetMainWidget(); - if (!widget) { - return false; - } - - FullscreenTransitionDuration duration; - bool performTransition = false; - nsCOMPtr transitionData; - if (aReason == nsPIDOMWindow::eForFullscreenAPI) { - GetFullscreenTransitionDuration(aFullscreen, &duration); - if (!duration.IsSuppressed()) { - performTransition = widget-> - PrepareForFullscreenTransition(getter_AddRefs(transitionData)); - } - } - nsCOMPtr screen = aHMD ? aHMD->GetScreen() : nullptr; - if (!performTransition) { - widget->MakeFullScreen(aFullscreen, screen); - } else { - nsCOMPtr task = - new FullscreenTransitionTask(duration, aWindow, aFullscreen, - widget, screen, transitionData); - task->Run(); - } - return true; -} - nsresult nsGlobalWindow::SetFullscreenInternal(FullscreenReason aReason, bool aFullScreen, @@ -6240,7 +6041,8 @@ nsGlobalWindow::SetFullscreenInternal(FullscreenReason aReason, // Only chrome can change our fullscreen mode. Otherwise, the state // can only be changed for DOM fullscreen. - if (aReason == eForFullscreenMode && !nsContentUtils::IsCallerChrome()) { + if (aFullScreen == FullScreen() || + (aReason == eForFullscreenMode && !nsContentUtils::IsCallerChrome())) { return NS_OK; } @@ -6296,7 +6098,16 @@ nsGlobalWindow::SetFullscreenInternal(FullscreenReason aReason, // dimensions to appear to increase when entering fullscreen mode; we just // want the content to fill the entire client area of the emulator window. if (!Preferences::GetBool("full-screen-api.ignore-widgets", false)) { - if (MakeWidgetFullscreen(this, aHMD, aReason, aFullScreen)) { + nsCOMPtr widget = GetMainWidget(); + if (widget) { + nsCOMPtr screen; + if (aHMD) { + screen = aHMD->GetScreen(); + } + if (aReason == eForFullscreenAPI) { + widget->PrepareForDOMFullscreenTransition(); + } + widget->MakeFullScreen(aFullScreen, screen); // The rest of code for switching fullscreen is in nsGlobalWindow:: // FinishFullscreenChange() which will be called after sizemodechange // event is dispatched. diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 9840bc830787..5b2ecde0addb 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -484,9 +484,6 @@ public: // Inner windows only. virtual void RefreshCompartmentPrincipal() override; - // For accessing protected field mFullScreen - friend class FullscreenTransitionTask; - // Outer windows only. virtual nsresult SetFullscreenInternal( FullscreenReason aReason, bool aIsFullscreen, diff --git a/dom/html/test/test_fullscreen-api.html b/dom/html/test/test_fullscreen-api.html index e8da30006132..424e78bcdd46 100644 --- a/dom/html/test/test_fullscreen-api.html +++ b/dom/html/test/test_fullscreen-api.html @@ -86,12 +86,8 @@ is(window.fullScreen, false, "Shouldn't be able to set window fullscreen from co // to write addLoadEvent(function() { SpecialPowers.pushPrefEnv({ - "set": [ - ["full-screen-api.enabled", true], - ["full-screen-api.allow-trusted-requests-only", false], - ["full-screen-api.transition-duration.enter", "0 0"], - ["full-screen-api.transition-duration.leave", "0 0"] - ]}, nextTest); + "set":[["full-screen-api.enabled", true], + ["full-screen-api.allow-trusted-requests-only", false]]}, nextTest); }); SimpleTest.waitForExplicitFinish(); diff --git a/dom/tests/mochitest/chrome/test_MozDomFullscreen_event.xul b/dom/tests/mochitest/chrome/test_MozDomFullscreen_event.xul index 7bb5f2352aea..076e9db4e49c 100644 --- a/dom/tests/mochitest/chrome/test_MozDomFullscreen_event.xul +++ b/dom/tests/mochitest/chrome/test_MozDomFullscreen_event.xul @@ -32,12 +32,8 @@ var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"] .getNoAppCodebasePrincipal(uri); pm.removeFromPrincipal(principal, "fullscreen"); -SpecialPowers.pushPrefEnv({"set": [ - ['full-screen-api.enabled', true], - ['full-screen-api.allow-trusted-requests-only', false], - ['full-screen-api.transition-duration.enter', '0 0'], - ['full-screen-api.transition-duration.leave', '0 0'] -]}, setup); +SpecialPowers.pushPrefEnv({"set": [['full-screen-api.enabled', true], + ['full-screen-api.allow-trusted-requests-only', false]]}, setup); function setup() { newwindow = window.open("MozDomFullscreen_chrome.xul", "_blank","chrome,resizable=yes,width=400,height=400"); diff --git a/dom/tests/mochitest/pointerlock/test_pointerlock-api.html b/dom/tests/mochitest/pointerlock/test_pointerlock-api.html index 94c3d4023fe9..78e61c6bfe04 100644 --- a/dom/tests/mochitest/pointerlock/test_pointerlock-api.html +++ b/dom/tests/mochitest/pointerlock/test_pointerlock-api.html @@ -28,17 +28,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=633602 SimpleTest.waitForExplicitFinish(); + // Ensure the full-screen api is enabled, and will be disabled on test exit. + SpecialPowers.setBoolPref("full-screen-api.enabled", true); + + // Disable the requirement for trusted contexts only, so the tests are easier to write. + SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only", false); + // Grant "fullscreen" permission on the test domain. This means fullscreen will be // automatically approved, so pointer lock in the tests will be too. SpecialPowers.setFullscreenAllowed(document); - SpecialPowers.pushPrefEnv({"set": [ - ["full-screen-api.enabled", true], - ["full-screen-api.allow-trusted-requests-only", false], - ["full-screen-api.transition-duration.enter", "0 0"], - ["full-screen-api.transition-duration.leave", "0 0"] - ]}, nextTest); - // Run the tests which go full-screen in new window, as Mochitests // normally run in an iframe, which by default will not have the // allowfullscreen attribute set, so full-screen won't work. @@ -73,6 +72,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=633602 var gTestIndex = 0; function finish() { + SpecialPowers.clearUserPref("full-screen-api.enabled"); + SpecialPowers.clearUserPref("full-screen-api.allow-trusted-requests-only"); SpecialPowers.removeFullscreenAllowed(document) SimpleTest.finish(); } @@ -106,6 +107,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=633602 finish(); } } + + addLoadEvent(nextTest); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 8a0fda5f19c6..70d1c8b9541f 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -4342,9 +4342,6 @@ pref("alerts.disableSlidingEffect", false); pref("full-screen-api.enabled", false); pref("full-screen-api.allow-trusted-requests-only", true); pref("full-screen-api.pointer-lock.enabled", true); -// transition duration of fade-to-black and fade-from-black, unit: ms -pref("full-screen-api.transition-duration.enter", "400 400"); -pref("full-screen-api.transition-duration.leave", "400 400"); // DOM idle observers API pref("dom.idle-observers-api.enabled", true); diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h index 05eb5b655b35..182d2c6dc6ab 100644 --- a/widget/cocoa/nsCocoaWindow.h +++ b/widget/cocoa/nsCocoaWindow.h @@ -285,7 +285,7 @@ public: nsIWidget *aWidget, bool aActivate) override; NS_IMETHOD SetSizeMode(int32_t aMode) override; NS_IMETHOD HideWindowChrome(bool aShouldHide) override; - virtual bool PrepareForFullscreenTransition(nsISupports** aData) override; + virtual void PrepareForDOMFullscreenTransition() override; void EnteredFullScreen(bool aFullScreen, bool aNativeMode = true); inline bool ShouldToggleNativeFullscreen(bool aFullScreen); NS_IMETHOD MakeFullScreen(bool aFullScreen, nsIScreen* aTargetScreen = nullptr) override; diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index 421c05b40c0f..eb9626fa3626 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -1266,11 +1266,9 @@ NS_IMETHODIMP nsCocoaWindow::HideWindowChrome(bool aShouldHide) NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT; } -/* virtual */ bool -nsCocoaWindow::PrepareForFullscreenTransition(nsISupports** aData) +void nsCocoaWindow::PrepareForDOMFullscreenTransition() { mInDOMFullscreenTransition = true; - return false; } void nsCocoaWindow::EnteredFullScreen(bool aFullScreen, bool aNativeMode) diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp index e8ae12c2441a..19284db48209 100644 --- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -770,16 +770,6 @@ NS_IMETHODIMP nsBaseWidget::HideWindowChrome(bool aShouldHide) return NS_ERROR_NOT_IMPLEMENTED; } -/* virtual */ void -nsBaseWidget::PerformFullscreenTransition(FullscreenTransitionStage aStage, - uint16_t aDuration, - nsISupports* aData, - nsIRunnable* aCallback) -{ - MOZ_ASSERT_UNREACHABLE( - "Should never call PerformFullscreenTransition on nsBaseWidget"); -} - //------------------------------------------------------------------------- // // Put the window into full-screen mode @@ -792,19 +782,37 @@ NS_IMETHODIMP nsBaseWidget::MakeFullScreen(bool aFullScreen, nsIScreen* aScreen) if (aFullScreen) { if (!mOriginalBounds) mOriginalBounds = new nsIntRect(); - *mOriginalBounds = GetScaledScreenBounds(); + GetScreenBounds(*mOriginalBounds); + // convert dev pix to display pix for window manipulation + CSSToLayoutDeviceScale scale = GetDefaultScale(); + mOriginalBounds->x = NSToIntRound(mOriginalBounds->x / scale.scale); + mOriginalBounds->y = NSToIntRound(mOriginalBounds->y / scale.scale); + mOriginalBounds->width = NSToIntRound(mOriginalBounds->width / scale.scale); + mOriginalBounds->height = NSToIntRound(mOriginalBounds->height / scale.scale); // Move to top-left corner of screen and size to the screen dimensions - nsCOMPtr screen = aScreen; - if (!screen) { - screen = GetWidgetScreen(); - } - if (screen) { - int32_t left, top, width, height; - if (NS_SUCCEEDED(screen->GetRectDisplayPix(&left, &top, &width, &height))) { - Resize(left, top, width, height, true); + nsCOMPtr screenManager; + screenManager = do_GetService("@mozilla.org/gfx/screenmanager;1"); + NS_ASSERTION(screenManager, "Unable to grab screenManager."); + if (screenManager) { + nsCOMPtr screen = aScreen; + if (!screen) { + // no screen was passed in, use the one that the window is on + screenManager->ScreenForRect(mOriginalBounds->x, + mOriginalBounds->y, + mOriginalBounds->width, + mOriginalBounds->height, + getter_AddRefs(screen)); + } + + if (screen) { + int32_t left, top, width, height; + if (NS_SUCCEEDED(screen->GetRectDisplayPix(&left, &top, &width, &height))) { + Resize(left, top, width, height, true); + } } } + } else if (mOriginalBounds) { Resize(mOriginalBounds->x, mOriginalBounds->y, mOriginalBounds->width, mOriginalBounds->height, true); @@ -1740,36 +1748,6 @@ nsBaseWidget::GetRootAccessible() #endif // ACCESSIBILITY -nsIntRect -nsBaseWidget::GetScaledScreenBounds() -{ - nsIntRect bounds; - GetScreenBounds(bounds); - CSSToLayoutDeviceScale scale = GetDefaultScale(); - bounds.x = NSToIntRound(bounds.x / scale.scale); - bounds.y = NSToIntRound(bounds.y / scale.scale); - bounds.width = NSToIntRound(bounds.width / scale.scale); - bounds.height = NSToIntRound(bounds.height / scale.scale); - return bounds; -} - -already_AddRefed -nsBaseWidget::GetWidgetScreen() -{ - nsCOMPtr screenManager; - screenManager = do_GetService("@mozilla.org/gfx/screenmanager;1"); - if (!screenManager) { - return nullptr; - } - - nsIntRect bounds = GetScaledScreenBounds(); - nsCOMPtr screen; - screenManager->ScreenForRect(bounds.x, bounds.y, - bounds.width, bounds.height, - getter_AddRefs(screen)); - return screen.forget(); -} - nsresult nsIWidget::SynthesizeNativeTouchTap(nsIntPoint aPointerScreenPoint, bool aLongTap, nsIObserver* aObserver) diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h index ae146a0cf4eb..dfb4a184b703 100644 --- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -143,11 +143,7 @@ public: virtual void SetShowsFullScreenButton(bool aShow) override {} virtual void SetWindowAnimationType(WindowAnimationType aType) override {} NS_IMETHOD HideWindowChrome(bool aShouldHide) override; - virtual bool PrepareForFullscreenTransition(nsISupports** aData) override { return false; } - virtual void PerformFullscreenTransition(FullscreenTransitionStage aStage, - uint16_t aDuration, - nsISupports* aData, - nsIRunnable* aCallback) override; + virtual void PrepareForDOMFullscreenTransition() override {} NS_IMETHOD MakeFullScreen(bool aFullScreen, nsIScreen* aScreen = nullptr) override; virtual LayerManager* GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr, LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE, @@ -283,13 +279,6 @@ public: return aClientSize; } - // return the widget's outside dimensions - // in global coordinates in display pixel. - nsIntRect GetScaledScreenBounds(); - - // return the screen the widget is in. - already_AddRefed GetWidgetScreen(); - // return true if this is a popup widget with a native titlebar bool IsPopupWithTitleBar() const { diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 1b444eba7640..cb3aa50d7fba 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -37,7 +37,6 @@ class ViewWrapper; class nsIWidgetListener; class nsIntRegion; class nsIScreen; -class nsIRunnable; namespace mozilla { class CompositorVsyncDispatcher; @@ -120,8 +119,8 @@ typedef void* nsNativeWidget; #define NS_NATIVE_PLUGIN_ID 105 #define NS_IWIDGET_IID \ -{ 0x22b4504e, 0xddba, 0x4211, \ - { 0xa1, 0x49, 0x6e, 0x11, 0x73, 0xc4, 0x11, 0x45 } }; +{ 0x53376F57, 0xF081, 0x4949, \ + { 0xB5, 0x5E, 0x87, 0xEF, 0x6A, 0xE9, 0xE3, 0x5A } }; /* * Window shadow styles @@ -1697,33 +1696,18 @@ class nsIWidget : public nsISupports { */ NS_IMETHOD HideWindowChrome(bool aShouldHide) = 0; - enum FullscreenTransitionStage - { - eBeforeFullscreenToggle, - eAfterFullscreenToggle - }; - /** - * Prepares for fullscreen transition and returns whether the widget - * supports fullscreen transition. If this method returns false, - * PerformFullscreenTransition() must never be called. Otherwise, - * caller should call that method twice with "before" and "after" - * stages respectively in order. In the latter case, this method may - * return some data via aData pointer. Caller must pass that data to - * PerformFullscreenTransition() if any, and caller is responsible - * for releasing that data. + * Ask the widget to start the transition for entering or exiting + * DOM Fullscreen. + * + * XXX This method is currently not actually implemented by any + * widget. The only function of this method is to notify cocoa + * window that it should not use the native fullscreen mode. This + * method is reserved for bug 1160014 where a transition will be + * added for DOM fullscreen. Hence, this function is likely to + * be further changed then. */ - virtual bool PrepareForFullscreenTransition(nsISupports** aData) = 0; - - /** - * Performs fullscreen transition. This method returns immediately, - * and will post aCallback to the main thread when the transition - * finishes. - */ - virtual void PerformFullscreenTransition(FullscreenTransitionStage aStage, - uint16_t aDuration, - nsISupports* aData, - nsIRunnable* aCallback) = 0; + virtual void PrepareForDOMFullscreenTransition() = 0; /** * Put the toplevel window into or out of fullscreen mode. diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 9db2b972361f..c6eec0f44aaf 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -325,7 +325,6 @@ nsWindow::nsWindow() : nsWindowBase() mIconSmall = nullptr; mIconBig = nullptr; mWnd = nullptr; - mTransitionWnd = nullptr; mPaintDC = nullptr; mCompositeDC = nullptr; mPrevWndProc = nullptr; @@ -1522,15 +1521,6 @@ NS_METHOD nsWindow::Resize(double aX, double aY, double aWidth, double aHeight, ClearThemeRegion(); VERIFY(::SetWindowPos(mWnd, nullptr, x, y, width, GetHeight(height), flags)); - if (mTransitionWnd) { - // If we have a fullscreen transition window, we need to make - // it topmost again, otherwise the taskbar may be raised by - // the system unexpectedly when we leave fullscreen state. - ::SetWindowPos(mTransitionWnd, HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - // Every transition window is only used once. - mTransitionWnd = nullptr; - } SetThemeRegion(); } @@ -2858,173 +2848,6 @@ NS_METHOD nsWindow::Invalidate(const nsIntRect & aRect) return NS_OK; } -static LRESULT CALLBACK -FullscreenTransitionWindowProc(HWND hWnd, UINT uMsg, - WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_FULLSCREEN_TRANSITION_BEFORE: - case WM_FULLSCREEN_TRANSITION_AFTER: { - // The message sender should have added ref for us. - nsCOMPtr callback = - already_AddRefed((nsIRunnable*)wParam); - DWORD duration = (DWORD)lParam; - DWORD flags = AW_BLEND; - if (uMsg == WM_FULLSCREEN_TRANSITION_AFTER) { - flags |= AW_HIDE; - } - ::AnimateWindow(hWnd, duration, flags); - NS_DispatchToMainThread(callback); - break; - } - case WM_DESTROY: - ::PostQuitMessage(0); - break; - default: - return ::DefWindowProcW(hWnd, uMsg, wParam, lParam); - } - return 0; -} - -struct FullscreenTransitionInitData -{ - nsIntRect mBounds; - HANDLE mSemaphore; - HANDLE mThread; - HWND mWnd; - - FullscreenTransitionInitData() - : mSemaphore(nullptr) - , mThread(nullptr) - , mWnd(nullptr) { } - - ~FullscreenTransitionInitData() - { - if (mSemaphore) { - ::CloseHandle(mSemaphore); - } - if (mThread) { - ::CloseHandle(mThread); - } - } -}; - -static DWORD WINAPI -FullscreenTransitionThreadProc(LPVOID lpParam) -{ - // Initialize window class - static bool sInitialized = false; - if (!sInitialized) { - WNDCLASSW wc = {}; - wc.lpfnWndProc = ::FullscreenTransitionWindowProc; - wc.hInstance = nsToolkit::mDllInstance; - wc.hbrBackground = ::CreateSolidBrush(RGB(0, 0, 0)); - wc.lpszClassName = kClassNameTransition; - ::RegisterClassW(&wc); - sInitialized = true; - } - - auto data = static_cast(lpParam); - HWND wnd = ::CreateWindowW( - kClassNameTransition, L"", 0, 0, 0, 0, 0, - nullptr, nullptr, nsToolkit::mDllInstance, nullptr); - if (!wnd) { - ::ReleaseSemaphore(data->mSemaphore, 1, nullptr); - return 0; - } - - // Since AnimateWindow blocks the thread of the transition window, - // we need to hide the cursor for that window, otherwise the system - // would show the busy pointer to the user. - ::ShowCursor(false); - ::SetWindowLongW(wnd, GWL_STYLE, 0); - ::SetWindowLongW(wnd, GWL_EXSTYLE, WS_EX_LAYERED | - WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE); - ::SetWindowPos(wnd, HWND_TOPMOST, data->mBounds.x, data->mBounds.y, - data->mBounds.width, data->mBounds.height, 0); - data->mWnd = wnd; - ::ReleaseSemaphore(data->mSemaphore, 1, nullptr); - // The initialization data may no longer be valid - // after we release the semaphore. - data = nullptr; - - MSG msg; - while (::GetMessageW(&msg, nullptr, 0, 0)) { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - ::ShowCursor(true); - ::DestroyWindow(wnd); - return 0; -} - -class FullscreenTransitionData final : public nsISupports -{ -public: - NS_DECL_ISUPPORTS - - explicit FullscreenTransitionData(HWND aWnd) - : mWnd(aWnd) - { - MOZ_ASSERT(NS_IsMainThread(), "FullscreenTransitionData " - "should be constructed in the main thread"); - } - - const HWND mWnd; - -private: - ~FullscreenTransitionData() - { - MOZ_ASSERT(NS_IsMainThread(), "FullscreenTransitionData " - "should be deconstructed in the main thread"); - ::PostMessageW(mWnd, WM_DESTROY, 0, 0); - } -}; - -NS_IMPL_ISUPPORTS0(FullscreenTransitionData) - -/* virtual */ bool -nsWindow::PrepareForFullscreenTransition(nsISupports** aData) -{ - FullscreenTransitionInitData initData; - nsCOMPtr screen = GetWidgetScreen(); - screen->GetRectDisplayPix(&initData.mBounds.x, &initData.mBounds.y, - &initData.mBounds.width, &initData.mBounds.height); - // Create a semaphore for synchronizing the window handle which will - // be created by the transition thread and used by the main thread for - // posting the transition messages. - initData.mSemaphore = ::CreateSemaphore(nullptr, 0, 1, nullptr); - if (initData.mSemaphore) { - initData.mThread = ::CreateThread( - nullptr, 0, FullscreenTransitionThreadProc, &initData, 0, nullptr); - if (initData.mThread) { - ::WaitForSingleObject(initData.mSemaphore, INFINITE); - } - } - if (!initData.mWnd) { - return false; - } - - mTransitionWnd = initData.mWnd; - auto data = new FullscreenTransitionData(initData.mWnd); - *aData = data; - NS_ADDREF(data); - return true; -} - -/* virtual */ void -nsWindow::PerformFullscreenTransition(FullscreenTransitionStage aStage, - uint16_t aDuration, nsISupports* aData, - nsIRunnable* aCallback) -{ - auto data = static_cast(aData); - nsCOMPtr callback = aCallback; - UINT msg = aStage == eBeforeFullscreenToggle ? - WM_FULLSCREEN_TRANSITION_BEFORE : WM_FULLSCREEN_TRANSITION_AFTER; - WPARAM wparam = (WPARAM)callback.forget().take(); - ::PostMessage(data->mWnd, msg, wparam, (LPARAM)aDuration); -} - NS_IMETHODIMP nsWindow::MakeFullScreen(bool aFullScreen, nsIScreen* aTargetScreen) { @@ -3052,16 +2875,26 @@ nsWindow::MakeFullScreen(bool aFullScreen, nsIScreen* aTargetScreen) // If we are going fullscreen, the window size continues to change // and the window will be reflow again then. UpdateNonClientMargins(mSizeMode, /* Reflow */ !aFullScreen); + + bool visible = mIsVisible; + if (mOldSizeMode == nsSizeMode_Normal) + Show(false); // Will call hide chrome, reposition window. Note this will // also cache dimensions for restoration, so it should only // be called once per fullscreen request. nsresult rv = nsBaseWidget::MakeFullScreen(aFullScreen, aTargetScreen); - if (mIsVisible && !aFullScreen && mOldSizeMode == nsSizeMode_Normal) { - // Ensure the window exiting fullscreen get activated. Window - // activation might be bypassed in SetSizeMode. - DispatchFocusToTopLevelWindow(true); + if (visible) { + Show(true); + Invalidate(); + + if (!aFullScreen && mOldSizeMode == nsSizeMode_Normal) { + // Ensure the window exiting fullscreen get activated. Window + // activation was bypassed by SetSizeMode, and hiding window for + // transition could also blur the current window. + DispatchFocusToTopLevelWindow(true); + } } // Notify the taskbar that we have exited full screen mode. diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index 60050f272d37..6766c16f8cd5 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -126,11 +126,6 @@ public: uint32_t aHotspotX, uint32_t aHotspotY); NS_IMETHOD SetCursor(nsCursor aCursor); virtual nsresult ConfigureChildren(const nsTArray& aConfigurations); - virtual bool PrepareForFullscreenTransition(nsISupports** aData) override; - virtual void PerformFullscreenTransition(FullscreenTransitionStage aStage, - uint16_t aDuration, - nsISupports* aData, - nsIRunnable* aCallback) override; NS_IMETHOD MakeFullScreen(bool aFullScreen, nsIScreen* aScreen = nullptr); NS_IMETHOD HideWindowChrome(bool aShouldHide); NS_IMETHOD Invalidate(bool aEraseBackground = false, @@ -468,7 +463,6 @@ protected: nsIntSize mLastSize; nsIntPoint mLastPoint; HWND mWnd; - HWND mTransitionWnd; WNDPROC mPrevWndProc; HBRUSH mBrush; bool mIsTopWidgetWindow; diff --git a/widget/windows/nsWindowDefs.h b/widget/windows/nsWindowDefs.h index c64588162f7c..5141b63f5909 100644 --- a/widget/windows/nsWindowDefs.h +++ b/widget/windows/nsWindowDefs.h @@ -91,16 +91,16 @@ #endif #ifndef WM_DWMCOMPOSITIONCHANGED -#define WM_DWMCOMPOSITIONCHANGED 0x031E +#define WM_DWMCOMPOSITIONCHANGED 0x031E #endif #ifndef WM_DWMNCRENDERINGCHANGED -#define WM_DWMNCRENDERINGCHANGED 0x031F +#define WM_DWMNCRENDERINGCHANGED 0x031F #endif #ifndef WM_DWMCOLORIZATIONCOLORCHANGED -#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320 +#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320 #endif #ifndef WM_DWMWINDOWMAXIMIZEDCHANGE -#define WM_DWMWINDOWMAXIMIZEDCHANGE 0x0321 +#define WM_DWMWINDOWMAXIMIZEDCHANGE 0x0321 #endif // ConstrainPosition window positioning slop value @@ -183,10 +183,6 @@ #define TABLET_INK_TOUCH 0x00000080 #define MOUSE_INPUT_SOURCE() WinUtils::GetMouseInputSource() -// Messages for fullscreen transition window -#define WM_FULLSCREEN_TRANSITION_BEFORE (WM_USER + 0) -#define WM_FULLSCREEN_TRANSITION_AFTER (WM_USER + 1) - /************************************************************** * * SECTION: enums @@ -222,7 +218,6 @@ const wchar_t kClassNameGeneral[] = L"MozillaWindowClass"; const wchar_t kClassNameDialog[] = L"MozillaDialogClass"; const wchar_t kClassNameDropShadow[] = L"MozillaDropShadowWindowClass"; const wchar_t kClassNameTemp[] = L"MozillaTempWindowClass"; -const wchar_t kClassNameTransition[] = L"MozillaTransitionWindowClass"; /************************************************************** *