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***
## 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
```

View file

@ -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')

View file

@ -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)

View file

@ -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<Button*, 9> 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<Box>();
@ -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<Box>();
@ -413,15 +407,14 @@ namespace Bar
mainWidget->SetSpacing({0, Config::Get().centerTime});
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>();
left->SetSpacing({0, false});
left->SetHorizontalTransform({-1, true, Alignment::Left});
#ifdef WITH_HYPRLAND
if (RuntimeConfig::Get().hasHyprland)
{
WidgetWorkspaces(*left);
}
#endif
auto time = Widget::Create<Text>();
@ -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);

View file

@ -5,7 +5,7 @@
#include <string>
#include <algorithm>
#ifdef HAS_BLUEZ
#ifdef WITH_BLUEZ
namespace BluetoothDevices
{
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 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
#include "Common.h"
#include "System.h"
#include "Config.h"
#include <cstdint>
#include <string>
@ -10,9 +11,19 @@
#include <sys/un.h>
#include <unistd.h>
#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());
}
}

View file

@ -1,8 +1,10 @@
#pragma once
#include "Common.h"
#include "Config.h"
#include <dlfcn.h>
#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;

View file

@ -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
}

View file

@ -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,

View file

@ -5,6 +5,7 @@
#include "AudioFlyin.h"
#include "BluetoothDevices.h"
#include "Plugin.h"
#include "Config.h"
#include <cmath>
#include <cstdio>
@ -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