Allow setting contrast and accent-color as well

This commit is contained in:
Kovid Goyal 2025-05-19 19:39:32 +05:30
parent fcc77c264f
commit 3119088a54
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
2 changed files with 92 additions and 12 deletions

View file

@ -3,6 +3,7 @@ package desktop_ui
import (
"fmt"
"github.com/kovidgoyal/dbus"
"github.com/kovidgoyal/kitty/tools/cli"
"github.com/kovidgoyal/kitty/tools/utils"
)
@ -10,12 +11,15 @@ import (
var _ = fmt.Print
type Options struct {
Color_scheme string
Color_scheme, AccentColor, Contrast string
}
func run_server(opts *Options) (err error) {
portal := NewPortal(opts)
if err = portal.Start(); err != nil {
portal, err := NewPortal(opts)
if err == nil {
err = portal.Start()
}
if err != nil {
return
}
c := make(chan string)
@ -50,6 +54,17 @@ func EntryPoint(root *cli.Command) {
Completer: cli.NamesCompleter("Choices for color-scheme", "no-preference", "light", "dark"),
Help: "The color scheme for your system. This sets the initial value of the color scheme. It can be changed subsequently by using the color-scheme sub-command.",
})
rs.Add(cli.OptionSpec{
Name: `--accent-color`,
Help: "The RGB accent color for your system, can be specified as a color name or in hex a decimal format.",
Default: "cyan",
})
rs.Add(cli.OptionSpec{
Name: `--contrast`, Type: "choices", Choices: "normal, high",
Help: "The preferred contrast level. Choices: normal, high",
Default: "normal",
})
parent.AddSubCommand(&cli.Command{
Name: "enable-portal",
ShortDescription: "This will create or edit the various files needed so that the portal from this kitten is used by xdg-desktop-portal",
@ -61,6 +76,7 @@ func EntryPoint(root *cli.Command) {
parent.AddSubCommand(&cli.Command{
Name: "set-color-scheme",
ShortDescription: "Change the color scheme",
ArgCompleter: cli.NamesCompleter("Choices for color-scheme", "no-preference", "light", "dark", "toggle"),
Usage: " light|dark|no-preference|toggle",
Run: func(cmd *cli.Command, args []string) (rc int, err error) {
if len(args) != 1 {
@ -71,6 +87,45 @@ func EntryPoint(root *cli.Command) {
return utils.IfElse(err == nil, 0, 1), err
},
})
parent.AddSubCommand(&cli.Command{
Name: "set-accent-color",
ShortDescription: "Change the accent color",
Usage: " color_as_hex_or_name",
Run: func(cmd *cli.Command, args []string) (rc int, err error) {
if len(args) != 1 {
cmd.ShowHelp()
return 1, fmt.Errorf("must specify the new accent color value")
}
var v dbus.Variant
if v, err = to_color(args[0]); err == nil {
err = set_variant_setting(PORTAL_APPEARANCE_NAMESPACE, PORTAL_ACCENT_COLOR_KEY, v, false)
}
return utils.IfElse(err == nil, 0, 1), err
},
})
parent.AddSubCommand(&cli.Command{
Name: "set-contrast",
ShortDescription: "Change the contrast. Can be high or normal.",
Usage: " high|normal",
Run: func(cmd *cli.Command, args []string) (rc int, err error) {
if len(args) != 1 {
cmd.ShowHelp()
return 1, fmt.Errorf("must specify the new contrast value")
}
var v dbus.Variant
switch args[0] {
case "normal":
v = dbus.MakeVariant(uint32(0))
case "high":
v = dbus.MakeVariant(uint32(1))
default:
return 1, fmt.Errorf("%s is not a valid contrast value", args[0])
}
err = set_variant_setting(PORTAL_APPEARANCE_NAMESPACE, PORTAL_CONTRAST_KEY, v, false)
return utils.IfElse(err == nil, 0, 1), err
},
})
st := parent.AddSubCommand(&cli.Command{
Name: "set-setting",
ShortDescription: "Change an arbitrary setting",

View file

@ -13,6 +13,7 @@ import (
"github.com/kovidgoyal/dbus/introspect"
"github.com/kovidgoyal/dbus/prop"
"github.com/kovidgoyal/kitty/tools/utils"
"github.com/kovidgoyal/kitty/tools/utils/style"
"golang.org/x/sys/unix"
)
@ -20,6 +21,8 @@ var _ = fmt.Print
const PORTAL_APPEARANCE_NAMESPACE = "org.freedesktop.appearance"
const PORTAL_COLOR_SCHEME_KEY = "color-scheme"
const PORTAL_ACCENT_COLOR_KEY = "accent-color"
const PORTAL_CONTRAST_KEY = "contrast"
const PORTAL_BUS_NAME = "org.freedesktop.impl.portal.desktop.kitty"
const SETTINGS_OBJECT_PATH = "/org/freedesktop/portal/desktop"
const SETTINGS_INTERFACE = "org.freedesktop.impl.portal.Settings"
@ -47,7 +50,14 @@ type Portal struct {
lock sync.Mutex
}
func NewPortal(opts *Options) *Portal {
func to_color(spec string) (v dbus.Variant, err error) {
if col, err := style.ParseColor(spec); err == nil {
return dbus.MakeVariant([]float64{float64(col.Red) / 255., float64(col.Green) / 255., float64(col.Blue) / 255.}), nil
}
return
}
func NewPortal(opts *Options) (p *Portal, err error) {
ans := Portal{}
ans.settings = SettingsMap{
SETTINGS_CANARY_NAMESPACE: map[string]dbus.Variant{
@ -63,7 +73,13 @@ func NewPortal(opts *Options) *Portal {
default:
ans.settings[PORTAL_APPEARANCE_NAMESPACE][PORTAL_COLOR_SCHEME_KEY] = dbus.MakeVariant(uint32(NO_PREFERENCE))
}
return &ans
ans.settings[PORTAL_APPEARANCE_NAMESPACE][PORTAL_ACCENT_COLOR_KEY], err = to_color(opts.AccentColor)
var contrast uint32
if opts.Contrast == "high" {
contrast = 1
}
ans.settings[PORTAL_APPEARANCE_NAMESPACE][PORTAL_CONTRAST_KEY] = dbus.MakeVariant(contrast)
return &ans, nil
}
type PropSpec map[string]*prop.Prop
@ -422,21 +438,17 @@ type SetOptions struct {
Namespace, DataType string
}
func set_setting(key, value string, opts *SetOptions) (err error) {
func set_variant_setting(namespace, key string, v dbus.Variant, remove_setting bool) (err error) {
conn, err := dbus.SessionBus()
if err != nil {
return fmt.Errorf("failed to connect to system bus with error: %w", err)
}
defer conn.Close()
method := "ChangeSetting"
var vals = []any{opts.Namespace, key}
if value == "" {
var vals = []any{namespace, key}
if remove_setting {
method = "RemoveSetting"
} else {
v, err := ParseValueWithSignature(value, opts.DataType)
if err != nil {
return err
}
vals = append(vals, v)
}
obj := conn.Object(PORTAL_BUS_NAME, dbus.ObjectPath(CHANGE_SETTINGS_OBJECT_PATH))
@ -447,6 +459,19 @@ func set_setting(key, value string, opts *SetOptions) (err error) {
return
}
func set_setting(key, value string, opts *SetOptions) (err error) {
remove_setting := false
var v dbus.Variant
if value == "" {
remove_setting = true
} else {
if v, err = ParseValueWithSignature(value, opts.DataType); err != nil {
return err
}
}
return set_variant_setting(opts.Namespace, key, v, remove_setting)
}
func set_color_scheme(which string) (err error) {
conn, err := dbus.SessionBus()
if err != nil {