From e0944806847a7f8862ba8c481e4ec00477bf6fef Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Sat, 2 Apr 2022 21:08:43 +0200 Subject: [PATCH] Very basic hypr window title module --- include/factory.hpp | 5 ++ include/modules/hypr/ipc.hpp | 22 +++++++++ include/modules/hypr/window.hpp | 23 +++++++++ meson.build | 6 +++ src/factory.cpp | 5 ++ src/modules/hypr/ipc.cpp | 86 +++++++++++++++++++++++++++++++++ src/modules/hypr/window.cpp | 27 +++++++++++ 7 files changed, 174 insertions(+) create mode 100644 include/modules/hypr/ipc.hpp create mode 100644 include/modules/hypr/window.hpp create mode 100644 src/modules/hypr/ipc.cpp create mode 100644 src/modules/hypr/window.cpp diff --git a/include/factory.hpp b/include/factory.hpp index 3954dac..d3e0a08 100644 --- a/include/factory.hpp +++ b/include/factory.hpp @@ -1,5 +1,7 @@ #pragma once +#define HAVE_HYPR + #include #ifdef HAVE_LIBDATE #include "modules/clock.hpp" @@ -19,6 +21,9 @@ #ifdef HAVE_RIVER #include "modules/river/tags.hpp" #endif +#ifdef HAVE_HYPR +#include "modules/hypr/window.hpp" +#endif #if defined(__linux__) && !defined(NO_FILESYSTEM) #include "modules/battery.hpp" #endif diff --git a/include/modules/hypr/ipc.hpp b/include/modules/hypr/ipc.hpp new file mode 100644 index 0000000..0cf061a --- /dev/null +++ b/include/modules/hypr/ipc.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "bar.hpp" +#include "client.hpp" + +namespace waybar::modules::hypr { + + std::string makeRequest(std::string); + +} // namespace waybar::modules::hypr diff --git a/include/modules/hypr/window.hpp b/include/modules/hypr/window.hpp new file mode 100644 index 0000000..83f8650 --- /dev/null +++ b/include/modules/hypr/window.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include +#include "ALabel.hpp" +#include "util/sleeper_thread.hpp" +#include "util/format.hpp" +#include "ipc.hpp" + +namespace waybar::modules::hypr { + +class Window : public ALabel { + public: + Window(const std::string&, const Json::Value&); + ~Window() = default; + auto update() -> void; + + private: + util::SleeperThread thread_; +}; + +} // namespace waybar::modules::hypr diff --git a/meson.build b/meson.build index e9daeca..645c1f6 100644 --- a/meson.build +++ b/meson.build @@ -187,6 +187,12 @@ src_files += [ 'src/modules/sway/workspaces.cpp' ] +add_project_arguments('-DHAVE_HYPR', language: 'cpp') +src_files += [ + 'src/modules/hypr/ipc.cpp', + 'src/modules/hypr/window.cpp', +] + if true add_project_arguments('-DHAVE_WLR', language: 'cpp') src_files += 'src/modules/wlr/taskbar.cpp' diff --git a/src/factory.cpp b/src/factory.cpp index ab0dc43..8a024d7 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -45,6 +45,11 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const { if (ref == "river/tags") { return new waybar::modules::river::Tags(id, bar_, config_[name]); } +#endif +#ifdef HAVE_HYPR + if (ref == "hypr/window") { + return new waybar::modules::hypr::Window(id, config_[name]); + } #endif if (ref == "idle_inhibitor") { return new waybar::modules::IdleInhibitor(id, bar_, config_[name]); diff --git a/src/modules/hypr/ipc.cpp b/src/modules/hypr/ipc.cpp new file mode 100644 index 0000000..40488ec --- /dev/null +++ b/src/modules/hypr/ipc.cpp @@ -0,0 +1,86 @@ +#include "modules/hypr/ipc.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util/string.hpp" + +std::string waybar::modules::hypr::makeRequest(std::string req) { + const auto SERVERSOCKET = socket(AF_INET, SOCK_STREAM, 0); + + if (SERVERSOCKET < 0) { + spdlog::error("[Hypr IPC] Couldn't open a socket."); + return ""; + } + + const auto SERVER = gethostbyname("localhost"); + + if (!SERVER) { + spdlog::error("[Hypr IPC] Couldn't get localhost."); + return ""; + } + + sockaddr_in serverAddress = {0}; + serverAddress.sin_family = AF_INET; + bcopy((char*)SERVER->h_addr, (char*)&serverAddress.sin_addr.s_addr, SERVER->h_length); + + std::ifstream socketPortStream; + socketPortStream.open("/tmp/hypr/.socket"); + + if (!socketPortStream.good()) { + spdlog::error("[Hypr IPC] No socket file. Is Hyprland running?"); + return ""; + } + + std::string port = ""; + std::getline(socketPortStream, port); + socketPortStream.close(); + + int portInt = 0; + try { + portInt = std::stoi(port.c_str()); + } catch (...) { + spdlog::error("[Hypr IPC] Port not an int?!"); + return ""; + } + + if (portInt == 0) { + spdlog::error("[Hypr IPC] Port 0. Aborting."); + return ""; + } + + serverAddress.sin_port = portInt; + + if (connect(SERVERSOCKET, (sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) { + spdlog::error("[Hypr IPC] Couldn't connect to port {} , is Hyprland running?", port); + return ""; + } + + auto sizeWritten = write(SERVERSOCKET, req.c_str(), req.length()); + + if (sizeWritten < 0) { + spdlog::error("[Hypr IPC] Couldn't write to the socket."); + return ""; + } + + char buffer[8192] = {0}; + + sizeWritten = read(SERVERSOCKET, buffer, 8192); + + if (sizeWritten < 0) { + spdlog::error("[Hypr IPC] Couldn't cread from the socket."); + return ""; + } + + close(SERVERSOCKET); + + return std::string(buffer); +} \ No newline at end of file diff --git a/src/modules/hypr/window.cpp b/src/modules/hypr/window.cpp new file mode 100644 index 0000000..ca224fc --- /dev/null +++ b/src/modules/hypr/window.cpp @@ -0,0 +1,27 @@ +#include "modules/hypr/window.hpp" +#include "modules/hypr/ipc.hpp" + +using namespace waybar::util; + +waybar::modules::hypr::Window::Window(const std::string& id, const Json::Value& config) : ALabel(config, "window", id, "{window}", 0.5f) { + thread_ = [this] { + dp.emit(); + thread_.sleep_for(interval_); + }; +} + +auto waybar::modules::hypr::Window::update() -> void { + auto format = format_; + + std::string windowName = waybar::modules::hypr::makeRequest("activewindow"); + + if (windowName != "") + windowName = windowName.substr(windowName.find_first_of('>') + 2, windowName.find_first_of('\n') - windowName.find_first_of('>') - 3); + + event_box_.show(); + label_.set_markup(fmt::format(format, + fmt::arg("window", windowName))); + + // Call parent update + ALabel::update(); +}