CP-20881 - Implement RDP console resize when toggling the full screen mode

In addition to ticket requirements, the console size is updated when the console is:
- resized in undocked mode
- resized manually by dragging window edges
- resized by dragging the panel splitter

Signed-off-by: Letsibogo Ramadi <letsibogo.ramadi@citrix.com>
This commit is contained in:
Letsibogo Ramadi 2017-02-27 18:00:46 +00:00
parent 8d2cbfc87c
commit 27918a1c02
9 changed files with 168 additions and 67 deletions

View File

@ -88,26 +88,26 @@ namespace XenAdmin.ConsoleView
rdpControl.Resize += resizeHandler;
}
private void RDPConfigure(Size oldSize)
private void RDPConfigure(Size currentConsoleSize)
{
rdpControl.BeginInit();
rdpLocationOffset = new Point(2, 2); //small offset to accomodate focus rectangle
rdpControl.Dock = DockStyle.None;
rdpControl.Anchor = AnchorStyles.None;
rdpControl.Size = oldSize;
rdpControl.Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right);
rdpControl.Size = currentConsoleSize;
RDPAddOnDisconnected();
rdpControl.Enter += RdpEnter;
rdpControl.Leave += rdpClient_Leave;
rdpControl.GotFocus += rdpClient_GotFocus;
rdpControl.Location = new Point(
parent.ClientSize.Width > oldSize.Width ? (parent.ClientSize.Width - oldSize.Width) / 2 : 0,
parent.ClientSize.Height > oldSize.Height ? (parent.ClientSize.Height - oldSize.Height) / 2 : 0
);
rdpControl.EndInit();
}
public Point rdpLocationOffset
{
set { rdpControl.Location = value; }
}
private void RDPAddOnDisconnected()
{
if (rdpControl == null)
@ -173,6 +173,20 @@ namespace XenAdmin.ConsoleView
}
}
public void Reconnect( int width, int height)
{
if (rdpControl == null)
return;
Log.DebugFormat("Reconnecting RDPClient8 using width '{0}' and height '{1}'", width, height);
if (Connected && rdpClient8 != null)
{
rdpClient8.Size = new Size(width, height);
rdpClient8.Reconnect((uint)width, (uint)height);
}
}
private bool Connected
{
get { return rdpControl == null ? false : (rdpClient8 == null ? rdpClient6.Connected == 1 : rdpClient8.Connected == 1); }

View File

@ -46,7 +46,7 @@ namespace XenAdmin.ConsoleView
{
public class VNCGraphicsClient : UserControl, IVNCGraphicsClient, IRemoteConsole
{
public const int BORDER_PADDING = 4;
public const int BORDER_PADDING = 5;
public const int BORDER_WIDTH = 1;
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

View File

@ -394,12 +394,12 @@ namespace XenAdmin.ConsoleView
if (Properties.Settings.Default.UncaptureShortcutKey == 0)
{
// Right Ctrl
KeyHandler.AddKeyHandler(ConsoleShortcutKey.RIGHT_CTRL, ToogleConsoleFocus);
KeyHandler.AddKeyHandler(ConsoleShortcutKey.RIGHT_CTRL, ToggleConsoleFocus);
}
else if (Properties.Settings.Default.UncaptureShortcutKey == 1)
{
// Left Alt
KeyHandler.AddKeyHandler(ConsoleShortcutKey.LEFT_ALT, ToogleConsoleFocus);
KeyHandler.AddKeyHandler(ConsoleShortcutKey.LEFT_ALT, ToggleConsoleFocus);
}
}
@ -1034,6 +1034,7 @@ namespace XenAdmin.ConsoleView
FocusVNC();
vncScreen.CaptureKeyboardAndMouse();
UpdateRDPResolution(true);
}
else
{
@ -1049,6 +1050,7 @@ namespace XenAdmin.ConsoleView
fullscreenForm.Hide();
fullscreenForm.Dispose();
fullscreenForm = null;
UpdateRDPResolution();
}
//Everytime we toggle full screen I'm going to force an unpause to make sure we don't acidentally undock / dock a pause VNC
@ -1457,15 +1459,15 @@ namespace XenAdmin.ConsoleView
return null;
}
private bool inToogleConsoleFocus = false;
private void ToogleConsoleFocus()
private bool inToggleConsoleFocus = false;
private void ToggleConsoleFocus()
{
Program.AssertOnEventThread();
if (inToogleConsoleFocus)
if (inToggleConsoleFocus)
return;
inToogleConsoleFocus = true;
inToggleConsoleFocus = true;
if (vncScreen.Focused && vncScreen.ActiveControl == null)
vncScreen.CaptureKeyboardAndMouse(); // focus console
@ -1475,7 +1477,7 @@ namespace XenAdmin.ConsoleView
vncScreen.Refresh();
}
inToogleConsoleFocus = false;
inToggleConsoleFocus = false;
}
private void ShowGpuWarningIfRequired(bool mustConnectRemoteDesktop)
@ -1487,6 +1489,12 @@ namespace XenAdmin.ConsoleView
{
get { return vncScreen.UseVNC; }
}
public void UpdateRDPResolution(bool fullscreen = false)
{
if (vncScreen != null)
vncScreen.UpdateRDPResolution(fullscreen);
}
#region SSH Console methods

