mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 11:06:11 -10:00
Merge pull request #11255 from AlfaRojo/fix/screen-over-playing-releases-keys
A book, sign editor or prompt over the world releases the held buttons
This commit is contained in:
3 files changed
+29
-12
No files matched your search
@@ -8312,7 +8312,7 @@ impl Game<'_> {
|
||||
gameplay_has_keyboard(
|
||||
self.screen,
|
||||
self.title.is_some(),
|
||||
self.dialog_open(),
|
||||
self.screen_over_playing(),
|
||||
),
|
||||
action,
|
||||
) {
|
||||
@@ -8357,8 +8357,11 @@ impl Game<'_> {
|
||||
(_, false) => KeyAction::Press,
|
||||
(_, true) => KeyAction::Repeat,
|
||||
};
|
||||
let screen_open =
|
||||
!gameplay_has_keyboard(self.screen, self.title.is_some(), self.dialog_open());
|
||||
let screen_open = !gameplay_has_keyboard(
|
||||
self.screen,
|
||||
self.title.is_some(),
|
||||
self.screen_over_playing(),
|
||||
);
|
||||
self.toggles.key(slot, action, screen_open, option);
|
||||
self.sync_toggle(slot);
|
||||
if !pressed {
|
||||
@@ -8386,7 +8389,11 @@ impl Game<'_> {
|
||||
fn track_toggle_screens(&mut self) {
|
||||
let dialog = self.dialog_open();
|
||||
drop_held_behind_dialog(dialog, &mut self.keys, &mut self.left, &mut self.right);
|
||||
let playing = gameplay_has_keyboard(self.screen, self.title.is_some(), dialog);
|
||||
let playing = gameplay_has_keyboard(
|
||||
self.screen,
|
||||
self.title.is_some(),
|
||||
self.screen_over_playing(),
|
||||
);
|
||||
if playing == self.was_playing {
|
||||
return;
|
||||
}
|
||||
@@ -22896,10 +22903,13 @@ fn keyboard_button(playing: bool, action: KeyAction) -> Option<bool> {
|
||||
playing.then_some(action != KeyAction::Release)
|
||||
}
|
||||
|
||||
/// Gameplay owns the keyboard: `Screen::Playing`, no title, no server dialog.
|
||||
/// Vanilla's `DialogScreen` is a screen, so `KeyMapping.releaseAll` runs.
|
||||
fn gameplay_has_keyboard(screen: Screen, title: bool, dialog: bool) -> bool {
|
||||
screen == Screen::Playing && !title && !dialog
|
||||
/// Gameplay owns the keyboard: `Screen::Playing`, no title, and nothing open
|
||||
/// over the world (`screen_over_playing`: a server dialog, a book or lectern,
|
||||
/// a sign editor, a prompt). Each is a `Screen` in vanilla, so `Gui.setScreen`
|
||||
/// runs `KeyMapping.releaseAll` and `Minecraft.tick` skips `handleKeybinds`
|
||||
/// while it is up: a mouse button held into it is let go of (#9729).
|
||||
fn gameplay_has_keyboard(screen: Screen, title: bool, screen_over: bool) -> bool {
|
||||
screen == Screen::Playing && !title && !screen_over
|
||||
}
|
||||
|
||||
/// A dialog drops held keys and mouse buttons it does not see (#4974).
|
||||
@@ -23636,8 +23646,10 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// A server dialog is a screen: held keys and the use button are released
|
||||
/// (`KeyMapping.releaseAll`), and toggled sneak comes back when it closes (#4974).
|
||||
/// A server dialog, a book, a sign editor or a prompt over the world is a
|
||||
/// screen: held keys and the mouse buttons are released
|
||||
/// (`KeyMapping.releaseAll`), and toggled sneak comes back when it closes
|
||||
/// (#4974, #9729).
|
||||
#[test]
|
||||
fn a_dialog_releases_held_keys_like_a_screen() {
|
||||
assert!(gameplay_has_keyboard(Screen::Playing, false, false));
|
||||
|
||||
@@ -9046,10 +9046,15 @@ impl Game<'_> {
|
||||
};
|
||||
let mut input = std::mem::take(&mut r.input);
|
||||
let stop = std::mem::take(&mut r.stop_mining);
|
||||
// Minecraft.tick runs handleKeybinds only while `gui.screen() == null`: a
|
||||
// book, a sign editor, a dialog or a prompt over the world (each a
|
||||
// `Screen` in vanilla) stops the attack and use mappings from acting,
|
||||
// and `KeyMapping.releaseAll` let go of the buttons when it opened
|
||||
// (`track_toggle_screens`), so a dig held into a book ends (#9729).
|
||||
let ready = r.loaded_sent
|
||||
&& self.screen == Screen::Playing
|
||||
&& self.sleeping.is_none()
|
||||
&& !self.dialog_open();
|
||||
&& !self.screen_over_playing();
|
||||
// MultiPlayerGameMode.tick, first in Minecraft.tick, screen or not: the slot
|
||||
// chosen since the last tick (the wheel, the last tick's number keys, the
|
||||
// server's SetHeldSlot) goes out before anything else of this tick.
|
||||
|
||||
@@ -47,7 +47,7 @@ struct Settings { keys: Bindings }
|
||||
struct Game { keys: HashSet<i32>, settings: Settings, screen: bool, title: Option<()>, modifiers: u32,
|
||||
open: bool, cancel: bool, calls: Cell<usize>, handled: usize, released: Vec<(bool, i32)> }
|
||||
impl Game {
|
||||
fn dialog_open(&self) -> bool { false }
|
||||
fn screen_over_playing(&self) -> bool { false }
|
||||
fn screen_view_now(&self) -> Option<&'static str> { self.open.then_some("options") }
|
||||
fn native_screen_key_released_pre(&self, screen: &&str, name: &str, modifiers: u32, canceled: &mut bool) {
|
||||
assert_eq!((*screen, name, modifiers), ("options", "key.keyboard.a", 5));
|
||||
|
||||
Reference in new issue
Block a user