1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-31 08:52:49 -05:00

Compare commits

..

9 Commits

Author SHA1 Message Date
bbedward
3ae1973e21 screenshot/colorpicker: fix scaling, update go-wayland to fix object
destruction, fix hyprland window detection
2025-12-07 13:44:35 -05:00
bbedward
308c8c3ea7 lock screen: fix inconsistency with network status, add VPN
maybe fix #926
2025-12-07 12:33:29 -05:00
bbedward
f49b5dd037 media player: replace color quantizer with album art 2025-12-07 12:23:00 -05:00
bbedward
f245ba82ad gamma: fix non-automation toggling
fixes #924
2025-12-07 12:02:50 -05:00
arfan
60d22d6973 feat: add workspace index display when app icon enabled (#936) 2025-12-07 11:48:48 -05:00
Farokh
d6f48a82d9 Update VSCode color theme templates for improved contrast and readability (#931)
* matugen/vscode-theme: update VSCode templates for contrast and readability

* vscode-theme: rework dark theme, refine light, restore default fallback

* dank16: add variants option, make default vscode consistent, fix termial
always dark

---------

Co-authored-by: bbedward <bbedward@gmail.com>
2025-12-07 11:47:25 -05:00
Marcus Ramberg
c0d73dae67 fix: handle ipc arguments (#930) 2025-12-07 11:01:31 -05:00
Marcus Ramberg
49eb60589d fix: also restart ghostty/kitty on nix (#934) 2025-12-07 10:28:26 -05:00
Marcus Ramberg
89993b7421 core: remove unused function after refactors (#935) 2025-12-07 10:27:44 -05:00
40 changed files with 1766 additions and 1844 deletions

View File

@@ -10,15 +10,15 @@ import (
) )
var dank16Cmd = &cobra.Command{ var dank16Cmd = &cobra.Command{
Use: "dank16 <hex_color>", Use: "dank16 [hex_color]",
Short: "Generate Base16 color palettes", Short: "Generate Base16 color palettes",
Long: "Generate Base16 color palettes from a color with support for various output formats", Long: "Generate Base16 color palettes from a color with support for various output formats",
Args: cobra.ExactArgs(1), Args: cobra.MaximumNArgs(1),
Run: runDank16, Run: runDank16,
} }
func init() { func init() {
dank16Cmd.Flags().Bool("light", false, "Generate light theme variant") dank16Cmd.Flags().Bool("light", false, "Generate light theme variant (sets default to light)")
dank16Cmd.Flags().Bool("json", false, "Output in JSON format") dank16Cmd.Flags().Bool("json", false, "Output in JSON format")
dank16Cmd.Flags().Bool("kitty", false, "Output in Kitty terminal format") dank16Cmd.Flags().Bool("kitty", false, "Output in Kitty terminal format")
dank16Cmd.Flags().Bool("foot", false, "Output in Foot terminal format") dank16Cmd.Flags().Bool("foot", false, "Output in Foot terminal format")
@@ -27,17 +27,15 @@ func init() {
dank16Cmd.Flags().Bool("wezterm", false, "Output in Wezterm terminal format") dank16Cmd.Flags().Bool("wezterm", false, "Output in Wezterm terminal format")
dank16Cmd.Flags().String("background", "", "Custom background color") dank16Cmd.Flags().String("background", "", "Custom background color")
dank16Cmd.Flags().String("contrast", "dps", "Contrast algorithm: dps (Delta Phi Star, default) or wcag") dank16Cmd.Flags().String("contrast", "dps", "Contrast algorithm: dps (Delta Phi Star, default) or wcag")
dank16Cmd.Flags().Bool("variants", false, "Output all variants (dark/light/default) in JSON")
dank16Cmd.Flags().String("primary-dark", "", "Primary color for dark mode (use with --variants)")
dank16Cmd.Flags().String("primary-light", "", "Primary color for light mode (use with --variants)")
_ = dank16Cmd.RegisterFlagCompletionFunc("contrast", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { _ = dank16Cmd.RegisterFlagCompletionFunc("contrast", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"dps", "wcag"}, cobra.ShellCompDirectiveNoFileComp return []string{"dps", "wcag"}, cobra.ShellCompDirectiveNoFileComp
}) })
} }
func runDank16(cmd *cobra.Command, args []string) { func runDank16(cmd *cobra.Command, args []string) {
primaryColor := args[0]
if !strings.HasPrefix(primaryColor, "#") {
primaryColor = "#" + primaryColor
}
isLight, _ := cmd.Flags().GetBool("light") isLight, _ := cmd.Flags().GetBool("light")
isJson, _ := cmd.Flags().GetBool("json") isJson, _ := cmd.Flags().GetBool("json")
isKitty, _ := cmd.Flags().GetBool("kitty") isKitty, _ := cmd.Flags().GetBool("kitty")
@@ -47,16 +45,57 @@ func runDank16(cmd *cobra.Command, args []string) {
isWezterm, _ := cmd.Flags().GetBool("wezterm") isWezterm, _ := cmd.Flags().GetBool("wezterm")
background, _ := cmd.Flags().GetString("background") background, _ := cmd.Flags().GetString("background")
contrastAlgo, _ := cmd.Flags().GetString("contrast") contrastAlgo, _ := cmd.Flags().GetString("contrast")
useVariants, _ := cmd.Flags().GetBool("variants")
primaryDark, _ := cmd.Flags().GetString("primary-dark")
primaryLight, _ := cmd.Flags().GetString("primary-light")
if background != "" && !strings.HasPrefix(background, "#") { if background != "" && !strings.HasPrefix(background, "#") {
background = "#" + background background = "#" + background
} }
if primaryDark != "" && !strings.HasPrefix(primaryDark, "#") {
primaryDark = "#" + primaryDark
}
if primaryLight != "" && !strings.HasPrefix(primaryLight, "#") {
primaryLight = "#" + primaryLight
}
contrastAlgo = strings.ToLower(contrastAlgo) contrastAlgo = strings.ToLower(contrastAlgo)
if contrastAlgo != "dps" && contrastAlgo != "wcag" { if contrastAlgo != "dps" && contrastAlgo != "wcag" {
log.Fatalf("Invalid contrast algorithm: %s (must be 'dps' or 'wcag')", contrastAlgo) log.Fatalf("Invalid contrast algorithm: %s (must be 'dps' or 'wcag')", contrastAlgo)
} }
if useVariants {
if primaryDark == "" || primaryLight == "" {
if len(args) == 0 {
log.Fatalf("--variants requires either a positional color argument or both --primary-dark and --primary-light")
}
primaryColor := args[0]
if !strings.HasPrefix(primaryColor, "#") {
primaryColor = "#" + primaryColor
}
primaryDark = primaryColor
primaryLight = primaryColor
}
variantOpts := dank16.VariantOptions{
PrimaryDark: primaryDark,
PrimaryLight: primaryLight,
Background: background,
UseDPS: contrastAlgo == "dps",
IsLightMode: isLight,
}
variantColors := dank16.GenerateVariantPalette(variantOpts)
fmt.Print(dank16.GenerateVariantJSON(variantColors))
return
}
if len(args) == 0 {
log.Fatalf("A color argument is required (or use --variants with --primary-dark and --primary-light)")
}
primaryColor := args[0]
if !strings.HasPrefix(primaryColor, "#") {
primaryColor = "#" + primaryColor
}
opts := dank16.PaletteOptions{ opts := dank16.PaletteOptions{
IsLight: isLight, IsLight: isLight,
Background: background, Background: background,

View File

@@ -16,7 +16,7 @@ import (
"github.com/AvengeMedia/DankMaterialShell/core/internal/server" "github.com/AvengeMedia/DankMaterialShell/core/internal/server"
) )
type ipcTargets map[string][]string type ipcTargets map[string]map[string][]string
var isSessionManaged bool var isSessionManaged bool
@@ -476,16 +476,29 @@ func runShellDaemon(session bool) {
} }
func parseTargetsFromIPCShowOutput(output string) ipcTargets { func parseTargetsFromIPCShowOutput(output string) ipcTargets {
targets := map[string][]string{} targets := make(ipcTargets)
var currentTarget string var currentTarget string
for _, line := range strings.Split(output, "\n") { for _, line := range strings.Split(output, "\n") {
if strings.HasPrefix(line, "target ") { if strings.HasPrefix(line, "target ") {
currentTarget = strings.TrimSpace(strings.TrimPrefix(line, "target ")) currentTarget = strings.TrimSpace(strings.TrimPrefix(line, "target "))
targets[currentTarget] = make(map[string][]string)
} }
if strings.HasPrefix(line, " function") && currentTarget != "" { if strings.HasPrefix(line, " function") && currentTarget != "" {
argsList := []string{}
currentFunc := strings.TrimPrefix(line, " function ") currentFunc := strings.TrimPrefix(line, " function ")
currentFunc = strings.SplitN(currentFunc, "(", 2)[0] funcDef := strings.SplitN(currentFunc, "(", 2)
targets[currentTarget] = append(targets[currentTarget], currentFunc) argList := strings.SplitN(funcDef[1], ")", 2)[0]
args := strings.Split(argList, ",")
if len(args) > 0 && strings.TrimSpace(args[0]) != "" {
argsList = append(argsList, funcDef[0])
for _, arg := range args {
argName := strings.SplitN(strings.TrimSpace(arg), ":", 2)[0]
argsList = append(argsList, argName)
}
targets[currentTarget][funcDef[0]] = argsList
} else {
targets[currentTarget][funcDef[0]] = make([]string, 0)
}
} }
} }
return targets return targets
@@ -497,7 +510,6 @@ func getShellIPCCompletions(args []string, toComplete string) []string {
var targets ipcTargets var targets ipcTargets
if output, err := cmd.Output(); err == nil { if output, err := cmd.Output(); err == nil {
log.Debugf("IPC show output: %s", string(output))
targets = parseTargetsFromIPCShowOutput(string(output)) targets = parseTargetsFromIPCShowOutput(string(output))
} else { } else {
log.Debugf("Error getting IPC show output for completions: %v", err) log.Debugf("Error getting IPC show output for completions: %v", err)
@@ -516,8 +528,24 @@ func getShellIPCCompletions(args []string, toComplete string) []string {
} }
return targetNames return targetNames
} }
if len(args) == 1 {
if targetFuncs, ok := targets[args[0]]; ok {
funcNames := make([]string, 0)
for k := range targetFuncs {
funcNames = append(funcNames, k)
}
return funcNames
}
return nil
}
if len(args) <= len(targets[args[0]]) {
funcArgs := targets[args[0]][args[1]]
if len(funcArgs) >= len(args) {
return []string{fmt.Sprintf("[%s]", funcArgs[len(args)-1])}
}
}
return targets[args[0]] return nil
} }
func runShellIPCCommand(args []string) { func runShellIPCCommand(args []string) {

View File

@@ -2,7 +2,6 @@ package colorpicker
import ( import (
"fmt" "fmt"
"math"
"sync" "sync"
"github.com/AvengeMedia/DankMaterialShell/core/internal/log" "github.com/AvengeMedia/DankMaterialShell/core/internal/log"
@@ -116,6 +115,11 @@ func (p *Picker) Run() (*Color, error) {
return nil, fmt.Errorf("roundtrip: %w", err) return nil, fmt.Errorf("roundtrip: %w", err)
} }
// Extra roundtrip to ensure pointer/keyboard from seat capabilities are registered
if err := p.roundtrip(); err != nil {
return nil, fmt.Errorf("roundtrip after seat: %w", err)
}
if err := p.createSurfaces(); err != nil { if err := p.createSurfaces(); err != nil {
return nil, fmt.Errorf("create surfaces: %w", err) return nil, fmt.Errorf("create surfaces: %w", err)
} }
@@ -405,15 +409,10 @@ func (p *Picker) createLayerSurface(output *Output) (*LayerSurface, error) {
func (p *Picker) computeSurfaceScale(ls *LayerSurface) int32 { func (p *Picker) computeSurfaceScale(ls *LayerSurface) int32 {
out := ls.output out := ls.output
if out == nil || out.fractionalScale <= 0 { if out == nil || out.scale <= 0 {
return 1 return 1
} }
return out.scale
scale := int32(math.Ceil(out.fractionalScale))
if scale <= 0 {
scale = 1
}
return scale
} }
func (p *Picker) ensureShortcutsInhibitor(ls *LayerSurface) { func (p *Picker) ensureShortcutsInhibitor(ls *LayerSurface) {
@@ -485,6 +484,13 @@ func (p *Picker) captureForSurface(ls *LayerSurface) {
frame.SetReadyHandler(func(e wlr_screencopy.ZwlrScreencopyFrameV1ReadyEvent) { frame.SetReadyHandler(func(e wlr_screencopy.ZwlrScreencopyFrameV1ReadyEvent) {
ls.state.OnScreencopyReady() ls.state.OnScreencopyReady()
logicalW, _ := ls.state.LogicalSize()
screenBuf := ls.state.ScreenBuffer()
if logicalW > 0 && screenBuf != nil {
ls.output.fractionalScale = float64(screenBuf.Width) / float64(logicalW)
}
scale := p.computeSurfaceScale(ls) scale := p.computeSurfaceScale(ls)
ls.state.SetScale(scale) ls.state.SetScale(scale)
frame.Destroy() frame.Destroy()
@@ -545,18 +551,17 @@ func (p *Picker) redrawSurface(ls *LayerSurface) {
logicalH = int(ls.output.height) logicalH = int(ls.output.height)
} }
scale := ls.state.Scale()
if scale <= 0 {
scale = 1
}
if ls.viewport != nil { if ls.viewport != nil {
srcW := float64(renderBuf.Width) / float64(scale) _ = ls.wlSurface.SetBufferScale(1)
srcH := float64(renderBuf.Height) / float64(scale) _ = ls.viewport.SetSource(0, 0, float64(renderBuf.Width), float64(renderBuf.Height))
_ = ls.viewport.SetSource(0, 0, srcW, srcH)
_ = ls.viewport.SetDestination(int32(logicalW), int32(logicalH)) _ = ls.viewport.SetDestination(int32(logicalW), int32(logicalH))
} else {
bufferScale := ls.output.scale
if bufferScale <= 0 {
bufferScale = 1
}
_ = ls.wlSurface.SetBufferScale(bufferScale)
} }
_ = ls.wlSurface.SetBufferScale(scale)
_ = ls.wlSurface.Attach(wlBuffer, 0, 0) _ = ls.wlSurface.Attach(wlBuffer, 0, 0)
_ = ls.wlSurface.Damage(0, 0, int32(logicalW), int32(logicalH)) _ = ls.wlSurface.Damage(0, 0, int32(logicalW), int32(logicalH))
_ = ls.wlSurface.Commit() _ = ls.wlSurface.Commit()
@@ -581,17 +586,19 @@ func (p *Picker) setupInput() {
p.seat.SetCapabilitiesHandler(func(e client.SeatCapabilitiesEvent) { p.seat.SetCapabilitiesHandler(func(e client.SeatCapabilitiesEvent) {
if e.Capabilities&uint32(client.SeatCapabilityPointer) != 0 && p.pointer == nil { if e.Capabilities&uint32(client.SeatCapabilityPointer) != 0 && p.pointer == nil {
pointer, err := p.seat.GetPointer() pointer, err := p.seat.GetPointer()
if err == nil { if err != nil {
p.pointer = pointer return
p.setupPointerHandlers()
} }
p.pointer = pointer
p.setupPointerHandlers()
} }
if e.Capabilities&uint32(client.SeatCapabilityKeyboard) != 0 && p.keyboard == nil { if e.Capabilities&uint32(client.SeatCapabilityKeyboard) != 0 && p.keyboard == nil {
keyboard, err := p.seat.GetKeyboard() keyboard, err := p.seat.GetKeyboard()
if err == nil { if err != nil {
p.keyboard = keyboard return
p.setupKeyboardHandlers()
} }
p.keyboard = keyboard
p.setupKeyboardHandlers()
} }
}) })
} }

View File

@@ -269,12 +269,17 @@ func (s *SurfaceState) Redraw() *ShmBuffer {
px = clamp(px, 0, dst.Width-1) px = clamp(px, 0, dst.Width-1)
py = clamp(py, 0, dst.Height-1) py = clamp(py, 0, dst.Height-1)
picked := GetPixelColorWithFormat(s.screenBuf, px, py, s.screenFormat) sampleY := py
if s.yInverted {
sampleY = s.screenBuf.Height - 1 - py
}
drawMagnifier( picked := GetPixelColorWithFormat(s.screenBuf, px, sampleY, s.screenFormat)
drawMagnifierWithInversion(
dst.Data(), dst.Stride, dst.Width, dst.Height, dst.Data(), dst.Stride, dst.Width, dst.Height,
s.screenBuf.Data(), s.screenBuf.Stride, s.screenBuf.Width, s.screenBuf.Height, s.screenBuf.Data(), s.screenBuf.Stride, s.screenBuf.Width, s.screenBuf.Height,
px, py, picked, px, py, picked, s.yInverted,
) )
drawColorPreview(dst.Data(), dst.Stride, dst.Width, dst.Height, px, py, picked, s.displayFormat, s.lowercase) drawColorPreview(dst.Data(), dst.Stride, dst.Width, dst.Height, px, py, picked, s.displayFormat, s.lowercase)
@@ -379,11 +384,12 @@ func blendColors(bg, fg Color, alpha float64) Color {
} }
} }
func drawMagnifier( func drawMagnifierWithInversion(
dst []byte, dstStride, dstW, dstH int, dst []byte, dstStride, dstW, dstH int,
src []byte, srcStride, srcW, srcH int, src []byte, srcStride, srcW, srcH int,
cx, cy int, cx, cy int,
borderColor Color, borderColor Color,
yInverted bool,
) { ) {
if dstW <= 0 || dstH <= 0 || srcW <= 0 || srcH <= 0 { if dstW <= 0 || dstH <= 0 || srcW <= 0 || srcH <= 0 {
return return
@@ -439,10 +445,11 @@ func drawMagnifier(
finalColor = blendColors(bgColor, borderColor, alpha) finalColor = blendColors(bgColor, borderColor, alpha)
case dist > innerRadius: case dist > innerRadius:
if dist > outerRadiusF-aaWidth { switch {
case dist > outerRadiusF-aaWidth:
alpha := clampF((outerRadiusF-dist)/aaWidth, 0, 1) alpha := clampF((outerRadiusF-dist)/aaWidth, 0, 1)
finalColor = blendColors(borderColor, borderColor, alpha) finalColor = blendColors(borderColor, borderColor, alpha)
} else if dist < innerRadius+aaWidth { case dist < innerRadius+aaWidth:
alpha := clampF((dist-innerRadius)/aaWidth, 0, 1) alpha := clampF((dist-innerRadius)/aaWidth, 0, 1)
fx := float64(dx) / zoom fx := float64(dx) / zoom
fy := float64(dy) / zoom fy := float64(dy) / zoom
@@ -450,6 +457,9 @@ func drawMagnifier(
sy := cy + int(math.Round(fy)) sy := cy + int(math.Round(fy))
sx = clamp(sx, 0, srcW-1) sx = clamp(sx, 0, srcW-1)
sy = clamp(sy, 0, srcH-1) sy = clamp(sy, 0, srcH-1)
if yInverted {
sy = srcH - 1 - sy
}
srcOff := sy*srcStride + sx*4 srcOff := sy*srcStride + sx*4
if srcOff+4 <= len(src) { if srcOff+4 <= len(src) {
magColor := Color{B: src[srcOff+0], G: src[srcOff+1], R: src[srcOff+2], A: 255} magColor := Color{B: src[srcOff+0], G: src[srcOff+1], R: src[srcOff+2], A: 255}
@@ -457,7 +467,7 @@ func drawMagnifier(
} else { } else {
finalColor = borderColor finalColor = borderColor
} }
} else { default:
finalColor = borderColor finalColor = borderColor
} }
@@ -468,6 +478,9 @@ func drawMagnifier(
sy := cy + int(math.Round(fy)) sy := cy + int(math.Round(fy))
sx = clamp(sx, 0, srcW-1) sx = clamp(sx, 0, srcW-1)
sy = clamp(sy, 0, srcH-1) sy = clamp(sy, 0, srcH-1)
if yInverted {
sy = srcH - 1 - sy
}
srcOff := sy*srcStride + sx*4 srcOff := sy*srcStride + sx*4
if srcOff+4 <= len(src) { if srcOff+4 <= len(src) {
finalColor = Color{B: src[srcOff+0], G: src[srcOff+1], R: src[srcOff+2], A: 255} finalColor = Color{B: src[srcOff+0], G: src[srcOff+1], R: src[srcOff+2], A: 255}

View File

@@ -23,6 +23,17 @@ type ColorInfo struct {
B int `json:"b"` B int `json:"b"`
} }
type VariantColorValue struct {
Hex string `json:"hex"`
HexStripped string `json:"hex_stripped"`
}
type VariantColorInfo struct {
Dark VariantColorValue `json:"dark"`
Light VariantColorValue `json:"light"`
Default VariantColorValue `json:"default"`
}
type Palette struct { type Palette struct {
Color0 ColorInfo `json:"color0"` Color0 ColorInfo `json:"color0"`
Color1 ColorInfo `json:"color1"` Color1 ColorInfo `json:"color1"`
@@ -42,6 +53,25 @@ type Palette struct {
Color15 ColorInfo `json:"color15"` Color15 ColorInfo `json:"color15"`
} }
type VariantPalette struct {
Color0 VariantColorInfo `json:"color0"`
Color1 VariantColorInfo `json:"color1"`
Color2 VariantColorInfo `json:"color2"`
Color3 VariantColorInfo `json:"color3"`
Color4 VariantColorInfo `json:"color4"`
Color5 VariantColorInfo `json:"color5"`
Color6 VariantColorInfo `json:"color6"`
Color7 VariantColorInfo `json:"color7"`
Color8 VariantColorInfo `json:"color8"`
Color9 VariantColorInfo `json:"color9"`
Color10 VariantColorInfo `json:"color10"`
Color11 VariantColorInfo `json:"color11"`
Color12 VariantColorInfo `json:"color12"`
Color13 VariantColorInfo `json:"color13"`
Color14 VariantColorInfo `json:"color14"`
Color15 VariantColorInfo `json:"color15"`
}
func NewColorInfo(hex string) ColorInfo { func NewColorInfo(hex string) ColorInfo {
rgb := HexToRGB(hex) rgb := HexToRGB(hex)
stripped := hex stripped := hex
@@ -492,3 +522,54 @@ func GeneratePalette(primaryColor string, opts PaletteOptions) Palette {
return palette return palette
} }
type VariantOptions struct {
PrimaryDark string
PrimaryLight string
Background string
UseDPS bool
IsLightMode bool
}
func mergeColorInfo(dark, light ColorInfo, isLightMode bool) VariantColorInfo {
darkVal := VariantColorValue{Hex: dark.Hex, HexStripped: dark.HexStripped}
lightVal := VariantColorValue{Hex: light.Hex, HexStripped: light.HexStripped}
defaultVal := darkVal
if isLightMode {
defaultVal = lightVal
}
return VariantColorInfo{
Dark: darkVal,
Light: lightVal,
Default: defaultVal,
}
}
func GenerateVariantPalette(opts VariantOptions) VariantPalette {
darkOpts := PaletteOptions{IsLight: false, Background: opts.Background, UseDPS: opts.UseDPS}
lightOpts := PaletteOptions{IsLight: true, Background: opts.Background, UseDPS: opts.UseDPS}
dark := GeneratePalette(opts.PrimaryDark, darkOpts)
light := GeneratePalette(opts.PrimaryLight, lightOpts)
return VariantPalette{
Color0: mergeColorInfo(dark.Color0, light.Color0, opts.IsLightMode),
Color1: mergeColorInfo(dark.Color1, light.Color1, opts.IsLightMode),
Color2: mergeColorInfo(dark.Color2, light.Color2, opts.IsLightMode),
Color3: mergeColorInfo(dark.Color3, light.Color3, opts.IsLightMode),
Color4: mergeColorInfo(dark.Color4, light.Color4, opts.IsLightMode),
Color5: mergeColorInfo(dark.Color5, light.Color5, opts.IsLightMode),
Color6: mergeColorInfo(dark.Color6, light.Color6, opts.IsLightMode),
Color7: mergeColorInfo(dark.Color7, light.Color7, opts.IsLightMode),
Color8: mergeColorInfo(dark.Color8, light.Color8, opts.IsLightMode),
Color9: mergeColorInfo(dark.Color9, light.Color9, opts.IsLightMode),
Color10: mergeColorInfo(dark.Color10, light.Color10, opts.IsLightMode),
Color11: mergeColorInfo(dark.Color11, light.Color11, opts.IsLightMode),
Color12: mergeColorInfo(dark.Color12, light.Color12, opts.IsLightMode),
Color13: mergeColorInfo(dark.Color13, light.Color13, opts.IsLightMode),
Color14: mergeColorInfo(dark.Color14, light.Color14, opts.IsLightMode),
Color15: mergeColorInfo(dark.Color15, light.Color15, opts.IsLightMode),
}
}

View File

@@ -11,6 +11,11 @@ func GenerateJSON(p Palette) string {
return string(marshalled) return string(marshalled)
} }
func GenerateVariantJSON(p VariantPalette) string {
marshalled, _ := json.Marshal(p)
return string(marshalled)
}
func GenerateKittyTheme(p Palette) string { func GenerateKittyTheme(p Palette) string {
var result strings.Builder var result strings.Builder
fmt.Fprintf(&result, "color0 %s\n", p.Color0.Hex) fmt.Fprintf(&result, "color0 %s\n", p.Color0.Hex)

View File

@@ -17,8 +17,10 @@ import (
"github.com/AvengeMedia/DankMaterialShell/core/internal/version" "github.com/AvengeMedia/DankMaterialShell/core/internal/version"
) )
const forceQuickshellGit = false const (
const forceDMSGit = false forceQuickshellGit = false
forceDMSGit = false
)
// BaseDistribution provides common functionality for all distributions // BaseDistribution provides common functionality for all distributions
type BaseDistribution struct { type BaseDistribution struct {
@@ -219,20 +221,6 @@ func (b *BaseDistribution) detectClipboardTools() []deps.Dependency {
return dependencies return dependencies
} }
func (b *BaseDistribution) detectHyprpicker() deps.Dependency {
status := deps.StatusMissing
if b.commandExists("hyprpicker") {
status = deps.StatusInstalled
}
return deps.Dependency{
Name: "hyprpicker",
Status: status,
Description: "Color picker for Wayland",
Required: true,
}
}
func (b *BaseDistribution) detectHyprlandTools() []deps.Dependency { func (b *BaseDistribution) detectHyprlandTools() []deps.Dependency {
var dependencies []deps.Dependency var dependencies []deps.Dependency
@@ -602,7 +590,7 @@ func (b *BaseDistribution) installDMSBinary(ctx context.Context, sudoPassword st
return fmt.Errorf("failed to get user home directory: %w", err) return fmt.Errorf("failed to get user home directory: %w", err)
} }
tmpDir := filepath.Join(homeDir, ".cache", "dankinstall", "manual-builds") tmpDir := filepath.Join(homeDir, ".cache", "dankinstall", "manual-builds")
if err := os.MkdirAll(tmpDir, 0755); err != nil { if err := os.MkdirAll(tmpDir, 0o755); err != nil {
return fmt.Errorf("failed to create temp directory: %w", err) return fmt.Errorf("failed to create temp directory: %w", err)
} }
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)

View File

@@ -44,7 +44,7 @@ func NewZdwlIpcManagerV2(ctx *client.Context) *ZdwlIpcManagerV2 {
// Indicates that the client will not the dwl_ipc_manager object anymore. // Indicates that the client will not the dwl_ipc_manager object anymore.
// Objects created through this instance are not affected. // Objects created through this instance are not affected.
func (i *ZdwlIpcManagerV2) Release() error { func (i *ZdwlIpcManagerV2) Release() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -188,7 +188,7 @@ func NewZdwlIpcOutputV2(ctx *client.Context) *ZdwlIpcOutputV2 {
// //
// Indicates to that the client no longer needs this dwl_ipc_output. // Indicates to that the client no longer needs this dwl_ipc_output.
func (i *ZdwlIpcOutputV2) Release() error { func (i *ZdwlIpcOutputV2) Release() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte

View File

@@ -174,7 +174,7 @@ func (i *ExtWorkspaceManagerV1) Stop() error {
} }
func (i *ExtWorkspaceManagerV1) Destroy() error { func (i *ExtWorkspaceManagerV1) Destroy() error {
i.Context().Unregister(i) i.MarkZombie()
return nil return nil
} }
@@ -385,7 +385,7 @@ func (i *ExtWorkspaceGroupHandleV1) CreateWorkspace(workspace string) error {
// use the workspace group object any more or after the removed event to finalize // use the workspace group object any more or after the removed event to finalize
// the destruction of the object. // the destruction of the object.
func (i *ExtWorkspaceGroupHandleV1) Destroy() error { func (i *ExtWorkspaceGroupHandleV1) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 1 const opcode = 1
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -655,7 +655,7 @@ func NewExtWorkspaceHandleV1(ctx *client.Context) *ExtWorkspaceHandleV1 {
// use the workspace object any more or after the remove event to finalize // use the workspace object any more or after the remove event to finalize
// the destruction of the object. // the destruction of the object.
func (i *ExtWorkspaceHandleV1) Destroy() error { func (i *ExtWorkspaceHandleV1) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte

View File

@@ -54,7 +54,7 @@ func NewZwpKeyboardShortcutsInhibitManagerV1(ctx *client.Context) *ZwpKeyboardSh
// //
// Destroy the keyboard shortcuts inhibitor manager. // Destroy the keyboard shortcuts inhibitor manager.
func (i *ZwpKeyboardShortcutsInhibitManagerV1) Destroy() error { func (i *ZwpKeyboardShortcutsInhibitManagerV1) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -218,7 +218,7 @@ func NewZwpKeyboardShortcutsInhibitorV1(ctx *client.Context) *ZwpKeyboardShortcu
// //
// Remove the keyboard shortcuts inhibitor from the associated wl_surface. // Remove the keyboard shortcuts inhibitor from the associated wl_surface.
func (i *ZwpKeyboardShortcutsInhibitorV1) Destroy() error { func (i *ZwpKeyboardShortcutsInhibitorV1) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte

View File

@@ -85,7 +85,7 @@ func (i *ZwlrGammaControlManagerV1) GetGammaControl(output *client.Output) (*Zwl
// All objects created by the manager will still remain valid, until their // All objects created by the manager will still remain valid, until their
// appropriate destroy request has been called. // appropriate destroy request has been called.
func (i *ZwlrGammaControlManagerV1) Destroy() error { func (i *ZwlrGammaControlManagerV1) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 1 const opcode = 1
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -169,7 +169,7 @@ func (i *ZwlrGammaControlV1) SetGamma(fd int) error {
// Destroys the gamma control object. If the object is still valid, this // Destroys the gamma control object. If the object is still valid, this
// restores the original gamma tables. // restores the original gamma tables.
func (i *ZwlrGammaControlV1) Destroy() error { func (i *ZwlrGammaControlV1) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 1 const opcode = 1
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte

View File

@@ -129,7 +129,7 @@ func (i *ZwlrLayerShellV1) GetLayerSurface(surface *client.Surface, output *clie
// object any more. Objects that have been created through this instance // object any more. Objects that have been created through this instance
// are not affected. // are not affected.
func (i *ZwlrLayerShellV1) Destroy() error { func (i *ZwlrLayerShellV1) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 1 const opcode = 1
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -509,7 +509,7 @@ func (i *ZwlrLayerSurfaceV1) AckConfigure(serial uint32) error {
// //
// This request destroys the layer surface. // This request destroys the layer surface.
func (i *ZwlrLayerSurfaceV1) Destroy() error { func (i *ZwlrLayerSurfaceV1) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 7 const opcode = 7
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte

View File

@@ -172,7 +172,7 @@ func (i *ZwlrOutputManagerV1) Stop() error {
} }
func (i *ZwlrOutputManagerV1) Destroy() error { func (i *ZwlrOutputManagerV1) Destroy() error {
i.Context().Unregister(i) i.MarkZombie()
return nil return nil
} }
@@ -334,7 +334,7 @@ func NewZwlrOutputHeadV1(ctx *client.Context) *ZwlrOutputHeadV1 {
// This request indicates that the client will no longer use this head // This request indicates that the client will no longer use this head
// object. // object.
func (i *ZwlrOutputHeadV1) Release() error { func (i *ZwlrOutputHeadV1) Release() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -879,7 +879,7 @@ func NewZwlrOutputModeV1(ctx *client.Context) *ZwlrOutputModeV1 {
// This request indicates that the client will no longer use this mode // This request indicates that the client will no longer use this mode
// object. // object.
func (i *ZwlrOutputModeV1) Release() error { func (i *ZwlrOutputModeV1) Release() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -1132,7 +1132,7 @@ func (i *ZwlrOutputConfigurationV1) Test() error {
// This request also destroys wlr_output_configuration_head objects created // This request also destroys wlr_output_configuration_head objects created
// via this object. // via this object.
func (i *ZwlrOutputConfigurationV1) Destroy() error { func (i *ZwlrOutputConfigurationV1) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 4 const opcode = 4
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -1415,7 +1415,7 @@ func (i *ZwlrOutputConfigurationHeadV1) SetAdaptiveSync(state uint32) error {
} }
func (i *ZwlrOutputConfigurationHeadV1) Destroy() error { func (i *ZwlrOutputConfigurationHeadV1) Destroy() error {
i.Context().Unregister(i) i.MarkZombie()
return nil return nil
} }

View File

@@ -79,7 +79,7 @@ func (i *ZwlrOutputPowerManagerV1) GetOutputPower(output *client.Output) (*ZwlrO
// All objects created by the manager will still remain valid, until their // All objects created by the manager will still remain valid, until their
// appropriate destroy request has been called. // appropriate destroy request has been called.
func (i *ZwlrOutputPowerManagerV1) Destroy() error { func (i *ZwlrOutputPowerManagerV1) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 1 const opcode = 1
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -143,7 +143,7 @@ func (i *ZwlrOutputPowerV1) SetMode(mode uint32) error {
// //
// Destroys the output power management mode control object. // Destroys the output power management mode control object.
func (i *ZwlrOutputPowerV1) Destroy() error { func (i *ZwlrOutputPowerV1) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 1 const opcode = 1
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte

View File

@@ -120,7 +120,7 @@ func (i *ZwlrScreencopyManagerV1) CaptureOutputRegion(overlayCursor int32, outpu
// All objects created by the manager will still remain valid, until their // All objects created by the manager will still remain valid, until their
// appropriate destroy request has been called. // appropriate destroy request has been called.
func (i *ZwlrScreencopyManagerV1) Destroy() error { func (i *ZwlrScreencopyManagerV1) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 2 const opcode = 2
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -219,7 +219,7 @@ func (i *ZwlrScreencopyFrameV1) Copy(buffer *client.Buffer) error {
// //
// Destroys the frame. This request can be sent at any time by the client. // Destroys the frame. This request can be sent at any time by the client.
func (i *ZwlrScreencopyFrameV1) Destroy() error { func (i *ZwlrScreencopyFrameV1) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 1 const opcode = 1
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte

View File

@@ -66,7 +66,7 @@ func NewWpViewporter(ctx *client.Context) *WpViewporter {
// protocol object anymore. This does not affect any other objects, // protocol object anymore. This does not affect any other objects,
// wp_viewport objects included. // wp_viewport objects included.
func (i *WpViewporter) Destroy() error { func (i *WpViewporter) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -267,7 +267,7 @@ func NewWpViewport(ctx *client.Context) *WpViewport {
// The associated wl_surface's crop and scale state is removed. // The associated wl_surface's crop and scale state is removed.
// The change is applied on the next wl_surface.commit. // The change is applied on the next wl_surface.commit.
func (i *WpViewport) Destroy() error { func (i *WpViewport) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte

View File

@@ -12,13 +12,44 @@ type Compositor int
const ( const (
CompositorUnknown Compositor = iota CompositorUnknown Compositor = iota
CompositorHyprland CompositorHyprland
CompositorSway
CompositorNiri
CompositorDWL
) )
var detectedCompositor Compositor = -1
func DetectCompositor() Compositor { func DetectCompositor() Compositor {
if os.Getenv("HYPRLAND_INSTANCE_SIGNATURE") != "" { if detectedCompositor >= 0 {
return CompositorHyprland return detectedCompositor
} }
return CompositorUnknown
hyprlandSig := os.Getenv("HYPRLAND_INSTANCE_SIGNATURE")
niriSocket := os.Getenv("NIRI_SOCKET")
swaySocket := os.Getenv("SWAYSOCK")
switch {
case niriSocket != "":
if _, err := os.Stat(niriSocket); err == nil {
detectedCompositor = CompositorNiri
return detectedCompositor
}
case swaySocket != "":
if _, err := os.Stat(swaySocket); err == nil {
detectedCompositor = CompositorSway
return detectedCompositor
}
case hyprlandSig != "":
detectedCompositor = CompositorHyprland
return detectedCompositor
}
detectedCompositor = CompositorUnknown
return detectedCompositor
}
func SetCompositorDWL() {
detectedCompositor = CompositorDWL
} }
type WindowGeometry struct { type WindowGeometry struct {
@@ -29,13 +60,11 @@ type WindowGeometry struct {
} }
func GetActiveWindow() (*WindowGeometry, error) { func GetActiveWindow() (*WindowGeometry, error) {
compositor := DetectCompositor() switch DetectCompositor() {
switch compositor {
case CompositorHyprland: case CompositorHyprland:
return getHyprlandActiveWindow() return getHyprlandActiveWindow()
default: default:
return nil, fmt.Errorf("window capture requires Hyprland (other compositors not yet supported)") return nil, fmt.Errorf("window capture requires Hyprland")
} }
} }
@@ -45,8 +74,7 @@ type hyprlandWindow struct {
} }
func getHyprlandActiveWindow() (*WindowGeometry, error) { func getHyprlandActiveWindow() (*WindowGeometry, error) {
cmd := exec.Command("hyprctl", "-j", "activewindow") output, err := exec.Command("hyprctl", "-j", "activewindow").Output()
output, err := cmd.Output()
if err != nil { if err != nil {
return nil, fmt.Errorf("hyprctl activewindow: %w", err) return nil, fmt.Errorf("hyprctl activewindow: %w", err)
} }
@@ -67,3 +95,144 @@ func getHyprlandActiveWindow() (*WindowGeometry, error) {
Height: win.Size[1], Height: win.Size[1],
}, nil }, nil
} }
type hyprlandMonitor struct {
Name string `json:"name"`
X int32 `json:"x"`
Y int32 `json:"y"`
Width int32 `json:"width"`
Height int32 `json:"height"`
Scale float64 `json:"scale"`
Focused bool `json:"focused"`
}
func GetHyprlandMonitorScale(name string) float64 {
output, err := exec.Command("hyprctl", "-j", "monitors").Output()
if err != nil {
return 0
}
var monitors []hyprlandMonitor
if err := json.Unmarshal(output, &monitors); err != nil {
return 0
}
for _, m := range monitors {
if m.Name == name {
return m.Scale
}
}
return 0
}
func getHyprlandFocusedMonitor() string {
output, err := exec.Command("hyprctl", "-j", "monitors").Output()
if err != nil {
return ""
}
var monitors []hyprlandMonitor
if err := json.Unmarshal(output, &monitors); err != nil {
return ""
}
for _, m := range monitors {
if m.Focused {
return m.Name
}
}
return ""
}
func GetHyprlandMonitorGeometry(name string) (x, y, w, h int32, ok bool) {
output, err := exec.Command("hyprctl", "-j", "monitors").Output()
if err != nil {
return 0, 0, 0, 0, false
}
var monitors []hyprlandMonitor
if err := json.Unmarshal(output, &monitors); err != nil {
return 0, 0, 0, 0, false
}
for _, m := range monitors {
if m.Name == name {
logicalW := int32(float64(m.Width) / m.Scale)
logicalH := int32(float64(m.Height) / m.Scale)
return m.X, m.Y, logicalW, logicalH, true
}
}
return 0, 0, 0, 0, false
}
type swayWorkspace struct {
Output string `json:"output"`
Focused bool `json:"focused"`
}
func getSwayFocusedMonitor() string {
output, err := exec.Command("swaymsg", "-t", "get_workspaces").Output()
if err != nil {
return ""
}
var workspaces []swayWorkspace
if err := json.Unmarshal(output, &workspaces); err != nil {
return ""
}
for _, ws := range workspaces {
if ws.Focused {
return ws.Output
}
}
return ""
}
type niriWorkspace struct {
Output string `json:"output"`
IsFocused bool `json:"is_focused"`
}
func getNiriFocusedMonitor() string {
output, err := exec.Command("niri", "msg", "-j", "workspaces").Output()
if err != nil {
return ""
}
var workspaces []niriWorkspace
if err := json.Unmarshal(output, &workspaces); err != nil {
return ""
}
for _, ws := range workspaces {
if ws.IsFocused {
return ws.Output
}
}
return ""
}
var dwlActiveOutput string
func SetDWLActiveOutput(name string) {
dwlActiveOutput = name
}
func getDWLFocusedMonitor() string {
return dwlActiveOutput
}
func GetFocusedMonitor() string {
switch DetectCompositor() {
case CompositorHyprland:
return getHyprlandFocusedMonitor()
case CompositorSway:
return getSwayFocusedMonitor()
case CompositorNiri:
return getNiriFocusedMonitor()
case CompositorDWL:
return getDWLFocusedMonitor()
}
return ""
}

View File

@@ -251,9 +251,10 @@ func (r *RegionSelector) handleGlobal(e client.RegistryGlobalEvent) {
if err := r.registry.Bind(e.Name, e.Interface, version, output); err == nil { if err := r.registry.Bind(e.Name, e.Interface, version, output); err == nil {
r.outputsMu.Lock() r.outputsMu.Lock()
r.outputs[e.Name] = &WaylandOutput{ r.outputs[e.Name] = &WaylandOutput{
wlOutput: output, wlOutput: output,
globalName: e.Name, globalName: e.Name,
scale: 1, scale: 1,
fractionalScale: 1.0,
} }
r.outputsMu.Unlock() r.outputsMu.Unlock()
r.setupOutputHandlers(e.Name, output) r.setupOutputHandlers(e.Name, output)
@@ -320,6 +321,7 @@ func (r *RegionSelector) setupOutputHandlers(name uint32, output *client.Output)
r.outputsMu.Lock() r.outputsMu.Lock()
if o, ok := r.outputs[name]; ok { if o, ok := r.outputs[name]; ok {
o.scale = e.Factor o.scale = e.Factor
o.fractionalScale = float64(e.Factor)
} }
r.outputsMu.Unlock() r.outputsMu.Unlock()
}) })
@@ -607,6 +609,10 @@ func (r *RegionSelector) captureForSurface(os *OutputSurface) {
os.screenFormat = pc.format os.screenFormat = pc.format
os.yInverted = pc.yInverted os.yInverted = pc.yInverted
if os.logicalW > 0 && os.screenBuf != nil {
os.output.fractionalScale = float64(os.screenBuf.Width) / float64(os.logicalW)
}
r.initRenderBuffer(os) r.initRenderBuffer(os)
r.applyPreSelection(os) r.applyPreSelection(os)
r.redrawSurface(os) r.redrawSurface(os)
@@ -713,19 +719,17 @@ func (r *RegionSelector) redrawSurface(os *OutputSurface) {
// Draw overlay (dimming + selection) into this slot // Draw overlay (dimming + selection) into this slot
r.drawOverlay(os, slot.shm) r.drawOverlay(os, slot.shm)
// Attach and commit (viewport only needs to be set once, but it's cheap)
scale := os.output.scale
if scale <= 0 {
scale = 1
}
if os.viewport != nil { if os.viewport != nil {
srcW := float64(slot.shm.Width) / float64(scale) _ = os.wlSurface.SetBufferScale(1)
srcH := float64(slot.shm.Height) / float64(scale) _ = os.viewport.SetSource(0, 0, float64(slot.shm.Width), float64(slot.shm.Height))
_ = os.viewport.SetSource(0, 0, srcW, srcH)
_ = os.viewport.SetDestination(int32(os.logicalW), int32(os.logicalH)) _ = os.viewport.SetDestination(int32(os.logicalW), int32(os.logicalH))
} else {
bufferScale := os.output.scale
if bufferScale <= 0 {
bufferScale = 1
}
_ = os.wlSurface.SetBufferScale(bufferScale)
} }
_ = os.wlSurface.SetBufferScale(scale)
_ = os.wlSurface.Attach(slot.wlBuf, 0, 0) _ = os.wlSurface.Attach(slot.wlBuf, 0, 0)
_ = os.wlSurface.Damage(0, 0, int32(os.logicalW), int32(os.logicalH)) _ = os.wlSurface.Damage(0, 0, int32(os.logicalW), int32(os.logicalH))

View File

@@ -223,16 +223,23 @@ func (r *RegionSelector) finishSelection() {
dstData := cropped.Data() dstData := cropped.Data()
for y := 0; y < h; y++ { for y := 0; y < h; y++ {
srcY := by1 + y srcY := by1 + y
if srcY >= srcBuf.Height { if os.yInverted {
break srcY = srcBuf.Height - 1 - (by1 + y)
}
if srcY < 0 || srcY >= srcBuf.Height {
continue
}
dstY := y
if os.yInverted {
dstY = h - 1 - y
} }
for x := 0; x < w; x++ { for x := 0; x < w; x++ {
srcX := bx1 + x srcX := bx1 + x
if srcX >= srcBuf.Width { if srcX < 0 || srcX >= srcBuf.Width {
break continue
} }
si := srcY*srcBuf.Stride + srcX*4 si := srcY*srcBuf.Stride + srcX*4
di := y*cropped.Stride + x*4 di := dstY*cropped.Stride + x*4
if si+3 < len(srcData) && di+3 < len(dstData) { if si+3 < len(srcData) && di+3 < len(dstData) {
dstData[di+0] = srcData[si+0] dstData[di+0] = srcData[si+0]
dstData[di+1] = srcData[si+1] dstData[di+1] = srcData[si+1]

View File

@@ -11,14 +11,15 @@ import (
) )
type WaylandOutput struct { type WaylandOutput struct {
wlOutput *client.Output wlOutput *client.Output
globalName uint32 globalName uint32
name string name string
x, y int32 x, y int32
width int32 width int32
height int32 height int32
scale int32 scale int32
transform int32 fractionalScale float64
transform int32
} }
type CaptureResult struct { type CaptureResult struct {
@@ -139,6 +140,10 @@ func (s *Screenshoter) captureWindow() (*CaptureResult, error) {
return nil, fmt.Errorf("could not find output for window") return nil, fmt.Errorf("could not find output for window")
} }
if DetectCompositor() == CompositorHyprland {
return s.captureAndCrop(output, region)
}
return s.captureRegionOnOutput(output, region) return s.captureRegionOnOutput(output, region)
} }
@@ -181,33 +186,8 @@ func (s *Screenshoter) captureOutput(name string) (*CaptureResult, error) {
func (s *Screenshoter) captureAllScreens() (*CaptureResult, error) { func (s *Screenshoter) captureAllScreens() (*CaptureResult, error) {
s.outputsMu.Lock() s.outputsMu.Lock()
outputs := make([]*WaylandOutput, 0, len(s.outputs)) outputs := make([]*WaylandOutput, 0, len(s.outputs))
var minX, minY, maxX, maxY int32
first := true
for _, o := range s.outputs { for _, o := range s.outputs {
outputs = append(outputs, o) outputs = append(outputs, o)
right := o.x + o.width
bottom := o.y + o.height
if first {
minX, minY = o.x, o.y
maxX, maxY = right, bottom
first = false
continue
}
if o.x < minX {
minX = o.x
}
if o.y < minY {
minY = o.y
}
if right > maxX {
maxX = right
}
if bottom > maxY {
maxY = bottom
}
} }
s.outputsMu.Unlock() s.outputsMu.Unlock()
@@ -219,18 +199,18 @@ func (s *Screenshoter) captureAllScreens() (*CaptureResult, error) {
return s.captureWholeOutput(outputs[0]) return s.captureWholeOutput(outputs[0])
} }
totalW := maxX - minX // Capture all outputs first to get actual buffer sizes
totalH := maxY - minY type capturedOutput struct {
output *WaylandOutput
compositeStride := int(totalW) * 4 result *CaptureResult
composite, err := CreateShmBuffer(int(totalW), int(totalH), compositeStride) physX int
if err != nil { physY int
return nil, fmt.Errorf("create composite buffer: %w", err)
} }
captured := make([]capturedOutput, 0, len(outputs))
composite.Clear() var minX, minY, maxX, maxY int
first := true
var format uint32
for _, output := range outputs { for _, output := range outputs {
result, err := s.captureWholeOutput(output) result, err := s.captureWholeOutput(output)
if err != nil { if err != nil {
@@ -238,16 +218,88 @@ func (s *Screenshoter) captureAllScreens() (*CaptureResult, error) {
continue continue
} }
if format == 0 { outX, outY := output.x, output.y
format = result.Format scale := float64(output.scale)
if DetectCompositor() == CompositorHyprland {
if hx, hy, _, _, ok := GetHyprlandMonitorGeometry(output.name); ok {
outX, outY = hx, hy
}
if s := GetHyprlandMonitorScale(output.name); s > 0 {
scale = s
}
} }
s.blitBuffer(composite, result.Buffer, int(output.x-minX), int(output.y-minY), result.YInverted) if scale <= 0 {
result.Buffer.Close() scale = 1.0
}
physX := int(float64(outX) * scale)
physY := int(float64(outY) * scale)
captured = append(captured, capturedOutput{
output: output,
result: result,
physX: physX,
physY: physY,
})
right := physX + result.Buffer.Width
bottom := physY + result.Buffer.Height
if first {
minX, minY = physX, physY
maxX, maxY = right, bottom
first = false
continue
}
if physX < minX {
minX = physX
}
if physY < minY {
minY = physY
}
if right > maxX {
maxX = right
}
if bottom > maxY {
maxY = bottom
}
}
if len(captured) == 0 {
return nil, fmt.Errorf("failed to capture any outputs")
}
if len(captured) == 1 {
return captured[0].result, nil
}
totalW := maxX - minX
totalH := maxY - minY
compositeStride := totalW * 4
composite, err := CreateShmBuffer(totalW, totalH, compositeStride)
if err != nil {
for _, c := range captured {
c.result.Buffer.Close()
}
return nil, fmt.Errorf("create composite buffer: %w", err)
}
composite.Clear()
var format uint32
for _, c := range captured {
if format == 0 {
format = c.result.Format
}
s.blitBuffer(composite, c.result.Buffer, c.physX-minX, c.physY-minY, c.result.YInverted)
c.result.Buffer.Close()
} }
return &CaptureResult{ return &CaptureResult{
Buffer: composite, Buffer: composite,
Region: Region{X: minX, Y: minY, Width: totalW, Height: totalH}, Region: Region{X: int32(minX), Y: int32(minY), Width: int32(totalW), Height: int32(totalH)},
Format: format, Format: format,
}, nil }, nil
} }
@@ -311,21 +363,106 @@ func (s *Screenshoter) captureWholeOutput(output *WaylandOutput) (*CaptureResult
}) })
} }
func (s *Screenshoter) captureAndCrop(output *WaylandOutput, region Region) (*CaptureResult, error) {
result, err := s.captureWholeOutput(output)
if err != nil {
return nil, err
}
outX, outY := output.x, output.y
scale := float64(output.scale)
if hx, hy, _, _, ok := GetHyprlandMonitorGeometry(output.name); ok {
outX, outY = hx, hy
}
if s := GetHyprlandMonitorScale(output.name); s > 0 {
scale = s
}
if scale <= 0 {
scale = 1.0
}
localX := int(float64(region.X-outX) * scale)
localY := int(float64(region.Y-outY) * scale)
w := int(float64(region.Width) * scale)
h := int(float64(region.Height) * scale)
cropped, err := CreateShmBuffer(w, h, w*4)
if err != nil {
result.Buffer.Close()
return nil, fmt.Errorf("create crop buffer: %w", err)
}
srcData := result.Buffer.Data()
dstData := cropped.Data()
for y := 0; y < h; y++ {
srcY := localY + y
if result.YInverted {
srcY = result.Buffer.Height - 1 - (localY + y)
}
if srcY < 0 || srcY >= result.Buffer.Height {
continue
}
dstY := y
if result.YInverted {
dstY = h - 1 - y
}
for x := 0; x < w; x++ {
srcX := localX + x
if srcX < 0 || srcX >= result.Buffer.Width {
continue
}
si := srcY*result.Buffer.Stride + srcX*4
di := dstY*cropped.Stride + x*4
if si+3 >= len(srcData) || di+3 >= len(dstData) {
continue
}
dstData[di+0] = srcData[si+0]
dstData[di+1] = srcData[si+1]
dstData[di+2] = srcData[si+2]
dstData[di+3] = srcData[si+3]
}
}
result.Buffer.Close()
cropped.Format = PixelFormat(result.Format)
return &CaptureResult{
Buffer: cropped,
Region: region,
YInverted: false,
Format: result.Format,
}, nil
}
func (s *Screenshoter) captureRegionOnOutput(output *WaylandOutput, region Region) (*CaptureResult, error) { func (s *Screenshoter) captureRegionOnOutput(output *WaylandOutput, region Region) (*CaptureResult, error) {
localX := region.X - output.x scale := output.fractionalScale
localY := region.Y - output.y if scale <= 0 && DetectCompositor() == CompositorHyprland {
scale = GetHyprlandMonitorScale(output.name)
}
if scale <= 0 {
scale = float64(output.scale)
}
if scale <= 0 {
scale = 1.0
}
localX := int32(float64(region.X-output.x) * scale)
localY := int32(float64(region.Y-output.y) * scale)
w := int32(float64(region.Width) * scale)
h := int32(float64(region.Height) * scale)
cursor := int32(0) cursor := int32(0)
if s.config.IncludeCursor { if s.config.IncludeCursor {
cursor = 1 cursor = 1
} }
frame, err := s.screencopy.CaptureOutputRegion( frame, err := s.screencopy.CaptureOutputRegion(cursor, output.wlOutput, localX, localY, w, h)
cursor,
output.wlOutput,
localX, localY,
region.Width, region.Height,
)
if err != nil { if err != nil {
return nil, fmt.Errorf("capture region: %w", err) return nil, fmt.Errorf("capture region: %w", err)
} }
@@ -335,6 +472,8 @@ func (s *Screenshoter) captureRegionOnOutput(output *WaylandOutput, region Regio
func (s *Screenshoter) processFrame(frame *wlr_screencopy.ZwlrScreencopyFrameV1, region Region) (*CaptureResult, error) { func (s *Screenshoter) processFrame(frame *wlr_screencopy.ZwlrScreencopyFrameV1, region Region) (*CaptureResult, error) {
var buf *ShmBuffer var buf *ShmBuffer
var pool *client.ShmPool
var wlBuf *client.Buffer
var format PixelFormat var format PixelFormat
var yInverted bool var yInverted bool
ready := false ready := false
@@ -360,15 +499,17 @@ func (s *Screenshoter) processFrame(frame *wlr_screencopy.ZwlrScreencopyFrameV1,
return return
} }
pool, err := s.shm.CreatePool(buf.Fd(), int32(buf.Size())) var err error
pool, err = s.shm.CreatePool(buf.Fd(), int32(buf.Size()))
if err != nil { if err != nil {
log.Error("failed to create pool", "err", err) log.Error("failed to create pool", "err", err)
return return
} }
wlBuf, err := pool.CreateBuffer(0, int32(buf.Width), int32(buf.Height), int32(buf.Stride), uint32(format)) wlBuf, err = pool.CreateBuffer(0, int32(buf.Width), int32(buf.Height), int32(buf.Stride), uint32(format))
if err != nil { if err != nil {
pool.Destroy() pool.Destroy()
pool = nil
log.Error("failed to create wl_buffer", "err", err) log.Error("failed to create wl_buffer", "err", err)
return return
} }
@@ -376,8 +517,6 @@ func (s *Screenshoter) processFrame(frame *wlr_screencopy.ZwlrScreencopyFrameV1,
if err := frame.Copy(wlBuf); err != nil { if err := frame.Copy(wlBuf); err != nil {
log.Error("failed to copy frame", "err", err) log.Error("failed to copy frame", "err", err)
} }
pool.Destroy()
}) })
frame.SetReadyHandler(func(e wlr_screencopy.ZwlrScreencopyFrameV1ReadyEvent) { frame.SetReadyHandler(func(e wlr_screencopy.ZwlrScreencopyFrameV1ReadyEvent) {
@@ -396,6 +535,12 @@ func (s *Screenshoter) processFrame(frame *wlr_screencopy.ZwlrScreencopyFrameV1,
} }
frame.Destroy() frame.Destroy()
if wlBuf != nil {
wlBuf.Destroy()
}
if pool != nil {
pool.Destroy()
}
if failed { if failed {
if buf != nil { if buf != nil {
@@ -420,14 +565,26 @@ func (s *Screenshoter) findOutputForRegion(region Region) *WaylandOutput {
cy := region.Y + region.Height/2 cy := region.Y + region.Height/2
for _, o := range s.outputs { for _, o := range s.outputs {
if cx >= o.x && cx < o.x+o.width && cy >= o.y && cy < o.y+o.height { x, y, w, h := o.x, o.y, o.width, o.height
if DetectCompositor() == CompositorHyprland {
if hx, hy, hw, hh, ok := GetHyprlandMonitorGeometry(o.name); ok {
x, y, w, h = hx, hy, hw, hh
}
}
if cx >= x && cx < x+w && cy >= y && cy < y+h {
return o return o
} }
} }
for _, o := range s.outputs { for _, o := range s.outputs {
if region.X >= o.x && region.X < o.x+o.width && x, y, w, h := o.x, o.y, o.width, o.height
region.Y >= o.y && region.Y < o.y+o.height { if DetectCompositor() == CompositorHyprland {
if hx, hy, hw, hh, ok := GetHyprlandMonitorGeometry(o.name); ok {
x, y, w, h = hx, hy, hw, hh
}
}
if region.X >= x && region.X < x+w &&
region.Y >= y && region.Y < y+h {
return o return o
} }
} }
@@ -436,6 +593,15 @@ func (s *Screenshoter) findOutputForRegion(region Region) *WaylandOutput {
} }
func (s *Screenshoter) findFocusedOutput() *WaylandOutput { func (s *Screenshoter) findFocusedOutput() *WaylandOutput {
if mon := GetFocusedMonitor(); mon != "" {
s.outputsMu.Lock()
defer s.outputsMu.Unlock()
for _, o := range s.outputs {
if o.name == mon {
return o
}
}
}
s.outputsMu.Lock() s.outputsMu.Lock()
defer s.outputsMu.Unlock() defer s.outputsMu.Unlock()
for _, o := range s.outputs { for _, o := range s.outputs {
@@ -501,9 +667,10 @@ func (s *Screenshoter) handleGlobal(e client.RegistryGlobalEvent) {
if err := s.registry.Bind(e.Name, e.Interface, version, output); err == nil { if err := s.registry.Bind(e.Name, e.Interface, version, output); err == nil {
s.outputsMu.Lock() s.outputsMu.Lock()
s.outputs[e.Name] = &WaylandOutput{ s.outputs[e.Name] = &WaylandOutput{
wlOutput: output, wlOutput: output,
globalName: e.Name, globalName: e.Name,
scale: 1, scale: 1,
fractionalScale: 1.0,
} }
s.outputsMu.Unlock() s.outputsMu.Unlock()
s.setupOutputHandlers(e.Name, output) s.setupOutputHandlers(e.Name, output)
@@ -546,6 +713,7 @@ func (s *Screenshoter) setupOutputHandlers(name uint32, output *client.Output) {
s.outputsMu.Lock() s.outputsMu.Lock()
if o, ok := s.outputs[name]; ok { if o, ok := s.outputs[name]; ok {
o.scale = e.Factor o.scale = e.Factor
o.fractionalScale = float64(e.Factor)
} }
s.outputsMu.Unlock() s.outputsMu.Unlock()
}) })

View File

@@ -113,7 +113,7 @@ func (i *Display) GetRegistry() (*Registry, error) {
} }
func (i *Display) Destroy() error { func (i *Display) Destroy() error {
i.Context().Unregister(i) i.MarkZombie()
return nil return nil
} }
@@ -224,15 +224,16 @@ func (i *Display) Dispatch(opcode uint32, fd int, data []byte) {
i.errorHandler(e) i.errorHandler(e)
case 1: case 1:
if i.deleteIdHandler == nil {
return
}
var e DisplayDeleteIdEvent var e DisplayDeleteIdEvent
l := 0 l := 0
e.Id = Uint32(data[l : l+4]) e.Id = Uint32(data[l : l+4])
l += 4 l += 4
i.deleteIdHandler(e) i.Context().DeleteID(e.Id)
if i.deleteIdHandler != nil {
i.deleteIdHandler(e)
}
} }
} }
@@ -326,7 +327,7 @@ func (i *Registry) Bind(name uint32, iface string, version uint32, id Proxy) err
} }
func (i *Registry) Destroy() error { func (i *Registry) Destroy() error {
i.Context().Unregister(i) i.MarkZombie()
return nil return nil
} }
@@ -433,7 +434,7 @@ func NewCallback(ctx *Context) *Callback {
} }
func (i *Callback) Destroy() error { func (i *Callback) Destroy() error {
i.Context().Unregister(i) i.MarkZombie()
return nil return nil
} }
@@ -529,7 +530,7 @@ func (i *Compositor) CreateRegion() (*Region, error) {
} }
func (i *Compositor) Destroy() error { func (i *Compositor) Destroy() error {
i.Context().Unregister(i) i.MarkZombie()
return nil return nil
} }
@@ -619,7 +620,7 @@ func (i *ShmPool) CreateBuffer(offset, width, height, stride int32, format uint3
// buffers that have been created from this pool // buffers that have been created from this pool
// are gone. // are gone.
func (i *ShmPool) Destroy() error { func (i *ShmPool) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 1 const opcode = 1
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -735,7 +736,7 @@ func (i *Shm) CreatePool(fd int, size int32) (*ShmPool, error) {
// //
// Objects created via this interface remain unaffected. // Objects created via this interface remain unaffected.
func (i *Shm) Release() error { func (i *Shm) Release() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 1 const opcode = 1
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -1642,7 +1643,7 @@ func NewBuffer(ctx *Context) *Buffer {
// //
// For possible side-effects to a surface, see wl_surface.attach. // For possible side-effects to a surface, see wl_surface.attach.
func (i *Buffer) Destroy() error { func (i *Buffer) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -1803,7 +1804,7 @@ func (i *DataOffer) Receive(mimeType string, fd int) error {
// //
// Destroy the data offer. // Destroy the data offer.
func (i *DataOffer) Destroy() error { func (i *DataOffer) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 2 const opcode = 2
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -2120,7 +2121,7 @@ func (i *DataSource) Offer(mimeType string) error {
// //
// Destroy the data source. // Destroy the data source.
func (i *DataSource) Destroy() error { func (i *DataSource) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 1 const opcode = 1
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -2540,7 +2541,7 @@ func (i *DataDevice) SetSelection(source *DataSource, serial uint32) error {
// //
// This request destroys the data device. // This request destroys the data device.
func (i *DataDevice) Release() error { func (i *DataDevice) Release() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 2 const opcode = 2
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -2859,7 +2860,7 @@ func (i *DataDeviceManager) GetDataDevice(seat *Seat) (*DataDevice, error) {
} }
func (i *DataDeviceManager) Destroy() error { func (i *DataDeviceManager) Destroy() error {
i.Context().Unregister(i) i.MarkZombie()
return nil return nil
} }
@@ -3000,7 +3001,7 @@ func (i *Shell) GetShellSurface(surface *Surface) (*ShellSurface, error) {
} }
func (i *Shell) Destroy() error { func (i *Shell) Destroy() error {
i.Context().Unregister(i) i.MarkZombie()
return nil return nil
} }
@@ -3421,7 +3422,7 @@ func (i *ShellSurface) SetClass(class string) error {
} }
func (i *ShellSurface) Destroy() error { func (i *ShellSurface) Destroy() error {
i.Context().Unregister(i) i.MarkZombie()
return nil return nil
} }
@@ -3798,7 +3799,7 @@ func NewSurface(ctx *Context) *Surface {
// //
// Deletes the surface and invalidates its object ID. // Deletes the surface and invalidates its object ID.
func (i *Surface) Destroy() error { func (i *Surface) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -4618,7 +4619,7 @@ func (i *Seat) GetTouch() (*Touch, error) {
// Using this request a client can tell the server that it is not going to // Using this request a client can tell the server that it is not going to
// use the seat object anymore. // use the seat object anymore.
func (i *Seat) Release() error { func (i *Seat) Release() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 3 const opcode = 3
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -4920,7 +4921,7 @@ func (i *Pointer) SetCursor(serial uint32, surface *Surface, hotspotX, hotspotY
// This request destroys the pointer proxy object, so clients must not call // This request destroys the pointer proxy object, so clients must not call
// wl_pointer_destroy() after using this request. // wl_pointer_destroy() after using this request.
func (i *Pointer) Release() error { func (i *Pointer) Release() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 1 const opcode = 1
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -5685,7 +5686,7 @@ func NewKeyboard(ctx *Context) *Keyboard {
// Release : release the keyboard object // Release : release the keyboard object
func (i *Keyboard) Release() error { func (i *Keyboard) Release() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -6091,7 +6092,7 @@ func NewTouch(ctx *Context) *Touch {
// Release : release the touch object // Release : release the touch object
func (i *Touch) Release() error { func (i *Touch) Release() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -6406,7 +6407,7 @@ func NewOutput(ctx *Context) *Output {
// Using this request a client can tell the server that it is not going to // Using this request a client can tell the server that it is not going to
// use the output object anymore. // use the output object anymore.
func (i *Output) Release() error { func (i *Output) Release() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -6923,7 +6924,7 @@ func NewRegion(ctx *Context) *Region {
// //
// Destroy the region. This will invalidate the object ID. // Destroy the region. This will invalidate the object ID.
func (i *Region) Destroy() error { func (i *Region) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -7057,7 +7058,7 @@ func NewSubcompositor(ctx *Context) *Subcompositor {
// protocol object anymore. This does not affect any other // protocol object anymore. This does not affect any other
// objects, wl_subsurface objects included. // objects, wl_subsurface objects included.
func (i *Subcompositor) Destroy() error { func (i *Subcompositor) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -7280,7 +7281,7 @@ func NewSubsurface(ctx *Context) *Subsurface {
// wl_subcompositor.get_subsurface request. The wl_surface's association // wl_subcompositor.get_subsurface request. The wl_surface's association
// to the parent is deleted. The wl_surface is unmapped immediately. // to the parent is deleted. The wl_surface is unmapped immediately.
func (i *Subsurface) Destroy() error { func (i *Subsurface) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte
@@ -7499,7 +7500,7 @@ func NewFixes(ctx *Context) *Fixes {
// Destroy : destroys this object // Destroy : destroys this object
func (i *Fixes) Destroy() error { func (i *Fixes) Destroy() error {
defer i.Context().Unregister(i) defer i.MarkZombie()
const opcode = 0 const opcode = 0
const _reqBufLen = 8 const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte var _reqBuf [_reqBufLen]byte

View File

@@ -1,5 +1,7 @@
package client package client
import "sync/atomic"
type Dispatcher interface { type Dispatcher interface {
Dispatch(opcode uint32, fd int, data []byte) Dispatch(opcode uint32, fd int, data []byte)
} }
@@ -9,11 +11,14 @@ type Proxy interface {
SetContext(ctx *Context) SetContext(ctx *Context)
ID() uint32 ID() uint32
SetID(id uint32) SetID(id uint32)
IsZombie() bool
MarkZombie()
} }
type BaseProxy struct { type BaseProxy struct {
ctx *Context ctx *Context
id uint32 id uint32
zombie atomic.Bool
} }
func (p *BaseProxy) ID() uint32 { func (p *BaseProxy) ID() uint32 {
@@ -31,3 +36,11 @@ func (p *BaseProxy) Context() *Context {
func (p *BaseProxy) SetContext(ctx *Context) { func (p *BaseProxy) SetContext(ctx *Context) {
p.ctx = ctx p.ctx = ctx
} }
func (p *BaseProxy) IsZombie() bool {
return p.zombie.Load()
}
func (p *BaseProxy) MarkZombie() {
p.zombie.Store(true)
}

View File

@@ -32,6 +32,10 @@ func (ctx *Context) Unregister(p Proxy) {
ctx.objects.Delete(p.ID()) ctx.objects.Delete(p.ID())
} }
func (ctx *Context) DeleteID(id uint32) {
ctx.objects.Delete(id)
}
func (ctx *Context) GetProxy(id uint32) Proxy { func (ctx *Context) GetProxy(id uint32) Proxy {
if val, ok := ctx.objects.Load(id); ok { if val, ok := ctx.objects.Load(id); ok {
return val return val
@@ -72,7 +76,11 @@ func (ctx *Context) GetDispatch() func() error {
return func() error { return func() error {
proxy, ok := ctx.objects.Load(senderID) proxy, ok := ctx.objects.Load(senderID)
if !ok { if !ok {
return fmt.Errorf("%w (senderID=%d)", ErrDispatchSenderNotFound, senderID) return nil // Proxy already deleted via delete_id, silently ignore
}
if proxy.IsZombie() {
return nil // Zombie proxy, discard late events
} }
sender, ok := proxy.(Dispatcher) sender, ok := proxy.(Dispatcher)

View File

@@ -541,6 +541,34 @@ Item {
} }
} }
function getWorkspaceIndex(modelData) {
let isPlaceholder;
if (root.useExtWorkspace) {
isPlaceholder = modelData?.hidden === true;
} else if (CompositorService.isHyprland) {
isPlaceholder = modelData?.id === -1;
} else if (CompositorService.isDwl) {
isPlaceholder = modelData?.tag === -1;
} else if (CompositorService.isSway) {
isPlaceholder = modelData?.num === -1;
} else {
isPlaceholder = modelData === -1;
}
if (isPlaceholder)
return index + 1;
if (root.useExtWorkspace)
return index + 1;
if (CompositorService.isHyprland)
return modelData?.id || "";
if (CompositorService.isDwl)
return (modelData?.tag !== undefined) ? (modelData.tag + 1) : "";
if (CompositorService.isSway)
return modelData?.num || "";
return modelData - 1;
}
readonly property bool hasNativeWorkspaceSupport: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway readonly property bool hasNativeWorkspaceSupport: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway
readonly property bool hasWorkspaces: getRealWorkspaces().length > 0 readonly property bool hasWorkspaces: getRealWorkspaces().length > 0
readonly property bool shouldShow: hasNativeWorkspaceSupport || (useExtWorkspace && hasWorkspaces) readonly property bool shouldShow: hasNativeWorkspaceSupport || (useExtWorkspace && hasWorkspaces)
@@ -862,7 +890,18 @@ Item {
id: rowLayout id: rowLayout
Row { Row {
spacing: 4 spacing: 4
visible: loadedIcons.length > 0 visible: loadedIcons.length > 0 || SettingsData.showWorkspaceIndex
StyledText {
topPadding: 2
rightPadding: isActive ? 4 : 0
visible: SettingsData.showWorkspaceIndex
text: {
return root.getWorkspaceIndex(modelData);
}
color: (isActive || isUrgent) ? Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95) : isPlaceholder ? Theme.surfaceTextAlpha : Theme.surfaceTextMedium
font.pixelSize: Theme.barTextSize(barThickness, barConfig?.fontScale)
font.weight: (isActive && !isPlaceholder) ? Font.DemiBold : Font.Normal
}
Repeater { Repeater {
model: ScriptModel { model: ScriptModel {
@@ -1045,31 +1084,7 @@ Item {
StyledText { StyledText {
anchors.centerIn: parent anchors.centerIn: parent
text: { text: {
let isPlaceholder; return root.getWorkspaceIndex(modelData);
if (root.useExtWorkspace) {
isPlaceholder = modelData?.hidden === true;
} else if (CompositorService.isHyprland) {
isPlaceholder = modelData?.id === -1;
} else if (CompositorService.isDwl) {
isPlaceholder = modelData?.tag === -1;
} else if (CompositorService.isSway) {
isPlaceholder = modelData?.num === -1;
} else {
isPlaceholder = modelData === -1;
}
if (isPlaceholder)
return index + 1;
if (root.useExtWorkspace)
return index + 1;
if (CompositorService.isHyprland)
return modelData?.id || "";
if (CompositorService.isDwl)
return (modelData?.tag !== undefined) ? (modelData.tag + 1) : "";
if (CompositorService.isSway)
return modelData?.num || "";
return modelData - 1;
} }
color: (isActive || isUrgent) ? Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95) : isPlaceholder ? Theme.surfaceTextAlpha : Theme.surfaceTextMedium color: (isActive || isUrgent) ? Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95) : isPlaceholder ? Theme.surfaceTextAlpha : Theme.surfaceTextMedium
font.pixelSize: Theme.barTextSize(barThickness, barConfig?.fontScale) font.pixelSize: Theme.barTextSize(barThickness, barConfig?.fontScale)

View File

@@ -51,17 +51,9 @@ Item {
readonly property bool usePlayerVolume: activePlayer && activePlayer.volumeSupported && !__isChromeBrowser readonly property bool usePlayerVolume: activePlayer && activePlayer.volumeSupported && !__isChromeBrowser
readonly property real currentVolume: usePlayerVolume ? activePlayer.volume : (AudioService.sink?.audio?.volume ?? 0) readonly property real currentVolume: usePlayerVolume ? activePlayer.volume : (AudioService.sink?.audio?.volume ?? 0)
// Palette that stays stable across track switches until new colors are ready
property color dom: Qt.rgba(Theme.surface.r, Theme.surface.g, Theme.surface.b, 1.0)
property color acc: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.25)
property color _nextDom: dom
property color _nextAcc: acc
// Track-switch hold (prevents banner flicker only during switches)
property bool isSwitching: false property bool isSwitching: false
property bool paletteReady: false
property string _lastArtUrl: "" property string _lastArtUrl: ""
property url _cqSource: "" property string _bgArtSource: ""
// Derived "no players" state: always correct, no timers. // Derived "no players" state: always correct, no timers.
readonly property int _playerCount: allPlayers ? allPlayers.length : 0 readonly property int _playerCount: allPlayers ? allPlayers.length : 0
@@ -69,7 +61,6 @@ Item {
readonly property bool _trulyIdle: activePlayer && activePlayer.playbackState === MprisPlaybackState.Stopped && !activePlayer.trackTitle && !activePlayer.trackArtist readonly property bool _trulyIdle: activePlayer && activePlayer.playbackState === MprisPlaybackState.Stopped && !activePlayer.trackTitle && !activePlayer.trackArtist
readonly property bool showNoPlayerNow: (!_switchHold) && (_noneAvailable || _trulyIdle) readonly property bool showNoPlayerNow: (!_switchHold) && (_noneAvailable || _trulyIdle)
// Short hold only during track switches (not when players disappear)
property bool _switchHold: false property bool _switchHold: false
Timer { Timer {
id: _switchHoldTimer id: _switchHoldTimer
@@ -86,11 +77,9 @@ Item {
} }
isSwitching = true; isSwitching = true;
_switchHold = true; _switchHold = true;
paletteReady = false;
_switchHoldTimer.restart(); _switchHoldTimer.restart();
if (activePlayer.trackArtUrl) { if (activePlayer.trackArtUrl)
loadArtwork(activePlayer.trackArtUrl); loadArtwork(activePlayer.trackArtUrl);
}
} }
property string activeTrackArtFile: "" property string activeTrackArtFile: ""
@@ -108,13 +97,13 @@ Item {
imageDownloader.command = ["curl", "-L", "-s", "--user-agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36", "-o", filename, url]; imageDownloader.command = ["curl", "-L", "-s", "--user-agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36", "-o", filename, url];
imageDownloader.targetFile = filename; imageDownloader.targetFile = filename;
imageDownloader.running = true; imageDownloader.running = true;
} else { return;
_preloadImage.source = url;
} }
_bgArtSource = url;
} }
function maybeFinishSwitch() { function maybeFinishSwitch() {
if (activePlayer && activePlayer.trackTitle !== "" && paletteReady) { if (activePlayer && activePlayer.trackTitle !== "") {
isSwitching = false; isSwitching = false;
_switchHold = false; _switchHold = false;
} }
@@ -219,9 +208,8 @@ Item {
property string targetFile: "" property string targetFile: ""
onExited: exitCode => { onExited: exitCode => {
if (exitCode === 0 && targetFile) { if (exitCode === 0 && targetFile)
_preloadImage.source = "file://" + targetFile; _bgArtSource = "file://" + targetFile;
}
} }
} }
@@ -230,121 +218,70 @@ Item {
running: false running: false
} }
Image {
id: _preloadImage
source: ""
asynchronous: true
cache: true
visible: false
onStatusChanged: {
if (status === Image.Ready) {
_cqSource = source;
colorQuantizer.source = _cqSource;
} else if (status === Image.Error) {
_cqSource = "";
}
}
}
ColorQuantizer {
id: colorQuantizer
source: _cqSource !== "" ? _cqSource : undefined
depth: 8
rescaleSize: 32
onColorsChanged: {
if (!colors || colors.length === 0)
return;
function enhanceColor(color) {
const satBoost = 1.4;
const valueBoost = 1.2;
return Qt.hsva(color.hsvHue, Math.min(1, color.hsvSaturation * satBoost), Math.min(1, color.hsvValue * valueBoost), color.a);
}
function getExtremeColor(startIdx, direction = 1) {
let bestColor = colors[startIdx];
let bestScore = 0;
for (let i = startIdx; i >= 0 && i < colors.length; i += direction) {
const c = colors[i];
const saturation = c.hsvSaturation;
const brightness = c.hsvValue;
const contrast = Math.abs(brightness - 0.5) * 2;
const score = saturation * 0.7 + contrast * 0.3;
if (score > bestScore) {
bestScore = score;
bestColor = c;
}
}
return enhanceColor(bestColor);
}
_pendingDom = getExtremeColor(Math.floor(colors.length * 0.2), 1);
_pendingAcc = getExtremeColor(Math.floor(colors.length * 0.8), -1);
paletteApplyDelay.restart();
}
}
property color _pendingDom: dom
property color _pendingAcc: acc
Timer {
id: paletteApplyDelay
interval: 90
repeat: false
onTriggered: {
const dist = (c1, c2) => {
const dr = c1.r - c2.r, dg = c1.g - c2.g, db = c1.b - c2.b;
return Math.sqrt(dr * dr + dg * dg + db * db);
};
const domChanged = dist(_pendingDom, dom) > 0.02;
const accChanged = dist(_pendingAcc, acc) > 0.02;
if (domChanged || accChanged) {
dom = _pendingDom;
acc = _pendingAcc;
}
paletteReady = true;
maybeFinishSwitch();
}
}
property bool isSeeking: false property bool isSeeking: false
Rectangle { Item {
id: bgContainer
anchors.fill: parent anchors.fill: parent
radius: Theme.cornerRadius visible: _bgArtSource !== ""
opacity: 1.0
gradient: Gradient {
GradientStop {
position: 0.0
color: Qt.rgba(dom.r, dom.g, dom.b, paletteReady ? 0.38 : 0.06)
}
GradientStop {
position: 0.3
color: Qt.rgba(acc.r, acc.g, acc.b, paletteReady ? 0.28 : 0.05)
}
GradientStop {
position: 1.0
color: Qt.rgba(Theme.surface.r, Theme.surface.g, Theme.surface.b, paletteReady ? 0.92 : 0.985)
}
}
Behavior on opacity {
NumberAnimation {
duration: 160
}
}
}
Behavior on dom { Image {
ColorAnimation { id: bgImage
duration: 220 anchors.centerIn: parent
easing.type: Easing.InOutQuad width: Math.max(parent.width, parent.height) * 1.1
height: width
source: _bgArtSource
fillMode: Image.PreserveAspectCrop
asynchronous: true
cache: true
visible: false
onStatusChanged: {
if (status === Image.Ready)
maybeFinishSwitch();
}
} }
}
Behavior on acc { Item {
ColorAnimation { id: blurredBg
duration: 220 anchors.fill: parent
easing.type: Easing.InOutQuad visible: false
MultiEffect {
anchors.centerIn: parent
width: bgImage.width
height: bgImage.height
source: bgImage
blurEnabled: true
blurMax: 64
blur: 0.8
saturation: -0.2
brightness: -0.25
}
}
Rectangle {
id: bgMask
anchors.fill: parent
radius: Theme.cornerRadius
visible: false
layer.enabled: true
}
MultiEffect {
anchors.fill: parent
source: blurredBg
maskEnabled: true
maskSource: bgMask
maskThresholdMin: 0.5
maskSpreadAtMin: 1.0
opacity: 0.7
}
Rectangle {
anchors.fill: parent
radius: Theme.cornerRadius
color: Theme.surface
opacity: 0.3
} }
} }

View File

@@ -1086,14 +1086,33 @@ Item {
Row { Row {
spacing: Theme.spacingM spacing: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
visible: NetworkService.networkStatus !== "disconnected" || (BluetoothService.available && BluetoothService.enabled) || (AudioService.sink && AudioService.sink.audio) visible: NetworkService.networkAvailable || (BluetoothService.available && BluetoothService.enabled) || (AudioService.sink && AudioService.sink.audio)
DankIcon { DankIcon {
name: NetworkService.networkStatus === "ethernet" ? "lan" : NetworkService.wifiSignalIcon name: {
if (NetworkService.wifiToggling)
return "sync";
switch (NetworkService.networkStatus) {
case "ethernet":
return "lan";
case "vpn":
return NetworkService.ethernetConnected ? "lan" : NetworkService.wifiSignalIcon;
default:
return NetworkService.wifiSignalIcon;
}
}
size: Theme.iconSize - 2 size: Theme.iconSize - 2
color: NetworkService.networkStatus !== "disconnected" ? "white" : Qt.rgba(255, 255, 255, 0.5) color: NetworkService.networkStatus !== "disconnected" ? "white" : Qt.rgba(255, 255, 255, 0.5)
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
visible: NetworkService.networkStatus !== "disconnected" visible: NetworkService.networkAvailable
}
DankIcon {
name: "vpn_lock"
size: Theme.iconSize - 2
color: NetworkService.vpnConnected ? Theme.primary : Qt.rgba(255, 255, 255, 0.5)
anchors.verticalCenter: parent.verticalCenter
visible: NetworkService.vpnAvailable && NetworkService.vpnConnected
} }
DankIcon { DankIcon {

View File

@@ -199,8 +199,8 @@ Item {
DankDropdown { DankDropdown {
width: parent.width - parent.leftPadding - parent.rightPadding width: parent.width - parent.leftPadding - parent.rightPadding
text: I18n.tr("Night Temperature") text: SessionData.nightModeAutoEnabled ? I18n.tr("Night Temperature") : I18n.tr("Color Temperature")
description: I18n.tr("Color temperature for night mode") description: SessionData.nightModeAutoEnabled ? I18n.tr("Color temperature for night mode") : I18n.tr("Warm color temperature to apply")
currentValue: SessionData.nightModeTemperature + "K" currentValue: SessionData.nightModeTemperature + "K"
options: { options: {
var temps = []; var temps = [];
@@ -223,6 +223,7 @@ Item {
text: I18n.tr("Day Temperature") text: I18n.tr("Day Temperature")
description: I18n.tr("Color temperature for day time") description: I18n.tr("Color temperature for day time")
currentValue: SessionData.nightModeHighTemperature + "K" currentValue: SessionData.nightModeHighTemperature + "K"
visible: SessionData.nightModeAutoEnabled
options: { options: {
var temps = []; var temps = [];
var minTemp = SessionData.nightModeTemperature; var minTemp = SessionData.nightModeTemperature;

View File

@@ -506,7 +506,7 @@ Singleton {
DMSService.sendRequest("wayland.gamma.setTemperature", { DMSService.sendRequest("wayland.gamma.setTemperature", {
"low": temperature, "low": temperature,
"high": 6500 "high": temperature
}, response => { }, response => {
if (response.error) { if (response.error) {
console.error("DisplayService: Failed to set temperature:", response.error); console.error("DisplayService: Failed to set temperature:", response.error);

View File

@@ -17,12 +17,19 @@ Item {
property color playheadColor: Theme.primary property color playheadColor: Theme.primary
property real dpr: (root.window ? root.window.devicePixelRatio : 1) property real dpr: (root.window ? root.window.devicePixelRatio : 1)
function snap(v) { return Math.round(v * dpr) / dpr } function snap(v) {
return Math.round(v * dpr) / dpr;
}
readonly property real playX: snap(root.width * root.value) readonly property real playX: snap(root.width * root.value)
readonly property real midY: snap(height / 2) readonly property real midY: snap(height / 2)
Behavior on currentAmp { NumberAnimation { duration: 300; easing.type: Easing.OutCubic } } Behavior on currentAmp {
NumberAnimation {
duration: 300
easing.type: Easing.OutCubic
}
}
onIsPlayingChanged: currentAmp = isPlaying ? amp : 0 onIsPlayingChanged: currentAmp = isPlaying ? amp : 0
Shape { Shape {
@@ -38,8 +45,16 @@ Item {
capStyle: ShapePath.RoundCap capStyle: ShapePath.RoundCap
joinStyle: ShapePath.RoundJoin joinStyle: ShapePath.RoundJoin
fillColor: "transparent" fillColor: "transparent"
PathMove { id: flatStart; x: 0; y: root.midY } PathMove {
PathLine { id: flatEnd; x: root.width; y: root.midY } id: flatStart
x: Math.min(root.width, snap(root.playX + playhead.width / 2))
y: root.midY
}
PathLine {
id: flatEnd
x: root.width
y: root.midY
}
} }
} }
@@ -48,7 +63,7 @@ Item {
anchors.fill: parent anchors.fill: parent
clip: true clip: true
readonly property real startX: snap(root.lineWidth/2) readonly property real startX: snap(root.lineWidth / 2)
readonly property real aaBias: (0.25 / root.dpr) readonly property real aaBias: (0.25 / root.dpr)
readonly property real endX: Math.max(startX, Math.min(root.playX - startX - aaBias, width)) readonly property real endX: Math.max(startX, Math.min(root.playX - startX - aaBias, width))
@@ -77,7 +92,10 @@ Item {
capStyle: ShapePath.RoundCap capStyle: ShapePath.RoundCap
joinStyle: ShapePath.RoundJoin joinStyle: ShapePath.RoundJoin
fillColor: "transparent" fillColor: "transparent"
PathSvg { id: waveSvg; path: "" } PathSvg {
id: waveSvg
path: ""
}
} }
} }
} }
@@ -88,8 +106,8 @@ Item {
height: snap(root.lineWidth) height: snap(root.lineWidth)
radius: width / 2 radius: width / 2
color: root.fillColor color: root.fillColor
x: waveClip.startX - width/2 x: waveClip.startX - width / 2
y: root.midY - height/2 + root.currentAmp * Math.sin((waveClip.startX / root.wavelength) * 2 * Math.PI + root.phase) y: root.midY - height / 2 + root.currentAmp * Math.sin((waveClip.startX / root.wavelength) * 2 * Math.PI + root.phase)
visible: waveClip.endX > waveClip.startX visible: waveClip.endX > waveClip.startX
z: 2 z: 2
} }
@@ -100,8 +118,8 @@ Item {
height: snap(root.lineWidth) height: snap(root.lineWidth)
radius: width / 2 radius: width / 2
color: root.fillColor color: root.fillColor
x: waveClip.endX - width/2 x: waveClip.endX - width / 2
y: root.midY - height/2 + root.currentAmp * Math.sin((waveClip.endX / root.wavelength) * 2 * Math.PI + root.phase) y: root.midY - height / 2 + root.currentAmp * Math.sin((waveClip.endX / root.wavelength) * 2 * Math.PI + root.phase)
visible: waveClip.endX > waveClip.startX visible: waveClip.endX > waveClip.startX
z: 2 z: 2
} }
@@ -119,48 +137,68 @@ Item {
} }
property real k: (2 * Math.PI) / Math.max(1e-6, wavelength) property real k: (2 * Math.PI) / Math.max(1e-6, wavelength)
function wrapMod(a, m) { let r = a % m; return r < 0 ? r + m : r } function wrapMod(a, m) {
let r = a % m;
return r < 0 ? r + m : r;
}
readonly property real waveOffsetX: -wrapMod(phase / k, wavelength) readonly property real waveOffsetX: -wrapMod(phase / k, wavelength)
FrameAnimation { FrameAnimation {
running: root.visible && (root.isPlaying || root.currentAmp > 0) running: root.visible && (root.isPlaying || root.currentAmp > 0)
onTriggered: { onTriggered: {
if (root.isPlaying) root.phase += 0.03 * frameTime * 60 if (root.isPlaying)
startCap.y = root.midY - startCap.height/2 + root.currentAmp * Math.sin((waveClip.startX / root.wavelength) * 2 * Math.PI + root.phase) root.phase += 0.03 * frameTime * 60;
endCap.y = root.midY - endCap.height/2 + root.currentAmp * Math.sin((waveClip.endX / root.wavelength) * 2 * Math.PI + root.phase) startCap.y = root.midY - startCap.height / 2 + root.currentAmp * Math.sin((waveClip.startX / root.wavelength) * 2 * Math.PI + root.phase);
endCap.y = root.midY - endCap.height / 2 + root.currentAmp * Math.sin((waveClip.endX / root.wavelength) * 2 * Math.PI + root.phase);
} }
} }
function buildStaticWave() { function buildStaticWave() {
const start = waveClip.startX - 2 * root.wavelength const start = waveClip.startX - 2 * root.wavelength;
const end = width + 2 * root.wavelength const end = width + 2 * root.wavelength;
if (end <= start) { waveSvg.path = ""; return } if (end <= start) {
waveSvg.path = "";
const kLocal = k return;
const halfPeriod = root.wavelength / 2
function y0(x) { return root.midY + root.currentAmp * Math.sin(kLocal * x) }
function dy0(x) { return root.currentAmp * Math.cos(kLocal * x) * kLocal }
let x0 = start
let d = `M ${x0} ${y0(x0)}`
while (x0 < end) {
const x1 = Math.min(x0 + halfPeriod, end)
const dx = x1 - x0
const yA = y0(x0), yB = y0(x1)
const dyA = dy0(x0), dyB = dy0(x1)
const c1x = x0 + dx/3
const c1y = yA + (dyA * dx)/3
const c2x = x1 - dx/3
const c2y = yB - (dyB * dx)/3
d += ` C ${c1x} ${c1y} ${c2x} ${c2y} ${x1} ${yB}`
x0 = x1
} }
waveSvg.path = d
const kLocal = k;
const halfPeriod = root.wavelength / 2;
function y0(x) {
return root.midY + root.currentAmp * Math.sin(kLocal * x);
}
function dy0(x) {
return root.currentAmp * Math.cos(kLocal * x) * kLocal;
}
let x0 = start;
let d = `M ${x0} ${y0(x0)}`;
while (x0 < end) {
const x1 = Math.min(x0 + halfPeriod, end);
const dx = x1 - x0;
const yA = y0(x0), yB = y0(x1);
const dyA = dy0(x0), dyB = dy0(x1);
const c1x = x0 + dx / 3;
const c1y = yA + (dyA * dx) / 3;
const c2x = x1 - dx / 3;
const c2y = yB - (dyB * dx) / 3;
d += ` C ${c1x} ${c1y} ${c2x} ${c2y} ${x1} ${yB}`;
x0 = x1;
}
waveSvg.path = d;
} }
Component.onCompleted: { currentAmp = isPlaying ? amp : 0; buildStaticWave() } Component.onCompleted: {
onWidthChanged: { flatStart.x = 0; flatEnd.x = width; buildStaticWave() } currentAmp = isPlaying ? amp : 0;
buildStaticWave();
}
onWidthChanged: {
flatEnd.x = width;
buildStaticWave();
}
onHeightChanged: buildStaticWave() onHeightChanged: buildStaticWave()
onCurrentAmpChanged: buildStaticWave() onCurrentAmpChanged: buildStaticWave()
onWavelengthChanged: { k = (2 * Math.PI) / Math.max(1e-6, wavelength); buildStaticWave() } onWavelengthChanged: {
k = (2 * Math.PI) / Math.max(1e-6, wavelength);
buildStaticWave();
}
} }

View File

@@ -11,21 +11,21 @@ text = '{{colors.background.default.hex}}'
cursor = '{{colors.primary.default.hex}}' cursor = '{{colors.primary.default.hex}}'
[colors.normal] [colors.normal]
black = '{{dank16.color0.hex}}' black = '{{dank16.color0.default.hex}}'
red = '{{dank16.color1.hex}}' red = '{{dank16.color1.default.hex}}'
green = '{{dank16.color2.hex}}' green = '{{dank16.color2.default.hex}}'
yellow = '{{dank16.color3.hex}}' yellow = '{{dank16.color3.default.hex}}'
blue = '{{dank16.color4.hex}}' blue = '{{dank16.color4.default.hex}}'
magenta = '{{dank16.color5.hex}}' magenta = '{{dank16.color5.default.hex}}'
cyan = '{{dank16.color6.hex}}' cyan = '{{dank16.color6.default.hex}}'
white = '{{dank16.color7.hex}}' white = '{{dank16.color7.default.hex}}'
[colors.bright] [colors.bright]
black = '{{dank16.color8.hex}}' black = '{{dank16.color8.default.hex}}'
red = '{{dank16.color9.hex}}' red = '{{dank16.color9.default.hex}}'
green = '{{dank16.color10.hex}}' green = '{{dank16.color10.default.hex}}'
yellow = '{{dank16.color11.hex}}' yellow = '{{dank16.color11.default.hex}}'
blue = '{{dank16.color12.hex}}' blue = '{{dank16.color12.default.hex}}'
magenta = '{{dank16.color13.hex}}' magenta = '{{dank16.color13.default.hex}}'
cyan = '{{dank16.color14.hex}}' cyan = '{{dank16.color14.default.hex}}'
white = '{{dank16.color15.hex}}' white = '{{dank16.color15.default.hex}}'

View File

@@ -4,19 +4,19 @@ background={{colors.background.default.hex_stripped}}
selection-foreground={{colors.on_surface.default.hex_stripped}} selection-foreground={{colors.on_surface.default.hex_stripped}}
selection-background={{colors.primary_container.default.hex_stripped}} selection-background={{colors.primary_container.default.hex_stripped}}
regular0={{dank16.color0.hex_stripped}} regular0={{dank16.color0.default.hex_stripped}}
regular1={{dank16.color1.hex_stripped}} regular1={{dank16.color1.default.hex_stripped}}
regular2={{dank16.color2.hex_stripped}} regular2={{dank16.color2.default.hex_stripped}}
regular3={{dank16.color3.hex_stripped}} regular3={{dank16.color3.default.hex_stripped}}
regular4={{dank16.color4.hex_stripped}} regular4={{dank16.color4.default.hex_stripped}}
regular5={{dank16.color5.hex_stripped}} regular5={{dank16.color5.default.hex_stripped}}
regular6={{dank16.color6.hex_stripped}} regular6={{dank16.color6.default.hex_stripped}}
regular7={{dank16.color7.hex_stripped}} regular7={{dank16.color7.default.hex_stripped}}
bright0={{dank16.color8.hex_stripped}} bright0={{dank16.color8.default.hex_stripped}}
bright1={{dank16.color9.hex_stripped}} bright1={{dank16.color9.default.hex_stripped}}
bright2={{dank16.color10.hex_stripped}} bright2={{dank16.color10.default.hex_stripped}}
bright3={{dank16.color11.hex_stripped}} bright3={{dank16.color11.default.hex_stripped}}
bright4={{dank16.color12.hex_stripped}} bright4={{dank16.color12.default.hex_stripped}}
bright5={{dank16.color13.hex_stripped}} bright5={{dank16.color13.default.hex_stripped}}
bright6={{dank16.color14.hex_stripped}} bright6={{dank16.color14.default.hex_stripped}}
bright7={{dank16.color15.hex_stripped}} bright7={{dank16.color15.default.hex_stripped}}

View File

@@ -4,19 +4,19 @@ cursor-color = {{colors.primary.default.hex}}
selection-background = {{colors.primary_container.default.hex}} selection-background = {{colors.primary_container.default.hex}}
selection-foreground = {{colors.on_surface.default.hex}} selection-foreground = {{colors.on_surface.default.hex}}
palette = 0={{dank16.color0.hex}} palette = 0={{dank16.color0.default.hex}}
palette = 1={{dank16.color1.hex}} palette = 1={{dank16.color1.default.hex}}
palette = 2={{dank16.color2.hex}} palette = 2={{dank16.color2.default.hex}}
palette = 3={{dank16.color3.hex}} palette = 3={{dank16.color3.default.hex}}
palette = 4={{dank16.color4.hex}} palette = 4={{dank16.color4.default.hex}}
palette = 5={{dank16.color5.hex}} palette = 5={{dank16.color5.default.hex}}
palette = 6={{dank16.color6.hex}} palette = 6={{dank16.color6.default.hex}}
palette = 7={{dank16.color7.hex}} palette = 7={{dank16.color7.default.hex}}
palette = 8={{dank16.color8.hex}} palette = 8={{dank16.color8.default.hex}}
palette = 9={{dank16.color9.hex}} palette = 9={{dank16.color9.default.hex}}
palette = 10={{dank16.color10.hex}} palette = 10={{dank16.color10.default.hex}}
palette = 11={{dank16.color11.hex}} palette = 11={{dank16.color11.default.hex}}
palette = 12={{dank16.color12.hex}} palette = 12={{dank16.color12.default.hex}}
palette = 13={{dank16.color13.hex}} palette = 13={{dank16.color13.default.hex}}
palette = 14={{dank16.color14.hex}} palette = 14={{dank16.color14.default.hex}}
palette = 15={{dank16.color15.hex}} palette = 15={{dank16.color15.default.hex}}

View File

@@ -7,19 +7,19 @@ selection_foreground {{colors.on_secondary.default.hex}}
selection_background {{colors.secondary_fixed_dim.default.hex}} selection_background {{colors.secondary_fixed_dim.default.hex}}
url_color {{colors.primary.default.hex}} url_color {{colors.primary.default.hex}}
color0 {{dank16.color0.hex}} color0 {{dank16.color0.default.hex}}
color1 {{dank16.color1.hex}} color1 {{dank16.color1.default.hex}}
color2 {{dank16.color2.hex}} color2 {{dank16.color2.default.hex}}
color3 {{dank16.color3.hex}} color3 {{dank16.color3.default.hex}}
color4 {{dank16.color4.hex}} color4 {{dank16.color4.default.hex}}
color5 {{dank16.color5.hex}} color5 {{dank16.color5.default.hex}}
color6 {{dank16.color6.hex}} color6 {{dank16.color6.default.hex}}
color7 {{dank16.color7.hex}} color7 {{dank16.color7.default.hex}}
color8 {{dank16.color8.hex}} color8 {{dank16.color8.default.hex}}
color9 {{dank16.color9.hex}} color9 {{dank16.color9.default.hex}}
color10 {{dank16.color10.hex}} color10 {{dank16.color10.default.hex}}
color11 {{dank16.color11.hex}} color11 {{dank16.color11.default.hex}}
color12 {{dank16.color12.hex}} color12 {{dank16.color12.default.hex}}
color13 {{dank16.color13.hex}} color13 {{dank16.color13.default.hex}}
color14 {{dank16.color14.hex}} color14 {{dank16.color14.default.hex}}
color15 {{dank16.color15.hex}} color15 {{dank16.color15.default.hex}}

View File

@@ -1,431 +1,299 @@
{ {
"$schema": "vscode://schemas/color-theme", "$schema": "vscode://schemas/color-theme",
"name": "Dynamic Base16 DankShell", "name": "Dynamic Base16 DankShell Dark",
"semanticHighlighting": true,
"colors": { "colors": {
//
// Core foreground + background hierarchy
//
"foreground": "{{colors.on_surface.dark.hex}}",
"editor.background": "{{colors.background.dark.hex}}", "editor.background": "{{colors.background.dark.hex}}",
"editor.foreground": "{{colors.on_surface.dark.hex}}", "editor.foreground": "{{colors.on_surface.dark.hex}}",
"editorLineNumber.foreground": "{{colors.outline.dark.hex}}", "errorForeground": "{{colors.error.dark.hex}}",
"editorLineNumber.activeForeground": "{{colors.on_surface.dark.hex}}", //
"editorCursor.foreground": "{{colors.primary.dark.hex}}", // Borders + dividers
"editor.selectionBackground": "{{colors.primary_container.dark.hex}}", //
"editor.inactiveSelectionBackground": "{{colors.background.dark.hex}}", "panel.border": "{{colors.outline_variant.dark.hex}}",
"editor.lineHighlightBackground": "{{colors.background.dark.hex}}", "panelTitle.activeBorder": "{{colors.primary.dark.hex}}",
"editorIndentGuide.background": "{{colors.background.dark.hex}}", "sideBar.border": "{{colors.outline_variant.dark.hex}}",
"editorIndentGuide.activeBackground": "{{colors.outline.dark.hex}}", "editorGroup.border": "{{colors.outline_variant.dark.hex}}",
"editorWhitespace.foreground": "{{colors.outline_variant.dark.hex}}", "tab.border": "{{colors.outline_variant.dark.hex}}",
"editorBracketMatch.background": "{{colors.background.dark.hex}}", "titleBar.border": "{{colors.outline_variant.dark.hex}}",
"editorBracketMatch.border": "{{colors.primary.dark.hex}}", //
// Focus + active indicators
//
"focusBorder": "{{colors.primary.dark.hex}}",
"selection.background": "{{colors.primary_container.dark.hex}}66",
//
// Title bar, activity bar, sidebar
//
"titleBar.activeBackground": "{{colors.background.dark.hex}}",
"titleBar.activeForeground": "{{colors.on_surface.dark.hex}}",
"titleBar.inactiveForeground": "{{colors.outline.dark.hex}}",
"activityBar.background": "{{colors.background.dark.hex}}", "activityBar.background": "{{colors.background.dark.hex}}",
"activityBar.foreground": "{{colors.on_surface.dark.hex}}", "activityBar.foreground": "{{colors.on_surface.dark.hex}}",
"activityBar.inactiveForeground": "{{colors.outline.dark.hex}}",
"activityBar.activeBorder": "{{colors.primary.dark.hex}}", "activityBar.activeBorder": "{{colors.primary.dark.hex}}",
"activityBar.activeBackground": "{{colors.background.dark.hex}}",
"activityBarBadge.background": "{{colors.primary.dark.hex}}", "activityBarBadge.background": "{{colors.primary.dark.hex}}",
"activityBarBadge.foreground": "{{colors.on_primary.dark.hex}}", "activityBarBadge.foreground": "{{colors.on_primary.dark.hex}}",
"sideBar.background": "{{colors.surface_container_low.dark.hex}}",
"sideBar.background": "{{colors.background.dark.hex}}",
"sideBar.foreground": "{{colors.on_surface.dark.hex}}", "sideBar.foreground": "{{colors.on_surface.dark.hex}}",
"sideBar.border": "{{colors.background.dark.hex}}", "statusBarItem.hoverBackground": "{{colors.surface_container_low.dark.hex}}",
"statusBarItem.activeBackground": "{{colors.surface_container.dark.hex}}",
"sideBarTitle.foreground": "{{colors.on_surface.dark.hex}}", "sideBarTitle.foreground": "{{colors.on_surface.dark.hex}}",
"sideBarSectionHeader.background": "{{colors.background.dark.hex}}", "panel.background": "{{colors.surface_container_low.dark.hex}}",
"panelTitle.activeForeground": "{{colors.on_surface.dark.hex}}",
"panelTitle.inactiveForeground": "{{colors.outline.dark.hex}}",
"sideBarSectionHeader.background": "{{colors.surface_container.dark.hex}}",
"sideBarSectionHeader.foreground": "{{colors.on_surface.dark.hex}}", "sideBarSectionHeader.foreground": "{{colors.on_surface.dark.hex}}",
//
"list.activeSelectionBackground": "{{colors.primary_container.dark.hex}}", // Tabs + editor groups
"list.activeSelectionForeground": "{{colors.on_primary_container.dark.hex}}", //
"list.inactiveSelectionBackground": "{{colors.surface_container.dark.hex}}", "editorGroupHeader.tabsBackground": "{{colors.background.dark.hex}}",
"list.inactiveSelectionForeground": "{{colors.on_surface.dark.hex}}", "tab.activeBackground": "{{colors.surface_container_low.dark.hex}}",
"list.hoverBackground": "{{colors.surface_container.dark.hex}}",
"list.hoverForeground": "{{colors.on_surface.dark.hex}}",
"list.focusBackground": "{{colors.surface_container_high.dark.hex}}",
"list.focusForeground": "{{colors.on_surface.dark.hex}}",
"list.highlightForeground": "{{colors.primary.dark.hex}}",
"statusBar.background": "{{colors.background.dark.hex}}",
"statusBar.foreground": "{{colors.on_surface.dark.hex}}",
"statusBar.border": "{{colors.background.dark.hex}}",
"statusBar.noFolderBackground": "{{colors.background.dark.hex}}",
"statusBar.debuggingBackground": "{{colors.error.dark.hex}}",
"statusBar.debuggingForeground": "{{colors.on_error.dark.hex}}",
"tab.activeBackground": "{{colors.background.dark.hex}}",
"tab.inactiveBackground": "{{colors.background.dark.hex}}", "tab.inactiveBackground": "{{colors.background.dark.hex}}",
"tab.activeForeground": "{{colors.on_surface.dark.hex}}", "tab.activeForeground": "{{colors.on_surface.dark.hex}}",
"tab.inactiveForeground": "{{colors.outline.dark.hex}}", "tab.inactiveForeground": "{{colors.outline.dark.hex}}",
"tab.border": "{{colors.background.dark.hex}}", "tab.activeBorderTop": "{{colors.primary.dark.hex}}",
"tab.activeBorder": "{{colors.primary.dark.hex}}", //
"tab.unfocusedActiveBorder": "{{colors.outline.dark.hex}}", // Lists (files, search results, etc.)
//
"editorGroupHeader.tabsBackground": "{{colors.background.dark.hex}}", "list.activeSelectionBackground": "{{colors.primary_container.dark.hex}}",
"editorGroupHeader.noTabsBackground": "{{colors.background.dark.hex}}", "list.activeSelectionForeground": "{{colors.on_primary_container.dark.hex}}",
"list.inactiveSelectionBackground": "{{colors.surface_container.dark.hex}}",
"titleBar.activeBackground": "{{colors.background.dark.hex}}", "list.hoverBackground": "{{colors.surface_container.dark.hex}}",
"titleBar.activeForeground": "{{colors.on_surface.dark.hex}}", "list.hoverForeground": "{{colors.on_surface.dark.hex}}",
"titleBar.inactiveBackground": "{{colors.background.dark.hex}}", "list.focusForeground": "{{colors.on_surface.dark.hex}}",
"titleBar.inactiveForeground": "{{colors.outline.dark.hex}}", "list.focusOutline": "{{colors.primary.dark.hex}}",
"titleBar.border": "{{colors.background.dark.hex}}", "list.focusBackground": "{{colors.surface_container_high.dark.hex}}",
"list.highlightForeground": "{{colors.primary.dark.hex}}",
"input.background": "{{colors.background.dark.hex}}", "list.errorForeground": "{{colors.error.dark.hex}}",
"list.warningForeground": "{{colors.secondary.dark.hex}}",
//
// Inputs + dropdowns
//
"input.background": "{{colors.surface_container_low.dark.hex}}",
"input.foreground": "{{colors.on_surface.dark.hex}}", "input.foreground": "{{colors.on_surface.dark.hex}}",
"input.border": "{{colors.outline.dark.hex}}", "input.border": "{{colors.outline_variant.dark.hex}}",
"input.placeholderForeground": "{{colors.outline.dark.hex}}", "input.placeholderForeground": "{{colors.outline.dark.hex}}",
"inputOption.activeBorder": "{{colors.primary.dark.hex}}", "dropdown.background": "{{colors.surface_container_low.dark.hex}}",
"inputValidation.errorBackground": "{{colors.error.dark.hex}}",
"inputValidation.errorBorder": "{{colors.error.dark.hex}}",
"dropdown.background": "{{colors.background.dark.hex}}",
"dropdown.foreground": "{{colors.on_surface.dark.hex}}", "dropdown.foreground": "{{colors.on_surface.dark.hex}}",
"dropdown.border": "{{colors.outline.dark.hex}}", "dropdown.border": "{{colors.outline_variant.dark.hex}}",
"quickInput.background": "{{colors.surface_container_low.dark.hex}}",
"quickInput.background": "{{colors.background.dark.hex}}",
"quickInput.foreground": "{{colors.on_surface.dark.hex}}", "quickInput.foreground": "{{colors.on_surface.dark.hex}}",
"quickInputList.focusBackground": "{{colors.surface_container_high.dark.hex}}", "widget.shadow": "{{colors.background.dark.hex}}80",
"quickInputList.focusForeground": "{{colors.on_surface.dark.hex}}", //
// Buttons
//
"button.background": "{{colors.primary.dark.hex}}", "button.background": "{{colors.primary.dark.hex}}",
"button.foreground": "{{colors.on_primary.dark.hex}}", "button.foreground": "{{colors.on_primary.dark.hex}}",
"button.hoverBackground": "{{colors.primary_container.dark.hex}}", "button.hoverBackground": "{{colors.primary_container.dark.hex}}",
//
"focusBorder": "{{colors.primary.dark.hex}}", // Status bar
"badge.background": "{{colors.secondary.dark.hex}}", //
"badge.foreground": "{{colors.on_secondary.dark.hex}}", "statusBar.background": "{{colors.background.dark.hex}}",
"statusBar.foreground": "{{colors.on_surface.dark.hex}}",
"panel.background": "{{colors.background.dark.hex}}", "statusBar.border": "{{colors.outline_variant.dark.hex}}",
"panel.border": "{{colors.primary.dark.hex}}", "statusBar.noFolderBackground": "{{colors.background.dark.hex}}",
"panelTitle.activeBorder": "{{colors.primary.dark.hex}}", "statusBar.noFolderForeground": "{{colors.on_surface.dark.hex}}",
"panelTitle.activeForeground": "{{colors.on_surface.dark.hex}}", "statusBar.debuggingBackground": "{{colors.error.dark.hex}}",
"panelTitle.inactiveForeground": "{{colors.outline.dark.hex}}", "statusBar.debuggingForeground": "{{colors.on_error.dark.hex}}",
//
"terminal.background": "{{colors.background.dark.hex}}", // Notifications
"terminal.foreground": "{{colors.on_surface.dark.hex}}", //
"terminal.ansiBlack": "{{dank16.color0.hex}}", "notificationCenterHeader.background": "{{colors.surface_container_low.dark.hex}}",
"terminal.ansiRed": "{{dank16.color1.hex}}", "notificationCenterHeader.foreground": "{{colors.on_surface.dark.hex}}",
"terminal.ansiGreen": "{{dank16.color2.hex}}", "notificationCenter.border": "{{colors.outline_variant.dark.hex}}",
"terminal.ansiYellow": "{{dank16.color3.hex}}", "notifications.background": "{{colors.surface_container_low.dark.hex}}",
"terminal.ansiBlue": "{{dank16.color4.hex}}", "notifications.foreground": "{{colors.on_surface.dark.hex}}",
"terminal.ansiMagenta": "{{dank16.color5.hex}}", "notifications.border": "{{colors.outline_variant.dark.hex}}",
"terminal.ansiCyan": "{{dank16.color6.hex}}", "notificationsErrorIcon.foreground": "{{colors.error.dark.hex}}",
"terminal.ansiWhite": "{{dank16.color7.hex}}", "notificationsWarningIcon.foreground": "{{colors.secondary.dark.hex}}",
"terminal.ansiBrightBlack": "{{dank16.color8.hex}}", "notificationsInfoIcon.foreground": "{{colors.primary.dark.hex}}",
"terminal.ansiBrightRed": "{{dank16.color9.hex}}", //
"terminal.ansiBrightGreen": "{{dank16.color10.hex}}", // Breadcrumbs
"terminal.ansiBrightYellow": "{{dank16.color11.hex}}", //
"terminal.ansiBrightBlue": "{{dank16.color12.hex}}", "breadcrumb.background": "{{colors.surface_container.dark.hex}}",
"terminal.ansiBrightMagenta": "{{dank16.color13.hex}}",
"terminal.ansiBrightCyan": "{{dank16.color14.hex}}",
"terminal.ansiBrightWhite": "{{dank16.color15.hex}}",
"gitDecoration.modifiedResourceForeground": "{{colors.primary.dark.hex}}",
"gitDecoration.addedResourceForeground": "{{colors.primary.dark.hex}}",
"gitDecoration.stageModifiedResourceForeground": "{{colors.primary.dark.hex}}",
"gitDecoration.stageDeletedResourceForeground": "{{colors.error.dark.hex}}",
"gitDecoration.deletedResourceForeground": "{{colors.error.dark.hex}}",
"gitDecoration.untrackedResourceForeground": "{{colors.secondary.dark.hex}}",
"gitDecoration.ignoredResourceForeground": "{{colors.outline.dark.hex}}",
"gitDecoration.conflictingResourceForeground": "{{colors.error_container.dark.hex}}",
"gitDecoration.submoduleResourceForeground": "{{colors.primary.dark.hex}}",
"editorWidget.background": "{{colors.background.dark.hex}}",
"editorWidget.border": "{{colors.outline.dark.hex}}",
"editorSuggestWidget.background": "{{colors.background.dark.hex}}",
"editorSuggestWidget.border": "{{colors.outline.dark.hex}}",
"editorSuggestWidget.selectedBackground": "{{colors.surface_container_high.dark.hex}}",
"editorSuggestWidget.highlightForeground": "{{colors.primary.dark.hex}}",
"peekView.border": "{{colors.primary.dark.hex}}",
"peekViewEditor.background": "{{colors.background.dark.hex}}",
"peekViewResult.background": "{{colors.background.dark.hex}}",
"peekViewTitle.background": "{{colors.background.dark.hex}}",
"notificationCenter.border": "{{colors.outline.dark.hex}}",
"notifications.background": "{{colors.background.dark.hex}}",
"notifications.border": "{{colors.outline.dark.hex}}",
"breadcrumb.foreground": "{{colors.outline.dark.hex}}", "breadcrumb.foreground": "{{colors.outline.dark.hex}}",
"breadcrumb.focusForeground": "{{colors.on_surface.dark.hex}}", "breadcrumb.focusForeground": "{{colors.on_surface.dark.hex}}",
"breadcrumb.activeSelectionForeground": "{{colors.primary.dark.hex}}", "breadcrumb.activeSelectionForeground": "{{colors.primary.dark.hex}}",
//
// Editor highlights + guides
//
"editorLineNumber.foreground": "{{colors.outline.dark.hex}}",
"editorLineNumber.activeForeground": "{{colors.primary.dark.hex}}",
"editorCursor.foreground": "{{colors.primary.dark.hex}}",
"editor.lineHighlightBackground": "{{colors.surface_container.dark.hex}}66",
"editor.wordHighlightBackground": "{{colors.secondary.dark.hex}}22",
"editor.wordHighlightStrongBackground": "{{colors.tertiary.dark.hex}}22",
"editor.selectionBackground": "{{colors.primary_container.dark.hex}}66",
"editor.inactiveSelectionBackground": "{{colors.primary_container.dark.hex}}33",
"editorWhitespace.foreground": "{{colors.outline.dark.hex}}66",
"editorIndentGuide.background1": "{{colors.outline.dark.hex}}33",
"editorIndentGuide.activeBackground1": "{{colors.primary.dark.hex}}99",
"editorOverviewRuler.border": "{{colors.outline_variant.dark.hex}}",
"editorOverviewRuler.errorForeground": "{{colors.error.dark.hex}}88",
"editorOverviewRuler.warningForeground": "{{colors.tertiary.dark.hex}}88",
"editorOverviewRuler.infoForeground": "{{colors.primary.dark.hex}}88",
"editorStickyScroll.background": "{{colors.background.dark.hex}}",
"editorStickyScrollHover.background": "{{colors.surface_container_low.dark.hex}}",
"editorBracketHighlight.unexpectedBracket.foreground": "{{colors.outline.dark.hex}}",
//
// Diff editor
//
"diffEditor.insertedTextBackground": "{{colors.secondary.dark.hex}}20",
"diffEditor.removedTextBackground": "{{colors.error.dark.hex}}20",
//
// Git
//
"gitDecoration.modifiedResourceForeground": "{{colors.primary.dark.hex}}",
"gitDecoration.addedResourceForeground": "{{colors.secondary.dark.hex}}",
"gitDecoration.deletedResourceForeground": "{{colors.error.dark.hex}}",
"gitDecoration.ignoredResourceForeground": "{{colors.outline.dark.hex}}",
//
// Peek, Hover, Widgets
//
"editorHoverWidget.background": "{{colors.surface_container_high.dark.hex}}",
"editorHoverWidget.border": "{{colors.outline.dark.hex}}",
"editorSuggestWidget.background": "{{colors.surface_container.dark.hex}}",
"editorSuggestWidget.foreground": "{{colors.on_surface.dark.hex}}",
"editorSuggestWidget.selectedBackground": "{{colors.surface_container_high.dark.hex}}",
"editorSuggestWidget.highlightForeground": "{{colors.primary.dark.hex}}",
//
// Scrollbar
//
"scrollbarSlider.background": "{{colors.outline.dark.hex}}40", "scrollbarSlider.background": "{{colors.outline.dark.hex}}40",
"scrollbarSlider.hoverBackground": "{{colors.outline.dark.hex}}60", "scrollbarSlider.hoverBackground": "{{colors.outline.dark.hex}}60",
"scrollbarSlider.activeBackground": "{{colors.outline.dark.hex}}80", "scrollbarSlider.activeBackground": "{{colors.outline.dark.hex}}80",
//
"editorError.foreground": "{{colors.error.dark.hex}}", // Terminal (Dank16)
"editorWarning.foreground": "{{colors.tertiary.dark.hex}}", //
"editorInfo.foreground": "{{colors.primary.dark.hex}}", "terminal.background": "{{colors.background.dark.hex}}",
"terminal.foreground": "{{colors.on_surface.dark.hex}}",
"editorGutter.addedBackground": "{{colors.secondary.dark.hex}}", "terminal.ansiBlack": "{{dank16.color0.dark.hex}}",
"editorGutter.modifiedBackground": "{{colors.tertiary.dark.hex}}", "terminal.ansiRed": "{{dank16.color1.dark.hex}}",
"editorGutter.deletedBackground": "{{colors.error.dark.hex}}", "terminal.ansiGreen": "{{dank16.color2.dark.hex}}",
"terminal.ansiYellow": "{{dank16.color3.dark.hex}}",
"diffEditor.insertedTextBackground": "{{colors.secondary.dark.hex}}20", "terminal.ansiBlue": "{{dank16.color4.dark.hex}}",
"diffEditor.removedTextBackground": "{{colors.error.dark.hex}}20", "terminal.ansiMagenta": "{{dank16.color5.dark.hex}}",
"terminal.ansiCyan": "{{dank16.color6.dark.hex}}",
"merge.currentHeaderBackground": "{{colors.primary.dark.hex}}40", "terminal.ansiWhite": "{{dank16.color7.dark.hex}}",
"merge.incomingHeaderBackground": "{{colors.secondary.dark.hex}}40", "terminal.ansiBrightBlack": "{{dank16.color8.dark.hex}}",
"terminal.ansiBrightRed": "{{dank16.color9.dark.hex}}",
"menubar.selectionBackground": "{{colors.surface_container.dark.hex}}", "terminal.ansiBrightGreen": "{{dank16.color10.dark.hex}}",
"menu.background": "{{colors.background.dark.hex}}", "terminal.ansiBrightYellow": "{{dank16.color11.dark.hex}}",
"menu.foreground": "{{colors.on_surface.dark.hex}}", "terminal.ansiBrightBlue": "{{dank16.color12.dark.hex}}",
"menu.selectionBackground": "{{colors.surface_container_high.dark.hex}}", "terminal.ansiBrightMagenta": "{{dank16.color13.dark.hex}}",
"menu.selectionForeground": "{{colors.on_surface.dark.hex}}", "terminal.ansiBrightCyan": "{{dank16.color14.dark.hex}}",
"terminal.ansiBrightWhite": "{{dank16.color15.dark.hex}}"
"debugToolBar.background": "{{colors.background.dark.hex}}",
"debugExceptionWidget.background": "{{colors.background.dark.hex}}",
"debugExceptionWidget.border": "{{colors.error.dark.hex}}"
}, },
//
// Token colors
//
"tokenColors": [ "tokenColors": [
{ {
"scope": ["variable", "meta.object-literal.key"], "scope": [
"comment"
],
"settings": { "settings": {
"foreground": "{{colors.on_surface.dark.hex}}" "foreground": "{{dank16.color8.dark.hex}}"
} }
}, },
{ {
"scope": ["string", "constant.other.symbol"], "scope": [
"keyword"
],
"settings": { "settings": {
"foreground": "{{colors.secondary.dark.hex}}" "foreground": "{{dank16.color5.dark.hex}}"
} }
}, },
{ {
"scope": ["constant.numeric", "constant.language", "constant.character"], "scope": [
"string"
],
"settings": { "settings": {
"foreground": "{{colors.tertiary.dark.hex}}" "foreground": "{{dank16.color3.dark.hex}}"
} }
}, },
{ {
"scope": ["entity.name.type", "support.type", "entity.name.class"], "scope": [
"constant",
"number"
],
"settings": { "settings": {
"foreground": "{{colors.tertiary.dark.hex}}" "foreground": "{{dank16.color12.dark.hex}}"
} }
}, },
{ {
"scope": ["entity.name.function", "support.function"], "scope": [
"variable"
],
"settings": { "settings": {
"foreground": "{{colors.primary.dark.hex}}" "foreground": "{{dank16.color15.dark.hex}}"
} }
}, },
{ {
"scope": ["support.class", "support.variable", "variable.language"], "scope": [
"entity.name.function"
],
"settings": { "settings": {
"foreground": "{{colors.secondary.dark.hex}}" "foreground": "{{dank16.color2.dark.hex}}"
} }
}, },
{ {
"scope": ["invalid"], "scope": [
"entity.name.class",
"support.type"
],
"settings": {
"foreground": "{{dank16.color12.dark.hex}}"
}
},
{
"scope": [
"invalid"
],
"settings": { "settings": {
"foreground": "{{colors.error.dark.hex}}" "foreground": "{{colors.error.dark.hex}}"
} }
}, },
{ {
"scope": ["invalid.deprecated"], "scope": [
"settings": { "markup.heading"
"foreground": "{{colors.outline.dark.hex}}" ],
}
},
{
"scope": ["markup.heading"],
"settings": { "settings": {
"foreground": "{{colors.primary.dark.hex}}", "foreground": "{{colors.primary.dark.hex}}",
"fontStyle": "bold" "fontStyle": "bold"
} }
},
{
"scope": ["markup.bold"],
"settings": {
"foreground": "{{colors.tertiary.dark.hex}}",
"fontStyle": "bold"
}
},
{
"scope": ["markup.italic"],
"settings": {
"foreground": "{{colors.primary.dark.hex}}",
"fontStyle": "italic"
}
},
{
"scope": ["markup.underline"],
"settings": {
"fontStyle": "underline"
}
},
{
"scope": ["markup.quote"],
"settings": {
"foreground": "{{colors.secondary.dark.hex}}"
}
},
{
"scope": ["markup.list"],
"settings": {
"foreground": "{{colors.on_surface.dark.hex}}"
}
},
{
"scope": ["markup.raw", "markup.inline.raw"],
"settings": {
"foreground": "{{colors.secondary.dark.hex}}"
}
},
{
"scope": ["comment", "punctuation.definition.comment"],
"settings": {
"foreground": "{{dank16.color8.hex}}"
}
},
{
"scope": "keyword",
"settings": {
"foreground": "{{dank16.color5.hex}}"
}
},
{
"scope": "storage.type",
"settings": {
"foreground": "{{dank16.color13.hex}}"
}
},
{
"scope": "storage.modifier",
"settings": {
"foreground": "{{dank16.color5.hex}}"
}
},
{
"scope": "variable",
"settings": {
"foreground": "{{dank16.color15.hex}}"
}
},
{
"scope": "variable.parameter",
"settings": {
"foreground": "{{dank16.color7.hex}}"
}
},
{
"scope": ["meta.object-literal.key", "meta.property.object", "variable.other.property"],
"settings": {
"foreground": "{{dank16.color4.hex}}"
}
},
{
"scope": "constant.other.symbol",
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": ["constant.numeric", "constant.language"],
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": "constant.character",
"settings": {
"foreground": "{{dank16.color3.hex}}"
}
},
{
"scope": ["entity.name.type", "entity.name.class"],
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": "support.type",
"settings": {
"foreground": "{{dank16.color13.hex}}"
}
},
{
"scope": ["entity.name.function", "support.function"],
"settings": {
"foreground": "{{dank16.color2.hex}}"
}
},
{
"scope": ["support.class", "support.variable"],
"settings": {
"foreground": "{{dank16.color15.hex}}"
}
},
{
"scope": "variable.language",
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": "entity.name.tag.yaml",
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": ["string.unquoted.plain.out.yaml", "string.unquoted.yaml"],
"settings": {
"foreground": "{{dank16.color15.hex}}"
}
},
{
"scope": "string",
"settings": {
"foreground": "{{dank16.color3.hex}}"
}
} }
], ],
//
"semanticHighlighting": true, // Semantic tokens
//
"semanticTokenColors": { "semanticTokenColors": {
"variable": { "variable": {
"foreground": "{{dank16.color15.hex}}" "foreground": "{{dank16.color15.dark.hex}}"
},
"variable.readonly": {
"foreground": "{{dank16.color12.hex}}"
},
"property": {
"foreground": "{{dank16.color4.hex}}"
},
"function": {
"foreground": "{{dank16.color2.hex}}"
},
"method": {
"foreground": "{{dank16.color2.hex}}"
},
"type": {
"foreground": "{{dank16.color12.hex}}"
},
"class": {
"foreground": "{{dank16.color12.hex}}"
},
"typeParameter": {
"foreground": "{{dank16.color13.hex}}"
},
"enumMember": {
"foreground": "{{dank16.color12.hex}}"
},
"string": {
"foreground": "{{dank16.color3.hex}}"
},
"number": {
"foreground": "{{dank16.color12.hex}}"
},
"comment": {
"foreground": "{{dank16.color8.hex}}"
},
"keyword": {
"foreground": "{{dank16.color5.hex}}"
},
"operator": {
"foreground": "{{dank16.color15.hex}}"
}, },
"parameter": { "parameter": {
"foreground": "{{dank16.color7.hex}}" "foreground": "{{dank16.color7.dark.hex}}"
}, },
"namespace": { "property": {
"foreground": "{{dank16.color15.hex}}" "foreground": "{{dank16.color4.dark.hex}}"
},
"function": {
"foreground": "{{dank16.color2.dark.hex}}"
},
"string": {
"foreground": "{{dank16.color3.dark.hex}}"
},
"number": {
"foreground": "{{dank16.color12.dark.hex}}"
},
"keyword": {
"foreground": "{{dank16.color5.dark.hex}}"
},
"comment": {
"foreground": "{{dank16.color8.dark.hex}}"
} }
} }
} }

View File

@@ -1,431 +1,251 @@
{ {
"$schema": "vscode://schemas/color-theme", "$schema": "vscode://schemas/color-theme",
"name": "Dynamic Base16 DankShell", "name": "Dynamic Base16 DankShell",
"semanticHighlighting": true,
"colors": { "colors": {
"foreground": "{{colors.on_surface.default.hex}}",
"editor.background": "{{colors.background.default.hex}}", "editor.background": "{{colors.background.default.hex}}",
"editor.foreground": "{{colors.on_surface.default.hex}}", "editor.foreground": "{{colors.on_surface.default.hex}}",
"editorLineNumber.foreground": "{{colors.outline.default.hex}}", "errorForeground": "{{colors.error.default.hex}}",
"editorLineNumber.activeForeground": "{{colors.on_surface.default.hex}}", "panel.border": "{{colors.outline_variant.default.hex}}",
"editorCursor.foreground": "{{colors.primary.default.hex}}", "panelTitle.activeBorder": "{{colors.primary.default.hex}}",
"editor.selectionBackground": "{{colors.primary_container.default.hex}}", "sideBar.border": "{{colors.outline_variant.default.hex}}",
"editor.inactiveSelectionBackground": "{{colors.background.default.hex}}", "editorGroup.border": "{{colors.outline_variant.default.hex}}",
"editor.lineHighlightBackground": "{{colors.background.default.hex}}", "tab.border": "{{colors.outline_variant.default.hex}}",
"editorIndentGuide.background": "{{colors.background.default.hex}}", "titleBar.border": "{{colors.outline_variant.default.hex}}",
"editorIndentGuide.activeBackground": "{{colors.outline.default.hex}}", "focusBorder": "{{colors.primary.default.hex}}",
"editorWhitespace.foreground": "{{colors.outline_variant.default.hex}}", "selection.background": "{{colors.primary_container.default.hex}}66",
"editorBracketMatch.background": "{{colors.background.default.hex}}", "titleBar.activeBackground": "{{colors.background.default.hex}}",
"editorBracketMatch.border": "{{colors.primary.default.hex}}", "titleBar.activeForeground": "{{colors.on_surface.default.hex}}",
"titleBar.inactiveForeground": "{{colors.outline.default.hex}}",
"activityBar.background": "{{colors.background.default.hex}}", "activityBar.background": "{{colors.background.default.hex}}",
"activityBar.foreground": "{{colors.on_surface.default.hex}}", "activityBar.foreground": "{{colors.on_surface.default.hex}}",
"activityBar.inactiveForeground": "{{colors.outline.default.hex}}",
"activityBar.activeBorder": "{{colors.primary.default.hex}}", "activityBar.activeBorder": "{{colors.primary.default.hex}}",
"activityBar.activeBackground": "{{colors.background.default.hex}}",
"activityBarBadge.background": "{{colors.primary.default.hex}}", "activityBarBadge.background": "{{colors.primary.default.hex}}",
"activityBarBadge.foreground": "{{colors.on_primary.default.hex}}", "activityBarBadge.foreground": "{{colors.on_primary.default.hex}}",
"sideBar.background": "{{colors.surface_container_low.default.hex}}",
"sideBar.background": "{{colors.background.default.hex}}",
"sideBar.foreground": "{{colors.on_surface.default.hex}}", "sideBar.foreground": "{{colors.on_surface.default.hex}}",
"sideBar.border": "{{colors.background.default.hex}}", "statusBarItem.hoverBackground": "{{colors.surface_container_low.default.hex}}",
"statusBarItem.activeBackground": "{{colors.surface_container.default.hex}}",
"sideBarTitle.foreground": "{{colors.on_surface.default.hex}}", "sideBarTitle.foreground": "{{colors.on_surface.default.hex}}",
"sideBarSectionHeader.background": "{{colors.background.default.hex}}", "panel.background": "{{colors.surface_container_low.default.hex}}",
"panelTitle.activeForeground": "{{colors.on_surface.default.hex}}",
"panelTitle.inactiveForeground": "{{colors.outline.default.hex}}",
"sideBarSectionHeader.background": "{{colors.surface_container.default.hex}}",
"sideBarSectionHeader.foreground": "{{colors.on_surface.default.hex}}", "sideBarSectionHeader.foreground": "{{colors.on_surface.default.hex}}",
"editorGroupHeader.tabsBackground": "{{colors.background.default.hex}}",
"list.activeSelectionBackground": "{{colors.primary_container.default.hex}}", "tab.activeBackground": "{{colors.surface_container_low.default.hex}}",
"list.activeSelectionForeground": "{{colors.on_primary_container.default.hex}}",
"list.inactiveSelectionBackground": "{{colors.surface_container.default.hex}}",
"list.inactiveSelectionForeground": "{{colors.on_surface.default.hex}}",
"list.hoverBackground": "{{colors.surface_container.default.hex}}",
"list.hoverForeground": "{{colors.on_surface.default.hex}}",
"list.focusBackground": "{{colors.surface_container_high.default.hex}}",
"list.focusForeground": "{{colors.on_surface.default.hex}}",
"list.highlightForeground": "{{colors.primary.default.hex}}",
"statusBar.background": "{{colors.background.default.hex}}",
"statusBar.foreground": "{{colors.on_surface.default.hex}}",
"statusBar.border": "{{colors.background.default.hex}}",
"statusBar.noFolderBackground": "{{colors.background.default.hex}}",
"statusBar.debuggingBackground": "{{colors.error.default.hex}}",
"statusBar.debuggingForeground": "{{colors.on_error.default.hex}}",
"tab.activeBackground": "{{colors.background.default.hex}}",
"tab.inactiveBackground": "{{colors.background.default.hex}}", "tab.inactiveBackground": "{{colors.background.default.hex}}",
"tab.activeForeground": "{{colors.on_surface.default.hex}}", "tab.activeForeground": "{{colors.on_surface.default.hex}}",
"tab.inactiveForeground": "{{colors.outline.default.hex}}", "tab.inactiveForeground": "{{colors.outline.default.hex}}",
"tab.border": "{{colors.background.default.hex}}", "tab.activeBorderTop": "{{colors.primary.default.hex}}",
"tab.activeBorder": "{{colors.primary.default.hex}}", "list.activeSelectionBackground": "{{colors.primary_container.default.hex}}",
"tab.unfocusedActiveBorder": "{{colors.outline.default.hex}}", "list.activeSelectionForeground": "{{colors.on_primary_container.default.hex}}",
"list.inactiveSelectionBackground": "{{colors.surface_container.default.hex}}",
"editorGroupHeader.tabsBackground": "{{colors.background.default.hex}}", "list.hoverBackground": "{{colors.surface_container.default.hex}}",
"editorGroupHeader.noTabsBackground": "{{colors.background.default.hex}}", "list.hoverForeground": "{{colors.on_surface.default.hex}}",
"list.focusForeground": "{{colors.on_surface.default.hex}}",
"titleBar.activeBackground": "{{colors.background.default.hex}}", "list.focusOutline": "{{colors.primary.default.hex}}",
"titleBar.activeForeground": "{{colors.on_surface.default.hex}}", "list.focusBackground": "{{colors.surface_container_high.default.hex}}",
"titleBar.inactiveBackground": "{{colors.background.default.hex}}", "list.highlightForeground": "{{colors.primary.default.hex}}",
"titleBar.inactiveForeground": "{{colors.outline.default.hex}}", "list.errorForeground": "{{colors.error.default.hex}}",
"titleBar.border": "{{colors.background.default.hex}}", "list.warningForeground": "{{colors.secondary.default.hex}}",
"input.background": "{{colors.surface_container_low.default.hex}}",
"input.background": "{{colors.background.default.hex}}",
"input.foreground": "{{colors.on_surface.default.hex}}", "input.foreground": "{{colors.on_surface.default.hex}}",
"input.border": "{{colors.outline.default.hex}}", "input.border": "{{colors.outline_variant.default.hex}}",
"input.placeholderForeground": "{{colors.outline.default.hex}}", "input.placeholderForeground": "{{colors.outline.default.hex}}",
"inputOption.activeBorder": "{{colors.primary.default.hex}}", "dropdown.background": "{{colors.surface_container_low.default.hex}}",
"inputValidation.errorBackground": "{{colors.error.default.hex}}",
"inputValidation.errorBorder": "{{colors.error.default.hex}}",
"dropdown.background": "{{colors.background.default.hex}}",
"dropdown.foreground": "{{colors.on_surface.default.hex}}", "dropdown.foreground": "{{colors.on_surface.default.hex}}",
"dropdown.border": "{{colors.outline.default.hex}}", "dropdown.border": "{{colors.outline_variant.default.hex}}",
"quickInput.background": "{{colors.surface_container_low.default.hex}}",
"quickInput.background": "{{colors.background.default.hex}}",
"quickInput.foreground": "{{colors.on_surface.default.hex}}", "quickInput.foreground": "{{colors.on_surface.default.hex}}",
"quickInputList.focusBackground": "{{colors.surface_container_high.default.hex}}", "widget.shadow": "{{colors.background.default.hex}}80",
"quickInputList.focusForeground": "{{colors.on_surface.default.hex}}",
"button.background": "{{colors.primary.default.hex}}", "button.background": "{{colors.primary.default.hex}}",
"button.foreground": "{{colors.on_primary.default.hex}}", "button.foreground": "{{colors.on_primary.default.hex}}",
"button.hoverBackground": "{{colors.primary_container.default.hex}}", "button.hoverBackground": "{{colors.primary_container.default.hex}}",
"statusBar.background": "{{colors.background.default.hex}}",
"focusBorder": "{{colors.primary.default.hex}}", "statusBar.foreground": "{{colors.on_surface.default.hex}}",
"badge.background": "{{colors.secondary.default.hex}}", "statusBar.border": "{{colors.outline_variant.default.hex}}",
"badge.foreground": "{{colors.on_secondary.default.hex}}", "statusBar.noFolderBackground": "{{colors.background.default.hex}}",
"statusBar.noFolderForeground": "{{colors.on_surface.default.hex}}",
"panel.background": "{{colors.background.default.hex}}", "statusBar.debuggingBackground": "{{colors.error.default.hex}}",
"panel.border": "{{colors.primary.default.hex}}", "statusBar.debuggingForeground": "{{colors.on_error.default.hex}}",
"panelTitle.activeBorder": "{{colors.primary.default.hex}}", "notificationCenterHeader.background": "{{colors.surface_container_low.default.hex}}",
"panelTitle.activeForeground": "{{colors.on_surface.default.hex}}", "notificationCenterHeader.foreground": "{{colors.on_surface.default.hex}}",
"panelTitle.inactiveForeground": "{{colors.outline.default.hex}}", "notificationCenter.border": "{{colors.outline_variant.default.hex}}",
"notifications.background": "{{colors.surface_container_low.default.hex}}",
"terminal.background": "{{colors.background.default.hex}}", "notifications.foreground": "{{colors.on_surface.default.hex}}",
"terminal.foreground": "{{colors.on_surface.default.hex}}", "notifications.border": "{{colors.outline_variant.default.hex}}",
"terminal.ansiBlack": "{{dank16.color0.hex}}", "notificationsErrorIcon.foreground": "{{colors.error.default.hex}}",
"terminal.ansiRed": "{{dank16.color1.hex}}", "notificationsWarningIcon.foreground": "{{colors.secondary.default.hex}}",
"terminal.ansiGreen": "{{dank16.color2.hex}}", "notificationsInfoIcon.foreground": "{{colors.primary.default.hex}}",
"terminal.ansiYellow": "{{dank16.color3.hex}}", "breadcrumb.background": "{{colors.surface_container.default.hex}}",
"terminal.ansiBlue": "{{dank16.color4.hex}}",
"terminal.ansiMagenta": "{{dank16.color5.hex}}",
"terminal.ansiCyan": "{{dank16.color6.hex}}",
"terminal.ansiWhite": "{{dank16.color7.hex}}",
"terminal.ansiBrightBlack": "{{dank16.color8.hex}}",
"terminal.ansiBrightRed": "{{dank16.color9.hex}}",
"terminal.ansiBrightGreen": "{{dank16.color10.hex}}",
"terminal.ansiBrightYellow": "{{dank16.color11.hex}}",
"terminal.ansiBrightBlue": "{{dank16.color12.hex}}",
"terminal.ansiBrightMagenta": "{{dank16.color13.hex}}",
"terminal.ansiBrightCyan": "{{dank16.color14.hex}}",
"terminal.ansiBrightWhite": "{{dank16.color15.hex}}",
"gitDecoration.modifiedResourceForeground": "{{colors.primary.default.hex}}",
"gitDecoration.addedResourceForeground": "{{colors.primary.default.hex}}",
"gitDecoration.stageModifiedResourceForeground": "{{colors.primary.default.hex}}",
"gitDecoration.stageDeletedResourceForeground": "{{colors.error.default.hex}}",
"gitDecoration.deletedResourceForeground": "{{colors.error.default.hex}}",
"gitDecoration.untrackedResourceForeground": "{{colors.secondary.default.hex}}",
"gitDecoration.ignoredResourceForeground": "{{colors.outline.default.hex}}",
"gitDecoration.conflictingResourceForeground": "{{colors.error_container.default.hex}}",
"gitDecoration.submoduleResourceForeground": "{{colors.primary.default.hex}}",
"editorWidget.background": "{{colors.background.default.hex}}",
"editorWidget.border": "{{colors.outline.default.hex}}",
"editorSuggestWidget.background": "{{colors.background.default.hex}}",
"editorSuggestWidget.border": "{{colors.outline.default.hex}}",
"editorSuggestWidget.selectedBackground": "{{colors.surface_container_high.default.hex}}",
"editorSuggestWidget.highlightForeground": "{{colors.primary.default.hex}}",
"peekView.border": "{{colors.primary.default.hex}}",
"peekViewEditor.background": "{{colors.background.default.hex}}",
"peekViewResult.background": "{{colors.background.default.hex}}",
"peekViewTitle.background": "{{colors.background.default.hex}}",
"notificationCenter.border": "{{colors.outline.default.hex}}",
"notifications.background": "{{colors.background.default.hex}}",
"notifications.border": "{{colors.outline.default.hex}}",
"breadcrumb.foreground": "{{colors.outline.default.hex}}", "breadcrumb.foreground": "{{colors.outline.default.hex}}",
"breadcrumb.focusForeground": "{{colors.on_surface.default.hex}}", "breadcrumb.focusForeground": "{{colors.on_surface.default.hex}}",
"breadcrumb.activeSelectionForeground": "{{colors.primary.default.hex}}", "breadcrumb.activeSelectionForeground": "{{colors.primary.default.hex}}",
"editorLineNumber.foreground": "{{colors.outline.default.hex}}",
"editorLineNumber.activeForeground": "{{colors.primary.default.hex}}",
"editorCursor.foreground": "{{colors.primary.default.hex}}",
"editor.lineHighlightBackground": "{{colors.surface_container.default.hex}}66",
"editor.wordHighlightBackground": "{{colors.secondary.default.hex}}22",
"editor.wordHighlightStrongBackground": "{{colors.tertiary.default.hex}}22",
"editor.selectionBackground": "{{colors.primary_container.default.hex}}66",
"editor.inactiveSelectionBackground": "{{colors.primary_container.default.hex}}33",
"editorWhitespace.foreground": "{{colors.outline.default.hex}}66",
"editorIndentGuide.background1": "{{colors.outline.default.hex}}33",
"editorIndentGuide.activeBackground1": "{{colors.primary.default.hex}}99",
"editorOverviewRuler.border": "{{colors.outline_variant.default.hex}}",
"editorOverviewRuler.errorForeground": "{{colors.error.default.hex}}88",
"editorOverviewRuler.warningForeground": "{{colors.tertiary.default.hex}}88",
"editorOverviewRuler.infoForeground": "{{colors.primary.default.hex}}88",
"editorStickyScroll.background": "{{colors.background.default.hex}}",
"editorStickyScrollHover.background": "{{colors.surface_container_low.default.hex}}",
"editorBracketHighlight.unexpectedBracket.foreground": "{{colors.outline.default.hex}}",
"diffEditor.insertedTextBackground": "{{colors.secondary.default.hex}}20",
"diffEditor.removedTextBackground": "{{colors.error.default.hex}}20",
"gitDecoration.modifiedResourceForeground": "{{colors.primary.default.hex}}",
"gitDecoration.addedResourceForeground": "{{colors.secondary.default.hex}}",
"gitDecoration.deletedResourceForeground": "{{colors.error.default.hex}}",
"gitDecoration.ignoredResourceForeground": "{{colors.outline.default.hex}}",
"editorHoverWidget.background": "{{colors.surface_container_high.default.hex}}",
"editorHoverWidget.border": "{{colors.outline.default.hex}}",
"editorSuggestWidget.background": "{{colors.surface_container.default.hex}}",
"editorSuggestWidget.foreground": "{{colors.on_surface.default.hex}}",
"editorSuggestWidget.selectedBackground": "{{colors.surface_container_high.default.hex}}",
"editorSuggestWidget.highlightForeground": "{{colors.primary.default.hex}}",
"scrollbarSlider.background": "{{colors.outline.default.hex}}40", "scrollbarSlider.background": "{{colors.outline.default.hex}}40",
"scrollbarSlider.hoverBackground": "{{colors.outline.default.hex}}60", "scrollbarSlider.hoverBackground": "{{colors.outline.default.hex}}60",
"scrollbarSlider.activeBackground": "{{colors.outline.default.hex}}80", "scrollbarSlider.activeBackground": "{{colors.outline.default.hex}}80",
"terminal.background": "{{colors.background.default.hex}}",
"editorError.foreground": "{{colors.error.default.hex}}", "terminal.foreground": "{{colors.on_surface.default.hex}}",
"editorWarning.foreground": "{{colors.tertiary.default.hex}}", "terminal.ansiBlack": "{{dank16.color0.default.hex}}",
"editorInfo.foreground": "{{colors.primary.default.hex}}", "terminal.ansiRed": "{{dank16.color1.default.hex}}",
"terminal.ansiGreen": "{{dank16.color2.default.hex}}",
"editorGutter.addedBackground": "{{colors.secondary.default.hex}}", "terminal.ansiYellow": "{{dank16.color3.default.hex}}",
"editorGutter.modifiedBackground": "{{colors.tertiary.default.hex}}", "terminal.ansiBlue": "{{dank16.color4.default.hex}}",
"editorGutter.deletedBackground": "{{colors.error.default.hex}}", "terminal.ansiMagenta": "{{dank16.color5.default.hex}}",
"terminal.ansiCyan": "{{dank16.color6.default.hex}}",
"diffEditor.insertedTextBackground": "{{colors.secondary.default.hex}}20", "terminal.ansiWhite": "{{dank16.color7.default.hex}}",
"diffEditor.removedTextBackground": "{{colors.error.default.hex}}20", "terminal.ansiBrightBlack": "{{dank16.color8.default.hex}}",
"terminal.ansiBrightRed": "{{dank16.color9.default.hex}}",
"merge.currentHeaderBackground": "{{colors.primary.default.hex}}40", "terminal.ansiBrightGreen": "{{dank16.color10.default.hex}}",
"merge.incomingHeaderBackground": "{{colors.secondary.default.hex}}40", "terminal.ansiBrightYellow": "{{dank16.color11.default.hex}}",
"terminal.ansiBrightBlue": "{{dank16.color12.default.hex}}",
"menubar.selectionBackground": "{{colors.surface_container.default.hex}}", "terminal.ansiBrightMagenta": "{{dank16.color13.default.hex}}",
"menu.background": "{{colors.background.default.hex}}", "terminal.ansiBrightCyan": "{{dank16.color14.default.hex}}",
"menu.foreground": "{{colors.on_surface.default.hex}}", "terminal.ansiBrightWhite": "{{dank16.color15.default.hex}}"
"menu.selectionBackground": "{{colors.surface_container_high.default.hex}}",
"menu.selectionForeground": "{{colors.on_surface.default.hex}}",
"debugToolBar.background": "{{colors.background.default.hex}}",
"debugExceptionWidget.background": "{{colors.background.default.hex}}",
"debugExceptionWidget.border": "{{colors.error.default.hex}}"
}, },
"tokenColors": [ "tokenColors": [
{ {
"scope": ["variable", "meta.object-literal.key"], "scope": [
"settings": { "comment"
"foreground": "{{colors.on_surface.default.hex}}" ],
}
},
{
"scope": ["string", "constant.other.symbol"],
"settings": {
"foreground": "{{colors.secondary.default.hex}}"
}
},
{
"scope": ["constant.numeric", "constant.language", "constant.character"],
"settings": {
"foreground": "{{colors.tertiary.default.hex}}"
}
},
{
"scope": ["entity.name.type", "support.type", "entity.name.class"],
"settings": {
"foreground": "{{colors.tertiary.default.hex}}"
}
},
{
"scope": ["entity.name.function", "support.function"],
"settings": {
"foreground": "{{colors.primary.default.hex}}"
}
},
{
"scope": ["support.class", "support.variable", "variable.language"],
"settings": {
"foreground": "{{colors.secondary.default.hex}}"
}
},
{
"scope": ["invalid"],
"settings": {
"foreground": "{{colors.error.default.hex}}"
}
},
{
"scope": ["invalid.deprecated"],
"settings": { "settings": {
"foreground": "{{colors.outline.default.hex}}" "foreground": "{{colors.outline.default.hex}}"
} }
}, },
{ {
"scope": ["markup.heading"], "scope": [
"keyword"
],
"settings": { "settings": {
"foreground": "{{colors.primary.default.hex}}", "foreground": "{{dank16.color5.default.hex}}"
"fontStyle": "bold"
} }
}, },
{ {
"scope": ["markup.bold"], "scope": [
"string"
],
"settings": { "settings": {
"foreground": "{{colors.tertiary.default.hex}}", "foreground": "{{dank16.color2.default.hex}}"
"fontStyle": "bold"
} }
}, },
{ {
"scope": ["markup.italic"], "scope": [
"constant",
"number"
],
"settings": { "settings": {
"foreground": "{{colors.primary.default.hex}}", "foreground": "{{dank16.color12.default.hex}}"
"fontStyle": "italic"
} }
}, },
{ {
"scope": ["markup.underline"], "scope": [
"settings": { "variable"
"fontStyle": "underline" ],
}
},
{
"scope": ["markup.quote"],
"settings": {
"foreground": "{{colors.secondary.default.hex}}"
}
},
{
"scope": ["markup.list"],
"settings": { "settings": {
"foreground": "{{colors.on_surface.default.hex}}" "foreground": "{{colors.on_surface.default.hex}}"
} }
}, },
{ {
"scope": ["markup.raw", "markup.inline.raw"], "scope": [
"entity.name.function"
],
"settings": {
"foreground": "{{dank16.color4.default.hex}}"
}
},
{
"scope": [
"entity.name.class",
"support.type"
],
"settings": { "settings": {
"foreground": "{{colors.secondary.default.hex}}" "foreground": "{{colors.secondary.default.hex}}"
} }
}, },
{ {
"scope": ["comment", "punctuation.definition.comment"], "scope": [
"invalid"
],
"settings": { "settings": {
"foreground": "{{dank16.color8.hex}}" "foreground": "{{colors.error.default.hex}}"
} }
}, },
{ {
"scope": "keyword", "scope": [
"markup.heading"
],
"settings": { "settings": {
"foreground": "{{dank16.color5.hex}}" "foreground": "{{colors.primary.default.hex}}",
} "fontStyle": "bold"
},
{
"scope": "storage.type",
"settings": {
"foreground": "{{dank16.color13.hex}}"
}
},
{
"scope": "storage.modifier",
"settings": {
"foreground": "{{dank16.color5.hex}}"
}
},
{
"scope": "variable",
"settings": {
"foreground": "{{dank16.color15.hex}}"
}
},
{
"scope": "variable.parameter",
"settings": {
"foreground": "{{dank16.color7.hex}}"
}
},
{
"scope": ["meta.object-literal.key", "meta.property.object", "variable.other.property"],
"settings": {
"foreground": "{{dank16.color4.hex}}"
}
},
{
"scope": "constant.other.symbol",
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": ["constant.numeric", "constant.language"],
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": "constant.character",
"settings": {
"foreground": "{{dank16.color3.hex}}"
}
},
{
"scope": ["entity.name.type", "entity.name.class"],
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": "support.type",
"settings": {
"foreground": "{{dank16.color13.hex}}"
}
},
{
"scope": ["entity.name.function", "support.function"],
"settings": {
"foreground": "{{dank16.color2.hex}}"
}
},
{
"scope": ["support.class", "support.variable"],
"settings": {
"foreground": "{{dank16.color15.hex}}"
}
},
{
"scope": "variable.language",
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": "entity.name.tag.yaml",
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": ["string.unquoted.plain.out.yaml", "string.unquoted.yaml"],
"settings": {
"foreground": "{{dank16.color15.hex}}"
}
},
{
"scope": "string",
"settings": {
"foreground": "{{dank16.color3.hex}}"
} }
} }
], ],
"semanticHighlighting": true,
"semanticTokenColors": { "semanticTokenColors": {
"variable": { "variable": {
"foreground": "{{dank16.color15.hex}}" "foreground": "{{colors.on_surface.default.hex}}"
},
"variable.readonly": {
"foreground": "{{dank16.color12.hex}}"
},
"property": {
"foreground": "{{dank16.color4.hex}}"
},
"function": {
"foreground": "{{dank16.color2.hex}}"
},
"method": {
"foreground": "{{dank16.color2.hex}}"
},
"type": {
"foreground": "{{dank16.color12.hex}}"
},
"class": {
"foreground": "{{dank16.color12.hex}}"
},
"typeParameter": {
"foreground": "{{dank16.color13.hex}}"
},
"enumMember": {
"foreground": "{{dank16.color12.hex}}"
},
"string": {
"foreground": "{{dank16.color3.hex}}"
},
"number": {
"foreground": "{{dank16.color12.hex}}"
},
"comment": {
"foreground": "{{dank16.color8.hex}}"
},
"keyword": {
"foreground": "{{dank16.color5.hex}}"
},
"operator": {
"foreground": "{{dank16.color15.hex}}"
}, },
"parameter": { "parameter": {
"foreground": "{{dank16.color7.hex}}" "foreground": "{{colors.on_surface.default.hex}}"
}, },
"namespace": { "property": {
"foreground": "{{dank16.color15.hex}}" "foreground": "{{dank16.color4.default.hex}}"
},
"function": {
"foreground": "{{dank16.color4.default.hex}}"
},
"method": {
"foreground": "{{dank16.color4.default.hex}}"
},
"type": {
"foreground": "{{colors.secondary.default.hex}}"
},
"class": {
"foreground": "{{colors.secondary.default.hex}}"
},
"string": {
"foreground": "{{dank16.color2.default.hex}}"
},
"number": {
"foreground": "{{dank16.color12.default.hex}}"
},
"keyword": {
"foreground": "{{dank16.color5.default.hex}}"
},
"comment": {
"foreground": "{{colors.outline.default.hex}}"
} }
} }
} }

View File

@@ -1,35 +1,74 @@
{ {
"$schema": "vscode://schemas/color-theme", "$schema": "vscode://schemas/color-theme",
"name": "Dynamic Base16 DankShell", "name": "Dynamic Base16 DankShell Light",
"semanticHighlighting": true,
"colors": { "colors": {
"foreground": "{{colors.on_surface.light.hex}}",
"selection.background": "{{colors.primary_container.light.hex}}66",
"errorForeground": "{{colors.error.light.hex}}",
"focusBorder": "{{colors.primary.light.hex}}",
"editor.background": "{{colors.background.light.hex}}", "editor.background": "{{colors.background.light.hex}}",
"editor.foreground": "{{colors.on_surface.light.hex}}", "editor.foreground": "{{colors.on_surface.light.hex}}",
"editorLineNumber.foreground": "{{colors.outline.light.hex}}", "editorLineNumber.foreground": "{{colors.outline.light.hex}}",
"editorLineNumber.activeForeground": "{{colors.on_surface.light.hex}}", "editorLineNumber.activeForeground": "{{colors.primary.light.hex}}",
"editorCursor.foreground": "{{colors.primary.light.hex}}", "editorCursor.foreground": "{{colors.primary.light.hex}}",
"editor.selectionBackground": "{{colors.primary_container.light.hex}}", "editor.selectionBackground": "{{colors.primary_container.light.hex}}B3",
"editor.inactiveSelectionBackground": "{{colors.background.light.hex}}", "editor.inactiveSelectionBackground": "{{colors.primary_container.light.hex}}33",
"editor.lineHighlightBackground": "{{colors.background.light.hex}}", "editor.lineHighlightBackground": "{{colors.surface_container.light.hex}}66",
"editorIndentGuide.background": "{{colors.background.light.hex}}", "editor.lineHighlightBorder": "{{colors.outline_variant.light.hex}}18",
"editorIndentGuide.activeBackground": "{{colors.outline.light.hex}}", "editor.wordHighlightBackground": "{{colors.secondary.light.hex}}22",
"editorWhitespace.foreground": "{{colors.outline_variant.light.hex}}", "editor.wordHighlightStrongBackground": "{{colors.tertiary.light.hex}}22",
"editorBracketMatch.background": "{{colors.background.light.hex}}", "editor.findMatchBackground": "{{colors.secondary.light.hex}}33",
"editor.findMatchHighlightBackground": "{{colors.secondary.light.hex}}22",
"editor.findRangeHighlightBackground": "{{colors.surface_container.light.hex}}33",
"editorWhitespace.foreground": "{{colors.outline.light.hex}}66",
"editorIndentGuide.background1": "{{colors.outline.light.hex}}99",
"editorIndentGuide.activeBackground1": "{{colors.primary.light.hex}}CC",
"editorBracketMatch.background": "{{colors.primary_container.light.hex}}33",
"editorBracketMatch.border": "{{colors.primary.light.hex}}", "editorBracketMatch.border": "{{colors.primary.light.hex}}",
"editorGutter.addedBackground": "{{colors.secondary.light.hex}}AA",
"editorGutter.modifiedBackground": "{{colors.tertiary.light.hex}}AA",
"editorGutter.deletedBackground": "{{colors.error.light.hex}}AA",
"editorError.foreground": "{{colors.error.light.hex}}",
"editorWarning.foreground": "{{colors.tertiary.light.hex}}",
"editorInfo.foreground": "{{colors.primary.light.hex}}",
"editorOverviewRuler.border": "{{colors.outline_variant.light.hex}}",
"editorOverviewRuler.errorForeground": "{{colors.error.light.hex}}88",
"editorOverviewRuler.warningForeground": "{{colors.tertiary.light.hex}}88",
"editorOverviewRuler.infoForeground": "{{colors.primary.light.hex}}88",
"editorWidget.background": "{{colors.surface_container.light.hex}}",
"editorWidget.border": "{{colors.outline_variant.light.hex}}",
"editorHoverWidget.background": "{{colors.surface_container_high.light.hex}}",
"editorHoverWidget.border": "{{colors.outline.light.hex}}",
"editorSuggestWidget.background": "{{colors.surface_container.light.hex}}",
"editorSuggestWidget.foreground": "{{colors.on_surface.light.hex}}",
"editorSuggestWidget.border": "{{colors.outline_variant.light.hex}}",
"editorSuggestWidget.selectedBackground": "{{colors.surface_container_high.light.hex}}",
"editorSuggestWidget.highlightForeground": "{{colors.primary.light.hex}}",
"editorGroup.border": "{{colors.outline_variant.light.hex}}",
"editorGroup.dropBackground": "{{colors.primary_container.light.hex}}33",
"editorGroupHeader.tabsBackground": "{{colors.background.light.hex}}",
"editorGroupHeader.noTabsBackground": "{{colors.background.light.hex}}",
"tab.border": "{{colors.outline_variant.light.hex}}",
"tab.activeBackground": "{{colors.surface_container_high.light.hex}}",
"tab.inactiveBackground": "{{colors.surface_container.light.hex}}",
"tab.activeForeground": "{{colors.on_surface.light.hex}}",
"tab.inactiveForeground": "{{colors.outline.light.hex}}",
"tab.activeBorder": "{{colors.primary.light.hex}}",
"tab.unfocusedActiveBorder": "{{colors.outline.light.hex}}",
"activityBar.background": "{{colors.background.light.hex}}", "activityBar.background": "{{colors.background.light.hex}}",
"activityBar.foreground": "{{colors.on_surface.light.hex}}", "activityBar.foreground": "{{colors.on_surface.light.hex}}",
"activityBar.inactiveForeground": "{{colors.outline.light.hex}}",
"activityBar.activeBorder": "{{colors.primary.light.hex}}", "activityBar.activeBorder": "{{colors.primary.light.hex}}",
"activityBar.activeBackground": "{{colors.background.light.hex}}", "activityBar.activeBackground": "{{colors.background.light.hex}}",
"activityBarBadge.background": "{{colors.primary.light.hex}}", "activityBarBadge.background": "{{colors.primary.light.hex}}",
"activityBarBadge.foreground": "{{colors.on_primary.light.hex}}", "activityBarBadge.foreground": "{{colors.on_primary.light.hex}}",
"sideBar.background": "{{colors.surface_container.light.hex}}",
"sideBar.background": "{{colors.background.light.hex}}",
"sideBar.foreground": "{{colors.on_surface.light.hex}}", "sideBar.foreground": "{{colors.on_surface.light.hex}}",
"sideBar.border": "{{colors.background.light.hex}}", "sideBar.border": "{{colors.outline_variant.light.hex}}",
"sideBarTitle.foreground": "{{colors.on_surface.light.hex}}", "sideBarTitle.foreground": "{{colors.on_surface.light.hex}}",
"sideBarSectionHeader.background": "{{colors.background.light.hex}}", "sideBarSectionHeader.background": "{{colors.surface_container_low.light.hex}}",
"sideBarSectionHeader.foreground": "{{colors.on_surface.light.hex}}", "sideBarSectionHeader.foreground": "{{colors.on_surface.light.hex}}",
"list.activeSelectionBackground": "{{colors.primary_container.light.hex}}", "list.activeSelectionBackground": "{{colors.primary_container.light.hex}}",
"list.activeSelectionForeground": "{{colors.on_primary_container.light.hex}}", "list.activeSelectionForeground": "{{colors.on_primary_container.light.hex}}",
"list.inactiveSelectionBackground": "{{colors.surface_container.light.hex}}", "list.inactiveSelectionBackground": "{{colors.surface_container.light.hex}}",
@@ -39,83 +78,64 @@
"list.focusBackground": "{{colors.surface_container_high.light.hex}}", "list.focusBackground": "{{colors.surface_container_high.light.hex}}",
"list.focusForeground": "{{colors.on_surface.light.hex}}", "list.focusForeground": "{{colors.on_surface.light.hex}}",
"list.highlightForeground": "{{colors.primary.light.hex}}", "list.highlightForeground": "{{colors.primary.light.hex}}",
"list.errorForeground": "{{colors.error.light.hex}}",
"statusBar.background": "{{colors.background.light.hex}}", "list.warningForeground": "{{colors.tertiary.light.hex}}",
"statusBar.background": "{{colors.surface_container.light.hex}}",
"statusBar.foreground": "{{colors.on_surface.light.hex}}", "statusBar.foreground": "{{colors.on_surface.light.hex}}",
"statusBar.border": "{{colors.background.light.hex}}", "statusBar.border": "{{colors.outline_variant.light.hex}}",
"statusBar.noFolderBackground": "{{colors.background.light.hex}}", "statusBar.noFolderBackground": "{{colors.surface_container.light.hex}}",
"statusBar.noFolderForeground": "{{colors.on_surface.light.hex}}",
"statusBar.debuggingBackground": "{{colors.error.light.hex}}", "statusBar.debuggingBackground": "{{colors.error.light.hex}}",
"statusBar.debuggingForeground": "{{colors.on_error.light.hex}}", "statusBar.debuggingForeground": "{{colors.on_error.light.hex}}",
"tab.activeBackground": "{{colors.background.light.hex}}",
"tab.inactiveBackground": "{{colors.background.light.hex}}",
"tab.activeForeground": "{{colors.on_surface.light.hex}}",
"tab.inactiveForeground": "{{colors.outline.light.hex}}",
"tab.border": "{{colors.background.light.hex}}",
"tab.activeBorder": "{{colors.primary.light.hex}}",
"tab.unfocusedActiveBorder": "{{colors.outline.light.hex}}",
"editorGroupHeader.tabsBackground": "{{colors.background.light.hex}}",
"editorGroupHeader.noTabsBackground": "{{colors.background.light.hex}}",
"titleBar.activeBackground": "{{colors.background.light.hex}}", "titleBar.activeBackground": "{{colors.background.light.hex}}",
"titleBar.activeForeground": "{{colors.on_surface.light.hex}}", "titleBar.activeForeground": "{{colors.on_surface.light.hex}}",
"titleBar.inactiveBackground": "{{colors.background.light.hex}}", "titleBar.inactiveBackground": "{{colors.background.light.hex}}",
"titleBar.inactiveForeground": "{{colors.outline.light.hex}}", "titleBar.inactiveForeground": "{{colors.outline.light.hex}}",
"titleBar.border": "{{colors.background.light.hex}}", "titleBar.border": "{{colors.outline_variant.light.hex}}",
"input.background": "{{colors.surface_container_low.light.hex}}",
"input.background": "{{colors.background.light.hex}}",
"input.foreground": "{{colors.on_surface.light.hex}}", "input.foreground": "{{colors.on_surface.light.hex}}",
"input.border": "{{colors.outline.light.hex}}", "input.border": "{{colors.outline_variant.light.hex}}",
"input.placeholderForeground": "{{colors.outline.light.hex}}", "input.placeholderForeground": "{{colors.outline.light.hex}}",
"inputOption.activeBorder": "{{colors.primary.light.hex}}", "inputOption.activeBorder": "{{colors.primary.light.hex}}",
"inputValidation.errorBackground": "{{colors.error.light.hex}}", "inputValidation.errorBackground": "{{colors.error_container.light.hex}}",
"inputValidation.errorBorder": "{{colors.error.light.hex}}", "inputValidation.errorBorder": "{{colors.error.light.hex}}",
"dropdown.background": "{{colors.surface_container_low.light.hex}}",
"dropdown.background": "{{colors.background.light.hex}}",
"dropdown.foreground": "{{colors.on_surface.light.hex}}", "dropdown.foreground": "{{colors.on_surface.light.hex}}",
"dropdown.border": "{{colors.outline.light.hex}}", "dropdown.border": "{{colors.outline_variant.light.hex}}",
"quickInput.background": "{{colors.surface_container.light.hex}}",
"quickInput.background": "{{colors.background.light.hex}}",
"quickInput.foreground": "{{colors.on_surface.light.hex}}", "quickInput.foreground": "{{colors.on_surface.light.hex}}",
"quickInputList.focusBackground": "{{colors.surface_container_high.light.hex}}", "quickInputList.focusBackground": "{{colors.surface_container_high.light.hex}}",
"quickInputList.focusForeground": "{{colors.on_surface.light.hex}}", "quickInputList.focusForeground": "{{colors.on_surface.light.hex}}",
"button.background": "{{colors.primary.light.hex}}", "button.background": "{{colors.primary.light.hex}}",
"button.foreground": "{{colors.on_primary.light.hex}}", "button.foreground": "{{colors.on_primary.light.hex}}",
"button.hoverBackground": "{{colors.primary_container.light.hex}}", "button.hoverBackground": "{{colors.primary_container.light.hex}}",
"focusBorder": "{{colors.primary.light.hex}}",
"badge.background": "{{colors.secondary.light.hex}}", "badge.background": "{{colors.secondary.light.hex}}",
"badge.foreground": "{{colors.on_secondary.light.hex}}", "badge.foreground": "{{colors.on_secondary.light.hex}}",
"panel.background": "{{colors.surface_container.light.hex}}",
"panel.background": "{{colors.background.light.hex}}", "panel.border": "{{colors.outline_variant.light.hex}}",
"panel.border": "{{colors.primary.light.hex}}",
"panelTitle.activeBorder": "{{colors.primary.light.hex}}", "panelTitle.activeBorder": "{{colors.primary.light.hex}}",
"panelTitle.activeForeground": "{{colors.on_surface.light.hex}}", "panelTitle.activeForeground": "{{colors.on_surface.light.hex}}",
"panelTitle.inactiveForeground": "{{colors.outline.light.hex}}", "panelTitle.inactiveForeground": "{{colors.outline.light.hex}}",
"terminal.background": "{{colors.background.light.hex}}", "terminal.background": "{{colors.background.light.hex}}",
"terminal.foreground": "{{colors.on_surface.light.hex}}", "terminal.foreground": "{{colors.on_surface.light.hex}}",
"terminal.ansiBlack": "{{dank16.color0.hex}}", "terminal.ansiBlack": "{{dank16.color0.light.hex}}",
"terminal.ansiRed": "{{dank16.color1.hex}}", "terminal.ansiRed": "{{dank16.color1.light.hex}}",
"terminal.ansiGreen": "{{dank16.color2.hex}}", "terminal.ansiGreen": "{{dank16.color2.light.hex}}",
"terminal.ansiYellow": "{{dank16.color3.hex}}", "terminal.ansiYellow": "{{dank16.color3.light.hex}}",
"terminal.ansiBlue": "{{dank16.color4.hex}}", "terminal.ansiBlue": "{{dank16.color4.light.hex}}",
"terminal.ansiMagenta": "{{dank16.color5.hex}}", "terminal.ansiMagenta": "{{dank16.color5.light.hex}}",
"terminal.ansiCyan": "{{dank16.color6.hex}}", "terminal.ansiCyan": "{{dank16.color6.light.hex}}",
"terminal.ansiWhite": "{{dank16.color7.hex}}", "terminal.ansiWhite": "{{dank16.color7.light.hex}}",
"terminal.ansiBrightBlack": "{{dank16.color8.hex}}", "terminal.ansiBrightBlack": "{{dank16.color8.light.hex}}",
"terminal.ansiBrightRed": "{{dank16.color9.hex}}", "terminal.ansiBrightRed": "{{dank16.color9.light.hex}}",
"terminal.ansiBrightGreen": "{{dank16.color10.hex}}", "terminal.ansiBrightGreen": "{{dank16.color10.light.hex}}",
"terminal.ansiBrightYellow": "{{dank16.color11.hex}}", "terminal.ansiBrightYellow": "{{dank16.color11.light.hex}}",
"terminal.ansiBrightBlue": "{{dank16.color12.hex}}", "terminal.ansiBrightBlue": "{{dank16.color12.light.hex}}",
"terminal.ansiBrightMagenta": "{{dank16.color13.hex}}", "terminal.ansiBrightMagenta": "{{dank16.color13.light.hex}}",
"terminal.ansiBrightCyan": "{{dank16.color14.hex}}", "terminal.ansiBrightCyan": "{{dank16.color14.light.hex}}",
"terminal.ansiBrightWhite": "{{dank16.color15.hex}}", "terminal.ansiBrightWhite": "{{dank16.color15.light.hex}}",
"gitDecoration.modifiedResourceForeground": "{{colors.primary.light.hex}}", "gitDecoration.modifiedResourceForeground": "{{colors.primary.light.hex}}",
"gitDecoration.addedResourceForeground": "{{colors.primary.light.hex}}", "gitDecoration.addedResourceForeground": "{{colors.secondary.light.hex}}",
"gitDecoration.stageModifiedResourceForeground": "{{colors.primary.light.hex}}", "gitDecoration.stageModifiedResourceForeground": "{{colors.primary.light.hex}}",
"gitDecoration.stageDeletedResourceForeground": "{{colors.error.light.hex}}", "gitDecoration.stageDeletedResourceForeground": "{{colors.error.light.hex}}",
"gitDecoration.deletedResourceForeground": "{{colors.error.light.hex}}", "gitDecoration.deletedResourceForeground": "{{colors.error.light.hex}}",
@@ -123,309 +143,276 @@
"gitDecoration.ignoredResourceForeground": "{{colors.outline.light.hex}}", "gitDecoration.ignoredResourceForeground": "{{colors.outline.light.hex}}",
"gitDecoration.conflictingResourceForeground": "{{colors.error_container.light.hex}}", "gitDecoration.conflictingResourceForeground": "{{colors.error_container.light.hex}}",
"gitDecoration.submoduleResourceForeground": "{{colors.primary.light.hex}}", "gitDecoration.submoduleResourceForeground": "{{colors.primary.light.hex}}",
"editorWidget.background": "{{colors.background.light.hex}}",
"editorWidget.border": "{{colors.outline.light.hex}}",
"editorSuggestWidget.background": "{{colors.background.light.hex}}",
"editorSuggestWidget.border": "{{colors.outline.light.hex}}",
"editorSuggestWidget.selectedBackground": "{{colors.surface_container_high.light.hex}}",
"editorSuggestWidget.highlightForeground": "{{colors.primary.light.hex}}",
"peekView.border": "{{colors.primary.light.hex}}", "peekView.border": "{{colors.primary.light.hex}}",
"peekViewEditor.background": "{{colors.background.light.hex}}", "peekViewEditor.background": "{{colors.surface_container_high.light.hex}}",
"peekViewResult.background": "{{colors.background.light.hex}}", "peekViewResult.background": "{{colors.surface_container.light.hex}}",
"peekViewTitle.background": "{{colors.background.light.hex}}", "peekViewTitle.background": "{{colors.surface_container_low.light.hex}}",
"notificationCenter.border": "{{colors.outline_variant.light.hex}}",
"notificationCenter.border": "{{colors.outline.light.hex}}", "notifications.background": "{{colors.surface_container.light.hex}}",
"notifications.background": "{{colors.background.light.hex}}", "notifications.border": "{{colors.outline_variant.light.hex}}",
"notifications.border": "{{colors.outline.light.hex}}", "breadcrumb.background": "{{colors.surface_container_high.light.hex}}",
"breadcrumb.foreground": "{{colors.outline.light.hex}}", "breadcrumb.foreground": "{{colors.outline.light.hex}}",
"breadcrumb.focusForeground": "{{colors.on_surface.light.hex}}", "breadcrumb.focusForeground": "{{colors.on_surface.light.hex}}",
"breadcrumb.activeSelectionForeground": "{{colors.primary.light.hex}}", "breadcrumb.activeSelectionForeground": "{{colors.primary.light.hex}}",
"scrollbarSlider.background": "{{colors.outline.light.hex}}40", "scrollbarSlider.background": "{{colors.outline.light.hex}}40",
"scrollbarSlider.hoverBackground": "{{colors.outline.light.hex}}60", "scrollbarSlider.hoverBackground": "{{colors.outline.light.hex}}60",
"scrollbarSlider.activeBackground": "{{colors.outline.light.hex}}80", "scrollbarSlider.activeBackground": "{{colors.outline.light.hex}}80",
"menubar.selectionBackground": "{{colors.primary_container.light.hex}}",
"editorError.foreground": "{{colors.error.light.hex}}", "menubar.selectionForeground": "{{colors.on_primary_container.light.hex}}",
"editorWarning.foreground": "{{colors.tertiary.light.hex}}", "menu.background": "{{colors.surface_container.light.hex}}",
"editorInfo.foreground": "{{colors.primary.light.hex}}",
"editorGutter.addedBackground": "{{colors.secondary.light.hex}}",
"editorGutter.modifiedBackground": "{{colors.tertiary.light.hex}}",
"editorGutter.deletedBackground": "{{colors.error.light.hex}}",
"diffEditor.insertedTextBackground": "{{colors.secondary.light.hex}}20",
"diffEditor.removedTextBackground": "{{colors.error.light.hex}}20",
"merge.currentHeaderBackground": "{{colors.primary.light.hex}}40",
"merge.incomingHeaderBackground": "{{colors.secondary.light.hex}}40",
"menubar.selectionBackground": "{{colors.surface_container.light.hex}}",
"menu.background": "{{colors.background.light.hex}}",
"menu.foreground": "{{colors.on_surface.light.hex}}", "menu.foreground": "{{colors.on_surface.light.hex}}",
"menu.selectionBackground": "{{colors.surface_container_high.light.hex}}", "menu.selectionBackground": "{{colors.primary_container.light.hex}}",
"menu.selectionForeground": "{{colors.on_surface.light.hex}}", "menu.selectionForeground": "{{colors.on_primary_container.light.hex}}",
"debugToolBar.background": "{{colors.surface_container.light.hex}}",
"debugToolBar.background": "{{colors.background.light.hex}}", "debugExceptionWidget.background": "{{colors.surface_container.light.hex}}",
"debugExceptionWidget.background": "{{colors.background.light.hex}}",
"debugExceptionWidget.border": "{{colors.error.light.hex}}" "debugExceptionWidget.border": "{{colors.error.light.hex}}"
}, },
"tokenColors": [ "tokenColors": [
{ {
"scope": ["variable", "meta.object-literal.key"], "name": "Comments",
"settings": { "scope": [
"foreground": "{{colors.on_surface.light.hex}}" "comment",
} "punctuation.definition.comment",
}, "string.comment"
{ ],
"scope": ["string", "constant.other.symbol"],
"settings": {
"foreground": "{{colors.secondary.light.hex}}"
}
},
{
"scope": ["constant.numeric", "constant.language", "constant.character"],
"settings": {
"foreground": "{{colors.tertiary.light.hex}}"
}
},
{
"scope": ["entity.name.type", "support.type", "entity.name.class"],
"settings": {
"foreground": "{{colors.tertiary.light.hex}}"
}
},
{
"scope": ["entity.name.function", "support.function"],
"settings": {
"foreground": "{{colors.primary.light.hex}}"
}
},
{
"scope": ["support.class", "support.variable", "variable.language"],
"settings": {
"foreground": "{{colors.secondary.light.hex}}"
}
},
{
"scope": ["invalid"],
"settings": {
"foreground": "{{colors.error.light.hex}}"
}
},
{
"scope": ["invalid.deprecated"],
"settings": { "settings": {
"foreground": "{{colors.outline.light.hex}}" "foreground": "{{colors.outline.light.hex}}"
} }
}, },
{ {
"scope": ["markup.heading"], "name": "Keywords and storage",
"scope": [
"keyword",
"punctuation.definition.keyword",
"storage",
"storage.type"
],
"settings": {
"foreground": "{{dank16.color5.light.hex}}"
}
},
{
"name": "Strings",
"scope": [
"string",
"string punctuation.section.embedded source"
],
"settings": {
"foreground": "{{dank16.color2.light.hex}}"
}
},
{
"name": "Constants and numbers",
"scope": [
"constant.numeric",
"constant.language",
"constant.other",
"constant.character"
],
"settings": {
"foreground": "{{dank16.color0.light.hex}}"
}
},
{
"name": "Variables (plain)",
"scope": [
"variable",
"variable.other"
],
"settings": {
"foreground": "{{colors.on_surface.light.hex}}"
}
},
{
"name": "Parameters",
"scope": [
"variable.parameter",
"variable.parameter.function"
],
"settings": {
"foreground": "{{colors.on_surface.light.hex}}"
}
},
{
"name": "Object properties and keys",
"scope": [
"meta.object-literal.key",
"meta.property.object",
"variable.other.property",
"entity.name.tag.yaml"
],
"settings": {
"foreground": "{{dank16.color4.light.hex}}"
}
},
{
"name": "Functions",
"scope": [
"entity.name.function",
"support.function"
],
"settings": {
"foreground": "{{dank16.color4.light.hex}}"
}
},
{
"name": "Types and classes",
"scope": [
"entity.name.type",
"entity.name.class",
"support.type"
],
"settings": {
"foreground": "{{colors.secondary.light.hex}}"
}
},
{
"name": "Language builtins and special variables",
"scope": [
"support.class",
"support.variable",
"variable.language",
"support.constant"
],
"settings": {
"foreground": "{{dank16.color4.light.hex}}"
}
},
{
"name": "Invalid",
"scope": [
"invalid"
],
"settings": {
"foreground": "{{colors.error.light.hex}}"
}
},
{
"name": "Invalid deprecated",
"scope": [
"invalid.deprecated"
],
"settings": {
"foreground": "{{colors.outline.light.hex}}"
}
},
{
"name": "Headings",
"scope": [
"markup.heading",
"markup.heading entity.name"
],
"settings": { "settings": {
"foreground": "{{colors.primary.light.hex}}", "foreground": "{{colors.primary.light.hex}}",
"fontStyle": "bold" "fontStyle": "bold"
} }
}, },
{ {
"scope": ["markup.bold"], "name": "Bold",
"scope": [
"markup.bold"
],
"settings": { "settings": {
"foreground": "{{colors.tertiary.light.hex}}", "foreground": "{{colors.tertiary.light.hex}}",
"fontStyle": "bold" "fontStyle": "bold"
} }
}, },
{ {
"scope": ["markup.italic"], "name": "Italic",
"scope": [
"markup.italic"
],
"settings": { "settings": {
"foreground": "{{colors.primary.light.hex}}", "foreground": "{{colors.primary.light.hex}}",
"fontStyle": "italic" "fontStyle": "italic"
} }
}, },
{ {
"scope": ["markup.underline"], "name": "Underline",
"scope": [
"markup.underline"
],
"settings": { "settings": {
"fontStyle": "underline" "fontStyle": "underline"
} }
}, },
{ {
"scope": ["markup.quote"], "name": "Quotes",
"scope": [
"markup.quote"
],
"settings": { "settings": {
"foreground": "{{colors.secondary.light.hex}}" "foreground": "{{colors.outline.light.hex}}"
} }
}, },
{ {
"scope": ["markup.list"], "name": "Lists",
"scope": [
"markup.list"
],
"settings": { "settings": {
"foreground": "{{colors.on_surface.light.hex}}" "foreground": "{{colors.on_surface.light.hex}}"
} }
}, },
{ {
"scope": ["markup.raw", "markup.inline.raw"], "name": "Inline code in prose",
"scope": [
"markup.raw",
"markup.inline.raw"
],
"settings": { "settings": {
"foreground": "{{colors.secondary.light.hex}}" "foreground": "{{dank16.color4.light.hex}}"
}
},
{
"scope": ["comment", "punctuation.definition.comment"],
"settings": {
"foreground": "{{dank16.color8.hex}}"
}
},
{
"scope": "keyword",
"settings": {
"foreground": "{{dank16.color5.hex}}"
}
},
{
"scope": "storage.type",
"settings": {
"foreground": "{{dank16.color13.hex}}"
}
},
{
"scope": "storage.modifier",
"settings": {
"foreground": "{{dank16.color5.hex}}"
}
},
{
"scope": "variable",
"settings": {
"foreground": "{{dank16.color15.hex}}"
}
},
{
"scope": "variable.parameter",
"settings": {
"foreground": "{{dank16.color7.hex}}"
}
},
{
"scope": ["meta.object-literal.key", "meta.property.object", "variable.other.property"],
"settings": {
"foreground": "{{dank16.color4.hex}}"
}
},
{
"scope": "constant.other.symbol",
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": ["constant.numeric", "constant.language"],
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": "constant.character",
"settings": {
"foreground": "{{dank16.color3.hex}}"
}
},
{
"scope": ["entity.name.type", "entity.name.class"],
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": "support.type",
"settings": {
"foreground": "{{dank16.color13.hex}}"
}
},
{
"scope": ["entity.name.function", "support.function"],
"settings": {
"foreground": "{{dank16.color2.hex}}"
}
},
{
"scope": ["support.class", "support.variable"],
"settings": {
"foreground": "{{dank16.color15.hex}}"
}
},
{
"scope": "variable.language",
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": "entity.name.tag.yaml",
"settings": {
"foreground": "{{dank16.color12.hex}}"
}
},
{
"scope": ["string.unquoted.plain.out.yaml", "string.unquoted.yaml"],
"settings": {
"foreground": "{{dank16.color15.hex}}"
}
},
{
"scope": "string",
"settings": {
"foreground": "{{dank16.color3.hex}}"
} }
} }
], ],
"semanticHighlighting": true,
"semanticTokenColors": { "semanticTokenColors": {
"variable": { "variable": {
"foreground": "{{dank16.color15.hex}}" "foreground": "{{colors.on_surface.light.hex}}"
}, },
"variable.readonly": { "variable.readonly": {
"foreground": "{{dank16.color12.hex}}" "foreground": "{{dank16.color1.light.hex}}"
},
"property": {
"foreground": "{{dank16.color4.hex}}"
},
"function": {
"foreground": "{{dank16.color2.hex}}"
},
"method": {
"foreground": "{{dank16.color2.hex}}"
},
"type": {
"foreground": "{{dank16.color12.hex}}"
},
"class": {
"foreground": "{{dank16.color12.hex}}"
},
"typeParameter": {
"foreground": "{{dank16.color13.hex}}"
},
"enumMember": {
"foreground": "{{dank16.color12.hex}}"
},
"string": {
"foreground": "{{dank16.color3.hex}}"
},
"number": {
"foreground": "{{dank16.color12.hex}}"
},
"comment": {
"foreground": "{{dank16.color8.hex}}"
},
"keyword": {
"foreground": "{{dank16.color5.hex}}"
},
"operator": {
"foreground": "{{dank16.color15.hex}}"
}, },
"parameter": { "parameter": {
"foreground": "{{dank16.color7.hex}}" "foreground": "{{colors.on_surface.light.hex}}"
},
"property": {
"foreground": "{{dank16.color4.light.hex}}"
},
"function": {
"foreground": "{{dank16.color4.light.hex}}"
},
"method": {
"foreground": "{{dank16.color4.light.hex}}"
},
"type": {
"foreground": "{{colors.secondary.light.hex}}"
},
"class": {
"foreground": "{{colors.secondary.light.hex}}"
},
"typeParameter": {
"foreground": "{{colors.tertiary.light.hex}}"
},
"enumMember": {
"foreground": "{{dank16.color1.light.hex}}"
},
"string": {
"foreground": "{{dank16.color2.light.hex}}"
},
"number": {
"foreground": "{{dank16.color1.light.hex}}"
},
"comment": {
"foreground": "{{colors.outline.light.hex}}"
},
"keyword": {
"foreground": "{{dank16.color5.light.hex}}"
},
"operator": {
"foreground": "{{colors.on_surface.light.hex}}"
}, },
"namespace": { "namespace": {
"foreground": "{{dank16.color15.hex}}" "foreground": "{{colors.on_surface.light.hex}}"
} }
} }
} }

View File

@@ -1,315 +0,0 @@
{
"$schema": "vscode://schemas/color-theme",
"name": "Dynamic Base16 DankShell",
"colors": {
"editor.background": "{{colors.background.default.hex}}",
"editor.foreground": "{{colors.on_surface.default.hex}}",
"editorLineNumber.foreground": "{{colors.outline.default.hex}}",
"editorLineNumber.activeForeground": "{{colors.on_surface.default.hex}}",
"editorCursor.foreground": "{{colors.primary.default.hex}}",
"editor.selectionBackground": "{{colors.primary_container.default.hex}}",
"editor.inactiveSelectionBackground": "{{colors.background.default.hex}}",
"editor.lineHighlightBackground": "{{colors.background.default.hex}}",
"editorIndentGuide.background": "{{colors.background.default.hex}}",
"editorIndentGuide.activeBackground": "{{colors.outline.default.hex}}",
"editorWhitespace.foreground": "{{colors.outline_variant.default.hex}}",
"editorBracketMatch.background": "{{colors.background.default.hex}}",
"editorBracketMatch.border": "{{colors.primary.default.hex}}",
"activityBar.background": "{{colors.background.default.hex}}",
"activityBar.foreground": "{{colors.on_surface.default.hex}}",
"activityBar.activeBorder": "{{colors.primary.default.hex}}",
"activityBar.activeBackground": "{{colors.background.default.hex}}",
"activityBarBadge.background": "{{colors.primary.default.hex}}",
"activityBarBadge.foreground": "{{colors.on_primary.default.hex}}",
"sideBar.background": "{{colors.background.default.hex}}",
"sideBar.foreground": "{{colors.on_surface.default.hex}}",
"sideBar.border": "{{colors.background.default.hex}}",
"sideBarTitle.foreground": "{{colors.on_surface.default.hex}}",
"sideBarSectionHeader.background": "{{colors.background.default.hex}}",
"sideBarSectionHeader.foreground": "{{colors.on_surface.default.hex}}",
"list.activeSelectionBackground": "{{colors.primary_container.default.hex}}",
"list.activeSelectionForeground": "{{colors.on_primary_container.default.hex}}",
"list.inactiveSelectionBackground": "{{colors.surface_container.default.hex}}",
"list.inactiveSelectionForeground": "{{colors.on_surface.default.hex}}",
"list.hoverBackground": "{{colors.surface_container.default.hex}}",
"list.hoverForeground": "{{colors.on_surface.default.hex}}",
"list.focusBackground": "{{colors.surface_container_high.default.hex}}",
"list.focusForeground": "{{colors.on_surface.default.hex}}",
"list.highlightForeground": "{{colors.primary.default.hex}}",
"statusBar.background": "{{colors.background.default.hex}}",
"statusBar.foreground": "{{colors.on_surface.default.hex}}",
"statusBar.border": "{{colors.background.default.hex}}",
"statusBar.noFolderBackground": "{{colors.background.default.hex}}",
"statusBar.debuggingBackground": "{{colors.error.default.hex}}",
"statusBar.debuggingForeground": "{{colors.on_error.default.hex}}",
"tab.activeBackground": "{{colors.background.default.hex}}",
"tab.inactiveBackground": "{{colors.background.default.hex}}",
"tab.activeForeground": "{{colors.on_surface.default.hex}}",
"tab.inactiveForeground": "{{colors.outline.default.hex}}",
"tab.border": "{{colors.background.default.hex}}",
"tab.activeBorder": "{{colors.primary.default.hex}}",
"tab.unfocusedActiveBorder": "{{colors.outline.default.hex}}",
"editorGroupHeader.tabsBackground": "{{colors.background.default.hex}}",
"editorGroupHeader.noTabsBackground": "{{colors.background.default.hex}}",
"titleBar.activeBackground": "{{colors.background.default.hex}}",
"titleBar.activeForeground": "{{colors.on_surface.default.hex}}",
"titleBar.inactiveBackground": "{{colors.background.default.hex}}",
"titleBar.inactiveForeground": "{{colors.outline.default.hex}}",
"titleBar.border": "{{colors.background.default.hex}}",
"input.background": "{{colors.background.default.hex}}",
"input.foreground": "{{colors.on_surface.default.hex}}",
"input.border": "{{colors.outline.default.hex}}",
"input.placeholderForeground": "{{colors.outline.default.hex}}",
"inputOption.activeBorder": "{{colors.primary.default.hex}}",
"inputValidation.errorBackground": "{{colors.error.default.hex}}",
"inputValidation.errorBorder": "{{colors.error.default.hex}}",
"dropdown.background": "{{colors.background.default.hex}}",
"dropdown.foreground": "{{colors.on_surface.default.hex}}",
"dropdown.border": "{{colors.outline.default.hex}}",
"quickInput.background": "{{colors.background.default.hex}}",
"quickInput.foreground": "{{colors.on_surface.default.hex}}",
"quickInputList.focusBackground": "{{colors.surface_container_high.default.hex}}",
"quickInputList.focusForeground": "{{colors.on_surface.default.hex}}",
"button.background": "{{colors.primary.default.hex}}",
"button.foreground": "{{colors.on_primary.default.hex}}",
"button.hoverBackground": "{{colors.primary_container.default.hex}}",
"focusBorder": "{{colors.primary.default.hex}}",
"badge.background": "{{colors.secondary.default.hex}}",
"badge.foreground": "{{colors.on_secondary.default.hex}}",
"panel.background": "{{colors.background.default.hex}}",
"panel.border": "{{colors.primary.default.hex}}",
"panelTitle.activeBorder": "{{colors.primary.default.hex}}",
"panelTitle.activeForeground": "{{colors.on_surface.default.hex}}",
"panelTitle.inactiveForeground": "{{colors.outline.default.hex}}",
"terminal.background": "{{colors.background.default.hex}}",
"terminal.foreground": "{{colors.on_surface.default.hex}}",
"gitDecoration.modifiedResourceForeground": "{{colors.primary.default.hex}}",
"gitDecoration.addedResourceForeground": "{{colors.primary.default.hex}}",
"gitDecoration.stageModifiedResourceForeground": "{{colors.primary.default.hex}}",
"gitDecoration.stageDeletedResourceForeground": "{{colors.error.default.hex}}",
"gitDecoration.deletedResourceForeground": "{{colors.error.default.hex}}",
"gitDecoration.untrackedResourceForeground": "{{colors.secondary.default.hex}}",
"gitDecoration.ignoredResourceForeground": "{{colors.outline.default.hex}}",
"gitDecoration.conflictingResourceForeground": "{{colors.error_container.default.hex}}",
"gitDecoration.submoduleResourceForeground": "{{colors.primary.default.hex}}",
"editorWidget.background": "{{colors.background.default.hex}}",
"editorWidget.border": "{{colors.outline.default.hex}}",
"editorSuggestWidget.background": "{{colors.background.default.hex}}",
"editorSuggestWidget.border": "{{colors.outline.default.hex}}",
"editorSuggestWidget.selectedBackground": "{{colors.surface_container_high.default.hex}}",
"editorSuggestWidget.highlightForeground": "{{colors.primary.default.hex}}",
"peekView.border": "{{colors.primary.default.hex}}",
"peekViewEditor.background": "{{colors.background.default.hex}}",
"peekViewResult.background": "{{colors.background.default.hex}}",
"peekViewTitle.background": "{{colors.background.default.hex}}",
"notificationCenter.border": "{{colors.outline.default.hex}}",
"notifications.background": "{{colors.background.default.hex}}",
"notifications.border": "{{colors.outline.default.hex}}",
"breadcrumb.foreground": "{{colors.outline.default.hex}}",
"breadcrumb.focusForeground": "{{colors.on_surface.default.hex}}",
"breadcrumb.activeSelectionForeground": "{{colors.primary.default.hex}}",
"scrollbarSlider.background": "{{colors.outline.default.hex}}40",
"scrollbarSlider.hoverBackground": "{{colors.outline.default.hex}}60",
"scrollbarSlider.activeBackground": "{{colors.outline.default.hex}}80",
"editorError.foreground": "{{colors.error.default.hex}}",
"editorWarning.foreground": "{{colors.tertiary.default.hex}}",
"editorInfo.foreground": "{{colors.primary.default.hex}}",
"editorGutter.addedBackground": "{{colors.secondary.default.hex}}",
"editorGutter.modifiedBackground": "{{colors.tertiary.default.hex}}",
"editorGutter.deletedBackground": "{{colors.error.default.hex}}",
"diffEditor.insertedTextBackground": "{{colors.secondary.default.hex}}20",
"diffEditor.removedTextBackground": "{{colors.error.default.hex}}20",
"merge.currentHeaderBackground": "{{colors.primary.default.hex}}40",
"merge.incomingHeaderBackground": "{{colors.secondary.default.hex}}40",
"menubar.selectionBackground": "{{colors.surface_container.default.hex}}",
"menu.background": "{{colors.background.default.hex}}",
"menu.foreground": "{{colors.on_surface.default.hex}}",
"menu.selectionBackground": "{{colors.surface_container_high.default.hex}}",
"menu.selectionForeground": "{{colors.on_surface.default.hex}}",
"debugToolBar.background": "{{colors.background.default.hex}}",
"debugExceptionWidget.background": "{{colors.background.default.hex}}",
"debugExceptionWidget.border": "{{colors.error.default.hex}}"
},
"tokenColors": [
{
"scope": ["comment", "punctuation.definition.comment"],
"settings": {
"foreground": "{{colors.outline.default.hex}}",
"fontStyle": "italic"
}
},
{
"scope": ["keyword", "storage.type", "storage.modifier"],
"settings": {
"foreground": "{{colors.primary.default.hex}}"
}
},
{
"scope": ["variable", "meta.object-literal.key"],
"settings": {
"foreground": "{{colors.on_surface.default.hex}}"
}
},
{
"scope": ["string", "constant.other.symbol"],
"settings": {
"foreground": "{{colors.secondary.default.hex}}"
}
},
{
"scope": ["constant.numeric", "constant.language", "constant.character"],
"settings": {
"foreground": "{{colors.tertiary.default.hex}}"
}
},
{
"scope": ["entity.name.type", "support.type", "entity.name.class"],
"settings": {
"foreground": "{{colors.tertiary.default.hex}}"
}
},
{
"scope": ["entity.name.function", "support.function"],
"settings": {
"foreground": "{{colors.primary.default.hex}}"
}
},
{
"scope": ["support.class", "support.variable", "variable.language"],
"settings": {
"foreground": "{{colors.secondary.default.hex}}"
}
},
{
"scope": ["invalid"],
"settings": {
"foreground": "{{colors.error.default.hex}}"
}
},
{
"scope": ["invalid.deprecated"],
"settings": {
"foreground": "{{colors.outline.default.hex}}"
}
},
{
"scope": ["markup.heading"],
"settings": {
"foreground": "{{colors.primary.default.hex}}",
"fontStyle": "bold"
}
},
{
"scope": ["markup.bold"],
"settings": {
"foreground": "{{colors.tertiary.default.hex}}",
"fontStyle": "bold"
}
},
{
"scope": ["markup.italic"],
"settings": {
"foreground": "{{colors.primary.default.hex}}",
"fontStyle": "italic"
}
},
{
"scope": ["markup.underline"],
"settings": {
"fontStyle": "underline"
}
},
{
"scope": ["markup.quote"],
"settings": {
"foreground": "{{colors.secondary.default.hex}}"
}
},
{
"scope": ["markup.list"],
"settings": {
"foreground": "{{colors.on_surface.default.hex}}"
}
},
{
"scope": ["markup.raw", "markup.inline.raw"],
"settings": {
"foreground": "{{colors.secondary.default.hex}}"
}
}
],
"semanticHighlighting": true,
"semanticTokenColors": {
"variable.readonly": {
"foreground": "{{colors.tertiary.default.hex}}"
},
"property": {
"foreground": "{{colors.on_surface.default.hex}}"
},
"function": {
"foreground": "{{colors.primary.default.hex}}"
},
"method": {
"foreground": "{{colors.primary.default.hex}}"
},
"type": {
"foreground": "{{colors.tertiary.default.hex}}"
},
"class": {
"foreground": "{{colors.tertiary.default.hex}}"
},
"enumMember": {
"foreground": "{{colors.tertiary.default.hex}}"
},
"string": {
"foreground": "{{colors.secondary.default.hex}}"
},
"number": {
"foreground": "{{colors.tertiary.default.hex}}"
},
"comment": {
"foreground": "{{colors.outline.default.hex}}",
"fontStyle": "italic"
},
"keyword": {
"foreground": "{{colors.primary.default.hex}}"
},
"operator": {
"foreground": "{{colors.on_surface.default.hex}}"
},
"parameter": {
"foreground": "{{colors.on_surface.default.hex}}"
},
"namespace": {
"foreground": "{{colors.secondary.default.hex}}"
}
}
}

View File

@@ -9,5 +9,5 @@ cursor_border = '{{colors.primary.default.hex}}'
selection_bg = '{{colors.primary_container.default.hex}}' selection_bg = '{{colors.primary_container.default.hex}}'
selection_fg = '{{colors.on_surface.default.hex}}' selection_fg = '{{colors.on_surface.default.hex}}'
ansi = ['{{dank16.color0.hex}}', '{{dank16.color1.hex}}', '{{dank16.color2.hex}}', '{{dank16.color3.hex}}', '{{dank16.color4.hex}}', '{{dank16.color5.hex}}', '{{dank16.color6.hex}}', '{{dank16.color7.hex}}'] ansi = ['{{dank16.color0.default.hex}}', '{{dank16.color1.default.hex}}', '{{dank16.color2.default.hex}}', '{{dank16.color3.default.hex}}', '{{dank16.color4.default.hex}}', '{{dank16.color5.default.hex}}', '{{dank16.color6.default.hex}}', '{{dank16.color7.default.hex}}']
brights = ['{{dank16.color8.hex}}', '{{dank16.color9.hex}}', '{{dank16.color10.hex}}', '{{dank16.color11.hex}}', '{{dank16.color12.hex}}', '{{dank16.color13.hex}}', '{{dank16.color14.hex}}', '{{dank16.color15.hex}}'] brights = ['{{dank16.color8.default.hex}}', '{{dank16.color9.default.hex}}', '{{dank16.color10.default.hex}}', '{{dank16.color11.default.hex}}', '{{dank16.color12.default.hex}}', '{{dank16.color13.default.hex}}', '{{dank16.color14.default.hex}}', '{{dank16.color15.default.hex}}']

View File

@@ -61,7 +61,7 @@ compute_key() {
local mtype=$(read_json_field "$json" "matugenType") local mtype=$(read_json_field "$json" "matugenType")
local run_user=$(read_json_bool "$json" "runUserTemplates") local run_user=$(read_json_bool "$json" "runUserTemplates")
local stock_colors=$(read_json_escaped_field "$json" "stockColors") local stock_colors=$(read_json_escaped_field "$json" "stockColors")
echo "${kind}|${value}|${mode}|${icon:-default}|${mtype:-scheme-tonal-spot}|${run_user:-true}|${stock_colors:-}" | sha256sum | cut -d' ' -f1 echo "${kind}|${value}|${mode}|${icon:-default}|${mtype:-scheme-tonal-spot}|${run_user:-true}|${stock_colors:-}|${TERMINALS_ALWAYS_DARK:-false}" | sha256sum | cut -d' ' -f1
} }
append_config() { append_config() {
@@ -73,6 +73,33 @@ append_config() {
echo "" >> "$cfg_file" echo "" >> "$cfg_file"
} }
append_terminal_config() {
local check_cmd="$1" file_name="$2" cfg_file="$3" tmp_dir="$4"
local config_file="$SHELL_DIR/matugen/configs/$file_name"
[[ ! -f "$config_file" ]] && return
[[ "$check_cmd" != "skip" ]] && ! command -v "$check_cmd" >/dev/null 2>&1 && return
if [[ "$TERMINALS_ALWAYS_DARK" == "true" ]]; then
local config_content
config_content=$(cat "$config_file")
local templates
templates=$(echo "$config_content" | grep "input_path.*SHELL_DIR/matugen/templates/" | sed "s/.*'SHELL_DIR\/matugen\/templates\/\([^']*\)'.*/\1/")
for tpl in $templates; do
local orig="$SHELL_DIR/matugen/templates/$tpl"
[[ ! -f "$orig" ]] && continue
local tmp_template="$tmp_dir/$tpl"
sed 's/\.default\./\.dark\./g' "$orig" > "$tmp_template"
config_content=$(echo "$config_content" | sed "s|'SHELL_DIR/matugen/templates/$tpl'|'$tmp_template'|g")
done
echo "$config_content" | sed "s|'SHELL_DIR/|'$SHELL_DIR/|g" >> "$cfg_file"
echo "" >> "$cfg_file"
return
fi
sed "s|'SHELL_DIR/|'$SHELL_DIR/|g" "$config_file" >> "$cfg_file"
echo "" >> "$cfg_file"
}
append_vscode_config() { append_vscode_config() {
local name="$1" ext_dir="$2" cfg_file="$3" local name="$1" ext_dir="$2" cfg_file="$3"
[[ ! -d "$ext_dir" ]] && return [[ ! -d "$ext_dir" ]] && return
@@ -95,7 +122,7 @@ EOF
} }
build_merged_config() { build_merged_config() {
local mode="$1" run_user="$2" cfg_file="$3" local mode="$1" run_user="$2" cfg_file="$3" tmp_dir="$4"
if [[ "$run_user" == "true" && -f "$CONFIG_DIR/matugen/config.toml" ]]; then if [[ "$run_user" == "true" && -f "$CONFIG_DIR/matugen/config.toml" ]]; then
awk '/^\[config\]/{p=1} /^\[templates\]/{p=0} p' "$CONFIG_DIR/matugen/config.toml" >> "$cfg_file" awk '/^\[config\]/{p=1} /^\[templates\]/{p=0} p' "$CONFIG_DIR/matugen/config.toml" >> "$cfg_file"
@@ -122,11 +149,11 @@ EOF
append_config "firefox" "firefox.toml" "$cfg_file" append_config "firefox" "firefox.toml" "$cfg_file"
append_config "pywalfox" "pywalfox.toml" "$cfg_file" append_config "pywalfox" "pywalfox.toml" "$cfg_file"
append_config "vesktop" "vesktop.toml" "$cfg_file" append_config "vesktop" "vesktop.toml" "$cfg_file"
append_config "ghostty" "ghostty.toml" "$cfg_file" append_terminal_config "ghostty" "ghostty.toml" "$cfg_file" "$tmp_dir"
append_config "kitty" "kitty.toml" "$cfg_file" append_terminal_config "kitty" "kitty.toml" "$cfg_file" "$tmp_dir"
append_config "foot" "foot.toml" "$cfg_file" append_terminal_config "foot" "foot.toml" "$cfg_file" "$tmp_dir"
append_config "alacritty" "alacritty.toml" "$cfg_file" append_terminal_config "alacritty" "alacritty.toml" "$cfg_file" "$tmp_dir"
append_config "wezterm" "wezterm.toml" "$cfg_file" append_terminal_config "wezterm" "wezterm.toml" "$cfg_file" "$tmp_dir"
append_config "dgop" "dgop.toml" "$cfg_file" append_config "dgop" "dgop.toml" "$cfg_file"
append_vscode_config "vscode" "$HOME/.vscode/extensions/local.dynamic-base16-dankshell-0.0.1" "$cfg_file" append_vscode_config "vscode" "$HOME/.vscode/extensions/local.dynamic-base16-dankshell-0.0.1" "$cfg_file"
@@ -149,10 +176,10 @@ EOF
fi fi
} }
generate_dank16() { generate_dank16_variants() {
local primary="$1" surface="$2" light_flag="$3" local primary_dark="$1" primary_light="$2" surface="$3" mode="$4"
local args=("$primary" --json) local args=(--variants --primary-dark "$primary_dark" --primary-light "$primary_light")
[[ -n "$light_flag" ]] && args+=("$light_flag") [[ "$mode" == "light" ]] && args+=(--light)
[[ -n "$surface" ]] && args+=(--background "$surface") [[ -n "$surface" ]] && args+=(--background "$surface")
dms dank16 "${args[@]}" 2>/dev/null || echo '{}' dms dank16 "${args[@]}" 2>/dev/null || echo '{}'
} }
@@ -195,6 +222,8 @@ refresh_gtk() {
signal_terminals() { signal_terminals() {
pgrep -x kitty >/dev/null 2>&1 && pkill -USR1 kitty pgrep -x kitty >/dev/null 2>&1 && pkill -USR1 kitty
pgrep -x ghostty >/dev/null 2>&1 && pkill -USR2 ghostty pgrep -x ghostty >/dev/null 2>&1 && pkill -USR2 ghostty
pgrep -x .kitty-wrapped >/dev/null 2>&1 && pkill -USR2 .kitty-wrapped
pgrep -x .ghostty-wrappe >/dev/null 2>&1 && pkill -USR2 .ghostty-wrappe
} }
build_once() { build_once() {
@@ -210,33 +239,28 @@ build_once() {
[[ -z "$run_user" ]] && run_user="true" [[ -z "$run_user" ]] && run_user="true"
local TMP_CFG=$(mktemp) local TMP_CFG=$(mktemp)
trap "rm -f '$TMP_CFG'" RETURN local TMP_DIR=$(mktemp -d)
trap "rm -f '$TMP_CFG'; rm -rf '$TMP_DIR'" RETURN
build_merged_config "$mode" "$run_user" "$TMP_CFG" build_merged_config "$mode" "$run_user" "$TMP_CFG" "$TMP_DIR"
local light_flag="" local primary_dark primary_light surface dank16 import_args=()
[[ "$mode" == "light" ]] && light_flag="--light"
local primary surface dank16_dark dank16_light import_args=()
if [[ -n "$stock_colors" ]]; then if [[ -n "$stock_colors" ]]; then
log "Using stock/custom theme colors with matugen base" log "Using stock/custom theme colors with matugen base"
primary=$(echo "$stock_colors" | sed -n 's/.*"primary"[^{]*{[^}]*"dark"[^{]*{[^}]*"color"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1) primary_dark=$(echo "$stock_colors" | sed -n 's/.*"primary"[^{]*{[^}]*"dark"[^{]*{[^}]*"color"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
primary_light=$(echo "$stock_colors" | sed -n 's/.*"primary"[^{]*{[^}]*"light"[^{]*{[^}]*"color"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
surface=$(echo "$stock_colors" | sed -n 's/.*"surface"[^{]*{[^}]*"dark"[^{]*{[^}]*"color"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1) surface=$(echo "$stock_colors" | sed -n 's/.*"surface"[^{]*{[^}]*"dark"[^{]*{[^}]*"color"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
[[ -z "$primary" ]] && { err "Failed to extract primary from stock colors"; return 1; } [[ -z "$primary_dark" ]] && { err "Failed to extract primary dark from stock colors"; return 1; }
[[ -z "$primary_light" ]] && primary_light="$primary_dark"
dank16_dark=$(generate_dank16 "$primary" "$surface" "") dank16=$(generate_dank16_variants "$primary_dark" "$primary_light" "$surface" "$mode")
dank16_light=$(generate_dank16 "$primary" "$surface" "--light")
local dank16_current import_args+=(--import-json-string "{\"colors\": $stock_colors, \"dank16\": $dank16}")
[[ "$mode" == "light" ]] && dank16_current="$dank16_light" || dank16_current="$dank16_dark"
[[ "$TERMINALS_ALWAYS_DARK" == "true" && "$mode" == "light" ]] && dank16_current="$dank16_dark"
import_args+=(--import-json-string "{\"colors\": $stock_colors, \"dank16\": $dank16_current}")
log "Running matugen color hex with stock color overrides" log "Running matugen color hex with stock color overrides"
if ! matugen color hex "$primary" -m "$mode" -t "${mtype:-scheme-tonal-spot}" -c "$TMP_CFG" "${import_args[@]}"; then if ! matugen color hex "$primary_dark" -m "$mode" -t "${mtype:-scheme-tonal-spot}" -c "$TMP_CFG" "${import_args[@]}"; then
err "matugen failed" err "matugen failed"
return 1 return 1
fi fi
@@ -251,19 +275,16 @@ build_once() {
mat_json=$("${matugen_cmd[@]}" -m dark -t "$mtype" --json hex --dry-run 2>/dev/null | tr -d '\n') mat_json=$("${matugen_cmd[@]}" -m dark -t "$mtype" --json hex --dry-run 2>/dev/null | tr -d '\n')
[[ -z "$mat_json" ]] && { err "matugen dry-run failed"; return 1; } [[ -z "$mat_json" ]] && { err "matugen dry-run failed"; return 1; }
primary=$(echo "$mat_json" | sed -n 's/.*"primary"[[:space:]]*:[[:space:]]*{[^}]*"dark"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p') primary_dark=$(echo "$mat_json" | sed -n 's/.*"primary"[[:space:]]*:[[:space:]]*{[^}]*"dark"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
primary_light=$(echo "$mat_json" | sed -n 's/.*"primary"[[:space:]]*:[[:space:]]*{[^}]*"light"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
surface=$(echo "$mat_json" | sed -n 's/.*"surface"[[:space:]]*:[[:space:]]*{[^}]*"dark"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p') surface=$(echo "$mat_json" | sed -n 's/.*"surface"[[:space:]]*:[[:space:]]*{[^}]*"dark"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
[[ -z "$primary" ]] && { err "Failed to extract primary color"; return 1; } [[ -z "$primary_dark" ]] && { err "Failed to extract primary color"; return 1; }
[[ -z "$primary_light" ]] && primary_light="$primary_dark"
dank16_dark=$(generate_dank16 "$primary" "$surface" "") dank16=$(generate_dank16_variants "$primary_dark" "$primary_light" "$surface" "$mode")
dank16_light=$(generate_dank16 "$primary" "$surface" "--light")
local dank16_current import_args+=(--import-json-string "{\"dank16\": $dank16}")
[[ "$mode" == "light" ]] && dank16_current="$dank16_light" || dank16_current="$dank16_dark"
[[ "$TERMINALS_ALWAYS_DARK" == "true" && "$mode" == "light" ]] && dank16_current="$dank16_dark"
import_args+=(--import-json-string "{\"dank16\": $dank16_current}")
log "Running matugen $kind with dank16 injection" log "Running matugen $kind with dank16 injection"
if ! "${matugen_cmd[@]}" -m "$mode" -t "$mtype" -c "$TMP_CFG" "${import_args[@]}"; then if ! "${matugen_cmd[@]}" -m "$mode" -t "$mtype" -c "$TMP_CFG" "${import_args[@]}"; then