View File

@ -348,6 +348,45 @@
<metadata name="tip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<data name="toggleConsoleButton.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Right</value>
</data>
<data name="toggleConsoleButton.Enabled" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="toggleConsoleButton.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="toggleConsoleButton.Location" type="System.Drawing.Point, System.Drawing">
<value>522, 6</value>
</data>
<data name="toggleConsoleButton.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 6, 6, 6</value>
</data>
<data name="toggleConsoleButton.Size" type="System.Drawing.Size, System.Drawing">
<value>175, 24</value>
</data>
<data name="toggleConsoleButton.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
</data>
<data name="toggleConsoleButton.Text" xml:space="preserve">
<value>Looking for guest console...</value>
</data>
<data name="toggleConsoleButton.ToolTip" xml:space="preserve">
<value>Remote access is not enabled on this guest</value>
</data>
<data name="&gt;&gt;toggleConsoleButton.Name" xml:space="preserve">
<value>toggleConsoleButton</value>
</data>
<data name="&gt;&gt;toggleConsoleButton.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toggleConsoleButton.Parent" xml:space="preserve">
<value>tableLayoutPanel2</value>
</data>
<data name="&gt;&gt;toggleConsoleButton.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<metadata name="LifeCycleMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>81, 17</value>
</metadata>
@ -510,45 +549,6 @@
<data name="&gt;&gt;buttonSSH.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="toggleConsoleButton.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Right</value>
</data>
<data name="toggleConsoleButton.Enabled" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="toggleConsoleButton.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
<value>NoControl</value>
</data>
<data name="toggleConsoleButton.Location" type="System.Drawing.Point, System.Drawing">
<value>522, 6</value>
</data>
<data name="toggleConsoleButton.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>3, 6, 6, 6</value>
</data>
<data name="toggleConsoleButton.Size" type="System.Drawing.Size, System.Drawing">
<value>175, 24</value>
</data>
<data name="toggleConsoleButton.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
</data>
<data name="toggleConsoleButton.Text" xml:space="preserve">
<value>Looking for guest console...</value>
</data>
<data name="toggleConsoleButton.ToolTip" xml:space="preserve">
<value>Remote access is not enabled on this guest</value>
</data>
<data name="&gt;&gt;toggleConsoleButton.Name" xml:space="preserve">
<value>toggleConsoleButton</value>
</data>
<data name="&gt;&gt;toggleConsoleButton.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toggleConsoleButton.Parent" xml:space="preserve">
<value>tableLayoutPanel2</value>
</data>
<data name="&gt;&gt;toggleConsoleButton.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="multipleDvdIsoList1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
@ -649,7 +649,7 @@
<value>0</value>
</data>
<data name="tableLayoutPanel2.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="HostLabel" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="buttonSSH" Row="0" RowSpan="1" Column="3" ColumnSpan="1" /&gt;&lt;Control Name="toggleConsoleButton" Row="0" RowSpan="1" Column="5" ColumnSpan="1" /&gt;&lt;Control Name="multipleDvdIsoList1" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /&gt;&lt;Control Name="pictureBox1" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="AutoSize,0,AutoSize,0,Percent,100,AutoSize,0,AutoSize,0" /&gt;&lt;Rows Styles="Percent,100,Absolute,100" /&gt;&lt;/TableLayoutSettings&gt;</value>
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="HostLabel" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="buttonSSH" Row="0" RowSpan="1" Column="3" ColumnSpan="1" /&gt;&lt;Control Name="toggleConsoleButton" Row="0" RowSpan="1" Column="5" ColumnSpan="1" /&gt;&lt;Control Name="multipleDvdIsoList1" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /&gt;&lt;Control Name="pictureBox1" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="AutoSize,0,AutoSize,0,Percent,100,AutoSize,0,AutoSize,0" /&gt;&lt;Rows Styles="Percent,100,Absolute,37" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="gradientPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Top</value>

