From 619985f2303708da5c684bff919373c827f66532 Mon Sep 17 00:00:00 2001 From: Noisrev Date: Wed, 21 Dec 2022 19:57:24 +0800 Subject: [PATCH 1/3] Improved floating window activation state - Update the IsActive property of the content when the floating window is active or inactive --- .../LayoutAnchorableFloatingWindowControl.cs | 15 +++++++++------ .../LayoutDocumentFloatingWindowControl.cs | 18 +++++++++--------- .../Controls/LayoutFloatingWindowControl.cs | 8 -------- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs index 54b6d454..cd9025c9 100644 --- a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs @@ -243,14 +243,17 @@ protected override IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, Int { switch (msg) { - case Win32Helper.WM_NCLBUTTONDOWN: //Left button down on title -> start dragging over docking manager - if (wParam.ToInt32() == Win32Helper.HT_CAPTION) + case Win32Helper.WM_ACTIVATE: + var anchorablePane = _model.Descendents().OfType() + .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); + + if (anchorablePane != null) { - var anchorablePane = _model.Descendents().OfType() - .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); - if (anchorablePane != null) anchorablePane.SelectedContent.IsActive = true; - handled = true; + var isActive = !(((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE); + anchorablePane.SelectedContent.IsActive = isActive; } + + handled = true; break; case Win32Helper.WM_NCRBUTTONUP: diff --git a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs index 5c25b593..34435a9f 100644 --- a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs @@ -118,17 +118,17 @@ protected override IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, Int { switch (msg) { - case Win32Helper.WM_NCLBUTTONDOWN: //Left button down on title -> start dragging over docking manager - if (wParam.ToInt32() == Win32Helper.HT_CAPTION) + case Win32Helper.WM_ACTIVATE: + var layoutDocumentPane = _model.Descendents().OfType() + .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); + + if (layoutDocumentPane != null) { - LayoutDocumentPane layoutDocumentPane = _model.Descendents().OfType().FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); - if (layoutDocumentPane != null) - { - layoutDocumentPane.SelectedContent.IsActive = true; - } - - handled = true; + var isActive = !(((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE); + layoutDocumentPane.SelectedContent.IsActive = isActive; } + + handled = true; break; case Win32Helper.WM_NCRBUTTONUP: diff --git a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs index ab398e1b..fa31758f 100644 --- a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs @@ -348,14 +348,6 @@ protected virtual IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntP switch (msg) { case Win32Helper.WM_ACTIVATE: - if (((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE) - { - if (lParam == this.GetParentWindowHandle()) - { - Win32Helper.SetActiveWindow(_hwndSrc.Handle); - handled = true; - } - } UpdateWindowsSizeBasedOnMinSize(); break; From 783ce8e9f0d3e1bf1dfb790a9a584ae488bba4c1 Mon Sep 17 00:00:00 2001 From: Noisrev Date: Thu, 22 Dec 2022 12:02:57 +0800 Subject: [PATCH 2/3] Move the "handled" variable inside the code block --- .../Controls/LayoutAnchorableFloatingWindowControl.cs | 3 ++- .../AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs | 3 ++- .../AvalonDock/Controls/LayoutFloatingWindowControl.cs | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs index cd9025c9..75f417da 100644 --- a/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs @@ -251,9 +251,10 @@ protected override IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, Int { var isActive = !(((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE); anchorablePane.SelectedContent.IsActive = isActive; + + handled = true; } - handled = true; break; case Win32Helper.WM_NCRBUTTONUP: diff --git a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs index 34435a9f..13845d3c 100644 --- a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs @@ -126,9 +126,10 @@ protected override IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, Int { var isActive = !(((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE); layoutDocumentPane.SelectedContent.IsActive = isActive; + + handled = true; } - handled = true; break; case Win32Helper.WM_NCRBUTTONUP: diff --git a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs index fa31758f..c1377a92 100644 --- a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs @@ -349,7 +349,6 @@ protected virtual IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntP { case Win32Helper.WM_ACTIVATE: UpdateWindowsSizeBasedOnMinSize(); - break; case Win32Helper.WM_EXITSIZEMOVE: From db7d8693b4abfaf0a00f80c6b2436ab0b161e61b Mon Sep 17 00:00:00 2001 From: Noisrev Date: Thu, 22 Dec 2022 20:32:02 +0800 Subject: [PATCH 3/3] Activate the pane when a floating window is active/inactive - Add handling for single/multiple pane activations --- .../LayoutDocumentFloatingWindowControl.cs | 110 ++++++++++++++++-- 1 file changed, 102 insertions(+), 8 deletions(-) diff --git a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs index 13845d3c..17ea136c 100644 --- a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs +++ b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs @@ -113,23 +113,117 @@ private void Model_PropertyChanged(object sender, System.ComponentModel.Property if (e.PropertyName == nameof(LayoutDocumentFloatingWindow.RootPanel) && _model.RootPanel == null) InternalClose(); } + private void ActiveOfSinglePane(bool isActive) + { + var layoutDocumentPane = _model.Descendents().OfType() + .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); + + layoutDocumentPane.SelectedContent.IsActive = isActive; + } + + private static LayoutDocumentPaneControl FindDocumentPaneControlByPoint(IEnumerable areaHosts, Point point) + { + foreach (var areaHost in areaHosts) + { + var area = areaHost.GetScreenArea(); + var pos = areaHost.TransformFromDeviceDPI(point); + var b = area.Contains(pos); + + if (b) + { + return areaHost; + } + } + + return null; + } + + private void ActiveOfMultiPane(bool isActive) + { + var mousePosition = Win32Helper.GetMousePosition(); + var rootVisual = ((FloatingWindowContentHost)Content).RootVisual; + var areaHosts = rootVisual.FindVisualChildren(); + + if (isActive) + { + var documentPane = FindDocumentPaneControlByPoint(areaHosts, mousePosition); + if (documentPane != null) + { + var model = (LayoutDocumentPane)documentPane.Model; + if (model.SelectedContent != null) + { + model.SelectedContent.IsActive = true; + return; + } + // AnchorablePane + else + { + var index = 0; + for (var i = 0; i < model.Children.Count; i++) + { + var item = model.Children[i]; + if (item.IsLastFocusedDocument) + { + index = i; + } + } + + model.SelectedContentIndex = index; + return; + } + } + else + { + // Active the Last Focus + foreach (var areaHost in areaHosts) + { + var model = (LayoutDocumentPane)areaHost.Model; + for (var i = 0; i < model.Children.Count; i++) + { + var item = model.Children[i]; + if (item.IsLastFocusedDocument) + { + item.IsActive = true; + return; + } + } + } + } + } + else + { + foreach (var areaHost in areaHosts) + { + var model = (LayoutDocumentPane)areaHost.Model; + for (var i = 0; i < model.Children.Count; i++) + { + var item = model.Children[i]; + if (item.IsActive) + { + item.IsActive = false; + } + } + } + } + } + /// protected override IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { switch (msg) { case Win32Helper.WM_ACTIVATE: - var layoutDocumentPane = _model.Descendents().OfType() - .FirstOrDefault(p => p.ChildrenCount > 0 && p.SelectedContent != null); - - if (layoutDocumentPane != null) + var isInactive = ((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE; + if (_model.IsSinglePane) { - var isActive = !(((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE); - layoutDocumentPane.SelectedContent.IsActive = isActive; - - handled = true; + ActiveOfSinglePane(!isInactive); + } + else + { + ActiveOfMultiPane(!isInactive); } + handled = true; break; case Win32Helper.WM_NCRBUTTONUP: