Skip to content

Commit 3049d89

Browse files
committed
window sensitive keys
1 parent 8f22045 commit 3049d89

File tree

2 files changed

+98
-32
lines changed

2 files changed

+98
-32
lines changed

deck.go

Lines changed: 95 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ type WindowWidgets struct {
3030

3131
// Deck is a set of widgets.
3232
type Deck struct {
33-
File string
34-
Background image.Image
35-
Windows []WindowWidgets
36-
Overrides map[uint8]*Widget
37-
Widgets map[uint8]Widget
33+
file string
34+
background image.Image
35+
windows []WindowWidgets
36+
overrides map[uint8]*Widget
37+
widgets map[uint8]Widget
3838
}
3939

4040
func expandExecutable(exe string) string {
@@ -66,8 +66,9 @@ func LoadDeck(dev *streamdeck.Device, base string, deck string) (*Deck, error) {
6666
}
6767

6868
d := Deck{
69-
Widgets: make(map[uint8]Widget),
70-
File: path,
69+
overrides: make(map[uint8]*Widget),
70+
widgets: make(map[uint8]Widget),
71+
file: path,
7172
}
7273
if dc.Background != "" {
7374
bgPath, err := expandPath(filepath.Dir(path), dc.Background)
@@ -97,7 +98,7 @@ func LoadDeck(dev *streamdeck.Device, base string, deck string) (*Deck, error) {
9798
w = NewBaseWidget(dev, filepath.Dir(path), i, nil, nil, bg)
9899
}
99100

100-
d.Widgets[i] = w
101+
d.widgets[i] = w
101102
}
102103

103104
for _, w := range dc.Windows {
@@ -109,7 +110,7 @@ func LoadDeck(dev *streamdeck.Device, base string, deck string) (*Deck, error) {
109110
return &d, nil
110111
}
111112

112-
func (d *Deck) addWindow(dev *streamdeck.Device, w *WindowConfig) error {
113+
func (deck *Deck) addWindow(dev *streamdeck.Device, w *WindowConfig) error {
113114
verboseLog("loading window overrides %s:%s", w.Resource, w.Title)
114115

115116
resource, err := regexp.Compile(w.Resource)
@@ -130,27 +131,33 @@ func (d *Deck) addWindow(dev *streamdeck.Device, w *WindowConfig) error {
130131
widgets: make(map[uint8]Widget),
131132
}
132133
for _, key := range w.Keys {
133-
if e := window.addWidget(dev, d, key); e != nil {
134+
if e := window.addWidget(dev, deck, key); e != nil {
134135
errorLogF("failed to add widget %s:%s[%d]", w.Resource, w.Title, key.Index)
135136
return e
136137
}
137138
}
138-
d.Windows = append(d.Windows, window)
139+
deck.windows = append(deck.windows, window)
139140
return nil
140141
}
141142

142-
func (w *WindowWidgets) addWidget(dev *streamdeck.Device, deck *Deck, key KeyConfig) error {
143+
func (ww *WindowWidgets) addWidget(dev *streamdeck.Device, deck *Deck, key KeyConfig) error {
143144
bg := deck.backgroundForKey(dev, key.Index)
144-
widget, err := NewWidget(dev, filepath.Dir(deck.File), key, bg)
145+
widget, err := NewWidget(dev, filepath.Dir(deck.file), key, bg)
145146
if err != nil {
146147
return err
147148
}
148-
w.widgets[key.Index] = widget
149+
ww.widgets[key.Index] = widget
149150
return nil
150151
}
151152

153+
func (ww *WindowWidgets) Matches(window ActiveWindow) bool {
154+
resource := ww.resource.MatchString(window.resource)
155+
title := ww.title.MatchString(window.title)
156+
return resource && title
157+
}
158+
152159
// loads a background image.
153-
func (d *Deck) loadBackground(dev *streamdeck.Device, bg string) error {
160+
func (deck *Deck) loadBackground(dev *streamdeck.Device, bg string) error {
154161
f, err := os.Open(bg)
155162
if err != nil {
156163
return err
@@ -174,25 +181,59 @@ func (d *Deck) loadBackground(dev *streamdeck.Device, bg string) error {
174181
return fmt.Errorf("supplied background image has wrong dimensions, expected %dx%d pixels", width, height)
175182
}
176183

177-
d.Background = background
184+
deck.background = background
178185
return nil
179186
}
180187

181188
// returns the background image for an individual key.
182-
func (d *Deck) backgroundForKey(dev *streamdeck.Device, key uint8) image.Image {
189+
func (deck *Deck) backgroundForKey(dev *streamdeck.Device, key uint8) image.Image {
183190
padding := int(dev.Padding)
184191
pixels := int(dev.Pixels)
185192
bg := image.NewRGBA(image.Rect(0, 0, pixels, pixels))
186193

187-
if d.Background != nil {
188-
startx := int(key%dev.Columns) * (pixels + padding)
189-
starty := int(key/dev.Columns) * (pixels + padding)
190-
draw.Draw(bg, bg.Bounds(), d.Background, image.Point{startx, starty}, draw.Src)
194+
if deck.background != nil {
195+
start := image.Point{
196+
X: int(key%dev.Columns) * (pixels + padding),
197+
Y: int(key/dev.Columns) * (pixels + padding),
198+
}
199+
draw.Draw(bg, bg.Bounds(), deck.background, start, draw.Src)
191200
}
192-
193201
return bg
194202
}
195203

204+
func (deck *Deck) WindowChanged(window ActiveWindow) {
205+
verboseLog("windowChanged %s:%s %s", window.resource, window.title, window.id)
206+
var match *WindowWidgets
207+
for _, w := range deck.windows {
208+
if w.Matches(window) {
209+
match = &w
210+
}
211+
}
212+
if match != nil {
213+
for i, widget := range match.widgets {
214+
deck.overrideWidget(i, widget)
215+
}
216+
} else {
217+
for key := range deck.overrides {
218+
deck.restoreWidget(key)
219+
}
220+
}
221+
}
222+
223+
func (deck *Deck) overrideWidget(key uint8, widget Widget) {
224+
deck.overrides[key] = &widget
225+
if err := widget.Update(); err != nil {
226+
fatal(err)
227+
}
228+
}
229+
230+
func (deck *Deck) restoreWidget(key uint8) {
231+
delete(deck.overrides, key)
232+
if err := deck.widgets[key].Update(); err != nil {
233+
fatal(err)
234+
}
235+
}
236+
196237
// handles keypress with delay.
197238
func emulateKeyPressWithDelay(keys string) {
198239
kd := strings.Split(keys, "+")
@@ -271,9 +312,34 @@ func executeCommand(cmd string) error {
271312
return c.Process.Release()
272313
}
273314

315+
func (deck *Deck) Widgets(yield func(Widget) bool) {
316+
for i, w := range deck.widgets {
317+
override := deck.overrides[i]
318+
if override == nil {
319+
if !yield(w) {
320+
return
321+
}
322+
}
323+
}
324+
for i := range deck.overrides {
325+
widget := deck.overrides[i]
326+
if !yield(*widget) {
327+
return
328+
}
329+
}
330+
}
331+
332+
func (deck *Deck) widget(key uint8) Widget {
333+
widget := deck.overrides[key]
334+
if widget != nil {
335+
return *widget
336+
}
337+
return deck.widgets[key]
338+
}
339+
274340
// triggerAction triggers an action.
275-
func (d *Deck) triggerAction(dev *streamdeck.Device, index uint8, hold bool) {
276-
var w = d.Widgets[index]
341+
func (deck *Deck) triggerAction(dev *streamdeck.Device, index uint8, hold bool) {
342+
w := deck.widget(index)
277343
w.TriggerAction(hold)
278344

279345
var a *ActionConfig
@@ -287,7 +353,7 @@ func (d *Deck) triggerAction(dev *streamdeck.Device, index uint8, hold bool) {
287353
return
288354
}
289355
if a.Deck != "" {
290-
newDeck, err := LoadDeck(dev, filepath.Dir(d.File), a.Deck)
356+
newDeck, err := LoadDeck(dev, filepath.Dir(deck.file), a.Deck)
291357
if err != nil {
292358
errorLog(err, "Failed to load deck %s", a.Deck)
293359
return
@@ -320,7 +386,7 @@ func (d *Deck) triggerAction(dev *streamdeck.Device, index uint8, hold bool) {
320386
}
321387

322388
case strings.HasPrefix(a.Device, "brightness"):
323-
d.adjustBrightness(dev, strings.TrimPrefix(a.Device, "brightness"))
389+
deck.adjustBrightness(dev, strings.TrimPrefix(a.Device, "brightness"))
324390

325391
default:
326392
errorLogF("Unrecognized special action: %s", a.Device)
@@ -329,8 +395,8 @@ func (d *Deck) triggerAction(dev *streamdeck.Device, index uint8, hold bool) {
329395
}
330396

331397
// updateWidgets updates/repaints all the widgets.
332-
func (d *Deck) updateWidgets() {
333-
for _, w := range d.Widgets {
398+
func (deck *Deck) updateWidgets() {
399+
for w := range deck.Widgets {
334400
if !w.RequiresUpdate() {
335401
continue
336402
}
@@ -343,7 +409,7 @@ func (d *Deck) updateWidgets() {
343409
}
344410

345411
// adjustBrightness adjusts the brightness.
346-
func (d *Deck) adjustBrightness(dev *streamdeck.Device, value string) {
412+
func (deck *Deck) adjustBrightness(dev *streamdeck.Device, value string) {
347413
if len(value) == 0 {
348414
errorLogF("no brightness value specified")
349415
return

main.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ func eventLoop(dev *streamdeck.Device, tch chan interface{}) error {
147147

148148
case changeType := <-pa.Updates():
149149
playback := changeType == SinkMuteChanged || changeType == SinkChanged
150-
for _, widget := range deck.Widgets {
150+
for widget := range deck.Widgets {
151151
w, success := widget.(MuteChangedMonitor)
152152
if success {
153153
w.MuteChanged(playback)
@@ -161,7 +161,7 @@ func eventLoop(dev *streamdeck.Device, tch chan interface{}) error {
161161
}
162162

163163
case activeWindow := <-wch:
164-
verboseLog("windowActivated: %v", activeWindow)
164+
deck.WindowChanged(activeWindow)
165165

166166
case event := <-tch:
167167
switch event := event.(type) {
@@ -178,7 +178,7 @@ func eventLoop(dev *streamdeck.Device, tch chan interface{}) error {
178178
case <-hup:
179179
verboseLog("Received SIGHUP, reloading configuration...")
180180

181-
nd, e := LoadDeck(dev, ".", deck.File)
181+
nd, e := LoadDeck(dev, ".", deck.file)
182182
if e != nil {
183183
errorLog(e, "invalid configuration")
184184
continue

0 commit comments

Comments
 (0)