From ce9fbf5822d19ae067773890374d92f4ee2d58d4 Mon Sep 17 00:00:00 2001 From: niksedk Date: Sun, 17 May 2026 15:29:33 +0200 Subject: [PATCH] Fix Typewriter plugin startup crash (NRE on named controls) MainWindow accessed InfoLabel/EndDelayInput/OkButton as if they were auto-assigned fields, but Avalonia 11 does not generate those out of the box without Avalonia.NameGenerator. Resolve them explicitly via FindControl in InitializeComponent, killing the NullReferenceException that aborted the plugin with exit code 134 right after Avalonia framework init. While here, drop PublishSingleFile/IncludeNativeLibrariesForSelfExtract from the workflow - Avalonia's recommended setup is multi-file self-contained publish, and the single-file extraction was a known source of subtle native-load issues. Bump plugin version to 1.0.1 and point se5-plugins.json at the new se5-typewriter-v1.0.1 release tag so SE shows "Update available" for anyone who installed the broken 1.0. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/typewriter.yml | 4 ++-- se5-plugins.json | 14 +++++++------- se5/TypewriterEffect/MainWindow.axaml.cs | 21 +++++++++++++++------ se5/TypewriterEffect/plugin.json | 2 +- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/.github/workflows/typewriter.yml b/.github/workflows/typewriter.yml index 7aca494..7862db0 100644 --- a/.github/workflows/typewriter.yml +++ b/.github/workflows/typewriter.yml @@ -59,8 +59,8 @@ jobs: -c Release \ -r ${{ matrix.rid }} \ --self-contained true \ - -p:PublishSingleFile=true \ - -p:IncludeNativeLibrariesForSelfExtract=true \ + -p:DebugType=None \ + -p:DebugSymbols=false \ -o staging/TypewriterEffect - name: Rewrite plugin.json for ${{ matrix.os }} diff --git a/se5-plugins.json b/se5-plugins.json index add5a84..65fc469 100644 --- a/se5-plugins.json +++ b/se5-plugins.json @@ -3,18 +3,18 @@ { "name": "Typewriter effect", "description": "Splits each subtitle line into short timed parts that progressively reveal the text, character by character.", - "version": "1.0.0", + "version": "1.0.1", "author": "Subtitle Edit", "url": "https://github.com/SubtitleEdit/plugins/tree/main/se5/TypewriterEffect", "date": "2026-05-17", "minSeVersion": "5.0.0", "downloads": { - "win-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-win-x64.zip", - "win-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-win-arm64.zip", - "linux-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-linux-x64.zip", - "linux-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-linux-arm64.zip", - "osx-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-osx-x64.zip", - "osx-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-osx-arm64.zip" + "win-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0.1/TypewriterEffect-win-x64.zip", + "win-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0.1/TypewriterEffect-win-arm64.zip", + "linux-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0.1/TypewriterEffect-linux-x64.zip", + "linux-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0.1/TypewriterEffect-linux-arm64.zip", + "osx-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0.1/TypewriterEffect-osx-x64.zip", + "osx-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0.1/TypewriterEffect-osx-arm64.zip" } }, { diff --git a/se5/TypewriterEffect/MainWindow.axaml.cs b/se5/TypewriterEffect/MainWindow.axaml.cs index 270738a..6f9eba6 100644 --- a/se5/TypewriterEffect/MainWindow.axaml.cs +++ b/se5/TypewriterEffect/MainWindow.axaml.cs @@ -2,6 +2,7 @@ using Avalonia.Interactivity; using Avalonia.Markup.Xaml; using System; +using System.Globalization; using System.Text.Json; namespace SubtitleEdit.Plugins.TypewriterEffect; @@ -9,24 +10,31 @@ namespace SubtitleEdit.Plugins.TypewriterEffect; public partial class MainWindow : Window { private readonly PluginRequest _request; + private TextBlock _infoLabel = null!; + private NumericUpDown _endDelayInput = null!; // Parameterless constructor only exists for the XAML designer. public MainWindow() : this(new PluginRequest()) { } public MainWindow(PluginRequest request) { - InitializeComponent(); _request = request; + InitializeComponent(); var selectedCount = request.SelectedIndices.Count; - InfoLabel.Text = selectedCount > 0 + _infoLabel.Text = selectedCount > 0 ? $"Each of the {selectedCount} selected line(s) will be split into several short lines that progressively reveal the text." : "Every line will be split into several short lines that progressively reveal the text."; - EndDelayInput.Value = (decimal)LoadEndDelaySetting(request.Settings, defaultValue: 0.5); + _endDelayInput.Value = (decimal)LoadEndDelaySetting(request.Settings, defaultValue: 0.5); } - private void InitializeComponent() => AvaloniaXamlLoader.Load(this); + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + _infoLabel = this.FindControl("InfoLabel")!; + _endDelayInput = this.FindControl("EndDelayInput")!; + } private void OnCancel(object? sender, RoutedEventArgs e) { @@ -36,7 +44,7 @@ private void OnCancel(object? sender, RoutedEventArgs e) private void OnOk(object? sender, RoutedEventArgs e) { - var endDelaySec = (double)(EndDelayInput.Value ?? 0m); + var endDelaySec = (double)(_endDelayInput.Value ?? 0m); try { @@ -84,7 +92,8 @@ private static double LoadEndDelaySetting(JsonElement? settings, double defaultV private static JsonElement BuildSettings(double endDelay) { - using var doc = JsonDocument.Parse($"{{\"endDelay\":{endDelay.ToString("0.###", System.Globalization.CultureInfo.InvariantCulture)}}}"); + var json = $"{{\"endDelay\":{endDelay.ToString("0.###", CultureInfo.InvariantCulture)}}}"; + using var doc = JsonDocument.Parse(json); return doc.RootElement.Clone(); } } diff --git a/se5/TypewriterEffect/plugin.json b/se5/TypewriterEffect/plugin.json index 8e630f6..8e6e267 100644 --- a/se5/TypewriterEffect/plugin.json +++ b/se5/TypewriterEffect/plugin.json @@ -2,7 +2,7 @@ "apiVersion": 1, "name": "Typewriter effect", "description": "Splits each subtitle line into short timed parts that progressively reveal the text, character by character.", - "version": "1.0.0", + "version": "1.0.1", "author": "Subtitle Edit", "url": "https://github.com/SubtitleEdit/plugins/tree/main/se5/TypewriterEffect", "menu": "Tools",