[mousetrap] Shutdown GTK on SIGINT and SIGTERM
- From: Stoney Jackson <stoneyjackson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mousetrap] Shutdown GTK on SIGINT and SIGTERM
- Date: Tue, 16 Jun 2015 13:40:37 +0000 (UTC)
commit c360c5b5939c95ed0ae6bcd935af011f64aa7db3
Author: Stoney Jackson <dr stoney gmail com>
Date: Thu May 28 07:05:39 2015 -0400
Shutdown GTK on SIGINT and SIGTERM
Currently MouseTrap hangs when a SIGINT (e.g., ^C from the terminal)
or a SIGTERM (e.g., kill PID) is received. The reason is that the
main event loop in GTK is still running.
This commit adds a signal handler to respond to SIGINT and SIGTERM,
and adds code to shutdown GTK.
Closes bug 750077
src/mousetrap/core.py | 12 ++++++++++--
src/mousetrap/gui.py | 19 +++++++++++++++----
src/mousetrap/main.py | 17 ++++++++++++-----
3 files changed, 37 insertions(+), 11 deletions(-)
---
diff --git a/src/mousetrap/core.py b/src/mousetrap/core.py
index 2211278..864e654 100644
--- a/src/mousetrap/core.py
+++ b/src/mousetrap/core.py
@@ -62,6 +62,10 @@ class App(object):
self.loop.start()
self.gui.start()
+ def stop(self):
+ self.gui.stop()
+ self.loop.stop()
+
class Observable(object):
@@ -93,6 +97,7 @@ class Loop(Observable):
self._timeout_id = None
self._set_loops_per_second(config['loops_per_second'])
self._add_argument('app', app)
+ self._loop_enabled = False
def _set_loops_per_second(self, loops_per_second):
self._loops_per_second = loops_per_second
@@ -100,9 +105,12 @@ class Loop(Observable):
self.MILLISECONDS_PER_SECOND / self._loops_per_second))
def start(self):
+ self._loop_enabled = True
self._timeout_id = GLib.timeout_add(self._interval, self._run)
+ def stop(self):
+ self._loop_enabled = False
+
def _run(self):
self._fire(self.CALLBACK_RUN)
- continue_ = True
- return continue_
+ return self._loop_enabled
diff --git a/src/mousetrap/gui.py b/src/mousetrap/gui.py
index c9cbe1b..2ea5c37 100644
--- a/src/mousetrap/gui.py
+++ b/src/mousetrap/gui.py
@@ -69,6 +69,21 @@ class ImageWindow(object):
class Gui(object):
+ _running = False
+
+ @classmethod
+ def start(cls):
+ '''Start handling events.'''
+ if not cls._running:
+ cls._running = True
+ get_gtk().main()
+
+ @classmethod
+ def stop(cls):
+ '''Stop handling events.'''
+ if cls._running:
+ cls._running = False
+ get_gtk().main_quit()
def __init__(self, config):
self._config = config
@@ -82,10 +97,6 @@ class Gui(object):
self._windows[window_name] = ImageWindow(self._config, window_name)
self._windows[window_name].draw(image)
- def start(self):
- '''Start handling events.'''
- get_gtk().main()
-
def get_screen_width(self):
return get_gtk().Window().get_screen().get_width()
diff --git a/src/mousetrap/main.py b/src/mousetrap/main.py
index cdf364b..ac267e6 100644
--- a/src/mousetrap/main.py
+++ b/src/mousetrap/main.py
@@ -8,14 +8,16 @@ Where it all begins.
'''
from argparse import ArgumentParser
+from io import open
import logging
import logging.config
+from os.path import dirname, expanduser, exists
+import signal
import sys
import yaml
-from os.path import dirname, expanduser, exists
-from io import open
from mousetrap.config import Config
+from mousetrap.core import App
class Main(object):
@@ -24,6 +26,7 @@ class Main(object):
def __init__(self):
try:
+ self._app = None
self._args = CommandLineArguments()
self._handle_dump_annotated()
self._config = Config().load(self._get_config_paths())
@@ -64,12 +67,16 @@ class Main(object):
logger.debug(yaml.dump(dict(self._config), default_flow_style=False))
def run(self):
- from mousetrap.core import App
- App(self._config).run()
+ self._app = App(self._config)
+ signal.signal(signal.SIGTERM, self._stop_signal_handler)
+ signal.signal(signal.SIGINT, self._stop_signal_handler)
+ self._app.run()
+ def _stop_signal_handler(self, signal_number, stack_frame):
+ self._app.stop()
-class CommandLineArguments(object):
+class CommandLineArguments(object):
def __init__(self):
parser = ArgumentParser()
parser.add_argument(
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]