mirror of
https://github.com/yusufipk/dikte.git
synced 2026-09-11 10:56:10 +00:00
Merge pull request #65 from dumbovita/fix/agent-doctor-and-wheel
Fix doctor CLI check, inactive wheel focus, and agent shortcut label
This commit is contained in:
+1
-1
@@ -873,7 +873,7 @@ def cmd_doctor(opts):
|
|||||||
# Recording, the device list, and KDE's shortcut registry.
|
# Recording, the device list, and KDE's shortcut registry.
|
||||||
wanted += ["pw-record", "pactl", "kwriteconfig6"]
|
wanted += ["pw-record", "pactl", "kwriteconfig6"]
|
||||||
wanted += ["ffmpeg",
|
wanted += ["ffmpeg",
|
||||||
assistant.executable(assistant.provider(conf)) or "claude",
|
assistant.executable(assistant.provider(conf)),
|
||||||
cleanup.executable(cleanup.provider(conf))]
|
cleanup.executable(cleanup.provider(conf))]
|
||||||
programs = {name: shutil.which(name) or "" for name in wanted if name}
|
programs = {name: shutil.which(name) or "" for name in wanted if name}
|
||||||
target = conf.transcribe_target()
|
target = conf.transcribe_target()
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ SHORTCUTS = {
|
|||||||
"Dikte: pause/resume the recording", "pause_shortcut", ""),
|
"Dikte: pause/resume the recording", "pause_shortcut", ""),
|
||||||
"cancel": Shortcut("cancel", CANCEL_DESKTOP_ID, "Dikte: discard the recording",
|
"cancel": Shortcut("cancel", CANCEL_DESKTOP_ID, "Dikte: discard the recording",
|
||||||
"cancel_shortcut", ""),
|
"cancel_shortcut", ""),
|
||||||
"ask": Shortcut("ask", ASK_DESKTOP_ID, "Dikte: ask Claude Code",
|
"ask": Shortcut("ask", ASK_DESKTOP_ID, "Dikte: ask the agent",
|
||||||
"assistant_shortcut", ""),
|
"assistant_shortcut", ""),
|
||||||
"meeting": Shortcut("meeting", MEETING_DESKTOP_ID,
|
"meeting": Shortcut("meeting", MEETING_DESKTOP_ID,
|
||||||
"Dikte: start/end a meeting recording",
|
"Dikte: start/end a meeting recording",
|
||||||
|
|||||||
@@ -223,7 +223,9 @@ class WheelGuard(QObject):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def eventFilter(self, box, event):
|
def eventFilter(self, box, event):
|
||||||
if event.type() == QEvent.Type.Wheel and not box.hasFocus():
|
win = box.window()
|
||||||
|
focused = box.hasFocus() or (win is not None and win.focusWidget() is box)
|
||||||
|
if event.type() == QEvent.Type.Wheel and not focused:
|
||||||
# Refused rather than swallowed. An unaccepted wheel event carries
|
# Refused rather than swallowed. An unaccepted wheel event carries
|
||||||
# on up the parents to the scroll area, so the page still moves.
|
# on up the parents to the scroll area, so the page still moves.
|
||||||
event.ignore()
|
event.ignore()
|
||||||
|
|||||||
@@ -578,6 +578,21 @@ class Doctor(DikteTest):
|
|||||||
self.run_doctor(as_json=False, cleanup_provider="codex",
|
self.run_doctor(as_json=False, cleanup_provider="codex",
|
||||||
cleanup_codex_model="gpt-5.4"))
|
cleanup_codex_model="gpt-5.4"))
|
||||||
|
|
||||||
|
def test_agent_on_hosted_provider_does_not_ask_for_a_cli_program(self):
|
||||||
|
for provider in ("openrouter", "opencode"):
|
||||||
|
with self.subTest(provider=provider):
|
||||||
|
reply = self.run_doctor(assistant_provider=provider)
|
||||||
|
self.assertEqual(reply["agent"]["provider"], provider)
|
||||||
|
for cli_name in ("claude", "codex", "agy"):
|
||||||
|
self.assertNotIn(cli_name, reply["programs"])
|
||||||
|
|
||||||
|
def test_agent_on_a_cli_asks_for_the_program(self):
|
||||||
|
for provider, binary in (("claude", "claude"), ("codex", "codex"), ("agy", "agy")):
|
||||||
|
with self.subTest(provider=provider):
|
||||||
|
reply = self.run_doctor(assistant_provider=provider)
|
||||||
|
self.assertEqual(reply["agent"]["provider"], provider)
|
||||||
|
self.assertIn(binary, reply["programs"])
|
||||||
|
|
||||||
|
|
||||||
class Devices(DikteTest):
|
class Devices(DikteTest):
|
||||||
def test_a_machine_with_nothing_names_its_own_missing_program(self):
|
def test_a_machine_with_nothing_names_its_own_missing_program(self):
|
||||||
|
|||||||
+46
-1
@@ -16,7 +16,7 @@ from unittest import mock
|
|||||||
|
|
||||||
from PyQt6.QtCore import QPoint, QPointF, QRect, Qt
|
from PyQt6.QtCore import QPoint, QPointF, QRect, Qt
|
||||||
from PyQt6.QtGui import QWheelEvent
|
from PyQt6.QtGui import QWheelEvent
|
||||||
from PyQt6.QtWidgets import QApplication, QMessageBox
|
from PyQt6.QtWidgets import QApplication, QComboBox, QMessageBox, QSpinBox, QWidget
|
||||||
|
|
||||||
from dikte import audio
|
from dikte import audio
|
||||||
from dikte import cleanup
|
from dikte import cleanup
|
||||||
@@ -230,6 +230,51 @@ class Settings(DikteTest):
|
|||||||
QApplication.sendEvent(box, self.wheel())
|
QApplication.sendEvent(box, self.wheel())
|
||||||
self.assertNotEqual(box.currentIndex(), before)
|
self.assertNotEqual(box.currentIndex(), before)
|
||||||
|
|
||||||
|
def test_the_wheel_uses_remembered_focus_in_an_inactive_window(self):
|
||||||
|
# Keep the window hidden so no desktop activation policy can give it
|
||||||
|
# keyboard focus. Its remembered focus still selects the wheel target.
|
||||||
|
for widget_type in (QComboBox, QSpinBox):
|
||||||
|
with self.subTest(widget=widget_type.__name__):
|
||||||
|
window = QWidget()
|
||||||
|
self.addCleanup(window.deleteLater)
|
||||||
|
box = widget_type(window)
|
||||||
|
other = QComboBox(window)
|
||||||
|
if isinstance(box, QComboBox):
|
||||||
|
box.addItems(["first", "second", "third"])
|
||||||
|
box.setCurrentIndex(1)
|
||||||
|
value = box.currentIndex
|
||||||
|
else:
|
||||||
|
box.setValue(5)
|
||||||
|
value = box.value
|
||||||
|
box.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
|
||||||
|
guard = settings_ui.WheelGuard(window)
|
||||||
|
box.installEventFilter(guard)
|
||||||
|
box.setFocus()
|
||||||
|
self.assertFalse(window.isActiveWindow())
|
||||||
|
self.assertFalse(box.hasFocus())
|
||||||
|
self.assertIs(window.focusWidget(), box)
|
||||||
|
before = value()
|
||||||
|
QApplication.sendEvent(box, self.wheel())
|
||||||
|
self.assertNotEqual(value(), before)
|
||||||
|
other.setFocus()
|
||||||
|
self.assertIs(window.focusWidget(), other)
|
||||||
|
before = value()
|
||||||
|
rolled = self.wheel()
|
||||||
|
QApplication.sendEvent(box, rolled)
|
||||||
|
self.assertEqual(value(), before)
|
||||||
|
self.assertFalse(rolled.isAccepted())
|
||||||
|
|
||||||
|
def test_the_wheel_is_refused_when_another_widget_has_focus(self):
|
||||||
|
window = self.window(cfg.Config())
|
||||||
|
box = window.ui_language
|
||||||
|
other = window.corner
|
||||||
|
other.setFocus()
|
||||||
|
before = box.currentIndex()
|
||||||
|
rolled = self.wheel()
|
||||||
|
QApplication.sendEvent(box, rolled)
|
||||||
|
self.assertEqual(box.currentIndex(), before)
|
||||||
|
self.assertFalse(rolled.isAccepted())
|
||||||
|
|
||||||
def test_a_wrapped_label_keeps_the_room_its_lines_need(self):
|
def test_a_wrapped_label_keeps_the_room_its_lines_need(self):
|
||||||
# The program path shares a row with a button, and a row is measured
|
# The program path shares a row with a button, and a row is measured
|
||||||
# before its width is known: the label has to claim the second line back
|
# before its width is known: the label has to claim the second line back
|
||||||
|
|||||||
Reference in New Issue
Block a user