Skip to content

Commit

Permalink
[Packages] AudioControl: multiple changes
Browse files Browse the repository at this point in the history
* add deamon-mode commandline parameter
* fixed the bug, when "No devices" was shown falsefuly
* refactoring

Signed-off-by: Nikita Bazulin <[email protected]>
  • Loading branch information
baz2142 committed Nov 22, 2024
1 parent e3a93d0 commit 490dc1e
Show file tree
Hide file tree
Showing 14 changed files with 136 additions and 63 deletions.
62 changes: 54 additions & 8 deletions packages/ghaf-audio-control/src/app/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,27 @@

#include "App.hpp"

#include <gtkmm/icontheme.h>

#include <glibmm/optioncontext.h>

#include <format>
#include <filesystem>

using namespace ghaf::AudioControl;

namespace
{

constexpr auto AppId = "Ghaf Audio Control";
constexpr auto IconName = "audio-volume-high-panel";
constexpr auto IconSize = 64;

struct AppArgs
{
Glib::ustring pulseServerAddress;
Glib::ustring indicatorIconPath;
Glib::ustring appVms;
bool isDeamonMode = false;
};

std::vector<std::string> GetAppVmsList(const std::string& appVms)
Expand All @@ -36,6 +41,18 @@ std::vector<std::string> GetAppVmsList(const std::string& appVms)
return result;
}

std::optional<std::filesystem::path> GetThemeIcon()
{
auto icon_theme = Gtk::IconTheme::get_default();

if (auto iconInfo = icon_theme->lookup_icon(IconName, IconSize, Gtk::ICON_LOOKUP_USE_BUILTIN))
return iconInfo.get_filename().c_str();

Logger::error("App::getThemeIcon: couldn't found an icon");

return std::nullopt;
}

} // namespace

App::AppMenu::AppMenu(App& app)
Expand All @@ -51,7 +68,8 @@ App::AppMenu::AppMenu(App& app)
}

App::App(int argc, char** argv)
: m_menu(*this)
: Gtk::Application("org.example.MyApp", Gio::APPLICATION_HANDLES_COMMAND_LINE)
, m_menu(*this)
, m_indicator(createAppIndicator())
, m_connections{m_dbusService.openSignal().connect(sigc::mem_fun(*this, &App::openWindow))}
{
Expand All @@ -69,10 +87,15 @@ App::App(int argc, char** argv)
appVmsOption.set_long_name("app_vms");
appVmsOption.set_description("AppVMs list");

Glib::OptionEntry deamonModeOption;
deamonModeOption.set_long_name("deamon_mode");
deamonModeOption.set_description("Deamon mode");

Glib::OptionGroup options("Main", "Main");
options.add_entry(pulseServerOption, appArgs.pulseServerAddress);
options.add_entry(indicatorIconPathOption, appArgs.indicatorIconPath);
options.add_entry(appVmsOption, appArgs.appVms);
options.add_entry(deamonModeOption, appArgs.isDeamonMode);

Glib::OptionContext context("Application Options");
context.set_main_group(options);
Expand All @@ -83,16 +106,28 @@ App::App(int argc, char** argv)
throw std::runtime_error{"Couldn't parse the command line arguments"};
}

app_indicator_set_icon(m_indicator.get(), appArgs.indicatorIconPath.c_str());
m_connections += signal_command_line().connect(
[this]([[maybe_unused]] const Glib::RefPtr<Gio::ApplicationCommandLine>& args)
{
hold();
return 0;
},
false);

if (const auto iconPath = GetThemeIcon())
{
Logger::info("Got icon path for the indicator: {}", iconPath->c_str());
app_indicator_set_icon(m_indicator.get(), iconPath->filename().c_str());
}

m_audioControl = std::make_unique<AudioControl>(std::make_unique<Backend::PulseAudio::AudioControlBackend>(appArgs.pulseServerAddress),
GetAppVmsList(appArgs.appVms));
}

int App::start(int argc, char** argv)
int App::start()
{
Logger::debug(__PRETTY_FUNCTION__);
return run(argc, argv);
return run();
}

bool App::onWindowDelete([[maybe_unused]] GdkEventAny* event)
Expand All @@ -105,15 +140,25 @@ bool App::onWindowDelete([[maybe_unused]] GdkEventAny* event)

void App::openWindow()
{
m_window->show_all();
m_window->show();
m_window->present();
}

void App::toggleWindow()
{
Logger::debug(__PRETTY_FUNCTION__);

if (m_window == nullptr)
{
on_activate();
openWindow();

return;
}

auto& window = *m_window;

ghaf::AudioControl::Logger::debug(std::format("Indicator has been activated. window.is_visible: {}", window.is_visible()));
Logger::debug("Indicator has been activated. window.is_visible: {}", window.is_visible());

if (window.is_visible())
window.hide();
Expand All @@ -140,7 +185,8 @@ void App::on_activate()
hold();
add_window(*m_window);

m_window->show_all();
m_window->show();
m_audioControl->show();
}

