diff --git a/lib/solaar/cli/config.py b/lib/solaar/cli/config.py index 635d6d8d..5027f68b 100644 --- a/lib/solaar/cli/config.py +++ b/lib/solaar/cli/config.py @@ -16,11 +16,17 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +import yaml as _yaml + from logitech_receiver import settings as _settings from logitech_receiver import settings_templates as _settings_templates from logitech_receiver.common import NamedInts as _NamedInts from solaar import configuration as _configuration +import gi # isort:skip +gi.require_version('Gtk', '3.0') # NOQA: E402 +from gi.repository import Gio, Gtk # NOQA: E402 # isort:skip + def _print_setting(s, verbose=True): print('#', s.label) @@ -175,28 +181,42 @@ def run(receivers, args, find_receiver, find_device): _print_setting(setting) return - result, message, value = set(dev, setting, args) + APP_ID = 'io.github.pwr.solaar' + application = Gtk.Application.new(APP_ID, Gio.ApplicationFlags.HANDLES_COMMAND_LINE) + application.register() + + # if the Solaar UI is running don't save configuration here + result, message, value = set(dev, setting, args, not application.get_is_remote()) if message is not None: print(message) if result is None: raise Exception("%s: failed to set value '%s' [%r]" % (setting.name, str(value), value)) + # if the Solaar UI is running tell it to also perform the set + if application.get_is_remote(): + argl = ['config', dev.serial, setting.name] + argl.extend([a for a in [args.value_key, args.extra_subkey, args.extra2] if a is not None]) + application.run(_yaml.safe_dump(argl)) -def set(dev, setting, args): + +def set(dev, setting, args, save): if setting.kind == _settings.KIND.toggle: value = select_toggle(args.value_key, setting) + args.value_key = value message = 'Setting %s of %s to %s' % (setting.name, dev.name, value) - result = setting.write(value) + result = setting.write(value, save=save) elif setting.kind == _settings.KIND.range: value = select_range(args.value_key, setting) + args.value_key = value message = 'Setting %s of %s to %s' % (setting.name, dev.name, value) - result = setting.write(value) + result = setting.write(value, save=save) elif setting.kind == _settings.KIND.choice: value = select_choice(args.value_key, setting.choices, setting, None) + args.value_key = int(value) message = 'Setting %s of %s to %s' % (setting.name, dev.name, value) - result = setting.write(value) + result = setting.write(value, save=save) elif setting.kind == _settings.KIND.map_choice: if args.extra_subkey is None: @@ -209,10 +229,12 @@ def set(dev, setting, args): k = next((k for k in setting.choices.keys() if ikey == k), None) if k is not None: value = select_choice(args.extra_subkey, setting.choices[k], setting, key) + args.extra_subkey = int(value) + args.value_key = str(int(k)) else: raise Exception("%s: key '%s' not in setting" % (setting.name, key)) message = 'Setting %s of %s key %r to %r' % (setting.name, dev.name, k, value) - result = setting.write_key_value(int(k), value) + result = setting.write_key_value(int(k), value, save=save) elif setting.kind == _settings.KIND.multiple_toggle: if args.extra_subkey is None: @@ -226,10 +248,12 @@ def set(dev, setting, args): k = next((k for k in setting._labels if ikey == k), None) if k is not None: value = select_toggle(args.extra_subkey, setting, key=k) + args.extra_subkey = value + args.value_key = str(int(k)) else: raise Exception("%s: key '%s' not in setting" % (setting.name, key)) message = 'Setting %s key %r to %r' % (setting.name, k, value) - result = setting.write_key_value(str(int(k)), value) + result = setting.write_key_value(str(int(k)), value, save=save) elif setting.kind == _settings.KIND.multiple_range: if args.extra_subkey is None: @@ -247,10 +271,11 @@ def set(dev, setting, args): item = setting._value[k] if args.extra_subkey in item.keys(): item[args.extra_subkey] = to_int(args.extra2) + args.value_key = str(int(k)) else: raise Exception("%s: key '%s' not in setting" % (setting.name, key)) message = 'Setting %s key %s parameter %s to %r' % (setting.name, k, args.extra_subkey, item[args.extra_subkey]) - result = setting.write_key_value(int(k), item) + result = setting.write_key_value(int(k), item, save=save) value = item else: diff --git a/lib/solaar/ui/__init__.py b/lib/solaar/ui/__init__.py index 76e09a7d..4676fb64 100644 --- a/lib/solaar/ui/__init__.py +++ b/lib/solaar/ui/__init__.py @@ -17,12 +17,14 @@ ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. from logging import DEBUG as _DEBUG +from logging import INFO as _INFO from logging import getLogger +import yaml as _yaml + import gi # isort:skip gi.require_version('Gtk', '3.0') # NOQA: E402 - -from gi.repository import GLib, Gtk # NOQA: E402 # isort:skip +from gi.repository import GLib, Gtk, Gio # NOQA: E402 # isort:skip from logitech_receiver.status import ALERT # NOQA: E402 # isort:skip from solaar.i18n import _ # NOQA: E402 # isort:skip @@ -126,9 +128,20 @@ def _activate(app): def _command_line(app, command_line): - if _log.isEnabledFor(_DEBUG): - _log.debug('command_line %s', command_line.get_arguments()) - + args = command_line.get_arguments() + args = _yaml.safe_load(''.join(args)) if args else args + if not args: + _activate(app) + elif args[0] == 'config': # config call from remote instance + if _log.isEnabledFor(_INFO): + _log.info('remote command line %s', args) + from solaar.ui.config_panel import change_setting # prevent circular import + from solaar.ui.window import find_device # prevent circular import + dev = find_device(args[1]) + if dev: + setting = next((s for s in dev.settings if s.name == args[2]), None) + if setting: + change_setting(dev, setting, args[3:]) return 0 @@ -147,18 +160,18 @@ def _shutdown(app, shutdown_hook): notify.uninit() -def run_loop(startup_hook, shutdown_hook, use_tray, show_window, args=None): +def run_loop(startup_hook, shutdown_hook, use_tray, show_window): assert use_tray or show_window, 'need either tray or visible window' # from gi.repository.Gio import ApplicationFlags as _ApplicationFlags APP_ID = 'io.github.pwr.solaar' - application = Gtk.Application.new(APP_ID, 0) # _ApplicationFlags.HANDLES_COMMAND_LINE) + application = Gtk.Application.new(APP_ID, Gio.ApplicationFlags.HANDLES_COMMAND_LINE) application.connect('startup', lambda app, startup_hook: _startup(app, startup_hook, use_tray, show_window), startup_hook) application.connect('command-line', _command_line) application.connect('activate', _activate) application.connect('shutdown', _shutdown, shutdown_hook) - application.run(args) + application.run() #