Add support for session restore on the linux portals backend, fixing #77
This commit is contained in:
parent
7a806f7b00
commit
c6c54c77a7
8 changed files with 70 additions and 13 deletions
12
README.md
12
README.md
|
|
@ -12,8 +12,16 @@ Supports Flatpak's RemoteDesktop portal (for Wayland), Windows and X11.
|
|||
* [Snap](https://snapcraft.io/remote-touchpad)
|
||||
* [Windows](https://github.com/Unrud/remote-touchpad/releases/latest)
|
||||
* Golang:
|
||||
* Portal & uinput & X11: `go install -tags portal,uinput,x11 github.com/unrud/remote-touchpad@latest`
|
||||
* Windows: `go install github.com/unrud/remote-touchpad@latest`
|
||||
* Portal & uinput & X11:
|
||||
|
||||
```sh
|
||||
go install -tags portal,uinput,x11 github.com/unrud/remote-touchpad@latest
|
||||
```
|
||||
* Windows:
|
||||
|
||||
```sh
|
||||
go install github.com/unrud/remote-touchpad@latest
|
||||
```
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
|
|
|||
|
|
@ -55,14 +55,14 @@ const (
|
|||
|
||||
type ControllerInfo struct {
|
||||
Name string
|
||||
Init func() (Controller, error)
|
||||
Init func(bool) (Controller, error)
|
||||
|
||||
priority int
|
||||
}
|
||||
|
||||
var Controllers []ControllerInfo
|
||||
|
||||
func RegisterController(name string, init func() (Controller, error), priority int) {
|
||||
func RegisterController(name string, init func(bool) (Controller, error), priority int) {
|
||||
Controllers = append(Controllers, ControllerInfo{name, init, priority})
|
||||
sort.SliceStable(Controllers, func(i, j int) bool {
|
||||
return Controllers[i].priority < Controllers[j].priority
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ func init() {
|
|||
RegisterController("null", InitNullController, 1000)
|
||||
}
|
||||
|
||||
func InitNullController() (Controller, error) {
|
||||
func InitNullController(saveRestoreToken bool) (Controller, error) {
|
||||
return &nullController{}, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"github.com/godbus/dbus/v5"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -34,6 +36,8 @@ const (
|
|||
btnReleased uint32 = 0
|
||||
btnPressed uint32 = 1
|
||||
|
||||
untilRevoked uint32 = 2
|
||||
|
||||
// linux/input-event-codes.h
|
||||
btnLeft int32 = 0x110
|
||||
btnRight int32 = 0x111
|
||||
|
|
@ -50,7 +54,26 @@ func init() {
|
|||
RegisterController("RemoteDesktop portal", InitPortalController, 1)
|
||||
}
|
||||
|
||||
func InitPortalController() (Controller, error) {
|
||||
func InitPortalController(saveRestoreToken bool) (Controller, error) {
|
||||
cacheDirectory, err := os.UserCacheDir()
|
||||
var restoreTokenFilePath string
|
||||
var restoreToken string
|
||||
if err != nil {
|
||||
err = errors.Join(errors.New("Cannot get user cache directory, therefore cannot get restore token file path in order to read or save the restore token. "), err)
|
||||
if saveRestoreToken == true {
|
||||
return nil, err
|
||||
} else {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
} else {
|
||||
restoreTokenFilePath = filepath.Join(cacheDirectory, "remote_touchpad_portals_restore_token")
|
||||
restoreTokenBytes, err := os.ReadFile(restoreTokenFilePath)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to read restore token file: %s\n", err)
|
||||
} else {
|
||||
restoreToken = string(restoreTokenBytes)
|
||||
}
|
||||
}
|
||||
bus, err := dbus.SessionBusPrivate()
|
||||
if err != nil {
|
||||
return nil, &UnsupportedPlatformError{err}
|
||||
|
|
@ -81,10 +104,18 @@ func InitPortalController() (Controller, error) {
|
|||
return nil, &UnsupportedPlatformError{
|
||||
errors.New("unexpected 'AvailableDeviceTypes' return type")}
|
||||
}
|
||||
if availableDeviceTypes&deviceKeyboard == 0 ||
|
||||
if availableDeviceTypes&deviceKeyboard == 0 &&
|
||||
availableDeviceTypes&devicePointer == 0 {
|
||||
return nil, &UnsupportedPlatformError{
|
||||
errors.New("keyboard or pointer source type not supported")}
|
||||
errors.New("keyboard and pointer source type not supported")}
|
||||
}
|
||||
if availableDeviceTypes&deviceKeyboard == 0 {
|
||||
return nil, &UnsupportedPlatformError{
|
||||
errors.New("keyboard source type not supported")}
|
||||
}
|
||||
if availableDeviceTypes&devicePointer == 0 {
|
||||
return nil, &UnsupportedPlatformError{
|
||||
errors.New("pointer source type not supported")}
|
||||
}
|
||||
inVardict := make(map[string]dbus.Variant)
|
||||
inVardict["session_handle_token"] = dbus.MakeVariant("t")
|
||||
|
|
@ -110,6 +141,12 @@ func InitPortalController() (Controller, error) {
|
|||
sessionHandle := dbus.ObjectPath(sessionHandleS)
|
||||
inVardict = make(map[string]dbus.Variant)
|
||||
inVardict["types"] = dbus.MakeVariant(deviceKeyboard | devicePointer)
|
||||
if restoreToken != "" {
|
||||
inVardict["restore_token"] = dbus.MakeVariant(restoreToken)
|
||||
}
|
||||
if saveRestoreToken {
|
||||
inVardict["persist_mode"] = dbus.MakeVariant(untilRevoked)
|
||||
}
|
||||
result, outVardict, err = getResponse(bus, remoteDesktop,
|
||||
"org.freedesktop.portal.RemoteDesktop.SelectDevices", 0, sessionHandle, inVardict)
|
||||
if err != nil {
|
||||
|
|
@ -128,6 +165,17 @@ func InitPortalController() (Controller, error) {
|
|||
if result != 0 {
|
||||
return nil, errors.New("keyboard or pointer access denied")
|
||||
}
|
||||
if saveRestoreToken {
|
||||
restoreToken, ok := outVardict["restore_token"].Value().(string)
|
||||
if !ok {
|
||||
return nil, errors.New("Failed to get new restore token")
|
||||
} else {
|
||||
err := os.WriteFile(restoreTokenFilePath, []byte(restoreToken), 0644)
|
||||
if err != nil {
|
||||
return nil, errors.Join(errors.New("Failed to write restore token: "), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
devicesV, ok := outVardict["devices"]
|
||||
if !ok {
|
||||
return nil, &UnsupportedPlatformError{
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ func init() {
|
|||
RegisterController("uinput", InitUinputController, 10)
|
||||
}
|
||||
|
||||
func InitUinputController() (Controller, error) {
|
||||
func InitUinputController(saveRestoreToken bool) (Controller, error) {
|
||||
keymapName, keymapSet := os.LookupEnv("REMOTE_TOUCHPAD_UINPUT_KEYMAP")
|
||||
if !keymapSet {
|
||||
keymapName = "defkeymap"
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ func init() {
|
|||
RegisterController("Windows", InitWindowsController, 0)
|
||||
}
|
||||
|
||||
func InitWindowsController() (Controller, error) {
|
||||
func InitWindowsController(saveRestoreToken bool) (Controller, error) {
|
||||
p := &windowsController{}
|
||||
if err := sendInputProc.Find(); err != nil {
|
||||
return nil, &UnsupportedPlatformError{err}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ func init() {
|
|||
RegisterController("X11", InitX11Controller, 0)
|
||||
}
|
||||
|
||||
func InitX11Controller() (Controller, error) {
|
||||
func InitX11Controller(saveRestoreToken bool) (Controller, error) {
|
||||
display := C.XOpenDisplay(nil)
|
||||
if display == nil {
|
||||
return nil, &UnsupportedPlatformError{
|
||||
|
|
|
|||
5
main.go
5
main.go
|
|
@ -152,7 +152,7 @@ func secureRandBase64(length int) string {
|
|||
func main() {
|
||||
terminal.SetTitle(prettyAppName)
|
||||
var bind, certFile, keyFile, secret string
|
||||
var showVersion bool
|
||||
var showVersion, savePlaintextRestoreToken bool
|
||||
var config config
|
||||
flag.BoolVar(&showVersion, "version", false, "show program's version number and exit")
|
||||
flag.StringVar(&bind, "bind", defaultBind, "bind server to [HOSTNAME]:PORT")
|
||||
|
|
@ -164,6 +164,7 @@ func main() {
|
|||
flag.Float64Var(&config.ScrollSpeed, "scroll-speed", 1, "scroll speed multiplier")
|
||||
flag.Float64Var(&config.MouseMoveSpeed, "mouse-move-speed", 1, "mouse move speed multiplier")
|
||||
flag.Float64Var(&config.MouseScrollSpeed, "mouse-scroll-speed", 1, "mouse scroll speed multiplier")
|
||||
flag.BoolVar(&savePlaintextRestoreToken, "save-plaintext-restore-token", false, "save a restore token in plaintext in order to avoid the confirmation dialogue that appears with some implementations of the portals backend on wayland on linux from appearing on the next run of remote-touchpad")
|
||||
flag.Parse()
|
||||
if showVersion {
|
||||
fmt.Println(version)
|
||||
|
|
@ -188,7 +189,7 @@ func main() {
|
|||
for _, controllerInfo := range inputcontrol.Controllers {
|
||||
controllerName = controllerInfo.Name
|
||||
var err error
|
||||
controller, err = controllerInfo.Init()
|
||||
controller, err = controllerInfo.Init(savePlaintextRestoreToken)
|
||||
if err == nil {
|
||||
break
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue