feat: add Push-To-Talk feature (#116)

This commit is contained in:
Curve 2021-03-31 16:44:23 +02:00
parent 52518e173c
commit 40f0740638
No known key found for this signature in database
GPG Key ID: 460F6C466BD35813
8 changed files with 91 additions and 26 deletions

View File

@ -58,7 +58,7 @@ if (UNIX)
find_package(PkgConfig REQUIRED)
pkg_check_modules(WNCK libwnck-3.0)
target_link_libraries(soundux PRIVATE ${X11_LIBRARIES} ${X11_Xinput_LIB})
target_link_libraries(soundux PRIVATE ${X11_LIBRARIES} ${X11_Xinput_LIB} ${X11_XTest_LIB})
if (${WNCK_FOUND})
add_definitions(${WNCK_CFLAGS})

View File

@ -70,6 +70,7 @@ namespace Soundux
struct Settings
{
std::vector<int> stopHotkey;
std::vector<int> pushToTalkKeys;
SortMode sortMode = SortMode::ModifiedDate_Descending;
bool useAsDefaultDevice = false;
bool muteDuringPlayback = false;

View File

@ -26,6 +26,10 @@ namespace Soundux
void onKeyUp(int);
void onKeyDown(int);
void pressKeys(const std::vector<int> &);
void releaseKeys(const std::vector<int> &);
std::string getKeyName(const int &);
std::string getKeySequence(const std::vector<int> &);
};

View File

@ -5,6 +5,7 @@
#include <X11/Xlib.h>
#include <X11/extensions/XI2.h>
#include <X11/extensions/XInput2.h>
#include <X11/extensions/XTest.h>
#include <chrono>
#include <cstdlib>
#include <fancy.hpp>
@ -120,6 +121,22 @@ namespace Soundux::Objects
kill = true;
listener.join();
}
void Hotkeys::pressKeys(const std::vector<int> &keys)
{
for (const auto &key : keys)
{
XTestFakeKeyEvent(display, key, True, 0);
}
}
void Hotkeys::releaseKeys(const std::vector<int> &keys)
{
for (const auto &key : keys)
{
XTestFakeKeyEvent(display, key, False, 0);
}
}
} // namespace Soundux::Objects
#endif

View File

@ -120,5 +120,21 @@ namespace Soundux::Objects
return name;
}
void Hotkeys::pressKeys(const std::vector<int> &keys)
{
for (const auto &key : keys)
{
keybd_event(key, 0, 0, 0);
}
}
void Hotkeys::releaseKeys(const std::vector<int> &keys)
{
for (const auto &key : keys)
{
keybd_event(key, 0, KEYEVENTF_KEYUP, 0);
}
}
} // namespace Soundux::Objects
#endif

View File

@ -79,6 +79,7 @@ namespace nlohmann
{"syncVolumes", obj.syncVolumes},
{"selectedTab", obj.selectedTab},
{"launchPadMode", obj.launchPadMode},
{"pushToTalkKeys", obj.pushToTalkKeys},
{"tabHotkeysOnly", obj.tabHotkeysOnly},
{"minimizeToTray", obj.minimizeToTray},
{"remoteVolume", obj.remoteVolume},
@ -118,6 +119,10 @@ namespace nlohmann
{
j.at("minimizeToTray").get_to(obj.minimizeToTray);
}
if (j.find("pushToTalkKeys") != j.end())
{
j.at("pushToTalkKeys").get_to(obj.pushToTalkKeys);
}
}
};
template <> struct adl_serializer<Soundux::Objects::Tab>

View File

