mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-28 08:47:59 +01:00
Fixes #3974. TabView steals keypresses from active ContextMenu
This commit is contained in:
@@ -84,6 +84,94 @@ public class TabView : View
|
||||
}
|
||||
);
|
||||
|
||||
AddCommand (
|
||||
Command.Up,
|
||||
() =>
|
||||
{
|
||||
if (_style.TabsOnBottom)
|
||||
{
|
||||
if (_tabsBar is { HasFocus: true } && _containerView.CanFocus)
|
||||
{
|
||||
_containerView.SetFocus ();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_containerView is { HasFocus: true })
|
||||
{
|
||||
var mostFocused = _containerView.MostFocused;
|
||||
|
||||
if (mostFocused is { })
|
||||
{
|
||||
for (int? i = mostFocused.SuperView?.InternalSubViews.IndexOf (mostFocused) - 1; i > -1; i--)
|
||||
{
|
||||
var view = mostFocused.SuperView?.InternalSubViews [(int)i];
|
||||
|
||||
if (view is { CanFocus: true, Enabled: true, Visible: true })
|
||||
{
|
||||
view.SetFocus ();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SelectedTab?.SetFocus ();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
AddCommand (
|
||||
Command.Down,
|
||||
() =>
|
||||
{
|
||||
if (_style.TabsOnBottom)
|
||||
{
|
||||
if (_containerView is { HasFocus: true })
|
||||
{
|
||||
var mostFocused = _containerView.MostFocused;
|
||||
|
||||
if (mostFocused is { })
|
||||
{
|
||||
for (int? i = mostFocused.SuperView?.InternalSubViews.IndexOf (mostFocused) + 1; i < mostFocused.SuperView?.InternalSubViews.Count; i++)
|
||||
{
|
||||
var view = mostFocused.SuperView?.InternalSubViews [(int)i];
|
||||
|
||||
if (view is { CanFocus: true, Enabled: true, Visible: true })
|
||||
{
|
||||
view.SetFocus ();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SelectedTab?.SetFocus ();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_tabsBar is { HasFocus: true } && _containerView.CanFocus)
|
||||
{
|
||||
_containerView.SetFocus ();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
// Default keybindings for this view
|
||||
KeyBindings.Add (Key.CursorLeft, Command.Left);
|
||||
KeyBindings.Add (Key.CursorRight, Command.Right);
|
||||
@@ -91,6 +179,8 @@ public class TabView : View
|
||||
KeyBindings.Add (Key.End, Command.RightEnd);
|
||||
KeyBindings.Add (Key.PageDown, Command.PageDown);
|
||||
KeyBindings.Add (Key.PageUp, Command.PageUp);
|
||||
KeyBindings.Add (Key.CursorUp, Command.Up);
|
||||
KeyBindings.Add (Key.CursorDown, Command.Down);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -155,7 +245,7 @@ public class TabView : View
|
||||
|
||||
private bool TabCanSetFocus ()
|
||||
{
|
||||
return IsInitialized && SelectedTab is { } && (_selectedTabHasFocus || !_containerView.CanFocus);
|
||||
return IsInitialized && SelectedTab is { } && (HasFocus || (bool)_containerView?.HasFocus) && (_selectedTabHasFocus || !_containerView.CanFocus);
|
||||
}
|
||||
|
||||
private void ContainerViewCanFocus (object sender, EventArgs eventArgs)
|
||||
@@ -518,7 +608,7 @@ public class TabView : View
|
||||
{
|
||||
SelectedTab?.SetFocus ();
|
||||
}
|
||||
else
|
||||
else if (HasFocus)
|
||||
{
|
||||
SelectedTab?.View?.SetFocus ();
|
||||
}
|
||||
|
||||
@@ -2135,4 +2135,84 @@ public class ContextMenuTests (ITestOutputHelper output)
|
||||
|
||||
top.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void Menu_Opened_In_SuperView_With_TabView_Has_Precedence_On_Key_Press ()
|
||||
{
|
||||
var win = new Window
|
||||
{
|
||||
Title = "My Window",
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = Dim.Fill (),
|
||||
Height = Dim.Fill ()
|
||||
};
|
||||
|
||||
// Tab View
|
||||
var tabView = new TabView
|
||||
{
|
||||
X = 1,
|
||||
Y = 1,
|
||||
Width = Dim.Fill () - 2,
|
||||
Height = Dim.Fill () - 2
|
||||
};
|
||||
tabView.AddTab (new () { DisplayText = "Tab 1" }, true);
|
||||
tabView.AddTab (new () { DisplayText = "Tab 2" }, false);
|
||||
win.Add (tabView);
|
||||
|
||||
// Context Menu
|
||||
var menuItems = new MenuBarItem (
|
||||
[
|
||||
new ("Item 1", "First item", () => MessageBox.Query ("Action", "Item 1 Clicked", "OK")),
|
||||
new MenuBarItem (
|
||||
"Submenu",
|
||||
new List<MenuItem []>
|
||||
{
|
||||
new []
|
||||
{
|
||||
new MenuItem (
|
||||
"Sub Item 1",
|
||||
"Submenu item",
|
||||
() => { MessageBox.Query ("Action", "Sub Item 1 Clicked", "OK"); })
|
||||
}
|
||||
})
|
||||
]);
|
||||
|
||||
var cm = new ContextMenu ();
|
||||
|
||||
win.MouseClick += (s, e) =>
|
||||
{
|
||||
if (e.Flags.HasFlag (MouseFlags.Button3Clicked)) // Right-click
|
||||
{
|
||||
cm.Position = e.Position;
|
||||
cm.Show (menuItems);
|
||||
}
|
||||
};
|
||||
Application.Begin (win);
|
||||
|
||||
cm.Show (menuItems);
|
||||
Assert.True (cm.MenuBar!.IsMenuOpen);
|
||||
|
||||
Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown));
|
||||
Assert.True (cm.MenuBar!.IsMenuOpen);
|
||||
|
||||
Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
|
||||
Assert.True (cm.MenuBar!.IsMenuOpen);
|
||||
|
||||
Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown));
|
||||
Assert.True (cm.MenuBar!.IsMenuOpen);
|
||||
|
||||
Assert.True (Application.RaiseKeyDownEvent (Key.CursorRight));
|
||||
Assert.True (cm.MenuBar!.IsMenuOpen);
|
||||
|
||||
Assert.True (Application.RaiseKeyDownEvent (Key.CursorLeft));
|
||||
Assert.True (cm.MenuBar!.IsMenuOpen);
|
||||
|
||||
Assert.True (Application.RaiseKeyDownEvent (Key.CursorLeft));
|
||||
Assert.False (cm.MenuBar!.IsMenuOpen);
|
||||
Assert.True (tabView.HasFocus);
|
||||
|
||||
win.Dispose ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,9 +434,8 @@ public class TabViewTests (ITestOutputHelper output)
|
||||
Assert.Equal (btnSubView, top.MostFocused);
|
||||
|
||||
Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
|
||||
// TabRow now has TabGroup which only F6 is allowed
|
||||
Assert.NotEqual (tab2, top.MostFocused);
|
||||
Assert.Equal (btn, top.MostFocused);
|
||||
Assert.Equal (tab2, top.MostFocused);
|
||||
Assert.NotEqual (btn, top.MostFocused);
|
||||
|
||||
Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
|
||||
Assert.Equal (btnSubView, top.MostFocused);
|
||||
@@ -459,7 +458,8 @@ public class TabViewTests (ITestOutputHelper output)
|
||||
// Press the cursor up key to focus the selected tab which it's the only way to do that
|
||||
Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
|
||||
Assert.Equal (tab2, tv.SelectedTab);
|
||||
Assert.Equal (btn, top.Focused);
|
||||
Assert.False (tab2.View.HasFocus);
|
||||
Assert.Equal (tv, top.Focused);
|
||||
|
||||
Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
|
||||
Assert.Equal (tv, top.Focused);
|
||||
|
||||
Reference in New Issue
Block a user