Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions Terminal.Gui/Views/Shortcut.cs
Original file line number Diff line number Diff line change
Expand Up @@ -805,11 +805,6 @@ private void SetKeyViewDefaultLayout ()

private void UpdateKeyBindings (Key oldKey)
{
if (!Key.IsValid)
{
return;
}

if (BindKeyToApplication)
{
if (oldKey != Key.Empty)
Expand All @@ -819,8 +814,11 @@ private void UpdateKeyBindings (Key oldKey)

App?.Keyboard.KeyBindings.Remove (Key);

// Use the form of Add that provides target since this is an app-level hotkey
App?.Keyboard.KeyBindings.AddApp (Key, this, Command.HotKey);
if (Key != Key.Empty)
{
// Use the form of Add that provides target since this is an app-level hotkey
App?.Keyboard.KeyBindings.AddApp (Key, this, Command.HotKey);
}
Comment thread
tig marked this conversation as resolved.
}
else
{
Expand All @@ -830,7 +828,11 @@ private void UpdateKeyBindings (Key oldKey)
}

HotKeyBindings.Remove (Key);
HotKeyBindings.Add (Key, Command.HotKey);

if (Key != Key.Empty)
{
HotKeyBindings.Add (Key, Command.HotKey);
}
Comment thread
tig marked this conversation as resolved.
}
}