RaiiWrap<AppIndicator*> App::createAppIndicator()
Expand Down
4 changes: 2 additions & 2 deletions packages/ghaf-audio-control/src/app/App.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class App : public Gtk::Application
class AppMenu : public Gtk::Menu
{
public:
AppMenu(App& app);
explicit AppMenu(App& app);
~AppMenu() override = default;

private:
Expand All @@ -38,7 +38,7 @@ class App : public Gtk::Application
public:
App(int argc, char** argv);

int start(int argc, char** argv);
int start();

[[nodiscard]] ghaf::AudioControl::RaiiWrap<AppIndicator*> createAppIndicator();

Expand Down
10 changes: 4 additions & 6 deletions packages/ghaf-audio-control/src/app/DBusService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@

#include <giomm/dbusownname.h>

#include <format>
#include <iostream>

using namespace ghaf::AudioControl;

namespace
Expand Down Expand Up @@ -54,11 +51,12 @@ void DBusService::onNameLost(const Glib::RefPtr<Gio::DBus::Connection>&, const G
Logger::error("Couldn't register service for org.ghaf.Audio");
}

void DBusService::onMethodCall(const Glib::RefPtr<Gio::DBus::Connection>& connection, const Glib::ustring& sender, const Glib::ustring& objectPath,
const Glib::ustring& interfaceName, const Glib::ustring& methodName, const Glib::VariantContainerBase& parameters,
void DBusService::onMethodCall([[maybe_unused]] const Glib::RefPtr<Gio::DBus::Connection>& connection, [[maybe_unused]] const Glib::ustring& sender,
[[maybe_unused]] const Glib::ustring& objectPath, [[maybe_unused]] const Glib::ustring& interfaceName,
const Glib::ustring& methodName, const Glib::VariantContainerBase& parameters,
const Glib::RefPtr<Gio::DBus::MethodInvocation>& invocation)
{
Logger::debug(std::format("Invokated method: {}", methodName.c_str()));
Logger::debug("Invokated method: {}", methodName.c_str());

if (methodName == "Open")
{
Expand Down
2 changes: 1 addition & 1 deletion packages/ghaf-audio-control/src/app/DBusService.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <giomm/dbusintrospection.h>
#include <giomm/dbusmethodinvocation.h>

class DBusService
class DBusService final
{
public:
using OpenSignalSignature = sigc::signal<void()>;
Expand Down
6 changes: 3 additions & 3 deletions packages/ghaf-audio-control/src/app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ int main(int argc, char** argv)
try
{
App app(argc, argv);
return app.start(argc, argv);
return app.start();
}
catch (const Glib::Error& ex)
{
Logger::error(std::format("Error: {}", ex.what().c_str()));
Logger::error("Error: {}", ex.what().c_str());
return 1;
}
catch (const std::exception& e)
{
Logger::error(std::format("Exception: {}", e.what()));
Logger::error("Exception: {}", e.what());
return 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ void ExecutePulseFuncPrivate(Fx fx, ArgsT... args)
}

#if defined(DEBUG)
#define ExecutePulseFunc(FX, ARGS...) \
{ \
Logger::debug(std::format("ExecutePulseFunc: {}", #FX)); \
ExecutePulseFuncPrivate(FX, ARGS); \
#define ExecutePulseFunc(FX, ARGS...) \
{ \
Logger::debug("ExecutePulseFunc: {}", #FX); \
ExecutePulseFuncPrivate(FX, ARGS); \
}
#else
template<class Fx, class... ArgsT>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ class ConnectionContainer final
std::ignore = m_connections.emplace_back(std::move(connection));
}

ConnectionContainer& operator+=(sigc::connection&& connection)
{
add(std::move(connection));
return *this;
}

ScopeExit blockGuarded();

ConnectionContainer& operator=(ConnectionContainer&) = delete;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,44 @@

#pragma once

#include <format>
#include <string_view>

namespace ghaf::AudioControl
{

class Logger
{
private:
enum class LogLevel
{
DEBUG,
ERROR,
INFO
};

public:
static void debug(std::string_view message);
static void error(std::string_view message);
static void info(std::string_view message);
template<class... ArgsT>
static void debug(std::string_view message, ArgsT... args)
{
log(std::vformat(message, std::make_format_args(args...)), LogLevel::DEBUG);
}

template<class... ArgsT>
static void error(std::string_view message, ArgsT... args)
{
log(std::vformat(message, std::make_format_args(args...)), LogLevel::ERROR);
}

template<class... ArgsT>
static void info(std::string_view message, ArgsT... args)
{
log(std::vformat(message, std::make_format_args(args...)), LogLevel::INFO);
}

private:
static void log(std::string_view message, std::string_view logLevel);
static std::string logLevelToString(LogLevel logLevel);
static void log(std::string_view message, LogLevel logLevel);

Logger();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void OnPulseDeviceInfo(const InfoT& info, IAudioControlBackend::SignalMap<IDevic
const IDeviceT& device = *deviceIt.value()->second;

map.update(*deviceIt, [&info](IDeviceT& device) { dynamic_cast<DeviceT&>(device).update(info); });
Logger::debug(std::format("Updating... {}", device.toString()));
Logger::debug("Updating... {}", device.toString());
}
else
{
Expand All @@ -51,11 +51,11 @@ void DeletePulseDevice(IAudioControlBackend::SignalMap<IDeviceT>& map, IndexT in
{
if (auto deviceIt = map.findByKey(index))
{
Logger::debug(std::format("AudioControlBackend::DeletePulseDevice: delete device with id: {}", index));
Logger::debug("AudioControlBackend::DeletePulseDevice: delete device with id: {}", index);
map.remove(*deviceIt, [](IDeviceT& device) { dynamic_cast<DeviceT&>(device).markDeleted(); });
}
else
Logger::error(std::format("AudioControlBackend::DeletePulseDevice: no device with id: {}", index));
Logger::error("AudioControlBackend::DeletePulseDevice: no device with id: {}", index);
}

std::string ToString(const pa_card_port_info& port)
Expand Down Expand Up @@ -145,7 +145,7 @@ AudioControlBackend::AudioControlBackend(std::string pulseAudioServerAddress)

void AudioControlBackend::start()
{
Logger::info(std::format("PulseAudio::AudioControlBackend: starting with server: {}", m_serverAddress));
Logger::info("PulseAudio::AudioControlBackend: starting with server: {}", m_serverAddress);
m_context = InitContext(*m_mainloopApi, contextStateCallback, *this);
}

Expand Down Expand Up @@ -243,7 +243,7 @@ void AudioControlBackend::subscribeCallback(pa_context* context, pa_subscription
break;

default:
Logger::error(std::format("subscribeCallback: unknown eventType: {0}", static_cast<int>(eventType)));
Logger::error("subscribeCallback: unknown eventType: {0}", static_cast<int>(eventType));
break;
};
}
Expand Down Expand Up @@ -274,7 +274,7 @@ void AudioControlBackend::contextStateCallback(pa_context* context, void* data)
break;

default:
Logger::error(std::format("contextStateCb: unknown state: {0}", static_cast<int>(state)));
Logger::error("contextStateCb: unknown state: {0}", static_cast<int>(state));
break;
}
}
Expand Down Expand Up @@ -336,7 +336,7 @@ void AudioControlBackend::cardInfoCallback(pa_context* context, const pa_card_in
return;

Logger::debug("###############################################");
Logger::debug(std::format("Card. index: {}, name: {}", info->index, info->name));
Logger::debug("Card. index: {}, name: {}", info->index, info->name);

for (size_t i = 0; i < info->n_ports; ++i)
Logger::info(ToString(*info->ports[i]));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ bool PulseCallbackCheck(const pa_context* context, int eol, std::string_view cal
{
if (context == nullptr)
{
Logger::error(std::format("pulseCallbackCheck: callback: {} context == nullptr", callbackName));
Logger::error("pulseCallbackCheck: callback: {} context == nullptr", callbackName);
return false;
}

Expand All @@ -28,7 +28,7 @@ bool PulseCallbackCheck(const pa_context* context, int eol, std::string_view cal
if (error == pa_error_code::PA_ERR_NOENTITY || error == pa_error_code::PA_OK)
return true;

Logger::error(std::format("pulseCallbackCheck: callback: {} failed with error: {}", callbackName, pa_strerror(error)));
Logger::error("pulseCallbackCheck: callback: {} failed with error: {}", callbackName, pa_strerror(error));

return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ void DeviceModel::onSoundEnabledChange()
{
const auto isEnabled = m_isSoundEnabled.get_value();

Logger::debug(std::format("SoundEnabled has changed to: {0}", isEnabled));
Logger::debug("SoundEnabled has changed to: {0}", isEnabled);
m_device->setMuted(!isEnabled);
}

void DeviceModel::onSoundVolumeChange()
{
Logger::debug(std::format("SoundVolume has changed to: {0}", m_soundVolume.get_value()));
Logger::debug("SoundVolume has changed to: {0}", m_soundVolume.get_value());
m_device->setVolume(Volume::fromPercents(m_soundVolume.get_value()));
}

Expand Down
Loading

0 comments on commit 490dc1e

Please sign in to comment.