We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Solaar exits with RC 1 when terminated
**Information**
<!-- Make sure that your issue is not one of the known issues in the Solaar documentation at https://pwr-solaar.github.io/Solaar/ -->
<!-- Do not bother opening an issue for a version older than 1.1.0.  Upgrade to the latest version and see if your issue persists. -->
<!-- If you not running the current version of Solaar, strongly consider upgrading to the newest version. -->
- Solaar version (`solaar --version` or `git describe --tags` if cloned from this repository): solaar 1.1.8+dfsg-2
- Distribution: Debian testing
- Kernel version (ex. `uname -srmo`): `Linux 6.1.0-3-amd64 x86_64 GNU/Linux`
- Output of `solaar show`: 

<details>

```

```
</details>

- Contents of `~/.config/solaar/config.yaml` (or `~/.config/solaar/config.json` if `~/.config/solaar/config.yaml` not present):

<details>

```
CONTENTS HERE
```
</details>


- Errors or warrnings from Solaar:
<!-- Under normal operation Solaar keeps a log of warning and error messages in ~/.tmp
while it is running as a file starting with 'Solaar'.
If this file is not available or does not have useful information you can
run Solaar as `solaar -dd`, after killing any running Solaar processes to
have Solaar log informational, warning, and error messages to stdout. -->


**Describe the bug**
When terminated, solaar exits with RC 1. This results in a failed unit if systemd is managing XDG autostart. No log warnings or stderr messages produced.

**To Reproduce**
Steps to reproduce the behavior: 
1. run `solaar ; echo $?`
2. run `killall solaar`
3. see rc 1 printed

