Переглянути джерело

Fixes #4241. v2net driver isn't suspending on Unix platforms (#4242)

Co-authored-by: Tig <[email protected]>
BDisp 17 годин тому
батько
коміт
e869f842e3

+ 0 - 81
Terminal.Gui/Drivers/CursesDriver/CursesDriver.cs

@@ -1082,84 +1082,3 @@ internal class CursesDriver : ConsoleDriver
     /// <inheritdoc/>
     public override void WriteRaw (string ansi) { _mainLoopDriver?.WriteRaw (ansi); }
 }
-
-// TODO: One type per file - move to another file
-internal static class Platform
-{
-    private static int _suspendSignal;
-
-    /// <summary>Suspends the process by sending SIGTSTP to itself</summary>
-    /// <returns>True if the suspension was successful.</returns>
-    public static bool Suspend ()
-    {
-        int signal = GetSuspendSignal ();
-
-        if (signal == -1)
-        {
-            return false;
-        }
-
-        killpg (0, signal);
-
-        return true;
-    }
-
-    private static int GetSuspendSignal ()
-    {
-        if (_suspendSignal != 0)
-        {
-            return _suspendSignal;
-        }
-
-        nint buf = Marshal.AllocHGlobal (8192);
-
-        if (uname (buf) != 0)
-        {
-            Marshal.FreeHGlobal (buf);
-            _suspendSignal = -1;
-
-            return _suspendSignal;
-        }
-
-        try
-        {
-            switch (Marshal.PtrToStringAnsi (buf))
-            {
-                case "Darwin":
-                case "DragonFly":
-                case "FreeBSD":
-                case "NetBSD":
-                case "OpenBSD":
-                    _suspendSignal = 18;
-
-                    break;
-                case "Linux":
-                    // TODO: should fetch the machine name and
-                    // if it is MIPS return 24
-                    _suspendSignal = 20;
-
-                    break;
-                case "Solaris":
-                    _suspendSignal = 24;
-
-                    break;
-                default:
-                    _suspendSignal = -1;
-
-                    break;
-            }
-
-            return _suspendSignal;
-        }
-        finally
-        {
-            Marshal.FreeHGlobal (buf);
-        }
-    }
-
-    [DllImport ("libc")]
-    private static extern int killpg (int pgrp, int pid);
-
-    [DllImport ("libc")]
-    private static extern int uname (nint buf);
-}

+ 83 - 0
Terminal.Gui/Drivers/CursesDriver/Platform.cs

@@ -0,0 +1,83 @@
+using System.Runtime.InteropServices;
+
+namespace Terminal.Gui.Drivers;
+
+internal static class Platform
+{
+    private static int _suspendSignal;
+
+    /// <summary>Suspends the process by sending SIGTSTP to itself</summary>
+    /// <returns>True if the suspension was successful.</returns>
+    public static bool Suspend ()
+    {
+        int signal = GetSuspendSignal ();
+
+        if (signal == -1)
+        {
+            return false;
+        }
+
+        killpg (0, signal);
+
+        return true;
+    }
+
+    private static int GetSuspendSignal ()
+    {
+        if (_suspendSignal != 0)
+        {
+            return _suspendSignal;
+        }
+
+        nint buf = Marshal.AllocHGlobal (8192);
+
+        if (uname (buf) != 0)
+        {
+            Marshal.FreeHGlobal (buf);
+            _suspendSignal = -1;
+
+            return _suspendSignal;
+        }
+
+        try
+        {
+            switch (Marshal.PtrToStringAnsi (buf))
+            {
+                case "Darwin":
+                case "DragonFly":
+                case "FreeBSD":
+                case "NetBSD":
+                case "OpenBSD":
+                    _suspendSignal = 18;
+
+                    break;
+                case "Linux":
+                    // TODO: should fetch the machine name and
+                    // if it is MIPS return 24
+                    _suspendSignal = 20;
+
+                    break;
+                case "Solaris":
+                    _suspendSignal = 24;
+
+                    break;
+                default:
+                    _suspendSignal = -1;
+
+                    break;
+            }
+
+            return _suspendSignal;
+        }
+        finally
+        {
+            Marshal.FreeHGlobal (buf);
+        }
+    }
+
+    [DllImport ("libc")]
+    private static extern int killpg (int pgrp, int pid);
+
+    [DllImport ("libc")]
+    private static extern int uname (nint buf);
+}

+ 30 - 1
Terminal.Gui/Drivers/V2/ConsoleDriverFacade.cs

@@ -326,7 +326,36 @@ internal class ConsoleDriverFacade<T> : IConsoleDriver, IConsoleDriverFacade
     }
 
     /// <inheritdoc/>
-    public void Suspend () { }
+    public void Suspend ()
+    {
+        if (Environment.OSVersion.Platform != PlatformID.Unix)
+        {
+            return;
+        }
+
+        Console.Out.Write (EscSeqUtils.CSI_DisableMouseEvents);
+
+        if (!ConsoleDriver.RunningUnitTests)
+        {
+            Console.ResetColor ();
+            Console.Clear ();
+
+            //Disable alternative screen buffer.
+            Console.Out.Write (EscSeqUtils.CSI_RestoreCursorAndRestoreAltBufferWithBackscroll);
+
+            //Set cursor key to cursor.
+            Console.Out.Write (EscSeqUtils.CSI_ShowCursor);
+
+            Platform.Suspend ();
+
+            //Enable alternative screen buffer.
+            Console.Out.Write (EscSeqUtils.CSI_SaveCursorAndActivateAltBufferNoBackscroll);
+
+            Application.LayoutAndDraw ();
+        }
+
+        Console.Out.Write (EscSeqUtils.CSI_EnableMouseEvents);
+    }
 
     /// <summary>
     ///     Sets the position of the terminal cursor to <see cref="ConsoleDriver.Col"/> and