Let the hotkey toggle the common PTT latch without a second latch state
This commit is contained in:
1 parent
3d0f3213f8
commit
d25d097287
3 files changed
+28
-30
No files matched your search
@@ -24,6 +24,7 @@ PttHotkeyManager* PttHotkeyManager::instance() {
|
||||
|
||||
PttHotkeyManager::PttHotkeyManager() : QObject(qApp) {
|
||||
m_clock.start();
|
||||
connect(RadioAudioEngine::instance(), &RadioAudioEngine::pttLatchChanged, this, [this]() { m_activation.reset(); });
|
||||
connect(RadioAudioEngine::instance(), &RadioAudioEngine::stateChanged, this, [this]() {
|
||||
auto* engine = RadioAudioEngine::instance();
|
||||
if (!engine->isActive() || !engine->captureAvailable())
|
||||
@@ -113,23 +114,23 @@ void PttHotkeyManager::updatePressed(bool pressed) {
|
||||
return;
|
||||
}
|
||||
if (m_activation.pressed == pressed) return;
|
||||
bool latched = m_activation.latched;
|
||||
m_activation.observe(pressed, m_clock.elapsed(), m_doublePressEnabled ? QApplication::doubleClickInterval() : 0);
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_RADIO, "PTT: shortcut pressed=%d latched=%d talking=%d group=%016llx",
|
||||
pressed, m_activation.latched, m_activation.talking, (unsigned long long)engine->groupId());
|
||||
if (latched != m_activation.latched)
|
||||
DEBUG_INFO(DEBUG_CATEGORY_RADIO, "PTT: shortcut %s group=%016llx", m_activation.latched ? "locked" : "unlocked",
|
||||
(unsigned long long)engine->groupId());
|
||||
engine->setHotkeyTalking(m_activation.talking);
|
||||
bool doublePress = m_activation.observe(pressed, m_clock.elapsed(), m_doublePressEnabled ? QApplication::doubleClickInterval() : 0);
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_RADIO, "PTT: shortcut pressed=%d double_press=%d latched=%d group=%016llx",
|
||||
pressed, doublePress, engine->pttLatched(), (unsigned long long)engine->groupId());
|
||||
if (pressed && engine->pttLatched()) engine->setPttLatched(false, "shortcut-pressed");
|
||||
else if (doublePress) engine->setPttLatched(true, "shortcut-double-press");
|
||||
else engine->setHotkeyTalking(pressed);
|
||||
}
|
||||
|
||||
/* Сброс не превращает ещё удерживаемую клавишу в новое нажатие после восстановления рации. */
|
||||
void PttHotkeyManager::resetHotkey(const char* reason) {
|
||||
if (m_activation.talking || m_activation.latched || m_activation.lastPress >= 0)
|
||||
DEBUG_INFO(DEBUG_CATEGORY_RADIO, "PTT: shortcut reset reason=%s pressed=%d latched=%d talking=%d",
|
||||
reason, m_activation.pressed, m_activation.latched, m_activation.talking);
|
||||
if (m_activation.pressed || m_activation.lastPress >= 0)
|
||||
DEBUG_INFO(DEBUG_CATEGORY_RADIO, "PTT: shortcut reset reason=%s pressed=%d double_press_pending=%d",
|
||||
reason, m_activation.pressed, m_activation.lastPress >= 0);
|
||||
m_activation.reset();
|
||||
RadioAudioEngine::instance()->setHotkeyTalking(false);
|
||||
auto* engine = RadioAudioEngine::instance();
|
||||
engine->setPttLatched(false, reason);
|
||||
engine->setHotkeyTalking(false);
|
||||
}
|
||||
|
||||
bool PttHotkeyManager::readKeys(PttKeyChord& held) const {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Все методы/сигналы — GUI-поток, singleton принадлежит qApp; init вызывается после открытия БД.
|
||||
* DbManager заимствуется. Одно сочетание читается из ui_state radio_ptt_hotkey; сохранение выполняет вызывающий.
|
||||
* Удержание передаёт; radio_ptt_double_press (по умолчанию 1) разрешает фиксацию двойным нажатием до следующего нажатия.
|
||||
* Wayland-комбинациями владеет портал. Менеджер меняет только hotkey-владельца PTT, не кнопку и не автоматическую передачу. */
|
||||
* Wayland-комбинациями владеет портал. Общим замком кнопки/хоткея владеет RadioAudioEngine; VAD от замка не зависит. */
|
||||
#pragma once
|
||||
|
||||
#include "ptt_key_chord.h"
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
/* Применяет одно физическое сочетание в памяти, снимая удержание/фиксацию; невалидное значение отключает хоткей.
|
||||
* В режиме портала ничего не делает; БД не меняет. */
|
||||
void setHotkey(const QString& chord);
|
||||
/* Включает фиксацию двойным нажатием только для хоткея; изменение сбрасывает его текущее PTT, БД не меняет. */
|
||||
/* Включает двойное нажатие только для хоткея; изменение снимает общую фиксацию/удержание хоткея, БД не меняет. */
|
||||
void setDoublePressEnabled(bool enabled);
|
||||
/* Загружает radio_ptt_hotkey и radio_ptt_double_press; без БД — пустое сочетание и разрешённая фиксация. */
|
||||
void reload();
|
||||
@@ -65,8 +65,8 @@ private:
|
||||
void pollKeys(); /* Обновляет hotkey-PTT/запись; ошибка чтения отключает PTT и останавливает таймер. */
|
||||
bool readKeys(PttKeyChord& held) const; /* Добавляет нажатые коды в изначально пустой held; false при отказе backend. */
|
||||
QString keyName(int key) const; /* Имя кода ОС либо локализованный запасной вариант Key N. */
|
||||
void updatePressed(bool pressed); // Общие фронты Windows/X11/Wayland; меняет только hotkey-владельца PTT.
|
||||
void resetHotkey(const char* reason); // Снимает передачу/фиксацию и историю кликов, логируя причину сброса.
|
||||
void updatePressed(bool pressed); // Фронты Windows/X11/Wayland: удержание, установка/снятие общего замка.
|
||||
void resetHotkey(const char* reason); // Снимает общую фиксацию, удержание хоткея и историю кликов с причиной в логе.
|
||||
|
||||
#ifdef UTUN_PTT_PORTAL
|
||||
PttPortal* m_portal = nullptr; /* Дочерняя portal-сессия, создаётся только для выбранного Wayland-режима. */
|
||||
@@ -78,7 +78,7 @@ private:
|
||||
PttKeyChord m_held; // Последний снимок ОС, не конфигурация сочетания.
|
||||
bool m_capturing = false; // Идёт ручная запись вместо вычисления hotkey-PTT.
|
||||
bool m_captureArmed = false; // Исходные клавиши полностью отпущены, можно выдавать keysChanged.
|
||||
PttHotkeyState m_activation; // Общая для всех backend логика удержания/двойного нажатия.
|
||||
PttHotkeyState m_activation; // Физическое состояние и история двойного нажатия; собственной фиксации нет.
|
||||
QElapsedTimer m_clock; // Монотонные мс для двойного нажатия, запускаются в конструкторе.
|
||||
bool m_doublePressEnabled = true; // radio_ptt_double_press: кнопка PTT от этой настройки не зависит.
|
||||
};
|
||||
@@ -1,26 +1,23 @@
|
||||
/* Состояние одного PTT-хоткея: удержание передаёт, двойное нажатие фиксирует, следующее снимает фиксацию.
|
||||
/* Распознавание двойного нажатия одного PTT-хоткея; общим замком владеет RadioAudioEngine.
|
||||
* observe получает полное состояние сочетания и монотонное время в мс; повторы одного состояния игнорируются.
|
||||
* reset снимает передачу и историю двойного нажатия, требуя отпускания уже удерживаемого сочетания. */
|
||||
* reset снимает историю двойного нажатия, сохраняя физическое состояние сочетания. */
|
||||
#pragma once
|
||||
#include <QtGlobal>
|
||||
|
||||
struct PttHotkeyState {
|
||||
bool pressed = false; // Последнее физическое состояние, включая нажатие, снявшее фиксацию.
|
||||
bool latched = false; // Фиксация до нового нажатия либо reset.
|
||||
bool talking = false; // Запрос передачи этого хоткея, независимый от кнопки и автоматики.
|
||||
qint64 lastPress = -1; // Начало первого нажатия в мс, -1 — двойное нажатие не ожидается.
|
||||
|
||||
/* Обновляет состояние по фронтам; interval — системный интервал двойного клика в мс. */
|
||||
void observe(bool held, qint64 now, int interval) {
|
||||
if (pressed == held) return;
|
||||
/* true только на втором нажатии пары; interval — системный интервал в мс, 0 отключает распознавание. */
|
||||
bool observe(bool held, qint64 now, int interval) {
|
||||
if (pressed == held) return false;
|
||||
pressed = held;
|
||||
if (!held) { talking = latched; return; }
|
||||
if (latched) { reset(); return; }
|
||||
latched = lastPress >= 0 && now - lastPress < interval;
|
||||
talking = true;
|
||||
lastPress = latched ? -1 : now;
|
||||
if (!held) return false;
|
||||
bool doublePress = lastPress >= 0 && now - lastPress < interval;
|
||||
lastPress = doublePress ? -1 : now;
|
||||
return doublePress;
|
||||
}
|
||||
|
||||
/* Сохраняет pressed, чтобы удерживаемый при сбросе хоткей не включил передачу снова. */
|
||||
void reset() { latched = talking = false; lastPress = -1; }
|
||||
void reset() { lastPress = -1; }
|
||||
};
|
||||
Reference in new issue
Block a user