View File

@ -45,6 +45,12 @@ namespace XenAdmin.ConsoleView
private readonly VNCTabView vncTabView;
public Form undockedForm = null;
/// <summary>
/// Helper boolean to only trigger Resize_End when window is really resized by dragging edges
/// Without this Resize_End is triggered even when window is moved around and not resized
/// </summary>
private bool undockedFormResized = false;
public bool isDocked
{
get
@ -102,9 +108,17 @@ namespace XenAdmin.ConsoleView
this.DockUnDock();
});
undockedForm.StartPosition = FormStartPosition.CenterScreen;
FormWindowState lastState = undockedForm.WindowState;
undockedForm.Resize += new EventHandler(
delegate(Object o, EventArgs a)
{
undockedFormResized = true;
if (undockedForm.WindowState != lastState && undockedForm.WindowState != FormWindowState.Minimized)
{
lastState = undockedForm.WindowState;
UpdateRDPResolution();
}
if (undockedForm.WindowState == FormWindowState.Minimized)
{
vncTabView.Pause();
@ -114,6 +128,15 @@ namespace XenAdmin.ConsoleView
vncTabView.Unpause();
}
});
undockedForm.ResizeEnd += new EventHandler(
delegate(Object o, EventArgs a)
{
if (undockedFormResized)
UpdateRDPResolution();
undockedFormResized = false;
});
}
this.Controls.Remove(vncTabView);
@ -174,6 +197,9 @@ namespace XenAdmin.ConsoleView
//Every time we dock / undock I'm going to force an unpause to make sure we don't ever pause a visible one.
vncTabView.Unpause();
vncTabView.focus_vnc();
//reconnect RDP with docked/undocked window dimensions
UpdateRDPResolution();
}
private string UndockedWindowTitle(VM source)
@ -256,5 +282,10 @@ namespace XenAdmin.ConsoleView
{
get { return vncTabView.IsVNC; }
}
public void UpdateRDPResolution(bool fullscreen = false)
{
vncTabView.UpdateRDPResolution(fullscreen);
}
}
}

View File

