Technical Reference

Documentation

A deep dive into how RenderFocus interfaces with the Darwin kernel to control Apple Silicon core allocation at the hardware level.

01

Privilege-Separated Architecture

RenderFocus uses a two-process architecture that cleanly separates the user interface from privileged kernel operations. The GUI application runs with normal user privileges while all kernel-level thread manipulation is isolated in a separate XPC daemon.

RenderFocus.app

SwiftUI menu bar interface. Runs in user-space. Discovers processes via NSWorkspace.

XPC Daemon (Root)

Privileged helper via SMAppService. Executes taskpolicy(2) for thread scheduling.

Darwin Kernel

XNU scheduler receives QoS changes. Directs threads to P-Core or E-Core clusters.

Key Design Decisions

The GUI application never acquires root privileges. All privileged operations are isolated in the XPC daemon.

LSUIElement = true makes the app invisible in the Dock — it lives only in the menu bar as an agent application.

Communication happens via Mach IPC (XPC), the fastest inter-process communication mechanism on macOS.

02

XPC Communication Protocol

All communication between the main application and the daemon is defined through a shared @objc protocol. This file is compiled into both targets.

// Shared/RenderFocusXPCProtocol.swift
@objc(RenderFocusXPCProtocol)
protocol RenderFocusXPCProtocol {
  func throttleProcess(pid: Int32, withReply: @escaping (Bool, String?) -> Void)
  func unthrottleProcess(pid: Int32, withReply: @escaping (Bool, String?) -> Void)
  func throttleMultipleProcesses(pids: [NSNumber], withReply: @escaping (Bool, String?) -> Void)
  func unthrottleAllProcesses(withReply: @escaping (Bool, String?) -> Void)
  func ping(withReply: @escaping (Bool) -> Void)
}
FunctionKernel EquivalentDescription
throttleProcess taskpolicy -b Puts a process into DARWIN_BG mode, directing it to E-Cores
unthrottleProcess taskpolicy -B Removes background policy, restoring P-Core access
throttleMultiple N × taskpolicy -b Bulk throttle via DispatchGroup, single reply on completion
unthrottleAll N × taskpolicy -B Restores all PIDs in the daemon's throttledPIDs set
ping Health check with 1.5s timeout for status indicator
03

taskpolicy & the Darwin Kernel

At its core, RenderFocus uses the taskpolicy(2) system utility to manipulate the XNU scheduler's Quality of Service classes. Here's what happens at the kernel level when a process is throttled.

// What happens when: taskpolicy -b -p 1234

proc_set_task_policy(pid, TASK_POLICY_DARWIN_BG, 1)

// Scheduler effects:
  Thread priority → MAXPRI_THROTTLE (4)
  Sched mode     → SCHED_MODE_BACKGROUND
  CPU affinity   → E-Cluster preferred

// I/O effects:
  Disk I/O tier  → THROTTLE_LEVEL_TIER3
  I/O priority   → IOPOL_THROTTLE

// Other effects:
  Timer coalescing → Aggressive
  Network QoS     → Background
  GPU priority    → Low
Normal Process
QoSUSER_INTERACTIVE
Priority31-47
SchedulerDynamic P/E
I/ONormal
After taskpolicy -b
QoSBACKGROUND
Priority4 (MAXPRI_THROTTLE)
SchedulerE-Core preferred
I/OTHROTTLE tier
04

Daemon Lifecycle (SMAppService)

The privileged helper daemon is registered with the system via Apple's SMAppService API (macOS 13+), the modern replacement for the legacy SMJobBless. Registration requires one-time administrator approval via Touch ID or password.

// Registration flow
let service = SMAppService.daemon(plistName: "com.renderfocus.helper.plist")
try service.register()

// What register() does internally:
// 1. Locates plist in Contents/Library/LaunchDaemons/
// 2. Reads BundleProgram path from plist
// 3. Validates code signing (same Team ID)
// 4. Requests admin approval (Touch ID / password)
// 5. Registers in BTM (Background Task Management)
// 6. Loads daemon into launchd system domain
// 7. Registers Mach port for XPC access
Daemon State Machine
notRegistered
Initial state
requiresApproval
Awaiting Touch ID
enabled
Active, XPC ready
05

Focus Mode Activation Flow

When the user presses the Focus button, a precise chain of events unfolds — from process discovery to kernel-level thread manipulation.

1

User selects target app and presses Focus

AppManager.activateFocusMode() is called with the selected application.

2

PID collection and filtering

All running .regular applications are collected. The focus app's PID is excluded. Remaining PIDs are sent to the daemon.

3

XPC call to daemon

throttleMultipleProcesses(pids:) sends PIDs via Mach IPC. The daemon executes taskpolicy -b -p for each PID in parallel using DispatchGroup.

4

Kernel applies QoS changes

The XNU scheduler sets TASK_POLICY_DARWIN_BG on each process. Thread priorities drop to 4, and the scheduler directs them to E-Cores.

5

UI updates and monitoring begins

The focus app moves to the P-Core visualization zone. All other apps move to E-Core zone. New app launches are automatically throttled via NSWorkspace.didLaunchApplicationNotification.

06

Apple Silicon Core Reference

RenderFocus leverages the asymmetric core architecture unique to Apple Silicon. Here's a reference of the P-Core and E-Core distribution across the M-series chip family.

P-Core (Performance)
Clock3.2 – 4.6 GHz
Decode8-wide
ROB~630 entries
L1 Cache192KB I + 128KB D
Power~15W / core
E-Core (Efficiency)
Clock2.0 – 2.8 GHz
Decode4-wide
ROB~96 entries
L1 Cache128KB I + 64KB D
Power~1-3W / core
ChipP-CoresE-CoresTotal
M1448
M1 Pro6–828–10
M2 Max8412
M3 Max10–12414–16
M4 Pro10414
M4 Max12–14416–18
07

Security Model

RenderFocus is built with a defense-in-depth approach. Every layer is designed to minimize attack surface while maintaining the kernel-level access required for thread manipulation.

ThreatProtectionDetail
Unauthorized XPC Code signing Only same Team ID apps can connect
Code injection Hardened Runtime DYLD_INSERT_LIBRARIES blocked
Malicious PID Process validation taskpolicy returns error for invalid PIDs
Daemon persistence SMAppService Removable from System Settings → Login Items
Privilege escalation Isolated architecture GUI never acquires root privileges
// Code signing chain
Apple Root CA
  └── Apple Worldwide Developer Relations CA
        └── Apple Development: [Developer]
              ├── com.renderfocus.app     // Main Application
              └── com.renderfocus.helper // XPC Daemon
08

Project Structure

The project is organized into three main targets: the main application, the helper daemon, and a shared protocol definition.

RenderFocus/
├── RenderFocus/                        // Main Application Target
│   ├── RenderFocusApp.swift          // @main entry, AppDelegate
│   ├── AppManager.swift             // NSWorkspace process monitoring
│   ├── XPCManager.swift             // SMAppService + XPC comms
│   ├── ContentView.swift            // Main UI (popover content)
│   ├── FocusVisualizerView.swift     // P/E-Core visualization
│   └── Info.plist                   // LSUIElement, bundle defs

├── RenderFocusHelper/               // Daemon Target
│   ├── main.swift                   // NSXPCListener startup
│   └── HelperTool.swift             // XPC protocol implementation

├── Shared/                          // Shared by both targets
│   └── RenderFocusXPCProtocol.swift  // @objc XPC protocol

├── com.renderfocus.helper.plist     // LaunchDaemon definition
└── project.yml                     // XcodeGen project definition