diff --git a/core/clipClearProcessDROID.go b/core/clipClearProcessDROID.go new file mode 100644 index 0000000..450fc29 --- /dev/null +++ b/core/clipClearProcessDROID.go @@ -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() + } +} diff --git a/core/clipClearProcessGeneric.go b/core/clipClearProcessGeneric.go new file mode 100644 index 0000000..7580a21 --- /dev/null +++ b/core/clipClearProcessGeneric.go @@ -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() + } +} diff --git a/core/copy.go b/core/copy.go index 84add28..40a4938 100644 --- a/core/copy.go +++ b/core/copy.go @@ -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). func GenTOTP(secret string, time time.Time, forSteam bool) string { var totpToken string diff --git a/core/copyDROID.go b/core/copyDROID.go index 316bcbc..e065518 100644 --- a/core/copyDROID.go +++ b/core/copyDROID.go @@ -3,16 +3,16 @@ package core 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. 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. -func getClipCommands() (*exec.Cmd, *exec.Cmd) { - // temporary dummy function to allow Android compilation - return nil, nil + if !continuous { + LaunchClipClearProcess(copySubject) + } } diff --git a/go.mod b/go.mod index 70a6a44..4605c81 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/fortis/go-steam-totp v0.0.0-20171114202746-18e928674727 github.com/pkg/sftp v1.13.8 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 gopkg.in/ini.v1 v1.67.0 ) @@ -13,5 +14,8 @@ require ( require ( github.com/boombuler/barcode v1.0.2 // 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 ) diff --git a/go.sum b/go.sum index 07174a5..2c61151 100644 --- a/go.sum +++ b/go.sum @@ -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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 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.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= 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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=