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.
This commit is contained in:
scorpion-26 2023-01-30 16:57:15 +01:00
parent 9aaf6d1884
commit 812e689c77
12 changed files with 186 additions and 64 deletions

View file

@ -4,7 +4,7 @@ My personal blazingly fast and efficient status bar + widgets, in case anyone fi
*gBar: **G**TK **Bar*** *gBar: **G**TK **Bar***
## Prerequisites ## 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 - wayland
- Hyprland(Optional -> For workspaces widget) - Hyprland(Optional -> For workspaces widget)
- nvidia-utils(Optional -> For GPU status) - 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* *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 4. Build and install
``` ```

View file

@ -17,19 +17,19 @@ headers = [
'src/Config.h' 'src/Config.h'
] ]
if get_option('HasHyprland') if get_option('WithHyprland')
add_global_arguments('-DHAS_HYPRLAND', language: 'cpp') add_global_arguments('-DWITH_HYPRLAND', language: 'cpp')
headers += 'src/Hyprland.h' headers += 'src/Hyprland.h'
endif endif
if get_option('HasNvidia') if get_option('WithNvidia')
add_global_arguments('-DHAS_NVIDIA', language: 'cpp') add_global_arguments('-DWITH_NVIDIA', language: 'cpp')
headers += 'src/NvidiaGPU.h' headers += 'src/NvidiaGPU.h'
endif endif
if get_option('HasBlueZ') if get_option('WithBlueZ')
add_global_arguments('-DHAS_BLUEZ', language: 'cpp') add_global_arguments('-DWITH_BLUEZ', language: 'cpp')
endif endif
if get_option('HasSys') if get_option('WithSys')
add_global_arguments('-DHAS_SYS', language: 'cpp') add_global_arguments('-DWITH_SYS', language: 'cpp')
endif endif
pulse = dependency('libpulse') pulse = dependency('libpulse')

View file

@ -1,6 +1,6 @@
option('HasHyprland', type: 'boolean', value : true) option('WithHyprland', type: 'boolean', value : true)
option('HasNvidia', type: 'boolean', value : true) option('WithNvidia', type: 'boolean', value : true)
option('HasBlueZ', type: 'boolean', value : true) option('WithBlueZ', type: 'boolean', value : true)
# You shouldn't enable this, unless you know what you are doing! # You shouldn't enable this, unless you know what you are doing!
option('HasSys', type: 'boolean', value : false) option('WithSys', type: 'boolean', value : false)

View file