Expand Down
108 changes: 75 additions & 33 deletions Tests/UnitTestsParallelizable/Views/ShortcutTests.KeyDown.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,67 @@ namespace ViewsTests;
[TestSubject (typeof (Shortcut))]
public partial class ShortcutTests
{
// Copilot
/// <summary>
/// Verifies that setting <see cref="Shortcut.Key"/> to <see cref="Key.Empty"/> removes the key binding,
/// so the previously-bound key no longer triggers the action.
/// </summary>
[Fact]
public void Setting_Key_To_Empty_Removes_KeyBinding ()
{
IApplication app = Application.Create ();
Runnable<bool> runnable = new ();
app.Begin (runnable);

var action = 0;

Shortcut shortcut = new () { Key = Key.F10, Title = "Test", Action = () => action++ };

runnable.Add (shortcut);

app.Keyboard.RaiseKeyDownEvent (Key.F10);
Assert.Equal (1, action);

shortcut.Key = Key.Empty;

app.Keyboard.RaiseKeyDownEvent (Key.F10);
Assert.Equal (1, action); // Should not have incremented; old binding must be gone
}

// Copilot
/// <summary>
/// Verifies that setting <see cref="Shortcut.Key"/> to <see cref="Key.Empty"/> removes the
/// application-level key binding when <see cref="Shortcut.BindKeyToApplication"/> is <see langword="true"/>.
/// </summary>
[Fact]
public void Setting_Key_To_Empty_Removes_AppLevel_KeyBinding ()
{
IApplication app = Application.Create ();
Runnable<bool> runnable = new ();
app.Begin (runnable);

var action = 0;

Shortcut shortcut = new ()
{
App = app,
Key = Key.F10,
Title = "Test",
BindKeyToApplication = true,
Action = () => action++
};

runnable.Add (shortcut);

app.Keyboard.RaiseKeyDownEvent (Key.F10);
Assert.Equal (1, action);

shortcut.Key = Key.Empty;

app.Keyboard.RaiseKeyDownEvent (Key.F10);
Assert.Equal (1, action); // Should not have incremented; old app binding must be gone
}

// Claude - Opus 4.6
/// <summary>
/// Verifies that pressing various keys invokes the <see cref="Shortcut.Action"/> delegate.
Expand Down Expand Up @@ -111,15 +172,15 @@ public void KeyDown_Key_Raises_HandlingHotKey_And_Accepting (bool canFocus)

var accepting = 0;

shortcut.Accepting += (_, e) => { accepting++; };
shortcut.Accepting += (_, _) => { accepting++; };

var activated = 0;

shortcut.Activating += (_, e) => { activated++; };
shortcut.Activating += (_, _) => { activated++; };

var handlingHotKey = 0;

shortcut.HandlingHotKey += (_, e) => { handlingHotKey++; };
shortcut.HandlingHotKey += (_, _) => { handlingHotKey++; };

app.Keyboard.RaiseKeyDownEvent (shortcut.Key);

Expand All @@ -143,15 +204,15 @@ public void CheckBox_KeyDown_Key_Raises_HandlingHotKey_And_Accepting (bool canFo

var accepting = 0;

shortcut.Accepting += (_, e) => { accepting++; };
shortcut.Accepting += (_, _) => { accepting++; };

var activated = 0;

shortcut.Activating += (_, e) => { activated++; };
shortcut.Activating += (_, _) => { activated++; };

var handlingHotKey = 0;

shortcut.HandlingHotKey += (_, e) => { handlingHotKey++; };
shortcut.HandlingHotKey += (_, _) => { handlingHotKey++; };

app.Keyboard.RaiseKeyDownEvent (shortcut.Key);

Expand Down Expand Up @@ -192,38 +253,18 @@ public void KeyDown_Valid_Keys_Raises_Accepted_Activated_Correctly (bool canFocu

var accepting = 0;

shortcut.Accepting += (_, e) =>
{
accepting++;

//e.Handled = true;
};
shortcut.Accepting += (_, _) => { accepting++; };

var activated = 0;

shortcut.Activating += (_, e) =>
{
activated++;

//e.Handled = true;
};

var handlingHotKey = 0;

shortcut.HandlingHotKey += (_, e) =>
{
handlingHotKey++;

//e.Handled = true;
};
shortcut.Activating += (_, _) => { activated++; };

app.Keyboard.RaiseKeyDownEvent (key);

Assert.Equal (expectedAccept, accepting);
Assert.Equal (expectedActivate, activated);
}


[Fact]
public void Mouse_Click_On_CommandView_Causes_Activation ()
{
Expand Down Expand Up @@ -255,7 +296,8 @@ public void Mouse_Click_On_CommandView_Causes_Activation ()

// Act & Assert - Click at various X positions across the entire CommandView
Rectangle screen = shortcut.CommandView.FrameToScreen ();
for (var x = screen.X; x < screen.X + screen.Width; x++)

for (int x = screen.X; x < screen.X + screen.Width; x++)
{
int expectedCount = activatingCount + 1;

Expand Down Expand Up @@ -298,7 +340,8 @@ public void Mouse_Click_On_HelpView_Causes_Activation ()

// Act & Assert - Click at various X positions across the entire HelpView
Rectangle screen = shortcut.HelpView.FrameToScreen ();
for (var x = screen.X; x < screen.X + screen.Width; x++)

for (int x = screen.X; x < screen.X + screen.Width; x++)
{
int expectedCount = activatingCount + 1;

Expand All @@ -310,7 +353,6 @@ public void Mouse_Click_On_HelpView_Causes_Activation ()
}
}


[Fact]
public void Mouse_Click_On_KeyView_Causes_Activation ()
{
Expand Down Expand Up @@ -342,7 +384,8 @@ public void Mouse_Click_On_KeyView_Causes_Activation ()

// Act & Assert - Click at various X positions across the entire KeyView
Rectangle screen = shortcut.KeyView.FrameToScreen ();
for (var x = screen.X+1; x < screen.X + screen.Width; x++)

for (int x = screen.X + 1; x < screen.X + screen.Width; x++)
{
int expectedCount = activatingCount + 1;

Expand Down Expand Up @@ -453,5 +496,4 @@ public void Mouse_Click_Button_CommandView_Raises_Accepting_On_Both (bool comman
Assert.Equal (0, buttonActivatingCount);
Assert.Equal (0, shortcutActivatingCount);
}

}
Loading