diff --git a/inputcontrol/controller.go b/inputcontrol/controller.go index 7e9e768..06ed8e4 100644 --- a/inputcontrol/controller.go +++ b/inputcontrol/controller.go @@ -70,11 +70,15 @@ func RegisterController(name string, init func() (Controller, error), priority i } type UnsupportedPlatformError struct { - err error + Err error } -func (e UnsupportedPlatformError) Error() string { - return e.err.Error() +func (e *UnsupportedPlatformError) Error() string { + return e.Err.Error() +} + +func (e *UnsupportedPlatformError) Unwrap() error { + return e.Err } type Controller interface { diff --git a/inputcontrol/controller_portal.go b/inputcontrol/controller_portal.go index 05ffb1d..d8e2700 100644 --- a/inputcontrol/controller_portal.go +++ b/inputcontrol/controller_portal.go @@ -55,7 +55,7 @@ func init() { func InitPortalController() (Controller, error) { bus, err := dbus.SessionBusPrivate() if err != nil { - return nil, UnsupportedPlatformError{err} + return nil, &UnsupportedPlatformError{err} } cleanupBus := true defer func() { @@ -65,49 +65,49 @@ func InitPortalController() (Controller, error) { }() err = bus.Auth(nil) if err != nil { - return nil, UnsupportedPlatformError{err} + return nil, &UnsupportedPlatformError{err} } err = bus.Hello() if err != nil { - return nil, UnsupportedPlatformError{err} + return nil, &UnsupportedPlatformError{err} } remoteDesktop := bus.Object("org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop") availableDeviceTypesV, err := remoteDesktop.GetProperty( "org.freedesktop.portal.RemoteDesktop.AvailableDeviceTypes") if err != nil { - return nil, UnsupportedPlatformError{err} + return nil, &UnsupportedPlatformError{err} } availableDeviceTypes, ok := availableDeviceTypesV.Value().(uint32) if !ok { - return nil, UnsupportedPlatformError{errors.New( - "unexpected 'AvailableDeviceTypes' return type")} + return nil, &UnsupportedPlatformError{ + errors.New("unexpected 'AvailableDeviceTypes' return type")} } if availableDeviceTypes&deviceKeyboard == 0 || availableDeviceTypes&devicePointer == 0 { - return nil, UnsupportedPlatformError{errors.New( - "keyboard or pointer source type not supported")} + return nil, &UnsupportedPlatformError{ + errors.New("keyboard or pointer source type not supported")} } inVardict := make(map[string]dbus.Variant) inVardict["session_handle_token"] = dbus.MakeVariant("t") result, outVardict, err := getResponse(bus, remoteDesktop, "org.freedesktop.portal.RemoteDesktop.CreateSession", 0, inVardict) if err != nil { - return nil, UnsupportedPlatformError{err} + return nil, &UnsupportedPlatformError{err} } if result != 0 { - return nil, UnsupportedPlatformError{errors.New(fmt.Sprintf( - "Calling 'CreateSession' failed (%v)", result))} + return nil, &UnsupportedPlatformError{ + fmt.Errorf("Calling 'CreateSession' failed (%v)", result)} } sessionHandleV, ok := outVardict["session_handle"] if !ok { - return nil, UnsupportedPlatformError{errors.New( - "'session_handle' missing from 'CreateSession' return value")} + return nil, &UnsupportedPlatformError{ + errors.New("'session_handle' missing from 'CreateSession' return value")} } sessionHandleS, ok := sessionHandleV.Value().(string) if !ok { - return nil, UnsupportedPlatformError{errors.New( - "unexpected 'session_handle' type in 'CreateSession' return value")} + return nil, &UnsupportedPlatformError{ + errors.New("unexpected 'session_handle' type in 'CreateSession' return value")} } sessionHandle := dbus.ObjectPath(sessionHandleS) inVardict = make(map[string]dbus.Variant) @@ -115,30 +115,30 @@ func InitPortalController() (Controller, error) { result, outVardict, err = getResponse(bus, remoteDesktop, "org.freedesktop.portal.RemoteDesktop.SelectDevices", 0, sessionHandle, inVardict) if err != nil { - return nil, UnsupportedPlatformError{err} + return nil, &UnsupportedPlatformError{err} } if result != 0 { - return nil, UnsupportedPlatformError{errors.New(fmt.Sprintf( - "Calling 'SelectDevices' failed (%v)", result))} + return nil, &UnsupportedPlatformError{ + fmt.Errorf("Calling 'SelectDevices' failed (%v)", result)} } inVardict = make(map[string]dbus.Variant) result, outVardict, err = getResponse(bus, remoteDesktop, "org.freedesktop.portal.RemoteDesktop.Start", 0, sessionHandle, "", inVardict) if err != nil { - return nil, UnsupportedPlatformError{err} + return nil, &UnsupportedPlatformError{err} } if result != 0 { return nil, errors.New("keyboard or pointer access denied") } devicesV, ok := outVardict["devices"] if !ok { - return nil, UnsupportedPlatformError{errors.New( - "'devices' missing from 'Start' return value")} + return nil, &UnsupportedPlatformError{ + errors.New("'devices' missing from 'Start' return value")} } devices, ok := devicesV.Value().(uint32) if !ok { - return nil, UnsupportedPlatformError{errors.New( - "unexpected 'devices' type in 'Start' return value")} + return nil, &UnsupportedPlatformError{ + errors.New("unexpected 'devices' type in 'Start' return value")} } if devices&deviceKeyboard == 0 || devices&devicePointer == 0 { return nil, errors.New("keyboard or pointer access denied") diff --git a/inputcontrol/controller_windows.go b/inputcontrol/controller_windows.go index 8cb73a7..78c36a8 100644 --- a/inputcontrol/controller_windows.go +++ b/inputcontrol/controller_windows.go @@ -98,7 +98,7 @@ func init() { func InitWindowsController() (Controller, error) { p := &windowsController{} if err := sendInputProc.Find(); err != nil { - return nil, UnsupportedPlatformError{err} + return nil, &UnsupportedPlatformError{err} } return p, nil } diff --git a/inputcontrol/controller_x11.go b/inputcontrol/controller_x11.go index bc1ec6b..c5d19d9 100644 --- a/inputcontrol/controller_x11.go +++ b/inputcontrol/controller_x11.go @@ -61,13 +61,13 @@ func init() { func InitX11Controller() (Controller, error) { display := C.XOpenDisplay(nil) if display == nil { - return nil, UnsupportedPlatformError{ + return nil, &UnsupportedPlatformError{ errors.New("failed to connect to X server")} } p := &x11Controller{display: display} if p.xIsXwayland() { p.Close() - return nil, UnsupportedPlatformError{ + return nil, &UnsupportedPlatformError{ errors.New("X server is Xwayland")} } return p, nil diff --git a/main.go b/main.go index 63d32fb..be123cd 100644 --- a/main.go +++ b/main.go @@ -184,21 +184,25 @@ func main() { } var controller inputcontrol.Controller var controllerName string - platformErrors := "" + var platformErrs []error for _, controllerInfo := range inputcontrol.Controllers { controllerName = controllerInfo.Name var err error controller, err = controllerInfo.Init() if err == nil { break - } else if _, ok := err.(inputcontrol.UnsupportedPlatformError); ok { - platformErrors += fmt.Sprintf("%s controller: %v\n", controllerName, err) } else { - log.Fatalf("%s controller: %v", controllerName, err) + var unsupportedErr *inputcontrol.UnsupportedPlatformError + wrappedErr := fmt.Errorf("%v controller: %w", controllerName, err) + if errors.As(err, &unsupportedErr) { + platformErrs = append(platformErrs, wrappedErr) + } else { + log.Fatal(wrappedErr) + } } } if controller == nil { - log.Fatal("unsupported platform:\n" + platformErrors) + log.Fatal(fmt.Errorf("unsupported platform:\n%w", errors.Join(platformErrs...))) } defer controller.Close() authenticationChallenges := make(chan challenge, authenticationRateBurst) @@ -241,7 +245,7 @@ func main() { return } if err := processCommand(controller, message); err != nil { - log.Printf("%s controller: %v", controllerName, err) + log.Print(fmt.Errorf("%s controller: %w", controllerName, err)) return } }