Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
ximperconf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ximper Linux
ximperconf
Commits
1dec1397
Verified
Commit
1dec1397
authored
Jan 24, 2026
by
Kirill Unitsaev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
hyprland/wallpaper: add wallpaper management commands
parent
aa008de8
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
525 additions
and
0 deletions
+525
-0
commands.go
hyprland/commands.go
+1
-0
wallpaper-actions.go
hyprland/wallpaper-actions.go
+195
-0
wallpaper-commands.go
hyprland/wallpaper-commands.go
+75
-0
wallpaper.go
hyprland/wallpaper.go
+254
-0
No files found.
hyprland/commands.go
View file @
1dec1397
...
@@ -232,6 +232,7 @@ func CommandList() *cli.Command {
...
@@ -232,6 +232,7 @@ func CommandList() *cli.Command {
},
},
},
},
},
},
WallpaperCommandList
(),
},
},
}
}
}
}
...
...
hyprland/wallpaper-actions.go
0 → 100644
View file @
1dec1397
package
hyprland
import
(
"context"
"fmt"
"ximperconf/config"
"ximperconf/ui"
"github.com/fatih/color"
"github.com/urfave/cli/v3"
)
func
WallpaperSetCommand
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
lightPath
:=
cmd
.
String
(
"light"
)
darkPath
:=
cmd
.
String
(
"dark"
)
monitor
:=
cmd
.
String
(
"monitor"
)
if
monitor
==
"default"
{
monitor
=
""
}
if
lightPath
==
""
&&
darkPath
==
""
{
return
fmt
.
Errorf
(
"укажите --light и/или --dark"
)
}
manager
,
err
:=
NewWallpaperManager
()
if
err
!=
nil
{
return
err
}
monitors
:=
[]
string
{
monitor
}
if
monitor
==
"all"
{
monitors
,
err
=
manager
.
GetHyprlandMonitors
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"не удалось получить список мониторов: %w"
,
err
)
}
}
for
_
,
mon
:=
range
monitors
{
if
err
:=
manager
.
SetWallpaper
(
lightPath
,
darkPath
,
mon
);
err
!=
nil
{
return
err
}
}
if
err
:=
manager
.
Save
();
err
!=
nil
{
return
err
}
color
.
Green
(
"Обои сохранены в конфиг"
)
theme
:=
manager
.
GetCurrentTheme
()
if
theme
==
""
{
if
darkPath
!=
""
{
theme
=
ThemeDark
}
else
{
theme
=
ThemeLight
}
manager
.
SetCurrentTheme
(
theme
)
manager
.
Save
()
}
if
err
:=
manager
.
ApplyAll
(
theme
);
err
!=
nil
{
color
.
Yellow
(
"Не удалось применить обои: %v"
,
err
)
}
else
{
color
.
Green
(
"Обои применены"
)
}
return
nil
}
func
WallpaperGetCommand
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
manager
,
err
:=
NewWallpaperManager
()
if
err
!=
nil
{
return
err
}
monitor
:=
cmd
.
String
(
"monitor"
)
if
monitor
==
"default"
{
monitor
=
""
}
if
cmd
.
Bool
(
"pair"
)
{
light
:=
manager
.
GetWallpaper
(
monitor
,
ThemeLight
)
dark
:=
manager
.
GetWallpaper
(
monitor
,
ThemeDark
)
fmt
.
Printf
(
"[
\"
%s
\"
,
\"
%s
\"
]
\n
"
,
light
,
dark
)
return
nil
}
var
theme
ThemeType
if
cmd
.
Bool
(
"light"
)
{
theme
=
ThemeLight
}
else
if
cmd
.
Bool
(
"dark"
)
{
theme
=
ThemeDark
}
else
{
theme
=
manager
.
GetCurrentTheme
()
if
theme
==
""
{
return
fmt
.
Errorf
(
"укажите --light или --dark, либо установите текущую тему через apply"
)
}
}
path
:=
manager
.
GetWallpaper
(
monitor
,
theme
)
if
config
.
IsJSON
(
cmd
)
{
return
ui
.
PrintJSON
(
map
[
string
]
string
{
"path"
:
path
,
"monitor"
:
monitor
,
"theme"
:
string
(
theme
),
})
}
if
path
==
""
{
return
fmt
.
Errorf
(
"обои не настроены"
)
}
fmt
.
Println
(
path
)
return
nil
}
func
WallpaperApplyCommand
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
themeArg
:=
cmd
.
Args
()
.
Get
(
0
)
manager
,
err
:=
NewWallpaperManager
()
if
err
!=
nil
{
return
err
}
var
targetTheme
ThemeType
if
themeArg
!=
""
{
if
themeArg
!=
"light"
&&
themeArg
!=
"dark"
{
return
fmt
.
Errorf
(
"укажите тему: light или dark"
)
}
targetTheme
=
ThemeType
(
themeArg
)
manager
.
SetCurrentTheme
(
targetTheme
)
if
err
:=
manager
.
Save
();
err
!=
nil
{
return
err
}
}
else
{
targetTheme
=
manager
.
GetCurrentTheme
()
if
targetTheme
==
""
{
return
fmt
.
Errorf
(
"текущая тема не установлена, укажите light или dark"
)
}
}
if
err
:=
manager
.
ApplyAll
(
targetTheme
);
err
!=
nil
{
return
err
}
color
.
Green
(
"Обои применены (тема: %s)"
,
targetTheme
)
return
nil
}
func
WallpaperInfoCommand
(
ctx
context
.
Context
,
cmd
*
cli
.
Command
)
error
{
manager
,
err
:=
NewWallpaperManager
()
if
err
!=
nil
{
return
err
}
monitors
,
err
:=
manager
.
GetHyprlandMonitors
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"не удалось получить список мониторов: %w"
,
err
)
}
type
monitorEntry
struct
{
Monitor
string
`json:"monitor"`
Light
string
`json:"light"`
Dark
string
`json:"dark"`
}
entries
:=
[]
monitorEntry
{
{
Monitor
:
"default"
,
Light
:
manager
.
Config
.
Default
.
Light
,
Dark
:
manager
.
Config
.
Default
.
Dark
,
},
}
for
_
,
mon
:=
range
monitors
{
entries
=
append
(
entries
,
monitorEntry
{
Monitor
:
mon
,
Light
:
manager
.
GetWallpaper
(
mon
,
ThemeLight
),
Dark
:
manager
.
GetWallpaper
(
mon
,
ThemeDark
),
})
}
if
config
.
IsJSON
(
cmd
)
{
return
ui
.
PrintJSON
(
entries
)
}
for
_
,
e
:=
range
entries
{
fmt
.
Printf
(
"%s:
\n
"
,
e
.
Monitor
)
fmt
.
Printf
(
" light: %s
\n
"
,
e
.
Light
)
fmt
.
Printf
(
" dark: %s
\n
"
,
e
.
Dark
)
}
return
nil
}
hyprland/wallpaper-commands.go
0 → 100644
View file @
1dec1397
package
hyprland
import
(
"ximperconf/config"
"github.com/urfave/cli/v3"
)
func
WallpaperCommandList
()
*
cli
.
Command
{
return
&
cli
.
Command
{
Name
:
"wallpaper"
,
Usage
:
"Управление обоями"
,
Commands
:
[]
*
cli
.
Command
{
{
Name
:
"set"
,
Usage
:
"установить обои в конфиг"
,
Flags
:
[]
cli
.
Flag
{
&
cli
.
StringFlag
{
Name
:
"light"
,
Usage
:
"путь к обоям для светлой темы"
,
},
&
cli
.
StringFlag
{
Name
:
"dark"
,
Usage
:
"путь к обоям для тёмной темы"
,
},
&
cli
.
StringFlag
{
Name
:
"monitor"
,
Aliases
:
[]
string
{
"m"
},
Usage
:
"имя монитора"
,
},
},
Action
:
WallpaperSetCommand
,
},
{
Name
:
"get"
,
Usage
:
"получить путь к обоям"
,
Flags
:
[]
cli
.
Flag
{
&
cli
.
BoolFlag
{
Name
:
"light"
,
Usage
:
"для светлой темы"
,
},
&
cli
.
BoolFlag
{
Name
:
"dark"
,
Usage
:
"для тёмной темы"
,
},
&
cli
.
BoolFlag
{
Name
:
"pair"
,
Usage
:
"вернуть пару [light, dark]"
,
},
&
cli
.
StringFlag
{
Name
:
"monitor"
,
Aliases
:
[]
string
{
"m"
},
Usage
:
"имя монитора"
,
},
config
.
FormatFlag
,
},
Action
:
WallpaperGetCommand
,
},
{
Name
:
"apply"
,
Usage
:
"применить обои"
,
ArgsUsage
:
"[light|dark]"
,
Action
:
WallpaperApplyCommand
,
},
{
Name
:
"info"
,
Usage
:
"информация о настроенных обоях"
,
Flags
:
[]
cli
.
Flag
{
config
.
FormatFlag
,
},
Action
:
WallpaperInfoCommand
,
},
},
}
}
hyprland/wallpaper.go
0 → 100644
View file @
1dec1397
package
hyprland
import
(
"encoding/json"
"fmt"
"os"
"os/exec"
"path/filepath"
"ximperconf/utils"
"gopkg.in/yaml.v3"
)
type
ThemeType
string
const
(
ThemeLight
ThemeType
=
"light"
ThemeDark
ThemeType
=
"dark"
)
type
WallpaperEntry
struct
{
Light
string
`yaml:"light,omitempty" json:"light,omitempty"`
Dark
string
`yaml:"dark,omitempty" json:"dark,omitempty"`
}
type
WallpaperConfig
struct
{
CurrentTheme
string
`yaml:"current_theme,omitempty" json:"current_theme,omitempty"`
Monitors
map
[
string
]
WallpaperEntry
`yaml:"monitors,omitempty" json:"monitors,omitempty"`
Default
WallpaperEntry
`yaml:"default,omitempty" json:"default,omitempty"`
}
type
WallpaperManager
struct
{
Config
*
WallpaperConfig
ConfigPath
string
Changed
bool
}
func
NewWallpaperManager
()
(
*
WallpaperManager
,
error
)
{
home
,
err
:=
os
.
UserHomeDir
()
if
err
!=
nil
{
return
nil
,
err
}
configPath
:=
filepath
.
Join
(
home
,
".config"
,
"ximper"
,
"wallpaper.yaml"
)
manager
:=
&
WallpaperManager
{
ConfigPath
:
configPath
,
Config
:
&
WallpaperConfig
{
Monitors
:
make
(
map
[
string
]
WallpaperEntry
),
},
}
if
utils
.
FileExists
(
configPath
)
{
data
,
err
:=
os
.
ReadFile
(
configPath
)
if
err
!=
nil
{
return
nil
,
err
}
if
err
:=
yaml
.
Unmarshal
(
data
,
manager
.
Config
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"ошибка парсинга %s: %w"
,
configPath
,
err
)
}
if
manager
.
Config
.
Monitors
==
nil
{
manager
.
Config
.
Monitors
=
make
(
map
[
string
]
WallpaperEntry
)
}
}
return
manager
,
nil
}
func
(
m
*
WallpaperManager
)
Save
()
error
{
if
!
m
.
Changed
{
return
nil
}
dir
:=
filepath
.
Dir
(
m
.
ConfigPath
)
if
err
:=
os
.
MkdirAll
(
dir
,
0755
);
err
!=
nil
{
return
err
}
data
,
err
:=
yaml
.
Marshal
(
m
.
Config
)
if
err
!=
nil
{
return
err
}
m
.
Changed
=
false
return
os
.
WriteFile
(
m
.
ConfigPath
,
data
,
0644
)
}
func
(
m
*
WallpaperManager
)
SetWallpaper
(
lightPath
,
darkPath
,
monitor
string
)
error
{
if
lightPath
!=
""
{
absPath
,
err
:=
filepath
.
Abs
(
lightPath
)
if
err
!=
nil
{
return
err
}
if
!
utils
.
FileExists
(
absPath
)
{
return
fmt
.
Errorf
(
"файл не найден: %s"
,
absPath
)
}
lightPath
=
absPath
}
if
darkPath
!=
""
{
absPath
,
err
:=
filepath
.
Abs
(
darkPath
)
if
err
!=
nil
{
return
err
}
if
!
utils
.
FileExists
(
absPath
)
{
return
fmt
.
Errorf
(
"файл не найден: %s"
,
absPath
)
}
darkPath
=
absPath
}
if
monitor
==
""
{
if
lightPath
!=
""
{
m
.
Config
.
Default
.
Light
=
lightPath
}
if
darkPath
!=
""
{
m
.
Config
.
Default
.
Dark
=
darkPath
}
}
else
{
entry
:=
m
.
Config
.
Monitors
[
monitor
]
if
lightPath
!=
""
{
entry
.
Light
=
lightPath
}
if
darkPath
!=
""
{
entry
.
Dark
=
darkPath
}
m
.
Config
.
Monitors
[
monitor
]
=
entry
}
m
.
Changed
=
true
return
nil
}
func
(
m
*
WallpaperManager
)
GetWallpaper
(
monitor
string
,
theme
ThemeType
)
string
{
var
entry
WallpaperEntry
var
found
bool
if
monitor
!=
""
{
entry
,
found
=
m
.
Config
.
Monitors
[
monitor
]
}
var
path
string
if
found
{
switch
theme
{
case
ThemeLight
:
path
=
entry
.
Light
case
ThemeDark
:
path
=
entry
.
Dark
}
}
if
path
==
""
{
switch
theme
{
case
ThemeLight
:
path
=
m
.
Config
.
Default
.
Light
case
ThemeDark
:
path
=
m
.
Config
.
Default
.
Dark
}
}
return
path
}
func
(
m
*
WallpaperManager
)
GetCurrentTheme
()
ThemeType
{
return
ThemeType
(
m
.
Config
.
CurrentTheme
)
}
func
(
m
*
WallpaperManager
)
SetCurrentTheme
(
theme
ThemeType
)
{
m
.
Config
.
CurrentTheme
=
string
(
theme
)
m
.
Changed
=
true
}
func
(
m
*
WallpaperManager
)
Apply
(
monitor
string
,
theme
ThemeType
)
error
{
path
:=
m
.
GetWallpaper
(
monitor
,
theme
)
if
path
==
""
{
return
fmt
.
Errorf
(
"обои не настроены для монитора %s, тема %s"
,
monitor
,
theme
)
}
if
!
utils
.
FileExists
(
path
)
{
return
fmt
.
Errorf
(
"файл обоев не найден: %s"
,
path
)
}
if
err
:=
m
.
hyprctlPreload
(
path
);
err
!=
nil
{
return
fmt
.
Errorf
(
"ошибка preload: %w"
,
err
)
}
if
err
:=
m
.
hyprctlSetWallpaper
(
monitor
,
path
);
err
!=
nil
{
return
fmt
.
Errorf
(
"ошибка установки обоев: %w"
,
err
)
}
return
nil
}
func
(
m
*
WallpaperManager
)
ApplyAll
(
theme
ThemeType
)
error
{
monitors
,
err
:=
m
.
GetHyprlandMonitors
()
defer
m
.
hyprctlUnloadUnused
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"ошибка получения списка мониторов: %w"
,
err
)
}
for
_
,
mon
:=
range
monitors
{
if
err
:=
m
.
Apply
(
mon
,
theme
);
err
!=
nil
{
return
fmt
.
Errorf
(
"монитор %s: %w"
,
mon
,
err
)
}
}
return
nil
}
func
(
m
*
WallpaperManager
)
hyprctlPreload
(
path
string
)
error
{
cmd
:=
exec
.
Command
(
"hyprctl"
,
"hyprpaper"
,
"preload"
,
path
)
out
,
err
:=
cmd
.
CombinedOutput
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"%v: %s"
,
err
,
string
(
out
))
}
return
nil
}
func
(
m
*
WallpaperManager
)
hyprctlUnloadUnused
()
{
cmd
:=
exec
.
Command
(
"hyprctl"
,
"hyprpaper"
,
"unload"
,
"unused"
)
cmd
.
Run
()
}
func
(
m
*
WallpaperManager
)
hyprctlSetWallpaper
(
monitor
,
path
string
)
error
{
arg
:=
monitor
+
","
+
path
cmd
:=
exec
.
Command
(
"hyprctl"
,
"hyprpaper"
,
"wallpaper"
,
arg
)
out
,
err
:=
cmd
.
CombinedOutput
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"%v: %s"
,
err
,
string
(
out
))
}
return
nil
}
func
(
m
*
WallpaperManager
)
GetHyprlandMonitors
()
([]
string
,
error
)
{
out
,
err
:=
exec
.
Command
(
"hyprctl"
,
"monitors"
,
"-j"
)
.
Output
()
if
err
!=
nil
{
return
nil
,
err
}
var
monitors
[]
struct
{
Name
string
`json:"name"`
}
if
err
:=
json
.
Unmarshal
(
out
,
&
monitors
);
err
!=
nil
{
return
nil
,
err
}
var
names
[]
string
for
_
,
mon
:=
range
monitors
{
names
=
append
(
names
,
mon
.
Name
)
}
return
names
,
nil
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment