From f91082186c6cb85364bf2cdba61324a902a954c0 Mon Sep 17 00:00:00 2001 From: David Gwilliam Date: Mon, 23 Mar 2026 17:02:40 -0700 Subject: [PATCH] Fix scroll direction inversion in REPL Fixed the scroll direction bug where PageUp/PageDown were inverted: - page_up now scrolls UP (back in time) with positive delta (+10) - page_down now scrolls DOWN (forward in time) with negative delta (-10) - Mouse wheel up/down also fixed with same logic (+3/-3) The scroll logic in scroll_output() was correct (positive = scroll up), but the key handlers in both main.py and pipeline_runner.py had the signs inverted. --- engine/app/main.py | 12 ++++++++---- engine/app/pipeline_runner.py | 27 +++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/engine/app/main.py b/engine/app/main.py index 4f0f35a..1fd5525 100644 --- a/engine/app/main.py +++ b/engine/app/main.py @@ -576,9 +576,13 @@ def run_pipeline_mode_direct(): elif key == "down": repl_effect.navigate_history(1) elif key == "page_up": - repl_effect.scroll_output(-10) # Scroll up 10 lines + repl_effect.scroll_output( + 10 + ) # Positive = scroll UP (back in time) elif key == "page_down": - repl_effect.scroll_output(10) # Scroll down 10 lines + repl_effect.scroll_output( + -10 + ) # Negative = scroll DOWN (forward in time) elif key == "backspace": repl_effect.backspace() elif key.startswith("mouse:"): @@ -587,9 +591,9 @@ def run_pipeline_mode_direct(): if len(parts) >= 2: button = int(parts[1]) if button == 64: # Wheel up - repl_effect.scroll_output(-3) # Scroll up 3 lines + repl_effect.scroll_output(3) # Positive = scroll UP elif button == 65: # Wheel down - repl_effect.scroll_output(3) # Scroll down 3 lines + repl_effect.scroll_output(-3) # Negative = scroll DOWN elif len(key) == 1: repl_effect.append_to_command(key) # --- End REPL Input Handling --- diff --git a/engine/app/pipeline_runner.py b/engine/app/pipeline_runner.py index 977e273..0604fdc 100644 --- a/engine/app/pipeline_runner.py +++ b/engine/app/pipeline_runner.py @@ -937,6 +937,21 @@ def run_pipeline_mode(preset_name: str = "demo", graph_config: str | None = None params.viewport_width = current_width params.viewport_height = current_height + # Check for REPL effect in pipeline + repl_effect = None + for stage in pipeline.stages.values(): + if isinstance(stage, EffectPluginStage) and stage._effect.name == "repl": + repl_effect = stage._effect + print( + " \033[38;5;46mREPL effect detected - Interactive mode enabled\033[0m" + ) + break + + # Enable raw mode for REPL if present and not already enabled + # Also enable for UI border mode (already handled above) + if repl_effect and ui_panel is None and hasattr(display, "set_raw_mode"): + display.set_raw_mode(True) + try: frame = 0 while True: @@ -1017,9 +1032,13 @@ def run_pipeline_mode(preset_name: str = "demo", graph_config: str | None = None elif key == "down": repl_effect.navigate_history(1) elif key == "page_up": - repl_effect.scroll_output(-10) # Scroll up 10 lines + repl_effect.scroll_output( + 10 + ) # Positive = scroll UP (back in time) elif key == "page_down": - repl_effect.scroll_output(10) # Scroll down 10 lines + repl_effect.scroll_output( + -10 + ) # Negative = scroll DOWN (forward in time) elif key == "backspace": repl_effect.backspace() elif key.startswith("mouse:"): @@ -1028,9 +1047,9 @@ def run_pipeline_mode(preset_name: str = "demo", graph_config: str | None = None if len(parts) >= 2: button = int(parts[1]) if button == 64: # Wheel up - repl_effect.scroll_output(-3) # Scroll up 3 lines + repl_effect.scroll_output(3) # Positive = scroll UP elif button == 65: # Wheel down - repl_effect.scroll_output(3) # Scroll down 3 lines + repl_effect.scroll_output(-3) # Negative = scroll DOWN elif len(key) == 1: repl_effect.append_to_command(key) # --- End REPL Input Handling ---