From 7c91d6976d75a3a256130db080b6e28923476292 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 27 Jul 2013 20:38:05 +1200 Subject: [PATCH] Split keyboard and mouse focus. Fixes #3304. Fixes #2075. Fixes C&C chat focus bug. --- OpenRA.Game/Game.cs | 3 +- OpenRA.Game/Widgets/BackgroundWidget.cs | 4 +- OpenRA.Game/Widgets/ButtonWidget.cs | 18 +++---- OpenRA.Game/Widgets/ChatEntryWidget.cs | 6 +-- OpenRA.Game/Widgets/ScrollPanelWidget.cs | 14 +++--- OpenRA.Game/Widgets/SliderWidget.cs | 6 +-- OpenRA.Game/Widgets/TextFieldWidget.cs | 28 +++++------ .../Widgets/ViewportScrollControllerWidget.cs | 4 +- OpenRA.Game/Widgets/Widget.cs | 48 ++++++++++++------- .../WorldInteractionControllerWidget.cs | 8 ++-- .../CncWorldInteractionControllerWidget.cs | 4 +- .../Widgets/ProductionTabsWidget.cs | 12 ++--- OpenRA.Mods.RA/Widgets/ColorMixerWidget.cs | 6 +-- .../Widgets/Logic/IngameChatLogic.cs | 4 +- OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs | 8 ++-- .../Widgets/Logic/SettingsMenuLogic.cs | 7 +-- 16 files changed, 93 insertions(+), 87 deletions(-) diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index bb73cfa2b2..a29a7b9ee3 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -215,7 +215,8 @@ namespace OpenRA worldRenderer = new WorldRenderer(orderManager.world); if (orderManager.GameStarted) return; - Ui.SelectedWidget = null; + Ui.MouseFocusWidget = null; + Ui.KeyboardFocusWidget = null; orderManager.LocalFrameNumber = 0; orderManager.LastTickTime = Environment.TickCount; diff --git a/OpenRA.Game/Widgets/BackgroundWidget.cs b/OpenRA.Game/Widgets/BackgroundWidget.cs index 936e568c4b..d7e9589437 100644 --- a/OpenRA.Game/Widgets/BackgroundWidget.cs +++ b/OpenRA.Game/Widgets/BackgroundWidget.cs @@ -33,7 +33,7 @@ namespace OpenRA.Widgets if (ClickThrough || !Bounds.Contains(mi.Location)) return false; - if (!Draggable || moving && (!TakeFocus(mi) || mi.Button != MouseButton.Left)) + if (!Draggable || moving && (!TakeMouseFocus(mi) || mi.Button != MouseButton.Left)) return true; if (prevMouseLocation == null) @@ -44,7 +44,7 @@ namespace OpenRA.Widgets { case MouseInputEvent.Up: moving = false; - LoseFocus(mi); + YieldMouseFocus(mi); break; case MouseInputEvent.Down: moving = true; diff --git a/OpenRA.Game/Widgets/ButtonWidget.cs b/OpenRA.Game/Widgets/ButtonWidget.cs index 0773bc8534..f80c9958f3 100644 --- a/OpenRA.Game/Widgets/ButtonWidget.cs +++ b/OpenRA.Game/Widgets/ButtonWidget.cs @@ -83,10 +83,10 @@ namespace OpenRA.Widgets Ui.Root.Get(TooltipContainer)); } - public override bool LoseFocus(MouseInput mi) + public override bool YieldMouseFocus(MouseInput mi) { Depressed = false; - return base.LoseFocus(mi); + return base.YieldMouseFocus(mi); } public override bool HandleKeyPress(KeyInput e) @@ -110,25 +110,25 @@ namespace OpenRA.Widgets if (mi.Button != MouseButton.Left) return false; - if (mi.Event == MouseInputEvent.Down && !TakeFocus(mi)) + if (mi.Event == MouseInputEvent.Down && !TakeMouseFocus(mi)) return false; var disabled = IsDisabled(); - if (Focused && mi.Event == MouseInputEvent.Up && mi.MultiTapCount == 2) + if (HasMouseFocus && mi.Event == MouseInputEvent.Up && mi.MultiTapCount == 2) { if (!disabled) { OnDoubleClick(); - return LoseFocus(mi); + return YieldMouseFocus(mi); } } // Only fire the onMouseUp event if we successfully lost focus, and were pressed - else if (Focused && mi.Event == MouseInputEvent.Up) + else if (HasMouseFocus && mi.Event == MouseInputEvent.Up) { if (Depressed && !disabled) OnMouseUp(mi); - return LoseFocus(mi); + return YieldMouseFocus(mi); } if (mi.Event == MouseInputEvent.Down) { @@ -141,11 +141,11 @@ namespace OpenRA.Widgets } else { - LoseFocus(mi); + YieldMouseFocus(mi); Sound.PlayNotification(null, "Sounds", "ClickDisabledSound", null); } } - else if (mi.Event == MouseInputEvent.Move && Focused) + else if (mi.Event == MouseInputEvent.Move && HasMouseFocus) Depressed = RenderBounds.Contains(mi.Location); return Depressed; diff --git a/OpenRA.Game/Widgets/ChatEntryWidget.cs b/OpenRA.Game/Widgets/ChatEntryWidget.cs index b06d82175d..0d1ce7bdf8 100755 --- a/OpenRA.Game/Widgets/ChatEntryWidget.cs +++ b/OpenRA.Game/Widgets/ChatEntryWidget.cs @@ -64,12 +64,12 @@ namespace OpenRA.Widgets orderManager.IssueOrder(Order.Chat(teamChat, content)); content = ""; - LoseFocus(); + YieldKeyboardFocus(); return true; } else { - TakeFocus(new MouseInput()); + TakeKeyboardFocus(); composing = true; teamChat = (Game.Settings.Game.TeamChatToggle && teamChat) ^ e.Modifiers.HasModifier(Modifiers.Shift); @@ -83,7 +83,7 @@ namespace OpenRA.Widgets { composing = false; content = ""; - LoseFocus(); + YieldKeyboardFocus(); return true; } else if (e.KeyName == "backspace") diff --git a/OpenRA.Game/Widgets/ScrollPanelWidget.cs b/OpenRA.Game/Widgets/ScrollPanelWidget.cs index b88c15b112..4572b18273 100644 --- a/OpenRA.Game/Widgets/ScrollPanelWidget.cs +++ b/OpenRA.Game/Widgets/ScrollPanelWidget.cs @@ -104,7 +104,7 @@ namespace OpenRA.Widgets ButtonWidget.DrawBackground("button", downButtonRect, downDisabled, DownPressed, downHover, false); if (thumbHeight > 0) - ButtonWidget.DrawBackground("scrollthumb", thumbRect, false, Focused && thumbHover, thumbHover, false); + ButtonWidget.DrawBackground("scrollthumb", thumbRect, false, HasMouseFocus && thumbHover, thumbHover, false); var upOffset = !UpPressed || upDisabled ? 4 : 4 + ButtonDepth; var downOffset = !DownPressed || downDisabled ? 4 : 4 + ButtonDepth; @@ -170,10 +170,10 @@ namespace OpenRA.Widgets if (DownPressed) Scroll(-1); } - public override bool LoseFocus (MouseInput mi) + public override bool YieldMouseFocus(MouseInput mi) { UpPressed = DownPressed = ThumbPressed = false; - return base.LoseFocus(mi); + return base.YieldMouseFocus(mi); } int2 lastMouseLocation; @@ -194,14 +194,14 @@ namespace OpenRA.Widgets if (mi.Button != MouseButton.Left) return false; - if (mi.Event == MouseInputEvent.Down && !TakeFocus(mi)) + if (mi.Event == MouseInputEvent.Down && !TakeMouseFocus(mi)) return false; - if (!Focused) + if (!HasMouseFocus) return false; - if (Focused && mi.Event == MouseInputEvent.Up) - return LoseFocus(mi); + if (HasMouseFocus && mi.Event == MouseInputEvent.Up) + return YieldMouseFocus(mi); if (ThumbPressed && mi.Event == MouseInputEvent.Move) { diff --git a/OpenRA.Game/Widgets/SliderWidget.cs b/OpenRA.Game/Widgets/SliderWidget.cs index d172914f8f..563785b506 100755 --- a/OpenRA.Game/Widgets/SliderWidget.cs +++ b/OpenRA.Game/Widgets/SliderWidget.cs @@ -56,14 +56,14 @@ namespace OpenRA.Widgets { if (mi.Button != MouseButton.Left) return false; if (IsDisabled()) return false; - if (mi.Event == MouseInputEvent.Down && !TakeFocus(mi)) return false; - if (!Focused) return false; + if (mi.Event == MouseInputEvent.Down && !TakeMouseFocus(mi)) return false; + if (!HasMouseFocus) return false; switch(mi.Event) { case MouseInputEvent.Up: isMoving = false; - LoseFocus(mi); + YieldMouseFocus(mi); break; case MouseInputEvent.Down: diff --git a/OpenRA.Game/Widgets/TextFieldWidget.cs b/OpenRA.Game/Widgets/TextFieldWidget.cs index fcb1cf5a1b..a4cfe4086f 100644 --- a/OpenRA.Game/Widgets/TextFieldWidget.cs +++ b/OpenRA.Game/Widgets/TextFieldWidget.cs @@ -52,11 +52,10 @@ namespace OpenRA.Widgets VisualHeight = widget.VisualHeight; } - public override bool LoseFocus(MouseInput mi) + public override bool YieldKeyboardFocus() { OnLoseFocus(); - var lose = base.LoseFocus(mi); - return lose; + return base.YieldKeyboardFocus(); } public override bool HandleMouseInput(MouseInput mi) @@ -64,14 +63,11 @@ namespace OpenRA.Widgets if (IsDisabled()) return false; - if (mi.Event == MouseInputEvent.Move) + if (mi.Event != MouseInputEvent.Down) return false; - // Lose focus if they click outside the box; return false so the next widget can grab this event - if (mi.Event == MouseInputEvent.Down && !RenderBounds.Contains(mi.Location) && LoseFocus(mi)) - return false; - - if (mi.Event == MouseInputEvent.Down && !TakeFocus(mi)) + // Attempt to take keyboard focus + if (!RenderBounds.Contains(mi.Location) || !TakeKeyboardFocus()) return false; blinkCycle = 10; @@ -89,7 +85,7 @@ namespace OpenRA.Widgets var textSize = font.Measure(apparentText); var start = RenderOrigin.X + LeftMargin; - if (textSize.X > Bounds.Width - LeftMargin - RightMargin && Focused) + if (textSize.X > Bounds.Width - LeftMargin - RightMargin && HasKeyboardFocus) start += Bounds.Width - LeftMargin - RightMargin - textSize.X; int minIndex = -1; @@ -107,13 +103,11 @@ namespace OpenRA.Widgets public override bool HandleKeyPress(KeyInput e) { - if (IsDisabled()) + if (IsDisabled() || e.Event == KeyInputEvent.Up) return false; - if (e.Event == KeyInputEvent.Up) return false; - // Only take input if we are focused - if (!Focused) + if (!HasKeyboardFocus) return false; if ((e.KeyName == "return" || e.KeyName == "enter") && OnEnterKey()) @@ -206,7 +200,7 @@ namespace OpenRA.Widgets var disabled = IsDisabled(); var state = disabled ? "textfield-disabled" : - Focused ? "textfield-focused" : + HasKeyboardFocus ? "textfield-focused" : Ui.MouseOverWidget == this ? "textfield-hover" : "textfield"; @@ -219,7 +213,7 @@ namespace OpenRA.Widgets // Right align when editing and scissor when the text overflows if (textSize.X > Bounds.Width - LeftMargin - RightMargin) { - if (Focused) + if (HasKeyboardFocus) textPos += new int2(Bounds.Width - LeftMargin - RightMargin - textSize.X, 0); Game.Renderer.EnableScissor(pos.X + LeftMargin, pos.Y, @@ -229,7 +223,7 @@ namespace OpenRA.Widgets var color = disabled ? DisabledColor : TextColor; font.DrawText(apparentText, textPos, color); - if (showCursor && Focused) + if (showCursor && HasKeyboardFocus) font.DrawText("|", new float2(textPos.X + cursorPosition.X - 2, textPos.Y), Color.White); if (textSize.X > Bounds.Width - LeftMargin - RightMargin) diff --git a/OpenRA.Game/Widgets/ViewportScrollControllerWidget.cs b/OpenRA.Game/Widgets/ViewportScrollControllerWidget.cs index 86fa5a39b0..772816ea11 100755 --- a/OpenRA.Game/Widgets/ViewportScrollControllerWidget.cs +++ b/OpenRA.Game/Widgets/ViewportScrollControllerWidget.cs @@ -72,10 +72,10 @@ namespace OpenRA.Widgets public override string GetCursor(int2 pos) { return GetScrollCursor(this, Edge, pos); } - public override bool LoseFocus(MouseInput mi) + public override bool YieldKeyboardFocus() { Keyboard = ScrollDirection.None; - return base.LoseFocus(mi); + return base.YieldKeyboardFocus(); } public override bool HandleKeyPress(KeyInput e) diff --git a/OpenRA.Game/Widgets/Widget.cs b/OpenRA.Game/Widgets/Widget.cs index 6e3264adf8..0e066ec0e0 100644 --- a/OpenRA.Game/Widgets/Widget.cs +++ b/OpenRA.Game/Widgets/Widget.cs @@ -23,7 +23,8 @@ namespace OpenRA.Widgets static Stack WindowList = new Stack(); - public static Widget SelectedWidget; + public static Widget MouseFocusWidget; + public static Widget KeyboardFocusWidget; public static Widget MouseOverWidget; public static void CloseWindow() @@ -74,7 +75,7 @@ namespace OpenRA.Widgets MouseOverWidget = null; bool handled = false; - if (SelectedWidget != null && SelectedWidget.HandleMouseInputOuter(mi)) + if (MouseFocusWidget != null && MouseFocusWidget.HandleMouseInputOuter(mi)) handled = true; if (!handled && Root.HandleMouseInputOuter(mi)) @@ -100,8 +101,8 @@ namespace OpenRA.Widgets public static bool HandleKeyPress(KeyInput e) { - if (SelectedWidget != null) - return SelectedWidget.HandleKeyPressOuter(e); + if (KeyboardFocusWidget != null) + return KeyboardFocusWidget.HandleKeyPressOuter(e); if (Root.HandleKeyPressOuter(e)) return true; @@ -234,31 +235,46 @@ namespace OpenRA.Widgets .Aggregate(EventBounds, Rectangle.Union); } - public bool Focused { get { return Ui.SelectedWidget == this; } } + public bool HasMouseFocus { get { return Ui.MouseFocusWidget == this; } } + public bool HasKeyboardFocus { get { return Ui.KeyboardFocusWidget == this; } } - public virtual bool TakeFocus(MouseInput mi) + public virtual bool TakeMouseFocus(MouseInput mi) { - if (Focused) + if (HasMouseFocus) return true; - if (Ui.SelectedWidget != null && !Ui.SelectedWidget.LoseFocus(mi)) + if (Ui.MouseFocusWidget != null && !Ui.MouseFocusWidget.YieldMouseFocus(mi)) return false; - Ui.SelectedWidget = this; + Ui.MouseFocusWidget = this; return true; } // Remove focus from this widget; return false if you don't want to give it up - public virtual bool LoseFocus(MouseInput mi) + public virtual bool YieldMouseFocus(MouseInput mi) { - // Some widgets may need to override focus depending on mouse click - return LoseFocus(); + if (Ui.MouseFocusWidget == this) + Ui.MouseFocusWidget = null; + + return true; } - public virtual bool LoseFocus() + public virtual bool TakeKeyboardFocus() { - if (Ui.SelectedWidget == this) - Ui.SelectedWidget = null; + if (HasKeyboardFocus) + return true; + + if (Ui.KeyboardFocusWidget != null && !Ui.KeyboardFocusWidget.YieldKeyboardFocus()) + return false; + + Ui.KeyboardFocusWidget = this; + return true; + } + + public virtual bool YieldKeyboardFocus() + { + if (Ui.KeyboardFocusWidget == this) + Ui.KeyboardFocusWidget = null; return true; } @@ -288,7 +304,7 @@ namespace OpenRA.Widgets public bool HandleMouseInputOuter(MouseInput mi) { // Are we able to handle this event? - if (!(Focused || (IsVisible() && GetEventBounds().Contains(mi.Location)))) + if (!(HasMouseFocus || (IsVisible() && GetEventBounds().Contains(mi.Location)))) return false; var oldMouseOver = Ui.MouseOverWidget; diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index e0689c669d..80d981b50a 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -60,7 +60,7 @@ namespace OpenRA.Widgets if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down) { - if (!TakeFocus(mi)) + if (!TakeMouseFocus(mi)) return false; dragStart = dragEnd = xy; @@ -75,13 +75,13 @@ namespace OpenRA.Widgets if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up) { - if (UseClassicMouseStyle && Focused) + if (UseClassicMouseStyle && HasMouseFocus) { //order units around if (!HasBox && world.Selection.Actors.Any() && !MultiClick) { ApplyOrders(world, xy, mi); - LoseFocus(mi); + YieldMouseFocus(mi); return true; } } @@ -108,7 +108,7 @@ namespace OpenRA.Widgets } dragStart = dragEnd = xy; - LoseFocus(mi); + YieldMouseFocus(mi); } if (mi.Button == MouseButton.None && mi.Event == MouseInputEvent.Move) diff --git a/OpenRA.Mods.Cnc/Widgets/CncWorldInteractionControllerWidget.cs b/OpenRA.Mods.Cnc/Widgets/CncWorldInteractionControllerWidget.cs index 107d1768c5..c8485a1379 100644 --- a/OpenRA.Mods.Cnc/Widgets/CncWorldInteractionControllerWidget.cs +++ b/OpenRA.Mods.Cnc/Widgets/CncWorldInteractionControllerWidget.cs @@ -100,10 +100,10 @@ namespace OpenRA.Mods.Cnc.Widgets ?? base.GetCursor(pos); } - public override bool LoseFocus(MouseInput mi) + public override bool YieldKeyboardFocus() { Keyboard = ScrollDirection.None; - return base.LoseFocus(mi); + return base.YieldKeyboardFocus(); } public override bool HandleKeyPress(KeyInput e) diff --git a/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs b/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs index d83f3bd5b7..b618409176 100755 --- a/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs +++ b/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs @@ -208,10 +208,10 @@ namespace OpenRA.Mods.Cnc.Widgets if (rightPressed) Scroll(-1); } - public override bool LoseFocus(MouseInput mi) + public override bool YieldMouseFocus(MouseInput mi) { leftPressed = rightPressed = false; - return base.LoseFocus(mi); + return base.YieldMouseFocus(mi); } public override bool HandleMouseInput(MouseInput mi) @@ -231,14 +231,14 @@ namespace OpenRA.Mods.Cnc.Widgets if (mi.Button != MouseButton.Left) return true; - if (mi.Event == MouseInputEvent.Down && !TakeFocus(mi)) + if (mi.Event == MouseInputEvent.Down && !TakeMouseFocus(mi)) return true; - if (!Focused) + if (!HasMouseFocus) return true; - if (Focused && mi.Event == MouseInputEvent.Up) - return LoseFocus(mi); + if (HasMouseFocus && mi.Event == MouseInputEvent.Up) + return YieldMouseFocus(mi); leftPressed = leftButtonRect.Contains(mi.Location); rightPressed = rightButtonRect.Contains(mi.Location); diff --git a/OpenRA.Mods.RA/Widgets/ColorMixerWidget.cs b/OpenRA.Mods.RA/Widgets/ColorMixerWidget.cs index 8d767ca3f1..96e1ac9e50 100755 --- a/OpenRA.Mods.RA/Widgets/ColorMixerWidget.cs +++ b/OpenRA.Mods.RA/Widgets/ColorMixerWidget.cs @@ -165,16 +165,16 @@ namespace OpenRA.Mods.RA.Widgets { if (mi.Button != MouseButton.Left) return false; - if (mi.Event == MouseInputEvent.Down && !TakeFocus(mi)) + if (mi.Event == MouseInputEvent.Down && !TakeMouseFocus(mi)) return false; - if (!Focused) + if (!HasMouseFocus) return false; switch (mi.Event) { case MouseInputEvent.Up: isMoving = false; - LoseFocus(mi); + YieldMouseFocus(mi); break; case MouseInputEvent.Down: diff --git a/OpenRA.Mods.RA/Widgets/Logic/IngameChatLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/IngameChatLogic.cs index 9dfbf91184..8587827343 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/IngameChatLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/IngameChatLogic.cs @@ -104,14 +104,14 @@ namespace OpenRA.Mods.RA.Widgets.Logic ChatText.Text = ""; ChatOverlay.Visible = false; ChatChrome.Visible = true; - ChatText.TakeFocus(new MouseInput()); + ChatText.TakeKeyboardFocus(); } public void CloseChat() { ChatOverlay.Visible = true; ChatChrome.Visible = false; - ChatText.LoseFocus(); + ChatText.YieldKeyboardFocus(); } public bool IsOpen { get { return ChatChrome.IsVisible(); } } diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs index 23fe2e70a9..5f1e18ae9a 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyUtils.cs @@ -215,23 +215,21 @@ namespace OpenRA.Mods.RA.Widgets.Logic name.IsDisabled = () => orderManager.LocalClient.IsReady; name.Text = c.Name; - name.OnEnterKey = () => + name.OnLoseFocus = () => { name.Text = name.Text.Trim(); if (name.Text.Length == 0) name.Text = c.Name; - name.LoseFocus(); if (name.Text == c.Name) - return true; + return; orderManager.IssueOrder(Order.Command("name " + name.Text)); Game.Settings.Player.Name = name.Text; Game.Settings.Save(); - return true; }; - name.OnLoseFocus = () => name.OnEnterKey(); + name.OnEnterKey = () => { name.YieldKeyboardFocus(); return true; }; } public static void SetupNameWidget(Widget parent, Session.Slot s, Session.Client c) diff --git a/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs index d149a2ef6e..17d13e4465 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs @@ -43,13 +43,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic name.OnLoseFocus = () => { name.Text = name.Text.Trim(); - if (name.Text.Length == 0) name.Text = Game.Settings.Player.Name; else Game.Settings.Player.Name = name.Text; }; - name.OnEnterKey = () => { name.LoseFocus(); return true; }; + name.OnEnterKey = () => { name.YieldKeyboardFocus(); return true; }; var edgescrollCheckbox = general.Get("EDGE_SCROLL"); edgescrollCheckbox.IsChecked = () => Game.Settings.Game.ViewportEdgeScroll; @@ -315,7 +314,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic var textBox = keyWidget.Get("HOTKEY"); textBox.Text = getValue(); - textBox.OnLoseFocus = () => { textBox.Text.Trim(); @@ -324,8 +322,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic else setValue(textBox.Text); }; - - textBox.OnEnterKey = () => { textBox.LoseFocus(); return true; }; + textBox.OnEnterKey = () => { textBox.YieldKeyboardFocus(); return true; }; } public static bool ShowRendererDropdown(DropDownButtonWidget dropdown, GraphicSettings s)