Skip to content

Commit

Permalink
feat(color): enable accent color for macOS
Browse files Browse the repository at this point in the history
resolves #5711
  • Loading branch information
JanDeDobbeleer committed Oct 5, 2024
1 parent ee7a857 commit f82c0a5
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/.goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ builds:
- osusergo
- static_build
env:
- CGO_ENABLED=0
- CGO_ENABLED=1
goos:
- linux
- windows
Expand Down
2 changes: 2 additions & 0 deletions src/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const (
ONEDAY = 1440
ONEWEEK = 10080
ONEMONTH = 43200
INFINITE = -1
)

type Entry struct {
Expand All @@ -61,5 +62,6 @@ func (c *Entry) Expired() bool {
if c.TTL < 0 {
return false
}

return time.Now().Unix() >= (c.Timestamp + int64(c.TTL)*60)
}
1 change: 1 addition & 0 deletions src/cache/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func (fc *File) Set(key, value string, ttl int) {
Timestamp: time.Now().Unix(),
TTL: ttl,
})

fc.dirty = true
}

Expand Down
52 changes: 52 additions & 0 deletions src/color/colors.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"fmt"
"strconv"
"strings"
"time"

"github.com/gookit/color"
"github.com/jandedobbeleer/oh-my-posh/src/cache"
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
"github.com/jandedobbeleer/oh-my-posh/src/template"
)
Expand All @@ -26,6 +28,20 @@ type Set struct {
Foreground Ansi `json:"foreground" toml:"foreground"`
}

func (c *Set) String() string {
return fmt.Sprintf("%s|%s", c.Foreground, c.Background)
}

func (c *Set) ParseString(colors string) {
parts := strings.Split(colors, "|")
if len(parts) != 2 {
return
}

c.Foreground = Ansi(parts[0])
c.Background = Ansi(parts[1])
}

type History []*Set

