From 304bfab038db119788194846ff9c8af8f20de5e2 Mon Sep 17 00:00:00 2001 From: Butkovits Atila Date: Thu, 29 Oct 2020 16:57:35 +0200 Subject: [PATCH] Backed out 2 changesets (bug 1666874, bug 1665455) for causing bustage on PreXULSkeletonUI.cpp. CLOSED TREE Backed out changeset 967c4cf56fd2 (bug 1666874) Backed out changeset e46238e6aabf (bug 1665455) --- mozglue/misc/PreXULSkeletonUI.cpp | 638 ++++++------------------------ mozglue/misc/PreXULSkeletonUI.h | 12 +- widget/windows/WinUtils.cpp | 3 - widget/windows/nsWindow.cpp | 233 +++-------- widget/windows/nsWindow.h | 2 +- xpfe/appshell/AppWindow.cpp | 7 +- 6 files changed, 185 insertions(+), 710 deletions(-) diff --git a/mozglue/misc/PreXULSkeletonUI.cpp b/mozglue/misc/PreXULSkeletonUI.cpp index 0346986ca277..2f414080ce7b 100644 --- a/mozglue/misc/PreXULSkeletonUI.cpp +++ b/mozglue/misc/PreXULSkeletonUI.cpp @@ -8,56 +8,15 @@ #include #include -#include #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/glue/Debug.h" -#include "mozilla/StaticPtr.h" -#include "mozilla/UniquePtr.h" -#include "mozilla/Vector.h" #include "mozilla/WindowsDpiAwareness.h" #include "mozilla/WindowsVersion.h" -#include "prthread.h" namespace mozilla { -struct ColorRect { - uint32_t color; - uint32_t x; - uint32_t y; - uint32_t width; - uint32_t height; -}; - -struct NormalizedRGB { - double r; - double g; - double b; -}; - -NormalizedRGB UintToRGB(uint32_t color) { - double r = static_cast(color >> 16 & 0xff) / 255.0; - double g = static_cast(color >> 8 & 0xff) / 255.0; - double b = static_cast(color >> 0 & 0xff) / 255.0; - return NormalizedRGB{r, g, b}; -} - -uint32_t RGBToUint(const NormalizedRGB& rgb) { - return (static_cast(rgb.r * 255.0) << 16) | - (static_cast(rgb.g * 255.0) << 8) | - (static_cast(rgb.b * 255.0) << 0); -} - -double Lerp(double a, double b, double x) { return a + x * (b - a); } - -NormalizedRGB Lerp(const NormalizedRGB& a, const NormalizedRGB& b, double x) { - return NormalizedRGB{Lerp(a.r, b.r, x), Lerp(a.g, b.g, x), Lerp(a.b, b.b, x)}; -} - -// Produces a smooth curve in [0,1] based on a linear input in [0,1] -double SmoothStep3(double x) { return x * x * (3.0 - 2.0 * x); } - static const wchar_t kPreXULSkeletonUIKeyPath[] = L"SOFTWARE" L"\\" MOZ_APP_VENDOR L"\\" MOZ_APP_BASENAME L"\\PreXULSkeletonUISettings"; @@ -66,20 +25,6 @@ static bool sPreXULSkeletonUIEnabled = false; static HWND sPreXULSkeletonUIWindow; static LPWSTR const gStockApplicationIcon = MAKEINTRESOURCEW(32512); static LPWSTR const gIDCWait = MAKEINTRESOURCEW(32514); -static HANDLE sPreXULSKeletonUIAnimationThread; - -static uint32_t* sPixelBuffer = nullptr; -static StaticAutoPtr> sAnimatedRects; -static int sTotalChromeHeight = 0; -static volatile LONG sAnimationControlFlag = 0; -static bool sMaximized = false; -static int sNonClientVerticalMargins = 0; -static int sNonClientHorizontalMargins = 0; -static uint32_t sDpi = 0; - -// Color values needed by the animation loop -static uint32_t sBackgroundColor; -static uint32_t sToolbarForegroundColor; typedef BOOL(WINAPI* EnableNonClientDpiScalingProc)(HWND); static EnableNonClientDpiScalingProc sEnableNonClientDpiScaling = NULL; @@ -101,6 +46,8 @@ typedef BOOL(WINAPI* ShowWindowProc)(HWND, int); ShowWindowProc sShowWindow = NULL; typedef BOOL(WINAPI* SetWindowPosProc)(HWND, HWND, int, int, int, int, UINT); SetWindowPosProc sSetWindowPos = NULL; +typedef BOOL(WINAPI* RedrawWindowProc)(HWND, const RECT*, HRGN, UINT); +RedrawWindowProc sRedrawWindow = NULL; typedef HDC(WINAPI* GetWindowDCProc)(HWND); GetWindowDCProc sGetWindowDC = NULL; typedef int(WINAPI* FillRectProc)(HDC, const RECT*, HBRUSH); @@ -109,12 +56,6 @@ typedef BOOL(WINAPI* DeleteObjectProc)(HGDIOBJ); DeleteObjectProc sDeleteObject = NULL; typedef int(WINAPI* ReleaseDCProc)(HWND, HDC); ReleaseDCProc sReleaseDC = NULL; -typedef HMONITOR(WINAPI* MonitorFromWindowProc)(HWND, DWORD); -MonitorFromWindowProc sMonitorFromWindow = NULL; -typedef BOOL(WINAPI* GetMonitorInfoWProc)(HMONITOR, LPMONITORINFO); -GetMonitorInfoWProc sGetMonitorInfoW = NULL; -typedef LONG_PTR(WINAPI* SetWindowLongPtrWProc)(HWND, int, LONG_PTR); -SetWindowLongPtrWProc sSetWindowLongPtrW = NULL; typedef int(WINAPI* StretchDIBitsProc)(HDC, int, int, int, int, int, int, int, int, const VOID*, const BITMAPINFO*, UINT, DWORD); @@ -126,8 +67,22 @@ static uint32_t sWindowWidth; static uint32_t sWindowHeight; static double sCSSToDevPixelScaling; -static const int kAnimationCSSPixelsPerFrame = 21; -static const int kAnimationCSSExtraWindowSize = 300; +// We style our initial blank window as a WS_POPUP to eliminate the window +// caption and all that jazz. Alternatively, we could do a big dance in our +// window proc to paint into the nonclient area similarly to what we do in +// nsWindow, but it would be nontrivial code duplication, and the added +// complexity would not be worth it, given that we can just change the +// window style to our liking when we consume sPreXULSkeletonUIWindow from +// nsWindow. +static DWORD sWindowStyle = WS_POPUP; + +// We add WS_EX_TOOLWINDOW here so that we do not produce a toolbar entry. +// We were not able to avoid flickering in the toolbar without this change, +// as the call to ::SetWindowLongPtrW to restyle the window inside +// nsWindow causes the toolbar entry to momentarily disappear. Not sure of +// the cause of this, but it doesn't feel too wrong to be missing a toolbar +// entry only so long as we are displaying a skeleton UI. +static DWORD sWindowStyleEx = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW; // We could use nsAutoRegKey, but including nsWindowsHelpers.h causes build // failures in random places because we're in mozglue. Overall it should be @@ -149,8 +104,20 @@ int CSSToDevPixels(int cssPixels, double scaling) { return CSSToDevPixels((double)cssPixels, scaling); } +struct ColorRect { + uint32_t color; + uint32_t x; + uint32_t y; + uint32_t width; + uint32_t height; +}; + void DrawSkeletonUI(HWND hWnd, double urlbarHorizontalOffsetCSS, double urlbarWidthCSS) { + if (!sGetSystemMetricsForDpi || !sGetDpiForWindow) { + return; + } + // NOTE: we opt here to paint a pixel buffer for the application chrome by // hand, without using native UI library methods. Why do we do this? // @@ -172,44 +139,37 @@ void DrawSkeletonUI(HWND hWnd, double urlbarHorizontalOffsetCSS, // manipulating raw pixels should not be *too* hard to maintain and // understand so long as it is only painting such simple shapes. - // NOTE: these could be constants, but eventually they won't be, and they will - // need to be set here. - // --toolbar-non-lwt-bgcolor in browser.css - sBackgroundColor = 0xf9f9fa; - // We define this, but it will need to differ based on theme - sToolbarForegroundColor = 0xe5e5e5; - // found in browser-aero.css ":root[tabsintitlebar]:not(:-moz-lwtheme)" // (set to "hsl(235,33%,19%)") uint32_t tabBarColor = 0x202340; + // --toolbar-non-lwt-bgcolor in browser.css + uint32_t backgroundColor = 0xf9f9fa; // --chrome-content-separator-color in browser.css uint32_t chromeContentDividerColor = 0xe2e1e3; + // We define this, but it will need to differ based on theme + uint32_t toolbarForegroundColor = 0xe5e5e5; // controlled by css variable --tab-line-color uint32_t tabLineColor = 0x0a75d3; // controlled by css variable --toolbar-color uint32_t urlbarColor = 0xffffff; int chromeHorMargin = CSSToDevPixels(2, sCSSToDevPixelScaling); - int verticalOffset = sMaximized ? sNonClientVerticalMargins : 0; - int horizontalOffset = - sNonClientHorizontalMargins - (sMaximized ? 0 : chromeHorMargin); + int dpi = sGetDpiForWindow(hWnd); + int verticalOffset = sGetSystemMetricsForDpi(SM_CYBORDER, dpi); + int nonClientHorMargins = sGetSystemMetricsForDpi(SM_CXFRAME, dpi) + + sGetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi); + int horizontalOffset = nonClientHorMargins - chromeHorMargin; - // found in browser-aero.css, ":root[sizemode=normal][tabsintitlebar]" - int topBorderHeight = - sMaximized ? 0 : CSSToDevPixels(1, sCSSToDevPixelScaling); // found in tabs.inc.css, "--tab-min-height" - depends on uidensity variable int tabBarHeight = CSSToDevPixels(33, sCSSToDevPixelScaling) + verticalOffset; // found in tabs.inc.css, ".titlebar-spacer" int titlebarSpacerWidth = - (sMaximized ? 0 : CSSToDevPixels(40, sCSSToDevPixelScaling)) + - horizontalOffset; + CSSToDevPixels(40, sCSSToDevPixelScaling) + horizontalOffset; // found in tabs.inc.css, ".tab-line" int tabLineHeight = CSSToDevPixels(2, sCSSToDevPixelScaling) + verticalOffset; int selectedTabWidth = CSSToDevPixels(224, sCSSToDevPixelScaling); + int toolbarHeight = CSSToDevPixels(39, sCSSToDevPixelScaling); - // found in urlbar-searchbar.inc.css, "#urlbar[breakout]" - int urlbarTopOffset = CSSToDevPixels(5, sCSSToDevPixelScaling); - int urlbarHeight = CSSToDevPixels(30, sCSSToDevPixelScaling); int tabPlaceholderBarMarginTop = CSSToDevPixels(13, sCSSToDevPixelScaling); int tabPlaceholderBarMarginLeft = CSSToDevPixels(10, sCSSToDevPixelScaling); @@ -230,18 +190,11 @@ void DrawSkeletonUI(HWND hWnd, double urlbarHorizontalOffsetCSS, std::min((int)urlbarWidthCSS - 10, 260), sCSSToDevPixelScaling); int urlbarTextPlaceholderHeight = CSSToDevPixels(10, sCSSToDevPixelScaling); - ColorRect topBorder = {}; - topBorder.color = 0x00000000; - topBorder.x = 0; - topBorder.y = 0; - topBorder.width = sWindowWidth; - topBorder.height = topBorderHeight; - // The (traditionally dark blue on Windows) background of the tab bar. ColorRect tabBar = {}; tabBar.color = tabBarColor; tabBar.x = 0; - tabBar.y = topBorder.height; + tabBar.y = 0; tabBar.width = sWindowWidth; tabBar.height = tabBarHeight; @@ -249,21 +202,21 @@ void DrawSkeletonUI(HWND hWnd, double urlbarHorizontalOffsetCSS, ColorRect tabLine = {}; tabLine.color = tabLineColor; tabLine.x = titlebarSpacerWidth; - tabLine.y = topBorder.height; + tabLine.y = 0; tabLine.width = selectedTabWidth; tabLine.height = tabLineHeight; // The initial selected tab ColorRect selectedTab = {}; - selectedTab.color = sBackgroundColor; + selectedTab.color = backgroundColor; selectedTab.x = titlebarSpacerWidth; - selectedTab.y = tabLine.y + tabLineHeight; + selectedTab.y = tabLineHeight; selectedTab.width = selectedTabWidth; - selectedTab.height = tabBar.y + tabBar.height - selectedTab.y; + selectedTab.height = tabBarHeight; // A placeholder rect representing text that will fill the selected tab title ColorRect tabTextPlaceholder = {}; - tabTextPlaceholder.color = sToolbarForegroundColor; + tabTextPlaceholder.color = toolbarForegroundColor; tabTextPlaceholder.x = selectedTab.x + tabPlaceholderBarMarginLeft; tabTextPlaceholder.y = selectedTab.y + tabPlaceholderBarMarginTop; tabTextPlaceholder.width = tabPlaceholderBarWidth; @@ -271,16 +224,16 @@ void DrawSkeletonUI(HWND hWnd, double urlbarHorizontalOffsetCSS, // The toolbar background ColorRect toolbar = {}; - toolbar.color = sBackgroundColor; + toolbar.color = backgroundColor; toolbar.x = 0; - toolbar.y = tabBar.y + tabBarHeight; + toolbar.y = tabBarHeight; toolbar.width = sWindowWidth; toolbar.height = toolbarHeight; // A placeholder rect representing UI elements that will fill the left part // of the toolbar ColorRect leftToolbarPlaceholder = {}; - leftToolbarPlaceholder.color = sToolbarForegroundColor; + leftToolbarPlaceholder.color = toolbarForegroundColor; leftToolbarPlaceholder.x = toolbar.x + toolbarPlaceholderMarginLeft + horizontalOffset; leftToolbarPlaceholder.y = toolbar.y + toolbarPlaceholderMarginTop; @@ -290,7 +243,7 @@ void DrawSkeletonUI(HWND hWnd, double urlbarHorizontalOffsetCSS, // A placeholder rect representing UI elements that will fill the right part // of the toolbar ColorRect rightToolbarPlaceholder = {}; - rightToolbarPlaceholder.color = sToolbarForegroundColor; + rightToolbarPlaceholder.color = toolbarForegroundColor; rightToolbarPlaceholder.x = sWindowWidth - horizontalOffset - toolbarPlaceholderMarginRight - toolbarPlaceholderWidth; @@ -311,14 +264,14 @@ void DrawSkeletonUI(HWND hWnd, double urlbarHorizontalOffsetCSS, urlbar.color = urlbarColor; urlbar.x = CSSToDevPixels(urlbarHorizontalOffsetCSS, sCSSToDevPixelScaling) + horizontalOffset; - urlbar.y = tabBar.y + tabBarHeight + urlbarTopOffset; + urlbar.y = CSSToDevPixels(39, sCSSToDevPixelScaling); urlbar.width = CSSToDevPixels(urlbarWidthCSS, sCSSToDevPixelScaling); - urlbar.height = urlbarHeight; + urlbar.height = CSSToDevPixels(30, sCSSToDevPixelScaling); // The urlbar placeholder rect representating text that will fill the urlbar // The placeholder rects should all be y-aligned. ColorRect urlbarTextPlaceholder = {}; - urlbarTextPlaceholder.color = sToolbarForegroundColor; + urlbarTextPlaceholder.color = toolbarForegroundColor; urlbarTextPlaceholder.x = urlbar.x + urlbarTextPlaceholderMarginLeft; // This is equivalent to rightToolbarPlaceholder.y and // leftToolbarPlaceholder.y @@ -327,7 +280,6 @@ void DrawSkeletonUI(HWND hWnd, double urlbarHorizontalOffsetCSS, urlbarTextPlaceholder.height = urlbarTextPlaceholderHeight; ColorRect rects[] = { - topBorder, tabBar, tabLine, selectedTab, @@ -340,29 +292,17 @@ void DrawSkeletonUI(HWND hWnd, double urlbarHorizontalOffsetCSS, urlbarTextPlaceholder, }; - sTotalChromeHeight = chromeContentDivider.y + chromeContentDivider.height; - if (sTotalChromeHeight > sWindowHeight) { - printf_stderr("Exiting drawing skeleton UI because window is too small.\n"); - return; - } + int totalChromeHeight = chromeContentDivider.y + chromeContentDivider.height; - if (!sAnimatedRects->append(tabTextPlaceholder) || - !sAnimatedRects->append(leftToolbarPlaceholder) || - !sAnimatedRects->append(rightToolbarPlaceholder) || - !sAnimatedRects->append(urlbarTextPlaceholder)) { - sAnimatedRects = nullptr; - return; - } - - sPixelBuffer = - (uint32_t*)calloc(sWindowWidth * sTotalChromeHeight, sizeof(uint32_t)); + uint32_t* pixelBuffer = + (uint32_t*)calloc(sWindowWidth * totalChromeHeight, sizeof(uint32_t)); for (int i = 0; i < sizeof(rects) / sizeof(rects[0]); ++i) { ColorRect rect = rects[i]; for (int y = rect.y; y < rect.y + rect.height; ++y) { - uint32_t* lineStart = &sPixelBuffer[y * sWindowWidth]; + uint32_t* lineStart = &pixelBuffer[y * sWindowWidth]; uint32_t* dataStart = lineStart + rect.x; - std::fill_n(dataStart, rect.width, rect.color); + std::fill(dataStart, dataStart + rect.width, rect.color); } } @@ -371,226 +311,34 @@ void DrawSkeletonUI(HWND hWnd, double urlbarHorizontalOffsetCSS, BITMAPINFO chromeBMI = {}; chromeBMI.bmiHeader.biSize = sizeof(chromeBMI.bmiHeader); chromeBMI.bmiHeader.biWidth = sWindowWidth; - chromeBMI.bmiHeader.biHeight = -sTotalChromeHeight; + chromeBMI.bmiHeader.biHeight = -totalChromeHeight; chromeBMI.bmiHeader.biPlanes = 1; chromeBMI.bmiHeader.biBitCount = 32; chromeBMI.bmiHeader.biCompression = BI_RGB; // First, we just paint the chrome area with our pixel buffer - sStretchDIBits(hdc, 0, 0, sWindowWidth, sTotalChromeHeight, 0, 0, - sWindowWidth, sTotalChromeHeight, sPixelBuffer, &chromeBMI, - DIB_RGB_COLORS, SRCCOPY); + sStretchDIBits(hdc, 0, 0, sWindowWidth, totalChromeHeight, 0, 0, sWindowWidth, + totalChromeHeight, pixelBuffer, &chromeBMI, DIB_RGB_COLORS, + SRCCOPY); // Then, we just fill the rest with FillRect - RECT rect = {0, sTotalChromeHeight, (LONG)sWindowWidth, (LONG)sWindowHeight}; - HBRUSH brush = sCreateSolidBrush(sBackgroundColor); + RECT rect = {0, totalChromeHeight, (LONG)sWindowWidth, (LONG)sWindowHeight}; + HBRUSH brush = sCreateSolidBrush(backgroundColor); sFillRect(hdc, &rect, brush); sReleaseDC(hWnd, hdc); + + free(pixelBuffer); + sDeleteObject(brush); } -DWORD WINAPI AnimateSkeletonUI(void* aUnused) { - if (!sPixelBuffer || sAnimatedRects->empty()) { - return 0; - } - - // On each of the animated rects (which happen to all be placeholder UI - // rects sharing the same color), we want to animate a gradient moving across - // the screen from left to right. The gradient starts as the rect's color on, - // the left side, changes to the background color of the window by the middle - // of the gradient, and then goes back down to the rect's color. To make this - // faster than interpolating between the two colors for each pixel for each - // frame, we simply create a lookup buffer in which we can look up the color - // for a particular offset into the gradient. - // - // To do this we just interpolate between the two values, and to give the - // gradient a smoother transition between colors, we transform the linear - // blend amount via the cubic smooth step function (SmoothStep3) to produce - // a smooth start and stop for the gradient. We do this for the first half - // of the gradient, and then simply copy that backwards for the second half. - // - // The CSS width of 80 chosen here is effectively is just to match the size - // of the animation provided in the design mockup. We define it in CSS pixels - // simply because the rest of our UI is based off of CSS scalings. - int animationWidth = CSSToDevPixels(80, sCSSToDevPixelScaling); - UniquePtr animationLookup = - MakeUnique(animationWidth); - uint32_t animationColor = sBackgroundColor; - NormalizedRGB rgbBlend = UintToRGB(animationColor); - - // Build the first half of the lookup table - for (int i = 0; i < animationWidth / 2; ++i) { - uint32_t baseColor = sToolbarForegroundColor; - double blendAmountLinear = - static_cast(i) / (static_cast(animationWidth / 2)); - double blendAmount = SmoothStep3(blendAmountLinear); - - NormalizedRGB rgbBase = UintToRGB(baseColor); - NormalizedRGB rgb = Lerp(rgbBase, rgbBlend, blendAmount); - animationLookup[i] = RGBToUint(rgb); - } - - // Copy the first half of the lookup table into the second half backwards - for (int i = animationWidth / 2; i < animationWidth; ++i) { - int j = animationWidth - 1 - i; - if (j == animationWidth / 2) { - // If animationWidth is odd, we'll be left with one pixel at the center. - // Just color that as the animation color. - animationLookup[i] = animationColor; - } else { - animationLookup[i] = animationLookup[j]; - } - } - - // The bitmap info remains unchanged throughout the animation - this just - // effectively describes the contents of sPixelBuffer - BITMAPINFO chromeBMI = {}; - chromeBMI.bmiHeader.biSize = sizeof(chromeBMI.bmiHeader); - chromeBMI.bmiHeader.biWidth = sWindowWidth; - chromeBMI.bmiHeader.biHeight = -sTotalChromeHeight; - chromeBMI.bmiHeader.biPlanes = 1; - chromeBMI.bmiHeader.biBitCount = 32; - chromeBMI.bmiHeader.biCompression = BI_RGB; - - uint32_t animationIteration = 0; - - int devPixelsPerFrame = - CSSToDevPixels(kAnimationCSSPixelsPerFrame, sCSSToDevPixelScaling); - int devPixelsExtraWindowSize = - CSSToDevPixels(kAnimationCSSExtraWindowSize, sCSSToDevPixelScaling); - - if (::InterlockedCompareExchange(&sAnimationControlFlag, 0, 0)) { - // The window got consumed before we were able to draw anything. - return 0; - } - - while (true) { - // The gradient will move across the screen at devPixelsPerFrame at - // 60fps, and then loop back to the beginning. However, we add a buffer of - // devPixelsExtraWindowSize around the edges so it doesn't immediately - // jump back, giving it a more pulsing feel. - int animationMin = ((animationIteration * devPixelsPerFrame) % - (sWindowWidth + devPixelsExtraWindowSize)) - - devPixelsExtraWindowSize / 2; - int animationMax = animationMin + animationWidth; - // The priorAnimationMin is the beginning of the previous frame's animation. - // Since we only want to draw the bits of the image that we updated, we need - // to overwrite the left bit of the animation we drew last frame with the - // default color. - int priorAnimationMin = animationMin - devPixelsPerFrame; - animationMin = std::max(0, animationMin); - priorAnimationMin = std::max(0, priorAnimationMin); - animationMax = std::min((int)sWindowWidth, animationMax); - - // The gradient only affects the specific rects that we put into - // sAnimatedRects. So we simply update those rects, and maintain a flag - // to avoid drawing when we don't need to. - bool updatedAnything = false; - for (ColorRect rect : *sAnimatedRects) { - int rectMin = rect.x; - int rectMax = rect.x + rect.width; - bool animationWindowOverlaps = - rectMax >= priorAnimationMin && rectMin < animationMax; - - int priorUpdateAreaMin = std::max(rectMin, priorAnimationMin); - int currentUpdateAreaMin = std::max(rectMin, animationMin); - int priorUpdateAreaMax = std::min(rectMax, animationMin); - int currentUpdateAreaMax = std::min(rectMax, animationMax); - - if (animationWindowOverlaps) { - updatedAnything = true; - for (int y = rect.y; y < rect.y + rect.height; ++y) { - uint32_t* lineStart = &sPixelBuffer[y * sWindowWidth]; - // Overwrite the tail end of last frame's animation with the rect's - // normal, unanimated color. - for (int x = priorUpdateAreaMin; x < priorUpdateAreaMax; ++x) { - lineStart[x] = rect.color; - } - // Then apply the animated color - for (int x = currentUpdateAreaMin; x < currentUpdateAreaMax; ++x) { - lineStart[x] = animationLookup[x - animationMin]; - } - } - } - } - - if (updatedAnything) { - HDC hdc = sGetWindowDC(sPreXULSkeletonUIWindow); - - sStretchDIBits(hdc, priorAnimationMin, 0, - animationMax - priorAnimationMin, sTotalChromeHeight, - priorAnimationMin, 0, animationMax - priorAnimationMin, - sTotalChromeHeight, sPixelBuffer, &chromeBMI, - DIB_RGB_COLORS, SRCCOPY); - - sReleaseDC(sPreXULSkeletonUIWindow, hdc); - } - - animationIteration++; - - // We coordinate around our sleep here to ensure that the main thread does - // not wait on us if we're sleeping. If we don't get 1 here, it means the - // window has been consumed and we don't need to sleep. If in - // ConsumePreXULSkeletonUIHandle we get a value other than 1 after - // incrementing, it means we're sleeping, and that function can assume that - // we will safely exit after the sleep because of the observed value of - // sAnimationControlFlag. - if (InterlockedIncrement(&sAnimationControlFlag) != 1) { - return 0; - } - - // Note: Sleep does not guarantee an exact time interval. If the system is - // busy, for instance, we could easily end up taking several frames longer, - // and really we could be left unscheduled for an arbitrarily long time. - // This is fine, and we don't really care. We could track how much time this - // actually took and jump the animation forward the appropriate amount, but - // its not even clear that that's a better user experience. So we leave this - // as simple as we can. - ::Sleep(16); - - // Here we bring sAnimationControlFlag back down - again, if we don't get a - // 0 here it means we consumed the skeleton UI window in the mean time, so - // we can simply exit. - if (InterlockedDecrement(&sAnimationControlFlag) != 0) { - return 0; - } - } - - return 0; -} - LRESULT WINAPI PreXULSkeletonUIProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - // NOTE: this block was copied from WinUtils.cpp, and needs to be kept in - // sync. if (msg == WM_NCCREATE && sEnableNonClientDpiScaling) { sEnableNonClientDpiScaling(hWnd); } - // NOTE: this block was paraphrased from the WM_NCCALCSIZE handler in - // nsWindow.cpp, and will need to be kept in sync. - if (msg == WM_NCCALCSIZE) { - RECT* clientRect = - wParam ? &(reinterpret_cast(lParam))->rgrc[0] - : (reinterpret_cast(lParam)); - - // These match the margins set in browser-tabsintitlebar.js with - // default prefs on Windows. Bug 1673092 tracks lining this up with - // that more correctly instead of hard-coding it. - int horizontalOffset = - sNonClientHorizontalMargins - - (sMaximized ? 0 : CSSToDevPixels(2, sCSSToDevPixelScaling)); - int verticalOffset = - sNonClientHorizontalMargins - - (sMaximized ? 0 : CSSToDevPixels(2, sCSSToDevPixelScaling)); - clientRect->top = clientRect->top; - clientRect->left += horizontalOffset; - clientRect->right -= horizontalOffset; - clientRect->bottom -= verticalOffset; - return 0; - } - return ::DefWindowProcW(hWnd, msg, wParam, lParam); } @@ -616,110 +364,6 @@ bool OpenPreXULSkeletonUIRegKey(HKEY& key) { return false; } -bool LoadGdi32AndUser32Procedures() { - HMODULE user32Dll = ::LoadLibraryW(L"user32"); - HMODULE gdi32Dll = ::LoadLibraryW(L"gdi32"); - - if (!user32Dll || !gdi32Dll) { - return false; - } - - auto getThreadDpiAwarenessContext = - (decltype(GetThreadDpiAwarenessContext)*)::GetProcAddress( - user32Dll, "GetThreadDpiAwarenessContext"); - auto areDpiAwarenessContextsEqual = - (decltype(AreDpiAwarenessContextsEqual)*)::GetProcAddress( - user32Dll, "AreDpiAwarenessContextsEqual"); - if (getThreadDpiAwarenessContext && areDpiAwarenessContextsEqual && - areDpiAwarenessContextsEqual(getThreadDpiAwarenessContext(), - DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) { - // EnableNonClientDpiScaling is optional - we can handle not having it. - sEnableNonClientDpiScaling = - (EnableNonClientDpiScalingProc)::GetProcAddress( - user32Dll, "EnableNonClientDpiScaling"); - } - - sGetSystemMetricsForDpi = (GetSystemMetricsForDpiProc)::GetProcAddress( - user32Dll, "GetSystemMetricsForDpi"); - if (!sGetSystemMetricsForDpi) { - return false; - } - sGetDpiForWindow = - (GetDpiForWindowProc)::GetProcAddress(user32Dll, "GetDpiForWindow"); - if (!sGetDpiForWindow) { - return false; - } - sRegisterClassW = - (RegisterClassWProc)::GetProcAddress(user32Dll, "RegisterClassW"); - if (!sRegisterClassW) { - return false; - } - sCreateWindowExW = - (CreateWindowExWProc)::GetProcAddress(user32Dll, "CreateWindowExW"); - if (!sCreateWindowExW) { - return false; - } - sShowWindow = (ShowWindowProc)::GetProcAddress(user32Dll, "ShowWindow"); - if (!sShowWindow) { - return false; - } - sSetWindowPos = (SetWindowPosProc)::GetProcAddress(user32Dll, "SetWindowPos"); - if (!sSetWindowPos) { - return false; - } - sGetWindowDC = (GetWindowDCProc)::GetProcAddress(user32Dll, "GetWindowDC"); - if (!sGetWindowDC) { - return false; - } - sFillRect = (FillRectProc)::GetProcAddress(user32Dll, "FillRect"); - if (!sFillRect) { - return false; - } - sReleaseDC = (ReleaseDCProc)::GetProcAddress(user32Dll, "ReleaseDC"); - if (!sReleaseDC) { - return false; - } - sLoadIconW = (LoadIconWProc)::GetProcAddress(user32Dll, "LoadIconW"); - if (!sLoadIconW) { - return false; - } - sLoadCursorW = (LoadCursorWProc)::GetProcAddress(user32Dll, "LoadCursorW"); - if (!sLoadCursorW) { - return false; - } - sMonitorFromWindow = - (MonitorFromWindowProc)::GetProcAddress(user32Dll, "MonitorFromWindow"); - if (!sMonitorFromWindow) { - return false; - } - sGetMonitorInfoW = - (GetMonitorInfoWProc)::GetProcAddress(user32Dll, "GetMonitorInfoW"); - if (!sGetMonitorInfoW) { - return false; - } - sSetWindowLongPtrW = - (SetWindowLongPtrWProc)::GetProcAddress(user32Dll, "SetWindowLongPtrW"); - if (!sSetWindowLongPtrW) { - return false; - } - sStretchDIBits = - (StretchDIBitsProc)::GetProcAddress(gdi32Dll, "StretchDIBits"); - if (!sStretchDIBits) { - return false; - } - sCreateSolidBrush = - (CreateSolidBrushProc)::GetProcAddress(gdi32Dll, "CreateSolidBrush"); - if (!sCreateSolidBrush) { - return false; - } - sDeleteObject = (DeleteObjectProc)::GetProcAddress(gdi32Dll, "DeleteObject"); - if (!sDeleteObject) { - return false; - } - - return true; -} - void CreateAndStorePreXULSkeletonUI(HINSTANCE hInstance) { HKEY regKey; if (!IsWin10OrLater() || !OpenPreXULSkeletonUIRegKey(regKey)) { @@ -737,13 +381,53 @@ void CreateAndStorePreXULSkeletonUI(HINSTANCE hInstance) { } sPreXULSkeletonUIEnabled = true; - MOZ_ASSERT(!sAnimatedRects); - sAnimatedRects = new Vector(); + // EnableNonClientDpiScaling must be called during the initialization of + // the window, so we have to find it and store it before we create our + // window in order to run it in our WndProc. + HMODULE user32Dll = ::LoadLibraryW(L"user32"); + HMODULE gdi32Dll = ::LoadLibraryW(L"gdi32"); - if (!LoadGdi32AndUser32Procedures()) { + if (!user32Dll || !gdi32Dll) { return; } + auto getThreadDpiAwarenessContext = + (decltype(GetThreadDpiAwarenessContext)*)::GetProcAddress( + user32Dll, "GetThreadDpiAwarenessContext"); + auto areDpiAwarenessContextsEqual = + (decltype(AreDpiAwarenessContextsEqual)*)::GetProcAddress( + user32Dll, "AreDpiAwarenessContextsEqual"); + if (getThreadDpiAwarenessContext && areDpiAwarenessContextsEqual && + areDpiAwarenessContextsEqual(getThreadDpiAwarenessContext(), + DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) { + // Only per-monitor v1 requires these workarounds. + sEnableNonClientDpiScaling = + (EnableNonClientDpiScalingProc)::GetProcAddress( + user32Dll, "EnableNonClientDpiScaling"); + } + + sGetSystemMetricsForDpi = (GetSystemMetricsForDpiProc)::GetProcAddress( + user32Dll, "GetSystemMetricsForDpi"); + sGetDpiForWindow = + (GetDpiForWindowProc)::GetProcAddress(user32Dll, "GetDpiForWindow"); + sRegisterClassW = + (RegisterClassWProc)::GetProcAddress(user32Dll, "RegisterClassW"); + sCreateWindowExW = + (CreateWindowExWProc)::GetProcAddress(user32Dll, "CreateWindowExW"); + sShowWindow = (ShowWindowProc)::GetProcAddress(user32Dll, "ShowWindow"); + sSetWindowPos = (SetWindowPosProc)::GetProcAddress(user32Dll, "SetWindowPos"); + sRedrawWindow = (RedrawWindowProc)::GetProcAddress(user32Dll, "RedrawWindow"); + sGetWindowDC = (GetWindowDCProc)::GetProcAddress(user32Dll, "GetWindowDC"); + sFillRect = (FillRectProc)::GetProcAddress(user32Dll, "FillRect"); + sDeleteObject = (DeleteObjectProc)::GetProcAddress(gdi32Dll, "DeleteObject"); + sReleaseDC = (ReleaseDCProc)::GetProcAddress(user32Dll, "ReleaseDC"); + sLoadIconW = (LoadIconWProc)::GetProcAddress(user32Dll, "LoadIconW"); + sLoadCursorW = (LoadCursorWProc)::GetProcAddress(user32Dll, "LoadCursorW"); + sStretchDIBits = + (StretchDIBitsProc)::GetProcAddress(gdi32Dll, "StretchDIBits"); + sCreateSolidBrush = + (CreateSolidBrushProc)::GetProcAddress(gdi32Dll, "CreateSolidBrush"); + WNDCLASSW wc; wc.style = CS_DBLCLKS; wc.lpfnWndProc = PreXULSkeletonUIProc; @@ -779,32 +463,20 @@ void CreateAndStorePreXULSkeletonUI(HINSTANCE hInstance) { return; } - uint32_t windowWidth; result = ::RegGetValueW(regKey, nullptr, L"width", RRF_RT_REG_DWORD, nullptr, - reinterpret_cast(&windowWidth), &dataLen); + reinterpret_cast(&sWindowWidth), &dataLen); if (result != ERROR_SUCCESS) { printf_stderr("Error reading width %lu\n", GetLastError()); return; } - uint32_t windowHeight; result = ::RegGetValueW(regKey, nullptr, L"height", RRF_RT_REG_DWORD, nullptr, - reinterpret_cast(&windowHeight), &dataLen); + reinterpret_cast(&sWindowHeight), &dataLen); if (result != ERROR_SUCCESS) { printf_stderr("Error reading height %lu\n", GetLastError()); return; } - uint32_t maximized; - result = - ::RegGetValueW(regKey, nullptr, L"maximized", RRF_RT_REG_DWORD, nullptr, - reinterpret_cast(&maximized), &dataLen); - if (result != ERROR_SUCCESS) { - printf_stderr("Error reading maximized %lu\n", GetLastError()); - return; - } - sMaximized = maximized != 0; - dataLen = sizeof(double); double urlbarHorizontalOffsetCSS; result = ::RegGetValueW( @@ -833,92 +505,28 @@ void CreateAndStorePreXULSkeletonUI(HINSTANCE hInstance) { return; } - int showCmd = SW_SHOWNORMAL; - DWORD windowStyle = kPreXULSkeletonUIWindowStyle; - if (sMaximized) { - showCmd = SW_SHOWMAXIMIZED; - windowStyle |= WS_MAXIMIZE; - } - sPreXULSkeletonUIWindow = - sCreateWindowExW(kPreXULSkeletonUIWindowStyleEx, L"MozillaWindowClass", - L"", windowStyle, screenX, screenY, windowWidth, - windowHeight, nullptr, nullptr, hInstance, nullptr); - sShowWindow(sPreXULSkeletonUIWindow, showCmd); - - sDpi = sGetDpiForWindow(sPreXULSkeletonUIWindow); - sNonClientHorizontalMargins = - sGetSystemMetricsForDpi(SM_CXFRAME, sDpi) + - sGetSystemMetricsForDpi(SM_CXPADDEDBORDER, sDpi); - sNonClientVerticalMargins = sGetSystemMetricsForDpi(SM_CYFRAME, sDpi) + - sGetSystemMetricsForDpi(SM_CXPADDEDBORDER, sDpi); - - if (sMaximized) { - HMONITOR monitor = - sMonitorFromWindow(sPreXULSkeletonUIWindow, MONITOR_DEFAULTTONULL); - if (!monitor) { - // NOTE: we specifically don't clean up the window here. If we're unable - // to finish setting up the window how we want it, we still need to keep - // it around and consume it with the first real toplevel window we - // create, to avoid flickering. - return; - } - MONITORINFO mi = {sizeof(MONITORINFO)}; - if (!sGetMonitorInfoW(monitor, &mi)) { - return; - } - - sWindowWidth = - mi.rcWork.right - mi.rcWork.left + sNonClientHorizontalMargins * 2; - sWindowHeight = - mi.rcWork.bottom - mi.rcWork.top + sNonClientVerticalMargins * 2; - } else { - sWindowWidth = windowWidth; - sWindowHeight = windowHeight; - } + sCreateWindowExW(sWindowStyleEx, L"MozillaWindowClass", L"", sWindowStyle, + screenX, screenY, sWindowWidth, sWindowHeight, nullptr, + nullptr, hInstance, nullptr); + sShowWindow(sPreXULSkeletonUIWindow, SW_SHOWNORMAL); sSetWindowPos(sPreXULSkeletonUIWindow, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER); DrawSkeletonUI(sPreXULSkeletonUIWindow, urlbarHorizontalOffsetCSS, urlbarWidthCSS); - - if (sAnimatedRects) { - sPreXULSKeletonUIAnimationThread = ::CreateThread( - nullptr, 256 * 1024, AnimateSkeletonUI, nullptr, 0, nullptr); - } + sRedrawWindow(sPreXULSkeletonUIWindow, NULL, NULL, RDW_INVALIDATE); } -bool WasPreXULSkeletonUIMaximized() { return sMaximized; } - HWND ConsumePreXULSkeletonUIHandle() { - // NOTE: we need to make sure that everything that runs here is a no-op if - // it failed to be set, which is a possibility. If anything fails to be set - // we don't want to clean everything up right away, because if we have a - // blank window up, we want that to stick around and get consumed by nsWindow - // as normal, otherwise the window will flicker in and out, which we imagine - // is unpleasant. - - // If we don't get 1 here, it means the thread is actually just sleeping, so - // we don't need to worry about giving out ownership of the window, because - // the thread will simply exit after its sleep. However, if it is 1, we need - // to wait for the thread to exit to be safe, as it could be doing anything. - if (InterlockedIncrement(&sAnimationControlFlag) == 1) { - ::WaitForSingleObject(sPreXULSKeletonUIAnimationThread, INFINITE); - } - ::CloseHandle(sPreXULSKeletonUIAnimationThread); - sPreXULSKeletonUIAnimationThread = nullptr; HWND result = sPreXULSkeletonUIWindow; sPreXULSkeletonUIWindow = nullptr; - free(sPixelBuffer); - sPixelBuffer = nullptr; - sAnimatedRects = nullptr; return result; } void PersistPreXULSkeletonUIValues(int screenX, int screenY, int width, - int height, bool maximized, - double urlbarHorizontalOffsetCSS, + int height, double urlbarHorizontalOffsetCSS, double urlbarWidthCSS, double cssToDevPixelScaling) { if (!sPreXULSkeletonUIEnabled) { @@ -960,14 +568,6 @@ void PersistPreXULSkeletonUIValues(int screenX, int screenY, int width, return; } - DWORD maximizedDword = maximized ? 1 : 0; - result = ::RegSetValueExW(regKey, L"maximized", 0, REG_DWORD, - reinterpret_cast(&maximizedDword), - sizeof(maximizedDword)); - if (result != ERROR_SUCCESS) { - printf_stderr("Failed persisting maximized to Windows registry\n"); - } - result = ::RegSetValueExW(regKey, L"urlbarHorizontalOffsetCSS", 0, REG_BINARY, reinterpret_cast(&urlbarHorizontalOffsetCSS), sizeof(urlbarHorizontalOffsetCSS)); diff --git a/mozglue/misc/PreXULSkeletonUI.h b/mozglue/misc/PreXULSkeletonUI.h index 38c314bb3785..da3617896101 100644 --- a/mozglue/misc/PreXULSkeletonUI.h +++ b/mozglue/misc/PreXULSkeletonUI.h @@ -12,20 +12,10 @@ namespace mozilla { -// These unfortunately need to be kept in sync with the window style and -// extended window style computations in nsWindow. Luckily those styles seem -// to not vary based off of any user settings for the initial toplevel window, -// so we're safe here for now. -static const DWORD kPreXULSkeletonUIWindowStyle = - WS_CLIPCHILDREN | WS_DLGFRAME | WS_BORDER | WS_MAXIMIZEBOX | - WS_MINIMIZEBOX | WS_SIZEBOX | WS_SYSMENU; -static const DWORD kPreXULSkeletonUIWindowStyleEx = WS_EX_WINDOWEDGE; - MFBT_API void CreateAndStorePreXULSkeletonUI(HINSTANCE hInstance); MFBT_API HWND ConsumePreXULSkeletonUIHandle(); -MFBT_API bool WasPreXULSkeletonUIMaximized(); MFBT_API void PersistPreXULSkeletonUIValues(int screenX, int screenY, int width, - int height, bool maximized, + int height, double urlbarHorizontalOffsetCSS, double urlbarWidthCSS, double cssToDevPixelScaling); diff --git a/widget/windows/WinUtils.cpp b/widget/windows/WinUtils.cpp index 2e62239ca5fd..0a59581cffd4 100644 --- a/widget/windows/WinUtils.cpp +++ b/widget/windows/WinUtils.cpp @@ -463,9 +463,6 @@ void WinUtils::Initialize() { LRESULT WINAPI WinUtils::NonClientDpiScalingDefWindowProcW(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - // NOTE: this function was copied out into the body of the pre-XUL skeleton - // UI window proc (PreXULSkeletonUI.cpp). If this function changes at any - // point, we should probably factor this out and use it from both locations. if (msg == WM_NCCREATE && sEnableNonClientDpiScaling) { sEnableNonClientDpiScaling(hWnd); } diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index ca058761643d..d447d5739b88 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -602,7 +602,7 @@ nsWindow::nsWindow(bool aIsChildWindow) mMouseInDraggableArea = false; mDestroyCalled = false; mIsEarlyBlankWindow = false; - mIsShowingPreXULSkeletonUI = false; + mWasPreXulSkeletonUI = false; mResizable = false; mHasTaskbarIconBeenCreated = false; mMouseTransparent = false; @@ -896,34 +896,9 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent, if (aInitData->mWindowType == eWindowType_toplevel && !aParent) { mWnd = ConsumePreXULSkeletonUIHandle(); if (mWnd) { - MOZ_ASSERT(style == kPreXULSkeletonUIWindowStyle, - "The skeleton UI window style should match the expected " - "style for the first window created"); - MOZ_ASSERT(extendedStyle == kPreXULSkeletonUIWindowStyleEx, - "The skeleton UI window extended style should match the " - "expected extended style for the first window created"); - mIsShowingPreXULSkeletonUI = true; - - // If we successfully consumed the pre-XUL skeleton UI, just update - // our internal state to match what is currently being displayed. - mIsVisible = true; - mSizeMode = WasPreXULSkeletonUIMaximized() ? nsSizeMode_Maximized - : nsSizeMode_Normal; - - // These match the margins set in browser-tabsintitlebar.js with - // default prefs on Windows. Bug 1673092 tracks lining this up with - // that more correctly instead of hard-coding it. - LayoutDeviceIntMargin margins(0, 2, 2, 2); - SetNonClientMargins(margins); - - // Reset the WNDPROC for this window and its whole class, as we had - // to use our own WNDPROC when creating the the skeleton UI window. - ::SetWindowLongPtrW(mWnd, GWLP_WNDPROC, - reinterpret_cast( - WinUtils::NonClientDpiScalingDefWindowProcW)); - ::SetClassLongPtrW(mWnd, GCLP_WNDPROC, - reinterpret_cast( - WinUtils::NonClientDpiScalingDefWindowProcW)); + mWasPreXulSkeletonUI = true; + ::SetWindowLongPtrW(mWnd, GWL_STYLE, style); + ::SetWindowLongPtrW(mWnd, GWL_EXSTYLE, extendedStyle); } } @@ -1594,13 +1569,6 @@ already_AddRefed nsWindow::GetFallbackScrollSnapshot( **************************************************************/ void nsWindow::Show(bool bState) { - if (bState) { - // The first time we decide to actually show the window is when we decide - // that we've taken over the window from the skeleton UI, and we should - // no longer treat resizes / moves specially. - mIsShowingPreXULSkeletonUI = false; - } - if (mWindowType == eWindowType_popup) { // See bug 603793. When we try to draw D3D9/10 windows with a drop shadow // without the DWM on a secondary monitor, windows fails to composite @@ -1949,56 +1917,24 @@ void nsWindow::Move(double aX, double aY) { } } #endif + ClearThemeRegion(); - // Normally, when the skeleton UI is disabled, we resize+move the window - // before showing it in order to ensure that it restores to the correct - // position when the user un-maximizes it. However, when we are using the - // skeleton UI, this results in the skeleton UI window being moved around - // undesirably before being locked back into the maximized position. To - // avoid this, we simply set the placement to restore to via - // SetWindowPlacement. It's a little bit more of a dance, though, since we - // need to convert the workspace coords that SetWindowPlacement uses to the - // screen space coordinates we normally use with SetWindowPos. - if (mIsShowingPreXULSkeletonUI && WasPreXULSkeletonUIMaximized()) { - WINDOWPLACEMENT pl = {sizeof(WINDOWPLACEMENT)}; - VERIFY(::GetWindowPlacement(mWnd, &pl)); - - HMONITOR monitor = ::MonitorFromWindow(mWnd, MONITOR_DEFAULTTONULL); - if (NS_WARN_IF(!monitor)) { - return; - } - MONITORINFO mi = {sizeof(MONITORINFO)}; - VERIFY(::GetMonitorInfo(monitor, &mi)); - - int32_t deltaX = - x + mi.rcWork.left - mi.rcMonitor.left - pl.rcNormalPosition.left; - int32_t deltaY = - y + mi.rcWork.top - mi.rcMonitor.top - pl.rcNormalPosition.top; - pl.rcNormalPosition.left += deltaX; - pl.rcNormalPosition.right += deltaX; - pl.rcNormalPosition.top += deltaY; - pl.rcNormalPosition.bottom += deltaY; - VERIFY(::SetWindowPlacement(mWnd, &pl)); - } else { - ClearThemeRegion(); - - UINT flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE; - // Workaround SetWindowPos bug with D3D9. If our window has a clip - // region, some drivers or OSes may incorrectly copy into the clipped-out - // area. - if (IsPlugin() && !mLayerManager && mClipRects && - (mClipRectCount != 1 || - !mClipRects[0].IsEqualInterior( - LayoutDeviceIntRect(0, 0, mBounds.Width(), mBounds.Height())))) { - flags |= SWP_NOCOPYBITS; - } - double oldScale = mDefaultScale; - mResizeState = IN_SIZEMOVE; - VERIFY(::SetWindowPos(mWnd, nullptr, x, y, 0, 0, flags)); - mResizeState = NOT_RESIZING; - if (WinUtils::LogToPhysFactor(mWnd) != oldScale) { - ChangedDPI(); - } + UINT flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE; + // Workaround SetWindowPos bug with D3D9. If our window has a clip + // region, some drivers or OSes may incorrectly copy into the clipped-out + // area. + if (IsPlugin() && !mLayerManager && mClipRects && + (mClipRectCount != 1 || + !mClipRects[0].IsEqualInterior( + LayoutDeviceIntRect(0, 0, mBounds.Width(), mBounds.Height())))) { + flags |= SWP_NOCOPYBITS; + } + double oldScale = mDefaultScale; + mResizeState = IN_SIZEMOVE; + VERIFY(::SetWindowPos(mWnd, nullptr, x, y, 0, 0, flags)); + mResizeState = NOT_RESIZING; + if (WinUtils::LogToPhysFactor(mWnd) != oldScale) { + ChangedDPI(); } SetThemeRegion(); @@ -2034,36 +1970,24 @@ void nsWindow::Resize(double aWidth, double aHeight, bool aRepaint) { mBounds.SizeTo(width, height); if (mWnd) { - // Refer to the comment above a similar check in nsWindow::Move - if (mIsShowingPreXULSkeletonUI && WasPreXULSkeletonUIMaximized()) { - WINDOWPLACEMENT pl = {sizeof(WINDOWPLACEMENT)}; - VERIFY(::GetWindowPlacement(mWnd, &pl)); - pl.rcNormalPosition.right = pl.rcNormalPosition.left + width; - pl.rcNormalPosition.bottom = pl.rcNormalPosition.top + GetHeight(height); - mResizeState = RESIZING; - VERIFY(::SetWindowPlacement(mWnd, &pl)); - mResizeState = NOT_RESIZING; - } else { - UINT flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE; + UINT flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE; - if (!aRepaint) { - flags |= SWP_NOREDRAW; - } - - ClearThemeRegion(); - double oldScale = mDefaultScale; - mResizeState = RESIZING; - VERIFY( - ::SetWindowPos(mWnd, nullptr, 0, 0, width, GetHeight(height), flags)); - - mResizeState = NOT_RESIZING; - if (WinUtils::LogToPhysFactor(mWnd) != oldScale) { - ChangedDPI(); - } - SetThemeRegion(); - - ResizeDirectManipulationViewport(); + if (!aRepaint) { + flags |= SWP_NOREDRAW; } + + ClearThemeRegion(); + double oldScale = mDefaultScale; + mResizeState = RESIZING; + VERIFY( + ::SetWindowPos(mWnd, nullptr, 0, 0, width, GetHeight(height), flags)); + mResizeState = NOT_RESIZING; + if (WinUtils::LogToPhysFactor(mWnd) != oldScale) { + ChangedDPI(); + } + SetThemeRegion(); + + ResizeDirectManipulationViewport(); } if (aRepaint) Invalidate(); @@ -2100,55 +2024,30 @@ void nsWindow::Resize(double aX, double aY, double aWidth, double aHeight, mBounds.SetRect(x, y, width, height); if (mWnd) { - // Refer to the comment above a similar check in nsWindow::Move - if (mIsShowingPreXULSkeletonUI && WasPreXULSkeletonUIMaximized()) { - WINDOWPLACEMENT pl = {sizeof(WINDOWPLACEMENT)}; - VERIFY(::GetWindowPlacement(mWnd, &pl)); - - HMONITOR monitor = ::MonitorFromWindow(mWnd, MONITOR_DEFAULTTONULL); - if (NS_WARN_IF(!monitor)) { - return; - } - MONITORINFO mi = {sizeof(MONITORINFO)}; - VERIFY(::GetMonitorInfo(monitor, &mi)); - - int32_t deltaX = - x + mi.rcWork.left - mi.rcMonitor.left - pl.rcNormalPosition.left; - int32_t deltaY = - y + mi.rcWork.top - mi.rcMonitor.top - pl.rcNormalPosition.top; - pl.rcNormalPosition.left += deltaX; - pl.rcNormalPosition.right = pl.rcNormalPosition.left + width; - pl.rcNormalPosition.top += deltaY; - pl.rcNormalPosition.bottom = pl.rcNormalPosition.top + GetHeight(height); - VERIFY(::SetWindowPlacement(mWnd, &pl)); - } else { - UINT flags = SWP_NOZORDER | SWP_NOACTIVATE; - if (!aRepaint) { - flags |= SWP_NOREDRAW; - } - - ClearThemeRegion(); - - double oldScale = mDefaultScale; - mResizeState = RESIZING; - VERIFY( - ::SetWindowPos(mWnd, nullptr, x, y, width, GetHeight(height), flags)); - mResizeState = NOT_RESIZING; - if (WinUtils::LogToPhysFactor(mWnd) != oldScale) { - ChangedDPI(); - } - - 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); - } - SetThemeRegion(); - - ResizeDirectManipulationViewport(); + UINT flags = SWP_NOZORDER | SWP_NOACTIVATE; + if (!aRepaint) { + flags |= SWP_NOREDRAW; } + + ClearThemeRegion(); + double oldScale = mDefaultScale; + mResizeState = RESIZING; + VERIFY( + ::SetWindowPos(mWnd, nullptr, x, y, width, GetHeight(height), flags)); + mResizeState = NOT_RESIZING; + if (WinUtils::LogToPhysFactor(mWnd) != oldScale) { + ChangedDPI(); + } + 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); + } + SetThemeRegion(); + + ResizeDirectManipulationViewport(); } if (aRepaint) Invalidate(); @@ -2268,14 +2167,6 @@ void nsWindow::SetSizeMode(nsSizeMode aMode) { // calls us directly, and then the OS triggers another call to us.) if (aMode == mSizeMode) return; - // If we are still displaying a maximized pre-XUL skeleton UI, ignore the - // noise of sizemode changes. Once we have "shown" the window for the first - // time (called nsWindow::Show(true), even though the window is already - // technically displayed), we will again accept sizemode changes. - if (mIsShowingPreXULSkeletonUI && WasPreXULSkeletonUIMaximized()) { - return; - } - // save the requested state mLastSizeMode = mSizeMode; nsBaseWidget::SetSizeMode(aMode); @@ -5427,8 +5318,6 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, } break; case WM_NCCALCSIZE: { - // NOTE: the following block is mirrored in PreXULSkeletonUI.cpp, and - // will need to be kept in sync. if (mCustomNonClient) { // If `wParam` is `FALSE`, `lParam` points to a `RECT` that contains // the proposed window rectangle for our window. During our @@ -8803,7 +8692,7 @@ bool nsWindow::SynchronouslyRepaintOnResize() { } void nsWindow::MaybeDispatchInitialFocusEvent() { - if (mIsShowingPreXULSkeletonUI && ::GetActiveWindow() == mWnd) { + if (mWasPreXulSkeletonUI && ::GetActiveWindow() == mWnd) { DispatchFocusToTopLevelWindow(true); } } diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index b7a7761aeec6..208ec78a139d 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -606,7 +606,7 @@ class nsWindow final : public nsWindowBase { bool mOpeningAnimationSuppressed; bool mAlwaysOnTop; bool mIsEarlyBlankWindow; - bool mIsShowingPreXULSkeletonUI; + bool mWasPreXulSkeletonUI; bool mResizable; DWORD_PTR mOldStyle; DWORD_PTR mOldExStyle; diff --git a/xpfe/appshell/AppWindow.cpp b/xpfe/appshell/AppWindow.cpp index 46d11f98cd24..aba942f83b76 100644 --- a/xpfe/appshell/AppWindow.cpp +++ b/xpfe/appshell/AppWindow.cpp @@ -1835,10 +1835,9 @@ nsresult AppWindow::MaybeSaveEarlyWindowPersistentValues( urlbarWidth -= (double)(2 * (urlbarBreakoutExtend + urlbarMarginInline)); } - PersistPreXULSkeletonUIValues( - aRect.X(), aRect.Y(), aRect.Width(), aRect.Height(), - mWindow->SizeMode() == nsSizeMode_Maximized, urlbarX, urlbarWidth, - mWindow->GetDefaultScale().scale); + PersistPreXULSkeletonUIValues(aRect.X(), aRect.Y(), aRect.Width(), + aRect.Height(), urlbarX, urlbarWidth, + mWindow->GetDefaultScale().scale); #endif return NS_OK;