diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-11-15 23:20:03 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-11-15 23:25:46 +0900 |
| commit | fe40af7b7e95356b7d88e35941097edc9700f093 (patch) | |
| tree | d04ddc46f4cf053e51156e1c08cdeaf16dd2a2fa /system | |
| parent | 12751932d1cbfc911a75445061d87264b927de5f (diff) | |
internal/wayland: relocate connection struct
This interface is getting replaced, so relocating it to the deprecated wrapper package before working on its replacement.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'system')
| -rw-r--r-- | system/wayland/deprecated.go | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/system/wayland/deprecated.go b/system/wayland/deprecated.go index e83c9107..e544597e 100644 --- a/system/wayland/deprecated.go +++ b/system/wayland/deprecated.go @@ -4,13 +4,89 @@ package wayland import ( + "errors" + "net" + "os" + "runtime" + "sync" + "syscall" _ "unsafe" // for go:linkname "hakurei.app/internal/wayland" ) // Conn represents a connection to the wayland display server. -type Conn = wayland.Conn +// +// Deprecated: this interface is being replaced. +// Additionally, the package it belongs to will be removed in 0.4. +type Conn struct { + conn *net.UnixConn + + done chan struct{} + doneOnce sync.Once + + mu sync.Mutex +} + +// Attach connects Conn to a wayland socket. +func (c *Conn) Attach(p string) (err error) { + c.mu.Lock() + defer c.mu.Unlock() + + if c.conn != nil { + return errors.New("socket already attached") + } + + c.conn, err = net.DialUnix("unix", nil, &net.UnixAddr{Name: p, Net: "unix"}) + return +} + +// Close releases resources and closes the connection to the wayland compositor. +func (c *Conn) Close() error { + c.mu.Lock() + defer c.mu.Unlock() + + if c.done == nil { + return errors.New("no socket bound") + } + + c.doneOnce.Do(func() { + c.done <- struct{}{} + <-c.done + }) + + // closed by wayland + runtime.SetFinalizer(c.conn, nil) + return nil +} + +//go:linkname bindRawConn hakurei.app/internal/wayland.bindRawConn +func bindRawConn(done chan struct{}, rc syscall.RawConn, p, appID, instanceID string) ([2]int, error) + +// Bind binds the new socket to pathname. +func (c *Conn) Bind(pathname, appID, instanceID string) (*os.File, error) { + c.mu.Lock() + defer c.mu.Unlock() + + if c.conn == nil { + return nil, errors.New("socket not attached") + } + if c.done != nil { + return nil, errors.New("socket already bound") + } + + if rc, err := c.conn.SyscallConn(); err != nil { + // unreachable + return nil, err + } else { + c.done = make(chan struct{}) + if closeFds, err := bindRawConn(c.done, rc, pathname, appID, instanceID); err != nil { + return nil, err + } else { + return os.NewFile(uintptr(closeFds[1]), "close_fd"), nil + } + } +} const ( // WaylandDisplay contains the name of the server socket |
