Skip to content

Commit

Permalink
Merge pull request #106 from nwg-piotr/otput-hypr
Browse files Browse the repository at this point in the history
Make binding to an output work on Hyprland
  • Loading branch information
nwg-piotr authored Nov 26, 2023
2 parents b05b0f4 + 55c095c commit 223e16f
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 35 deletions.
46 changes: 36 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@ import (
"github.com/gotk3/gotk3/gtk"
)

const version = "0.4.2"
const version = "0.4.3"

var (
appDirs []string
configDirectory string
pinnedFile string
pinned []string
id2entry map[string]desktopEntry
preferredApps map[string]interface{}
exclusions []string
appDirs []string
configDirectory string
pinnedFile string
pinned []string
id2entry map[string]desktopEntry
preferredApps map[string]interface{}
exclusions []string
hyprlandMonitors []monitor
)

var categoryNames = [...]string{
Expand Down Expand Up @@ -66,6 +67,30 @@ type desktopEntry struct {
NoDisplay bool
}

type monitor struct {
Id int `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Make string `json:"make"`
Model string `json:"model"`
Serial string `json:"serial"`
Width int `json:"width"`
Height int `json:"height"`
RefreshRate float64 `json:"refreshRate"`
X int `json:"x"`
Y int `json:"y"`
ActiveWorkspace struct {
Id int `json:"id"`
Name string `json:"name"`
} `json:"activeWorkspace"`
Reserved []int `json:"reserved"`
Scale float64 `json:"scale"`
Transform int `json:"transform"`
Focused bool `json:"focused"`
DpmsStatus bool `json:"dpmsStatus"`
Vrr bool `json:"vrr"`
}

// slices below will hold DesktopID strings
var (
listUtility []string
Expand Down Expand Up @@ -123,7 +148,7 @@ func validateWm() {

// Flags
var cssFileName = flag.String("s", "drawer.css", "Styling: css file name")
var targetOutput = flag.String("o", "", "name of the Output to display the drawer on (sway only)")
var targetOutput = flag.String("o", "", "name of the Output to display the drawer on (sway & Hyprland only)")
var displayVersion = flag.Bool("v", false, "display Version information")
var keyboard = flag.Bool("k", false, "set GTK layer shell Keyboard interactivity to 'on-demand' mode")
var overlay = flag.Bool("ovl", false, "use OVerLay layer")
Expand All @@ -141,7 +166,7 @@ var itemSpacing = flag.Uint("spacing", 20, "icon spacing")
var lang = flag.String("lang", "", "force lang, e.g. \"en\", \"pl\"")
var fileManager = flag.String("fm", "thunar", "File Manager")
var term = flag.String("term", defaultTermIfBlank(os.Getenv("TERM"), "foot"), "Terminal emulator")
var wm = flag.String("wm", "", "Use `swaymsg exec` (with 'sway' argument) or `hyprctl dispatch exec` (with 'hyprland') to launch programs")
var wm = flag.String("wm", "", "use swaymsg exec (with 'sway' argument) or hyprctl dispatch exec (with 'hyprland') to launch programs")
var nameLimit = flag.Int("fslen", 80, "File Search name LENgth Limit")
var noCats = flag.Bool("nocats", false, "Disable filtering by category")
var noFS = flag.Bool("nofs", false, "Disable file search")
Expand Down Expand Up @@ -372,6 +397,7 @@ func main() {
if *targetOutput != "" {
// We want to assign layershell to a monitor, but we only know the output name!
output2mon, err = mapOutputs()
fmt.Println(">>>", output2mon)
if err == nil {
monitor := output2mon[*targetOutput]
layershell.SetMonitor(win, monitor)
Expand Down
114 changes: 89 additions & 25 deletions tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/joshuarubin/go-sway"
log "github.com/sirupsen/logrus"
"io"
"io/fs"
"net"
"os"
"os/exec"
"path"
Expand All @@ -17,11 +20,8 @@ import (
"syscall"
"time"

log "github.com/sirupsen/logrus"

"github.com/gotk3/gotk3/gdk"
"github.com/gotk3/gotk3/gtk"
"github.com/joshuarubin/go-sway"
)

func wayland() bool {
Expand Down Expand Up @@ -651,35 +651,64 @@ func open(filePath string, xdgOpen bool) {
func mapOutputs() (map[string]*gdk.Monitor, error) {
result := make(map[string]*gdk.Monitor)

ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
if os.Getenv("HYPRLAND_INSTANCE_SIGNATURE") != "" {
err := listHyprlandMonitors()
if err == nil {

client, err := sway.New(ctx)
if err != nil {
return nil, err
}
display, err := gdk.DisplayGetDefault()
if err != nil {
return nil, err
}

outputs, err := client.GetOutputs(ctx)
if err != nil {
return nil, err
}
num := display.GetNMonitors()
for i := 0; i < num; i++ {
mon, _ := display.GetMonitor(i)
geometry := mon.GetGeometry()
// assign output to monitor on the basis of the same x, y coordinates
for _, output := range hyprlandMonitors {
if int(output.X) == geometry.GetX() && int(output.Y) == geometry.GetY() {
result[output.Name] = mon
}
}
}
} else {
return nil, err
}

display, err := gdk.DisplayGetDefault()
if err != nil {
return nil, err
}
} else if os.Getenv("SWAYSOCK") != "" {
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()

client, err := sway.New(ctx)
if err != nil {
return nil, err
}

outputs, err := client.GetOutputs(ctx)
if err != nil {
return nil, err
}

display, err := gdk.DisplayGetDefault()
if err != nil {
return nil, err
}

num := display.GetNMonitors()
for i := 0; i < num; i++ {
monitor, _ := display.GetMonitor(i)
geometry := monitor.GetGeometry()
// assign output to monitor on the basis of the same x, y coordinates
for _, output := range outputs {
if int(output.Rect.X) == geometry.GetX() && int(output.Rect.Y) == geometry.GetY() {
result[output.Name] = monitor
num := display.GetNMonitors()
for i := 0; i < num; i++ {
monitor, _ := display.GetMonitor(i)
geometry := monitor.GetGeometry()
// assign output to monitor on the basis of the same x, y coordinates
for _, output := range outputs {
if int(output.Rect.X) == geometry.GetX() && int(output.Rect.Y) == geometry.GetY() {
result[output.Name] = monitor
}
}
}
} else {
return nil, errors.New("output assignment only supported on sway and Hyprland")
}

return result, nil
}

Expand All @@ -698,3 +727,38 @@ func substring(s string, start int, end int) string {
}
return s[startStrIdx:]
}

func hyprctl(cmd string) ([]byte, error) {
his := os.Getenv("HYPRLAND_INSTANCE_SIGNATURE")
socketFile := fmt.Sprintf("/tmp/hypr/%s/.socket.sock", his)
conn, err := net.Dial("unix", socketFile)
if err != nil {
return nil, err
}

message := []byte(cmd)
_, err = conn.Write(message)
if err != nil {
return nil, err
}

reply := make([]byte, 102400)
n, err := conn.Read(reply)
if err != nil {
return nil, err
}

defer conn.Close()

return reply[:n], nil
}

func listHyprlandMonitors() error {
reply, err := hyprctl("j/monitors")
if err != nil {
return err
} else {
err = json.Unmarshal([]byte(reply), &hyprlandMonitors)
}
return err
}

0 comments on commit 223e16f

Please sign in to comment.