feat: add configurable operator appearance and layout

This commit is contained in:
2026-07-23 11:14:10 +09:00
parent cf117de144
commit f43483533a
34 changed files with 5942 additions and 740 deletions

View File

@@ -68,6 +68,8 @@ public static class LegacyPackageInputNative
public int ScreenTop;
public int Width;
public int Height;
public double CssScaleX;
public double CssScaleY;
}
[StructLayout(LayoutKind.Sequential)]
@@ -391,13 +393,11 @@ public static class LegacyPackageInputNative
Point source = CssPointToScreen(
baseline,
sourceCssX,
sourceCssY,
devicePixelRatio);
sourceCssY);
Point target = CssPointToScreen(
baseline,
targetCssX,
targetCssY,
devicePixelRatio);
targetCssY);
if (source.X == target.X && source.Y == target.Y)
{
throw new InvalidOperationException("The Windows drag source and target are identical.");
@@ -429,7 +429,7 @@ public static class LegacyPackageInputNative
source, true, false);
Point threshold = new Point {
X = source.X + Math.Max(8, (int)Math.Round(12.0 * devicePixelRatio)),
X = source.X + Math.Max(8, (int)Math.Round(12.0 * baseline.CssScaleX)),
Y = source.Y
};
AssertPointOwnedByWindow(window, threshold);
@@ -566,11 +566,11 @@ public static class LegacyPackageInputNative
viewportCssHeight, devicePixelRatio, baseline);
Point rangeStart = CssPointToScreen(
baseline, rangeStartCssX, rangeStartCssY, devicePixelRatio);
baseline, rangeStartCssX, rangeStartCssY);
Point rangeEnd = CssPointToScreen(
baseline, rangeEndCssX, rangeEndCssY, devicePixelRatio);
baseline, rangeEndCssX, rangeEndCssY);
Point restore = CssPointToScreen(
baseline, restoreCssX, restoreCssY, devicePixelRatio);
baseline, restoreCssX, restoreCssY);
if ((rangeStart.X == rangeEnd.X && rangeStart.Y == rangeEnd.Y) ||
(rangeEnd.X == restore.X && rangeEnd.Y == restore.Y))
{
@@ -710,7 +710,7 @@ public static class LegacyPackageInputNative
150, window, processId, forbiddenPort, viewportCssWidth,
viewportCssHeight, devicePixelRatio, baseline);
Point point = CssPointToScreen(baseline, cssX, cssY, devicePixelRatio);
Point point = CssPointToScreen(baseline, cssX, cssY);
AssertPointOwnedByWindow(window, point);
bool leftButtonDown = false;
try
@@ -784,7 +784,7 @@ public static class LegacyPackageInputNative
150, window, processId, forbiddenPort, viewportCssWidth,
viewportCssHeight, devicePixelRatio, baseline);
Point point = CssPointToScreen(baseline, cssX, cssY, devicePixelRatio);
Point point = CssPointToScreen(baseline, cssX, cssY);
AssertPointOwnedByWindow(window, point);
bool leftButtonDown = false;
try
@@ -1056,16 +1056,31 @@ public static class LegacyPackageInputNative
throw new InvalidOperationException("The package client rectangle is invalid.");
}
int expectedWidth = (int)Math.Round(viewportCssWidth * devicePixelRatio);
int expectedHeight = (int)Math.Round(viewportCssHeight * devicePixelRatio);
if (expectedWidth <= 0 || expectedHeight <= 0 ||
Math.Abs(client.Right - expectedWidth) > ClientPixelTolerance ||
Math.Abs(client.Bottom - expectedHeight) > ClientPixelTolerance)
int deviceWidth = (int)Math.Round(viewportCssWidth * devicePixelRatio);
int deviceHeight = (int)Math.Round(viewportCssHeight * devicePixelRatio);
int logicalWidth = (int)Math.Round(viewportCssWidth);
int logicalHeight = (int)Math.Round(viewportCssHeight);
bool deviceMatches = deviceWidth > 0 && deviceHeight > 0 &&
Math.Abs(client.Right - deviceWidth) <= ClientPixelTolerance &&
Math.Abs(client.Bottom - deviceHeight) <= ClientPixelTolerance;
bool logicalMatches = logicalWidth > 0 && logicalHeight > 0 &&
Math.Abs(client.Right - logicalWidth) <= ClientPixelTolerance &&
Math.Abs(client.Bottom - logicalHeight) <= ClientPixelTolerance;
if (!deviceMatches && !logicalMatches)
{
throw new InvalidOperationException(
"The browser viewport does not match the package client rectangle.");
}
double cssScaleX = client.Right / viewportCssWidth;
double cssScaleY = client.Bottom / viewportCssHeight;
if (!IsFinitePositive(cssScaleX) || !IsFinitePositive(cssScaleY) ||
Math.Abs(cssScaleX - cssScaleY) > 0.02)
{
throw new InvalidOperationException(
"The package client CSS coordinate scale is invalid.");
}
Point origin = new Point { X = 0, Y = 0 };
if (!ClientToScreen(window, ref origin))
{
@@ -1075,7 +1090,9 @@ public static class LegacyPackageInputNative
ScreenLeft = origin.X,
ScreenTop = origin.Y,
Width = client.Right,
Height = client.Bottom
Height = client.Bottom,
CssScaleX = cssScaleX,
CssScaleY = cssScaleY
};
}
@@ -1321,8 +1338,7 @@ public static class LegacyPackageInputNative
private static Point CssPointToScreen(
ClientGeometry geometry,
double cssX,
double cssY,
double devicePixelRatio)
double cssY)
{
if (Double.IsNaN(cssX) || Double.IsInfinity(cssX) ||
Double.IsNaN(cssY) || Double.IsInfinity(cssY) || cssX < 0 || cssY < 0)
@@ -1330,8 +1346,8 @@ public static class LegacyPackageInputNative
throw new InvalidOperationException("A CSS input point is invalid.");
}
int x = (int)Math.Round(cssX * devicePixelRatio);
int y = (int)Math.Round(cssY * devicePixelRatio);
int x = (int)Math.Round(cssX * geometry.CssScaleX);
int y = (int)Math.Round(cssY * geometry.CssScaleY);
if (x < 0 || x >= geometry.Width || y < 0 || y >= geometry.Height)
{
throw new InvalidOperationException("A CSS input point is outside the package client area.");
@@ -1787,7 +1803,11 @@ function Assert-DebugAppXMatchesLatestPackage([string]$InstallLocation) {
'MBN_STOCK_WEBVIEW.LegacyApplication.dll',
'MBN_STOCK_WEBVIEW.LegacyBridge.dll',
'MBN_STOCK_WEBVIEW.LegacyParityApp.dll',
'Web/app.js'
'Web/app.js',
'Web/index.html',
'Web/playout-ui.js',
'Web/styles.css',
'Web/workspace-navigation.js'
)
foreach ($relativePath in $expectedFiles) {
$entry = $archive.GetEntry($relativePath)