feat: add Push-To-Talk feature (#116)
This commit is contained in:
parent
52518e173c
commit
40f0740638
@ -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})
|
||||
|
@ -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;
|
||||
|
@ -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> &);
|
||||
};
|
||||
|
@ -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
|
@ -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
|
@ -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>
|
||||
|
@ -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
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user