nice spotify notification

This commit is contained in:
2026-02-01 01:53:47 +01:00
parent caca94bc6a
commit dc325834c7
7 changed files with 256 additions and 167 deletions

132
src/services/dbus/mpris.cpp Normal file
View File

@@ -0,0 +1,132 @@
#include "services/dbus/mpris.hpp"
#include <iostream>
#include <map>
#include "helpers/string.hpp"
#include "services/notificationController.hpp"
#include "giomm/dbusconnection.h"
#include "giomm/dbusproxy.h"
MprisController::MprisController() {
// 1. Connect to the Session Bus
Gio::DBus::Connection::get(
Gio::DBus::BusType::SESSION,
sigc::mem_fun(*this, &MprisController::on_bus_connected));
}
void MprisController::on_bus_connected(const Glib::RefPtr<Gio::AsyncResult> &result) {
if (!result) {
std::cerr << "DBus Connection Error: null async result" << std::endl;
return;
}
try {
m_connection = Gio::DBus::Connection::get_finish(result);
std::string player_bus_name = "org.mpris.MediaPlayer2.spotify";
m_proxy = Gio::DBus::Proxy::create_sync(
m_connection,
player_bus_name, // The Bus Name
"/org/mpris/MediaPlayer2", // The Object Path
"org.mpris.MediaPlayer2.Player" // The Interface
);
if (m_proxy) {
std::cout << "Connected to: " << player_bus_name << std::endl;
// uncomment if launch notification on start
launchNotification();
m_proxy->signal_properties_changed().connect(
sigc::mem_fun(*this, &MprisController::on_properties_changed));
}
} catch (const Glib::Error &ex) {
std::cerr << "DBus Connection Error: " << ex.what() << std::endl;
}
}
void MprisController::launchNotification() {
if (!m_proxy) {
return;
}
Glib::VariantBase metadata_var;
m_proxy->get_cached_property(metadata_var, "Metadata");
if (!metadata_var) {
std::cout << "No metadata available." << std::endl;
return;
}
using MetadataMap = std::map<Glib::ustring, Glib::VariantBase>;
MetadataMap metadata_map;
Glib::Variant<MetadataMap> variant_dict =
Glib::VariantBase::cast_dynamic<Glib::Variant<MetadataMap>>(metadata_var);
metadata_map = variant_dict.get();
std::string title, artist, artwork_url;
if (metadata_map.count("xesam:title")) {
auto title_var = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring>>(metadata_map["xesam:title"]);
title = title_var.get();
}
if (metadata_map.count("xesam:artist")) {
auto artist_var = metadata_map["xesam:artist"];
if (artist_var.is_of_type(Glib::VariantType("as"))) {
auto artists = Glib::VariantBase::cast_dynamic<Glib::Variant<std::vector<Glib::ustring>>>(artist_var).get();
if (!artists.empty()) {
artist = artists[0]; // Take the first artist
}
}
}
if (metadata_map.count("mpris:artUrl")) {
auto art_var = Glib::VariantBase::cast_dynamic<Glib::Variant<Glib::ustring>>(metadata_map["mpris:artUrl"]);
artwork_url = art_var.get();
}
auto notifactionController = NotificationController::getInstance();
MprisController::MprisPlayer2Message mpris;
mpris.title = StringHelper::trimToSize(title, 30);
mpris.artist = StringHelper::trimToSize(artist, 30);
mpris.artwork_url = artwork_url;
mpris.play_pause = [this]() { this->toggle_play(); };
mpris.next = [this]() { this->next_song(); };
mpris.previous = [this]() { this->previous_song(); };
notifactionController->showSpotifyNotification(mpris);
}
void MprisController::on_properties_changed(const Gio::DBus::Proxy::MapChangedProperties &changed_properties,
const std::vector<Glib::ustring> &) {
if (changed_properties.find("Metadata") != changed_properties.end()) {
launchNotification();
}
}
void MprisController::previous_song() {
if (m_proxy) {
m_proxy->call("Previous");
}
}
void MprisController::toggle_play() {
if (m_proxy) {
m_proxy->call("PlayPause");
}
}
void MprisController::next_song() {
if (m_proxy) {
m_proxy->call("Next");
}
}