From ad5e678c5d9806e3a442bf497487100109cbec72 Mon Sep 17 00:00:00 2001 From: Arif Hasanic Date: Sat, 31 Jan 2026 11:46:12 +0100 Subject: [PATCH] quick commit --- CMakeLists.txt | 14 ++- include/bar/bar.hpp | 5 +- include/components/todoEntry.hpp | 21 ---- include/helpers/command.hpp | 31 ++++++ include/helpers/hypr.hpp | 69 ++++++++++++ include/helpers/socket.hpp | 52 +++++++++ include/helpers/string.hpp | 40 +++++++ include/helpers/system.hpp | 17 +++ include/helpers/systemHelper.hpp | 39 ------- include/icons.hpp | 3 - include/services/hyprland.hpp | 11 +- include/services/todo.hpp | 28 ----- include/services/todoAdapter.hpp | 21 ---- include/widgets/todo.hpp | 21 ---- resources/bar.css | 32 ++++++ src/bar/bar.cpp | 5 +- src/components/base/button.cpp | 13 +-- src/components/popover.cpp | 3 - src/components/todoEntry.cpp | 47 --------- src/services/hyprland.cpp | 38 +++---- src/services/sqliteTodoAdapter.cpp | 164 ----------------------------- src/services/todo.cpp | 128 ---------------------- src/widgets/controlCenter.cpp | 20 ++-- src/widgets/todo.cpp | 78 -------------- src/widgets/volumeWidget.cpp | 9 +- 25 files changed, 287 insertions(+), 622 deletions(-) delete mode 100644 include/components/todoEntry.hpp create mode 100644 include/helpers/command.hpp create mode 100644 include/helpers/hypr.hpp create mode 100644 include/helpers/socket.hpp create mode 100644 include/helpers/string.hpp create mode 100644 include/helpers/system.hpp delete mode 100644 include/helpers/systemHelper.hpp delete mode 100644 include/icons.hpp delete mode 100644 include/services/todo.hpp delete mode 100644 include/services/todoAdapter.hpp delete mode 100644 include/widgets/todo.hpp delete mode 100644 src/components/todoEntry.cpp delete mode 100644 src/services/sqliteTodoAdapter.cpp delete mode 100644 src/services/todo.cpp delete mode 100644 src/widgets/todo.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c789c54..ed3f62b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,10 +12,12 @@ find_package(PkgConfig REQUIRED) pkg_check_modules(GTKMM REQUIRED gtkmm-4.0) pkg_check_modules(LAYERSHELL REQUIRED gtk4-layer-shell-0) pkg_check_modules(WEBKIT REQUIRED webkitgtk-6.0) -pkg_check_modules(SQLITE3 REQUIRED sqlite3) +pkg_check_modules(CURL REQUIRED libcurl) -include_directories(${GTKMM_INCLUDE_DIRS} ${LAYERSHELL_INCLUDE_DIRS} ${WEBKIT_INCLUDE_DIRS} ${SQLITE3_INCLUDE_DIRS}) -link_directories(${GTKMM_LIBRARY_DIRS} ${LAYERSHELL_LIBRARY_DIRS} ${WEBKIT_LIBRARY_DIRS} ${SQLITE3_LIBRARY_DIRS}) +find_package(nlohmann_json 3.2.0 REQUIRED) + +include_directories(${GTKMM_INCLUDE_DIRS} ${LAYERSHELL_INCLUDE_DIRS} ${WEBKIT_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} ${nlohmann_json_INCLUDE_DIRS}) +link_directories(${GTKMM_LIBRARY_DIRS} ${LAYERSHELL_LIBRARY_DIRS} ${WEBKIT_LIBRARY_DIRS} ${CURL_LIBRARY_DIRS}) add_library(bar_lib) target_sources(bar_lib @@ -29,20 +31,16 @@ target_sources(bar_lib src/widgets/volumeWidget.cpp src/widgets/webWidget.cpp - src/services/todo.cpp - src/services/sqliteTodoAdapter.cpp src/services/hyprland.cpp src/services/tray.cpp src/services/notifications.cpp src/services/bluetooth.cpp src/widgets/tray.cpp - src/widgets/todo.cpp src/widgets/bluetooth.cpp src/widgets/controlCenter.cpp src/components/popover.cpp - src/components/todoEntry.cpp src/components/base/button.cpp ) include_directories(bar_lib PRIVATE @@ -51,7 +49,7 @@ include_directories(bar_lib PRIVATE add_executable(bar main.cpp) -target_link_libraries(bar bar_lib ${GTKMM_LIBRARIES} ${LAYERSHELL_LIBRARIES} ${WEBKIT_LIBRARIES} ${SQLITE3_LIBRARIES}) +target_link_libraries(bar bar_lib ${GTKMM_LIBRARIES} ${LAYERSHELL_LIBRARIES} ${WEBKIT_LIBRARIES} ${CURL_LIBRARIES} nlohmann_json::nlohmann_json) # Copy `resources/bar.css` into the build directory when it changes set(RES_SRC "${CMAKE_CURRENT_SOURCE_DIR}/resources/bar.css") diff --git a/include/bar/bar.hpp b/include/bar/bar.hpp index 464129c..4173277 100644 --- a/include/bar/bar.hpp +++ b/include/bar/bar.hpp @@ -3,7 +3,6 @@ #include #include -#include "icons.hpp" #include "widgets/clock.hpp" #include "widgets/date.hpp" #include "widgets/tray.hpp" @@ -26,8 +25,8 @@ class Bar : public Gtk::Window { Clock clock; Date date; - WebWidget homeAssistant{ICON_HOME, "Home Assistant", "https://home.rivercry.com"}; - ControlCenter controlCenter{"\ue8bb", "Control Center"}; + WebWidget homeAssistant{"\ue88a", "Home Assistant", "https://home.rivercry.com"}; + ControlCenter controlCenter{"\ue88a", "Control Center"}; WorkspaceIndicator *workspaceIndicator = nullptr; TrayWidget *trayWidget = nullptr; diff --git a/include/components/todoEntry.hpp b/include/components/todoEntry.hpp deleted file mode 100644 index 463eb61..0000000 --- a/include/components/todoEntry.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#include "gtkmm/box.h" - -class TodoEntry : public Gtk::Box { - public: - TodoEntry(int id, std::string text, sigc::signal signal_dismissed, sigc::signal signal_edited); - - int get_id() const { return id; } - std::string get_text() const { return text; } - - private: - int id; - std::string text; - sigc::signal signal_dismissed; - sigc::signal signal_edited; - - void on_dismiss_clicked(); -}; \ No newline at end of file diff --git a/include/helpers/command.hpp b/include/helpers/command.hpp new file mode 100644 index 0000000..5a9fb72 --- /dev/null +++ b/include/helpers/command.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include +#include +#include + +class CommandHelper { + public: + static std::string exec(const char *cmd) { + std::array buffer; + std::string result; + std::unique_ptr pipe(popen(cmd, "r"), pclose); + if (!pipe) { + throw std::runtime_error("popen() failed!"); + } + while (fgets(buffer.data(), static_cast(buffer.size()), pipe.get()) != nullptr) { + result += buffer.data(); + } + return result; + } + + static void execNoOutput(std::string cmd) { + std::string command = cmd + " > /dev/null 2>&1"; + int ret = std::system(command.c_str()); + if (ret != 0) { + throw std::runtime_error("Command failed with return code: " + std::to_string(ret)); + } + } +}; \ No newline at end of file diff --git a/include/helpers/hypr.hpp b/include/helpers/hypr.hpp new file mode 100644 index 0000000..aefea66 --- /dev/null +++ b/include/helpers/hypr.hpp @@ -0,0 +1,69 @@ +#pragma once + +#include +#include +#include +#include + +#include "helpers/command.hpp" + +class HyprctlHelper { + public: + static nlohmann::json getMonitorData() { + std::string result = CommandHelper::exec("hyprctl -j monitors"); + assert(!result.empty() && "Failed to get monitor data from hyprctl"); + + auto json = nlohmann::json::parse(result); + + assert(json.is_array()); + + return json; + } + + static nlohmann::json getWorkspaceData() { + std::string result = CommandHelper::exec("hyprctl -j workspaces"); + assert(!result.empty() && "Failed to get workspace data from hyprctl"); + + auto json = nlohmann::json::parse(result); + + assert(json.is_array()); + + return json; + } + + static nlohmann::json getClientData() { + std::string result = CommandHelper::exec("hyprctl -j clients"); + assert(!result.empty() && "Failed to get client data from hyprctl"); + + auto json = nlohmann::json::parse(result); + + assert(json.is_array()); + + return json; + } + + static void dispatchWorkspace(int workspaceNumber) { + std::string out = "hyprctl dispatch workspace " + std::to_string(workspaceNumber); + CommandHelper::execNoOutput(out.c_str()); + } +}; + +class HyprSocketHelper { + public: + static std::string getHyprlandSocketPath() { + const char *hyprlandInstanceSignature = std::getenv("HYPRLAND_INSTANCE_SIGNATURE"); + const char *xdgRuntimeDir = std::getenv("XDG_RUNTIME_DIR"); + + if (!xdgRuntimeDir || !hyprlandInstanceSignature) { + return std::string(); + } + + std::string basePath = std::string(xdgRuntimeDir) + "/hypr/" + std::string(hyprlandInstanceSignature) + "/"; + std::string sock1 = basePath + ".socket2.sock"; + if (access(sock1.c_str(), F_OK) == 0) { + return sock1; + } + + return std::string(); + } +}; \ No newline at end of file diff --git a/include/helpers/socket.hpp b/include/helpers/socket.hpp new file mode 100644 index 0000000..0345c5d --- /dev/null +++ b/include/helpers/socket.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "helper/string.hpp" + +class SocketHelper { + typedef struct SocketMessage { + std::string eventType; + std::string eventData; + } SocketMessage; + + public: + static std::vector parseSocketMessage(int socketFd, const std::string &delimiter) { + char buffer[4096]; + std::string data; + ssize_t bytesRead = recv(socketFd, buffer, sizeof(buffer) - 1, 0); + if (bytesRead > 0) { + buffer[bytesRead] = '\0'; + data = std::string(buffer); + } else if (bytesRead == 0) { + std::cerr << "Socket closed by peer" << std::endl; + } else { + std::cerr << "Error reading from socket" << std::endl; + } + + auto delimiterPos = data.find(delimiter); + + if (delimiterPos == std::string::npos) { + assert(false && "Delimiter not found in socket message"); + } + + auto splitMessages = StringHelper::split(data, '\n'); + auto splitMessagesFinal = std::vector(); + for (auto splitMessage : splitMessages) { + + + SocketMessage message; + auto messageCommandVector = StringHelper::split(splitMessage, ">>"); + + message.eventType = messageCommandVector[0]; + message.eventData = messageCommandVector.size() > 1 ? messageCommandVector[1] : ""; + splitMessagesFinal.push_back(message); + } + + return splitMessagesFinal; + } +}; \ No newline at end of file diff --git a/include/helpers/string.hpp b/include/helpers/string.hpp new file mode 100644 index 0000000..4729c69 --- /dev/null +++ b/include/helpers/string.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include +#include + + +class StringHelper { +public: + static std::vector split(const std::string &input, char delimiter) { + std::vector tokens; + std::string token; + for (char ch : input) { + if (ch == delimiter) { + if (!token.empty()) { + tokens.push_back(token); + token.clear(); + } + } else { + token += ch; + } + } + if (!token.empty()) { + tokens.push_back(token); + } + return tokens; + } + + static std::vector split(const std::string &input, std::string delimiter) { + std::vector tokens; + size_t start = 0; + size_t end = input.find(delimiter); + while (end != std::string::npos) { + tokens.push_back(input.substr(start, end - start)); + start = end + delimiter.length(); + end = input.find(delimiter, start); + } + tokens.push_back(input.substr(start)); + return tokens; + } +}; \ No newline at end of file diff --git a/include/helpers/system.hpp b/include/helpers/system.hpp new file mode 100644 index 0000000..343812d --- /dev/null +++ b/include/helpers/system.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include + +class SystemHelper { + public: + static std::string read_file_to_string(const std::string &filePath) { + std::ifstream file(filePath); + if (!file.is_open()) { + throw std::runtime_error("Could not open file: " + filePath); + } + std::string content((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + file.close(); + return content; + } +}; \ No newline at end of file diff --git a/include/helpers/systemHelper.hpp b/include/helpers/systemHelper.hpp deleted file mode 100644 index ae4d442..0000000 --- a/include/helpers/systemHelper.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -class SystemHelper { - public: - static std::string get_command_output(const char *cmd) { - std::array buffer; - std::string result; - std::unique_ptr pipe(popen(cmd, "r"), pclose); - - if (!pipe) { - throw std::runtime_error("popen() failed!"); - } - - // Read the output a chunk at a time until the stream ends - while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { - result += buffer.data(); - } - - return result; - } - - // Read an entire file into a string. Throws std::runtime_error on failure. - static std::string read_file_to_string(const std::string &path) { - std::ifstream in(path, std::ios::in | std::ios::binary); - if (!in) { - throw std::runtime_error("Failed to open file: " + path); - } - - std::ostringstream ss; - ss << in.rdbuf(); - return ss.str(); - } -}; diff --git a/include/icons.hpp b/include/icons.hpp deleted file mode 100644 index 9be3c58..0000000 --- a/include/icons.hpp +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#define ICON_HOME "\ue88a" diff --git a/include/services/hyprland.hpp b/include/services/hyprland.hpp index 16e358c..5bd057d 100644 --- a/include/services/hyprland.hpp +++ b/include/services/hyprland.hpp @@ -13,13 +13,6 @@ class HyprlandService { public: static constexpr int kWorkspaceSlotCount = 7; - const char *kMonitorCommand = "hyprctl monitors -j"; - const char *kWorkspaceCommand = "hyprctl workspaces -j"; - const char *kClientsCommand = "hyprctl clients -j"; - - struct WindowState { - int hyprId = -1; - }; struct WorkspaceState { int hyprId = -1; @@ -64,6 +57,10 @@ class HyprlandService { } private: + const char *kMonitorCommand = "hyprctl monitors -j"; + const char *kWorkspaceCommand = "hyprctl workspaces -j"; + const char *kClientsCommand = "hyprctl clients -j"; + HyprlandService(); ~HyprlandService(); diff --git a/include/services/todo.hpp b/include/services/todo.hpp deleted file mode 100644 index 4569df2..0000000 --- a/include/services/todo.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include - -#include "components/todoEntry.hpp" -#include "services/todoAdapter.hpp" - -class TodoService { - public: - TodoService(sigc::signal refreshSignal); - ~TodoService(); - - std::map getTodos(); - void init(); - void removeTodo(int id); - TodoEntry *addTodo(std::string text, bool emitSignal = true, bool persist = true); - void updateTodo(int id, std::string text); - - private: - void load(); - - int nextId = 1; - std::map todos; - sigc::signal refreshSignal; - - std::unique_ptr adapter; -}; \ No newline at end of file diff --git a/include/services/todoAdapter.hpp b/include/services/todoAdapter.hpp deleted file mode 100644 index ad499cd..0000000 --- a/include/services/todoAdapter.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -#include - -struct TodoRecord { - int id; - std::string text; -}; - -class ITodoAdapter { - public: - virtual ~ITodoAdapter() = default; - - virtual bool init() = 0; - virtual std::vector listTodos() = 0; - - virtual int addTodo(const std::string &text) = 0; - virtual bool removeTodo(int id) = 0; - virtual bool updateTodo(int id, const std::string &text) = 0; -}; diff --git a/include/widgets/todo.hpp b/include/widgets/todo.hpp deleted file mode 100644 index 7964aba..0000000 --- a/include/widgets/todo.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#include "components/popover.hpp" -#include "services/todo.hpp" - -class TodoPopover : public Popover { - - public: - TodoPopover(std::string icon, std::string title); - - void update(); - - private: - std::string name; - TodoService *todoService = nullptr; - Gtk::Box container; - Gtk::Box inputArea; - Gtk::Box *todoList = nullptr; -}; \ No newline at end of file diff --git a/resources/bar.css b/resources/bar.css index 0fc3c30..60990f0 100644 --- a/resources/bar.css +++ b/resources/bar.css @@ -136,3 +136,35 @@ button { opacity: 1; } } + + +.todo-tag-area { + min-height: 40px; + padding: 5px; +} + +.tag-button { + background-color: #444444; + color: #ffffff; + padding: 2px 8px; + margin: 2px; + border-radius: 12px; + font-size: 12px; + font-family: "Hack Nerd Font Mono", sans-serif; + min-height: 24px; + min-width: 50px; +} + +.tag-button:hover { + background-color: #555555; +} + +.tag-button.suggested-action { + background-color: #3498db; + color: #ffffff; +} + +.todo-entry-box { + margin-top: 5px; + margin-bottom: 5px; +} \ No newline at end of file diff --git a/src/bar/bar.cpp b/src/bar/bar.cpp index c7e6849..6cba594 100644 --- a/src/bar/bar.cpp +++ b/src/bar/bar.cpp @@ -5,10 +5,9 @@ #include #include -#include "helpers/systemHelper.hpp" +#include "helpers/system.hpp" #include "widgets/date.hpp" #include "widgets/spacer.hpp" -#include "widgets/todo.hpp" #include "widgets/volumeWidget.hpp" #include "widgets/workspaceIndicator.hpp" @@ -66,8 +65,6 @@ void Bar::setup_left_box() { void Bar::setup_center_box() { center_box.set_hexpand(false); - center_box.append(*(new TodoPopover("\uf23a", "To-Do"))); - center_box.append(*(new Spacer())); center_box.append(this->date); center_box.append(*(new Spacer())); center_box.append(this->clock); diff --git a/src/components/base/button.cpp b/src/components/base/button.cpp index 23d1fb1..a16f834 100644 --- a/src/components/base/button.cpp +++ b/src/components/base/button.cpp @@ -2,18 +2,13 @@ #include "sigc++/functors/mem_fun.h" - -Button::Button(const std::string label) - : Gtk::Button(label) { - signal_clicked().connect( - sigc::mem_fun(*this, &Button::on_clicked)); +Button::Button(const std::string label) : Gtk::Button(label) { + signal_clicked().connect(sigc::mem_fun(*this, &Button::on_clicked)); this->add_css_class("button"); } -Button::Button(Gtk::Image &image) - : Gtk::Button() { +Button::Button(Gtk::Image &image) : Gtk::Button() { set_child(image); - signal_clicked().connect( - sigc::mem_fun(*this, &Button::on_clicked)); + signal_clicked().connect(sigc::mem_fun(*this, &Button::on_clicked)); this->add_css_class("button"); } \ No newline at end of file diff --git a/src/components/popover.cpp b/src/components/popover.cpp index a0759cb..ffcaa14 100644 --- a/src/components/popover.cpp +++ b/src/components/popover.cpp @@ -1,8 +1,5 @@ #include "components/popover.hpp" -#include "gtkmm/label.h" -#include "gtkmm/object.h" - Popover::Popover(const std::string icon, std::string name): Button(icon) { signal_clicked().connect(sigc::mem_fun(*this, &Popover::on_toggle_window)); diff --git a/src/components/todoEntry.cpp b/src/components/todoEntry.cpp deleted file mode 100644 index c44df21..0000000 --- a/src/components/todoEntry.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "components/todoEntry.hpp" - -#include -#include -#include "components/base/button.hpp" - -TodoEntry::TodoEntry(int id, std::string text, sigc::signal signal_dismissed, sigc::signal signal_edited) - : Gtk::Box(Gtk::Orientation::HORIZONTAL) { - this->id = id; - this->text = text; - this->signal_dismissed = signal_dismissed; - this->signal_edited = signal_edited; - - auto box = Gtk::make_managed(Gtk::Orientation::HORIZONTAL); - box->set_hexpand(true); - box->set_halign(Gtk::Align::START); - box->set_valign(Gtk::Align::CENTER); - box->set_name("todo-entry-box"); - box->add_css_class("todo-entry-box"); - append(*box); - - auto label = Gtk::make_managed(text); - label->set_halign(Gtk::Align::START); - label->set_valign(Gtk::Align::CENTER); - box->append(*label); - - auto buttonBox = Gtk::make_managed(Gtk::Orientation::HORIZONTAL); - buttonBox->set_halign(Gtk::Align::END); - buttonBox->set_valign(Gtk::Align::CENTER); - append(*buttonBox); - - auto dismissButton = Gtk::make_managed