import threading
from transitions.extensions import HierarchicalMachine as Machine
+# All drawing operations should happen in the main thread
+# https://github.com/kivy/kivy/wiki/Working-with-Python-threads-inside-a-Kivy-application
+from kivy.clock import mainthread
+
class KeyMachine(Widget):
STATES = [
'initial',
def is_loaded_inactive(self):
return self.is_loaded_no_config() or self.is_loaded_no_actions()
+ @mainthread
def on_enter_configuring(self):
+ self.destroy_actions()
+ self.key.unset_description()
+ self.key.unset_color()
+
if self.key.key_sym in self.key.parent.key_config:
self.key.config = self.key.parent.key_config[self.key.key_sym]
- self.key.actions = []
for key_action in self.key.config['actions']:
self.key.add_action(key_action[0], **key_action[1])
if 'description' in self.key.config['properties']:
self.key.set_description(self.key.config['properties']['description'])
- else:
- self.key.unset_description()
if 'color' in self.key.config['properties']:
self.key.set_color(self.key.config['properties']['color'])
- else:
- self.key.unset_color()
self.success()
else:
self.no_config()
else:
self.no_actions()
+ def destroy_actions(self):
+ for action in self.key.actions:
+ action.destroy()
+ self.key.actions = []
+
def run_actions(self, modifiers):
self.key.parent.parent.ids['KeyList'].append(self.key.key_sym)
debug_print("running actions for {}".format(self.key.key_sym))
start_time = time.time()
- self.key.parent.start_running(self, start_time)
+ self.key.parent.start_running(self.key, start_time)
for self.key.current_action in self.key.actions:
- if self.key.parent.keep_running(self, start_time):
+ if self.key.parent.keep_running(self.key, start_time):
self.key.list_actions()
self.key.current_action.run(start_time)
self.key.list_actions(last_action_finished=True)
- self.key.parent.finished_running(self, start_time)
+ self.key.parent.finished_running(self.key, start_time)
def on_enter_loaded_protecting_repeat(self, modifiers):
if self.key.repeat_delay > 0:
self.key.repeat_protection_finished()
# Callbacks
+ @mainthread
def key_loaded_callback(self):
self.key.parent.key_loaded_callback()
super(Key, self).__init__(**kwargs)
# Kivy events
+ @mainthread
+ def update_state(self, value):
+ self.machine_state = value
+
def on_key_sym(self, key, key_sym):
if key_sym != "":
self.configure()
# Helpers
@property
def repeat_delay(self):
- if 'repeat_delay' in self.key.config['properties']:
- return self.key.config['properties']['repeat_delay']
+ if hasattr(self, 'config') and\
+ 'repeat_delay' in self.config['properties']:
+ return self.config['properties']['repeat_delay']
else:
return 0