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)
This commit is contained in:
Butkovits Atila 2020-10-29 16:57:35 +02:00
parent 8745656461
commit 304bfab038
6 changed files with 185 additions and 710 deletions

View File

@ -8,56 +8,15 @@
#include <algorithm>
#include <math.h>
#include <limits.h>
#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<double>(color >> 16 & 0xff) / 255.0;
double g = static_cast<double>(color >> 8 & 0xff) / 255.0;
double b = static_cast<double>(color >> 0 & 0xff) / 255.0;
return NormalizedRGB{r, g, b};
}
uint32_t RGBToUint(const NormalizedRGB& rgb) {
return (static_cast<uint32_t>(rgb.r * 255.0) << 16) |
(static_cast<uint32_t>(rgb.g * 255.0) << 8) |
(static_cast<uint32_t>(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<Vector<ColorRect>> 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<uint32_t[]> animationLookup =
MakeUnique<uint32_t[]>(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<double>(i) / (static_cast<double>(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<NCCALCSIZE_PARAMS*>(lParam))->rgrc[0]
: (reinterpret_cast<RECT*>(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<ColorRect>();
// 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<PBYTE>(&windowWidth), &dataLen);
reinterpret_cast<PBYTE>(&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<PBYTE>(&windowHeight), &dataLen);
reinterpret_cast<PBYTE>(&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<PBYTE>(&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<PBYTE>(&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<PBYTE>(&urlbarHorizontalOffsetCSS),
sizeof(urlbarHorizontalOffsetCSS));

View File

@ -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);

View File

@ -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);
}

View File

@ -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<LONG_PTR>(
WinUtils::NonClientDpiScalingDefWindowProcW));
::SetClassLongPtrW(mWnd, GCLP_WNDPROC,
reinterpret_cast<LONG_PTR>(
WinUtils::NonClientDpiScalingDefWindowProcW));
mWasPreXulSkeletonUI = true;
::SetWindowLongPtrW(mWnd, GWL_STYLE, style);
::SetWindowLongPtrW(mWnd, GWL_EXSTYLE, extendedStyle);
}
}
@ -1594,13 +1569,6 @@ already_AddRefed<SourceSurface> 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);
}
}

View File

@ -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;

View File

@ -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;