suckle
This commit is contained in:
parent
e7372afa2f
commit
ea13e2fc57
13
flake.lock
13
flake.lock
|
@ -2,15 +2,16 @@
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1738611518,
|
"lastModified": 1739863612,
|
||||||
"narHash": "sha256-gOP/qsGtUCTkazx3qQ/tn6xaDERRgOtF2eRe1gmIU5s=",
|
"narHash": "sha256-UbtgxplOhFcyjBcNbTVO8+HUHAl/WXFDOb6LvqShiZo=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "eb3431789cef743af9dace58eb2ba7b33a332b56",
|
"rev": "632f04521e847173c54fa72973ec6c39a371211c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
@ -58,11 +59,11 @@
|
||||||
"nixpkgs": "nixpkgs_2"
|
"nixpkgs": "nixpkgs_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1738070913,
|
"lastModified": 1739829690,
|
||||||
"narHash": "sha256-j6jC12vCFsTGDmY2u1H12lMr62fnclNjuCtAdF1a4Nk=",
|
"narHash": "sha256-mL1szCeIsjh6Khn3nH2cYtwO5YXG6gBiTw1A30iGeDU=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "treefmt-nix",
|
"repo": "treefmt-nix",
|
||||||
"rev": "bebf27d00f7d10ba75332a0541ac43676985dea3",
|
"rev": "3d0579f5cc93436052d94b73925b48973a104204",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
28
flake.nix
28
flake.nix
|
@ -2,7 +2,7 @@
|
||||||
description = "C/C++ environment";
|
description = "C/C++ environment";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
treefmt-nix.url = "github:numtide/treefmt-nix";
|
treefmt-nix.url = "github:numtide/treefmt-nix";
|
||||||
utils.url = "github:numtide/flake-utils";
|
utils.url = "github:numtide/flake-utils";
|
||||||
};
|
};
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
then stdenvAdapters.useMoldLinker
|
then stdenvAdapters.useMoldLinker
|
||||||
else lib.id
|
else lib.id
|
||||||
)
|
)
|
||||||
llvmPackages_19.stdenv;
|
llvmPackages_20.stdenv;
|
||||||
|
|
||||||
sources = import ./_sources/generated.nix {
|
sources = import ./_sources/generated.nix {
|
||||||
inherit (pkgs) fetchFromGitHub fetchgit fetchurl dockerTools;
|
inherit (pkgs) fetchFromGitHub fetchgit fetchurl dockerTools;
|
||||||
|
@ -36,7 +36,6 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
fmt = mkPkg "fmt";
|
fmt = mkPkg "fmt";
|
||||||
yyjson = mkPkg "yyjson";
|
|
||||||
|
|
||||||
tomlplusplus = pkgs.pkgsStatic.tomlplusplus.overrideAttrs {
|
tomlplusplus = pkgs.pkgsStatic.tomlplusplus.overrideAttrs {
|
||||||
inherit (sources.tomlplusplus) pname version src;
|
inherit (sources.tomlplusplus) pname version src;
|
||||||
|
@ -45,6 +44,17 @@
|
||||||
|
|
||||||
sdbus-cpp = pkgs.sdbus-cpp.overrideAttrs {
|
sdbus-cpp = pkgs.sdbus-cpp.overrideAttrs {
|
||||||
inherit (sources.sdbus-cpp) pname version src;
|
inherit (sources.sdbus-cpp) pname version src;
|
||||||
|
|
||||||
|
cmakeFlags = [
|
||||||
|
(pkgs.lib.cmakeBool "BUILD_CODE_GEN" true)
|
||||||
|
(pkgs.lib.cmakeBool "BUILD_SHARED_LIBS" false)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
yyjson = pkgs.pkgsStatic.stdenv.mkDerivation {
|
||||||
|
inherit (sources.yyjson) pname version src;
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [cmake ninja pkg-config];
|
||||||
};
|
};
|
||||||
|
|
||||||
reflect-cpp = stdenv.mkDerivation rec {
|
reflect-cpp = stdenv.mkDerivation rec {
|
||||||
|
@ -57,6 +67,7 @@
|
||||||
"-DCMAKE_TOOLCHAIN_FILE=OFF"
|
"-DCMAKE_TOOLCHAIN_FILE=OFF"
|
||||||
"-DREFLECTCPP_TOML=ON"
|
"-DREFLECTCPP_TOML=ON"
|
||||||
"-DREFLECTCPP_JSON=ON"
|
"-DREFLECTCPP_JSON=ON"
|
||||||
|
"-DREFLECTCPP_USE_STD_EXPECTED=ON"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,19 +81,20 @@
|
||||||
reflect-cpp
|
reflect-cpp
|
||||||
sqlitecpp
|
sqlitecpp
|
||||||
ftxui
|
ftxui
|
||||||
|
libunistring
|
||||||
]
|
]
|
||||||
++ linuxPkgs
|
++ linuxPkgs
|
||||||
++ darwinPkgs;
|
++ darwinPkgs;
|
||||||
|
|
||||||
linuxPkgs = nixpkgs.lib.optionals stdenv.isLinux (with pkgs;
|
linuxPkgs = nixpkgs.lib.optionals stdenv.isLinux (with pkgs;
|
||||||
[
|
[
|
||||||
pkgsStatic.glib
|
|
||||||
systemdLibs
|
systemdLibs
|
||||||
sdbus-cpp
|
|
||||||
valgrind
|
valgrind
|
||||||
xorg.libX11
|
|
||||||
]
|
]
|
||||||
++ (with pkgsStatic; [
|
++ (with pkgsStatic; [
|
||||||
|
glib
|
||||||
|
sdbus-cpp
|
||||||
|
xorg.libX11
|
||||||
wayland
|
wayland
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
@ -133,7 +145,7 @@
|
||||||
|
|
||||||
clang-format = {
|
clang-format = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.clang-tools_19;
|
package = pkgs.llvmPackages_20.clang-tools;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -143,7 +155,7 @@
|
||||||
[
|
[
|
||||||
alejandra
|
alejandra
|
||||||
bear
|
bear
|
||||||
clang-tools_19
|
llvmPackages_20.clang-tools
|
||||||
cmake
|
cmake
|
||||||
lldb
|
lldb
|
||||||
hyperfine
|
hyperfine
|
||||||
|
|
|
@ -49,6 +49,7 @@ common_cpp_args = [
|
||||||
'-Wunused-function',
|
'-Wunused-function',
|
||||||
'-fvisibility=hidden',
|
'-fvisibility=hidden',
|
||||||
'-fno-strict-enums',
|
'-fno-strict-enums',
|
||||||
|
'-nostdlib++',
|
||||||
]
|
]
|
||||||
|
|
||||||
if host_machine.system() == 'windows'
|
if host_machine.system() == 'windows'
|
||||||
|
@ -60,7 +61,7 @@ add_project_arguments(cpp.get_supported_arguments(common_cpp_args), language: 'c
|
||||||
source_file_names = ['src/main.cpp', 'src/config/config.cpp', 'src/config/weather.cpp']
|
source_file_names = ['src/main.cpp', 'src/config/config.cpp', 'src/config/weather.cpp']
|
||||||
|
|
||||||
if host_machine.system() == 'linux'
|
if host_machine.system() == 'linux'
|
||||||
source_file_names += ['src/os/linux.cpp']
|
source_file_names += ['src/os/linux.cpp', 'src/os/linux/issetugid_stub.cpp']
|
||||||
elif host_machine.system() == 'freebsd'
|
elif host_machine.system() == 'freebsd'
|
||||||
source_file_names += ['src/os/freebsd.cpp']
|
source_file_names += ['src/os/freebsd.cpp']
|
||||||
elif host_machine.system() == 'darwin'
|
elif host_machine.system() == 'darwin'
|
||||||
|
@ -106,6 +107,9 @@ elif host_machine.system() == 'linux' or host_machine.system() == 'freebsd'
|
||||||
deps += dependency('SQLiteCpp')
|
deps += dependency('SQLiteCpp')
|
||||||
deps += dependency('sdbus-c++')
|
deps += dependency('sdbus-c++')
|
||||||
deps += dependency('x11')
|
deps += dependency('x11')
|
||||||
|
deps += dependency('xcb')
|
||||||
|
deps += dependency('xau')
|
||||||
|
deps += dependency('xdmcp')
|
||||||
deps += dependency('wayland-client')
|
deps += dependency('wayland-client')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -114,6 +118,8 @@ link_args = []
|
||||||
|
|
||||||
if host_machine.system() == 'darwin'
|
if host_machine.system() == 'darwin'
|
||||||
objc_args += ['-fobjc-arc']
|
objc_args += ['-fobjc-arc']
|
||||||
|
elif host_machine.system() == 'linux'
|
||||||
|
link_args += ['-static-libgcc', '-static-libstdc++']
|
||||||
elif host_machine.system() == 'windows'
|
elif host_machine.system() == 'windows'
|
||||||
windows_sdk_lib_dir = 'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64'
|
windows_sdk_lib_dir = 'C:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64'
|
||||||
link_args += ['-L' + windows_sdk_lib_dir, '-lwindowsapp', '-ldwmapi', '-static']
|
link_args += ['-L' + windows_sdk_lib_dir, '-lwindowsapp', '-ldwmapi', '-static']
|
||||||
|
|
|
@ -35,7 +35,7 @@ fn Config::getInstance() -> Config {
|
||||||
const Result<Config> result = rfl::toml::load<Config>(configPath.string());
|
const Result<Config> result = rfl::toml::load<Config>(configPath.string());
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
ERROR_LOG("Failed to load config file: {}", result.error().what());
|
ERROR_LOG("Failed to load config file: {}", result.error()->what());
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace {
|
||||||
|
|
||||||
rfl::Result<WeatherOutput> result = rfl::json::read<WeatherOutput>(content);
|
rfl::Result<WeatherOutput> result = rfl::json::read<WeatherOutput>(content);
|
||||||
if (!result)
|
if (!result)
|
||||||
return std::unexpected(result.error().what());
|
return std::unexpected(result.error()->what());
|
||||||
|
|
||||||
DEBUG_LOG("Successfully read from cache file.");
|
DEBUG_LOG("Successfully read from cache file.");
|
||||||
return *result;
|
return *result;
|
||||||
|
@ -117,7 +117,7 @@ namespace {
|
||||||
|
|
||||||
rfl::Result<WeatherOutput> output = rfl::json::read<WeatherOutput>(responseBuffer);
|
rfl::Result<WeatherOutput> output = rfl::json::read<WeatherOutput>(responseBuffer);
|
||||||
if (!output)
|
if (!output)
|
||||||
return std::unexpected(output.error().what());
|
return std::unexpected(output.error()->what());
|
||||||
|
|
||||||
return *output;
|
return *output;
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ namespace {
|
||||||
std::async(std::launch::async, GetKernelVersion)
|
std::async(std::launch::async, GetKernelVersion)
|
||||||
);
|
);
|
||||||
|
|
||||||
auto [os, mem, de, wm] = std::tuple(
|
auto [osVer, mem, desktop, winManager] = std::tuple(
|
||||||
std::async(std::launch::async, GetOSVersion),
|
std::async(std::launch::async, GetOSVersion),
|
||||||
std::async(std::launch::async, GetMemInfo),
|
std::async(std::launch::async, GetMemInfo),
|
||||||
std::async(std::launch::async, GetDesktopEnvironment),
|
std::async(std::launch::async, GetDesktopEnvironment),
|
||||||
|
@ -106,10 +106,10 @@ namespace {
|
||||||
data.date = date.get();
|
data.date = date.get();
|
||||||
data.host = host.get();
|
data.host = host.get();
|
||||||
data.kernel_version = kernel.get();
|
data.kernel_version = kernel.get();
|
||||||
data.os_version = os.get();
|
data.os_version = osVer.get();
|
||||||
data.mem_info = mem.get();
|
data.mem_info = mem.get();
|
||||||
data.desktop_environment = de.get();
|
data.desktop_environment = desktop.get();
|
||||||
data.window_manager = wm.get();
|
data.window_manager = winManager.get();
|
||||||
|
|
||||||
if (weather.valid())
|
if (weather.valid())
|
||||||
data.weather_info = weather.get();
|
data.weather_info = weather.get();
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace {
|
||||||
vector<string> mprisPlayers;
|
vector<string> mprisPlayers;
|
||||||
|
|
||||||
for (const string& name : names)
|
for (const string& name : names)
|
||||||
if (const char* mprisInterfaceName = "org.mpris.MediaPlayer2"; name.find(mprisInterfaceName) != string::npos)
|
if (const char* mprisInterfaceName = "org.mpris.MediaPlayer2"; name.contains(mprisInterfaceName))
|
||||||
mprisPlayers.push_back(name);
|
mprisPlayers.push_back(name);
|
||||||
|
|
||||||
return mprisPlayers;
|
return mprisPlayers;
|
||||||
|
@ -103,7 +103,7 @@ namespace {
|
||||||
&data
|
&data
|
||||||
) == Success &&
|
) == Success &&
|
||||||
data) {
|
data) {
|
||||||
memcpy(&wmWindow, data, sizeof(Window));
|
wmWindow = *std::bit_cast<Window*>(data);
|
||||||
XFree(data);
|
XFree(data);
|
||||||
data = nullptr;
|
data = nullptr;
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn TrimHyprlandWrapper(const string& input) -> string {
|
fn TrimHyprlandWrapper(const string& input) -> string {
|
||||||
if (input.find("hyprland") != string::npos)
|
if (input.contains("hyprland"))
|
||||||
return "Hyprland";
|
return "Hyprland";
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ namespace {
|
||||||
|
|
||||||
// 2. Check cmdline for actual binary reference
|
// 2. Check cmdline for actual binary reference
|
||||||
string cmdline = ReadProcessCmdline(cred.pid);
|
string cmdline = ReadProcessCmdline(cred.pid);
|
||||||
if (cmdline.find("hyprland") != string::npos) {
|
if (cmdline.contains("hyprland")) {
|
||||||
wl_display_disconnect(display);
|
wl_display_disconnect(display);
|
||||||
return "Hyprland";
|
return "Hyprland";
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ namespace {
|
||||||
if (lenBuf != -1) {
|
if (lenBuf != -1) {
|
||||||
buf.at(static_cast<usize>(lenBuf)) = '\0';
|
buf.at(static_cast<usize>(lenBuf)) = '\0';
|
||||||
string exe(buf.data());
|
string exe(buf.data());
|
||||||
if (exe.find("hyprland") != string::npos) {
|
if (exe.contains("hyprland")) {
|
||||||
wl_display_disconnect(display);
|
wl_display_disconnect(display);
|
||||||
return "Hyprland";
|
return "Hyprland";
|
||||||
}
|
}
|
||||||
|
@ -316,7 +316,7 @@ namespace {
|
||||||
string envVars((istreambuf_iterator<char>(cmdline)), istreambuf_iterator<char>());
|
string envVars((istreambuf_iterator<char>(cmdline)), istreambuf_iterator<char>());
|
||||||
|
|
||||||
for (const auto& [process, deName] : processChecks)
|
for (const auto& [process, deName] : processChecks)
|
||||||
if (envVars.find(process) != string::npos)
|
if (envVars.contains(process))
|
||||||
return string(deName);
|
return string(deName);
|
||||||
|
|
||||||
return nullopt;
|
return nullopt;
|
||||||
|
@ -331,7 +331,7 @@ namespace {
|
||||||
usize count = 0;
|
usize count = 0;
|
||||||
|
|
||||||
// 1. Direct URI construction without string concatenation
|
// 1. Direct URI construction without string concatenation
|
||||||
const string uri = fmt::format("file:{}{}immutable=1", dbPath, (dbPath.find('?') != string_view::npos) ? "&" : "?");
|
const string uri = fmt::format("file:{}{}immutable=1", dbPath, (dbPath.find('?') == string::npos) ? "&" : "?");
|
||||||
|
|
||||||
// 2. Open database with optimized flags
|
// 2. Open database with optimized flags
|
||||||
if (sqlite3_open_v2(uri.c_str(), &sqlDB, SQLITE_OPEN_READONLY | SQLITE_OPEN_URI | SQLITE_OPEN_NOMUTEX, nullptr) !=
|
if (sqlite3_open_v2(uri.c_str(), &sqlDB, SQLITE_OPEN_READONLY | SQLITE_OPEN_URI | SQLITE_OPEN_NOMUTEX, nullptr) !=
|
||||||
|
@ -528,7 +528,7 @@ fn GetWindowManager() -> string {
|
||||||
const char* waylandDisplay = getenv("WAYLAND_DISPLAY");
|
const char* waylandDisplay = getenv("WAYLAND_DISPLAY");
|
||||||
|
|
||||||
// Prefer Wayland detection if Wayland session
|
// Prefer Wayland detection if Wayland session
|
||||||
if ((waylandDisplay != nullptr) || (xdgSessionType && strstr(xdgSessionType, "wayland"))) {
|
if ((waylandDisplay != nullptr) || (xdgSessionType && std::string_view(xdgSessionType).contains("wayland"))) {
|
||||||
string compositor = GetWaylandCompositor();
|
string compositor = GetWaylandCompositor();
|
||||||
if (!compositor.empty())
|
if (!compositor.empty())
|
||||||
return compositor;
|
return compositor;
|
||||||
|
@ -538,7 +538,7 @@ fn GetWindowManager() -> string {
|
||||||
if (xdgCurrentDesktop) {
|
if (xdgCurrentDesktop) {
|
||||||
string desktop(xdgCurrentDesktop);
|
string desktop(xdgCurrentDesktop);
|
||||||
transform(compositor, compositor.begin(), ::tolower);
|
transform(compositor, compositor.begin(), ::tolower);
|
||||||
if (desktop.find("hyprland") != string::npos)
|
if (desktop.contains("hyprland"))
|
||||||
return "hyprland";
|
return "hyprland";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
src/os/linux/issetugid_stub.cpp
Normal file
3
src/os/linux/issetugid_stub.cpp
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#include "src/util/macros.h"
|
||||||
|
|
||||||
|
extern "C" fn issetugid() -> usize { return 0; } // NOLINT
|
|
@ -22,6 +22,9 @@ fn GetZypperPackageCount() -> std::optional<usize>;
|
||||||
// Get package count from apk (Alpine)
|
// Get package count from apk (Alpine)
|
||||||
fn GetApkPackageCount() -> std::optional<usize>;
|
fn GetApkPackageCount() -> std::optional<usize>;
|
||||||
|
|
||||||
|
// Get package count from nix
|
||||||
|
fn GetNixPackageCount() -> std::optional<usize>;
|
||||||
|
|
||||||
// Get package count from flatpak
|
// Get package count from flatpak
|
||||||
fn GetFlatpakPackageCount() -> std::optional<usize>;
|
fn GetFlatpakPackageCount() -> std::optional<usize>;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue