Compare commits

..

3 commits

4 changed files with 216 additions and 174 deletions

View file

@ -1,20 +1,23 @@
package cmd package cmd
import ( import (
"fmt" "git.dayl.in/daylin/hyprman/internal"
"github.com/spf13/cobra" "github.com/spf13/cobra"
// "git.dayl.in/daylin/hyprman/internal"
) )
var makoCmd = &cobra.Command{ var makoCmd = &cobra.Command{
Use: "mako", Use: "mako",
Short: "mako integration", Short: "mako integration",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
fmt.Println("hahah mako baby") hyprman.ListNotifications(number)
}, },
} }
var (
number int
)
func init() { func init() {
rootCmd.AddCommand(makoCmd) rootCmd.AddCommand(makoCmd)
makoCmd.Flags().IntVarP(&number, "number", "n", 10, "number of notifications")
} }

144
internal/eww.go Normal file
View file

@ -0,0 +1,144 @@
package hyprman
import (
"bufio"
"encoding/json"
"fmt"
"io"
"log"
"net"
"os/exec"
"strings"
"time"
)
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 (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(2 * time.Second)
if err := exec.Command("eww", cmd, "bar1").Run(); err != nil {
log.Fatal(err)
}
}
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)
}
}

View file

@ -1,17 +1,13 @@
package hyprman package hyprman
import ( import (
"bufio"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"log" "log"
"net" "net"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strings"
"time"
yaml "github.com/goccy/go-yaml" yaml "github.com/goccy/go-yaml"
) )
@ -133,21 +129,6 @@ func getClients() []Client {
return clients 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 { func openWorkspaces(monitors []Monitor) []int {
open := make([]int, len(monitors)) open := make([]int, len(monitors))
for i, m := range monitors { for i, m := range monitors {
@ -156,124 +137,12 @@ func openWorkspaces(monitors []Monitor) []int {
return open 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) { func notify(message string) {
cmd := exec.Command("notify-send", "hyprman", message) cmd := exec.Command(
"notify-send",
"--app-name=hyprman",
"--transient",
message,
)
cmd.Run() 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)
}
}

View file

@ -1,35 +1,61 @@
package hyprman package hyprman
// import ( import (
// "log" "encoding/json"
// "os/exec" "fmt"
// ) "log"
// "os/exec"
// type MakoHistory struct { )
// Type string `json:"type"`
// Data [][]MakoNotification `json:"data"` type MakoHistory struct {
// } Type string `json:"type"`
// Data [][]MakoNotification `json:"data"`
// type MakoNotification struct { }
// AppName MakoNotificationData `json:"app-name"`
// // AppIcon MakoNotificationData `json:"app-icon"` type MakoNotification struct {
// // Category MakoNotificationData AppName MakoNotificationData `json:"app-name"`
// // DesktopEntry MakoNotificationData `json:"desktop-entry"` Summary MakoNotificationData
// Summary MakoNotificationData `json:"summary"` Body MakoNotificationData
// Body MakoNotificationData // AppIcon MakoNotificationData `json:"app-icon"`
// // Id MakoNotificationData // Category MakoNotificationData
// // Urgency MakoNotificationData // DesktopEntry MakoNotificationData `json:"desktop-entry"`
// // Actions MakoNotificationData // Id MakoNotificationData
// } // Urgency MakoNotificationData
// // Actions MakoNotificationData
// type MakoNotificationData struct { }
// Type string `json:"type"`
// Data string `json:"data"` type MakoNotificationData struct {
// } Type string `json:"type"`
// Data string `json:"data"`
// func getHistory() MakoHistory { }
// makoOutput, err := exec.Command("makoctl", "history").CombinedOutput()
// if err != nil { func getHistory() MakoHistory {
// log.Fatal(err) var history MakoHistory
// } makoOutput, err := exec.Command("makoctl", "history").CombinedOutput()
// } if err != nil {
log.Fatal(err)
}
json.Unmarshal(makoOutput, &history)
return history
}
func displayNotification(n MakoNotification) {
fmt.Println("--- ", n.AppName.Data)
if len(n.Summary.Data) > 0 {
fmt.Println(n.Summary.Data)
}
if len(n.Body.Data) > 0 {
fmt.Println(n.Body.Data)
}
}
func ListNotifications(number int) {
history := getHistory()
// TODO: align output ? by app-name
for i, notification := range history.Data[0] {
displayNotification(notification)
if i > number-1 {
break
}
}
}