feat: add optional output_path, change default to monitors.conf
This commit is contained in:
@@ -19,23 +19,30 @@ import (
|
||||
// hyprlandBackend implements Backend for the Hyprland compositor.
|
||||
//
|
||||
// Monitor queries: hyprctl -j monitors all
|
||||
// Layout application: write ~/.config/hypr/monitor-lets-go-monitors.conf + hyprctl reload
|
||||
// Layout application: write ~/.config/hypr/monitors.conf + hyprctl reload
|
||||
// Hotplug events: socket2 unix socket ($XDG_RUNTIME_DIR/hypr/$HIS/.socket2.sock)
|
||||
//
|
||||
// The user must add the following line to their hyprland.lua:
|
||||
//
|
||||
// source = os.getenv("HOME") .. "/.config/hypr/monitor-lets-go-monitors.conf"
|
||||
// source = os.getenv("HOME") .. "/.config/hypr/monitors.conf"
|
||||
type hyprlandBackend struct {
|
||||
logger *slog.Logger
|
||||
|
||||
// outputPath overrides the generated monitor config file path.
|
||||
// Empty means the default: ~/.config/hypr/monitors.conf.
|
||||
outputPath string
|
||||
|
||||
// conn is the current socket2 connection; guarded by mu.
|
||||
conn net.Conn
|
||||
mu sync.Mutex
|
||||
conn net.Conn
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// NewHyprland creates a Hyprland backend. The backend auto-detects the
|
||||
// Hyprland instance signature from the environment.
|
||||
func NewHyprland(logger *slog.Logger) (Backend, error) {
|
||||
//
|
||||
// outputPath overrides the generated monitor config file location.
|
||||
// When empty, defaults to ~/.config/hypr/monitors.conf.
|
||||
func NewHyprland(logger *slog.Logger, outputPath string) (Backend, error) {
|
||||
sig := os.Getenv("HYPRLAND_INSTANCE_SIGNATURE")
|
||||
if sig == "" {
|
||||
return nil, errors.New("HYPRLAND_INSTANCE_SIGNATURE is not set; is Hyprland running?")
|
||||
@@ -50,7 +57,7 @@ func NewHyprland(logger *slog.Logger) (Backend, error) {
|
||||
return nil, fmt.Errorf("socket2 not found at %s: %w", socketPath, err)
|
||||
}
|
||||
|
||||
return &hyprlandBackend{logger: logger}, nil
|
||||
return &hyprlandBackend{logger: logger, outputPath: outputPath}, nil
|
||||
}
|
||||
|
||||
func (h *hyprlandBackend) Name() string { return "hyprland" }
|
||||
@@ -77,11 +84,10 @@ func (h *hyprlandBackend) GetMonitors(ctx context.Context) ([]MonitorInfo, error
|
||||
func (h *hyprlandBackend) ApplyLayout(ctx context.Context, monitors []MonitorConfig) error {
|
||||
content := h.generateConf(monitors)
|
||||
|
||||
configDir, err := h.hyprConfigDir()
|
||||
destPath, err := h.resolveOutputPath()
|
||||
if err != nil {
|
||||
return fmt.Errorf("hypr config dir: %w", err)
|
||||
return fmt.Errorf("resolve output path: %w", err)
|
||||
}
|
||||
destPath := filepath.Join(configDir, "monitor-lets-go-monitors.conf")
|
||||
|
||||
// Atomic write: temp file, write, fsync, rename.
|
||||
if err := atomicWrite(destPath, []byte(content)); err != nil {
|
||||
@@ -285,6 +291,32 @@ func (h *hyprlandBackend) hyprConfigDir() (string, error) {
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
// resolveOutputPath returns the path for the generated monitor config file.
|
||||
// When outputPath is set (via constructor), it is used after ~ expansion.
|
||||
// Otherwise the default ~/.config/hypr/monitors.conf is returned.
|
||||
func (h *hyprlandBackend) resolveOutputPath() (string, error) {
|
||||
if h.outputPath != "" {
|
||||
p := h.outputPath
|
||||
if strings.HasPrefix(p, "~") {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("resolve home directory: %w", err)
|
||||
}
|
||||
p = filepath.Join(home, p[1:])
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil {
|
||||
return "", fmt.Errorf("create output directory: %w", err)
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
configDir, err := h.hyprConfigDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(configDir, "monitors.conf"), nil
|
||||
}
|
||||
|
||||
func (h *hyprlandBackend) Close() error {
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
|
||||
@@ -50,6 +50,11 @@ type Config struct {
|
||||
// Uses *bool so we can distinguish "not set" from explicit false.
|
||||
RestoreOnExit *bool `yaml:"restore_on_exit"`
|
||||
|
||||
// OutputPath overrides the generated monitor config file path.
|
||||
// Supports ~ for home directory expansion.
|
||||
// Empty means the default: ~/.config/hypr/monitors.conf.
|
||||
OutputPath string `yaml:"output_path"`
|
||||
|
||||
// External lists monitor identifiers that trigger docked mode.
|
||||
// Each entry is a name (DP-1) or a desc: prefix (desc:Dell U2723QE).
|
||||
External []string `yaml:"external"`
|
||||
|
||||
Reference in New Issue
Block a user