Add Android (native) clipboard support via gomobile

This commit is contained in:
2025-03-18 22:59:10 -04:00
parent 44924737ab
commit 0f90e82514
6 changed files with 93 additions and 39 deletions
+34
View File
@@ -0,0 +1,34 @@
//go:build android && !termux
package core
import (
"strings"
"time"
"golang.design/x/clipboard"
)
// clipClearProcess clears the clipboard after 30 seconds if the clipboard contents have not changed.
// assignedContents can be omitted to clear the clipboard immediately and unconditionally.
func clipClearProcess(assignedContents string) {
clearClipboard := func() {
clipboard.Write(clipboard.FmtText, []byte(""))
Exit(0)
}
// if assignedContents is empty, clear the clipboard immediately and unconditionally
if assignedContents == "" {
clearClipboard()
return
}
// wait 30 seconds before checking clipboard contents
time.Sleep(30 * time.Second)
newContents := clipboard.Read(clipboard.FmtText)
if assignedContents == strings.TrimRight(string(newContents), "\r\n") {
clearClipboard()
}
}
+40
View File
@@ -0,0 +1,40 @@
//go:build !android || termux
package core
import (
"strings"
"time"
)
// clipClearProcess clears the clipboard after 30 seconds if the clipboard contents have not changed.
// assignedContents can be omitted to clear the clipboard immediately and unconditionally.
func clipClearProcess(assignedContents string) {
cmdPaste, cmdClear := getClipCommands()
clearClipboard := func() {
err := cmdClear.Run()
if err != nil {
PrintError("Failed to clear clipboard", ErrorClipboard, true)
}
Exit(0)
}
// if assignedContents is empty, clear the clipboard immediately and unconditionally
if assignedContents == "" {
clearClipboard()
return
}
// wait 30 seconds before checking clipboard contents
time.Sleep(30 * time.Second)
newContents, err := cmdPaste.Output()
if err != nil {
PrintError("Failed to read clipboard contents", ErrorClipboard, true)
}
if assignedContents == strings.TrimRight(string(newContents), "\r\n") {
clearClipboard()
}
}
-32
View File
@@ -69,38 +69,6 @@ func ClipClearArgument() {
} }
} }
// clipClearProcess clears the clipboard after 30 seconds if the clipboard contents have not changed.
// assignedContents can be omitted to clear the clipboard immediately and unconditionally.
func clipClearProcess(assignedContents string) {
cmdPaste, cmdClear := getClipCommands()
clearClipboard := func() {
err := cmdClear.Run()
if err != nil {
PrintError("Failed to clear clipboard", ErrorClipboard, true)
}
Exit(0)
}
// if assignedContents is empty, clear the clipboard immediately and unconditionally
if assignedContents == "" {
clearClipboard()
return
}
// wait 30 seconds before checking clipboard contents
time.Sleep(30 * time.Second)
newContents, err := cmdPaste.Output()
if err != nil {
PrintError("Failed to read clipboard contents", ErrorClipboard, true)
}
if assignedContents == strings.TrimRight(string(newContents), "\r\n") {
clearClipboard()
}
}
// GenTOTP generates a TOTP token from a secret (supports standard and Steam TOTP). // GenTOTP generates a TOTP token from a secret (supports standard and Steam TOTP).
func GenTOTP(secret string, time time.Time, forSteam bool) string { func GenTOTP(secret string, time time.Time, forSteam bool) string {
var totpToken string var totpToken string
+7 -7
View File
@@ -3,16 +3,16 @@
package core package core
import ( import (
"os/exec" "golang.design/x/clipboard"
) )
// TODO Investigate background clipboard clearing and on-app-close clipboard clearing for Android
// copyString copies a string to the clipboard. // copyString copies a string to the clipboard.
func copyString(continuous bool, copySubject string) { func copyString(continuous bool, copySubject string) {
// temporary dummy function to allow Android compilation clipboard.Write(clipboard.FmtText, []byte(copySubject))
}
// getClipCommands returns the commands for pasting and clearing the clipboard contents. if !continuous {
func getClipCommands() (*exec.Cmd, *exec.Cmd) { LaunchClipClearProcess(copySubject)
// temporary dummy function to allow Android compilation }
return nil, nil
} }
+4
View File
@@ -6,6 +6,7 @@ require (
github.com/fortis/go-steam-totp v0.0.0-20171114202746-18e928674727 github.com/fortis/go-steam-totp v0.0.0-20171114202746-18e928674727
github.com/pkg/sftp v1.13.8 github.com/pkg/sftp v1.13.8
github.com/pquerna/otp v1.4.1-0.20231130234153-3357de7c0481 github.com/pquerna/otp v1.4.1-0.20231130234153-3357de7c0481
golang.design/x/clipboard v0.7.0 // only for Android builds
golang.org/x/crypto v0.36.0 golang.org/x/crypto v0.36.0
gopkg.in/ini.v1 v1.67.0 gopkg.in/ini.v1 v1.67.0
) )
@@ -13,5 +14,8 @@ require (
require ( require (
github.com/boombuler/barcode v1.0.2 // indirect github.com/boombuler/barcode v1.0.2 // indirect
github.com/kr/fs v0.1.0 // indirect github.com/kr/fs v0.1.0 // indirect
golang.org/x/exp/shiny v0.0.0-20250305212735-054e65f0b394 // indirect; only for Android builds
golang.org/x/image v0.25.0 // indirect; only for Android builds
golang.org/x/mobile v0.0.0-20250305212854-3a7bc9f8a4de // indirect; only for Android builds
golang.org/x/sys v0.31.0 // indirect golang.org/x/sys v0.31.0 // indirect
) )
+8
View File
@@ -22,6 +22,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.design/x/clipboard v0.7.0 h1:4Je8M/ys9AJumVnl8m+rZnIvstSnYj1fvzqYrU3TXvo=
golang.design/x/clipboard v0.7.0/go.mod h1:PQIvqYO9GP29yINEfsEn5zSQKAz3UgXmZKzDA6dnq2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
@@ -30,6 +32,12 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/exp/shiny v0.0.0-20250305212735-054e65f0b394 h1:bFYqOIMdeiCEdzPJkLiOoMDzW/v3tjW4AA/RmUZYsL8=
golang.org/x/exp/shiny v0.0.0-20250305212735-054e65f0b394/go.mod h1:ygj7T6vSGhhm/9yTpOQQNvuAUFziTH7RUiH74EoE2C8=
golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ=
golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs=
golang.org/x/mobile v0.0.0-20250305212854-3a7bc9f8a4de h1:WuckfUoaRGJfaQTPZvlmcaQwg4Xj9oS2cvvh3dUqpDo=
golang.org/x/mobile v0.0.0-20250305212854-3a7bc9f8a4de/go.mod h1:/IZuixag1ELW37+FftdmIt59/3esqpAWM/QqWtf7HUI=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=