1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-04 14:26:46 +00:00

feat: add screen refresh rate display in status view

This commit is contained in:
Tw93
2026-01-03 13:33:49 +08:00
parent 5c1e3a939d
commit da7bb2cde2
3 changed files with 85 additions and 16 deletions

View File

@@ -37,11 +37,12 @@ type MetricsSnapshot struct {
}
type HardwareInfo struct {
Model string // MacBook Pro 14-inch, 2021
CPUModel string // Apple M1 Pro / Intel Core i7
TotalRAM string // 16GB
DiskSize string // 512GB
OSVersion string // macOS Sonoma 14.5
Model string // MacBook Pro 14-inch, 2021
CPUModel string // Apple M1 Pro / Intel Core i7
TotalRAM string // 16GB
DiskSize string // 512GB
OSVersion string // macOS Sonoma 14.5
RefreshRate string // 120Hz / 60Hz
}
type DiskIOStatus struct {

View File

@@ -2,6 +2,7 @@ package main
import (
"context"
"fmt"
"runtime"
"strings"
"time"
@@ -10,11 +11,12 @@ import (
func collectHardware(totalRAM uint64, disks []DiskStatus) HardwareInfo {
if runtime.GOOS != "darwin" {
return HardwareInfo{
Model: "Unknown",
CPUModel: runtime.GOARCH,
TotalRAM: humanBytes(totalRAM),
DiskSize: "Unknown",
OSVersion: runtime.GOOS,
Model: "Unknown",
CPUModel: runtime.GOARCH,
TotalRAM: humanBytes(totalRAM),
DiskSize: "Unknown",
OSVersion: runtime.GOOS,
RefreshRate: "",
}
}
@@ -22,7 +24,7 @@ func collectHardware(totalRAM uint64, disks []DiskStatus) HardwareInfo {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
var model, cpuModel, osVersion string
var model, cpuModel, osVersion, refreshRate string
out, err := runCmd(ctx, "system_profiler", "SPHardwareDataType")
if err == nil {
@@ -58,16 +60,79 @@ func collectHardware(totalRAM uint64, disks []DiskStatus) HardwareInfo {
osVersion = "macOS " + strings.TrimSpace(out2)
}
// Get refresh rate from display info (use mini detail to keep it fast).
ctx3, cancel3 := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel3()
out3, err := runCmd(ctx3, "system_profiler", "-detailLevel", "mini", "SPDisplaysDataType")
if err == nil {
refreshRate = parseRefreshRate(out3)
}
diskSize := "Unknown"
if len(disks) > 0 {
diskSize = humanBytes(disks[0].Total)
}
return HardwareInfo{
Model: model,
CPUModel: cpuModel,
TotalRAM: humanBytes(totalRAM),
DiskSize: diskSize,
OSVersion: osVersion,
Model: model,
CPUModel: cpuModel,
TotalRAM: humanBytes(totalRAM),
DiskSize: diskSize,
OSVersion: osVersion,
RefreshRate: refreshRate,
}
}
// parseRefreshRate extracts the highest refresh rate from system_profiler display output.
func parseRefreshRate(output string) string {
lines := strings.Split(output, "\n")
maxHz := 0
for _, line := range lines {
lower := strings.ToLower(line)
// Look for patterns like "@ 60Hz", "@ 60.00Hz", or "Refresh Rate: 120 Hz".
if strings.Contains(lower, "hz") {
fields := strings.Fields(lower)
for i, field := range fields {
if field == "hz" && i > 0 {
if hz := parseInt(fields[i-1]); hz > maxHz && hz < 500 {
maxHz = hz
}
continue
}
if strings.HasSuffix(field, "hz") {
numStr := strings.TrimSuffix(field, "hz")
if numStr == "" && i > 0 {
numStr = fields[i-1]
}
if hz := parseInt(numStr); hz > maxHz && hz < 500 {
maxHz = hz
}
}
}
}
}
if maxHz > 0 {
return fmt.Sprintf("%dHz", maxHz)
}
return ""
}
// parseInt safely parses an integer from a string.
func parseInt(s string) int {
// Trim away non-numeric padding, keep digits and '.' for decimals.
cleaned := strings.TrimSpace(s)
cleaned = strings.TrimLeftFunc(cleaned, func(r rune) bool {
return (r < '0' || r > '9') && r != '.'
})
cleaned = strings.TrimRightFunc(cleaned, func(r rune) bool {
return (r < '0' || r > '9') && r != '.'
})
if cleaned == "" {
return 0
}
var num int
fmt.Sscanf(cleaned, "%d", &num)
return num
}

View File

@@ -125,6 +125,9 @@ func renderHeader(m MetricsSnapshot, errMsg string, animFrame int, termWidth int
if len(specs) > 0 {
infoParts = append(infoParts, strings.Join(specs, "/"))
}
if m.Hardware.RefreshRate != "" {
infoParts = append(infoParts, m.Hardware.RefreshRate)
}
if m.Hardware.OSVersion != "" {
infoParts = append(infoParts, m.Hardware.OSVersion)
}