@@ -319,30 +319,68 @@ private ResizeDirection GetResizeDirection(Window window, Point point)
319319 // Corner resize areas
320320 if ( relativePoint . Y == 0 )
321321 {
322- if ( inTitleBarCorner && onLeftBorder ) return ResizeDirection . TopLeft ;
323- if ( inTitleBarCorner && onRightBorder ) return ResizeDirection . TopRight ;
322+ if ( inTitleBarCorner && onLeftBorder ) return AllowedDirection ( window , ResizeDirection . TopLeft ) ;
323+ if ( inTitleBarCorner && onRightBorder ) return AllowedDirection ( window , ResizeDirection . TopRight ) ;
324324 }
325325 else
326326 {
327- if ( onTopBorder && onLeftBorder ) return ResizeDirection . TopLeft ;
328- if ( onTopBorder && onRightBorder ) return ResizeDirection . TopRight ;
327+ if ( onTopBorder && onLeftBorder ) return AllowedDirection ( window , ResizeDirection . TopLeft ) ;
328+ if ( onTopBorder && onRightBorder ) return AllowedDirection ( window , ResizeDirection . TopRight ) ;
329329 }
330330
331- if ( onBottomBorder && onLeftBorder ) return ResizeDirection . BottomLeft ;
332- if ( onBottomBorder && onRightBorder ) return ResizeDirection . BottomRight ;
331+ if ( onBottomBorder && onLeftBorder ) return AllowedDirection ( window , ResizeDirection . BottomLeft ) ;
332+ if ( onBottomBorder && onRightBorder ) return AllowedDirection ( window , ResizeDirection . BottomRight ) ;
333333
334334 // Resize grip at bottom-right
335- if ( IsOnResizeGrip ( window , point ) ) return ResizeDirection . BottomRight ;
335+ if ( IsOnResizeGrip ( window , point ) ) return AllowedDirection ( window , ResizeDirection . BottomRight ) ;
336336
337337 // Edge resize areas
338- if ( onTopBorder ) return ResizeDirection . Top ;
339- if ( onBottomBorder ) return ResizeDirection . Bottom ;
340- if ( onLeftBorder ) return ResizeDirection . Left ;
341- if ( onRightBorder ) return ResizeDirection . Right ;
338+ if ( onTopBorder ) return AllowedDirection ( window , ResizeDirection . Top ) ;
339+ if ( onBottomBorder ) return AllowedDirection ( window , ResizeDirection . Bottom ) ;
340+ if ( onLeftBorder ) return AllowedDirection ( window , ResizeDirection . Left ) ;
341+ if ( onRightBorder ) return AllowedDirection ( window , ResizeDirection . Right ) ;
342342
343343 return ResizeDirection . None ;
344344 }
345345
346+ /// <summary>
347+ /// Returns <paramref name="direction"/> if it is permitted by the window's
348+ /// <see cref="Window.AllowedResizeDirections"/> (a border is active when at least one of
349+ /// its two movement directions is enabled); otherwise <see cref="ResizeDirection.None"/>.
350+ /// </summary>
351+ private static ResizeDirection AllowedDirection ( Window window , ResizeDirection direction )
352+ {
353+ var d = window . AllowedResizeDirections ;
354+ bool topActive = d . HasFlag ( ResizeBorderDirections . TopExpand ) || d . HasFlag ( ResizeBorderDirections . TopContract ) ;
355+ bool bottomActive = d . HasFlag ( ResizeBorderDirections . BottomExpand ) || d . HasFlag ( ResizeBorderDirections . BottomContract ) ;
356+ bool leftActive = d . HasFlag ( ResizeBorderDirections . LeftExpand ) || d . HasFlag ( ResizeBorderDirections . LeftContract ) ;
357+ bool rightActive = d . HasFlag ( ResizeBorderDirections . RightExpand ) || d . HasFlag ( ResizeBorderDirections . RightContract ) ;
358+
359+ bool allowed = direction switch
360+ {
361+ ResizeDirection . Top => topActive ,
362+ ResizeDirection . Bottom => bottomActive ,
363+ ResizeDirection . Left => leftActive ,
364+ ResizeDirection . Right => rightActive ,
365+ ResizeDirection . TopLeft => topActive && leftActive ,
366+ ResizeDirection . TopRight => topActive && rightActive ,
367+ ResizeDirection . BottomLeft => bottomActive && leftActive ,
368+ ResizeDirection . BottomRight => bottomActive && rightActive ,
369+ _ => true
370+ } ;
371+ return allowed ? direction : ResizeDirection . None ;
372+ }
373+
374+ /// <summary>
375+ /// Clamps a resize delta to zero when the movement direction is not permitted.
376+ /// </summary>
377+ private static int ClampResizeDelta ( int delta , bool allowNegative , bool allowPositive )
378+ {
379+ if ( delta < 0 && ! allowNegative ) return 0 ;
380+ if ( delta > 0 && ! allowPositive ) return 0 ;
381+ return delta ;
382+ }
383+
346384 /// <summary>
347385 /// Checks if a point is in the draggable title bar area.
348386 /// </summary>
@@ -509,40 +547,57 @@ private void HandleWindowResize(Point currentMousePos)
509547 int newWidth = currentResize . StartWindowSize . Width ;
510548 int newHeight = currentResize . StartWindowSize . Height ;
511549
512- // Apply resize based on direction
550+ // Apply resize based on direction, clamping each axis to allowed movement directions
551+ var dirs = window . AllowedResizeDirections ;
513552 switch ( currentResize . Direction )
514553 {
515554 case ResizeDirection . Left :
555+ // deltaX < 0 = left border expands left; deltaX > 0 = contracts right
556+ deltaX = ClampResizeDelta ( deltaX , dirs . HasFlag ( ResizeBorderDirections . LeftExpand ) , dirs . HasFlag ( ResizeBorderDirections . LeftContract ) ) ;
516557 newLeft += deltaX ;
517558 newWidth -= deltaX ;
518559 break ;
519560 case ResizeDirection . Right :
561+ // deltaX > 0 = right border expands right; deltaX < 0 = contracts left
562+ deltaX = ClampResizeDelta ( deltaX , dirs . HasFlag ( ResizeBorderDirections . RightContract ) , dirs . HasFlag ( ResizeBorderDirections . RightExpand ) ) ;
520563 newWidth += deltaX ;
521564 break ;
522565 case ResizeDirection . Top :
566+ // deltaY < 0 = top border expands up; deltaY > 0 = contracts down
567+ deltaY = ClampResizeDelta ( deltaY , dirs . HasFlag ( ResizeBorderDirections . TopExpand ) , dirs . HasFlag ( ResizeBorderDirections . TopContract ) ) ;
523568 newTop += deltaY ;
524569 newHeight -= deltaY ;
525570 break ;
526571 case ResizeDirection . Bottom :
572+ // deltaY > 0 = bottom border expands down; deltaY < 0 = contracts up
573+ deltaY = ClampResizeDelta ( deltaY , dirs . HasFlag ( ResizeBorderDirections . BottomContract ) , dirs . HasFlag ( ResizeBorderDirections . BottomExpand ) ) ;
527574 newHeight += deltaY ;
528575 break ;
529576 case ResizeDirection . TopLeft :
577+ deltaX = ClampResizeDelta ( deltaX , dirs . HasFlag ( ResizeBorderDirections . LeftExpand ) , dirs . HasFlag ( ResizeBorderDirections . LeftContract ) ) ;
578+ deltaY = ClampResizeDelta ( deltaY , dirs . HasFlag ( ResizeBorderDirections . TopExpand ) , dirs . HasFlag ( ResizeBorderDirections . TopContract ) ) ;
530579 newLeft += deltaX ;
531580 newWidth -= deltaX ;
532581 newTop += deltaY ;
533582 newHeight -= deltaY ;
534583 break ;
535584 case ResizeDirection . TopRight :
585+ deltaX = ClampResizeDelta ( deltaX , dirs . HasFlag ( ResizeBorderDirections . RightContract ) , dirs . HasFlag ( ResizeBorderDirections . RightExpand ) ) ;
586+ deltaY = ClampResizeDelta ( deltaY , dirs . HasFlag ( ResizeBorderDirections . TopExpand ) , dirs . HasFlag ( ResizeBorderDirections . TopContract ) ) ;
536587 newWidth += deltaX ;
537588 newTop += deltaY ;
538589 newHeight -= deltaY ;
539590 break ;
540591 case ResizeDirection . BottomLeft :
592+ deltaX = ClampResizeDelta ( deltaX , dirs . HasFlag ( ResizeBorderDirections . LeftExpand ) , dirs . HasFlag ( ResizeBorderDirections . LeftContract ) ) ;
593+ deltaY = ClampResizeDelta ( deltaY , dirs . HasFlag ( ResizeBorderDirections . BottomContract ) , dirs . HasFlag ( ResizeBorderDirections . BottomExpand ) ) ;
541594 newLeft += deltaX ;
542595 newWidth -= deltaX ;
543596 newHeight += deltaY ;
544597 break ;
545598 case ResizeDirection . BottomRight :
599+ deltaX = ClampResizeDelta ( deltaX , dirs . HasFlag ( ResizeBorderDirections . RightContract ) , dirs . HasFlag ( ResizeBorderDirections . RightExpand ) ) ;
600+ deltaY = ClampResizeDelta ( deltaY , dirs . HasFlag ( ResizeBorderDirections . BottomContract ) , dirs . HasFlag ( ResizeBorderDirections . BottomExpand ) ) ;
546601 newWidth += deltaX ;
547602 newHeight += deltaY ;
548603 break ;
@@ -626,25 +681,32 @@ private bool HandleMoveInput(ConsoleKeyInfo key)
626681 /// </summary>
627682 private bool HandleResizeInput ( ConsoleKeyInfo key )
628683 {
629- var activeWindow = _context . ActiveWindow ;
630- if ( activeWindow == null ) return false ;
684+ var w = _context . ActiveWindow ;
685+ if ( w == null ) return false ;
686+
687+ var dirs = w . AllowedResizeDirections ;
631688
689+ // Each arrow key moves the natural border outward (expand only)
632690 switch ( key . Key )
633691 {
634692 case ConsoleKey . UpArrow :
635- _context . Positioning . ResizeWindowBy ( activeWindow , 0 , - 1 ) ;
693+ if ( ! dirs . HasFlag ( ResizeBorderDirections . TopExpand ) ) return false ;
694+ _context . Positioning . ResizeWindowTo ( w , w . Left , w . Top - 1 , w . Width , w . Height + 1 ) ;
636695 return true ;
637696
638697 case ConsoleKey . DownArrow :
639- _context . Positioning . ResizeWindowBy ( activeWindow , 0 , 1 ) ;
698+ if ( ! dirs . HasFlag ( ResizeBorderDirections . BottomExpand ) ) return false ;
699+ _context . Positioning . ResizeWindowTo ( w , w . Left , w . Top , w . Width , w . Height + 1 ) ;
640700 return true ;
641701
642702 case ConsoleKey . LeftArrow :
643- _context . Positioning . ResizeWindowBy ( activeWindow , - 1 , 0 ) ;
703+ if ( ! dirs . HasFlag ( ResizeBorderDirections . LeftExpand ) ) return false ;
704+ _context . Positioning . ResizeWindowTo ( w , w . Left - 1 , w . Top , w . Width + 1 , w . Height ) ;
644705 return true ;
645706
646707 case ConsoleKey . RightArrow :
647- _context . Positioning . ResizeWindowBy ( activeWindow , 1 , 0 ) ;
708+ if ( ! dirs . HasFlag ( ResizeBorderDirections . RightExpand ) ) return false ;
709+ _context . Positioning . ResizeWindowTo ( w , w . Left , w . Top , w . Width + 1 , w . Height ) ;
648710 return true ;
649711
650712 default :
0 commit comments