@ -141,6 +141,10 @@ namespace Soundux::Objects
{
Globals::gPulse.muteLoopback(true);
}
if (!Globals::gSettings.pushToTalkKeys.empty())
{
Globals::gHotKeys.pressKeys(Globals::gSettings.pushToTalkKeys);
}
if (Globals::gSettings.output.empty() && !Globals::gSettings.useAsDefaultDevice)
{
@ -190,6 +194,11 @@ namespace Soundux::Objects
auto sound = Globals::gData.getSound(id);
auto device = Globals::gAudio.getAudioDevice(Globals::gSettings.output);
if (!Globals::gSettings.pushToTalkKeys.empty())
{
Globals::gHotKeys.pressKeys(Globals::gSettings.pushToTalkKeys);
}
if (sound && (Globals::gSettings.output.empty() || (device && device->get().isDefault)))
{
if (!Globals::gSettings.allowOverlapping)
@ -390,23 +399,18 @@ namespace Soundux::Objects
Globals::gAudio.stop(*remoteSoundId);
}
#if defined(__linux__)
if (Globals::gAudio.getPlayingSounds().empty() && !Globals::gSettings.useAsDefaultDevice)
if (Globals::gAudio.getPlayingSounds().empty())
{
if (!Globals::gPulse.moveBackCurrentApplications())
{
Fancy::fancy.logTime().failure()
<< "Failed to move back current application, sound: " << id << std::endl;
onError(ErrorCode::FailedToMoveBack);
}
onAllSoundsFinished();
}
#endif
return status;
}
void Window::stopSounds()
{
Globals::gQueue.push_unique(0, []() { Globals::gAudio.stopAll(); });
onAllSoundsFinished();
#if defined(__linux__)
if (!Globals::gPulse.moveBackCurrentApplications())
{
@ -609,23 +613,10 @@ namespace Soundux::Objects
}
lock.unlock();
#if defined(__linux__)
if (Globals::gAudio.getPlayingSounds().size() == 1)
{
if (Globals::gSettings.muteDuringPlayback)
{
Globals::gPulse.muteLoopback(false);
}
if (!Globals::gPulse.currentlyPassingthrough())
{
if (!Globals::gPulse.moveBackCurrentApplications())
{
Fancy::fancy.logTime().failure() << "Failed to move back current application" << std::endl;
onError(ErrorCode::FailedToMoveBack);
}
}
onAllSoundsFinished();
}
#endif
}
std::vector<Sound> Window::getFavourites()
{
@ -635,4 +626,33 @@ namespace Soundux::Objects
{
return Globals::gData.markFavorite(id, favourite);
}
void Window::onAllSoundsFinished()
{
if (!Globals::gSettings.pushToTalkKeys.empty())
{
Globals::gHotKeys.releaseKeys(Globals::gSettings.pushToTalkKeys);
}
#if defined(__linux__)
if (Globals::gSettings.muteDuringPlayback)
{
Globals::gPulse.muteLoopback(false);
}
if (!Globals::gPulse.currentlyPassingthrough())
{
if (!Globals::gPulse.moveBackCurrentApplications())
{
Fancy::fancy.logTime().failure() << "Failed to move back current application" << std::endl;
onError(ErrorCode::FailedToMoveBack);
}
}
#endif
}
void Window::onSoundPlayed([[maybe_unused]] const PlayingSound &sound)
{
if (!Globals::gSettings.pushToTalkKeys.empty())
{
Globals::gHotKeys.pressKeys(Globals::gSettings.pushToTalkKeys);
}
}
} // namespace Soundux::Objects

View File

@ -21,6 +21,8 @@ namespace Soundux
std::shared_mutex groupedSoundsMutex;
std::map<std::uint32_t, std::uint32_t> groupedSounds;
virtual void onAllSoundsFinished();
virtual void stopSounds();
virtual bool stopSound(const std::uint32_t &);
virtual std::vector<Tab> removeTab(const std::uint32_t &);
@ -60,8 +62,8 @@ namespace Soundux
virtual void onError(const ErrorCode &) = 0;
virtual void onSoundPlayed(
const PlayingSound &) = 0; //* This will be called when a sound is played through a hotkey. PlaySound
//* will be called before this gets called
const PlayingSound &); //* This will be called when a sound is played through a hotkey. PlaySound
//* will be called before this gets called
virtual void onSoundFinished(const PlayingSound &);
virtual void onSoundProgressed(const PlayingSound &) = 0;
virtual void onDownloadProgressed(float, const std::string &) = 0;