aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSébastien Dailly <sebastien@chimrod.com>2025-05-05 17:35:17 +0200
committerSébastien Dailly <sebastien@chimrod.com>2025-05-05 17:36:00 +0200
commit0d037fd1170ecc30cea677f563dfb50dff7360c6 (patch)
tree3f759d60884f1dc27d8fdbc70c95b5021186431b
parentac4fa300658b962c43768bc0867a1f46fdb23272 (diff)
Better exception handling in the tk codeHEADmaster
-rwxr-xr-xmacropad.pyw44
1 files changed, 30 insertions, 14 deletions
diff --git a/macropad.pyw b/macropad.pyw
index 35bd77a..f73cd1c 100755
--- a/macropad.pyw
+++ b/macropad.pyw
@@ -69,6 +69,7 @@ else:
server = None
+
class Icon(object):
def __init__(self, image):
@@ -82,12 +83,16 @@ class Icon(object):
self.stop = threading.Event()
self.show_hide = threading.Event()
- # Start the icon into a new thread in order to keep the main loop
- # control
+ # Start the icon into a new thread in order to keep the main loop control
icon_thread = threading.Thread(target=self.icon.run)
self.icon_thread = icon_thread
def start(self):
+ """ Start the icon.
+
+ Handler is runned in a dedicated thread to avoid blocking the
+ events from the main loop.
+ """
self.icon_thread.start()
def quit(self):
@@ -105,6 +110,8 @@ class Icon(object):
class Application(object):
def __init__(self):
+ # Override the default function called when exception are reported
+ tk.Tk.report_callback_exception = self.report_callback_exception
self.window = tk.Tk()
self.text = Text(self.window, height=8)
## State of the #pplication
@@ -133,7 +140,6 @@ class Application(object):
self.icon.start()
component.handle(Debug("Started"))
-
def connect_desktop(self):
""" Launch the thread listening events from the desktop
"""
@@ -141,17 +147,28 @@ class Application(object):
component.handle(Debug(platform))
if platform == "win32":
import win32
- window_listener = win32.Listener(mapping, q)
- component.provideUtility(window_listener, interfaces.desktopEvent.IDesktop)
- window_listener.start()
-
+ listener = win32.Listener(mapping, q)
elif platform == 'linux':
import xlib
- xlib_listener = xlib.Listener(mapping, q)
- component.provideUtility(xlib_listener, interfaces.desktopEvent.IDesktop)
+ listener = xlib.Listener(mapping, q)
component.handle(Debug("Starting xlib"))
- xlib_listener.start()
+ component.provideUtility(listener, interfaces.desktopEvent.IDesktop)
+ listener.start()
+ def report_callback_exception(self, exc, val, tb):
+ """ Handle exception reported inside the Tk application.
+ This method overrid the default Tk.tk.report_callback_exception
+ method.
+ """
+ import traceback
+ traceback.print_exception(exc, value=val, tb=tb)
+ self.icon.stop.set()
+ self.icon.quit()
+ self.running = False
+ self.window.destroy()
+ component.queryUtility(interfaces.desktopEvent.IDesktop).stop()
+ return
+
def hide(self):
self.icon.show_hide.clear()
self.visible = False
@@ -160,6 +177,7 @@ class Application(object):
def update(self):
if self.icon.stop.is_set():
+ print("stopping")
self.icon.quit()
self.running = False
self.window.destroy()
@@ -224,7 +242,7 @@ class Application(object):
# Check if we have something to read from the server, and by
# the by if the server is still active.
conn.fetch()
- except Exception as e:
+ except BaseException as e:
component.handle(Debug( str(e) ))
print(e)
# Got any error, stop the application properly
@@ -238,7 +256,6 @@ class Application(object):
self.send(last_layout)
if app_ is not None: self.associate(last_layout, app_)
-
if __name__ == '__main__':
# Start the main application, Initializing the message listener before
# listening desktop events
@@ -247,10 +264,9 @@ if __name__ == '__main__':
# Initialize the main loop
app.exec()
- component.handle(Debug("Exec runned first"))
try:
app.window.mainloop()
- except:
+ except BaseException as e:
app.running = False
app.window.destroy()
app.icon.quit()