Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYurii H <gardenapple@posteo.net>2021-06-11 20:50:49 +0300
committerGitHub <noreply@github.com>2021-06-11 20:50:49 +0300
commit1a50864b48efeabad79232a3320db10bde7b96e3 (patch)
treea540ed377ac308a20ef1d48c1ff11ecf3ad02a84
parent423b807f2d227ee7052f848bb0ca9029a8ff68f9 (diff)
Allow manipulating console window size in Xterm (#20886)
Added implementations for `Console.SetWindowSize(int, int)`, `Console.SetBufferSize(int, int)` and associated properties. This is [based on Xterm control sequences](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Miscellaneous) which are supported by a lot of Linux terminals. The previous API was very hit or miss - e.g. the method `Console.SetWindowSize(int, int)` just does absolutely nothing, while the setter for `Console.WindowWidth` always throws an exception. The new implementation sends a control sequence if `TERM` starts with "xterm", otherwise throws an exception.
-rw-r--r--mcs/class/corlib/System/Console.cs12
-rw-r--r--mcs/class/corlib/System/TermInfoDriver.cs59
2 files changed, 53 insertions, 18 deletions
diff --git a/mcs/class/corlib/System/Console.cs b/mcs/class/corlib/System/Console.cs
index 0830e4ff079..551f5fcd46f 100644
--- a/mcs/class/corlib/System/Console.cs
+++ b/mcs/class/corlib/System/Console.cs
@@ -548,13 +548,13 @@ namespace System
public static int BufferHeight {
get { return ConsoleDriver.BufferHeight; }
- [MonoLimitation ("Implemented only on Windows")]
+ [MonoLimitation ("Works only on Windows, or with some Xterm-based terminals")]
set { ConsoleDriver.BufferHeight = value; }
}
public static int BufferWidth {
get { return ConsoleDriver.BufferWidth; }
- [MonoLimitation ("Implemented only on Windows")]
+ [MonoLimitation ("Works only on Windows, or with some Xterm-based terminals")]
set { ConsoleDriver.BufferWidth = value; }
}
@@ -616,21 +616,25 @@ namespace System
public static int WindowHeight {
get { return ConsoleDriver.WindowHeight; }
+ [MonoLimitation ("Works only on Windows, or with some Xterm-based terminals")]
set { ConsoleDriver.WindowHeight = value; }
}
public static int WindowLeft {
get { return ConsoleDriver.WindowLeft; }
+ [MonoLimitation ("Works only on Windows")]
set { ConsoleDriver.WindowLeft = value; }
}
public static int WindowTop {
get { return ConsoleDriver.WindowTop; }
+ [MonoLimitation ("Works only on Windows")]
set { ConsoleDriver.WindowTop = value; }
}
public static int WindowWidth {
get { return ConsoleDriver.WindowWidth; }
+ [MonoLimitation ("Works only on Windows, or with some Xterm-based terminals")]
set { ConsoleDriver.WindowWidth = value; }
}
@@ -704,7 +708,7 @@ namespace System
ConsoleDriver.ResetColor ();
}
- [MonoLimitation ("Only works on windows")]
+ [MonoLimitation ("Works only on Windows, or with some Xterm-based terminals")]
public static void SetBufferSize (int width, int height)
{
ConsoleDriver.SetBufferSize (width, height);
@@ -715,11 +719,13 @@ namespace System
ConsoleDriver.SetCursorPosition (left, top);
}
+ [MonoLimitation ("Works only on Windows")]
public static void SetWindowPosition (int left, int top)
{
ConsoleDriver.SetWindowPosition (left, top);
}
+ [MonoLimitation ("Works only on Windows, or with some Xterm-based terminals")]
public static void SetWindowSize (int width, int height)
{
ConsoleDriver.SetWindowSize (width, height);
diff --git a/mcs/class/corlib/System/TermInfoDriver.cs b/mcs/class/corlib/System/TermInfoDriver.cs
index c16b7367279..62a33b8e1cc 100644
--- a/mcs/class/corlib/System/TermInfoDriver.cs
+++ b/mcs/class/corlib/System/TermInfoDriver.cs
@@ -42,6 +42,7 @@
using System.Collections;
using System.IO;
using System.Text;
+using System.Threading;
using System.Runtime.InteropServices;
namespace System {
class TermInfoDriver : IConsoleDriver {
@@ -524,7 +525,7 @@ namespace System {
Init ();
}
- throw new NotSupportedException ();
+ SetBufferSize (BufferWidth, value);
}
}
@@ -542,7 +543,7 @@ namespace System {
Init ();
}
- throw new NotSupportedException ();
+ SetBufferSize (value, BufferHeight);
}
}
@@ -716,6 +717,29 @@ namespace System {
bufferWidth = windowWidth;
}
+ // Should be called after init
+ //
+ // Only works on some Xterm-based terminals
+ void TrySetWindowDimensions (int width, int height)
+ {
+ if (width <= 0)
+ throw new ArgumentOutOfRangeException ("width", "Value must be higher than 0");
+ if (height <= 0)
+ throw new ArgumentOutOfRangeException ("height", "Value must be highet than 0");
+
+ if (height == WindowHeight && width == WindowWidth)
+ return;
+
+ if (term.StartsWith ("xterm")) {
+ WriteConsole ("\x1b[8;" + height.ToString () + ";" + width.ToString () + "t");
+
+ // Wait for window to get resized
+ Thread.Sleep (50);
+ } else {
+ throw new PlatformNotSupportedException ("Resizing can only work in xterm-based terminals");
+ }
+ }
+
public int WindowHeight {
get {
@@ -731,7 +755,7 @@ namespace System {
Init ();
}
- throw new NotSupportedException ();
+ SetWindowSize (WindowWidth, value);
}
}
@@ -749,7 +773,10 @@ namespace System {
Init ();
}
- throw new NotSupportedException ();
+ if (value == 0)
+ return;
+
+ throw new ArgumentOutOfRangeException ("Unix terminals only support window position (0; 0)");
}
}
@@ -767,7 +794,10 @@ namespace System {
Init ();
}
- throw new NotSupportedException ();
+ if (value == 0)
+ return;
+
+ throw new ArgumentOutOfRangeException ("Unix terminals only support window position (0; 0)");
}
}
@@ -785,7 +815,7 @@ namespace System {
Init ();
}
- throw new NotSupportedException ();
+ SetWindowSize (value, WindowHeight);
}
}
@@ -817,7 +847,7 @@ namespace System {
Init ();
}
- throw new NotImplementedException ();
+ throw new PlatformNotSupportedException ("Implemented only on Windows");
}
void AddToBuffer (int b)
@@ -1191,7 +1221,7 @@ namespace System {
Init ();
}
- throw new NotImplementedException (String.Empty);
+ TrySetWindowDimensions (width, height);
}
public void SetCursorPosition (int left, int top)
@@ -1202,15 +1232,15 @@ namespace System {
CheckWindowDimensions ();
if (left < 0 || left >= bufferWidth)
- throw new ArgumentOutOfRangeException ("left", "Value must be positive and below the buffer width.");
+ throw new ArgumentOutOfRangeException ("left", left.ToString (), "Value must be positive and below the buffer width.");
if (top < 0 || top >= bufferHeight)
- throw new ArgumentOutOfRangeException ("top", "Value must be positive and below the buffer height.");
+ throw new ArgumentOutOfRangeException ("top", top.ToString (), "Value must be positive and below the buffer height.");
// Either CursorAddress or nothing.
// We might want to play with up/down/left/right/home when ca is not available.
if (cursorAddress == null)
- throw new NotSupportedException ("This terminal does not suport setting the cursor position.");
+ throw new IOException ("This terminal does not suport setting the cursor position.");
WriteConsole (ParameterizedStrings.Evaluate (cursorAddress, top, left));
cursorLeft = left;
@@ -1223,8 +1253,8 @@ namespace System {
Init ();
}
- // No need to throw exceptions here.
- //throw new NotSupportedException ();
+ if (left != 0 || top != 0)
+ throw new ArgumentOutOfRangeException ("Unix terminals only support window position (0; 0)");
}
public void SetWindowSize (int width, int height)
@@ -1233,8 +1263,7 @@ namespace System {
Init ();
}
- // No need to throw exceptions here.
- //throw new NotSupportedException ();
+ TrySetWindowDimensions (width, height);
}