aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/pipewire
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-12-11 03:34:33 +0900
committerOphestra <cat@gensokyo.uk>2025-12-11 03:34:33 +0900
commit0a3fe5f907d868f828f64c650e7a63a599e7ed68 (patch)
tree9cec0462e6ec4cddd8c4de1cbe27b0c0c860d97f /internal/pipewire
parentb72d502f1c5568cd8f93c9142247fa0d94caece5 (diff)
internal/pipewire: export Registry::Destroy
This handles the error returned by Sync. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/pipewire')
-rw-r--r--internal/pipewire/core.go31
-rw-r--r--internal/pipewire/pipewire.go14
-rw-r--r--internal/pipewire/pipewire_test.go5
3 files changed, 49 insertions, 1 deletions
diff --git a/internal/pipewire/core.go b/internal/pipewire/core.go
index d2677818..a53f02d5 100644
--- a/internal/pipewire/core.go
+++ b/internal/pipewire/core.go
@@ -641,6 +641,37 @@ func (registry *Registry) destroy(id Int) error {
)
}
+// Destroy tries to destroy the global object with id.
+func (registry *Registry) Destroy(id Int) error {
+ if err := registry.destroy(id); err != nil {
+ return err
+ }
+ destroySeq := registry.ctx.currentSeq()
+
+ err := registry.ctx.GetCore().Sync()
+ if err == nil {
+ return nil
+ }
+
+ var coreError *CoreError
+ if proxyErrors, ok := err.(ProxyConsumeError); !ok ||
+ len(proxyErrors) != 1 ||
+ !errors.As(proxyErrors[0], &coreError) ||
+ coreError == nil ||
+ coreError.ID != registry.ID ||
+ coreError.Sequence != destroySeq {
+ return err
+ }
+
+ switch syscall.Errno(-coreError.Result) {
+ case syscall.EPERM:
+ return &PermissionError{registry.ID, coreError.Message}
+
+ default:
+ return coreError
+ }
+}
+
// An UnsupportedObjectTypeError is the name of a type not known by the server [Registry].
type UnsupportedObjectTypeError string
diff --git a/internal/pipewire/pipewire.go b/internal/pipewire/pipewire.go
index a87a4e95..5473797c 100644
--- a/internal/pipewire/pipewire.go
+++ b/internal/pipewire/pipewire.go
@@ -636,7 +636,7 @@ func (ctx *Context) roundtrip() (err error) {
}
// currentSeq returns the current sequence number.
-// This must only be called from eventProxy.consume.
+// This must only be called immediately after queueing a message.
func (ctx *Context) currentSeq() Int { return ctx.sequence - 1 }
// currentRemoteSeq returns the current remote sequence number.
@@ -786,6 +786,18 @@ func (ctx *Context) Close() (err error) {
}
}
+// A PermissionError describes an error emitted by the server when trying to
+// perform an operation that the client has no permission for.
+type PermissionError struct {
+ // The id of the resource (proxy if emitted by the client) that is in error.
+ ID Int `json:"id"`
+ // An error message.
+ Message string `json:"message"`
+}
+
+func (*PermissionError) Unwrap() error { return syscall.EPERM }
+func (e *PermissionError) Error() string { return e.Message }
+
// Remote is the environment (sic) with the remote name.
const Remote = "PIPEWIRE_REMOTE"
diff --git a/internal/pipewire/pipewire_test.go b/internal/pipewire/pipewire_test.go
index 7c2cc332..afa2d7e4 100644
--- a/internal/pipewire/pipewire_test.go
+++ b/internal/pipewire/pipewire_test.go
@@ -870,6 +870,11 @@ func TestContextErrors(t *testing.T) {
}, "new Registry::Global event for PipeWire:Interface:NewInvalid stepping on previous id 2989 for PipeWire:Interface:Invalid"},
{"UnknownGlobalIDRemoveError", pipewire.UnknownGlobalIDRemoveError(0xbad), "Registry::GlobalRemove event targets unknown id 2989"},
+
+ {"PermissionError", &pipewire.PermissionError{
+ ID: 2,
+ Message: "no permission to destroy 0",
+ }, "no permission to destroy 0"},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {