Skip to content

Commit

Permalink
Feature: RDP session resize event in dragged out tab / split view (#2976
Browse files Browse the repository at this point in the history
)

* Feature: RDP session resize event in dragged out tab / split view

* Docs: #2976
  • Loading branch information
BornToBeRoot authored Jan 1, 2025
1 parent 0cc4bb6 commit 5e28465
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 35 deletions.
89 changes: 74 additions & 15 deletions Source/NETworkManager/Controls/DragablzTabHostWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Interop;
using Dragablz;
using MahApps.Metro.Controls.Dialogs;
using NETworkManager.Localization;
Expand Down Expand Up @@ -60,21 +62,16 @@ private async void FocusEmbeddedWindow()
if (!_embeddedWindowApplicationNames.Contains(ApplicationName))
return;

var window = Application.Current.Windows.OfType<Window>().FirstOrDefault(x => x.IsActive);

if (window == null)
return;

// Find all TabablzControl in the active window
foreach (var tabablzControl in VisualTreeHelper.FindVisualChildren<TabablzControl>(window))
foreach (var tabablzControl in VisualTreeHelper.FindVisualChildren<TabablzControl>(this))
{
// Skip if no items
if (tabablzControl.Items.Count == 0)
continue;

// Focus embedded window in the selected tab
(((DragablzTabItem)tabablzControl.SelectedItem)?.View as IEmbeddedWindow)?.FocusEmbeddedWindow();

break;
}
}
Expand Down Expand Up @@ -212,7 +209,7 @@ private void RemoteDesktop_FullscreenAction(object view)
private void RemoteDesktop_AdjustScreenAction(object view)
{
if (view is RemoteDesktopControl control)
control.AdjustScreen(force:true);
control.AdjustScreen(force: true);
}

public ICommand RemoteDesktop_SendCtrlAltDelCommand =>
Expand Down Expand Up @@ -377,14 +374,8 @@ private void MetroWindow_Activated(object sender, EventArgs e)

private void DragablzTabHostWindow_OnClosing(object sender, CancelEventArgs e)
{
// Close all tabs properly when the window is closing
var window = Application.Current.Windows.OfType<Window>().FirstOrDefault(x => x.IsActive);

if (window == null)
return;

// Find all TabablzControl in the active window
foreach (var tabablzControl in VisualTreeHelper.FindVisualChildren<TabablzControl>(window))
foreach (var tabablzControl in VisualTreeHelper.FindVisualChildren<TabablzControl>(this))
foreach (var tabItem in tabablzControl.Items.OfType<DragablzTabItem>())
((IDragablzTabItem)tabItem.View).CloseTab();

Expand Down Expand Up @@ -439,4 +430,72 @@ private void TabablzControl_OnIsDraggingWindowChanged(object sender, RoutedPrope
}

#endregion

#region Handle WndProc messages (handle window size events)

private HwndSource _hwndSource;

private const int WmExitSizeMove = 0x232;
private const int WmSysCommand = 0x0112;
private const int ScMaximize = 0xF030;
private const int ScRestore = 0xF120;

protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);

_hwndSource = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
_hwndSource?.AddHook(HwndHook);
}

[DebuggerStepThrough]
private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
// Window size events
switch (msg)
{
// Handle window resize and move events
case WmExitSizeMove:
UpdateOnWindowResize();
break;

// Handle system commands (like maximize and restore)
case WmSysCommand:

switch (wParam.ToInt32())
{
// Window is maximized
case ScMaximize:
// Window is restored (back to normal size from maximized state)
case ScRestore:
UpdateOnWindowResize();
break;
}

break;
}

handled = false;

return IntPtr.Zero;
}

private void UpdateOnWindowResize()
{
// Find all TabablzControl
foreach (var tabablzControl in VisualTreeHelper.FindVisualChildren<TabablzControl>(this))
{
// Skip if no items
if (tabablzControl.Items.Count == 0)
continue;

foreach (var item in tabablzControl.Items.OfType<DragablzTabItem>())
{
if (item.View is RemoteDesktopControl control)
control.UpdateOnWindowResize();
}
}
}

#endregion
}
1 change: 1 addition & 0 deletions Source/NETworkManager/Controls/IEmbeddedWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ public interface IEmbeddedWindow
/// </summary>
public void FocusEmbeddedWindow()
{

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ private set
OnPropertyChanged();
}
}

#endregion

