mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Merge pull request #253 from CarterLi/master
[macOS] Disk & Media improvements
This commit is contained in:
@@ -261,6 +261,7 @@ if(LINUX OR ANDROID OR BSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/detection/cpuUsage/cpuUsage_linux.c
|
||||
src/detection/battery/battery_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -296,6 +297,7 @@ if(APPLE)
|
||||
src/detection/displayserver/displayserver_apple.c
|
||||
src/detection/terminalfont/terminalfont_apple.c
|
||||
src/detection/media/media_apple.m
|
||||
src/detection/disk/disk_apple.m
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -222,6 +222,7 @@ static void defaultConfig(FFinstance* instance)
|
||||
instance->config.titleFQDN = false;
|
||||
|
||||
ffStrbufInitA(&instance->config.diskFolders, 0);
|
||||
instance->config.diskRemovable = false;
|
||||
|
||||
ffStrbufInitA(&instance->config.batteryDir, 0);
|
||||
|
||||
|
||||
+2
-1
@@ -87,10 +87,11 @@ Library options: Set the path of a library to load
|
||||
--lib-plist <path>
|
||||
|
||||
Module specific options:
|
||||
--title-fqdn <?value>: sets if the title should use fully qualified domain name. Default is false.
|
||||
--title-fqdn <?value>: Sets if the title should use fully qualified domain name. Default is false.
|
||||
--separator-string <str>: Set the string printed by the separator module
|
||||
--os-file <path>: Set the path to the file containing OS informations
|
||||
--disk-folders <folders>: A colon separated list of folder paths for the disk output. Default is "/:/home"
|
||||
--disk-removable <?value>: Sets if removable volume should be printed. Default is false
|
||||
--battery-dir <folder>: The directory where the battery folders are. Standard: /sys/class/power_supply/
|
||||
--localip-show-ipv4 <?value>: Show ipv4 addresses in local ip module. Default is true
|
||||
--localip-show-ipv6 <?value>: Show ipv6 addresses in local ip module. Default is false
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef FF_INCLUDED_detection_disk_disk
|
||||
#define FF_INCLUDED_detection_disk_disk
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "disk.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders)
|
||||
{
|
||||
NSArray *keys = [NSArray arrayWithObjects:NSURLVolumeNameKey, nil];
|
||||
NSArray *urls = [NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys:keys
|
||||
options:NSVolumeEnumerationSkipHiddenVolumes];
|
||||
if(urls == nil)
|
||||
return "[NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys] failed";
|
||||
|
||||
for (NSURL *url in urls) {
|
||||
NSError *error;
|
||||
NSNumber* removable;
|
||||
if([url getResourceValue:&removable forKey:NSURLVolumeIsRemovableKey error:&error] == NO)
|
||||
continue;
|
||||
if(removable.boolValue && !instance->config.diskRemovable)
|
||||
continue;
|
||||
|
||||
ffStrbufInitS((FFstrbuf *)ffListAdd(folders), [url.relativePath cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "disk.h"
|
||||
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
const char* ffDiskAutodetectFolders(FFinstance* instance, FFlist* folders)
|
||||
{
|
||||
FF_UNUSED(instance);
|
||||
|
||||
struct statvfs fsRoot;
|
||||
int rootRet = statvfs(FASTFETCH_TARGET_DIR_ROOT"/", &fsRoot);
|
||||
if(rootRet != 0)
|
||||
return "statvfs(\"/\") failed";
|
||||
|
||||
ffStrbufInitS((FFstrbuf *)ffListAdd(folders), FASTFETCH_TARGET_DIR_ROOT"/");
|
||||
|
||||
struct statvfs fsHome;
|
||||
int homeRet = statvfs(FASTFETCH_TARGET_DIR_HOME, &fsHome);
|
||||
if(homeRet == 0 && (fsRoot.f_fsid != fsHome.f_fsid))
|
||||
ffStrbufInitS((FFstrbuf *)ffListAdd(folders), FASTFETCH_TARGET_DIR_HOME);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -32,18 +32,27 @@ static const char* getMedia(FFMediaResult* result)
|
||||
});
|
||||
|
||||
dispatch_group_enter(group);
|
||||
__block const char* error = NULL;
|
||||
MRMediaRemoteGetNowPlayingInfo(queue, ^(_Nullable CFDictionaryRef info) {
|
||||
if(info != nil) {
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoTitle"), &result->song);
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoArtist"), &result->artist);
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoAlbum"), &result->album);
|
||||
if(info != nil)
|
||||
{
|
||||
error = ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoTitle"), &result->song);
|
||||
if(!error)
|
||||
{
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoArtist"), &result->artist);
|
||||
ffCfDictGetString(info, CFSTR("kMRMediaRemoteNowPlayingInfoAlbum"), &result->album);
|
||||
}
|
||||
}
|
||||
else
|
||||
error = "MRMediaRemoteGetNowPlayingInfo() failed";
|
||||
|
||||
dispatch_group_leave(group);
|
||||
});
|
||||
|
||||
dispatch_group_enter(group);
|
||||
MRMediaRemoteGetNowPlayingClient(queue, ^(_Nullable id clientObj) {
|
||||
if (clientObj != nil) {
|
||||
if (clientObj != nil)
|
||||
{
|
||||
CFStringRef identifier = MRNowPlayingClientGetBundleIdentifier(clientObj);
|
||||
if (identifier == nil)
|
||||
identifier = MRNowPlayingClientGetParentAppBundleIdentifier(clientObj);
|
||||
@@ -65,7 +74,7 @@ static const char* getMedia(FFMediaResult* result)
|
||||
if(result->song.length > 0)
|
||||
return NULL;
|
||||
|
||||
return "MediaRemote failed";
|
||||
return error;
|
||||
}
|
||||
|
||||
void ffDetectMediaImpl(const FFinstance* instance, FFMediaResult* media)
|
||||
|
||||
@@ -1255,6 +1255,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con
|
||||
instance->config.titleFQDN = optionParseBoolean(value);
|
||||
else if(strcasecmp(key, "--disk-folders") == 0)
|
||||
optionParseString(key, value, &instance->config.diskFolders);
|
||||
else if(strcasecmp(key, "--disk-removable") == 0)
|
||||
instance->config.diskRemovable = optionParseBoolean(value);
|
||||
else if(strcasecmp(key, "--battery-dir") == 0)
|
||||
optionParseString(key, value, &instance->config.batteryDir);
|
||||
else if(strcasecmp(key, "--separator-string") == 0)
|
||||
|
||||
@@ -154,6 +154,7 @@ typedef struct FFconfig
|
||||
bool titleFQDN;
|
||||
|
||||
FFstrbuf diskFolders;
|
||||
bool diskRemovable;
|
||||
|
||||
FFstrbuf batteryDir;
|
||||
|
||||
|
||||
+16
-46
@@ -1,6 +1,7 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/printing.h"
|
||||
#include "common/parsing.h"
|
||||
#include "detection/disk/disk.h"
|
||||
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
@@ -64,49 +65,7 @@ static void printStatvfs(FFinstance* instance, const FFstrbuf* key, const char*
|
||||
ffStrbufDestroy(&usedPretty);
|
||||
}
|
||||
|
||||
static void printFolderAutodetection(FFinstance* instance, const char* folderPath, struct statvfs* fs)
|
||||
{
|
||||
FFstrbuf key;
|
||||
ffStrbufInit(&key);
|
||||
createKey(instance, folderPath, &key);
|
||||
printStatvfs(instance, &key, folderPath, fs);
|
||||
ffStrbufDestroy(&key);
|
||||
}
|
||||
|
||||
static void printFoldersAutodetection(FFinstance* instance)
|
||||
{
|
||||
struct statvfs fsRoot;
|
||||
int rootRet = statvfs(FASTFETCH_TARGET_DIR_ROOT"/", &fsRoot);
|
||||
|
||||
if(rootRet != 0)
|
||||
{
|
||||
FFstrbuf key;
|
||||
ffStrbufInit(&key);
|
||||
createKey(instance, NULL, &key);
|
||||
ffPrintErrorString(instance, key.chars, 0, NULL, &instance->config.disk.errorFormat, "statvfs for / returned not zero: %i", rootRet);
|
||||
ffStrbufDestroy(&key);
|
||||
return;
|
||||
}
|
||||
|
||||
//On MacOS statvfs seems to return different f_fsid for the same filesystem.
|
||||
//Since it isn't really possible to install /Users on a separate disk anyway, just never print it by default.
|
||||
#ifndef __APPLE__
|
||||
struct statvfs fsHome;
|
||||
int homeRet = statvfs(FASTFETCH_TARGET_DIR_HOME, &fsHome);
|
||||
bool printHome = homeRet == 0 && (fsRoot.f_fsid != fsHome.f_fsid);
|
||||
#else
|
||||
bool printHome = false;
|
||||
#endif // !__APPLE__
|
||||
|
||||
printFolderAutodetection(instance, printHome ? FASTFETCH_TARGET_DIR_ROOT"/" : NULL, &fsRoot);
|
||||
|
||||
#ifndef __APPLE__
|
||||
if(printHome)
|
||||
printFolderAutodetection(instance, FASTFETCH_TARGET_DIR_HOME, &fsHome);
|
||||
#endif // !__APPLE__
|
||||
}
|
||||
|
||||
static void printFolderCustom(FFinstance* instance, const char* folderPath)
|
||||
static void printFolder(FFinstance* instance, const char* folderPath)
|
||||
{
|
||||
FFstrbuf key;
|
||||
ffStrbufInit(&key);
|
||||
@@ -131,17 +90,28 @@ void ffPrintDisk(FFinstance* instance)
|
||||
|
||||
if(instance->config.diskFolders.length == 0)
|
||||
{
|
||||
printFoldersAutodetection(instance);
|
||||
FFlist folders;
|
||||
ffListInit(&folders, sizeof(FFstrbuf));
|
||||
const char* error = ffDiskAutodetectFolders(instance, &folders);
|
||||
if(error)
|
||||
ffPrintError(instance, FF_DISK_MODULE_NAME, 0, &instance->config.disk, "%s", error);
|
||||
for(uint32_t i = 0; i < folders.length; ++i)
|
||||
{
|
||||
FFstrbuf* folder = (FFstrbuf*)ffListGet(&folders, i);
|
||||
printFolder(instance, folder->chars);
|
||||
ffStrbufDestroy(folder);
|
||||
}
|
||||
ffListDestroy(&folders);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t startIndex = 0;
|
||||
while (startIndex < instance->config.diskFolders.length)
|
||||
while(startIndex < instance->config.diskFolders.length)
|
||||
{
|
||||
uint32_t colonIndex = ffStrbufNextIndexC(&instance->config.diskFolders, startIndex, ':');
|
||||
instance->config.diskFolders.chars[colonIndex] = '\0';
|
||||
|
||||
printFolderCustom(instance, instance->config.diskFolders.chars + startIndex);
|
||||
printFolder(instance, instance->config.diskFolders.chars + startIndex);
|
||||
|
||||
startIndex = colonIndex + 1;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,11 @@ const char* ffCfStrGetString(CFStringRef str, FFstrbuf* result)
|
||||
//CFString stores UTF16 characters, therefore may require larger buffer to convert to UTF8 string
|
||||
ffStrbufEnsureFree(result, length * 2);
|
||||
if(!CFStringGetCString(str, result->chars, result->allocated, kCFStringEncodingUTF8))
|
||||
return "CFStringGetCString() failed";
|
||||
{
|
||||
ffStrbufEnsureFree(result, length * 4);
|
||||
if(!CFStringGetCString(str, result->chars, result->allocated, kCFStringEncodingUTF8))
|
||||
return "CFStringGetCString() failed";
|
||||
}
|
||||
// CFStringGetCString ensures the buffer is NUL terminated
|
||||
// https://developer.apple.com/documentation/corefoundation/1542721-cfstringgetcstring
|
||||
result->length = (uint32_t) strnlen(result->chars, (uint32_t)result->allocated);
|
||||
|
||||
Reference in New Issue
Block a user