@@ -78,7 +78,7 @@ class StreamDeck(ABC):
78
78
DECK_VISUAL = False
79
79
DECK_TOUCH = False
80
80
81
- def __init__ (self , device ):
81
+ def __init__ (self , device , resume_from_suspend : bool = True ):
82
82
self .device = device
83
83
self .last_key_states = [False ] * (self .KEY_COUNT + self .TOUCH_KEY_COUNT )
84
84
self .last_dial_states = [False ] * self .DIAL_COUNT
@@ -200,6 +200,63 @@ def _read(self):
200
200
self .run_read_thread = False
201
201
self .close ()
202
202
203
+ def _read_with_resume_from_suspend (self ):
204
+ """
205
+ Read handler for the underlying transport, listening for button state
206
+ changes on the underlying device, caching the new states and firing off
207
+ any registered callbacks.
208
+ """
209
+ while self .run_read_thread :
210
+ try :
211
+ control_states = self ._read_control_states ()
212
+ if control_states is None :
213
+ time .sleep (1.0 / self .read_poll_hz )
214
+ continue
215
+
216
+ if ControlType .KEY in control_states and self .key_callback is not None :
217
+ for k , (old , new ) in enumerate (zip (self .last_key_states , control_states [ControlType .KEY ])):
218
+ if old != new :
219
+ self .last_key_states [k ] = new
220
+ self .key_callback (self , k , new )
221
+
222
+ elif ControlType .DIAL in control_states and self .dial_callback is not None :
223
+ if DialEventType .PUSH in control_states [ControlType .DIAL ]:
224
+ for k , (old , new ) in enumerate (zip (self .last_dial_states ,
225
+ control_states [ControlType .DIAL ][DialEventType .PUSH ])):
226
+ if old != new :
227
+ self .last_dial_states [k ] = new
228
+ self .dial_callback (self , k , DialEventType .PUSH , new )
229
+
230
+ if DialEventType .TURN in control_states [ControlType .DIAL ]:
231
+ for k , amount in enumerate (control_states [ControlType .DIAL ][DialEventType .TURN ]):
232
+ if amount != 0 :
233
+ self .dial_callback (self , k , DialEventType .TURN , amount )
234
+
235
+ elif ControlType .TOUCHSCREEN in control_states and self .touchscreen_callback is not None :
236
+ self .touchscreen_callback (self , * control_states [ControlType .TOUCHSCREEN ])
237
+
238
+ except TransportError :
239
+ self .run_read_thread = False
240
+ self .close ()
241
+
242
+ if self .reconnect_after_suspend :
243
+ if self .connected () and not self .is_open ():
244
+ # This is the case when resuming from suspend
245
+ TIMEOUT = 10
246
+ start_time = time .time ()
247
+ while True :
248
+ try :
249
+ self .open ()
250
+ break
251
+ except TransportError :
252
+ time .sleep (0.1 )
253
+
254
+ if not self .connected ():
255
+ break
256
+
257
+ if time .time () - start_time > TIMEOUT :
258
+ break
259
+
203
260
def _setup_reader (self , callback ):
204
261
"""
205
262
Sets up the internal transport reader thread with the given callback,
@@ -233,7 +290,10 @@ def open(self):
233
290
self .device .open ()
234
291
235
292
self ._reset_key_stream ()
236
- self ._setup_reader (self ._read )
293
+ if self .resume_from_suspend :
294
+ self ._setup_reader (self ._read_with_resume_from_suspend )
295
+ else :
296
+ self ._setup_reader (self ._read )
237
297
238
298
def close (self ):
239
299
"""
0 commit comments