From b77ac561ce86406d31907605b02a1867fba5f059 Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Mon, 19 Oct 2020 23:36:23 +0200 Subject: [PATCH] Add support for short / long press actions Signed-off-by: Knut Ahlers --- cmd/streamdeck/config.go | 31 ++++++++++++++++++-- cmd/streamdeck/main.go | 63 +++++++++++++++++++++------------------- 2 files changed, 62 insertions(+), 32 deletions(-) diff --git a/cmd/streamdeck/config.go b/cmd/streamdeck/config.go index 7810c9d..c820919 100644 --- a/cmd/streamdeck/config.go +++ b/cmd/streamdeck/config.go @@ -1,9 +1,15 @@ package main import ( + "os" "time" + + "github.com/pkg/errors" + "gopkg.in/yaml.v2" ) +const defaultLongPressDuration = 500 * time.Millisecond + type config struct { AutoReload bool `yaml:"auto_reload"` CaptionBorder int `yaml:"caption_border"` @@ -14,6 +20,7 @@ type config struct { DefaultBrightness int `yaml:"default_brightness"` DefaultPage string `yaml:"default_page"` DisplayOffTime time.Duration `yaml:"display_off_time"` + LongPressDuration time.Duration `yaml:"long_press_duration"` Pages map[string]page `yaml:"pages"` RenderFont string `yaml:"render_font"` } @@ -27,17 +34,18 @@ type page struct { type keyDefinition struct { Display dynamicElement `yaml:"display"` Actions []dynamicElement `yaml:"actions"` - On string `yaml:"on"` } type dynamicElement struct { Type string `yaml:"type"` + LongPress bool `yaml:"long_press"` Attributes map[string]interface{} `yaml:"attributes"` } func newConfig() config { return config{ - AutoReload: true, + AutoReload: true, + LongPressDuration: defaultLongPressDuration, } } @@ -47,3 +55,22 @@ const ( captionPositionBottom = "bottom" captionPositionTop = "top" ) + +func loadConfig() error { + userConfFile, err := os.Open(cfg.Config) + if err != nil { + return errors.Wrap(err, "Unable to open config") + } + defer userConfFile.Close() + + tempConf := newConfig() + if err = yaml.NewDecoder(userConfFile).Decode(&tempConf); err != nil { + return errors.Wrap(err, "Unable to parse config") + } + + applySystemPages(&tempConf) + + userConfig = tempConf + + return nil +} diff --git a/cmd/streamdeck/main.go b/cmd/streamdeck/main.go index a737620..5f50dfb 100644 --- a/cmd/streamdeck/main.go +++ b/cmd/streamdeck/main.go @@ -15,7 +15,6 @@ import ( "github.com/pkg/errors" "github.com/sashko/go-uinput" log "github.com/sirupsen/logrus" - "gopkg.in/yaml.v2" ) var ( @@ -65,25 +64,6 @@ func init() { } } -func loadConfig() error { - userConfFile, err := os.Open(cfg.Config) - if err != nil { - return errors.Wrap(err, "Unable to open config") - } - defer userConfFile.Close() - - var tempConf config - if err = yaml.NewDecoder(userConfFile).Decode(&tempConf); err != nil { - return errors.Wrap(err, "Unable to parse config") - } - - applySystemPages(&tempConf) - - userConfig = tempConf - - return nil -} - func main() { if cfg.List { listAndQuit() @@ -160,6 +140,11 @@ func main() { } } + var ( + actor *int + actStart time.Time + ) + for { select { case evt := <-sd.Subscribe(): @@ -167,15 +152,25 @@ func main() { offTimer.Reset(userConfig.DisplayOffTime) } - kd, ok := activePage.GetKeyDefinitions(userConfig)[evt.Key] + if evt.Type == streamdeck.EventTypeDown { + actor = &evt.Key + actStart = time.Now() + continue + } + + if evt.Key != *actor { + continue + } + + kd, ok := activePage.GetKeyDefinitions(userConfig)[*actor] if !ok { continue } - if kd.On == "down" && evt.Type == streamdeck.EventTypeDown || (kd.On == "up" || kd.On == "") && evt.Type == streamdeck.EventTypeUp || kd.On == "both" { - if err := triggerAction(kd); err != nil { - log.WithError(err).Error("Unable to execute action") - } + isLongPress := time.Since(actStart) > userConfig.LongPressDuration + + if err := triggerAction(kd, isLongPress); err != nil { + log.WithError(err).Error("Unable to execute action") } case <-offTimer.C: @@ -253,12 +248,20 @@ func togglePage(page string) error { return nil } -func triggerAction(kd keyDefinition) error { +func triggerAction(kd keyDefinition, isLongPress bool) error { for _, a := range kd.Actions { - if a.Type != "" { - if err := callAction(a); err != nil { - return err - } + if a.Type == "" { + // No type on that action: Invalid + continue + } + + if isLongPress != a.LongPress { + // press duration does not match requirement + continue + } + + if err := callAction(a); err != nil { + return err } }