@@ -152,6 +152,7 @@ public void ResizeWindowBy(Window window, int deltaWidth, int deltaHeight)
152152 /// <summary>
153153 /// Performs a move or resize operation with desktop clearing and window invalidation.
154154 /// Used for keyboard-based window operations.
155+ /// Uses the same queued rendering approach as mouse drag for consistency.
155156 /// </summary>
156157 /// <param name="window">The window to move or resize.</param>
157158 /// <param name="windowTopologyAction">The type of operation (Move or Resize).</param>
@@ -160,55 +161,37 @@ public void MoveOrResizeOperation(Window? window, WindowTopologyAction windowTop
160161 {
161162 if ( window == null ) return ;
162163
163- var context = _getWindowSystem ( ) ;
164- var theme = context . Theme ;
165-
166164 // Store the current window bounds before any operation
167165 var oldBounds = new Rectangle ( window . Left , window . Top , window . Width , window . Height ) ;
168166
169- // FIRST: Clear the old window position completely (same as mouse operations)
170- _renderer . FillRect ( window . Left , window . Top , window . Width , window . Height ,
171- theme . DesktopBackgroundChar , theme . DesktopBackgroundColor , theme . DesktopForegroundColor ) ;
172-
173- // Redraw the necessary regions that were underneath the window
174- foreach ( var w in context . Windows . Values . OrderBy ( w => w . ZIndex ) )
175- {
176- // Skip minimized windows - they're invisible
177- if ( w . State == WindowState . Minimized )
178- continue ;
179-
180- if ( w != window && GeometryHelpers . DoesRectangleOverlapWindow ( oldBounds , w ) )
181- {
182- // Redraw the parts of underlying windows that were covered
183- var intersection = GeometryHelpers . GetRectangleIntersection ( oldBounds ,
184- new Rectangle ( w . Left , w . Top , w . Width , w . Height ) ) ;
185-
186- if ( ! intersection . IsEmpty )
187- {
188- _renderer . RenderRegion ( w , intersection ) ;
189- }
190- }
191- }
167+ // Use the same queued approach as mouse move for consistent rendering.
168+ // The pending desktop clear will be processed at the start of UpdateDisplay().
169+ _renderCoordinator . AddPendingDesktopClear ( oldBounds ) ;
192170
193- // FINALLY: Invalidate the window which will cause it to redraw at its new position
171+ // Invalidate the window which will cause it to redraw at its new position
194172 // (The actual position/size change happens in the calling HandleMoveInput method)
195- window . Invalidate ( false ) ;
173+ window . Invalidate ( true ) ;
174+
175+ // Invalidate windows that were underneath (now exposed) and at new position
176+ InvalidateExposedRegions ( window , oldBounds ) ;
196177 }
197178
198179 #region Private Helper Methods
199180
200181 /// <summary>
201- /// Invalidates windows that were underneath the moved window and are now exposed.
182+ /// Invalidates windows that were underneath the moved window and are now exposed,
183+ /// as well as windows at the new position that need to re-render with updated occlusion.
202184 /// </summary>
203185 /// <param name="movedWindow">The window that was moved.</param>
204186 /// <param name="oldBounds">The old bounds of the moved window.</param>
205187 private void InvalidateExposedRegions ( Window movedWindow , Rectangle oldBounds )
206188 {
207- // BRUTE FORCE FIX: Instead of trying to render tiny exposed regions (which causes blanks),
208- // just invalidate all windows that were underneath the old position.
209- // They'll render normally with proper visibleRegions in the next UpdateDisplay.
189+ // Invalidate windows at both OLD position (now exposed) and NEW position (now covered).
190+ // This ensures proper re-rendering in both areas affected by the move.
210191
211192 var context = _getWindowSystem ( ) ;
193+ var newBounds = new Rectangle ( movedWindow . Left , movedWindow . Top ,
194+ movedWindow . Width , movedWindow . Height ) ;
212195
213196 foreach ( var window in context . Windows . Values )
214197 {
@@ -218,8 +201,10 @@ private void InvalidateExposedRegions(Window movedWindow, Rectangle oldBounds)
218201 if ( window . ZIndex >= movedWindow . ZIndex )
219202 continue ; // Only invalidate windows that were underneath
220203
221- // Check if this window overlaps with the OLD position
222- if ( GeometryHelpers . DoesRectangleOverlapWindow ( oldBounds , window ) )
204+ // Check overlap with OLD position (exposed regions that need re-rendering)
205+ // AND NEW position (newly covered regions that need refresh when uncovered)
206+ if ( GeometryHelpers . DoesRectangleOverlapWindow ( oldBounds , window ) ||
207+ GeometryHelpers . DoesRectangleOverlapWindow ( newBounds , window ) )
223208 {
224209 window . Invalidate ( true ) ;
225210 }
0 commit comments