From 4eeebdf11394f55f899f18550b66e554c4478a01 Mon Sep 17 00:00:00 2001 From: SQReder Date: Mon, 21 Sep 2026 18:11:31 +0300 Subject: [PATCH] Position window actions over the actual window The actions bar and its reveal highlight were laid out from the node's computed rectangle, while the reveal logic hit-tests against the real window position. For a window smaller than its cell (e.g. one that has reached its maximum size) the bar was centered over the cell, outside the horizontal range that keeps it visible, so it disappeared before the cursor could reach it. Track the visible window bounds in the view model and bind the bar and the highlight to them instead. --- .../Controls/NonHitTestableTilingOverlay.xaml | 6 +++--- FancyWM/Controls/TilingOverlay.xaml | 8 ++++---- FancyWM/ViewModels/TilingWindowViewModel.cs | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/FancyWM/Controls/NonHitTestableTilingOverlay.xaml b/FancyWM/Controls/NonHitTestableTilingOverlay.xaml index c0339b2..a254156 100644 --- a/FancyWM/Controls/NonHitTestableTilingOverlay.xaml +++ b/FancyWM/Controls/NonHitTestableTilingOverlay.xaml @@ -144,7 +144,7 @@ diff --git a/FancyWM/Controls/TilingOverlay.xaml b/FancyWM/Controls/TilingOverlay.xaml index 1a496a3..12d382d 100644 --- a/FancyWM/Controls/TilingOverlay.xaml +++ b/FancyWM/Controls/TilingOverlay.xaml @@ -62,10 +62,10 @@ diff --git a/FancyWM/ViewModels/TilingWindowViewModel.cs b/FancyWM/ViewModels/TilingWindowViewModel.cs index c9732dc..16ee551 100644 --- a/FancyWM/ViewModels/TilingWindowViewModel.cs +++ b/FancyWM/ViewModels/TilingWindowViewModel.cs @@ -31,6 +31,11 @@ private enum RevealState public Visibility ActionsVisibility { get => m_actionsVisibility; set => SetField(ref m_actionsVisibility, value); } + /// + /// Bounds of the visible window in overlay coordinates. Updated on cursor movement. + /// + public Rectangle ActionsBounds { get => m_actionsBounds; set => SetField(ref m_actionsBounds, value); } + public double ActionsHeight { get => m_actionsHeight; set => SetField(ref m_actionsHeight, value); } public double RevealHighlightRadius { get => m_revealHighlightRadius; set => SetField(ref m_revealHighlightRadius, value); } @@ -43,6 +48,7 @@ private enum RevealState private IWorkspace? m_workspace; private string? m_title; private Visibility m_actionsVisibility = Visibility.Hidden; + private Rectangle m_actionsBounds; private double m_actionsHeight = 22; private RevealState m_actionsRevealState = RevealState.Hidden; private double m_revealHighlightOpacity = 0; @@ -185,6 +191,17 @@ private void OnCursorLocationChanged(object? sender, CursorLocationChangedEventA var windowPos = node.WindowReference.Position; + // The window may be smaller than its cell (e.g. max size reached), + // so the actions must follow the visible window, not the cell. + var frame = node.WindowReference.FrameMargins; + var displayOffsetX = ComputedBounds.Left - node.ComputedRectangle.Left; + var displayOffsetY = ComputedBounds.Top - node.ComputedRectangle.Top; + ActionsBounds = new Rectangle( + left: windowPos.Left + frame.Left + displayOffsetX, + top: windowPos.Top + frame.Top + displayOffsetY, + right: windowPos.Right - frame.Right + displayOffsetX, + bottom: windowPos.Bottom - frame.Bottom + displayOffsetY); + var x = e.NewLocation.X - windowPos.Left; var y = e.NewLocation.Y - windowPos.Top;