From ea29a5e8faf6ae681ee1436cbbb59f4a16be9ab9 Mon Sep 17 00:00:00 2001 From: Joel Christner Date: Sun, 31 May 2026 20:57:19 -0700 Subject: [PATCH 1/2] Fix XTerm.NET build warnings --- src/XTerm.NET.Tests/OscSequenceTests.cs | 12 ++++++++++++ src/XTerm.NET/Events/TerminalEvents.cs | 5 ++--- src/XTerm.NET/InputHandler.cs | 3 +++ src/XTerm.NET/Parser/EscapeSequenceParser.cs | 5 ----- src/XTerm.NET/Terminal.cs | 3 +++ 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/XTerm.NET.Tests/OscSequenceTests.cs b/src/XTerm.NET.Tests/OscSequenceTests.cs index 3b17d4b..c29f18e 100644 --- a/src/XTerm.NET.Tests/OscSequenceTests.cs +++ b/src/XTerm.NET.Tests/OscSequenceTests.cs @@ -127,12 +127,15 @@ public void OscHyperlink_StartLink_SetsHyperlink() { // Arrange var terminal = CreateTerminal(); + string? changedUrl = null; + terminal.HyperlinkChanged += (sender, e) => changedUrl = e.Url; // Act terminal.Write("\x1B]8;;http://example.com\x07"); // Assert Assert.Equal("http://example.com", terminal.CurrentHyperlink); + Assert.Equal("http://example.com", changedUrl); } [Fact] @@ -141,12 +144,21 @@ public void OscHyperlink_EndLink_ClearsHyperlink() // Arrange var terminal = CreateTerminal(); terminal.Write("\x1B]8;;http://example.com\x07"); + var eventCount = 0; + string? changedUrl = "not cleared"; + terminal.HyperlinkChanged += (sender, e) => + { + eventCount++; + changedUrl = e.Url; + }; // Act terminal.Write("\x1B]8;;\x07"); // Assert Assert.Null(terminal.CurrentHyperlink); + Assert.Equal(1, eventCount); + Assert.Null(changedUrl); } [Fact] diff --git a/src/XTerm.NET/Events/TerminalEvents.cs b/src/XTerm.NET/Events/TerminalEvents.cs index 70befd0..6b55a0c 100644 --- a/src/XTerm.NET/Events/TerminalEvents.cs +++ b/src/XTerm.NET/Events/TerminalEvents.cs @@ -137,9 +137,9 @@ public DirectoryChangeEventArgs(string directory) /// public class HyperlinkEventArgs : EventArgs { - public string Url { get; } + public string? Url { get; } - public HyperlinkEventArgs(string url) + public HyperlinkEventArgs(string? url) { Url = url; } @@ -267,4 +267,3 @@ public CursorStyleChangedEventArgs(CursorStyle style, bool blink) } } } - diff --git a/src/XTerm.NET/InputHandler.cs b/src/XTerm.NET/InputHandler.cs index 5e2daf7..64a4631 100644 --- a/src/XTerm.NET/InputHandler.cs +++ b/src/XTerm.NET/InputHandler.cs @@ -704,6 +704,7 @@ private void HandleHyperlink(string data) // End hyperlink _terminal.CurrentHyperlink = null; _terminal.HyperlinkId = null; + _terminal.RaiseHyperlinkChanged(null); } else { @@ -722,6 +723,8 @@ private void HandleHyperlink(string data) } } } + + _terminal.RaiseHyperlinkChanged(uri); } } } diff --git a/src/XTerm.NET/Parser/EscapeSequenceParser.cs b/src/XTerm.NET/Parser/EscapeSequenceParser.cs index a4ed8e6..0858984 100644 --- a/src/XTerm.NET/Parser/EscapeSequenceParser.cs +++ b/src/XTerm.NET/Parser/EscapeSequenceParser.cs @@ -43,11 +43,6 @@ public class EscapeSequenceParser /// public event EventHandler? Osc; - /// - /// Fired when DCS sequences are parsed. - /// - public event EventHandler? Dcs; - public EscapeSequenceParser() { _state = ParserState.Ground; diff --git a/src/XTerm.NET/Terminal.cs b/src/XTerm.NET/Terminal.cs index 97c88a7..c19a935 100644 --- a/src/XTerm.NET/Terminal.cs +++ b/src/XTerm.NET/Terminal.cs @@ -476,6 +476,9 @@ internal void RaiseTitleChanged(string title) => internal void RaiseDirectoryChanged(string directory) => DirectoryChanged?.Invoke(this, new TerminalEvents.DirectoryChangeEventArgs(directory)); + + internal void RaiseHyperlinkChanged(string? url) => + HyperlinkChanged?.Invoke(this, new TerminalEvents.HyperlinkEventArgs(url)); internal void RaiseWindowMoved(int x, int y) => WindowMoved?.Invoke(this, new TerminalEvents.WindowMovedEventArgs(x, y)); From 5fcdadc402c3574febb5e070aa6d281e1aaa5032 Mon Sep 17 00:00:00 2001 From: Joel Christner Date: Sun, 21 Jun 2026 09:30:42 -0700 Subject: [PATCH 2/2] Address build warning review feedback --- src/XTerm.NET.Tests/OscSequenceTests.cs | 10 ++++++++-- src/XTerm.NET/Events/TerminalEvents.cs | 20 +++++++++++++++++--- src/XTerm.NET/Parser/EscapeSequenceParser.cs | 8 ++++++++ src/XTerm.NET/Terminal.cs | 2 +- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/XTerm.NET.Tests/OscSequenceTests.cs b/src/XTerm.NET.Tests/OscSequenceTests.cs index c29f18e..5ec03f8 100644 --- a/src/XTerm.NET.Tests/OscSequenceTests.cs +++ b/src/XTerm.NET.Tests/OscSequenceTests.cs @@ -128,7 +128,9 @@ public void OscHyperlink_StartLink_SetsHyperlink() // Arrange var terminal = CreateTerminal(); string? changedUrl = null; + var isCleared = true; terminal.HyperlinkChanged += (sender, e) => changedUrl = e.Url; + terminal.HyperlinkChanged += (sender, e) => isCleared = e.IsCleared; // Act terminal.Write("\x1B]8;;http://example.com\x07"); @@ -136,6 +138,7 @@ public void OscHyperlink_StartLink_SetsHyperlink() // Assert Assert.Equal("http://example.com", terminal.CurrentHyperlink); Assert.Equal("http://example.com", changedUrl); + Assert.False(isCleared); } [Fact] @@ -145,11 +148,13 @@ public void OscHyperlink_EndLink_ClearsHyperlink() var terminal = CreateTerminal(); terminal.Write("\x1B]8;;http://example.com\x07"); var eventCount = 0; - string? changedUrl = "not cleared"; + string changedUrl = "not cleared"; + var isCleared = false; terminal.HyperlinkChanged += (sender, e) => { eventCount++; changedUrl = e.Url; + isCleared = e.IsCleared; }; // Act @@ -158,7 +163,8 @@ public void OscHyperlink_EndLink_ClearsHyperlink() // Assert Assert.Null(terminal.CurrentHyperlink); Assert.Equal(1, eventCount); - Assert.Null(changedUrl); + Assert.Equal(string.Empty, changedUrl); + Assert.True(isCleared); } [Fact] diff --git a/src/XTerm.NET/Events/TerminalEvents.cs b/src/XTerm.NET/Events/TerminalEvents.cs index 6b55a0c..23d577a 100644 --- a/src/XTerm.NET/Events/TerminalEvents.cs +++ b/src/XTerm.NET/Events/TerminalEvents.cs @@ -133,15 +133,29 @@ public DirectoryChangeEventArgs(string directory) } /// - /// Hyperlink event - fired when a hyperlink is encountered. + /// Hyperlink event - fired when a hyperlink is encountered or cleared. /// public class HyperlinkEventArgs : EventArgs { - public string? Url { get; } + /// + /// Hyperlink URL. Empty when is true. + /// + public string Url { get; } + + /// + /// True when the active hyperlink was cleared. + /// + public bool IsCleared { get; } - public HyperlinkEventArgs(string? url) + public HyperlinkEventArgs(string url) + : this(url, false) + { + } + + internal HyperlinkEventArgs(string url, bool isCleared) { Url = url; + IsCleared = isCleared; } } diff --git a/src/XTerm.NET/Parser/EscapeSequenceParser.cs b/src/XTerm.NET/Parser/EscapeSequenceParser.cs index 0858984..0c978e2 100644 --- a/src/XTerm.NET/Parser/EscapeSequenceParser.cs +++ b/src/XTerm.NET/Parser/EscapeSequenceParser.cs @@ -43,6 +43,14 @@ public class EscapeSequenceParser /// public event EventHandler? Osc; + /// + /// DCS parsing is not implemented yet. This event is retained for source compatibility. + /// +#pragma warning disable CS0067 + [Obsolete("DCS parsing is not implemented yet; this event is retained for source compatibility.")] + public event EventHandler? Dcs; +#pragma warning restore CS0067 + public EscapeSequenceParser() { _state = ParserState.Ground; diff --git a/src/XTerm.NET/Terminal.cs b/src/XTerm.NET/Terminal.cs index c19a935..a66ef2d 100644 --- a/src/XTerm.NET/Terminal.cs +++ b/src/XTerm.NET/Terminal.cs @@ -478,7 +478,7 @@ internal void RaiseDirectoryChanged(string directory) => DirectoryChanged?.Invoke(this, new TerminalEvents.DirectoryChangeEventArgs(directory)); internal void RaiseHyperlinkChanged(string? url) => - HyperlinkChanged?.Invoke(this, new TerminalEvents.HyperlinkEventArgs(url)); + HyperlinkChanged?.Invoke(this, new TerminalEvents.HyperlinkEventArgs(url ?? string.Empty, url == null)); internal void RaiseWindowMoved(int x, int y) => WindowMoved?.Invoke(this, new TerminalEvents.WindowMovedEventArgs(x, y));