Workaround:
```
cat << EOF > ~/.config/systemd/user/app-solaar@autostart.service.d/exit-tweak.conf 
[Service]
SuccessExitStatus=0 1
EOF
systemctl --user daemon-reload
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lib/solaar/gtk.py`
Content:
```
1 #!/usr/bin/env python3
2 # -*- python-mode -*-
3 # -*- coding: UTF-8 -*-
4 
5 ## Copyright (C) 2012-2013  Daniel Pavel
6 ##
7 ## This program is free software; you can redistribute it and/or modify
8 ## it under the terms of the GNU General Public License as published by
9 ## the Free Software Foundation; either version 2 of the License, or
10 ## (at your option) any later version.
11 ##
12 ## This program is distributed in the hope that it will be useful,
13 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ## GNU General Public License for more details.
16 ##
17 ## You should have received a copy of the GNU General Public License along
18 ## with this program; if not, write to the Free Software Foundation, Inc.,
19 ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 
21 import importlib
22 import logging
23 import os.path
24 import signal
25 import sys
26 import tempfile
27 
28 from logging import INFO as _INFO
29 from logging import WARNING as _WARNING
30 
31 import solaar.cli as _cli
32 import solaar.i18n as _i18n
33 
34 from solaar import NAME, __version__
35 
36 _log = logging.getLogger(__name__)
37 
38 #
39 #
40 #
41 
42 
43 def _require(module, os_package, gi=None, gi_package=None, gi_version=None):
44     try:
45         if gi is not None:
46             gi.require_version(gi_package, gi_version)
47         return importlib.import_module(module)
48     except (ImportError, ValueError):
49         sys.exit('%s: missing required system package %s' % (NAME, os_package))
50 
51 
52 battery_icons_style = 'regular'
53 temp = tempfile.NamedTemporaryFile(prefix='Solaar_', mode='w', delete=True)
54 
55 
56 def _parse_arguments():
57     import argparse
58     arg_parser = argparse.ArgumentParser(
59         prog=NAME.lower(), epilog='For more information see https://pwr-solaar.github.io/Solaar'
60     )
61     arg_parser.add_argument(
62         '-d',
63         '--debug',
64         action='count',
65         default=0,
66         help='print logging messages, for debugging purposes (may be repeated for extra verbosity)'
67     )
68     arg_parser.add_argument(
69         '-D',
70         '--hidraw',
71         action='store',
72         dest='hidraw_path',
73         metavar='PATH',
74         help='unifying receiver to use; the first detected receiver if unspecified. Example: /dev/hidraw2'
75     )
76     arg_parser.add_argument('--restart-on-wake-up', action='store_true', help='restart Solaar on sleep wake-up (experimental)')
77     arg_parser.add_argument(
78         '-w', '--window', choices=('show', 'hide', 'only'), help='start with window showing / hidden / only (no tray icon)'
79     )
80     arg_parser.add_argument(
81         '-b',
82         '--battery-icons',
83         choices=('regular', 'symbolic', 'solaar'),
84         help='prefer regular battery / symbolic battery / solaar icons'
85     )
86     arg_parser.add_argument('--tray-icon-size', type=int, help='explicit size for tray icons')
87     arg_parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + __version__)
88     arg_parser.add_argument('--help-actions', action='store_true', help='print help for the optional actions')
89     arg_parser.add_argument('action', nargs=argparse.REMAINDER, choices=_cli.actions, help='optional actions to perform')
90 
91     args = arg_parser.parse_args()
92 
93     if args.help_actions:
94         _cli.print_help()
95         return
96 
97     if args.window is None:
98         args.window = 'show'  # default behaviour is to show main window
99 
100     global battery_icons_style
101     battery_icons_style = args.battery_icons if args.battery_icons is not None else 'regular'
102     global tray_icon_size
103     tray_icon_size = args.tray_icon_size
104 
105     log_format = '%(asctime)s,%(msecs)03d %(levelname)8s [%(threadName)s] %(name)s: %(message)s'
106     log_level = logging.ERROR - 10 * args.debug
107     logging.getLogger('').setLevel(min(log_level, logging.WARNING))
108     file_handler = logging.StreamHandler(temp)
109     file_handler.setLevel(max(min(log_level, logging.WARNING), logging.INFO))
110     file_handler.setFormatter(logging.Formatter(log_format))
111     logging.getLogger('').addHandler(file_handler)
112     if args.debug > 0:
113         stream_handler = logging.StreamHandler()
114         stream_handler.setFormatter(logging.Formatter(log_format))
115         stream_handler.setLevel(log_level)
116         logging.getLogger('').addHandler(stream_handler)
117 
118     if not args.action:
119         if _log.isEnabledFor(logging.INFO):
120             logging.info('language %s (%s), translations path %s', _i18n.language, _i18n.encoding, _i18n.path)
121 
122     return args
123 
124 
125 # On first SIGINT, dump threads to stderr; on second, exit
126 def _handlesig(signl, stack):
127     import faulthandler
128     signal.signal(signal.SIGINT, signal.SIG_DFL)
129     signal.signal(signal.SIGTERM, signal.SIG_DFL)
130 
131     if signl == int(signal.SIGINT):
132         if _log.isEnabledFor(_INFO):
133             faulthandler.dump_traceback()
134         sys.exit('%s: exit due to keyboard interrupt' % (NAME.lower()))
135     else:
136         sys.exit('')
137 
138 
139 def main():
140     _require('pyudev', 'python3-pyudev')
141 
142     args = _parse_arguments()
143     if not args:
144         return
145     if args.action:
146         # if any argument, run comandline and exit
147         return _cli.run(args.action, args.hidraw_path)
148 
149     gi = _require('gi', 'python3-gi (in Ubuntu) or python3-gobject (in Fedora)')
150     _require('gi.repository.Gtk', 'gir1.2-gtk-3.0', gi, 'Gtk', '3.0')
151 
152     # handle ^C in console
153     signal.signal(signal.SIGINT, signal.SIG_DFL)
154     signal.signal(signal.SIGINT, _handlesig)
155     signal.signal(signal.SIGTERM, _handlesig)
156 
157     udev_file = '42-logitech-unify-permissions.rules'
158     if _log.isEnabledFor(_WARNING) \
159        and not os.path.isfile('/etc/udev/rules.d/' + udev_file) \
160        and not os.path.isfile('/usr/lib/udev/rules.d/' + udev_file) \
161        and not os.path.isfile('/usr/local/lib/udev/rules.d/' + udev_file):
162         _log.warning('Solaar udev file not found in expected location')
163         _log.warning('See https://pwr-solaar.github.io/Solaar/installation for more information')
164     try:
165         import solaar.listener as listener
166         import solaar.ui as ui
167 
168         listener.setup_scanner(ui.status_changed, ui.error_dialog)
169 
170         import solaar.upower as _upower
171         if args.restart_on_wake_up:
172             _upower.watch(listener.start_all, listener.stop_all)
173         else:
174             _upower.watch(lambda: listener.ping_all(True))
175 
176         import solaar.configuration as _configuration
177         _configuration.defer_saves = True  # allow configuration saves to be deferred
178 
179         # main UI event loop
180         ui.run_loop(listener.start_all, listener.stop_all, args.window != 'only', args.window != 'hide')
181     except Exception:
182         from traceback import format_exc
183         sys.exit('%s: error: %s' % (NAME.lower(), format_exc()))
184 
185     temp.close()
186 
187 
188 if __name__ == '__main__':
189     main()
190
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/lib/solaar/gtk.py b/lib/solaar/gtk.py
--- a/lib/solaar/gtk.py
+++ b/lib/solaar/gtk.py
@@ -133,7 +133,7 @@
             faulthandler.dump_traceback()
         sys.exit('%s: exit due to keyboard interrupt' % (NAME.lower()))
     else:
-        sys.exit('')
+        sys.exit(0)
 
 
 def main():

{"golden_diff": "diff --git a/lib/solaar/gtk.py b/lib/solaar/gtk.py\n--- a/lib/solaar/gtk.py\n+++ b/lib/solaar/gtk.py\n@@ -133,7 +133,7 @@\n             faulthandler.dump_traceback()\n         sys.exit('%s: exit due to keyboard interrupt' % (NAME.lower()))\n     else:\n-        sys.exit('')\n+        sys.exit(0)\n \n \n def main():\n", "issue": "Solaar exits with RC 1 when terminated\n**Information**\r\n<!-- Make sure that your issue is not one of the known issues in the Solaar documentation at https://pwr-solaar.github.io/Solaar/ -->\r\n<!-- Do not bother opening an issue for a version older than 1.1.0.  Upgrade to the latest version and see if your issue persists. -->\r\n<!-- If you not running the current version of Solaar, strongly consider upgrading to the newest version. -->\r\n- Solaar version (`solaar --version` or `git describe --tags` if cloned from this repository): solaar 1.1.8+dfsg-2\r\n- Distribution: Debian testing\r\n- Kernel version (ex. `uname -srmo`): `Linux 6.1.0-3-amd64 x86_64 GNU/Linux`\r\n- Output of `solaar show`: \r\n\r\n<details>\r\n\r\n```\r\n\r\n```\r\n</details>\r\n\r\n- Contents of `~/.config/solaar/config.yaml` (or `~/.config/solaar/config.json` if `~/.config/solaar/config.yaml` not present):\r\n\r\n<details>\r\n\r\n```\r\nCONTENTS HERE\r\n```\r\n</details>\r\n\r\n\r\n- Errors or warrnings from Solaar:\r\n<!-- Under normal operation Solaar keeps a log of warning and error messages in ~/.tmp\r\nwhile it is running as a file starting with 'Solaar'.\r\nIf this file is not available or does not have useful information you can\r\nrun Solaar as `solaar -dd`, after killing any running Solaar processes to\r\nhave Solaar log informational, warning, and error messages to stdout. -->\r\n\r\n\r\n**Describe the bug**\r\nWhen terminated, solaar exits with RC 1. This results in a failed unit if systemd is managing XDG autostart. No log warnings or stderr messages produced.\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior: \r\n1. run `solaar ; echo $?`\r\n2. run `killall solaar`\r\n3. see rc 1 printed\r\n\r\nWorkaround:\r\n```\r\ncat << EOF > ~/.config/systemd/user/app-solaar@autostart.service.d/exit-tweak.conf \r\n[Service]\r\nSuccessExitStatus=0 1\r\nEOF\r\nsystemctl --user daemon-reload\r\n```\n", "before_files": [{"content": "#!/usr/bin/env python3\n# -*- python-mode -*-\n# -*- coding: UTF-8 -*-\n\n## Copyright (C) 2012-2013  Daniel Pavel\n##\n## This program is free software; you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation; either version 2 of the License, or\n## (at your option) any later version.\n##\n## This program is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License along\n## with this program; if not, write to the Free Software Foundation, Inc.,\n## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nimport importlib\nimport logging\nimport os.path\nimport signal\nimport sys\nimport tempfile\n\nfrom logging import INFO as _INFO\nfrom logging import WARNING as _WARNING\n\nimport solaar.cli as _cli\nimport solaar.i18n as _i18n\n\nfrom solaar import NAME, __version__\n\n_log = logging.getLogger(__name__)\n\n#\n#\n#\n\n\ndef _require(module, os_package, gi=None, gi_package=None, gi_version=None):\n    try:\n        if gi is not None:\n            gi.require_version(gi_package, gi_version)\n        return importlib.import_module(module)\n    except (ImportError, ValueError):\n        sys.exit('%s: missing required system package %s' % (NAME, os_package))\n\n\nbattery_icons_style = 'regular'\ntemp = tempfile.NamedTemporaryFile(prefix='Solaar_', mode='w', delete=True)\n\n\ndef _parse_arguments():\n    import argparse\n    arg_parser = argparse.ArgumentParser(\n        prog=NAME.lower(), epilog='For more information see https://pwr-solaar.github.io/Solaar'\n    )\n    arg_parser.add_argument(\n        '-d',\n        '--debug',\n        action='count',\n        default=0,\n        help='print logging messages, for debugging purposes (may be repeated for extra verbosity)'\n    )\n    arg_parser.add_argument(\n        '-D',\n        '--hidraw',\n        action='store',\n        dest='hidraw_path',\n        metavar='PATH',\n        help='unifying receiver to use; the first detected receiver if unspecified. Example: /dev/hidraw2'\n    )\n    arg_parser.add_argument('--restart-on-wake-up', action='store_true', help='restart Solaar on sleep wake-up (experimental)')\n    arg_parser.add_argument(\n        '-w', '--window', choices=('show', 'hide', 'only'), help='start with window showing / hidden / only (no tray icon)'\n    )\n    arg_parser.add_argument(\n        '-b',\n        '--battery-icons',\n        choices=('regular', 'symbolic', 'solaar'),\n        help='prefer regular battery / symbolic battery / solaar icons'\n    )\n    arg_parser.add_argument('--tray-icon-size', type=int, help='explicit size for tray icons')\n    arg_parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + __version__)\n    arg_parser.add_argument('--help-actions', action='store_true', help='print help for the optional actions')\n    arg_parser.add_argument('action', nargs=argparse.REMAINDER, choices=_cli.actions, help='optional actions to perform')\n\n    args = arg_parser.parse_args()\n\n    if args.help_actions:\n        _cli.print_help()\n        return\n\n    if args.window is None:\n        args.window = 'show'  # default behaviour is to show main window\n\n    global battery_icons_style\n    battery_icons_style = args.battery_icons if args.battery_icons is not None else 'regular'\n    global tray_icon_size\n    tray_icon_size = args.tray_icon_size\n\n    log_format = '%(asctime)s,%(msecs)03d %(levelname)8s [%(threadName)s] %(name)s: %(message)s'\n    log_level = logging.ERROR - 10 * args.debug\n    logging.getLogger('').setLevel(min(log_level, logging.WARNING))\n    file_handler = logging.StreamHandler(temp)\n    file_handler.setLevel(max(min(log_level, logging.WARNING), logging.INFO))\n    file_handler.setFormatter(logging.Formatter(log_format))\n    logging.getLogger('').addHandler(file_handler)\n    if args.debug > 0:\n        stream_handler = logging.StreamHandler()\n        stream_handler.setFormatter(logging.Formatter(log_format))\n        stream_handler.setLevel(log_level)\n        logging.getLogger('').addHandler(stream_handler)\n\n    if not args.action:\n        if _log.isEnabledFor(logging.INFO):\n            logging.info('language %s (%s), translations path %s', _i18n.language, _i18n.encoding, _i18n.path)\n\n    return args\n\n\n# On first SIGINT, dump threads to stderr; on second, exit\ndef _handlesig(signl, stack):\n    import faulthandler\n    signal.signal(signal.SIGINT, signal.SIG_DFL)\n    signal.signal(signal.SIGTERM, signal.SIG_DFL)\n\n    if signl == int(signal.SIGINT):\n        if _log.isEnabledFor(_INFO):\n            faulthandler.dump_traceback()\n        sys.exit('%s: exit due to keyboard interrupt' % (NAME.lower()))\n    else:\n        sys.exit('')\n\n\ndef main():\n    _require('pyudev', 'python3-pyudev')\n\n    args = _parse_arguments()\n    if not args:\n        return\n    if args.action:\n        # if any argument, run comandline and exit\n        return _cli.run(args.action, args.hidraw_path)\n\n    gi = _require('gi', 'python3-gi (in Ubuntu) or python3-gobject (in Fedora)')\n    _require('gi.repository.Gtk', 'gir1.2-gtk-3.0', gi, 'Gtk', '3.0')\n\n    # handle ^C in console\n    signal.signal(signal.SIGINT, signal.SIG_DFL)\n    signal.signal(signal.SIGINT, _handlesig)\n    signal.signal(signal.SIGTERM, _handlesig)\n\n    udev_file = '42-logitech-unify-permissions.rules'\n    if _log.isEnabledFor(_WARNING) \\\n       and not os.path.isfile('/etc/udev/rules.d/' + udev_file) \\\n       and not os.path.isfile('/usr/lib/udev/rules.d/' + udev_file) \\\n       and not os.path.isfile('/usr/local/lib/udev/rules.d/' + udev_file):\n        _log.warning('Solaar udev file not found in expected location')\n        _log.warning('See https://pwr-solaar.github.io/Solaar/installation for more information')\n    try:\n        import solaar.listener as listener\n        import solaar.ui as ui\n\n        listener.setup_scanner(ui.status_changed, ui.error_dialog)\n\n        import solaar.upower as _upower\n        if args.restart_on_wake_up:\n            _upower.watch(listener.start_all, listener.stop_all)\n        else:\n            _upower.watch(lambda: listener.ping_all(True))\n\n        import solaar.configuration as _configuration\n        _configuration.defer_saves = True  # allow configuration saves to be deferred\n\n        # main UI event loop\n        ui.run_loop(listener.start_all, listener.stop_all, args.window != 'only', args.window != 'hide')\n    except Exception:\n        from traceback import format_exc\n        sys.exit('%s: error: %s' % (NAME.lower(), format_exc()))\n\n    temp.close()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "lib/solaar/gtk.py"}], "after_files": [{"content": "#!/usr/bin/env python3\n# -*- python-mode -*-\n# -*- coding: UTF-8 -*-\n\n## Copyright (C) 2012-2013  Daniel Pavel\n##\n## This program is free software; you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation; either version 2 of the License, or\n## (at your option) any later version.\n##\n## This program is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License along\n## with this program; if not, write to the Free Software Foundation, Inc.,\n## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nimport importlib\nimport logging\nimport os.path\nimport signal\nimport sys\nimport tempfile\n\nfrom logging import INFO as _INFO\nfrom logging import WARNING as _WARNING\n\nimport solaar.cli as _cli\nimport solaar.i18n as _i18n\n\nfrom solaar import NAME, __version__\n\n_log = logging.getLogger(__name__)\n\n#\n#\n#\n\n\ndef _require(module, os_package, gi=None, gi_package=None, gi_version=None):\n    try:\n        if gi is not None:\n            gi.require_version(gi_package, gi_version)\n        return importlib.import_module(module)\n    except (ImportError, ValueError):\n        sys.exit('%s: missing required system package %s' % (NAME, os_package))\n\n\nbattery_icons_style = 'regular'\ntemp = tempfile.NamedTemporaryFile(prefix='Solaar_', mode='w', delete=True)\n\n\ndef _parse_arguments():\n    import argparse\n    arg_parser = argparse.ArgumentParser(\n        prog=NAME.lower(), epilog='For more information see https://pwr-solaar.github.io/Solaar'\n    )\n    arg_parser.add_argument(\n        '-d',\n        '--debug',\n        action='count',\n        default=0,\n        help='print logging messages, for debugging purposes (may be repeated for extra verbosity)'\n    )\n    arg_parser.add_argument(\n        '-D',\n        '--hidraw',\n        action='store',\n        dest='hidraw_path',\n        metavar='PATH',\n        help='unifying receiver to use; the first detected receiver if unspecified. Example: /dev/hidraw2'\n    )\n    arg_parser.add_argument('--restart-on-wake-up', action='store_true', help='restart Solaar on sleep wake-up (experimental)')\n    arg_parser.add_argument(\n        '-w', '--window', choices=('show', 'hide', 'only'), help='start with window showing / hidden / only (no tray icon)'\n    )\n    arg_parser.add_argument(\n        '-b',\n        '--battery-icons',\n        choices=('regular', 'symbolic', 'solaar'),\n        help='prefer regular battery / symbolic battery / solaar icons'\n    )\n    arg_parser.add_argument('--tray-icon-size', type=int, help='explicit size for tray icons')\n    arg_parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + __version__)\n    arg_parser.add_argument('--help-actions', action='store_true', help='print help for the optional actions')\n    arg_parser.add_argument('action', nargs=argparse.REMAINDER, choices=_cli.actions, help='optional actions to perform')\n\n    args = arg_parser.parse_args()\n\n    if args.help_actions:\n        _cli.print_help()\n        return\n\n    if args.window is None:\n        args.window = 'show'  # default behaviour is to show main window\n\n    global battery_icons_style\n    battery_icons_style = args.battery_icons if args.battery_icons is not None else 'regular'\n    global tray_icon_size\n    tray_icon_size = args.tray_icon_size\n\n    log_format = '%(asctime)s,%(msecs)03d %(levelname)8s [%(threadName)s] %(name)s: %(message)s'\n    log_level = logging.ERROR - 10 * args.debug\n    logging.getLogger('').setLevel(min(log_level, logging.WARNING))\n    file_handler = logging.StreamHandler(temp)\n    file_handler.setLevel(max(min(log_level, logging.WARNING), logging.INFO))\n    file_handler.setFormatter(logging.Formatter(log_format))\n    logging.getLogger('').addHandler(file_handler)\n    if args.debug > 0:\n        stream_handler = logging.StreamHandler()\n        stream_handler.setFormatter(logging.Formatter(log_format))\n        stream_handler.setLevel(log_level)\n        logging.getLogger('').addHandler(stream_handler)\n\n    if not args.action:\n        if _log.isEnabledFor(logging.INFO):\n            logging.info('language %s (%s), translations path %s', _i18n.language, _i18n.encoding, _i18n.path)\n\n    return args\n\n\n# On first SIGINT, dump threads to stderr; on second, exit\ndef _handlesig(signl, stack):\n    import faulthandler\n    signal.signal(signal.SIGINT, signal.SIG_DFL)\n    signal.signal(signal.SIGTERM, signal.SIG_DFL)\n\n    if signl == int(signal.SIGINT):\n        if _log.isEnabledFor(_INFO):\n            faulthandler.dump_traceback()\n        sys.exit('%s: exit due to keyboard interrupt' % (NAME.lower()))\n    else:\n        sys.exit(0)\n\n\ndef main():\n    _require('pyudev', 'python3-pyudev')\n\n    args = _parse_arguments()\n    if not args:\n        return\n    if args.action:\n        # if any argument, run comandline and exit\n        return _cli.run(args.action, args.hidraw_path)\n\n    gi = _require('gi', 'python3-gi (in Ubuntu) or python3-gobject (in Fedora)')\n    _require('gi.repository.Gtk', 'gir1.2-gtk-3.0', gi, 'Gtk', '3.0')\n\n    # handle ^C in console\n    signal.signal(signal.SIGINT, signal.SIG_DFL)\n    signal.signal(signal.SIGINT, _handlesig)\n    signal.signal(signal.SIGTERM, _handlesig)\n\n    udev_file = '42-logitech-unify-permissions.rules'\n    if _log.isEnabledFor(_WARNING) \\\n       and not os.path.isfile('/etc/udev/rules.d/' + udev_file) \\\n       and not os.path.isfile('/usr/lib/udev/rules.d/' + udev_file) \\\n       and not os.path.isfile('/usr/local/lib/udev/rules.d/' + udev_file):\n        _log.warning('Solaar udev file not found in expected location')\n        _log.warning('See https://pwr-solaar.github.io/Solaar/installation for more information')\n    try:\n        import solaar.listener as listener\n        import solaar.ui as ui\n\n        listener.setup_scanner(ui.status_changed, ui.error_dialog)\n\n        import solaar.upower as _upower\n        if args.restart_on_wake_up:\n            _upower.watch(listener.start_all, listener.stop_all)\n        else:\n            _upower.watch(lambda: listener.ping_all(True))\n\n        import solaar.configuration as _configuration\n        _configuration.defer_saves = True  # allow configuration saves to be deferred\n\n        # main UI event loop\n        ui.run_loop(listener.start_all, listener.stop_all, args.window != 'only', args.window != 'hide')\n    except Exception:\n        from traceback import format_exc\n        sys.exit('%s: error: %s' % (NAME.lower(), format_exc()))\n\n    temp.close()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "lib/solaar/gtk.py"}]}