fix(notes): Shift+Enter in the capture box, not just in the note rows

The previous fix put AcceptsReturn on the rows in the DataTemplate and
missed the box you actually type new notes into, which still had it off
and only a KeyBinding for Enter — so Shift+Enter there did nothing.

Both now go through the same tunnel handler: Enter files the note,
Shift+Enter is left to the TextBox for the line break. The KeyBinding is
gone; with AcceptsReturn on it could never have fired anyway, because
TextBox consumes Enter in its own OnKeyDown before bindings or bubbling
handlers run.

Verified against the running app: a note typed with Shift+Enter is
stored as "fe\r\ndwa".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
CubeGameLP
2026-08-28 21:46:59 +02:00
co-authored by Claude Opus 5
parent b90c5855f4
commit f640580463
2 changed files with 25 additions and 10 deletions
@@ -45,14 +45,14 @@
<PathIcon Width="12" Height="12" Data="{StaticResource Icon.Plus}" <PathIcon Width="12" Height="12" Data="{StaticResource Icon.Plus}"
Foreground="{DynamicResource TextFaintBrush}"/> Foreground="{DynamicResource TextFaintBrush}"/>
</Border> </Border>
<!-- Enter/Shift+Enter are handled in the code-behind's tunnel handler, same as the note
rows: a KeyBinding would never fire, because AcceptsReturn makes TextBox consume
Enter first. -->
<TextBox Grid.Column="1" x:Name="NewNoteBox" Classes="add-task-input" <TextBox Grid.Column="1" x:Name="NewNoteBox" Classes="add-task-input"
PlaceholderText="{loc:Tr notes.newNotePlaceholder}" PlaceholderText="{loc:Tr notes.newNotePlaceholder}"
Text="{Binding NewBulletText, Mode=TwoWay}" Text="{Binding NewBulletText, Mode=TwoWay}"
VerticalAlignment="Center" Margin="12,0,0,0"> AcceptsReturn="True" TextWrapping="Wrap"
<TextBox.KeyBindings> VerticalAlignment="Center" Margin="12,0,0,0"/>
<KeyBinding Gesture="Enter" Command="{Binding AddBulletCommand}"/>
</TextBox.KeyBindings>
</TextBox>
<Border Grid.Column="2" Classes="kbd kbd-enter" VerticalAlignment="Center" <Border Grid.Column="2" Classes="kbd kbd-enter" VerticalAlignment="Center"
IsVisible="{Binding #NewNoteBox.IsFocused}"> IsVisible="{Binding #NewNoteBox.IsFocused}">
<TextBlock Text="{loc:Tr tasks.enterKey}"/> <TextBlock Text="{loc:Tr tasks.enterKey}"/>
@@ -21,6 +21,7 @@ public partial class NotesEditorView : UserControl
AddHandler(KeyDownEvent, OnBulletKeyDown, RoutingStrategies.Tunnel); AddHandler(KeyDownEvent, OnBulletKeyDown, RoutingStrategies.Tunnel);
} }
private void OnDataContextChanged(object? sender, EventArgs e) private void OnDataContextChanged(object? sender, EventArgs e)
{ {
if (_vm is not null) _vm.FocusRequested -= FocusBullet; if (_vm is not null) _vm.FocusRequested -= FocusBullet;
@@ -37,13 +38,27 @@ public partial class NotesEditorView : UserControl
private void OnBulletKeyDown(object? sender, KeyEventArgs e) private void OnBulletKeyDown(object? sender, KeyEventArgs e)
{ {
// Source, not sender: the tunnel handler is attached to the whole view, so this also sees // Source, not sender: the tunnel handler is attached to the whole view, so it sees the
// keys from the capture box at the top — which has no bullet behind it and is skipped. // capture box at the top as well as the note rows. Both need the same Enter/Shift+Enter
if (e.Source is not TextBox { DataContext: NoteBulletViewModel bullet } box // split, and neither can get it from a KeyBinding — with AcceptsReturn on, TextBox eats
|| DataContext is not NotesEditorViewModel vm) return; // Enter in its own OnKeyDown before any bubbling handler or binding runs.
if (e.Source is not TextBox box || DataContext is not NotesEditorViewModel vm) return;
var shift = e.KeyModifiers.HasFlag(KeyModifiers.Shift);
if (ReferenceEquals(box, NewNoteBox))
{
if (e.Key == Key.Enter && !shift)
{
e.Handled = true;
vm.AddBulletCommand.Execute(null);
}
return;
}
if (box.DataContext is not NoteBulletViewModel bullet) return;
// Shift+Enter falls through to the TextBox and breaks the line — a note can be several. // Shift+Enter falls through to the TextBox and breaks the line — a note can be several.
if (e.Key == Key.Enter && !e.KeyModifiers.HasFlag(KeyModifiers.Shift)) if (e.Key == Key.Enter && !shift)
{ {
e.Handled = true; e.Handled = true;
vm.SplitBulletCommand.Execute(bullet); vm.SplitBulletCommand.Execute(bullet);