From 812e689c772f6aee00ad54ce6b1165751f64c095 Mon Sep 17 00:00:00 2001 From: scorpion-26 <58082714+scorpion-26@users.noreply.github.com> Date: Mon, 30 Jan 2023 16:57:15 +0100 Subject: [PATCH] Disable opt. dependencies dynamically This lifts the requirement of needing to disable the dependencies by hand if you don't have them installed. It also enables us to have a single package, that works for all. --- README.md | 4 +-- meson.build | 16 +++++------ meson_options.txt | 8 +++--- src/Bar.cpp | 58 ++++++++++++++++++---------------------- src/BluetoothDevices.cpp | 2 +- src/Config.cpp | 6 +++++ src/Config.h | 25 +++++++++++++++++ src/Hyprland.h | 26 +++++++++++++++++- src/NvidiaGPU.h | 40 +++++++++++++++++++++++---- src/System.cpp | 46 ++++++++++++++++++++++++++----- src/System.h | 6 ++--- src/gBar.cpp | 13 +++++++-- 12 files changed, 186 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 55b4c66..bc9884b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ My personal blazingly fast and efficient status bar + widgets, in case anyone fi *gBar: **G**TK **Bar*** ## Prerequisites -*If you don't have the optional dependencies, some features are not available and you must manually disable them.* +*If you don't have the optional dependencies, some features are not available.* - wayland - Hyprland(Optional -> For workspaces widget) - nvidia-utils(Optional -> For GPU status) @@ -23,7 +23,7 @@ My personal blazingly fast and efficient status bar + widgets, in case anyone fi ``` *All optional dependencies are disabled* ``` - meson build --buildtype=release -DHasHyprland=false -DHasNvidia=false -DHasBlueZ=false + meson build --buildtype=release -DWithHyprland=false -DWithNvidia=false -DWithBlueZ=false ``` 4. Build and install ``` diff --git a/meson.build b/meson.build index 86862a0..7d42657 100644 --- a/meson.build +++ b/meson.build @@ -17,19 +17,19 @@ headers = [ 'src/Config.h' ] -if get_option('HasHyprland') - add_global_arguments('-DHAS_HYPRLAND', language: 'cpp') +if get_option('WithHyprland') + add_global_arguments('-DWITH_HYPRLAND', language: 'cpp') headers += 'src/Hyprland.h' endif -if get_option('HasNvidia') - add_global_arguments('-DHAS_NVIDIA', language: 'cpp') +if get_option('WithNvidia') + add_global_arguments('-DWITH_NVIDIA', language: 'cpp') headers += 'src/NvidiaGPU.h' endif -if get_option('HasBlueZ') - add_global_arguments('-DHAS_BLUEZ', language: 'cpp') +if get_option('WithBlueZ') + add_global_arguments('-DWITH_BLUEZ', language: 'cpp') endif -if get_option('HasSys') - add_global_arguments('-DHAS_SYS', language: 'cpp') +if get_option('WithSys') + add_global_arguments('-DWITH_SYS', language: 'cpp') endif pulse = dependency('libpulse') diff --git a/meson_options.txt b/meson_options.txt index 5488172..5407866 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,6 +1,6 @@ -option('HasHyprland', type: 'boolean', value : true) -option('HasNvidia', type: 'boolean', value : true) -option('HasBlueZ', type: 'boolean', value : true) +option('WithHyprland', type: 'boolean', value : true) +option('WithNvidia', type: 'boolean', value : true) +option('WithBlueZ', type: 'boolean', value : true) # You shouldn't enable this, unless you know what you are doing! -option('HasSys', type: 'boolean', value : false) +option('WithSys', type: 'boolean', value : false) diff --git a/src/Bar.cpp b/src/Bar.cpp index 8c39718..ca111e4 100644 --- a/src/Bar.cpp +++ b/src/Bar.cpp @@ -52,7 +52,7 @@ namespace Bar return TimerResult::Ok; } -#ifdef HAS_NVIDIA +#ifdef WITH_NVIDIA static Text* gpuText; static TimerResult UpdateGPU(CairoSensor& sensor) { @@ -87,7 +87,7 @@ namespace Bar return TimerResult::Ok; } -#ifdef HAS_BLUEZ +#ifdef WITH_BLUEZ static Button* btIconText; static Text* btDevText; static TimerResult UpdateBluetooth(Box&) @@ -161,7 +161,7 @@ namespace Bar return TimerResult::Ok; } -#ifdef HAS_HYPRLAND +#ifdef WITH_HYPRLAND static std::array workspaces; TimerResult UpdateWorkspaces(Box&) { @@ -169,21 +169,11 @@ namespace Bar { switch (System::GetWorkspaceStatus((uint32_t)monitorID, i + 1)) { - case System::WorkspaceStatus::Dead: - workspaces[i]->SetClass("ws-dead"); - break; - case System::WorkspaceStatus::Inactive: - workspaces[i]->SetClass("ws-inactive"); - break; - case System::WorkspaceStatus::Visible: - workspaces[i]->SetClass("ws-visible"); - break; - case System::WorkspaceStatus::Current: - workspaces[i]->SetClass("ws-current"); - break; - case System::WorkspaceStatus::Active: - workspaces[i]->SetClass("ws-active"); - break; + case System::WorkspaceStatus::Dead: workspaces[i]->SetClass("ws-dead"); break; + case System::WorkspaceStatus::Inactive: workspaces[i]->SetClass("ws-inactive"); break; + case System::WorkspaceStatus::Visible: workspaces[i]->SetClass("ws-visible"); break; + case System::WorkspaceStatus::Current: workspaces[i]->SetClass("ws-current"); break; + case System::WorkspaceStatus::Active: workspaces[i]->SetClass("ws-active"); break; } workspaces[i]->SetText(System::GetWorkspaceSymbol(i)); } @@ -256,7 +246,7 @@ namespace Bar parent.AddChild(std::move(box)); } -#ifdef HAS_BLUEZ +#ifdef WITH_BLUEZ void WidgetBluetooth(Widget& parent) { auto box = Widget::Create(); @@ -282,14 +272,18 @@ namespace Bar void WidgetSensors(Widget& parent) { Sensor(parent, DynCtx::UpdateDisk, "disk-util-progress", "disk-data-text", DynCtx::diskText); -#ifdef HAS_NVIDIA - Sensor(parent, DynCtx::UpdateVRAM, "vram-util-progress", "vram-data-text", DynCtx::vramText); - Sensor(parent, DynCtx::UpdateGPU, "gpu-util-progress", "gpu-data-text", DynCtx::gpuText); +#ifdef WITH_NVIDIA + if (RuntimeConfig::Get().hasNvidia) + { + Sensor(parent, DynCtx::UpdateVRAM, "vram-util-progress", "vram-data-text", DynCtx::vramText); + Sensor(parent, DynCtx::UpdateGPU, "gpu-util-progress", "gpu-data-text", DynCtx::gpuText); + } #endif Sensor(parent, DynCtx::UpdateRAM, "ram-util-progress", "ram-data-text", DynCtx::ramText); Sensor(parent, DynCtx::UpdateCPU, "cpu-util-progress", "cpu-data-text", DynCtx::cpuText); // Only show battery percentage if battery folder is set and exists - if (System::GetBatteryPercentage() >= 0) { + if (System::GetBatteryPercentage() >= 0) + { Sensor(parent, DynCtx::UpdateBattery, "battery-util-progress", "battery-data-text", DynCtx::batteryText); } } @@ -376,7 +370,7 @@ namespace Bar parent.AddChild(std::move(eventBox)); } -#ifdef HAS_HYPRLAND +#ifdef WITH_HYPRLAND void WidgetWorkspaces(Widget& parent) { auto margin = Widget::Create(); @@ -413,15 +407,14 @@ namespace Bar mainWidget->SetSpacing({0, Config::Get().centerTime}); mainWidget->SetClass("bar"); { -#ifdef HAS_HYPRLAND - auto left = Widget::Create(); - left->SetSpacing({0, false}); - left->SetHorizontalTransform({-1, true, Alignment::Left}); - WidgetWorkspaces(*left); -#else auto left = Widget::Create(); left->SetSpacing({0, false}); left->SetHorizontalTransform({-1, true, Alignment::Left}); +#ifdef WITH_HYPRLAND + if (RuntimeConfig::Get().hasHyprland) + { + WidgetWorkspaces(*left); + } #endif auto time = Widget::Create(); @@ -437,8 +430,9 @@ namespace Bar { WidgetAudio(*right); -#ifdef HAS_BLUEZ - WidgetBluetooth(*right); +#ifdef WITH_BLUEZ + if (RuntimeConfig::Get().hasBlueZ) + WidgetBluetooth(*right); #endif WidgetSensors(*right); diff --git a/src/BluetoothDevices.cpp b/src/BluetoothDevices.cpp index 449ff8e..a6e3f9f 100644 --- a/src/BluetoothDevices.cpp +++ b/src/BluetoothDevices.cpp @@ -5,7 +5,7 @@ #include #include -#ifdef HAS_BLUEZ +#ifdef WITH_BLUEZ namespace BluetoothDevices { namespace DynCtx diff --git a/src/Config.cpp b/src/Config.cpp index e8d0558..c693878 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -138,3 +138,9 @@ void Config::Load() } } } + +RuntimeConfig& RuntimeConfig::Get() +{ + static RuntimeConfig config; + return config; +} diff --git a/src/Config.h b/src/Config.h index 1be019b..0860381 100644 --- a/src/Config.h +++ b/src/Config.h @@ -18,3 +18,28 @@ public: static void Load(); static const Config& Get(); }; + +// Configs, that rely on specific files to be available(e.g. Hyprland running) +class RuntimeConfig +{ +public: +#ifdef WITH_NVIDIA + bool hasNvidia = true; +#else + bool hasNvidia = false; +#endif + +#ifdef WITH_HYPRLAND + bool hasHyprland = true; +#else + bool hasHyprland = false; +#endif + +#ifdef WITH_BLUEZ + bool hasBlueZ = true; +#else + bool hasBlueZ = false; +#endif + + static RuntimeConfig& Get(); +}; diff --git a/src/Hyprland.h b/src/Hyprland.h index 900d211..09f97ed 100644 --- a/src/Hyprland.h +++ b/src/Hyprland.h @@ -1,6 +1,7 @@ #pragma once #include "Common.h" #include "System.h" +#include "Config.h" #include #include @@ -10,9 +11,19 @@ #include #include -#ifdef HAS_HYPRLAND +#ifdef WITH_HYPRLAND namespace Hyprland { + inline void Init() + { + if (!getenv("HYPRLAND_INSTANCE_SIGNATURE")) + { + LOG("Hyprland not running, disabling workspaces"); + // Not available + RuntimeConfig::Get().hasHyprland = false; + } + } + inline std::string DispatchIPC(const std::string& arg) { int hyprSocket = socket(AF_UNIX, SOCK_STREAM, 0); @@ -46,6 +57,12 @@ namespace Hyprland inline System::WorkspaceStatus GetStatus(uint32_t monitorID, uint32_t workspaceId) { + if (RuntimeConfig::Get().hasHyprland == false) + { + LOG("Error: Queried for workspace status, but Hyprland isn't open!"); + return System::WorkspaceStatus::Dead; + } + std::string workspaces = DispatchIPC("/workspaces"); if (workspaces.find("workspace ID " + std::to_string(workspaceId)) == std::string::npos) { @@ -87,8 +104,15 @@ namespace Hyprland return System::WorkspaceStatus::Inactive; } } + inline void Goto(uint32_t workspace) { + if (RuntimeConfig::Get().hasHyprland == false) + { + LOG("Error: Called Go to workspace, but Hyprland isn't open!"); + return; + } + system(("hyprctl dispatch workspace " + std::to_string(workspace)).c_str()); } } diff --git a/src/NvidiaGPU.h b/src/NvidiaGPU.h index f9fe3e1..4ad0a3e 100644 --- a/src/NvidiaGPU.h +++ b/src/NvidiaGPU.h @@ -1,8 +1,10 @@ #pragma once #include "Common.h" +#include "Config.h" + #include -#ifdef HAS_NVIDIA +#ifdef WITH_NVIDIA namespace NvidiaGPU { static void* nvmldl; @@ -11,9 +13,18 @@ namespace NvidiaGPU inline void Init() { - if (nvmldl) return; + if (nvmldl || !RuntimeConfig::Get().hasNvidia) + return; + nvmldl = dlopen("libnvidia-ml.so", RTLD_NOW); - ASSERT(nvmldl, "Cannot open libnvidia-ml.so"); + // nvmldl not found. Nvidia probably not installed + if (!nvmldl) + { + LOG("NVML not found, disabling Nvidia GPU"); + RuntimeConfig::Get().hasNvidia = false; + return; + } + typedef int (*PFN_nvmlInit)(); auto nvmlInit = (PFN_nvmlInit)dlsym(nvmldl, "nvmlInit"); int res = nvmlInit(); @@ -25,10 +36,11 @@ namespace NvidiaGPU res = nvmlDeviceGetHandle(0, &nvmlGPUHandle); ASSERT(res == 0, "Failed getting device"); } - + inline void Shutdown() { - dlclose(nvmldl); + if (nvmldl) + dlclose(nvmldl); } struct GPUUtilization @@ -45,6 +57,12 @@ namespace NvidiaGPU inline GPUUtilization GetUtilization() { + if (!RuntimeConfig::Get().hasNvidia) + { + LOG("Error: Called Nvidia GetUtilization, but nvml wasn't found!"); + return {}; + } + GPUUtilization util; typedef int (*PFN_nvmlDeviceGetUtilizationRates)(void*, GPUUtilization*); auto nvmlDeviceGetUtilizationRates = (PFN_nvmlDeviceGetUtilizationRates)dlsym(nvmldl, "nvmlDeviceGetUtilizationRates"); @@ -56,6 +74,12 @@ namespace NvidiaGPU inline uint32_t GetTemperature() { + if (!RuntimeConfig::Get().hasNvidia) + { + LOG("Error: Called Nvidia GetTemperature, but nvml wasn't found!"); + return {}; + } + typedef int (*PFN_nvmlDeviceGetTemperature)(void*, uint32_t, uint32_t*); auto nvmlDeviceGetTemperature = (PFN_nvmlDeviceGetTemperature)dlsym(nvmldl, "nvmlDeviceGetTemperature"); uint32_t temp; @@ -66,6 +90,12 @@ namespace NvidiaGPU inline VRAM GetVRAM() { + if (!RuntimeConfig::Get().hasNvidia) + { + LOG("Error: Called Nvidia GetVRAM, but nvml wasn't found!"); + return {}; + } + typedef int (*PFN_nvmlDeviceGetMemoryInfo)(void*, VRAM*); auto nvmlDeviceGetMemoryInfo = (PFN_nvmlDeviceGetMemoryInfo)dlsym(nvmldl, "nvmlDeviceGetMemoryInfo"); VRAM mem; diff --git a/src/System.cpp b/src/System.cpp index 063b9fa..048cc61 100644 --- a/src/System.cpp +++ b/src/System.cpp @@ -133,7 +133,7 @@ namespace System return out; } -#ifdef HAS_NVIDIA +#ifdef WITH_NVIDIA GPUInfo GetGPUInfo() { NvidiaGPU::GPUUtilization util = NvidiaGPU::GetUtilization(); @@ -165,10 +165,33 @@ namespace System return out; } -#ifdef HAS_BLUEZ +#ifdef WITH_BLUEZ + void InitBluetooth() + { + // Try connecting to d-bus and org.bluez + GDBusConnection* connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, nullptr); + ASSERT(connection, "Failed to connect to d-bus!"); + + GError* err = nullptr; + GVariant* objects = g_dbus_connection_call_sync(connection, "org.bluez", "/", "org.freedesktop.DBus.ObjectManager", "GetManagedObjects", + nullptr, G_VARIANT_TYPE("(a{oa{sa{sv}}})"), G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &err); + if (!objects) + { + LOG("Can't connect to BlueZ d-bus! Disabling Bluetooth!"); + LOG(err->message); + g_error_free(err); + // Not found, disable bluetooth + RuntimeConfig::Get().hasBlueZ = false; + } + } BluetoothInfo GetBluetoothInfo() { BluetoothInfo out{}; + if (!RuntimeConfig::Get().hasBlueZ) + { + LOG("Error: GetBluetoothInfo called, but bluetooth isn't available"); + return out; + } // Init D-Bus GDBusConnection* connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, nullptr); ASSERT(connection, "Failed to connect to d-bus!"); @@ -381,7 +404,7 @@ namespace System PulseAudio::SetVolume(volume); } -#ifdef HAS_HYPRLAND +#ifdef WITH_HYPRLAND WorkspaceStatus GetWorkspaceStatus(uint32_t monitor, uint32_t workspace) { return Hyprland::GetStatus(monitor, workspace); @@ -441,18 +464,29 @@ namespace System void Init() { Config::Load(); -#ifdef HAS_NVIDIA + +#ifdef WITH_NVIDIA NvidiaGPU::Init(); #endif + +#ifdef WITH_HYPRLAND + Hyprland::Init(); +#endif + +#ifdef WITH_BLUEZ + InitBluetooth(); +#endif + PulseAudio::Init(); } void FreeResources() { -#ifdef HAS_NVIDIA +#ifdef WITH_NVIDIA NvidiaGPU::Shutdown(); #endif PulseAudio::Shutdown(); -#ifdef HAS_BLUEZ + +#ifdef WITH_BLUEZ StopBTScan(); #endif } diff --git a/src/System.h b/src/System.h index fbae1a4..2a5f73d 100644 --- a/src/System.h +++ b/src/System.h @@ -19,7 +19,7 @@ namespace System }; RAMInfo GetRAMInfo(); -#ifdef HAS_NVIDIA +#ifdef WITH_NVIDIA struct GPUInfo { double utilisation; @@ -42,7 +42,7 @@ namespace System }; DiskInfo GetDiskInfo(); -#ifdef HAS_BLUEZ +#ifdef WITH_BLUEZ struct BluetoothDevice { bool connected; @@ -79,7 +79,7 @@ namespace System AudioInfo GetAudioInfo(); void SetVolume(double volume); -#ifdef HAS_HYPRLAND +#ifdef WITH_HYPRLAND enum class WorkspaceStatus { Dead, diff --git a/src/gBar.cpp b/src/gBar.cpp index ea02e4f..ea3c781 100644 --- a/src/gBar.cpp +++ b/src/gBar.cpp @@ -5,6 +5,7 @@ #include "AudioFlyin.h" #include "BluetoothDevices.h" #include "Plugin.h" +#include "Config.h" #include #include @@ -43,10 +44,18 @@ int main(int argc, char** argv) exit(0); } } -#ifdef HAS_BLUEZ +#ifdef WITH_BLUEZ else if (strcmp(argv[1], "bluetooth") == 0) { - BluetoothDevices::Create(window, monitor); + if (RuntimeConfig::Get().hasBlueZ) + { + BluetoothDevices::Create(window, monitor); + } + else + { + LOG("Blutooth disabled, cannot open bluetooth widget!"); + exit(1); + } } #endif else