go
This commit is contained in:
parent
e2e5e2162c
commit
f7284f1104
15 changed files with 642 additions and 0 deletions
31
.gitignore
vendored
Normal file
31
.gitignore
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Created by https://www.toptal.com/developers/gitignore/api/go
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=go
|
||||
|
||||
### Go ###
|
||||
# If you prefer the allow list template instead of the deny list, see community template:
|
||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||
#
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
# Go workspace file
|
||||
go.work
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/go
|
||||
|
||||
# nix
|
||||
result
|
||||
hyprman
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 Daylin Morgan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
16
cmd/eww.go
Normal file
16
cmd/eww.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var ewwCmd = &cobra.Command{
|
||||
Use:"eww" ,
|
||||
Short: "eww integration",
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(ewwCmd)
|
||||
}
|
||||
|
||||
|
17
cmd/eww_start.go
Normal file
17
cmd/eww_start.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var startCmd = &cobra.Command{
|
||||
Use: "start",
|
||||
Short: "Launch eww",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
hm.LaunchEww()
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
ewwCmd.AddCommand(startCmd)
|
||||
}
|
17
cmd/eww_watch.go
Normal file
17
cmd/eww_watch.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var watchCmd = &cobra.Command{
|
||||
Use: "watch",
|
||||
Short: "Watch hyprland events and propagate to eww",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
hm.Watch()
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
ewwCmd.AddCommand(watchCmd)
|
||||
}
|
22
cmd/mako.go
Normal file
22
cmd/mako.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
// "git.dayl.in/daylin/hyprman/internal"
|
||||
)
|
||||
|
||||
var makoCmd = &cobra.Command{
|
||||
Use:"mako" ,
|
||||
Short: "mako integration",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("hahah mako baby")
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(makoCmd)
|
||||
}
|
||||
|
||||
|
46
cmd/root.go
Normal file
46
cmd/root.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
cc "github.com/ivanpirog/coloredcobra"
|
||||
"git.dayl.in/daylin/hyprman/internal"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
||||
func Execute() {
|
||||
cc.Init(&cc.Config{
|
||||
RootCmd: rootCmd,
|
||||
Headings: cc.HiMagenta + cc.Bold,
|
||||
Commands: cc.Bold,
|
||||
Example: cc.Italic,
|
||||
ExecName: cc.Bold,
|
||||
Flags: cc.Bold,
|
||||
NoExtraNewlines: true,
|
||||
NoBottomNewline: true,
|
||||
})
|
||||
err := rootCmd.Execute()
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
var configPath string
|
||||
var hm = &hyprman.Hyprman{}
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "hyprman",
|
||||
Short: "hyprland companion app",
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
hm.LoadConfig(configPath)
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
func init() {
|
||||
rootCmd.CompletionOptions.HiddenDefaultCmd = true
|
||||
rootCmd.PersistentFlags().StringVarP(&configPath, "config", "c", hyprman.DefaultConfigPath(), "path to config file")
|
||||
}
|
||||
|
||||
|
27
flake.lock
Normal file
27
flake.lock
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1716312448,
|
||||
"narHash": "sha256-PH3w5av8d+TdwCkiWN4UPBTxrD9MpxIQPDVWctlomVo=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e381a1288138aceda0ac63db32c7be545b446921",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
48
flake.nix
Normal file
48
flake.nix
Normal file
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
description = "hyprman";
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||
};
|
||||
|
||||
outputs =
|
||||
inputs@{
|
||||
nixpkgs,
|
||||
self,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (nixpkgs.lib) genAttrs cleanSource;
|
||||
supportedSystems = [
|
||||
"x86_64-linux"
|
||||
"x86_64-darwin"
|
||||
"aarch64-linux"
|
||||
"aarch64-darwin"
|
||||
];
|
||||
forAllSystems = f: genAttrs supportedSystems (system: f nixpkgs.legacyPackages.${system});
|
||||
in
|
||||
{
|
||||
devShells = forAllSystems (pkgs: {
|
||||
default = pkgs.mkShell {
|
||||
packages = with pkgs; [go];
|
||||
};
|
||||
});
|
||||
packages = forAllSystems (pkgs: {
|
||||
default = self.packages.${pkgs.system}.hyprman;
|
||||
hyprman = pkgs.buildGoModule {
|
||||
pname = "hyprman";
|
||||
version = "unstable";
|
||||
src = cleanSource ./.;
|
||||
vendorHash = "sha256-eKeUhS2puz6ALb+cQKl7+DGvm9Cl+miZAHX0imf9wdg=";
|
||||
|
||||
nativeBuildInputs = with pkgs; [installShellFiles];
|
||||
|
||||
postInstall = ''
|
||||
installShellCompletion --cmd hyprman \
|
||||
--zsh <($out/bin/hyprman completion zsh)
|
||||
'';
|
||||
};
|
||||
|
||||
});
|
||||
formatter = forAllSystems (pkgs: pkgs.nixfmt-rfc-style);
|
||||
};
|
||||
}
|
21
go.mod
Normal file
21
go.mod
Normal file
|
@ -0,0 +1,21 @@
|
|||
module git.dayl.in/daylin/hyprman
|
||||
|
||||
go 1.22.2
|
||||
|
||||
require (
|
||||
github.com/goccy/go-yaml v1.11.3
|
||||
github.com/ivanpirog/coloredcobra v1.0.1
|
||||
github.com/spf13/cobra v1.8.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fatih/color v1.17.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
)
|
||||
|
||||
replace github.com/ivanpirog/coloredcobra => github.com/daylinmorgan/coloredcobra v0.0.0-20240527152736-9d3ce38297a6
|
45
go.sum
Normal file
45
go.sum
Normal file
|
@ -0,0 +1,45 @@
|
|||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/daylinmorgan/coloredcobra v0.0.0-20240527152736-9d3ce38297a6 h1:Zst7HlWvQj8LPJ3mhIWtGH2DxqUo6VEq0oekNyAho6M=
|
||||
github.com/daylinmorgan/coloredcobra v0.0.0-20240527152736-9d3ce38297a6/go.mod h1:csDZxFD5oWCy1x8hxXVD4txpYQgo12WOcLS7JON5SVE=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
|
||||
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
|
||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
|
||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||
github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I=
|
||||
github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
|
||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
280
internal/hyprman.go
Normal file
280
internal/hyprman.go
Normal file
|
@ -0,0 +1,280 @@
|
|||
package hyprman
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
)
|
||||
|
||||
func DefaultConfigPath() string {
|
||||
configPath, exists := os.LookupEnv("XDG_CONFIG_HOME")
|
||||
if !exists {
|
||||
home, exists := os.LookupEnv("HOME")
|
||||
if !exists {
|
||||
log.Fatalln("failed to set default icons.json path is $HOME or $XDG_CONFIG_HOME set?")
|
||||
}
|
||||
configPath = filepath.Join(home, ".config")
|
||||
}
|
||||
return filepath.Join(configPath, "hyprman", "config.yml")
|
||||
}
|
||||
|
||||
func hyprSocketBase() string {
|
||||
runtimeDir, exists := os.LookupEnv("XDG_RUNTIME_DIR")
|
||||
if !exists {
|
||||
log.Fatalln("XDG_RUNTIME_DIR not set")
|
||||
}
|
||||
instanceSig, exists := os.LookupEnv("HYPRLAND_INSTANCE_SIGNATURE")
|
||||
if !exists {
|
||||
log.Fatalln("HYPRLAND_INSTANCE_SIGNATURE not set")
|
||||
}
|
||||
return filepath.Join(runtimeDir, "hypr", instanceSig)
|
||||
}
|
||||
|
||||
func hyprSocket() string {
|
||||
return filepath.Join(hyprSocketBase(), ".socket.sock")
|
||||
}
|
||||
|
||||
func hyprSocket2() string {
|
||||
return filepath.Join(hyprSocketBase(), ".socket2.sock")
|
||||
}
|
||||
|
||||
type Workspace struct {
|
||||
Name string
|
||||
Id int
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
Class string
|
||||
Workspace Workspace
|
||||
}
|
||||
|
||||
type Icons map[string]string
|
||||
|
||||
type Hyprman struct {
|
||||
Config Config
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Classes Icons
|
||||
NoClientIcon string `yaml:"no-client"`
|
||||
DefaultIcon string `yaml:"default-icon"`
|
||||
}
|
||||
|
||||
func (hm *Hyprman) LoadConfig(path string) {
|
||||
var config Config
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
log.Fatal(fmt.Errorf("failed to read config at %s:\n%w", path, err))
|
||||
}
|
||||
if err := yaml.Unmarshal([]byte(data), &config); err != nil {
|
||||
log.Fatal(fmt.Errorf("failed to read config at %s:\n%w", path, err))
|
||||
}
|
||||
hm.Config = config
|
||||
}
|
||||
|
||||
func hyprctl(cmd string) []byte {
|
||||
socketPath := hyprSocket()
|
||||
conn, err := net.Dial("unix", socketPath)
|
||||
if err != nil {
|
||||
log.Fatalln("Error connecting to hyprland IPC:", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
_, err = conn.Write([]byte(cmd))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
buf := make([]byte, 1024*8) // Bigger?
|
||||
n, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return buf[0:n]
|
||||
}
|
||||
|
||||
type ActiveWorkspace struct {
|
||||
Name string
|
||||
Id int
|
||||
}
|
||||
|
||||
type Monitor struct {
|
||||
ActiveWorkspace ActiveWorkspace
|
||||
Id int
|
||||
}
|
||||
|
||||
// generic or interface?
|
||||
func getMonitors() []Monitor {
|
||||
data := hyprctl("[-j]/monitors")
|
||||
var monitors []Monitor
|
||||
err := json.Unmarshal(data, &monitors)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
return monitors
|
||||
}
|
||||
|
||||
func getClients() []Client {
|
||||
data := hyprctl("[-j]/clients")
|
||||
var clients []Client
|
||||
err := json.Unmarshal(data, &clients)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
return clients
|
||||
}
|
||||
|
||||
type EwwWorkspace struct {
|
||||
Icon string `json:"icon"`
|
||||
Class string `json:"class"`
|
||||
Id int `json:"id"`
|
||||
}
|
||||
|
||||
func (hm *Hyprman) pickIcon(class string) string {
|
||||
for k, v := range hm.Config.Classes {
|
||||
if strings.Contains(k, class) {
|
||||
return v
|
||||
}
|
||||
}
|
||||
return hm.Config.DefaultIcon
|
||||
}
|
||||
|
||||
func openWorkspaces(monitors []Monitor) []int {
|
||||
open := make([]int, len(monitors))
|
||||
for i, m := range monitors {
|
||||
open[i] = m.ActiveWorkspace.Id
|
||||
}
|
||||
return open
|
||||
}
|
||||
|
||||
func (hm *Hyprman) generateEwwClasses() {
|
||||
monitors := getMonitors()
|
||||
clients := getClients()
|
||||
|
||||
var ewwClasses [][]EwwWorkspace
|
||||
|
||||
monitor := make([]EwwWorkspace, 9)
|
||||
|
||||
for i := range 9 {
|
||||
monitor[i] = EwwWorkspace{
|
||||
hm.Config.NoClientIcon,
|
||||
fmt.Sprintf("ws-button-%d", i+1),
|
||||
i + 1,
|
||||
}
|
||||
}
|
||||
|
||||
for _, client := range clients {
|
||||
id := client.Workspace.Id - 1
|
||||
currentIcon := monitor[id].Icon
|
||||
if currentIcon == hm.Config.NoClientIcon {
|
||||
monitor[id].Icon = hm.pickIcon(client.Class)
|
||||
} else {
|
||||
monitor[id].Icon = fmt.Sprintf("%s%s", currentIcon, hm.pickIcon(client.Class))
|
||||
}
|
||||
}
|
||||
|
||||
for _, id := range openWorkspaces(monitors) {
|
||||
// activeId := m.ActiveWorkspace.Id
|
||||
monitor[id-1].Class = fmt.Sprintf("%s %s", monitor[id-1].Class, "ws-button-open")
|
||||
}
|
||||
|
||||
for i, m := range monitors {
|
||||
activeId := m.ActiveWorkspace.Id - 1
|
||||
ewwClasses = append(ewwClasses, make([]EwwWorkspace, 9))
|
||||
copy(ewwClasses[i], monitor)
|
||||
ewwClasses[i][activeId].Class = fmt.Sprintf("%s %s-%d", monitor[activeId].Class, "ws-button-active", activeId+1)
|
||||
|
||||
}
|
||||
|
||||
bytes, err := json.Marshal(ewwClasses)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(string(bytes))
|
||||
}
|
||||
|
||||
func ewwBar1(cmd string) {
|
||||
time.Sleep(200 * time.Second)
|
||||
if err := exec.Command("eww", cmd, "bar1").Run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func notify(message string) {
|
||||
cmd := exec.Command("notify-send", "hyprman", message)
|
||||
cmd.Run()
|
||||
}
|
||||
|
||||
func (hm *Hyprman) handleHyprEvent(line string) {
|
||||
s := strings.Split(line, ">>")
|
||||
event, _ := s[0], s[1]
|
||||
switch event {
|
||||
case "monitorremoved":
|
||||
notify("Monitor removed closing bar1")
|
||||
go ewwBar1("close")
|
||||
hm.generateEwwClasses()
|
||||
case "monitoradded":
|
||||
notify("Monitor added opening bar1")
|
||||
go ewwBar1("open")
|
||||
hm.generateEwwClasses()
|
||||
case "workspace",
|
||||
"focusedmon",
|
||||
"activewindow",
|
||||
"createworkspace",
|
||||
"destroyworkspace",
|
||||
"moveworkspace",
|
||||
"renameworkspace",
|
||||
"openwindow",
|
||||
"closewindow",
|
||||
"movewindow",
|
||||
"movewindowv2",
|
||||
"changefloatingmode",
|
||||
"windowtitle",
|
||||
"togglegroup",
|
||||
"moveintogroup",
|
||||
"moveoutofgroup",
|
||||
"configreloaded":
|
||||
hm.generateEwwClasses()
|
||||
}
|
||||
}
|
||||
|
||||
func (hm *Hyprman) LaunchEww() {
|
||||
for i := range getMonitors() {
|
||||
if err := exec.Command("eww", "open", fmt.Sprintf("bar%d", i)).Run(); err != nil {
|
||||
notify(fmt.Sprintf("Error lanching eww:\n%v", err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (hm *Hyprman) Watch() {
|
||||
socketPath := hyprSocket2()
|
||||
conn, err := net.Dial("unix", socketPath)
|
||||
if err != nil {
|
||||
log.Fatalln("Error connecting to hyprland IPC:", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
reader := bufio.NewReader(conn)
|
||||
hm.generateEwwClasses()
|
||||
for {
|
||||
line, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
// log.Printf("reached EOF for %s\n", socketPath)
|
||||
break
|
||||
}
|
||||
// log.Println("error reading line")
|
||||
continue
|
||||
}
|
||||
hm.handleHyprEvent(line)
|
||||
}
|
||||
}
|
||||
|
36
internal/mako.go
Normal file
36
internal/mako.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package hyprman
|
||||
|
||||
// import (
|
||||
// "log"
|
||||
// "os/exec"
|
||||
// )
|
||||
//
|
||||
// type MakoHistory struct {
|
||||
// Type string `json:"type"`
|
||||
// Data [][]MakoNotification `json:"data"`
|
||||
// }
|
||||
//
|
||||
// type MakoNotification struct {
|
||||
// AppName MakoNotificationData `json:"app-name"`
|
||||
// // AppIcon MakoNotificationData `json:"app-icon"`
|
||||
// // Category MakoNotificationData
|
||||
// // DesktopEntry MakoNotificationData `json:"desktop-entry"`
|
||||
// Summary MakoNotificationData `json:"summary"`
|
||||
// Body MakoNotificationData
|
||||
// // Id MakoNotificationData
|
||||
// // Urgency MakoNotificationData
|
||||
// // Actions MakoNotificationData
|
||||
// }
|
||||
//
|
||||
// type MakoNotificationData struct {
|
||||
// Type string `json:"type"`
|
||||
// Data string `json:"data"`
|
||||
// }
|
||||
//
|
||||
// func getHistory() MakoHistory {
|
||||
// makoOutput, err := exec.Command("makoctl", "history").CombinedOutput()
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// }
|
||||
|
7
main.go
Normal file
7
main.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package main
|
||||
|
||||
import "git.dayl.in/daylin/hyprman/cmd"
|
||||
|
||||
func main() {
|
||||
cmd.Execute()
|
||||
}
|
8
todo.md
Normal file
8
todo.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
# hyprman-go todo's
|
||||
|
||||
- [ ] include in class the 'other' active monitor?
|
||||
- [ ] use goroutine with slightly delay to "open/close"
|
||||
bar to give hyprland time to draw/setup monitor
|
||||
|
||||
<!-- generated with <3 by daylinmorgan/todo -->
|
||||
|
Loading…
Reference in a new issue