func (c *History) Len() int {
Expand Down Expand Up @@ -144,6 +160,42 @@ func MakeColors(palette Palette, cacheEnabled bool, accentColor Ansi, env runtim
return
}

func (d *Defaults) SetAccentColor(env runtime.Environment, defaultColor Ansi) {
defer env.Trace(time.Now())

// get accent color from session cache first
if accent, OK := env.Session().Get("accent_color"); OK {
accentColors := &Set{}
accentColors.ParseString(accent)
d.accent = accentColors
return
}

rgb, err := GetAccentColor(env)
if err != nil {
d.accent = &Set{
Foreground: d.ToAnsi(defaultColor, false),
Background: d.ToAnsi(defaultColor, true),
}

return
}

if len(defaultColor) == 0 {
return
}

foreground := color.RGB(rgb.R, rgb.G, rgb.B, false)
background := color.RGB(rgb.R, rgb.G, rgb.B, true)

d.accent = &Set{
Foreground: Ansi(foreground.String()),
Background: Ansi(background.String()),
}

env.Session().Set("accent_color", d.accent.String(), cache.INFINITE)
}

type RGB struct {
R, G, B uint8
}
Expand Down
60 changes: 60 additions & 0 deletions src/color/colors_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package color

/*
#cgo CFLAGS: -x objective-c
#cgo LDFLAGS: -framework Cocoa
#import <Cocoa/Cocoa.h>
typedef struct {
uint8_t R;
uint8_t G;
uint8_t B;
} RGB;
RGB getAccentColor() {
RGB color = {0, 0, 0}; // Default to black
NSColor *accentColor;
if (@available(macOS 10.14, *)) {
accentColor = [NSColor controlAccentColor];
} else {
accentColor = [NSColor blueColor]; // Default fallback
}
NSColor *rgbColor = [accentColor colorUsingColorSpace:[NSColorSpace sRGBColorSpace]];
if (rgbColor) {
CGFloat red, green, blue, alpha;
[rgbColor getRed:&red green:&green blue:&blue alpha:&alpha];
color.R = (uint8_t)(red * 255);
color.G = (uint8_t)(green * 255);
color.B = (uint8_t)(blue * 255);
}
return color;
}
*/
import "C"
import (
"errors"
"time"

"github.com/jandedobbeleer/oh-my-posh/src/runtime"
)

func GetAccentColor(env runtime.Environment) (*RGB, error) {
defer env.Trace(time.Now())

color := C.getAccentColor()

if color.R == 0 && color.G == 0 && color.B == 0 {
err := errors.New("unable to get accent color")
env.Error(err)
return nil, err
}

return &RGB{
R: uint8(color.R),
G: uint8(color.G),
B: uint8(color.B),
}, nil
}
7 changes: 7 additions & 0 deletions src/color/colors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/alecthomas/assert"
"github.com/jandedobbeleer/oh-my-posh/src/cache"
cache_ "github.com/jandedobbeleer/oh-my-posh/src/cache/mock"
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"

Expand Down Expand Up @@ -43,6 +44,12 @@ func TestGetAnsiFromColorString(t *testing.T) {
func TestMakeColors(t *testing.T) {
env := &mock.Environment{}

env.On("Trace", testify_.Anything, testify_.Anything).Return(nil)

c := &cache_.Cache{}
c.On("Get", "accent_color").Return("", false)
env.On("Session").Return(c)

env.On("WindowsRegistryKeyValue", `HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM\ColorizationColor`).Return(&runtime.WindowsRegistryValue{}, errors.New("err"))
colors := MakeColors(nil, false, "", env)
assert.IsType(t, &Defaults{}, colors)
Expand Down
13 changes: 1 addition & 12 deletions src/color/colors_unix.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build !windows
//go:build !windows && !darwin

package color

Expand All @@ -7,14 +7,3 @@ import "github.com/jandedobbeleer/oh-my-posh/src/runtime"
func GetAccentColor(_ runtime.Environment) (*RGB, error) {
return nil, &runtime.NotImplemented{}
}

func (d *Defaults) SetAccentColor(_ runtime.Environment, defaultColor Ansi) {
if len(defaultColor) == 0 {
return
}

d.accent = &Set{
Foreground: d.ToAnsi(defaultColor, false),
Background: d.ToAnsi(defaultColor, true),
}
}
24 changes: 3 additions & 21 deletions src/color/colors_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package color

import (
"errors"
"time"

"github.com/gookit/color"
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
)

func GetAccentColor(env runtime.Environment) (*RGB, error) {
defer env.Trace(time.Now())

if env == nil {
return nil, errors.New("unable to get color without environment")
}
Expand All @@ -24,23 +26,3 @@ func GetAccentColor(env runtime.Environment) (*RGB, error) {
B: byte(value.DWord),
}, nil
}

func (d *Defaults) SetAccentColor(env runtime.Environment, defaultColor Ansi) {
rgb, err := GetAccentColor(env)
if err != nil {
d.accent = &Set{
Foreground: d.ToAnsi(defaultColor, false),
Background: d.ToAnsi(defaultColor, true),
}

return
}

foreground := color.RGB(rgb.R, rgb.G, rgb.B, false)
background := color.RGB(rgb.R, rgb.G, rgb.B, true)

d.accent = &Set{
Foreground: Ansi(foreground.String()),
Background: Ansi(background.String()),
}
}
2 changes: 1 addition & 1 deletion website/docs/configuration/colors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Oh My Posh supports multiple different color references, being:
- The `background` keyword which can be used to reference the current segment's background color.
- The `parentForeground` keyword which can be used to inherit the previous active segment's foreground color.
- The `parentBackground` keyword which can be used to inherit the previous active segment's background color.
- The `accent` keyword which references the OS accent color (Windows only).
- The `accent` keyword which references the OS accent color (Windows and macOS only).

## Color templates

Expand Down

0 comments on commit f82c0a5

Please sign in to comment.