This commit is contained in:
Mars 2024-06-08 22:28:26 -04:00
parent 3ea546fe08
commit 05451841e8
Signed by: pupbrained
GPG key ID: 0FF5B8826803F895
8 changed files with 96 additions and 109 deletions

View file

@ -1,4 +1,3 @@
---
AlignAfterOpenBracket: BlockIndent AlignAfterOpenBracket: BlockIndent
AlignArrayOfStructures: Right AlignArrayOfStructures: Right
AlignConsecutiveAssignments: true AlignConsecutiveAssignments: true
@ -10,9 +9,10 @@ AllowShortFunctionsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: WithoutElse AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: true AllowShortLoopsOnASingleLine: true
BasedOnStyle: Chromium BasedOnStyle: Chromium
BinPackArguments: false
BinPackParameters: false
IndentAccessModifiers: false IndentAccessModifiers: false
IndentExternBlock: Indent IndentExternBlock: Indent
Language: Cpp
NamespaceIndentation: All NamespaceIndentation: All
SpaceBeforeCpp11BracedList: true SpaceBeforeCpp11BracedList: true
SpacesBeforeTrailingComments: 1 SpacesBeforeTrailingComments: 1

View file

@ -1,10 +1,12 @@
Checks: > Checks: >
*, *,
-abseil-*,
-altera-*, -altera-*,
-bugprone-easily-swappable-parameters, -bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result, -bugprone-implicit-widening-of-multiplication-result,
-concurrency-mt-unsafe, -concurrency-mt-unsafe,
-cppcoreguidelines-avoid-magic-numbers, -cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-owning-memory,
-cppcoreguidelines-pro-type-member-init, -cppcoreguidelines-pro-type-member-init,
-fuchsia-*, -fuchsia-*,
-google-*, -google-*,
@ -16,6 +18,7 @@ Checks: >
-modernize-use-trailing-return-type, -modernize-use-trailing-return-type,
-readability-braces-around-statements, -readability-braces-around-statements,
-readability-implicit-bool-conversion, -readability-implicit-bool-conversion,
-readability-isolate-declaration,
-readability-magic-numbers -readability-magic-numbers
CheckOptions: CheckOptions:
readability-identifier-naming.ClassCase: CamelCase readability-identifier-naming.ClassCase: CamelCase

View file

@ -1,2 +1,2 @@
CompileFlags: CompileFlags:
Add: [-std=c++20, -Wunused-function] Add: [-std=c++23, -Wunused-function]

View file

@ -16,37 +16,7 @@
}: }:
utils.lib.eachDefaultSystem ( utils.lib.eachDefaultSystem (
system: let system: let
pkgs = import nixpkgs { pkgs = import nixpkgs {inherit system;};
inherit system;
overlays = [
(_self: super: {
ccacheWrapper = super.ccacheWrapper.override {
extraConfig = ''
export CCACHE_COMPRESS=1
export CCACHE_DIR="/var/cache/ccache"
export CCACHE_UMASK=007
if [ ! -d "$CCACHE_DIR" ]; then
echo "====="
echo "Directory '$CCACHE_DIR' does not exist"
echo "Please create it with:"
echo " sudo mkdir -m0770 '$CCACHE_DIR'"
echo " sudo chown root:nixbld '$CCACHE_DIR'"
echo "====="
exit 1
fi
if [ ! -w "$CCACHE_DIR" ]; then
echo "====="
echo "Directory '$CCACHE_DIR' is not accessible for user $(whoami)"
echo "Please verify its access permissions"
echo "====="
exit 1
fi
'';
};
})
];
};
stdenv = stdenv =
if pkgs.hostPlatform.isLinux if pkgs.hostPlatform.isLinux

View file

@ -4,10 +4,10 @@ project(
default_options: [ default_options: [
'objc_std=c++20', 'objc_std=c++20',
'objcpp_std=c++20', 'objcpp_std=c++20',
'cpp_std=c++20', 'cpp_std=c++23',
'default_library=static', 'default_library=static',
'warning_level=everything', 'warning_level=everything',
'buildtype=debugoptimized', 'buildtype=debugoptimized'
] ]
) )

View file

@ -81,7 +81,12 @@ int main() {
fmt::println("It is {}°F in {}", temp, townName); fmt::println("It is {}°F in {}", temp, townName);
fmt::println("{}", GetOSVersion()); const char* version = GetOSVersion();
fmt::println("{}", version);
delete[] version;
delete &config;
return 0; return 0;
} }

