diff --git a/src/host/getset.cpp b/src/host/getset.cpp index 7a088afb638..53a112d3fee 100644 --- a/src/host/getset.cpp +++ b/src/host/getset.cpp @@ -524,7 +524,24 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont COORD const coordScreenBufferSize = screenInfo.GetBufferSize().Dimensions(); if (size.X != coordScreenBufferSize.X || size.Y != coordScreenBufferSize.Y) { - RETURN_NTSTATUS(screenInfo.ResizeScreenBuffer(size, TRUE)); + RETURN_IF_NTSTATUS_FAILED(screenInfo.ResizeScreenBuffer(size, TRUE)); + } + + // Make sure the viewport doesn't now overflow the buffer dimensions. + auto overflow = screenInfo.GetViewport().EndExclusive() - screenInfo.GetBufferSize().Dimensions(); + if (overflow.X > 0 || overflow.Y > 0) + { + overflow = { std::max(overflow.X, 0), std::max(overflow.Y, 0) }; + RETURN_IF_NTSTATUS_FAILED(screenInfo.SetViewportOrigin(false, -overflow, false)); + } + + // And also that the cursor position is clamped within the buffer boundaries. + auto& cursor = screenInfo.GetTextBuffer().GetCursor(); + auto clampedCursorPosition = cursor.GetPosition(); + screenInfo.GetBufferSize().Clamp(clampedCursorPosition); + if (clampedCursorPosition != cursor.GetPosition()) + { + cursor.SetPosition(clampedCursorPosition); } return S_OK; @@ -620,6 +637,23 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont // (see https://msdn.microsoft.com/en-us/library/windows/desktop/ms686125(v=vs.85).aspx and DoSrvSetConsoleWindowInfo) // Note that it also doesn't set cursor position. + // However, we do need to make sure the viewport doesn't now overflow the buffer dimensions. + auto overflow = context.GetViewport().EndExclusive() - context.GetBufferSize().Dimensions(); + if (overflow.X > 0 || overflow.Y > 0) + { + overflow = { std::max(overflow.X, 0), std::max(overflow.Y, 0) }; + RETURN_IF_NTSTATUS_FAILED(context.SetViewportOrigin(false, -overflow, false)); + } + + // And also that the cursor position is clamped within the buffer boundaries. + auto& cursor = context.GetTextBuffer().GetCursor(); + auto clampedCursorPosition = cursor.GetPosition(); + context.GetBufferSize().Clamp(clampedCursorPosition); + if (clampedCursorPosition != cursor.GetPosition()) + { + cursor.SetPosition(clampedCursorPosition); + } + return S_OK; } CATCH_RETURN(); diff --git a/src/host/renderData.cpp b/src/host/renderData.cpp index 41d41d4d035..a84b95ac5e5 100644 --- a/src/host/renderData.cpp +++ b/src/host/renderData.cpp @@ -276,7 +276,7 @@ const std::vector RenderData::GetOver // - // Return Value: // - true if the cursor should be drawn twice as wide as usual -bool RenderData::IsCursorDoubleWidth() const noexcept +bool RenderData::IsCursorDoubleWidth() const { const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); return gci.GetActiveOutputBuffer().CursorIsDoubleWidth(); diff --git a/src/host/renderData.hpp b/src/host/renderData.hpp index 26f291477d0..17172aba435 100644 --- a/src/host/renderData.hpp +++ b/src/host/renderData.hpp @@ -46,7 +46,7 @@ class RenderData final : CursorType GetCursorStyle() const noexcept override; ULONG GetCursorPixelWidth() const noexcept override; COLORREF GetCursorColor() const noexcept override; - bool IsCursorDoubleWidth() const noexcept override; + bool IsCursorDoubleWidth() const override; bool IsScreenReversed() const noexcept override; diff --git a/src/host/screenInfo.cpp b/src/host/screenInfo.cpp index 57edb1058e9..41b1a818c9a 100644 --- a/src/host/screenInfo.cpp +++ b/src/host/screenInfo.cpp @@ -2146,7 +2146,7 @@ void SCREEN_INFORMATION::SetViewport(const Viewport& newViewport, } // do adjustments on a copy that's easily manipulated. - SMALL_RECT srCorrected = newViewport.ToInclusive(); + SMALL_RECT srCorrected = newViewport.ToExclusive(); if (srCorrected.Left < 0) { @@ -2160,16 +2160,16 @@ void SCREEN_INFORMATION::SetViewport(const Viewport& newViewport, } const COORD coordScreenBufferSize = GetBufferSize().Dimensions(); - if (srCorrected.Right >= coordScreenBufferSize.X) + if (srCorrected.Right > coordScreenBufferSize.X) { srCorrected.Right = coordScreenBufferSize.X; } - if (srCorrected.Bottom >= coordScreenBufferSize.Y) + if (srCorrected.Bottom > coordScreenBufferSize.Y) { srCorrected.Bottom = coordScreenBufferSize.Y; } - _viewport = Viewport::FromInclusive(srCorrected); + _viewport = Viewport::FromExclusive(srCorrected); if (updateBottom) { UpdateBottom();