#region Constructor, load
Expand Down
35 changes: 28 additions & 7 deletions Source/NETworkManager/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
using System.Windows.Interop;
using System.Windows.Markup;
using System.Windows.Threading;
using Dragablz;
using Application = System.Windows.Application;
using ContextMenu = System.Windows.Controls.ContextMenu;
using MouseEventArgs = System.Windows.Forms.MouseEventArgs;
Expand Down Expand Up @@ -1590,19 +1591,23 @@ private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref
// Window size events
switch (msg)
{
// Handle window resize and move events
case WmExitSizeMove:
_remoteDesktopHostView?.UpdateOnWindowResize();
UpdateOnWindowResize();
break;

// Handle system commands (like maximize and restore)
case WmSysCommand:
// Handle system commands (like maximize and restore)
if (wParam.ToInt32() == ScMaximize)

switch (wParam.ToInt32())
{
// Window is maximized
_remoteDesktopHostView?.UpdateOnWindowResize();

if (wParam.ToInt32() == ScRestore)
case ScMaximize:
// Window is restored (back to normal size from maximized state)
_remoteDesktopHostView?.UpdateOnWindowResize();
case ScRestore:
UpdateOnWindowResize();
break;
}

break;
}
Expand All @@ -1611,6 +1616,22 @@ private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref

return IntPtr.Zero;
}

private void UpdateOnWindowResize()
{
foreach (var tabablzControl in VisualTreeHelper.FindVisualChildren<TabablzControl>(this))
{
// Skip if no items
if (tabablzControl.Items.Count == 0)
continue;

foreach (var item in tabablzControl.Items.OfType<DragablzTabItem>())
{
if (item.View is RemoteDesktopControl control)
control.UpdateOnWindowResize();
}
}
}

#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,7 @@ public void FocusEmbeddedWindow()

// Focus embedded window in the selected tab
(((DragablzTabItem)tabablzControl.SelectedItem)?.View as IEmbeddedWindow)?.FocusEmbeddedWindow();

break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ public void FocusEmbeddedWindow()

// Focus embedded window in the selected tab
(((DragablzTabItem)tabablzControl.SelectedItem)?.View as IEmbeddedWindow)?.FocusEmbeddedWindow();

break;
}
}
Expand Down
1 change: 1 addition & 0 deletions Source/NETworkManager/ViewModels/PuTTYHostViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@ public void FocusEmbeddedWindow()

// Focus embedded window in the selected tab
(((DragablzTabItem)tabablzControl.SelectedItem)?.View as IEmbeddedWindow)?.FocusEmbeddedWindow();

break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -574,12 +574,6 @@ public void OnViewHide()
_isViewActive = false;
}

public void UpdateOnWindowResize()
{
foreach (var tab in TabItems)
(tab.View as RemoteDesktopControl)?.UpdateOnWindowResize();
}

private void SetProfilesView(ProfileInfo profile = null)
{
Profiles = new CollectionViewSource
Expand Down
5 changes: 0 additions & 5 deletions Source/NETworkManager/Views/RemoteDesktopHostView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,4 @@ public void OnViewVisible()
{
_viewModel.OnViewVisible();
}

public void UpdateOnWindowResize()
{
_viewModel.UpdateOnWindowResize();
}
}
2 changes: 1 addition & 1 deletion Website/docs/changelog/next-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,6 @@ Release date: **xx.xx.2024**
## Dependencies, Refactoring & Documentation

- Migrated code for some loading indicators from the library [LoadingIndicators.WPF] (https://github.com/zeluisping/LoadingIndicators.WPF) to the NETworkManager repo, as the original repo looks unmaintained and has problems with MahApps.Metro version 2 and later. [#2963](https://github.com/BornToBeRoot/NETworkManager/pull/2963)
- Code cleanup & refactoring [#2940](https://github.com/BornToBeRoot/NETworkManager/pull/2940)
- Code cleanup & refactoring [#2940](https://github.com/BornToBeRoot/NETworkManager/pull/2940) [#2976](https://github.com/BornToBeRoot/NETworkManager/pull/2976)
- Language files updated via [#transifex](https://github.com/BornToBeRoot/NETworkManager/pulls?q=author%3Aapp%2Ftransifex-integration)
- Dependencies updated via [#dependabot](https://github.com/BornToBeRoot/NETworkManager/pulls?q=author%3Aapp%2Fdependabot)

0 comments on commit 5e28465

Please sign in to comment.