rajveermalviya / go-wayland Goto Github PK
View Code? Open in Web Editor NEWWayland Client in Pure Go
License: BSD 2-Clause "Simplified" License
Wayland Client in Pure Go
License: BSD 2-Clause "Simplified" License
Hi! it would be extremely beneficial if go-wayland-scanner could be abstracted into a library instead of a binary.
This would help downstream repositories easily integrate go-wayland into their build system by calling it in a build step programmatically instead of having to look for a binary. Eg: https://github.com/waycrate/NextWM/blob/master/nextctl-go/Makefile#L13
This reduces complexity to contribution for downstream projects and increases usability.
When Compositor send fd
to Client, only the following conditions will be ensured:
fd
s will be send in order.fd
is send with Event's Head or Body, not part of them.fd
arg fdB, when eB's Body have been sent, fdB must have been sent too.fdB is not ensured to be send with eB's Head or Body.
Assume Event eA was Sent before eB, fdB can be send with eA's Head or Body, no matter eA have fd
arg or not.
So the right way to receive fd
is try to read fd
from every Event's Head and Body, if get fd
, put it into a que in order.
When a Event that has fd
arg has been read and parsed, get fd
from que in order.
Because your Context.ReadMsg only use ReadMsgUnix for event header, but the fd may be send with the body of the event.
When oobn is 0 after read event header, you should use ReadMsgUnix to read event body and get oob data.
Currently, go-wayland-scanner
generates a piece of code that uses reflect
to
get the pointer of a Go closure to compare its value with existing closures
added inside a registry, like so:
go-wayland/cmd/go-wayland-scanner/scanner.go
Line 624 in 5ab8266
This piece of code depends on an implementation detail that may not necessarily
be correct in all cases, which is why Go doesn't allow comparing closures in the
first place.
To fix this, I propose adding a new
github.com/rajveermalviya/go-wayland/wayland/utils/handler
package that
contains specific structures to hold closures and allow removing them using a
callback.
Package handler
should expose a public API that looks roughly like this
pseudocode:
package handler
// Registry implements a registry of function handlers. All its methods are
// concurrently safe.
type Registry struct {
mu sync.Mutex
// any implementation
}
// Add adds the given function value into the registry and returns a function
// that removes the given function from the registry.
func (r *Registry) Add(fn interface{}) (remove func())
The generated code could then look like this:
// AddConfigureHandler : adds handler for SurfaceConfigureEvent
func (i *Surface) AddConfigureHandler(f SurfaceConfigureHandlerFunc) (remove func()) {
if f == nil {
return
}
return i.configureHandlers.Add(f)
}
Package handler
can be implemented in multiple ways. One way would be to wrap
the closure inside a boxed struct and use its pointer as the key to a map:
type Registry struct {
mu sync.Mutex
h map[*box]struct{}
}
type box struct {
v interface{}
}
func (r *Registry) Add(fn interface{}) func() {
v := &box{fn}
r.mu.Lock()
r.h[v] = struct{}{}
r.mu.Unlock()
return func() {
r.mu.Lock()
delete(r.h, v)
r.mu.Unlock()
}
}
While this is the simplest way to implement handler
, it might be fairly costly
on the garbage collector, since an extra heap pointer will be made for each
closure added, and if the user removes closures a lot, the garbage collector
will likely spend a lot of time catching up to free the boxes.
Another way that is slightly more complicated would be to use a free list, like
what I have in diamondburned/arikawa/v3/utils/handler.
Since GO's goroutine is lightweight thread and GO's Channel is perfect Queue, is very easy to give every Proxy a goroutine and Event Que.
In every goroutine use a loop to get Event from Event Que and handle it.
The problem is how to "flush" a Proxy Event Que?
My anser is to use a Mark Event.
A Mark Event markEvt
is a special Event which hold a Channel markEvt.SyncCh=make(chan byte, 1)
.
When I wanna "flush" Proxy pA
's Event Que, I use Display.Sync
to get a Callback
, in Callback
's DoneHandler
I put a Mark Event markEvt
in pA
's Event Que ch:=make(chan byte,1);pA.EvtQue<-&Event{SyncCh: ch}
, and use <-ch
to block my goroutine.
When pA
's Event Handle Loop get a Event evt
that evt.SyncCh!=nil
, it will use evt.SyncCh<-0
to unblock my goroutine.
First of all thank you for your contribution, I've learned a lot from reading your codes.
And I wanna feed you back by helping you with your code, here's one issue I find in your code:
When the Wayland say it's stream bytes use your nativebyteorder, it means you don't need to worry about the byteorder;
so you can just use pointer convertion to convert between Value(Go Values) and Data(Stream []byte);
no need to find out native byteorder, then use NativeEndian's , PutUintX, UintX to convert between Value and Data.
Here's some code may help you to understand: byteorder sample codes
I use go work
to maintain the work space, which makes things much easier;
I learned that from your codes, so thanks again.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.