Skip to content

Commit ce9fbf5

Browse files
niksedkclaude
andcommitted
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) <noreply@anthropic.com>
1 parent 248558f commit ce9fbf5

4 files changed

Lines changed: 25 additions & 16 deletions

File tree

.github/workflows/typewriter.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ jobs:
5959
-c Release \
6060
-r ${{ matrix.rid }} \
6161
--self-contained true \
62-
-p:PublishSingleFile=true \
63-
-p:IncludeNativeLibrariesForSelfExtract=true \
62+
-p:DebugType=None \
63+
-p:DebugSymbols=false \
6464
-o staging/TypewriterEffect
6565
6666
- name: Rewrite plugin.json for ${{ matrix.os }}

se5-plugins.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
{
44
"name": "Typewriter effect",
55
"description": "Splits each subtitle line into short timed parts that progressively reveal the text, character by character.",
6-
"version": "1.0.0",
6+
"version": "1.0.1",
77
"author": "Subtitle Edit",
88
"url": "https://github.com/SubtitleEdit/plugins/tree/main/se5/TypewriterEffect",
99
"date": "2026-05-17",
1010
"minSeVersion": "5.0.0",
1111
"downloads": {
12-
"win-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-win-x64.zip",
13-
"win-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-win-arm64.zip",
14-
"linux-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-linux-x64.zip",
15-
"linux-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-linux-arm64.zip",
16-
"osx-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-osx-x64.zip",
17-
"osx-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0/TypewriterEffect-osx-arm64.zip"
12+
"win-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0.1/TypewriterEffect-win-x64.zip",
13+
"win-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0.1/TypewriterEffect-win-arm64.zip",
14+
"linux-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0.1/TypewriterEffect-linux-x64.zip",
15+
"linux-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0.1/TypewriterEffect-linux-arm64.zip",
16+
"osx-x64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0.1/TypewriterEffect-osx-x64.zip",
17+
"osx-arm64": "https://github.com/SubtitleEdit/plugins/releases/download/se5-typewriter-v1.0.1/TypewriterEffect-osx-arm64.zip"
1818
}
1919
},
2020
{

se5/TypewriterEffect/MainWindow.axaml.cs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,39 @@
22
using Avalonia.Interactivity;
33
using Avalonia.Markup.Xaml;
44
using System;
5+
using System.Globalization;
56
using System.Text.Json;
67

78
namespace SubtitleEdit.Plugins.TypewriterEffect;
89

910
public partial class MainWindow : Window
1011
{
1112
private readonly PluginRequest _request;
13+
private TextBlock _infoLabel = null!;
14+
private NumericUpDown _endDelayInput = null!;
1215

1316
// Parameterless constructor only exists for the XAML designer.
1417
public MainWindow() : this(new PluginRequest()) { }
1518

1619
public MainWindow(PluginRequest request)
1720
{
18-
InitializeComponent();
1921
_request = request;
22+
InitializeComponent();
2023

2124
var selectedCount = request.SelectedIndices.Count;
22-
InfoLabel.Text = selectedCount > 0
25+
_infoLabel.Text = selectedCount > 0
2326
? $"Each of the {selectedCount} selected line(s) will be split into several short lines that progressively reveal the text."
2427
: "Every line will be split into several short lines that progressively reveal the text.";
2528

26-
EndDelayInput.Value = (decimal)LoadEndDelaySetting(request.Settings, defaultValue: 0.5);
29+
_endDelayInput.Value = (decimal)LoadEndDelaySetting(request.Settings, defaultValue: 0.5);
2730
}
2831

29-
private void InitializeComponent() => AvaloniaXamlLoader.Load(this);
32+
private void InitializeComponent()
33+
{
34+
AvaloniaXamlLoader.Load(this);
35+
_infoLabel = this.FindControl<TextBlock>("InfoLabel")!;
36+
_endDelayInput = this.FindControl<NumericUpDown>("EndDelayInput")!;
37+
}
3038

3139
private void OnCancel(object? sender, RoutedEventArgs e)
3240
{
@@ -36,7 +44,7 @@ private void OnCancel(object? sender, RoutedEventArgs e)
3644

3745
private void OnOk(object? sender, RoutedEventArgs e)
3846
{
39-
var endDelaySec = (double)(EndDelayInput.Value ?? 0m);
47+
var endDelaySec = (double)(_endDelayInput.Value ?? 0m);
4048

4149
try
4250
{
@@ -84,7 +92,8 @@ private static double LoadEndDelaySetting(JsonElement? settings, double defaultV
8492

8593
private static JsonElement BuildSettings(double endDelay)
8694
{
87-
using var doc = JsonDocument.Parse($"{{\"endDelay\":{endDelay.ToString("0.###", System.Globalization.CultureInfo.InvariantCulture)}}}");
95+
var json = $"{{\"endDelay\":{endDelay.ToString("0.###", CultureInfo.InvariantCulture)}}}";
96+
using var doc = JsonDocument.Parse(json);
8897
return doc.RootElement.Clone();
8998
}
9099
}

se5/TypewriterEffect/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"apiVersion": 1,
33
"name": "Typewriter effect",
44
"description": "Splits each subtitle line into short timed parts that progressively reveal the text, character by character.",
5-
"version": "1.0.0",
5+
"version": "1.0.1",
66
"author": "Subtitle Edit",
77
"url": "https://github.com/SubtitleEdit/plugins/tree/main/se5/TypewriterEffect",
88
"menu": "Tools",

0 commit comments

Comments
 (0)