master ohmu/fastfetch-openbsd / src / detection / terminalfont / terminalfont_apple.m
ohmu  ·  2026-10-15
  1#include "terminalfont.h"
  2#include "common/font.h"
  3#include "detection/terminalshell/terminalshell.h"
  4#include "common/apple/osascript.h"
  5
  6#include <stdlib.h>
  7#include <string.h>
  8#import <Foundation/Foundation.h>
  9
 10static void detectIterm2(FFTerminalFontResult* terminalFont)
 11{
 12    const char* profile = getenv("ITERM_PROFILE");
 13    if (profile == nullptr)
 14    {
 15        ffStrbufAppendS(&terminalFont->error, "environment variable ITERM_PROFILE not set");
 16        return;
 17    }
 18
 19    NSError* error;
 20    NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/com.googlecode.iterm2.plist", instance.state.platform.homeDir.chars];
 21    NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName]
 22                                       error:&error];
 23    if(error)
 24    {
 25        ffStrbufAppendS(&terminalFont->error, error.localizedDescription.UTF8String);
 26        return;
 27    }
 28
 29    for(NSDictionary* bookmark in dict[@"New Bookmarks"])
 30    {
 31        if(![bookmark[@"Name"] isEqualToString:@(profile)])
 32            continue;
 33
 34        NSString* normalFont = bookmark[@"Normal Font"];
 35        if(!normalFont)
 36        {
 37            ffStrbufAppendF(&terminalFont->error, "`Normal Font` key in profile `%s` doesn't exist", profile);
 38            return;
 39        }
 40        ffFontInitWithSpace(&terminalFont->font, normalFont.UTF8String);
 41
 42        NSNumber* useNonAsciiFont = bookmark[@"Use Non-ASCII Font"];
 43        if(useNonAsciiFont.boolValue)
 44        {
 45            NSString* nonAsciiFont = bookmark[@"Non Ascii Font"];
 46            if (nonAsciiFont)
 47                ffFontInitWithSpace(&terminalFont->fallback, nonAsciiFont.UTF8String);
 48        }
 49        return;
 50    }
 51
 52    ffStrbufAppendF(&terminalFont->error, "find profile `%s` bookmark failed", profile);
 53}
 54
 55static void detectAppleTerminal(FFTerminalFontResult* terminalFont)
 56{
 57    FF_STRBUF_AUTO_DESTROY font = ffStrbufCreate();
 58    ffOsascript("tell application \"Terminal\" to font name of window frontmost & \" \" & font size of window frontmost", &font);
 59
 60    if(font.length == 0)
 61    {
 62        ffStrbufAppendS(&terminalFont->error, "executing osascript failed");
 63        return;
 64    }
 65
 66    ffFontInitWithSpace(&terminalFont->font, font.chars);
 67}
 68
 69static void detectWarpTerminal(FFTerminalFontResult* terminalFont)
 70{
 71    NSError* error;
 72    NSString* fileName = [NSString stringWithFormat:@"file://%s/Library/Preferences/dev.warp.Warp-Stable.plist", instance.state.platform.homeDir.chars];
 73    NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL URLWithString:fileName]
 74                                       error:&error];
 75    if(error)
 76    {
 77        ffStrbufAppendS(&terminalFont->error, error.localizedDescription.UTF8String);
 78        return;
 79    }
 80
 81    NSString* fontName = dict[@"FontName"];
 82    if(!fontName)
 83        fontName = @"Hack";
 84    else
 85        fontName = [fontName stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\""]];
 86
 87    NSString* fontSize = dict[@"FontSize"];
 88    if(!fontSize)
 89        fontSize = @"13";
 90
 91    ffFontInitValues(&terminalFont->font, fontName.UTF8String, fontSize.UTF8String);
 92}
 93
 94bool ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
 95{
 96    if(ffStrbufIgnCaseEqualS(&terminal->processName, "iterm.app") ||
 97        ffStrbufStartsWithIgnCaseS(&terminal->processName, "iTermServer-"))
 98        detectIterm2(terminalFont);
 99    else if(ffStrbufIgnCaseEqualS(&terminal->processName, "Apple_Terminal"))
100        detectAppleTerminal(terminalFont);
101    else if(ffStrbufIgnCaseEqualS(&terminal->processName, "WarpTerminal"))
102        detectWarpTerminal(terminalFont);
103    else
104        return false;
105    return true;
106}