Add keyboard shortcuts

* spacebar: play/pause
* f: toggle full screen
* enter: focus chat
* horizontal arrows: +- 5s seek
* vertical arrows: +- volume
* m: mute
This commit is contained in:
Peter Stockings
2026-03-04 23:06:01 +11:00
parent 6a8dc7e5e6
commit d1a87e004e
2 changed files with 79 additions and 1 deletions

View File

@@ -209,6 +209,12 @@ class RoomWidget(QWidget):
layout.addWidget(video_container, 1)
layout.addWidget(self.chat_container)
# Prevent UI components from stealing focus (which breaks spacebar shortcuts)
for w in [self.copy_code_btn, self.leave_btn, self.play_btn, self.fullscreen_btn,
self.chat_send_btn, self.seekbar, self.volume_slider, self.chat_messages]:
w.setFocusPolicy(Qt.FocusPolicy.NoFocus)
self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
# Instantiate the VLC Player Wrapper
self.vlc_player = VLCSyncPlayer(self.video_frame)
self.vlc_player.signals.time_changed.connect(self.on_vlc_time)
@@ -259,6 +265,77 @@ class RoomWidget(QWidget):
self.chat_container.hide()
self.topbar.hide()
def toggle_mute(self):
current_vol = self.vlc_player.get_volume()
if current_vol > 0:
self._last_volume = current_vol
self.on_volume_changed(0)
self.volume_slider.setValue(0)
else:
vol = getattr(self, '_last_volume', 100)
self.on_volume_changed(vol)
self.volume_slider.setValue(vol)
def seek_relative(self, offset_ms):
length_ms = self.vlc_player.get_length()
if length_ms > 0:
current_ms = self.vlc_player.current_time_ms
target_ms = max(0, min(current_ms + offset_ms, length_ms))
req = self._tell_vlc_and_expect("seek", target_ms / 1000.0)
self.sync_action_requested.emit("seek", target_ms / 1000.0, req)
def change_volume(self, offset):
new_vol = max(0, min(100, self.volume_slider.value() + offset))
self.volume_slider.setValue(new_vol)
self.on_volume_changed(new_vol)
def mousePressEvent(self, event):
self.setFocus()
super().mousePressEvent(event)
def keyPressEvent(self, event):
# Allow typing in input fields without triggering shortcuts
focus_widget = QApplication.focusWidget()
if isinstance(focus_widget, QLineEdit) or isinstance(focus_widget, QTextEdit):
if event.key() == Qt.Key.Key_Escape:
focus_widget.clearFocus()
self.setFocus()
event.accept()
else:
super().keyPressEvent(event)
return
if event.key() == Qt.Key.Key_Space:
self.toggle_playback()
event.accept()
elif event.key() == Qt.Key.Key_F:
self.toggle_fullscreen()
event.accept()
elif event.key() == Qt.Key.Key_M:
self.toggle_mute()
event.accept()
elif event.key() == Qt.Key.Key_Left:
self.seek_relative(-5000)
event.accept()
elif event.key() == Qt.Key.Key_Right:
self.seek_relative(5000)
event.accept()
elif event.key() == Qt.Key.Key_Up:
self.change_volume(5)
event.accept()
elif event.key() == Qt.Key.Key_Down:
self.change_volume(-5)
event.accept()
elif event.key() == Qt.Key.Key_Escape:
if self.window().isFullScreen():
self.toggle_fullscreen()
event.accept()
elif event.key() in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
self.chat_input.setFocus()
event.accept()
else:
super().keyPressEvent(event)
def copy_room_code(self):
if self.room_code:
QApplication.clipboard().setText(self.room_code)