@@ -9,4 +9,7 @@ IncludeCategories:
|
|||||||
Priority: 2
|
Priority: 2
|
||||||
- Regex: '.*'
|
- Regex: '.*'
|
||||||
Priority: 3
|
Priority: 3
|
||||||
IncludeBlocks: Regroup
|
IncludeBlocks: Regroup
|
||||||
|
|
||||||
|
# remove unused includes
|
||||||
|
SortIncludes: true
|
||||||
|
|||||||
20
.gitea/workflows/ci.yml
Normal file
20
.gitea/workflows/ci.yml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: it.rivercry.com/system/bar:latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Configure
|
||||||
|
run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build build --config Release -j "$(nproc)"
|
||||||
@@ -8,6 +8,9 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -DNDEBUG -Wall -Wextra -Wpedantic -Werror")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -DNDEBUG -Wall -Wextra -Wpedantic -Werror")
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -Wall -Wextra -Wpedantic")
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -Wall -Wextra -Wpedantic")
|
||||||
|
|
||||||
|
set(CMAKE_C_COMPILER "clang")
|
||||||
|
set(CMAKE_CXX_COMPILER "clang++")
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
|
|
||||||
pkg_check_modules(GTKMM REQUIRED gtkmm-4.0)
|
pkg_check_modules(GTKMM REQUIRED gtkmm-4.0)
|
||||||
|
|||||||
23
Dockerfile
Normal file
23
Dockerfile
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
FROM archlinux:latest
|
||||||
|
|
||||||
|
RUN pacman -Syu --noconfirm --needed \
|
||||||
|
base-devel \
|
||||||
|
clang \
|
||||||
|
lld \
|
||||||
|
ninja \
|
||||||
|
cmake \
|
||||||
|
pkgconf \
|
||||||
|
git \
|
||||||
|
ca-certificates \
|
||||||
|
gtkmm-4.0 \
|
||||||
|
gtk4 \
|
||||||
|
gtk4-layer-shell \
|
||||||
|
webkitgtk-6.0 \
|
||||||
|
curl \
|
||||||
|
nlohmann-json \
|
||||||
|
&& pacman -Scc --noconfirm
|
||||||
|
|
||||||
|
ENV CC=clang \
|
||||||
|
CXX=clang++
|
||||||
|
|
||||||
|
WORKDIR /workspace
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <giomm.h>
|
#include <giomm.h>
|
||||||
|
#include <sigc++/sigc++.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "services/dbus/messages.hpp"
|
||||||
|
|
||||||
class MprisController {
|
class MprisController {
|
||||||
public:
|
public:
|
||||||
@@ -12,12 +14,15 @@ class MprisController {
|
|||||||
void next_song();
|
void next_song();
|
||||||
void previous_song();
|
void previous_song();
|
||||||
|
|
||||||
|
sigc::signal<void(const MprisPlayer2Message &)> &signal_mpris_updated();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Glib::RefPtr<Gio::DBus::Connection> m_connection;
|
Glib::RefPtr<Gio::DBus::Connection> m_connection;
|
||||||
Glib::RefPtr<Gio::DBus::Proxy> m_proxy;
|
Glib::RefPtr<Gio::DBus::Proxy> m_proxy;
|
||||||
|
sigc::signal<void(const MprisPlayer2Message &)> mprisUpdatedSignal;
|
||||||
|
|
||||||
void on_bus_connected(const Glib::RefPtr<Gio::AsyncResult> &result);
|
void on_bus_connected(const Glib::RefPtr<Gio::AsyncResult> &result);
|
||||||
void launchNotification();
|
void signalNotification();
|
||||||
|
|
||||||
// Called when the song changes
|
// Called when the song changes
|
||||||
void on_properties_changed(const Gio::DBus::Proxy::MapChangedProperties &changed_properties,
|
void on_properties_changed(const Gio::DBus::Proxy::MapChangedProperties &changed_properties,
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ class HyprlandService {
|
|||||||
int socketFd;
|
int socketFd;
|
||||||
///
|
///
|
||||||
|
|
||||||
void bindSocket();
|
void bindHyprlandSocket();
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
|
||||||
#include "services/dbus/messages.hpp"
|
#include "services/dbus/messages.hpp"
|
||||||
#include "widgets/notification/baseNotification.hpp"
|
#include "widgets/notification/baseNotification.hpp"
|
||||||
#include "gtkmm/box.h"
|
|
||||||
#include "gtkmm/centerbox.h"
|
#include "gtkmm/centerbox.h"
|
||||||
|
|
||||||
class SpotifyNotification : public BaseNotification {
|
class SpotifyNotification : public BaseNotification {
|
||||||
public:
|
public:
|
||||||
SpotifyNotification(std::shared_ptr<Gdk::Monitor> monitor, MprisPlayer2Message message);
|
SpotifyNotification(std::shared_ptr<Gdk::Monitor> monitor, MprisPlayer2Message message);
|
||||||
virtual ~SpotifyNotification() = default;
|
virtual ~SpotifyNotification() = default;
|
||||||
private:
|
|
||||||
std::unique_ptr<Gtk::CenterBox> createButtonBox(MprisPlayer2Message mpris);
|
private:
|
||||||
|
std::unique_ptr<Gtk::CenterBox> createButtonBox(MprisPlayer2Message mpris);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include "services/dbus/notification.hpp"
|
#include "services/dbus/notification.hpp"
|
||||||
#include "services/dbus/mpris.hpp"
|
#include "services/dbus/mpris.hpp"
|
||||||
|
#include "services/notificationController.hpp"
|
||||||
#include "services/textureCache.hpp"
|
#include "services/textureCache.hpp"
|
||||||
|
|
||||||
App::App() {
|
App::App() {
|
||||||
@@ -13,6 +14,12 @@ App::App() {
|
|||||||
this->notificationService = std::make_shared<NotificationService>();
|
this->notificationService = std::make_shared<NotificationService>();
|
||||||
this->mprisController = std::make_shared<MprisController>();
|
this->mprisController = std::make_shared<MprisController>();
|
||||||
|
|
||||||
|
auto notificationController = NotificationController::getInstance();
|
||||||
|
this->mprisController->signal_mpris_updated().connect(
|
||||||
|
[notificationController](const MprisPlayer2Message &msg) {
|
||||||
|
notificationController->showSpotifyNotification(msg);
|
||||||
|
});
|
||||||
|
|
||||||
app->signal_activate().connect([&]() {
|
app->signal_activate().connect([&]() {
|
||||||
auto display = Gdk::Display::get_default();
|
auto display = Gdk::Display::get_default();
|
||||||
auto monitors = display->get_monitors();
|
auto monitors = display->get_monitors();
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
#include "services/dbus/mpris.hpp"
|
#include "services/dbus/mpris.hpp"
|
||||||
#include "services/dbus/messages.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "helpers/string.hpp"
|
#include "helpers/string.hpp"
|
||||||
#include "services/notificationController.hpp"
|
|
||||||
|
|
||||||
#include "giomm/dbusconnection.h"
|
#include "giomm/dbusconnection.h"
|
||||||
#include "giomm/dbusproxy.h"
|
#include "giomm/dbusproxy.h"
|
||||||
@@ -17,6 +14,11 @@ MprisController::MprisController() {
|
|||||||
sigc::mem_fun(*this, &MprisController::on_bus_connected));
|
sigc::mem_fun(*this, &MprisController::on_bus_connected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sigc::signal<void(const MprisPlayer2Message &)> &
|
||||||
|
MprisController::signal_mpris_updated() {
|
||||||
|
return mprisUpdatedSignal;
|
||||||
|
}
|
||||||
|
|
||||||
void MprisController::on_bus_connected(const Glib::RefPtr<Gio::AsyncResult> &result) {
|
void MprisController::on_bus_connected(const Glib::RefPtr<Gio::AsyncResult> &result) {
|
||||||
if (!result) {
|
if (!result) {
|
||||||
std::cerr << "DBus Connection Error: null async result" << std::endl;
|
std::cerr << "DBus Connection Error: null async result" << std::endl;
|
||||||
@@ -38,7 +40,7 @@ void MprisController::on_bus_connected(const Glib::RefPtr<Gio::AsyncResult> &res
|
|||||||
std::cout << "Connected to: " << player_bus_name << std::endl;
|
std::cout << "Connected to: " << player_bus_name << std::endl;
|
||||||
|
|
||||||
// uncomment if launch notification on start
|
// uncomment if launch notification on start
|
||||||
launchNotification();
|
signalNotification();
|
||||||
|
|
||||||
m_proxy->signal_properties_changed().connect(
|
m_proxy->signal_properties_changed().connect(
|
||||||
sigc::mem_fun(*this, &MprisController::on_properties_changed));
|
sigc::mem_fun(*this, &MprisController::on_properties_changed));
|
||||||
@@ -49,7 +51,7 @@ void MprisController::on_bus_connected(const Glib::RefPtr<Gio::AsyncResult> &res
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MprisController::launchNotification() {
|
void MprisController::signalNotification() {
|
||||||
if (!m_proxy) {
|
if (!m_proxy) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -93,8 +95,6 @@ void MprisController::launchNotification() {
|
|||||||
artwork_url = art_var.get();
|
artwork_url = art_var.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto notifactionController = NotificationController::getInstance();
|
|
||||||
|
|
||||||
MprisPlayer2Message mpris;
|
MprisPlayer2Message mpris;
|
||||||
mpris.title = StringHelper::trimToSize(title, 30);
|
mpris.title = StringHelper::trimToSize(title, 30);
|
||||||
mpris.artist = StringHelper::trimToSize(artist, 30);
|
mpris.artist = StringHelper::trimToSize(artist, 30);
|
||||||
@@ -102,14 +102,14 @@ void MprisController::launchNotification() {
|
|||||||
mpris.play_pause = [this]() { this->toggle_play(); };
|
mpris.play_pause = [this]() { this->toggle_play(); };
|
||||||
mpris.next = [this]() { this->next_song(); };
|
mpris.next = [this]() { this->next_song(); };
|
||||||
mpris.previous = [this]() { this->previous_song(); };
|
mpris.previous = [this]() { this->previous_song(); };
|
||||||
notifactionController->showSpotifyNotification(mpris);
|
mprisUpdatedSignal.emit(mpris);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MprisController::on_properties_changed(const Gio::DBus::Proxy::MapChangedProperties &changed_properties,
|
void MprisController::on_properties_changed(const Gio::DBus::Proxy::MapChangedProperties &changed_properties,
|
||||||
const std::vector<Glib::ustring> &) {
|
const std::vector<Glib::ustring> &) {
|
||||||
|
|
||||||
if (changed_properties.find("Metadata") != changed_properties.end()) {
|
if (changed_properties.find("Metadata") != changed_properties.end()) {
|
||||||
launchNotification();
|
signalNotification();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
HyprlandService::HyprlandService() {
|
HyprlandService::HyprlandService() {
|
||||||
init();
|
init();
|
||||||
bindSocket();
|
this->bindHyprlandSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HyprlandService::init() {
|
void HyprlandService::init() {
|
||||||
@@ -83,7 +83,7 @@ void HyprlandService::init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HyprlandService::bindSocket() {
|
void HyprlandService::bindHyprlandSocket() {
|
||||||
std::string socketPath = HyprSocketHelper::getHyprlandSocketPath();
|
std::string socketPath = HyprSocketHelper::getHyprlandSocketPath();
|
||||||
|
|
||||||
socketFd = socket(AF_UNIX, SOCK_STREAM, 0);
|
socketFd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
@@ -105,7 +105,8 @@ void HyprlandService::bindSocket() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSource *source = g_unix_fd_source_new(socketFd, static_cast<GIOCondition>(G_IO_IN | G_IO_HUP | G_IO_ERR));
|
auto socket_conditions = static_cast<GIOCondition>(G_IO_IN | G_IO_HUP | G_IO_ERR); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
|
||||||
|
GSource *source = g_unix_fd_source_new(socketFd, socket_conditions);
|
||||||
|
|
||||||
auto onSocketEvent = [](gint fd, GIOCondition , gpointer user_data) -> gboolean {
|
auto onSocketEvent = [](gint fd, GIOCondition , gpointer user_data) -> gboolean {
|
||||||
HyprlandService *self = static_cast<HyprlandService *>(user_data);
|
HyprlandService *self = static_cast<HyprlandService *>(user_data);
|
||||||
@@ -214,7 +215,6 @@ void HyprlandService::onCloseWindow(std::string windowData) {
|
|||||||
|
|
||||||
void HyprlandService::handleSocketMessage(SocketHelper::SocketMessage message) {
|
void HyprlandService::handleSocketMessage(SocketHelper::SocketMessage message) {
|
||||||
if (socketEventTypeMap.find(message.eventType) == socketEventTypeMap.end()) {
|
if (socketEventTypeMap.find(message.eventType) == socketEventTypeMap.end()) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user