@ -63,6 +63,7 @@ namespace XenAdmin.ConsoleView
private const int RDP_POLL_INTERVAL = 30000;
public const int RDP_PORT = 3389;
private const int VNC_PORT = 5900;
private const int CONSOLE_SIZE_OFFSET = 6;
private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@ -520,13 +521,12 @@ namespace XenAdmin.ConsoleView
bool wasFocused = false;
this.Controls.Clear();
Size oldSize = new Size(1024, 768);
//console size with some offset to accomodate focus rectangle
Size currentConsoleSize = new Size(this.Size.Width - CONSOLE_SIZE_OFFSET, this.Size.Height - CONSOLE_SIZE_OFFSET); ;
// Kill the old client.
if (RemoteConsole != null)
{
oldSize = RemoteConsole.DesktopSize;
wasFocused = RemoteConsole.ConsoleControl != null && RemoteConsole.ConsoleControl.Focused;
RemoteConsole.DisconnectAndDispose();
RemoteConsole = null;
@ -555,11 +555,8 @@ namespace XenAdmin.ConsoleView
if (rdpClient == null)
{
if (this.ParentForm is FullScreenForm)
oldSize = ((FullScreenForm)ParentForm).GetContentSize();
this.AutoScroll = true;
this.AutoScrollMinSize = oldSize;
rdpClient = new RdpClient(this, oldSize, ResizeHandler);
currentConsoleSize = ((FullScreenForm)ParentForm).GetContentSize();
rdpClient = new RdpClient(this, currentConsoleSize, ResizeHandler);
rdpClient.OnDisconnected += new EventHandler(parentVNCTabView.RdpDisconnectedHandler);
}
@ -1386,5 +1383,23 @@ namespace XenAdmin.ConsoleView
return false;
}
public void UpdateRDPResolution(bool fullscreen = false)
{
if (rdpClient == null)
return;
//remove offsets because there is no focus border to accomodate in fullscreen
if (fullscreen)
{
rdpClient.rdpLocationOffset = new Point(0, 0);
rdpClient.Reconnect(this.Size.Width, this.Size.Height);
}
else
{
rdpClient.rdpLocationOffset = new Point(2, 2);
rdpClient.Reconnect(this.Size.Width - CONSOLE_SIZE_OFFSET, this.Size.Height - CONSOLE_SIZE_OFFSET);
}
}
}
}

View File

@ -98,6 +98,12 @@ namespace XenAdmin.Controls
activeVNCView.FocusConsole();
}
public void UpdateRDPResolution(bool fullscreen = false)
{
if (activeVNCView != null)
activeVNCView.UpdateRDPResolution(fullscreen);
}
internal void setCurrentSource(VM source)
{
Program.AssertOnEventThread();

View File

@ -324,6 +324,7 @@ namespace XenAdmin
this.splitContainer1.Panel2.Controls.Add(this.eventsPage);
this.splitContainer1.Panel2.Controls.Add(this.TitleBackPanel);
resources.ApplyResources(this.splitContainer1.Panel2, "splitContainer1.Panel2");
this.splitContainer1.SplitterMoved += new System.Windows.Forms.SplitterEventHandler(this.splitContainer1_SplitterMoved);
//
// navigationPane
//
@ -1900,6 +1901,7 @@ namespace XenAdmin
this.Name = "MainWindow";
this.Load += new System.EventHandler(this.MainWindow_Load);
this.Shown += new System.EventHandler(this.MainWindow_Shown);
this.ResizeEnd += new System.EventHandler(this.MainWindow_ResizeEnd);
this.HelpRequested += new System.Windows.Forms.HelpEventHandler(this.MainWindow_HelpRequested);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainWindow_KeyDown);
this.Resize += new System.EventHandler(this.MainWindow_Resize);

View File

@ -110,6 +110,12 @@ namespace XenAdmin
private bool IgnoreTabChanges = false;
private bool ToolbarsEnabled;
/// <summary>
/// Helper boolean to only trigger Resize_End when window is really resized by dragging edges
/// Without this Resize_End is triggered even when window is moved around and not resized
/// </summary>
private bool mainWindowResized = false;
private readonly Dictionary<IXenConnection, IList<Form>> activePoolWizards = new Dictionary<IXenConnection, IList<Form>>();
private readonly Dictionary<IXenObject, Form> activeXenModelObjectWizards = new Dictionary<IXenObject, Form>();
@ -3280,9 +3286,16 @@ namespace XenAdmin
SetSplitterDistance();
}
FormWindowState lastState = FormWindowState.Normal;
private void MainWindow_Resize(object sender, EventArgs e)
{
SetSplitterDistance();
if(WindowState != lastState && WindowState != FormWindowState.Minimized)
{
lastState = WindowState;
ConsolePanel.UpdateRDPResolution();
}
mainWindowResized = true;
}
private void SetSplitterDistance()
@ -3302,5 +3315,17 @@ namespace XenAdmin
else if (splitContainer1.SplitterDistance > max)
splitContainer1.SplitterDistance = max;
}
private void MainWindow_ResizeEnd(object sender, EventArgs e)
{
if (mainWindowResized)
ConsolePanel.UpdateRDPResolution();
mainWindowResized = false;
}
private void splitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
{
ConsolePanel.UpdateRDPResolution();
}
}
}