@ -52,7 +52,7 @@ namespace Bar
return TimerResult::Ok; return TimerResult::Ok;
} }
#ifdef HAS_NVIDIA #ifdef WITH_NVIDIA
static Text* gpuText; static Text* gpuText;
static TimerResult UpdateGPU(CairoSensor& sensor) static TimerResult UpdateGPU(CairoSensor& sensor)
{ {
@ -87,7 +87,7 @@ namespace Bar
return TimerResult::Ok; return TimerResult::Ok;
} }
#ifdef HAS_BLUEZ #ifdef WITH_BLUEZ
static Button* btIconText; static Button* btIconText;
static Text* btDevText; static Text* btDevText;
static TimerResult UpdateBluetooth(Box&) static TimerResult UpdateBluetooth(Box&)
@ -161,7 +161,7 @@ namespace Bar
return TimerResult::Ok; return TimerResult::Ok;
} }
#ifdef HAS_HYPRLAND #ifdef WITH_HYPRLAND
static std::array<Button*, 9> workspaces; static std::array<Button*, 9> workspaces;
TimerResult UpdateWorkspaces(Box&) TimerResult UpdateWorkspaces(Box&)
{ {
@ -169,21 +169,11 @@ namespace Bar
{ {
switch (System::GetWorkspaceStatus((uint32_t)monitorID, i + 1)) switch (System::GetWorkspaceStatus((uint32_t)monitorID, i + 1))
{ {
case System::WorkspaceStatus::Dead: case System::WorkspaceStatus::Dead: workspaces[i]->SetClass("ws-dead"); break;
workspaces[i]->SetClass("ws-dead"); case System::WorkspaceStatus::Inactive: workspaces[i]->SetClass("ws-inactive"); break;
break; case System::WorkspaceStatus::Visible: workspaces[i]->SetClass("ws-visible"); break;
case System::WorkspaceStatus::Inactive: case System::WorkspaceStatus::Current: workspaces[i]->SetClass("ws-current"); break;
workspaces[i]->SetClass("ws-inactive"); case System::WorkspaceStatus::Active: workspaces[i]->SetClass("ws-active"); break;
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)); workspaces[i]->SetText(System::GetWorkspaceSymbol(i));
} }
@ -256,7 +246,7 @@ namespace Bar
parent.AddChild(std::move(box)); parent.AddChild(std::move(box));
} }
#ifdef HAS_BLUEZ #ifdef WITH_BLUEZ
void WidgetBluetooth(Widget& parent) void WidgetBluetooth(Widget& parent)
{ {
auto box = Widget::Create<Box>(); auto box = Widget::Create<Box>();
@ -282,14 +272,18 @@ namespace Bar
void WidgetSensors(Widget& parent) void WidgetSensors(Widget& parent)
{ {
Sensor(parent, DynCtx::UpdateDisk, "disk-util-progress", "disk-data-text", DynCtx::diskText); Sensor(parent, DynCtx::UpdateDisk, "disk-util-progress", "disk-data-text", DynCtx::diskText);
#ifdef HAS_NVIDIA #ifdef WITH_NVIDIA
Sensor(parent, DynCtx::UpdateVRAM, "vram-util-progress", "vram-data-text", DynCtx::vramText); if (RuntimeConfig::Get().hasNvidia)
Sensor(parent, DynCtx::UpdateGPU, "gpu-util-progress", "gpu-data-text", DynCtx::gpuText); {
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 #endif
Sensor(parent, DynCtx::UpdateRAM, "ram-util-progress", "ram-data-text", DynCtx::ramText); Sensor(parent, DynCtx::UpdateRAM, "ram-util-progress", "ram-data-text", DynCtx::ramText);
Sensor(parent, DynCtx::UpdateCPU, "cpu-util-progress", "cpu-data-text", DynCtx::cpuText); Sensor(parent, DynCtx::UpdateCPU, "cpu-util-progress", "cpu-data-text", DynCtx::cpuText);
// Only show battery percentage if battery folder is set and exists // 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); Sensor(parent, DynCtx::UpdateBattery, "battery-util-progress", "battery-data-text", DynCtx::batteryText);
} }
} }
@ -376,7 +370,7 @@ namespace Bar
parent.AddChild(std::move(eventBox)); parent.AddChild(std::move(eventBox));
} }
#ifdef HAS_HYPRLAND #ifdef WITH_HYPRLAND
void WidgetWorkspaces(Widget& parent) void WidgetWorkspaces(Widget& parent)
{ {
auto margin = Widget::Create<Box>(); auto margin = Widget::Create<Box>();
@ -413,15 +407,14 @@ namespace Bar
mainWidget->SetSpacing({0, Config::Get().centerTime}); mainWidget->SetSpacing({0, Config::Get().centerTime});
mainWidget->SetClass("bar"); mainWidget->SetClass("bar");
{ {
#ifdef HAS_HYPRLAND
auto left = Widget::Create<Box>();
left->SetSpacing({0, false});
left->SetHorizontalTransform({-1, true, Alignment::Left});
WidgetWorkspaces(*left);
#else
auto left = Widget::Create<Box>(); auto left = Widget::Create<Box>();
left->SetSpacing({0, false}); left->SetSpacing({0, false});
left->SetHorizontalTransform({-1, true, Alignment::Left}); left->SetHorizontalTransform({-1, true, Alignment::Left});
#ifdef WITH_HYPRLAND
if (RuntimeConfig::Get().hasHyprland)
{
WidgetWorkspaces(*left);
}
#endif #endif
auto time = Widget::Create<Text>(); auto time = Widget::Create<Text>();
@ -437,8 +430,9 @@ namespace Bar
{ {
WidgetAudio(*right); WidgetAudio(*right);
#ifdef HAS_BLUEZ #ifdef WITH_BLUEZ
WidgetBluetooth(*right); if (RuntimeConfig::Get().hasBlueZ)
WidgetBluetooth(*right);
#endif #endif
WidgetSensors(*right); WidgetSensors(*right);

View file

@ -5,7 +5,7 @@
#include <string> #include <string>
#include <algorithm> #include <algorithm>
#ifdef HAS_BLUEZ #ifdef WITH_BLUEZ
namespace BluetoothDevices namespace BluetoothDevices
{ {
namespace DynCtx namespace DynCtx

View file

@ -138,3 +138,9 @@ void Config::Load()
} }
} }
} }
RuntimeConfig& RuntimeConfig::Get()
{
static RuntimeConfig config;
return config;
}

View file

@ -18,3 +18,28 @@ public:
static void Load(); static void Load();
static const Config& Get(); 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();
};

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "Common.h" #include "Common.h"
#include "System.h" #include "System.h"
#include "Config.h"
#include <cstdint> #include <cstdint>
#include <string> #include <string>
@ -10,9 +11,19 @@
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h> #include <unistd.h>
#ifdef HAS_HYPRLAND #ifdef WITH_HYPRLAND
namespace 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) inline std::string DispatchIPC(const std::string& arg)
{ {
int hyprSocket = socket(AF_UNIX, SOCK_STREAM, 0); int hyprSocket = socket(AF_UNIX, SOCK_STREAM, 0);
@ -46,6 +57,12 @@ namespace Hyprland
inline System::WorkspaceStatus GetStatus(uint32_t monitorID, uint32_t workspaceId) 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"); std::string workspaces = DispatchIPC("/workspaces");
if (workspaces.find("workspace ID " + std::to_string(workspaceId)) == std::string::npos) if (workspaces.find("workspace ID " + std::to_string(workspaceId)) == std::string::npos)
{ {
@ -87,8 +104,15 @@ namespace Hyprland
return System::WorkspaceStatus::Inactive; return System::WorkspaceStatus::Inactive;
} }
} }
inline void Goto(uint32_t workspace) 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()); system(("hyprctl dispatch workspace " + std::to_string(workspace)).c_str());
} }
} }

