diff --git a/app/__init__.py b/app/__init__.py deleted file mode 100644 index ba48849c..00000000 --- a/app/__init__.py +++ /dev/null @@ -1,53 +0,0 @@ -# -# -# - -from gi.repository import GObject - -from . import ui -from logitech.devices import constants as C - - -APP_TITLE = 'Solaar' - - -def _status_updated(watcher, icon, window): - while True: - watcher.status_changed.wait() - text = watcher.status_text - watcher.status_changed.clear() - - icon_name = APP_TITLE + '-fail' if watcher.rstatus.code < C.STATUS.CONNECTED else APP_TITLE - - if icon: - GObject.idle_add(ui.icon.update, icon, watcher.rstatus, text, icon_name) - - if window: - GObject.idle_add(ui.window.update, window, watcher.rstatus, dict(watcher.devices), icon_name) - - -def run(config): - GObject.threads_init() - - ui.notify.init(APP_TITLE, config.notifications) - - from .watcher import WatcherThread - watcher = WatcherThread(ui.notify.show) - watcher.start() - - window = ui.window.create(APP_TITLE, watcher.rstatus, not config.start_hidden, config.close_to_tray) - window.set_icon_name(APP_TITLE + '-fail') - - tray_icon = ui.icon.create(APP_TITLE, (ui.window.toggle, window)) - tray_icon.set_from_icon_name(APP_TITLE + '-fail') - - import threading - ui_update_thread = threading.Thread(target=_status_updated, name='ui_update', args=(watcher, tray_icon, window)) - ui_update_thread.daemon = True - ui_update_thread.start() - - from gi.repository import Gtk - Gtk.main() - - watcher.stop() - ui.notify.set_active(False) diff --git a/app/actions.py b/app/actions.py index 2504a143..df65856a 100644 --- a/app/actions.py +++ b/app/actions.py @@ -7,8 +7,7 @@ import logging from logitech.unifying_receiver import api from logitech import devices -from . import ui -import ui.pair +import ui def full_scan(button, watcher): diff --git a/app/solaar.py b/app/solaar.py new file mode 100644 index 00000000..1733a2cf --- /dev/null +++ b/app/solaar.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python + +__version__ = '0.4' + +# +# +# + +import logging +from gi.repository import Gtk +from gi.repository import GObject + +from logitech.devices import constants as C + +import ui +from watcher import Watcher + + +APP_TITLE = 'Solaar' + + +def _status_updated(watcher, icon, window): + while True: + watcher.status_changed.wait() + text = watcher.status_text + watcher.status_changed.clear() + + icon_name = APP_TITLE + '-fail' if watcher.rstatus.code < C.STATUS.CONNECTED else APP_TITLE + + if icon: + GObject.idle_add(ui.icon.update, icon, watcher.rstatus, text, icon_name) + + if window: + GObject.idle_add(ui.window.update, window, watcher.rstatus, dict(watcher.devices), icon_name) + + +if __name__ == '__main__': + import argparse + arg_parser = argparse.ArgumentParser(prog=APP_TITLE) + arg_parser.add_argument('-v', '--verbose', action='count', default=0, + help='increase the logger verbosity') + arg_parser.add_argument('-N', '--disable-notifications', action='store_false', dest='notifications', + help='disable desktop notifications') + arg_parser.add_argument('-H', '--start-hidden', action='store_true', dest='start_hidden', + help='hide the application window on start') + arg_parser.add_argument('-t', '--close-to-tray', action='store_true', + help='closing the application window hides it instead of terminating the application') + arg_parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + __version__) + args = arg_parser.parse_args() + + log_level = logging.root.level - 10 * args.verbose + log_format='%(asctime)s %(levelname)8s [%(threadName)s] %(name)s: %(message)s' + logging.basicConfig(level=log_level if log_level > 0 else 1, format=log_format) + + GObject.threads_init() + + ui.notify.init(APP_TITLE, args.notifications) + + watcher = Watcher(ui.notify.show) + watcher.start() + + window = ui.window.create(APP_TITLE, watcher.rstatus, not args.start_hidden, args.close_to_tray) + window.set_icon_name(APP_TITLE + '-fail') + + tray_icon = ui.icon.create(APP_TITLE, (ui.window.toggle, window)) + tray_icon.set_from_icon_name(APP_TITLE + '-fail') + + import threading + ui_update_thread = threading.Thread(target=_status_updated, name='ui_update', args=(watcher, tray_icon, window)) + ui_update_thread.daemon = True + ui_update_thread.start() + + Gtk.main() + + watcher.stop() + ui.notify.set_active(False) diff --git a/app/ui/__init__.py b/app/ui/__init__.py index 94a3aab5..bacb7d14 100644 --- a/app/ui/__init__.py +++ b/app/ui/__init__.py @@ -1,3 +1,3 @@ # pass -from . import (notify, icon, window) +from . import (notify, icon, window, pair) diff --git a/app/watcher.py b/app/watcher.py index a09e44e2..5d4db61d 100644 --- a/app/watcher.py +++ b/app/watcher.py @@ -11,7 +11,7 @@ from logitech.unifying_receiver.listener import EventsListener from logitech import devices from logitech.devices import constants as C -from . import actions +import actions _l = logging.getLogger('watcher') @@ -38,10 +38,10 @@ class _DevStatus(api.AttachedDeviceInfo): return 'DevStatus(%d,%s,%d)' % (self.number, self.name, self.code) -class WatcherThread(threading.Thread): +class Watcher(threading.Thread): """Keeps a map of all attached devices and their statuses.""" def __init__(self, notify_callback=None): - super(WatcherThread, self).__init__(group='Solaar', name='Watcher') + super(Watcher, self).__init__(group='Solaar', name='Watcher') self.daemon = True self.active = False @@ -194,7 +194,7 @@ class WatcherThread(threading.Thread): devstatus.code = status_code devstatus.text = status_text - _l.debug("%s status update %s => %s: %s", devstatus, old_status_code, status_code, status_text) + _l.debug("%s update %s => %s: %s", devstatus, old_status_code, status_code, status_text) if self.notify: if status_code < C.STATUS.CONNECTED or old_status_code < C.STATUS.CONNECTED or status_code < old_status_code: diff --git a/lib/logitech/unifying_receiver/listener.py b/lib/logitech/unifying_receiver/listener.py index d0ee65a9..36fc51a6 100644 --- a/lib/logitech/unifying_receiver/listener.py +++ b/lib/logitech/unifying_receiver/listener.py @@ -104,10 +104,10 @@ class EventsListener(threading.Thread): self._active = False def request(self, api_function, *args, **kwargs): - """Make an UR API request. + """Make an UR API request through this listener's receiver. - The api_function will get the receiver handle as a first agument, all - other args and kwargs will follow. + The api_function must have a receiver handle as a first agument, all + other passed args and kwargs will follow. """ # if _l.isEnabledFor(_LOG_LEVEL): # _l.log(_LOG_LEVEL, "%s request '%s.%s' with %s, %s", self, api_function.__module__, api_function.__name__, args, kwargs) diff --git a/solaar b/solaar index 620fe707..24a93a44 100755 --- a/solaar +++ b/solaar @@ -3,10 +3,10 @@ cd -P `dirname "$0"` export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/lib/native/`uname -m` -export PYTHONPATH=$PWD:$PWD/lib +export PYTHONPATH=$PWD/app:$PWD/lib export XDG_DATA_DIRS=$PWD/resources:$XDG_DATA_DIRS cd - -exec python -OO solaar.py "$@" +exec python -OO -m solaar "$@" # exec python -OO -m profile -o $TMPDIR/profile.log solaar.py "$@" diff --git a/solaar.py b/solaar.py deleted file mode 100644 index 646b1505..00000000 --- a/solaar.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python - -__version__ = '0.4' - -# -# -# - -if __name__ == '__main__': - import argparse - arg_parser = argparse.ArgumentParser(prog='Solaar') - arg_parser.add_argument('-v', '--verbose', action='count', default=0, - help='increase the logger verbosity') - arg_parser.add_argument('-N', '--disable-notifications', action='store_false', dest='notifications', - help='disable desktop notifications') - arg_parser.add_argument('-H', '--start-hidden', action='store_true', dest='start_hidden', - help='hide the application window on start') - arg_parser.add_argument('-t', '--close-to-tray', action='store_true', - help='closing the application window hides it instead of terminating the application') - arg_parser.add_argument('-V', '--version', action='version', version='%(prog)s ' + __version__) - args = arg_parser.parse_args() - - import logging - log_level = logging.root.level - 10 * args.verbose - log_format='%(asctime)s %(levelname)8s [%(threadName)s] %(name)s: %(message)s' - logging.basicConfig(level=log_level if log_level > 0 else 1, format=log_format) - - import app - app.run(args)