mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 11:06:11 -10:00
Clear a container's keyboard focus when it closes
Gui.setScreen runs Screen.clearFocus on the screen it takes down, but Horizon kept the keyboard focus in PadMenu after an inventory closed. The inventory key bound to Tab moves the focus on Tab and then closes the screen in the same press, so the screen it moved on stayed focused: a button was left highlighted after the inventory went away. The remote close path (single player runs on the server thread, remote.rs) never reached close_container and cleared nothing. Clear the focus where the container teardown starts: close_container, the remote menu teardown (remote_close_local), and the Creative screen's two close arms. The focus, the click origin and the slider edit go, as ComponentPath.applyFocus(false) does. Co-Authored-By: OpenCode GLM 5.3 <[email protected]>
This commit is contained in:
1 parent
0de9fbac48
commit
cd18f6c74f
3 files changed
+47
No files matched your search
@@ -9021,6 +9021,10 @@ impl Game<'_> {
|
||||
self.last_inv_click = None;
|
||||
}
|
||||
pub(super) fn close_container(&mut self) {
|
||||
// `Gui.setScreen` clears the old screen's focus before it goes: the
|
||||
// key that closed the container (Tab bound to the inventory) has
|
||||
// already moved the focus, and it must not outlive the screen.
|
||||
self.pad_clear_focus();
|
||||
self.mod_browser_closed();
|
||||
self.reset_inventory_clicks();
|
||||
self.close_station();
|
||||
@@ -15760,6 +15764,7 @@ impl Game<'_> {
|
||||
self.capture(false);
|
||||
}
|
||||
Screen::Creative => {
|
||||
self.pad_clear_focus();
|
||||
self.carried = None;
|
||||
self.screen = Screen::Playing;
|
||||
self.capture(true);
|
||||
@@ -15872,6 +15877,7 @@ impl Game<'_> {
|
||||
}
|
||||
}
|
||||
Screen::Creative => {
|
||||
self.pad_clear_focus();
|
||||
if let Some(c) = self.carried.take() {
|
||||
let _ = self.give(c);
|
||||
}
|
||||
|
||||
@@ -112,6 +112,17 @@ pub(super) struct MenuCursor {
|
||||
key_restart: Option<u64>,
|
||||
}
|
||||
|
||||
impl MenuCursor {
|
||||
/// `Screen.clearFocus`: nothing is focused any more, and no click focus
|
||||
/// is kept for the next Tab (`ComponentPath.applyFocus(false)`).
|
||||
fn clear_focus(&mut self) {
|
||||
self.focus = None;
|
||||
self.origin = None;
|
||||
self.slider_edit = false;
|
||||
self.pending = None;
|
||||
}
|
||||
}
|
||||
|
||||
impl Game<'_> {
|
||||
/// A menu, a screen, the title, a sign or a book is open: the pad drives
|
||||
/// it instead of the player.
|
||||
@@ -1041,6 +1052,15 @@ impl Game<'_> {
|
||||
|| self.ui.options.selected_pad_action.is_some()))
|
||||
}
|
||||
|
||||
/// `Screen.clearFocus`, which `Gui.setScreen` runs on the screen it takes
|
||||
/// down: the keyboard's focus belongs to that screen. A key bound to the
|
||||
/// container's own close key can move the focus and close the screen in
|
||||
/// one press (Tab bound to the inventory), and vanilla clears the focus
|
||||
/// before the next frame, so nothing stays highlighted.
|
||||
pub(super) fn pad_clear_focus(&mut self) {
|
||||
self.pad.menu.clear_focus();
|
||||
}
|
||||
|
||||
/// A key pressed in a menu, before the screen takes it
|
||||
/// (`Screen.keyPressed`): Tab, Shift+Tab and the arrows move the focus,
|
||||
/// Enter, Space and keypad Enter press the focused widget; the focused
|
||||
@@ -1543,6 +1563,23 @@ mod tests {
|
||||
assert!(!osk_auto_opens(false, false, true, 5, false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clear_focus_leaves_nothing_focused() {
|
||||
let mut menu = MenuCursor {
|
||||
focus: Some(Target {
|
||||
rect: [229.0, 98.0, 20.0, 18.0],
|
||||
kind: Kind::Button,
|
||||
}),
|
||||
origin: Some([229.0, 98.0, 20.0, 18.0]),
|
||||
slider_edit: true,
|
||||
..MenuCursor::default()
|
||||
};
|
||||
menu.clear_focus();
|
||||
assert!(menu.focus.is_none());
|
||||
assert!(menu.origin.is_none());
|
||||
assert!(!menu.slider_edit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn field_hit_test() {
|
||||
let t = |rect, kind| Target { rect, kind };
|
||||
|
||||
@@ -9097,6 +9097,10 @@ impl Game<'_> {
|
||||
self.remote_close_local();
|
||||
}
|
||||
fn remote_close_local(&mut self) {
|
||||
// `Gui.setScreen` clears the focus of the screen it takes down: the
|
||||
// container's keyboard focus must not outlive it (a Tab bound to the
|
||||
// inventory moves the focus and closes the container in one press).
|
||||
self.pad_clear_focus();
|
||||
self.recipe_ui.reset_screen();
|
||||
if let Some(r) = self.remote.as_mut() {
|
||||
r.menu = None;
|
||||
|
||||
Reference in new issue
Block a user