diff --git a/croppa/main.py b/croppa/main.py index 08cb4ce..f81e38e 100644 --- a/croppa/main.py +++ b/croppa/main.py @@ -104,6 +104,7 @@ class VideoEditor: self.auto_repeat_shift = False self.auto_repeat_ctrl = False self.last_display_update = 0 + self.last_key_activity = 0 # Track when key was last detected # Crop settings self.crop_rect = None # (x, y, width, height) @@ -519,29 +520,36 @@ class VideoEditor: if self.is_image_mode: return - # If the same key is already being auto-repeated, don't restart + current_time = time.time() + + # If the same key is already being auto-repeated, just update the last activity time if (self.auto_repeat_active and self.auto_repeat_key == key and self.auto_repeat_direction == direction and self.auto_repeat_shift == shift_pressed and self.auto_repeat_ctrl == ctrl_pressed): - # Just update the last seek time to prevent timeout - self.last_seek_time = time.time() + # Update last activity time to keep auto-repeat alive + self.last_seek_time = current_time return + # Start new auto-repeat self.auto_repeat_active = True self.auto_repeat_key = key self.auto_repeat_direction = direction self.auto_repeat_shift = shift_pressed self.auto_repeat_ctrl = ctrl_pressed - self.key_first_press_time = time.time() - self.last_seek_time = time.time() # Initialize to current time + self.key_first_press_time = current_time + self.last_seek_time = current_time + self.last_key_activity = current_time # Do initial seek immediately self.seek_video_with_modifier(direction, shift_pressed, ctrl_pressed) + print(f"DEBUG: Started auto-repeat for key {key}") def stop_auto_repeat_seek(self): """Stop auto-repeat seeking""" + if self.auto_repeat_active: + print(f"DEBUG: Stopped auto-repeat") self.auto_repeat_active = False self.auto_repeat_key = None self.auto_repeat_direction = 0 @@ -1815,20 +1823,29 @@ class VideoEditor: if self.should_update_display(): self.display_current_frame() - delay = self.calculate_frame_delay() if self.is_playing else 30 + delay = self.calculate_frame_delay() if self.is_playing else 1 # Very short delay for responsive key detection key = cv2.waitKey(delay) & 0xFF + # Debug key detection + if key != 255: + print(f"DEBUG: Key detected: {key} (auto_repeat_active: {self.auto_repeat_active}, auto_repeat_key: {self.auto_repeat_key})") + # Handle auto-repeat - stop if a different key is pressed or no key for too long if key == 255 and self.auto_repeat_active: # 255 means no key pressed - # Check if enough time has passed since last key press - if time.time() - self.last_seek_time > 1.0: # 1 second timeout + # Check if enough time has passed since last key activity (key was released) + if time.time() - self.last_key_activity > 0.1: # 100ms timeout + print(f"DEBUG: Key released - stopping auto-repeat") self.stop_auto_repeat_seek() elif key != 255 and self.auto_repeat_active: - # A key is pressed, update the last seek time to prevent timeout - self.last_seek_time = time.time() + # A key is pressed, update the last key activity time + self.last_key_activity = time.time() # If it's a different key, stop auto-repeat if key != self.auto_repeat_key: + print(f"DEBUG: Different key pressed ({key} vs {self.auto_repeat_key}) - stopping auto-repeat") self.stop_auto_repeat_seek() + # If it's the same key, just update the last activity time (don't restart auto-repeat) + else: + print(f"DEBUG: Same key pressed ({key}) - updating last activity time") # Get modifier key states window_title = "Image Editor" if self.is_image_mode else "Video Editor" @@ -1850,25 +1867,37 @@ class VideoEditor: if not self.is_image_mode: # Check if it's uppercase A (Shift+A) if key == ord("A"): - self.start_auto_repeat_seek(key, -1, True, False) # Shift+A: -10 frames + # Only start auto-repeat if not already active for this key + if not (self.auto_repeat_active and self.auto_repeat_key == key): + self.start_auto_repeat_seek(key, -1, True, False) # Shift+A: -10 frames else: - self.start_auto_repeat_seek(key, -1, False, False) # A: -1 frame + # Only start auto-repeat if not already active for this key + if not (self.auto_repeat_active and self.auto_repeat_key == key): + self.start_auto_repeat_seek(key, -1, False, False) # A: -1 frame elif key == ord("d") or key == ord("D"): # Seeking only for videos if not self.is_image_mode: # Check if it's uppercase D (Shift+D) if key == ord("D"): - self.start_auto_repeat_seek(key, 1, True, False) # Shift+D: +10 frames + # Only start auto-repeat if not already active for this key + if not (self.auto_repeat_active and self.auto_repeat_key == key): + self.start_auto_repeat_seek(key, 1, True, False) # Shift+D: +10 frames else: - self.start_auto_repeat_seek(key, 1, False, False) # D: +1 frame + # Only start auto-repeat if not already active for this key + if not (self.auto_repeat_active and self.auto_repeat_key == key): + self.start_auto_repeat_seek(key, 1, False, False) # D: +1 frame elif key == 1: # Ctrl+A # Seeking only for videos if not self.is_image_mode: - self.start_auto_repeat_seek(key, -1, False, True) # Ctrl+A: -60 frames + # Only start auto-repeat if not already active for this key + if not (self.auto_repeat_active and self.auto_repeat_key == key): + self.start_auto_repeat_seek(key, -1, False, True) # Ctrl+A: -60 frames elif key == 4: # Ctrl+D # Seeking only for videos if not self.is_image_mode: - self.start_auto_repeat_seek(key, 1, False, True) # Ctrl+D: +60 frames + # Only start auto-repeat if not already active for this key + if not (self.auto_repeat_active and self.auto_repeat_key == key): + self.start_auto_repeat_seek(key, 1, False, True) # Ctrl+D: +60 frames elif key == ord("-") or key == ord("_"): self.rotate_clockwise() print(f"Rotated to {self.rotation_angle}°")