From fc09b7ad832dee4ffb4fedb27904b1fd95585598 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Thu, 23 Apr 2026 16:48:09 +0800 Subject: [PATCH] refactor(new_editor): introduce win32 window session state --- new_editor/CMakeLists.txt | 1 + .../Chrome/EditorWindowChromeController.cpp | 82 +++++---- .../Win32/Runtime/EditorWindowFrameDriver.cpp | 2 +- .../Platform/Win32/Windowing/EditorWindow.cpp | 166 +++++++++--------- .../Platform/Win32/Windowing/EditorWindow.h | 13 +- .../Windowing/EditorWindowHostRuntime.cpp | 2 +- .../Win32/Windowing/EditorWindowSession.cpp | 126 +++++++++++++ .../Win32/Windowing/EditorWindowSession.h | 47 +++++ 8 files changed, 307 insertions(+), 132 deletions(-) create mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp create mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowSession.h diff --git a/new_editor/CMakeLists.txt b/new_editor/CMakeLists.txt index 26531e8e..4cca2f57 100644 --- a/new_editor/CMakeLists.txt +++ b/new_editor/CMakeLists.txt @@ -242,6 +242,7 @@ if(XCENGINE_BUILD_XCUI_EDITOR_APP) set(XCUI_EDITOR_APP_PLATFORM_SOURCES app/Platform/Win32/Windowing/EditorWindow.cpp app/Platform/Win32/Windowing/EditorFloatingWindowPlacement.cpp + app/Platform/Win32/Windowing/EditorWindowSession.cpp app/Platform/Win32/Content/EditorUtilityWindowContentController.cpp app/Platform/Win32/Chrome/EditorWindowChromeController.cpp app/Platform/Win32/Runtime/EditorWindowFrameDriver.cpp diff --git a/new_editor/app/Platform/Win32/Chrome/EditorWindowChromeController.cpp b/new_editor/app/Platform/Win32/Chrome/EditorWindowChromeController.cpp index 103ea46f..7f41ac94 100644 --- a/new_editor/app/Platform/Win32/Chrome/EditorWindowChromeController.cpp +++ b/new_editor/app/Platform/Win32/Chrome/EditorWindowChromeController.cpp @@ -3,7 +3,6 @@ #include "Platform/Win32/Windowing/EditorWindow.h" #include "Platform/Win32/Runtime/EditorWindowFrameDriver.h" #include "Platform/Win32/Runtime/EditorWindowRuntimeController.h" -#include "Platform/Win32/Windowing/EditorWindowState.h" #include "Platform/Win32/Windowing/EditorWindowSupport.h" #include @@ -233,12 +232,13 @@ bool EditorWindowChromeController::HandleSystemCommand( EditorContext& editorContext, bool globalTabDragActive, WPARAM wParam) { + const HWND hwnd = window.GetHwnd(); switch (wParam & 0xFFF0u) { case SC_MAXIMIZE: ToggleMaximizeRestore(window, editorContext, globalTabDragActive); return true; case SC_RESTORE: - if (!IsIconic(window.m_state->window.hwnd)) { + if (hwnd != nullptr && !IsIconic(hwnd)) { ToggleMaximizeRestore(window, editorContext, globalTabDragActive); return true; } @@ -253,7 +253,7 @@ bool EditorWindowChromeController::HandleGetMinMaxInfo( LPARAM lParam) const { const ::XCEngine::UI::UISize minimumOuterSize = window.m_runtime->ResolveMinimumOuterSize(); return Host::HandleBorderlessWindowGetMinMaxInfo( - window.m_state->window.hwnd, + window.GetHwnd(), lParam, static_cast(minimumOuterSize.width), static_cast(minimumOuterSize.height)); @@ -264,7 +264,7 @@ LRESULT EditorWindowChromeController::HandleNcCalcSize( WPARAM wParam, LPARAM lParam) const { return Host::HandleBorderlessWindowNcCalcSize( - window.m_state->window.hwnd, + window.GetHwnd(), wParam, lParam, GetWindowDpi()); @@ -283,8 +283,8 @@ bool EditorWindowChromeController::UpdateResizeHover(EditorWindow& window, LPARA bool EditorWindowChromeController::HandleResizeButtonDown(EditorWindow& window, LPARAM lParam) { const Host::BorderlessWindowResizeEdge edge = HitTestResizeEdge(window, lParam); - if (edge == Host::BorderlessWindowResizeEdge::None || - window.m_state->window.hwnd == nullptr) { + const HWND hwnd = window.GetHwnd(); + if (edge == Host::BorderlessWindowResizeEdge::None || hwnd == nullptr) { return false; } @@ -294,7 +294,7 @@ bool EditorWindowChromeController::HandleResizeButtonDown(EditorWindow& window, } RECT windowRect = {}; - if (!GetWindowRect(window.m_state->window.hwnd, &windowRect)) { + if (!GetWindowRect(hwnd, &windowRect)) { return false; } @@ -319,8 +319,8 @@ bool EditorWindowChromeController::HandleResizePointerMove( EditorWindow& window, EditorContext& editorContext, bool globalTabDragActive) { - if (!IsBorderlessResizeActive() || - window.m_state->window.hwnd == nullptr) { + const HWND hwnd = window.GetHwnd(); + if (!IsBorderlessResizeActive() || hwnd == nullptr) { return false; } @@ -380,14 +380,14 @@ bool EditorWindowChromeController::HandleResizePointerMove( const auto setWindowPosBegin = std::chrono::steady_clock::now(); SetWindowPos( - window.m_state->window.hwnd, + hwnd, nullptr, targetRect.left, targetRect.top, width, height, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOREDRAW); - ValidateRect(window.m_state->window.hwnd, nullptr); + ValidateRect(hwnd, nullptr); if (IsVerboseResizeTraceEnabled()) { const auto totalEnd = std::chrono::steady_clock::now(); const auto setWindowPosMs = @@ -434,12 +434,13 @@ void EditorWindowChromeController::ForceClearResizeState(EditorWindow& window) { Host::BorderlessWindowResizeEdge EditorWindowChromeController::HitTestResizeEdge( const EditorWindow& window, LPARAM lParam) const { - if (window.m_state->window.hwnd == nullptr || IsBorderlessWindowMaximized()) { + const HWND hwnd = window.GetHwnd(); + if (hwnd == nullptr || IsBorderlessWindowMaximized()) { return Host::BorderlessWindowResizeEdge::None; } RECT clientRect = {}; - if (!GetClientRect(window.m_state->window.hwnd, &clientRect)) { + if (!GetClientRect(hwnd, &clientRect)) { return Host::BorderlessWindowResizeEdge::None; } @@ -482,6 +483,7 @@ bool EditorWindowChromeController::HandleChromeButtonDown(EditorWindow& window, return false; } + const HWND hwnd = window.GetHwnd(); const Host::BorderlessWindowChromeHitTarget hitTarget = HitTestChrome(window, lParam); switch (hitTarget) { case Host::BorderlessWindowChromeHitTarget::MinimizeButton: @@ -492,7 +494,7 @@ bool EditorWindowChromeController::HandleChromeButtonDown(EditorWindow& window, window.InvalidateHostWindow(); return true; case Host::BorderlessWindowChromeHitTarget::DragRegion: - if (window.m_state->window.hwnd != nullptr) { + if (hwnd != nullptr) { if (IsBorderlessWindowMaximized()) { POINT screenPoint = {}; if (GetCursorPos(&screenPoint)) { @@ -503,7 +505,7 @@ bool EditorWindowChromeController::HandleChromeButtonDown(EditorWindow& window, } window.ForceReleasePointerCapture(); - SendMessageW(window.m_state->window.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); + SendMessageW(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); } return true; case Host::BorderlessWindowChromeHitTarget::None: @@ -565,8 +567,8 @@ bool EditorWindowChromeController::HandleChromeDragRestorePointerMove( EditorWindow& window, EditorContext& editorContext, bool globalTabDragActive) { - if (!IsBorderlessWindowDragRestoreArmed() || - window.m_state->window.hwnd == nullptr) { + const HWND hwnd = window.GetHwnd(); + if (!IsBorderlessWindowDragRestoreArmed() || hwnd == nullptr) { return false; } @@ -630,7 +632,7 @@ bool EditorWindowChromeController::HandleChromeDragRestorePointerMove( SetBorderlessWindowMaximized(false); ApplyPredictedWindowRectTransition(window, editorContext, globalTabDragActive, targetRect); ClearChromeDragRestoreState(window); - SendMessageW(window.m_state->window.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); + SendMessageW(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); return true; } @@ -655,12 +657,13 @@ void EditorWindowChromeController::ClearChromeState(EditorWindow& window) { Host::BorderlessWindowChromeHitTarget EditorWindowChromeController::HitTestChrome( const EditorWindow& window, LPARAM lParam) const { - if (window.m_state->window.hwnd == nullptr) { + const HWND hwnd = window.GetHwnd(); + if (hwnd == nullptr) { return Host::BorderlessWindowChromeHitTarget::None; } RECT clientRect = {}; - if (!GetClientRect(window.m_state->window.hwnd, &clientRect)) { + if (!GetClientRect(hwnd, &clientRect)) { return Host::BorderlessWindowChromeHitTarget::None; } @@ -695,7 +698,7 @@ Host::BorderlessWindowChromeLayout EditorWindowChromeController::ResolveChromeLa bool EditorWindowChromeController::ShouldUseDetachedTitleBarTabStrip( const EditorWindow& window) const { const EditorWindowTitleBarBinding* titleBarBinding = window.m_runtime->TryGetTitleBarBinding(); - return !window.m_state->window.primary && + return !window.IsPrimary() && titleBarBinding != nullptr && titleBarBinding->ShouldUseDetachedTitleBarTabStrip(); } @@ -718,7 +721,7 @@ void EditorWindowChromeController::AppendChrome( 1.0f); } - if (!window.m_state->window.primary) { + if (!window.IsPrimary()) { if (useDetachedTitleBarTabStrip) { if (window.m_runtime->GetTitleBarLogoIcon().IsValid()) { drawList.AddImage( @@ -750,10 +753,11 @@ void EditorWindowChromeController::AppendChrome( (layout.titleBarRect.height - kBorderlessTitleBarFontSize) * 0.5f - 1.0f)), [&window]() { + const std::string_view cachedTitleText = window.GetCachedTitleText(); const std::string_view fallbackWindowTitle = - window.m_state->window.titleText.empty() + cachedTitleText.empty() ? std::string_view("XCEngine Editor") - : std::string_view(window.m_state->window.titleText); + : cachedTitleText; const EditorWindowTitleBarBinding* titleBarBinding = window.m_runtime->TryGetTitleBarBinding(); return titleBarBinding != nullptr @@ -775,10 +779,10 @@ void EditorWindowChromeController::AppendChrome( UIColor(1.0f, 1.0f, 1.0f, 1.0f)); } - const std::string titleText = - window.m_state->window.titleText.empty() + const std::string_view cachedTitleText = window.GetCachedTitleText(); + const std::string titleText = cachedTitleText.empty() ? std::string("XCEngine Editor") - : window.m_state->window.titleText; + : std::string(cachedTitleText); const std::string frameRateText = window.m_runtime->BuildFrameRateText(); drawList.AddText( UIPoint( @@ -834,20 +838,20 @@ bool EditorWindowChromeController::QueryCurrentWindowRect( const EditorWindow& window, RECT& outRect) const { outRect = {}; - return window.m_state->window.hwnd != nullptr && - GetWindowRect(window.m_state->window.hwnd, &outRect) != FALSE; + const HWND hwnd = window.GetHwnd(); + return hwnd != nullptr && GetWindowRect(hwnd, &outRect) != FALSE; } bool EditorWindowChromeController::QueryBorderlessWindowWorkAreaRect( const EditorWindow& window, RECT& outRect) const { outRect = {}; - if (window.m_state->window.hwnd == nullptr) { + const HWND hwnd = window.GetHwnd(); + if (hwnd == nullptr) { return false; } - const HMONITOR monitor = - MonitorFromWindow(window.m_state->window.hwnd, MONITOR_DEFAULTTONEAREST); + const HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if (monitor == nullptr) { return false; } @@ -867,7 +871,8 @@ bool EditorWindowChromeController::ApplyPredictedWindowRectTransition( EditorContext& editorContext, bool globalTabDragActive, const RECT& targetRect) { - if (window.m_state->window.hwnd == nullptr) { + const HWND hwnd = window.GetHwnd(); + if (hwnd == nullptr) { return false; } @@ -887,7 +892,7 @@ bool EditorWindowChromeController::ApplyPredictedWindowRectTransition( MarkPredictedClientPixelSizePresented(); } SetWindowPos( - window.m_state->window.hwnd, + hwnd, nullptr, targetRect.left, targetRect.top, @@ -902,7 +907,7 @@ void EditorWindowChromeController::ToggleMaximizeRestore( EditorWindow& window, EditorContext& editorContext, bool globalTabDragActive) { - if (window.m_state->window.hwnd == nullptr) { + if (window.GetHwnd() == nullptr) { return; } @@ -934,19 +939,20 @@ void EditorWindowChromeController::ExecuteChromeAction( EditorContext& editorContext, bool globalTabDragActive, Host::BorderlessWindowChromeHitTarget target) { - if (window.m_state->window.hwnd == nullptr) { + const HWND hwnd = window.GetHwnd(); + if (hwnd == nullptr) { return; } switch (target) { case Host::BorderlessWindowChromeHitTarget::MinimizeButton: - ShowWindow(window.m_state->window.hwnd, SW_MINIMIZE); + ShowWindow(hwnd, SW_MINIMIZE); break; case Host::BorderlessWindowChromeHitTarget::MaximizeRestoreButton: ToggleMaximizeRestore(window, editorContext, globalTabDragActive); break; case Host::BorderlessWindowChromeHitTarget::CloseButton: - PostMessageW(window.m_state->window.hwnd, WM_CLOSE, 0, 0); + PostMessageW(hwnd, WM_CLOSE, 0, 0); break; case Host::BorderlessWindowChromeHitTarget::DragRegion: case Host::BorderlessWindowChromeHitTarget::None: diff --git a/new_editor/app/Platform/Win32/Runtime/EditorWindowFrameDriver.cpp b/new_editor/app/Platform/Win32/Runtime/EditorWindowFrameDriver.cpp index a4b2f2b5..e4104db5 100644 --- a/new_editor/app/Platform/Win32/Runtime/EditorWindowFrameDriver.cpp +++ b/new_editor/app/Platform/Win32/Runtime/EditorWindowFrameDriver.cpp @@ -23,7 +23,7 @@ EditorWindowFrameTransferRequests EditorWindowFrameDriver::DriveFrameInternal( ValidateRect(hwnd, nullptr); } if (requestSkipNextSteadyStateFrame) { - window.m_chromeController->RequestSkipNextSteadyStateFrame(); + window.RequestSkipNextSteadyStateFrame(); } return transferRequests; diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindow.cpp b/new_editor/app/Platform/Win32/Windowing/EditorWindow.cpp index fbbe80b1..1f67497d 100644 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindow.cpp +++ b/new_editor/app/Platform/Win32/Windowing/EditorWindow.cpp @@ -3,10 +3,10 @@ #include "Platform/Win32/Chrome/EditorWindowChromeController.h" #include "Platform/Win32/Content/EditorWindowContentController.h" #include "Platform/Win32/Runtime/EditorWindowFrameDriver.h" +#include "Platform/Win32/Windowing/EditorWindowSession.h" #include "Platform/Win32/Windowing/EditorWindowSupport.h" #include "Platform/Win32/Runtime/EditorWindowFrameOrchestrator.h" #include "Platform/Win32/Runtime/EditorWindowInputController.h" -#include "Platform/Win32/Windowing/EditorWindowState.h" #include "Platform/Win32/Runtime/EditorWindowRuntimeController.h" #include "Composition/EditorContext.h" #include @@ -79,46 +79,44 @@ EditorWindow::EditorWindow( std::wstring title, bool primary, std::unique_ptr contentController) - : m_state(std::make_unique()) + : m_session(std::make_unique( + std::move(windowId), + std::move(title), + primary)) , m_chromeController(std::make_unique()) , m_frameOrchestrator(std::make_unique()) , m_inputController(std::make_unique()) , m_runtime(std::make_unique( - std::move(contentController))) { - m_state->window.windowId = std::move(windowId); - m_state->window.title = std::move(title); - m_state->window.primary = primary; - UpdateCachedTitleText(); -} + std::move(contentController))) {} EditorWindow::~EditorWindow() = default; std::string_view EditorWindow::GetWindowId() const { - return m_state->window.windowId; + return m_session->GetWindowId(); } HWND EditorWindow::GetHwnd() const { - return m_state->window.hwnd; + return m_session->GetHwnd(); } bool EditorWindow::HasHwnd() const { - return m_state->window.hwnd != nullptr; + return m_session->HasHwnd(); } EditorWindowLifecycleState EditorWindow::GetLifecycleState() const { - return m_state->window.lifecycle; + return m_session->GetLifecycleState(); } bool EditorWindow::IsPrimary() const { - return m_state->window.primary; + return m_session->IsPrimary(); } bool EditorWindow::IsClosing() const { - return m_state->window.lifecycle == EditorWindowLifecycleState::Closing; + return m_session->IsClosing(); } bool EditorWindow::IsDestroyed() const { - return m_state->window.lifecycle == EditorWindowLifecycleState::Destroyed; + return m_session->IsDestroyed(); } bool EditorWindow::IsRenderReady() const { @@ -126,7 +124,11 @@ bool EditorWindow::IsRenderReady() const { } const std::wstring& EditorWindow::GetTitle() const { - return m_state->window.title; + return m_session->GetTitle(); +} + +std::string_view EditorWindow::GetCachedTitleText() const { + return m_session->GetCachedTitleText(); } const UIEditorWorkspaceController* EditorWindow::TryGetWorkspaceController() const { @@ -143,35 +145,32 @@ const UIEditorWorkspaceController& EditorWindow::GetWorkspaceController() const } void EditorWindow::AttachHwnd(HWND hwnd) { - m_state->window.hwnd = hwnd; - m_state->window.lifecycle = EditorWindowLifecycleState::NativeAttached; + m_session->AttachHwnd(hwnd); } void EditorWindow::MarkInitializing() { - m_state->window.lifecycle = EditorWindowLifecycleState::Initializing; + m_session->MarkInitializing(); } void EditorWindow::MarkRunning() { - m_state->window.lifecycle = EditorWindowLifecycleState::Running; + m_session->MarkRunning(); } void EditorWindow::MarkDestroyed() { - m_state->window.hwnd = nullptr; - m_state->window.lifecycle = EditorWindowLifecycleState::Destroyed; + m_session->MarkDestroyed(); m_inputController->ResetWindowState(); } void EditorWindow::MarkClosing() { - m_state->window.lifecycle = EditorWindowLifecycleState::Closing; + m_session->MarkClosing(); } void EditorWindow::SetPrimary(bool primary) { - m_state->window.primary = primary; + m_session->SetPrimary(primary); } void EditorWindow::SetTitle(std::wstring title) { - m_state->window.title = std::move(title); - UpdateCachedTitleText(); + m_session->SetTitle(std::move(title)); } void EditorWindow::ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController) { @@ -181,8 +180,9 @@ void EditorWindow::ReplaceWorkspaceController(UIEditorWorkspaceController worksp } void EditorWindow::InvalidateHostWindow() const { - if (m_state->window.hwnd != nullptr && IsWindow(m_state->window.hwnd)) { - InvalidateRect(m_state->window.hwnd, nullptr, FALSE); + if (const HWND hwnd = m_session->GetHwnd(); + hwnd != nullptr && IsWindow(hwnd)) { + InvalidateRect(hwnd, nullptr, FALSE); } } @@ -191,14 +191,14 @@ bool EditorWindow::Initialize( EditorContext& editorContext, const std::filesystem::path& captureRoot, bool autoCaptureOnStartup) { - if (m_state->window.hwnd == nullptr) { + if (m_session->GetHwnd() == nullptr) { LogRuntimeTrace("app", "window initialize skipped: hwnd is null"); return false; } - Host::RefreshBorderlessWindowDwmDecorations(m_state->window.hwnd); + Host::RefreshBorderlessWindowDwmDecorations(m_session->GetHwnd()); m_chromeController->Reset(); - m_chromeController->SetWindowDpi(QueryWindowDpi(m_state->window.hwnd)); + m_chromeController->SetWindowDpi(QueryWindowDpi(m_session->GetHwnd())); m_runtime->SetDpiScale(GetDpiScale()); std::ostringstream dpiTrace = {}; @@ -208,7 +208,7 @@ bool EditorWindow::Initialize( MarkInitializing(); const bool initialized = m_runtime->Initialize( - m_state->window.hwnd, + m_session->GetHwnd(), repoRoot, editorContext, captureRoot, @@ -216,7 +216,7 @@ bool EditorWindow::Initialize( if (initialized) { MarkRunning(); } else { - m_state->window.lifecycle = EditorWindowLifecycleState::NativeAttached; + m_session->MarkNativeAttached(); } return initialized; } @@ -267,12 +267,13 @@ bool EditorWindow::ApplyWindowResize(UINT width, UINT height) { bool EditorWindow::QueryCurrentClientPixelSize(UINT& outWidth, UINT& outHeight) const { outWidth = 0u; outHeight = 0u; - if (m_state->window.hwnd == nullptr || !IsWindow(m_state->window.hwnd)) { + const HWND hwnd = m_session->GetHwnd(); + if (hwnd == nullptr || !IsWindow(hwnd)) { return false; } RECT clientRect = {}; - if (!GetClientRect(m_state->window.hwnd, &clientRect)) { + if (!GetClientRect(hwnd, &clientRect)) { return false; } @@ -312,8 +313,9 @@ UIPoint EditorWindow::ConvertClientPixelsToDips(LONG x, LONG y) const { UIPoint EditorWindow::ConvertScreenPixelsToClientDips(const POINT& screenPoint) const { POINT clientPoint = screenPoint; - if (m_state->window.hwnd != nullptr) { - ScreenToClient(m_state->window.hwnd, &clientPoint); + if (const HWND hwnd = m_session->GetHwnd(); + hwnd != nullptr) { + ScreenToClient(hwnd, &clientPoint); } const float dpiScale = m_chromeController->GetDpiScale(kBaseDpiScale); @@ -374,8 +376,9 @@ bool EditorWindow::OnResize(UINT width, UINT height) { if (!matchedPresentedPrediction) { m_chromeController->ClearPredictedClientPixelSize(); } - if (m_state->window.hwnd != nullptr) { - Host::RefreshBorderlessWindowDwmDecorations(m_state->window.hwnd); + if (const HWND hwnd = m_session->GetHwnd(); + hwnd != nullptr) { + Host::RefreshBorderlessWindowDwmDecorations(hwnd); } if (matchedPresentedPrediction) { @@ -405,11 +408,12 @@ bool EditorWindow::OnExitSizeMove() { void EditorWindow::OnDpiChanged(UINT dpi, const RECT& suggestedRect) { m_chromeController->SetWindowDpi(dpi == 0u ? kDefaultDpi : dpi); m_runtime->SetDpiScale(GetDpiScale()); - if (m_state->window.hwnd != nullptr) { + if (const HWND hwnd = m_session->GetHwnd(); + hwnd != nullptr) { const LONG windowWidth = suggestedRect.right - suggestedRect.left; const LONG windowHeight = suggestedRect.bottom - suggestedRect.top; SetWindowPos( - m_state->window.hwnd, + hwnd, nullptr, suggestedRect.left, suggestedRect.top, @@ -421,7 +425,7 @@ void EditorWindow::OnDpiChanged(UINT dpi, const RECT& suggestedRect) { if (QueryCurrentClientPixelSize(clientWidth, clientHeight)) { ApplyWindowResize(clientWidth, clientHeight); } - Host::RefreshBorderlessWindowDwmDecorations(m_state->window.hwnd); + Host::RefreshBorderlessWindowDwmDecorations(hwnd); } std::ostringstream trace = {}; @@ -435,10 +439,6 @@ bool EditorWindow::IsVerboseRuntimeTraceEnabled() { return s_enabled; } -void EditorWindow::UpdateCachedTitleText() { - m_state->window.titleText = WideToUtf8(m_state->window.title); -} - } // namespace XCEngine::UI::Editor::App namespace XCEngine::UI::Editor::App { @@ -512,7 +512,7 @@ std::uint8_t ResolveExpectedShellCaptureButtons( EditorWindowFrameTransferRequests EditorWindow::RenderFrame( EditorContext& editorContext, bool globalTabDragActive) { - if (!m_runtime->IsReady() || m_state->window.hwnd == nullptr) { + if (!m_runtime->IsReady() || m_session->GetHwnd() == nullptr) { return {}; } @@ -554,49 +554,41 @@ EditorWindowFrameTransferRequests EditorWindow::RenderFrame( EditorWindowFrameTransferRequests EditorWindow::OnPaintMessage( EditorContext& editorContext, bool globalTabDragActive) { - if (!m_runtime->IsReady() || m_state->window.hwnd == nullptr) { + if (!m_runtime->IsReady() || m_session->GetHwnd() == nullptr) { return {}; } PAINTSTRUCT paintStruct = {}; - BeginPaint(m_state->window.hwnd, &paintStruct); + BeginPaint(m_session->GetHwnd(), &paintStruct); const EditorWindowFrameTransferRequests transferRequests = EditorWindowFrameDriver::DriveImmediateFrame( *this, editorContext, globalTabDragActive); - EndPaint(m_state->window.hwnd, &paintStruct); + EndPaint(m_session->GetHwnd(), &paintStruct); return transferRequests; } void EditorWindow::QueueCompletedImmediateFrame( EditorWindowFrameTransferRequests transferRequests) { - m_hasQueuedCompletedImmediateFrame = true; - if (transferRequests.beginGlobalTabDrag.has_value()) { - m_queuedImmediateFrameTransferRequests.beginGlobalTabDrag = - std::move(transferRequests.beginGlobalTabDrag); - } - if (transferRequests.detachPanel.has_value()) { - m_queuedImmediateFrameTransferRequests.detachPanel = - std::move(transferRequests.detachPanel); - } - if (transferRequests.openUtilityWindow.has_value()) { - m_queuedImmediateFrameTransferRequests.openUtilityWindow = - std::move(transferRequests.openUtilityWindow); - } + m_session->QueueCompletedImmediateFrame(std::move(transferRequests)); } bool EditorWindow::HasQueuedCompletedImmediateFrame() const { - return m_hasQueuedCompletedImmediateFrame; + return m_session->HasQueuedCompletedImmediateFrame(); } EditorWindowFrameTransferRequests EditorWindow::ConsumeQueuedCompletedImmediateFrameTransferRequests() { - m_hasQueuedCompletedImmediateFrame = false; - EditorWindowFrameTransferRequests transferRequests = - std::move(m_queuedImmediateFrameTransferRequests); - m_queuedImmediateFrameTransferRequests = {}; - return transferRequests; + return m_session->ConsumeQueuedCompletedImmediateFrameTransferRequests(); +} + +void EditorWindow::RequestSkipNextSteadyStateFrame() { + m_chromeController->RequestSkipNextSteadyStateFrame(); +} + +bool EditorWindow::ConsumeSkipNextSteadyStateFrame() { + return m_chromeController->ConsumeSkipNextSteadyStateFrame(); } UIRect EditorWindow::ResolveWorkspaceBounds(float clientWidthDips, float clientHeightDips) const { @@ -634,7 +626,7 @@ EditorWindowFrameTransferRequests EditorWindow::RenderRuntimeFrame( .bounds = workspaceBounds, .inputEvents = frameEvents, .captureStatusText = m_runtime->BuildCaptureStatusText(), - .primary = m_state->window.primary, + .primary = m_session->IsPrimary(), .globalTabDragActive = globalTabDragActive, .useDetachedTitleBarTabStrip = useDetachedTitleBarTabStrip, }, @@ -748,21 +740,22 @@ bool EditorWindow::OwnsPointerCapture(EditorWindowPointerCaptureOwner owner) con } void EditorWindow::AcquirePointerCapture(EditorWindowPointerCaptureOwner owner) { - m_inputController->AcquirePointerCapture(m_state->window.hwnd, owner); + m_inputController->AcquirePointerCapture(m_session->GetHwnd(), owner); } void EditorWindow::ReleasePointerCapture(EditorWindowPointerCaptureOwner owner) { - m_inputController->ReleasePointerCapture(m_state->window.hwnd, owner); + m_inputController->ReleasePointerCapture(m_session->GetHwnd(), owner); } void EditorWindow::ForceReleasePointerCapture() { - m_inputController->ForceReleasePointerCapture(m_state->window.hwnd); + m_inputController->ForceReleasePointerCapture(m_session->GetHwnd()); } void EditorWindow::TryStartImmediateShellPointerCapture(LPARAM lParam) { - if (m_state->window.hwnd == nullptr || - !IsWindow(m_state->window.hwnd) || - GetCapture() == m_state->window.hwnd) { + const HWND hwnd = m_session->GetHwnd(); + if (hwnd == nullptr || + !IsWindow(hwnd) || + GetCapture() == hwnd) { return; } @@ -794,7 +787,8 @@ void EditorWindow::QueuePointerEvent( void EditorWindow::QueueSyntheticPointerStateSyncEvent( const ::XCEngine::UI::UIInputModifiers& modifiers) { - if (m_state->window.hwnd == nullptr || !IsWindow(m_state->window.hwnd)) { + const HWND hwnd = m_session->GetHwnd(); + if (hwnd == nullptr || !IsWindow(hwnd)) { return; } @@ -802,7 +796,7 @@ void EditorWindow::QueueSyntheticPointerStateSyncEvent( if (!GetCursorPos(&screenPoint)) { return; } - if (!ScreenToClient(m_state->window.hwnd, &screenPoint)) { + if (!ScreenToClient(hwnd, &screenPoint)) { return; } @@ -813,17 +807,18 @@ void EditorWindow::QueueSyntheticPointerStateSyncEvent( void EditorWindow::QueuePointerLeaveEvent() { ::XCEngine::UI::UIPoint position = {}; - if (m_state->window.hwnd != nullptr) { + if (const HWND hwnd = m_session->GetHwnd(); + hwnd != nullptr) { POINT clientPoint = {}; GetCursorPos(&clientPoint); - ScreenToClient(m_state->window.hwnd, &clientPoint); + ScreenToClient(hwnd, &clientPoint); position = ConvertClientPixelsToDips(clientPoint.x, clientPoint.y); } m_inputController->QueuePointerLeaveEvent(position); } void EditorWindow::QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARAM lParam) { - if (m_state->window.hwnd == nullptr) { + if (m_session->GetHwnd() == nullptr) { return; } @@ -831,7 +826,7 @@ void EditorWindow::QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARA GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - ScreenToClient(m_state->window.hwnd, &screenPoint); + ScreenToClient(m_session->GetHwnd(), &screenPoint); m_inputController->QueuePointerWheelEvent( ConvertClientPixelsToDips(screenPoint.x, screenPoint.y), @@ -840,7 +835,8 @@ void EditorWindow::QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARA } bool EditorWindow::IsPointerInsideClientArea() const { - if (m_state->window.hwnd == nullptr || !IsWindow(m_state->window.hwnd)) { + const HWND hwnd = m_session->GetHwnd(); + if (hwnd == nullptr || !IsWindow(hwnd)) { return false; } @@ -849,14 +845,14 @@ bool EditorWindow::IsPointerInsideClientArea() const { return false; } - if (!IsScreenPointOverWindow(m_state->window.hwnd, screenPoint)) { + if (!IsScreenPointOverWindow(hwnd, screenPoint)) { return false; } const LPARAM pointParam = MAKELPARAM( static_cast(screenPoint.x), static_cast(screenPoint.y)); - return SendMessageW(m_state->window.hwnd, WM_NCHITTEST, 0, pointParam) == HTCLIENT; + return SendMessageW(hwnd, WM_NCHITTEST, 0, pointParam) == HTCLIENT; } LPCWSTR EditorWindow::ResolveCurrentCursorResource() const { diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindow.h b/new_editor/app/Platform/Win32/Windowing/EditorWindow.h index e82d4f5a..84cbf521 100644 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindow.h +++ b/new_editor/app/Platform/Win32/Windowing/EditorWindow.h @@ -5,8 +5,7 @@ #endif #include "Platform/Win32/Windowing/EditorWindowPointerCapture.h" -#include "Platform/Win32/Windowing/EditorWindowState.h" -#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h" +#include "Platform/Win32/Windowing/EditorWindowSession.h" #include @@ -61,7 +60,7 @@ class EditorWindowLifecycleCoordinator; class EditorWindowMessageDispatcher; class EditorWindowRuntimeController; class EditorWindowWorkspaceCoordinator; -struct EditorWindowState; +class EditorWindowSession; class EditorWindow { public: @@ -85,6 +84,7 @@ public: bool IsClosing() const; bool IsDestroyed() const; const std::wstring& GetTitle() const; + std::string_view GetCachedTitleText() const; const UIEditorWorkspaceController* TryGetWorkspaceController() const; const UIEditorWorkspaceController& GetWorkspaceController() const; ::XCEngine::UI::UIPoint ConvertScreenPixelsToClientDips(const POINT& screenPoint) const; @@ -135,6 +135,8 @@ private: EditorWindowFrameTransferRequests transferRequests); bool HasQueuedCompletedImmediateFrame() const; EditorWindowFrameTransferRequests ConsumeQueuedCompletedImmediateFrameTransferRequests(); + void RequestSkipNextSteadyStateFrame(); + bool ConsumeSkipNextSteadyStateFrame(); bool OnResize(UINT width, UINT height); void OnEnterSizeMove(); bool OnExitSizeMove(); @@ -177,16 +179,13 @@ private: float PixelsToDips(float pixels) const; ::XCEngine::UI::UIPoint ConvertClientPixelsToDips(LONG x, LONG y) const; void ApplyShellRuntimePointerCapture(); - void UpdateCachedTitleText(); static bool IsVerboseRuntimeTraceEnabled(); - std::unique_ptr m_state = {}; + std::unique_ptr m_session = {}; std::unique_ptr m_chromeController = {}; std::unique_ptr m_frameOrchestrator = {}; std::unique_ptr m_inputController = {}; std::unique_ptr m_runtime = {}; - EditorWindowFrameTransferRequests m_queuedImmediateFrameTransferRequests = {}; - bool m_hasQueuedCompletedImmediateFrame = false; }; } // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.cpp b/new_editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.cpp index 6460bd1a..f2e3b382 100644 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.cpp +++ b/new_editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.cpp @@ -190,7 +190,7 @@ void EditorWindowHostRuntime::RenderAllWindows( continue; } - if (window->m_chromeController->ConsumeSkipNextSteadyStateFrame()) { + if (window->ConsumeSkipNextSteadyStateFrame()) { workspaceCoordinator.RefreshWindowPresentation(*window); continue; } diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp b/new_editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp new file mode 100644 index 00000000..2e5045ad --- /dev/null +++ b/new_editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp @@ -0,0 +1,126 @@ +#include "Platform/Win32/Windowing/EditorWindowSession.h" + +#include "Platform/Win32/Windowing/EditorWindowSupport.h" + +#include + +namespace XCEngine::UI::Editor::App { + +using namespace EditorWindowSupport; + +EditorWindowSession::EditorWindowSession( + std::string windowId, + std::wstring title, + bool primary) { + m_state.window.windowId = std::move(windowId); + m_state.window.title = std::move(title); + m_state.window.primary = primary; + UpdateCachedTitleText(); +} + +std::string_view EditorWindowSession::GetWindowId() const { + return m_state.window.windowId; +} + +HWND EditorWindowSession::GetHwnd() const { + return m_state.window.hwnd; +} + +bool EditorWindowSession::HasHwnd() const { + return m_state.window.hwnd != nullptr; +} + +EditorWindowLifecycleState EditorWindowSession::GetLifecycleState() const { + return m_state.window.lifecycle; +} + +bool EditorWindowSession::IsPrimary() const { + return m_state.window.primary; +} + +bool EditorWindowSession::IsClosing() const { + return m_state.window.lifecycle == EditorWindowLifecycleState::Closing; +} + +bool EditorWindowSession::IsDestroyed() const { + return m_state.window.lifecycle == EditorWindowLifecycleState::Destroyed; +} + +const std::wstring& EditorWindowSession::GetTitle() const { + return m_state.window.title; +} + +std::string_view EditorWindowSession::GetCachedTitleText() const { + return m_state.window.titleText; +} + +void EditorWindowSession::AttachHwnd(HWND hwnd) { + m_state.window.hwnd = hwnd; + m_state.window.lifecycle = EditorWindowLifecycleState::NativeAttached; +} + +void EditorWindowSession::MarkNativeAttached() { + m_state.window.lifecycle = EditorWindowLifecycleState::NativeAttached; +} + +void EditorWindowSession::MarkInitializing() { + m_state.window.lifecycle = EditorWindowLifecycleState::Initializing; +} + +void EditorWindowSession::MarkRunning() { + m_state.window.lifecycle = EditorWindowLifecycleState::Running; +} + +void EditorWindowSession::MarkDestroyed() { + m_state.window.hwnd = nullptr; + m_state.window.lifecycle = EditorWindowLifecycleState::Destroyed; +} + +void EditorWindowSession::MarkClosing() { + m_state.window.lifecycle = EditorWindowLifecycleState::Closing; +} + +void EditorWindowSession::SetPrimary(bool primary) { + m_state.window.primary = primary; +} + +void EditorWindowSession::SetTitle(std::wstring title) { + m_state.window.title = std::move(title); + UpdateCachedTitleText(); +} + +void EditorWindowSession::QueueCompletedImmediateFrame( + EditorWindowFrameTransferRequests transferRequests) { + m_hasQueuedCompletedImmediateFrame = true; + if (transferRequests.beginGlobalTabDrag.has_value()) { + m_queuedImmediateFrameTransferRequests.beginGlobalTabDrag = + std::move(transferRequests.beginGlobalTabDrag); + } + if (transferRequests.detachPanel.has_value()) { + m_queuedImmediateFrameTransferRequests.detachPanel = + std::move(transferRequests.detachPanel); + } + if (transferRequests.openUtilityWindow.has_value()) { + m_queuedImmediateFrameTransferRequests.openUtilityWindow = + std::move(transferRequests.openUtilityWindow); + } +} + +bool EditorWindowSession::HasQueuedCompletedImmediateFrame() const { + return m_hasQueuedCompletedImmediateFrame; +} + +EditorWindowFrameTransferRequests +EditorWindowSession::ConsumeQueuedCompletedImmediateFrameTransferRequests() { + m_hasQueuedCompletedImmediateFrame = false; + EditorWindowFrameTransferRequests transferRequests = + std::move(m_queuedImmediateFrameTransferRequests); + m_queuedImmediateFrameTransferRequests = {}; + return transferRequests; +} + +void EditorWindowSession::UpdateCachedTitleText() { + m_state.window.titleText = WideToUtf8(m_state.window.title); +} + +} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowSession.h b/new_editor/app/Platform/Win32/Windowing/EditorWindowSession.h new file mode 100644 index 00000000..c2027c0b --- /dev/null +++ b/new_editor/app/Platform/Win32/Windowing/EditorWindowSession.h @@ -0,0 +1,47 @@ +#pragma once + +#include "Platform/Win32/Windowing/EditorWindowState.h" +#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h" + +#include +#include + +namespace XCEngine::UI::Editor::App { + +class EditorWindowSession final { +public: + EditorWindowSession(std::string windowId, std::wstring title, bool primary); + + std::string_view GetWindowId() const; + HWND GetHwnd() const; + bool HasHwnd() const; + EditorWindowLifecycleState GetLifecycleState() const; + bool IsPrimary() const; + bool IsClosing() const; + bool IsDestroyed() const; + const std::wstring& GetTitle() const; + std::string_view GetCachedTitleText() const; + + void AttachHwnd(HWND hwnd); + void MarkNativeAttached(); + void MarkInitializing(); + void MarkRunning(); + void MarkDestroyed(); + void MarkClosing(); + void SetPrimary(bool primary); + void SetTitle(std::wstring title); + + void QueueCompletedImmediateFrame( + EditorWindowFrameTransferRequests transferRequests); + bool HasQueuedCompletedImmediateFrame() const; + EditorWindowFrameTransferRequests ConsumeQueuedCompletedImmediateFrameTransferRequests(); + +private: + void UpdateCachedTitleText(); + + EditorWindowState m_state = {}; + EditorWindowFrameTransferRequests m_queuedImmediateFrameTransferRequests = {}; + bool m_hasQueuedCompletedImmediateFrame = false; +}; + +} // namespace XCEngine::UI::Editor::App