Refine editor native window frame contract

This commit is contained in:
2026-04-26 22:41:27 +08:00
parent cddd12b7c7
commit d4e0276b96
6 changed files with 224 additions and 89 deletions

View File

@@ -167,7 +167,7 @@ bool EditorWindowInstance::TryResolveDockTabDragHotspot(
return false;
}
const float dpiScale = m_nativePeer->GetDpiScale();
const float dpiScale = m_nativePeer->CaptureMetrics().dpiScale;
outHotspot.x = static_cast<std::int32_t>(std::lround(hotspotDips.x * dpiScale));
outHotspot.y = static_cast<std::int32_t>(std::lround(hotspotDips.y * dpiScale));
return true;
@@ -286,31 +286,31 @@ bool EditorWindowInstance::IsRenderReady() const {
bool EditorWindowInstance::InitializeRuntime(
const EditorHostWindowRuntimeInitializationParams& params) {
if (m_nativePeer == nullptr || m_nativePeer->GetNativeWindowHandle() == nullptr) {
if (m_nativePeer == nullptr) {
AppendUIEditorRuntimeTrace("app", "window initialize skipped: native window is null");
return false;
}
m_nativePeer->PrepareRuntimeInitialization(*this);
m_runtime->SetDpiScale(m_nativePeer->GetDpiScale());
EditorNativeWindowRuntimeSurface runtimeSurface = {};
if (!m_nativePeer->CaptureRuntimeSurface(*this, runtimeSurface) ||
!runtimeSurface.IsValid()) {
AppendUIEditorRuntimeTrace("app", "window initialize skipped: native surface is invalid");
return false;
}
m_runtime->SetDpiScale(runtimeSurface.dpiScale);
std::ostringstream dpiTrace = {};
dpiTrace << "initial dpiScale=" << m_nativePeer->GetDpiScale();
dpiTrace << "initial dpiScale=" << runtimeSurface.dpiScale;
AppendUIEditorRuntimeTrace("window", dpiTrace.str());
MarkInitializing();
std::uint32_t clientWidth = 0u;
std::uint32_t clientHeight = 0u;
if (!m_nativePeer->QueryCurrentClientPixelSize(clientWidth, clientHeight)) {
clientWidth = 1u;
clientHeight = 1u;
}
const bool initialized = m_runtime->Initialize(
Rendering::Host::EditorWindowRenderRuntimeSurface{
.nativeWindowHandle = m_nativePeer->GetNativeWindowHandle(),
.widthPixels = clientWidth,
.heightPixels = clientHeight,
.nativeWindowHandle = runtimeSurface.nativeWindowHandle,
.widthPixels = runtimeSurface.widthPixels,
.heightPixels = runtimeSurface.heightPixels,
},
params.repoRoot,
params.captureRoot,
@@ -329,34 +329,32 @@ EditorWindowFrameTransferRequests EditorWindowInstance::RenderHostFrame(
return {};
}
std::uint32_t pixelWidth = 0u;
std::uint32_t pixelHeight = 0u;
if (!m_nativePeer->ResolveRenderClientPixelSize(pixelWidth, pixelHeight)) {
EditorNativeWindowFrameSnapshot frameSnapshot = {};
if (!m_nativePeer->CaptureFrameSnapshot(
*this,
m_runtime->GetShellInteractionState(),
frameSnapshot) ||
!frameSnapshot.IsValid()) {
return {};
}
const float width = m_nativePeer->PixelsToDips(static_cast<float>(pixelWidth));
const float height = m_nativePeer->PixelsToDips(static_cast<float>(pixelHeight));
const UIRect workspaceBounds =
m_nativePeer->ResolveWorkspaceBounds(*this, width, height);
UIDrawData drawData = {};
UIDrawList& backgroundDrawList = drawData.EmplaceDrawList("XCEditorWindow.Surface");
backgroundDrawList.AddFilledRect(
UIRect(0.0f, 0.0f, width, height),
UIRect(0.0f, 0.0f, frameSnapshot.widthDips, frameSnapshot.heightDips),
kShellSurfaceColor);
EditorWindowFrameTransferRequests transferRequests = {};
if (m_runtime->IsEditorContextValid()) {
transferRequests =
RenderRuntimeFrame(globalTabDragActive, workspaceBounds, drawData);
RenderRuntimeFrame(globalTabDragActive, frameSnapshot, drawData);
} else {
UIDrawList& invalidDrawList = drawData.EmplaceDrawList("XCEditorWindow.Invalid");
m_runtime->AppendInvalidFrame(invalidDrawList);
}
UIDrawList& windowChromeDrawList = drawData.EmplaceDrawList("XCEditorWindow.Chrome");
m_nativePeer->AppendChrome(*this, windowChromeDrawList, width);
m_nativePeer->AppendChrome(*this, windowChromeDrawList, frameSnapshot.widthDips);
const auto presentResult = m_runtime->Present(drawData);
if (!presentResult.warning.empty()) {
@@ -441,39 +439,37 @@ void EditorWindowInstance::UpdateCachedTitleText() {
EditorWindowFrameTransferRequests EditorWindowInstance::RenderRuntimeFrame(
bool globalTabDragActive,
const UIRect& workspaceBounds,
const EditorNativeWindowFrameSnapshot& frameSnapshot,
UIDrawData& drawData) {
if (m_nativePeer == nullptr) {
return {};
}
m_nativePeer->SyncShellCapturedPointerButtonsFromSystemState(
m_runtime->GetShellInteractionState());
std::vector<::XCEngine::UI::UIInputEvent> frameEvents =
m_nativePeer->TakePendingInputEvents();
m_runtime->PrepareEditorContext();
const auto frameContext = m_runtime->BeginFrame();
if (!frameContext.warning.empty()) {
AppendUIEditorRuntimeTrace("viewport", frameContext.warning);
}
const bool useDetachedTitleBarTabStrip =
m_nativePeer->ShouldUseDetachedTitleBarTabStrip(*this);
const EditorWindowFrameTransferRequests transferRequests =
m_runtime->UpdateAndAppend(
workspaceBounds,
frameEvents,
m_nativePeer->QueryCursorScreenPoint(),
frameSnapshot.workspaceBounds,
frameSnapshot.inputEvents,
frameSnapshot.cursorScreenPoint,
IsPrimary(),
globalTabDragActive,
useDetachedTitleBarTabStrip,
frameSnapshot.useDetachedTitleBarTabStrip,
drawData);
if (frameContext.canRenderViewports) {
m_runtime->RenderRequestedViewports(frameContext.renderContext);
}
m_nativePeer->ApplyShellRuntimePointerCapture(*this);
m_nativePeer->ApplyCurrentCursor();
m_nativePeer->ApplyFrameCommands(
*this,
EditorNativeWindowFrameCommands{
.applyShellRuntimePointerCapture = true,
.applyCurrentCursor = true,
});
return transferRequests;
}