desktop: add clipboard command replacement. (#539)
we always keep running the last clipboard function as that is supposed to contain the clipboard data being pasted. as soon as a new one is spawn, the old one is stutdown.
This commit is contained in:
parent
d530b759f5
commit
84aa78bfcb
2 changed files with 46 additions and 4 deletions
|
|
@ -58,6 +58,23 @@ func (manager *DesktopManagerCtx) ClipboardGetBinary(mime string) ([]byte, error
|
|||
return stdout.Bytes(), nil
|
||||
}
|
||||
|
||||
func (manager *DesktopManagerCtx) replaceClipboardCommand(newCmd *exec.Cmd) {
|
||||
// Swap the current clipboard command with the new one.
|
||||
oldCmd := manager.clipboardCommand.Swap(newCmd)
|
||||
|
||||
// If the command is already running, we need to shutdown it properly.
|
||||
if oldCmd == nil || oldCmd.ProcessState != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// If there is a previous command running and it was not stopped yet, we need to kill it.
|
||||
if err := oldCmd.Process.Kill(); err != nil {
|
||||
manager.logger.Err(err).Msg("failed to kill previous clipboard command")
|
||||
} else {
|
||||
manager.logger.Debug().Msg("killed previous clipboard command")
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *DesktopManagerCtx) ClipboardSetBinary(mime string, data []byte) error {
|
||||
cmd := exec.Command("xclip", "-selection", "clipboard", "-in", "-target", mime)
|
||||
|
||||
|
|
@ -69,7 +86,9 @@ func (manager *DesktopManagerCtx) ClipboardSetBinary(mime string, data []byte) e
|
|||
return err
|
||||
}
|
||||
|
||||
// TODO: Refactor.
|
||||
// Shutdown previous command if it exists and replace it with the new one.
|
||||
manager.replaceClipboardCommand(cmd)
|
||||
|
||||
// We need to wait until the data came to the clipboard.
|
||||
wait := make(chan struct{})
|
||||
xevent.Emmiter.Once("clipboard-updated", func(payload ...any) {
|
||||
|
|
@ -89,9 +108,23 @@ func (manager *DesktopManagerCtx) ClipboardSetBinary(mime string, data []byte) e
|
|||
|
||||
stdin.Close()
|
||||
|
||||
// TODO: Refactor.
|
||||
// cmd.Wait()
|
||||
<-wait
|
||||
select {
|
||||
case <-manager.shutdown:
|
||||
return fmt.Errorf("clipboard manager is shutting down")
|
||||
case <-wait:
|
||||
}
|
||||
|
||||
manager.wg.Add(1)
|
||||
go func() {
|
||||
defer manager.wg.Done()
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
msg := strings.TrimSpace(stderr.String())
|
||||
manager.logger.Err(err).Msgf("clipboard command finished with error: %s", msg)
|
||||
} else {
|
||||
manager.logger.Debug().Msg("clipboard command finished successfully")
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package desktop
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/kataras/go-events"
|
||||
|
|
@ -25,6 +27,11 @@ type DesktopManagerCtx struct {
|
|||
config *config.Desktop
|
||||
screenSize types.ScreenSize // cached screen size
|
||||
input xinput.Driver
|
||||
|
||||
// Clipboard process holding the most recent clipboard data.
|
||||
// It must remain running to allow pasting clipboard data.
|
||||
// The last command is kept running until it is replaced or shutdown.
|
||||
clipboardCommand atomic.Pointer[exec.Cmd]
|
||||
}
|
||||
|
||||
func New(config *config.Desktop) *DesktopManagerCtx {
|
||||
|
|
@ -131,6 +138,8 @@ func (manager *DesktopManagerCtx) Shutdown() error {
|
|||
manager.logger.Info().Msgf("shutdown")
|
||||
|
||||
close(manager.shutdown)
|
||||
|
||||
manager.replaceClipboardCommand(nil)
|
||||
manager.wg.Wait()
|
||||
|
||||
xorg.DisplayClose()
|
||||
|
|
|
|||
Loading…
Reference in a new issue