View file

@ -1,5 +1,6 @@
#ifdef __linux__ #ifdef __linux__
#include <cstring>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <sdbus-c++/sdbus-c++.h> #include <sdbus-c++/sdbus-c++.h>
@ -9,13 +10,6 @@
using std::string; using std::string;
static const char *DBUS_INTERFACE = "org.freedesktop.DBus",
*DBUS_OBJECT_PATH = "/org/freedesktop/DBus",
*DBUS_METHOD_LIST_NAMES = "ListNames",
*MPRIS_INTERFACE_NAME = "org.mpris.MediaPlayer2",
*PLAYER_OBJECT_PATH = "/org/mpris/MediaPlayer2",
*PLAYER_INTERFACE_NAME = "org.mpris.MediaPlayer2.Player";
u64 ParseLineAsNumber(const string& input) { u64 ParseLineAsNumber(const string& input) {
// Find the first number // Find the first number
string::size_type start = 0; string::size_type start = 0;
@ -48,8 +42,6 @@ u64 MeminfoParse(std::ifstream input) {
u64 GetMemInfo() { return MeminfoParse(std::ifstream("/proc/meminfo")) * 1024; } u64 GetMemInfo() { return MeminfoParse(std::ifstream("/proc/meminfo")) * 1024; }
const char* GetOSVersion() { const char* GetOSVersion() {
static std::string prettyName;
std::ifstream file("/etc/os-release"); std::ifstream file("/etc/os-release");
if (!file.is_open()) { if (!file.is_open()) {
@ -57,40 +49,51 @@ const char* GetOSVersion() {
return nullptr; return nullptr;
} }
std::string line; std::string line;
const std::string prefix = "PRETTY_NAME=";
while (std::getline(file, line)) { while (std::getline(file, line)) {
if (line.find("PRETTY_NAME=") == 0) { if (line.find(prefix) == 0) {
// Remove the "PRETTY_NAME=" part and any surrounding quotes std::string prettyName = line.substr(prefix.size());
prettyName = line.substr(12);
if (!prettyName.empty() && prettyName.front() == '"' && // Remove surrounding quotes if present
prettyName.back() == '"') // clang-format off
if (!prettyName.empty() &&
prettyName.front() == '"' &&
prettyName.back() == '"')
prettyName = prettyName.substr(1, prettyName.size() - 2); prettyName = prettyName.substr(1, prettyName.size() - 2);
// clang-format on
file.close(); // Allocate memory for the C-string and copy the content
return prettyName.c_str(); char* cstr = new char[prettyName.size() + 1];
std::strcpy(cstr, prettyName.c_str());
return cstr;
} }
} }
file.close();
return nullptr; return nullptr;
} }
std::vector<std::string> GetMprisPlayers(sdbus::IConnection& connection) { std::vector<std::string> GetMprisPlayers(sdbus::IConnection& connection) {
const char *dbusInterface = "org.freedesktop.DBus",
*dbusObjectPath = "/org/freedesktop/DBus",
*dbusMethodListNames = "ListNames",
*mprisInterfaceName = "org.mpris.MediaPlayer2";
std::unique_ptr<sdbus::IProxy> dbusProxy = std::unique_ptr<sdbus::IProxy> dbusProxy =
sdbus::createProxy(connection, DBUS_INTERFACE, DBUS_OBJECT_PATH); sdbus::createProxy(connection, dbusInterface, dbusObjectPath);
std::vector<std::string> names; std::vector<std::string> names;
dbusProxy->callMethod(DBUS_METHOD_LIST_NAMES) dbusProxy->callMethod(dbusMethodListNames)
.onInterface(DBUS_INTERFACE) .onInterface(dbusInterface)
.storeResultsTo(names); .storeResultsTo(names);
std::vector<std::string> mprisPlayers; std::vector<std::string> mprisPlayers;
for (const std::basic_string<char>& name : names) for (const std::basic_string<char>& name : names)
if (name.find(MPRIS_INTERFACE_NAME) != std::string::npos) if (name.contains(mprisInterfaceName)) mprisPlayers.push_back(name);
mprisPlayers.push_back(name);
return mprisPlayers; return mprisPlayers;
} }
@ -103,6 +106,9 @@ std::string GetActivePlayer(const std::vector<std::string>& mprisPlayers) {
std::string GetNowPlaying() { std::string GetNowPlaying() {
try { try {
const char *playerObjectPath = "/org/mpris/MediaPlayer2",
*playerInterfaceName = "org.mpris.MediaPlayer2.Player";
std::unique_ptr<sdbus::IConnection> connection = std::unique_ptr<sdbus::IConnection> connection =
sdbus::createSessionBusConnection(); sdbus::createSessionBusConnection();
@ -115,10 +121,10 @@ std::string GetNowPlaying() {
if (activePlayer.empty()) return ""; if (activePlayer.empty()) return "";
std::unique_ptr<sdbus::IProxy> playerProxy = std::unique_ptr<sdbus::IProxy> playerProxy =
sdbus::createProxy(*connection, activePlayer, PLAYER_OBJECT_PATH); sdbus::createProxy(*connection, activePlayer, playerObjectPath);
std::map<std::string, sdbus::Variant> metadata = std::map<std::string, sdbus::Variant> metadata =
playerProxy->getProperty("Metadata").onInterface(PLAYER_INTERFACE_NAME); playerProxy->getProperty("Metadata").onInterface(playerInterfaceName);
auto iter = metadata.find("xesam:title"); auto iter = metadata.find("xesam:title");

View file

@ -1,18 +1,23 @@
#ifdef __APPLE__ #ifdef __APPLE__
#import "bridge.h"
#import <dispatch/dispatch.h> #import <dispatch/dispatch.h>
#import <objc/runtime.h> #import <objc/runtime.h>
#import "bridge.h"
using MRMediaRemoteGetNowPlayingInfoFunction = void (*)( using MRMediaRemoteGetNowPlayingInfoFunction = void (*)(
dispatch_queue_t queue, void (^handler)(NSDictionary *information)); dispatch_queue_t queue,
void (^handler)(NSDictionary* information)
);
@implementation Bridge @implementation Bridge
+ (NSDictionary *)currentPlayingMetadata { + (NSDictionary*)currentPlayingMetadata {
CFURLRef ref = CFURLCreateWithFileSystemPath( CFURLRef ref = CFURLCreateWithFileSystemPath(
kCFAllocatorDefault, kCFAllocatorDefault,
CFSTR("/System/Library/PrivateFrameworks/MediaRemote.framework"), CFSTR("/System/Library/PrivateFrameworks/MediaRemote.framework"),
kCFURLPOSIXPathStyle, false); kCFURLPOSIXPathStyle,
false
);
if (!ref) { if (!ref) {
NSLog(@"Failed to load MediaRemote framework"); NSLog(@"Failed to load MediaRemote framework");
@ -30,7 +35,9 @@ using MRMediaRemoteGetNowPlayingInfoFunction = void (*)(
MRMediaRemoteGetNowPlayingInfoFunction mrMediaRemoteGetNowPlayingInfo = MRMediaRemoteGetNowPlayingInfoFunction mrMediaRemoteGetNowPlayingInfo =
reinterpret_cast<MRMediaRemoteGetNowPlayingInfoFunction>( reinterpret_cast<MRMediaRemoteGetNowPlayingInfoFunction>(
CFBundleGetFunctionPointerForName( CFBundleGetFunctionPointerForName(
bundle, CFSTR("MRMediaRemoteGetNowPlayingInfo"))); bundle, CFSTR("MRMediaRemoteGetNowPlayingInfo")
)
);
if (!mrMediaRemoteGetNowPlayingInfo) { if (!mrMediaRemoteGetNowPlayingInfo) {
NSLog(@"Failed to get function pointer for MRMediaRemoteGetNowPlayingInfo"); NSLog(@"Failed to get function pointer for MRMediaRemoteGetNowPlayingInfo");
@ -38,15 +45,16 @@ using MRMediaRemoteGetNowPlayingInfoFunction = void (*)(
return nil; return nil;
} }
__block NSDictionary *nowPlayingInfo = nil; __block NSDictionary* nowPlayingInfo = nil;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
mrMediaRemoteGetNowPlayingInfo( mrMediaRemoteGetNowPlayingInfo(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^(NSDictionary *information) { ^(NSDictionary* information) {
nowPlayingInfo = [information copy]; nowPlayingInfo = [information copy];
dispatch_semaphore_signal(semaphore); dispatch_semaphore_signal(semaphore);
}); }
);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
@ -54,26 +62,26 @@ using MRMediaRemoteGetNowPlayingInfoFunction = void (*)(
return nowPlayingInfo; return nowPlayingInfo;
} }
+ (NSString *)macOSVersion { + (NSString*)macOSVersion {
NSProcessInfo *processInfo = [NSProcessInfo processInfo]; NSProcessInfo* processInfo = [NSProcessInfo processInfo];
NSOperatingSystemVersion osVersion = [processInfo operatingSystemVersion]; NSOperatingSystemVersion osVersion = [processInfo operatingSystemVersion];
NSString *version = [NSString NSString* version = [NSString stringWithFormat:@"%ld.%ld.%ld",
stringWithFormat:@"%ld.%ld.%ld", osVersion.majorVersion, osVersion.majorVersion,
osVersion.minorVersion, osVersion.patchVersion]; osVersion.minorVersion,
osVersion.patchVersion];
// Dictionary to map macOS versions to their respective names // Dictionary to map macOS versions to their respective names
NSDictionary<NSNumber *, NSString *> *versionNames = NSDictionary<NSNumber*, NSString*>* versionNames =
@{@11 : @"Big Sur", @12 : @"Monterey", @13 : @"Ventura", @14 : @"Sonoma"}; @{@11 : @"Big Sur", @12 : @"Monterey", @13 : @"Ventura", @14 : @"Sonoma"};
NSNumber *majorVersionNumber = @(osVersion.majorVersion); NSNumber* majorVersionNumber = @(osVersion.majorVersion);
NSString *versionName = versionNames[majorVersionNumber]; NSString* versionName = versionNames[majorVersionNumber];
if (versionName == nil) if (versionName == nil) versionName = @"Unknown";
versionName = @"Unknown";
NSString *fullVersion = NSString* fullVersion =
[NSString stringWithFormat:@"macOS %@ %@", version, versionName]; [NSString stringWithFormat:@"macOS %@ %@", version, versionName];
return fullVersion; return fullVersion;
@ -81,44 +89,39 @@ using MRMediaRemoteGetNowPlayingInfoFunction = void (*)(
@end @end
extern "C" { extern "C" {
const char *GetCurrentPlayingTitle() { const char* GetCurrentPlayingTitle() {
NSDictionary *metadata = [Bridge currentPlayingMetadata]; NSDictionary* metadata = [Bridge currentPlayingMetadata];
if (metadata == nil) return nullptr;
NSString* title =
[metadata objectForKey:@"kMRMediaRemoteNowPlayingInfoTitle"];
if (title) return strdup([title UTF8String]);
if (metadata == nil)
return nullptr; return nullptr;
}
NSString *title = const char* GetCurrentPlayingArtist() {
[metadata objectForKey:@"kMRMediaRemoteNowPlayingInfoTitle"]; NSDictionary* metadata = [Bridge currentPlayingMetadata];
if (title) if (metadata == nil) return nullptr;
return strdup([title UTF8String]);
return nullptr; NSString* artist =
} [metadata objectForKey:@"kMRMediaRemoteNowPlayingInfoArtist"];
const char *GetCurrentPlayingArtist() { if (artist) return strdup([artist UTF8String]);
NSDictionary *metadata = [Bridge currentPlayingMetadata];
if (metadata == nil)
return nullptr; return nullptr;
}
NSString *artist = const char* GetMacOSVersion() {
[metadata objectForKey:@"kMRMediaRemoteNowPlayingInfoArtist"]; NSString* version = [Bridge macOSVersion];
if (artist) if (version) return strdup([version UTF8String]);
return strdup([artist UTF8String]);
return nullptr; return nullptr;
} }
const char *GetMacOSVersion() {
NSString *version = [Bridge macOSVersion];
if (version)
return strdup([version UTF8String]);
return nullptr;
}
} }
#endif #endif