View file

@ -1,8 +1,10 @@
#pragma once #pragma once
#include "Common.h" #include "Common.h"
#include "Config.h"
#include <dlfcn.h> #include <dlfcn.h>
#ifdef HAS_NVIDIA #ifdef WITH_NVIDIA
namespace NvidiaGPU namespace NvidiaGPU
{ {
static void* nvmldl; static void* nvmldl;
@ -11,9 +13,18 @@ namespace NvidiaGPU
inline void Init() inline void Init()
{ {
if (nvmldl) return; if (nvmldl || !RuntimeConfig::Get().hasNvidia)
return;
nvmldl = dlopen("libnvidia-ml.so", RTLD_NOW); 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)(); typedef int (*PFN_nvmlInit)();
auto nvmlInit = (PFN_nvmlInit)dlsym(nvmldl, "nvmlInit"); auto nvmlInit = (PFN_nvmlInit)dlsym(nvmldl, "nvmlInit");
int res = nvmlInit(); int res = nvmlInit();
@ -28,7 +39,8 @@ namespace NvidiaGPU
inline void Shutdown() inline void Shutdown()
{ {
dlclose(nvmldl); if (nvmldl)
dlclose(nvmldl);
} }
struct GPUUtilization struct GPUUtilization
@ -45,6 +57,12 @@ namespace NvidiaGPU
inline GPUUtilization GetUtilization() inline GPUUtilization GetUtilization()
{ {
if (!RuntimeConfig::Get().hasNvidia)
{
LOG("Error: Called Nvidia GetUtilization, but nvml wasn't found!");
return {};
}
GPUUtilization util; GPUUtilization util;
typedef int (*PFN_nvmlDeviceGetUtilizationRates)(void*, GPUUtilization*); typedef int (*PFN_nvmlDeviceGetUtilizationRates)(void*, GPUUtilization*);
auto nvmlDeviceGetUtilizationRates = (PFN_nvmlDeviceGetUtilizationRates)dlsym(nvmldl, "nvmlDeviceGetUtilizationRates"); auto nvmlDeviceGetUtilizationRates = (PFN_nvmlDeviceGetUtilizationRates)dlsym(nvmldl, "nvmlDeviceGetUtilizationRates");
@ -56,6 +74,12 @@ namespace NvidiaGPU
inline uint32_t GetTemperature() 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*); typedef int (*PFN_nvmlDeviceGetTemperature)(void*, uint32_t, uint32_t*);
auto nvmlDeviceGetTemperature = (PFN_nvmlDeviceGetTemperature)dlsym(nvmldl, "nvmlDeviceGetTemperature"); auto nvmlDeviceGetTemperature = (PFN_nvmlDeviceGetTemperature)dlsym(nvmldl, "nvmlDeviceGetTemperature");
uint32_t temp; uint32_t temp;
@ -66,6 +90,12 @@ namespace NvidiaGPU
inline VRAM GetVRAM() inline VRAM GetVRAM()
{ {
if (!RuntimeConfig::Get().hasNvidia)
{
LOG("Error: Called Nvidia GetVRAM, but nvml wasn't found!");
return {};
}
typedef int (*PFN_nvmlDeviceGetMemoryInfo)(void*, VRAM*); typedef int (*PFN_nvmlDeviceGetMemoryInfo)(void*, VRAM*);
auto nvmlDeviceGetMemoryInfo = (PFN_nvmlDeviceGetMemoryInfo)dlsym(nvmldl, "nvmlDeviceGetMemoryInfo"); auto nvmlDeviceGetMemoryInfo = (PFN_nvmlDeviceGetMemoryInfo)dlsym(nvmldl, "nvmlDeviceGetMemoryInfo");
VRAM mem; VRAM mem;

View file

@ -133,7 +133,7 @@ namespace System
return out; return out;
} }
#ifdef HAS_NVIDIA #ifdef WITH_NVIDIA
GPUInfo GetGPUInfo() GPUInfo GetGPUInfo()
{ {
NvidiaGPU::GPUUtilization util = NvidiaGPU::GetUtilization(); NvidiaGPU::GPUUtilization util = NvidiaGPU::GetUtilization();
@ -165,10 +165,33 @@ namespace System
return out; 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 GetBluetoothInfo()
{ {
BluetoothInfo out{}; BluetoothInfo out{};
if (!RuntimeConfig::Get().hasBlueZ)
{
LOG("Error: GetBluetoothInfo called, but bluetooth isn't available");
return out;
}
// Init D-Bus // Init D-Bus
GDBusConnection* connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, nullptr); GDBusConnection* connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, nullptr);
ASSERT(connection, "Failed to connect to d-bus!"); ASSERT(connection, "Failed to connect to d-bus!");
@ -381,7 +404,7 @@ namespace System
PulseAudio::SetVolume(volume); PulseAudio::SetVolume(volume);
} }
#ifdef HAS_HYPRLAND #ifdef WITH_HYPRLAND
WorkspaceStatus GetWorkspaceStatus(uint32_t monitor, uint32_t workspace) WorkspaceStatus GetWorkspaceStatus(uint32_t monitor, uint32_t workspace)
{ {
return Hyprland::GetStatus(monitor, workspace); return Hyprland::GetStatus(monitor, workspace);
@ -441,18 +464,29 @@ namespace System
void Init() void Init()
{ {
Config::Load(); Config::Load();
#ifdef HAS_NVIDIA
#ifdef WITH_NVIDIA
NvidiaGPU::Init(); NvidiaGPU::Init();
#endif #endif
#ifdef WITH_HYPRLAND
Hyprland::Init();
#endif
#ifdef WITH_BLUEZ
InitBluetooth();
#endif
PulseAudio::Init(); PulseAudio::Init();
} }
void FreeResources() void FreeResources()
{ {
#ifdef HAS_NVIDIA #ifdef WITH_NVIDIA
NvidiaGPU::Shutdown(); NvidiaGPU::Shutdown();
#endif #endif
PulseAudio::Shutdown(); PulseAudio::Shutdown();
#ifdef HAS_BLUEZ
#ifdef WITH_BLUEZ
StopBTScan(); StopBTScan();
#endif #endif
} }

View file

@ -19,7 +19,7 @@ namespace System
}; };
RAMInfo GetRAMInfo(); RAMInfo GetRAMInfo();
#ifdef HAS_NVIDIA #ifdef WITH_NVIDIA
struct GPUInfo struct GPUInfo
{ {
double utilisation; double utilisation;
@ -42,7 +42,7 @@ namespace System
}; };
DiskInfo GetDiskInfo(); DiskInfo GetDiskInfo();
#ifdef HAS_BLUEZ #ifdef WITH_BLUEZ
struct BluetoothDevice struct BluetoothDevice
{ {
bool connected; bool connected;
@ -79,7 +79,7 @@ namespace System
AudioInfo GetAudioInfo(); AudioInfo GetAudioInfo();
void SetVolume(double volume); void SetVolume(double volume);
#ifdef HAS_HYPRLAND #ifdef WITH_HYPRLAND
enum class WorkspaceStatus enum class WorkspaceStatus
{ {
Dead, Dead,

View file

@ -5,6 +5,7 @@
#include "AudioFlyin.h" #include "AudioFlyin.h"
#include "BluetoothDevices.h" #include "BluetoothDevices.h"
#include "Plugin.h" #include "Plugin.h"
#include "Config.h"
#include <cmath> #include <cmath>
#include <cstdio> #include <cstdio>
@ -43,10 +44,18 @@ int main(int argc, char** argv)
exit(0); exit(0);
} }
} }
#ifdef HAS_BLUEZ #ifdef WITH_BLUEZ
else if (strcmp(argv[1], "bluetooth") == 0) 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 #endif
else else