Fixed double mouse lock logic

This commit is contained in:
2026-06-13 19:32:39 +02:00
parent d584e418f5
commit a585dff09d
+14 -15
View File
@@ -280,13 +280,12 @@ impl App {
let PhysicalKey::Code(code) = key.physical_key else { return; }; let PhysicalKey::Code(code) = key.physical_key else { return; };
let down = key.state == ElementState::Pressed; let down = key.state == ElementState::Pressed;
// Escape: erst die (Flycam-)Maus freigeben; sonst das Menü // Escape togglet das Menü über denselben exec-Trichter wie Konsole
// umschalten — über denselben exec-Trichter wie Konsole und Klick. // und Klick. Der Lock-Zustand folgt danach automatisch dem Modus
// Im Dialog tut Escape nichts (der Dialog endet über seine Choices). // (siehe redraw). Im Dialog tut Escape nichts (Dialog endet über
// seine Choices).
if code == KeyCode::Escape && down { if code == KeyCode::Escape && down {
if self.input.grabbed { if !matches!(self.session.mode, Mode::Dialog(_)) {
self.set_grab(false);
} else if !matches!(self.session.mode, Mode::Dialog(_)) {
let r = self.session.exec("menu"); let r = self.session.exec("menu");
for out in r.output { println!("{out}"); } for out in r.output { println!("{out}"); }
if r.quit { event_loop.exit(); } if r.quit { event_loop.exit(); }
@@ -311,16 +310,18 @@ impl App {
let now = Instant::now(); let now = Instant::now();
let dt = self.last.replace(now).map_or(0.0, |prev| (now - prev).as_secs_f32()); let dt = self.last.replace(now).map_or(0.0, |prev| (now - prev).as_secs_f32());
if matches!(self.session.mode, Mode::Free) { // Lock-Zustand folgt dem Modus: nur in Free ist die Flycam aktiv
// (Maus gefangen, relativer Blick). Menü/Dialog geben die Maus frei
// fürs UI. So gibt es keine parallele Lock-Logik mehr.
let fly = matches!(self.session.mode, Mode::Free);
if fly != self.input.grabbed { self.set_grab(fly); }
if fly {
self.camera.apply_mouse(self.input.mouse_dx, self.input.mouse_dy, MOUSE_SENS); self.camera.apply_mouse(self.input.mouse_dx, self.input.mouse_dy, MOUSE_SENS);
let fwd = axis(self.input.fwd, self.input.back); let fwd = axis(self.input.fwd, self.input.back);
let right = axis(self.input.right, self.input.left); let right = axis(self.input.right, self.input.left);
let up = axis(self.input.up, self.input.down); let up = axis(self.input.up, self.input.down);
self.camera.translate(fwd, right, up, MOVE_SPEED * dt); self.camera.translate(fwd, right, up, MOVE_SPEED * dt);
} else if self.input.grabbed {
// Nicht-Free (Dialog/Menü) → Maus freigeben, damit das UI klickbar
// ist und der Maus-Cursor statt des HUD-Pointers erscheint.
self.set_grab(false);
} }
// Delta immer verwerfen, auch im Dialog — sonst springt der Blick // Delta immer verwerfen, auch im Dialog — sonst springt der Blick
// beim Fortsetzen um die aufgestaute Bewegung. // beim Fortsetzen um die aufgestaute Bewegung.
@@ -342,16 +343,14 @@ impl App {
); );
// Vorgemerkten Klick auflösen: über einem Klickziel → dessen Aktion // Vorgemerkten Klick auflösen: über einem Klickziel → dessen Aktion
// durch denselben exec-Trichter wie die Konsole; sonst im Free-Modus // durch denselben exec-Trichter wie die Konsole. Klick in der freien
// die Maus für die Flycam greifen. // Welt tut (noch) nichts — hier käme später der `use`-Raycast.
if self.pending_click { if self.pending_click {
self.pending_click = false; self.pending_click = false;
if let Some(action) = screen.hover_action.clone() { if let Some(action) = screen.hover_action.clone() {
let r = self.session.exec(&action); let r = self.session.exec(&action);
for out in r.output { println!("{out}"); } for out in r.output { println!("{out}"); }
if r.quit { event_loop.exit(); } if r.quit { event_loop.exit(); }
} else if matches!(self.session.mode, Mode::Free) && !self.input.grabbed {
self.set_grab(true);
} }
} }