mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-25 17:52:02 +02:00
Code to show desktop settings
This commit is contained in:
@@ -50,5 +50,39 @@ func EntryPoint(root *cli.Command) {
|
|||||||
Completer: cli.NamesCompleter("Choices for color-scheme", "no-preference", "light", "dark"),
|
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.",
|
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.",
|
||||||
})
|
})
|
||||||
|
parent.AddSubCommand(&cli.Command{
|
||||||
|
Name: "set-color-scheme",
|
||||||
|
ShortDescription: "Change the color scheme",
|
||||||
|
Usage: " light|dark|no-preference|toggle",
|
||||||
|
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 color scheme value")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
},
|
||||||
|
})
|
||||||
|
ss := parent.AddSubCommand(&cli.Command{
|
||||||
|
Name: "show-settings",
|
||||||
|
ShortDescription: "Print the current values of the desktop settings",
|
||||||
|
Run: func(cmd *cli.Command, args []string) (rc int, err error) {
|
||||||
|
if len(args) != 0 {
|
||||||
|
cmd.ShowHelp()
|
||||||
|
return 1, fmt.Errorf("no arguments allowed")
|
||||||
|
}
|
||||||
|
opts := ShowSettingsOptions{}
|
||||||
|
err = cmd.GetOptionValues(&opts)
|
||||||
|
if err == nil {
|
||||||
|
err = show_settings(&opts)
|
||||||
|
}
|
||||||
|
return utils.IfElse(err == nil, 0, 1), err
|
||||||
|
},
|
||||||
|
})
|
||||||
|
ss.Add(cli.OptionSpec{
|
||||||
|
Name: "--as-json",
|
||||||
|
Dest: "As_json",
|
||||||
|
Help: "Show the settings as JSON for machine consumption",
|
||||||
|
Type: "bool-set",
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package desktop_ui
|
package desktop_ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"maps"
|
"maps"
|
||||||
"os"
|
"os"
|
||||||
@@ -22,6 +23,7 @@ const SETTINGS_OBJECT_PATH = "/org/freedesktop/portal/desktop"
|
|||||||
const SETTINGS_INTERFACE = "org.freedesktop.impl.portal.Settings"
|
const SETTINGS_INTERFACE = "org.freedesktop.impl.portal.Settings"
|
||||||
const CHANGE_SETTINGS_OBJECT_PATH = "/net/kovidgoyal/kitty/portal"
|
const CHANGE_SETTINGS_OBJECT_PATH = "/net/kovidgoyal/kitty/portal"
|
||||||
const CHANGE_SETTINGS_INTERFACE = "net.kovidgoyal.kitty.settings"
|
const CHANGE_SETTINGS_INTERFACE = "net.kovidgoyal.kitty.settings"
|
||||||
|
const DESKTOP_PORTAL_NAME = "org.freedesktop.portal.Desktop"
|
||||||
|
|
||||||
// Special portal setting used to check if we are being called by xdg-desktop-portal
|
// Special portal setting used to check if we are being called by xdg-desktop-portal
|
||||||
const SETTINGS_CANARY_NAMESPACE = "net.kovidgoyal.kitty"
|
const SETTINGS_CANARY_NAMESPACE = "net.kovidgoyal.kitty"
|
||||||
@@ -175,18 +177,76 @@ func (self *Portal) Start() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseValue(value, value_type_signature string) (dbus.Variant, error) {
|
func ParseValueWithSignature(value, value_type_signature string) (v dbus.Variant, err error) {
|
||||||
s, err := dbus.ParseSignature(value_type_signature)
|
var s dbus.Signature
|
||||||
if err != nil {
|
if value_type_signature != "" {
|
||||||
return dbus.Variant{}, fmt.Errorf("%s is not a valid type signature: %w", value_type_signature, err)
|
s, err = dbus.ParseSignature(value_type_signature)
|
||||||
|
if err != nil {
|
||||||
|
return dbus.Variant{}, fmt.Errorf("%s is not a valid type signature: %w", value_type_signature, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
v, err := dbus.ParseVariant(value, s)
|
v, err = dbus.ParseVariant(value, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dbus.Variant{}, fmt.Errorf("%s is not a valid value for signature: %s with error: %w", value, value_type_signature, err)
|
return dbus.Variant{}, fmt.Errorf("%s is not a valid value for signature: %s with error: %w", value, value_type_signature, err)
|
||||||
}
|
}
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ParseValue(value string) (dbus.Variant, error) {
|
||||||
|
return ParseValueWithSignature(value, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShowSettingsOptions struct {
|
||||||
|
As_json bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func show_settings(opts *ShowSettingsOptions) (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()
|
||||||
|
path := "/" + strings.ToLower(strings.ReplaceAll(DESKTOP_PORTAL_NAME, ".", "/"))
|
||||||
|
obj := conn.Object(DESKTOP_PORTAL_NAME, dbus.ObjectPath(path))
|
||||||
|
interface_name := strings.ReplaceAll(DESKTOP_PORTAL_NAME, "Desktop", "Settings")
|
||||||
|
call := obj.Call(interface_name+".ReadAll", dbus.FlagNoAutoStart, []string{""})
|
||||||
|
var response ReadAllType
|
||||||
|
if err = call.Store(&response); err != nil {
|
||||||
|
return fmt.Errorf("Failed to read response from ReadAll with error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.As_json {
|
||||||
|
unwrapped := make(map[string]map[string]any, len(response))
|
||||||
|
for ns, m := range response {
|
||||||
|
w := make(map[string]any, len(m))
|
||||||
|
for k, a := range m {
|
||||||
|
w[k] = a.Value()
|
||||||
|
}
|
||||||
|
unwrapped[ns] = w
|
||||||
|
}
|
||||||
|
j, err := json.MarshalIndent(unwrapped, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Failed to format the response as JSON: %w", err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(j))
|
||||||
|
} else {
|
||||||
|
for ns, m := range response {
|
||||||
|
fmt.Println(ns + ":")
|
||||||
|
for key, v := range m {
|
||||||
|
fmt.Printf("\t%s: %s\n", key, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is_running_self := false
|
||||||
|
if m, found := response[SETTINGS_CANARY_NAMESPACE]; found {
|
||||||
|
_, is_running_self = m[SETTINGS_CANARY_KEY]
|
||||||
|
}
|
||||||
|
if !is_running_self {
|
||||||
|
err = fmt.Errorf("the settings did not come from the desktop-ui kitten. Some other portal backend is providing the service.")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Portal) ChangeSetting(namespace, key string, value dbus.Variant) *dbus.Error {
|
func (self *Portal) ChangeSetting(namespace, key string, value dbus.Variant) *dbus.Error {
|
||||||
self.lock.Lock()
|
self.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer self.lock.Unlock()
|
||||||
@@ -218,7 +278,9 @@ func (self *Portal) Read(namespace, key string) (dbus.Variant, *dbus.Error) {
|
|||||||
return dbus.Variant{}, dbus.NewError("org.freedesktop.portal.Error.NotFound", []any{fmt.Sprintf("the setting %s in the namespace %s is not supported", key, namespace)})
|
return dbus.Variant{}, dbus.NewError("org.freedesktop.portal.Error.NotFound", []any{fmt.Sprintf("the setting %s in the namespace %s is not supported", key, namespace)})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Portal) ReadAll(namespaces []string) (map[string]map[string]dbus.Variant, *dbus.Error) {
|
type ReadAllType map[string]map[string]dbus.Variant
|
||||||
|
|
||||||
|
func (self *Portal) ReadAll(namespaces []string) (ReadAllType, *dbus.Error) {
|
||||||
self.lock.Lock()
|
self.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer self.lock.Unlock()
|
||||||
var matched_namespaces = SettingsMap{}
|
var matched_namespaces = SettingsMap{}
|
||||||
|
|||||||
Reference in New Issue
Block a user