diff --git a/data/key-mapper.glade b/data/key-mapper.glade index 88a5456f..b1b19b65 100644 --- a/data/key-mapper.glade +++ b/data/key-mapper.glade @@ -707,38 +707,4 @@ Control_R - - False - dialog - False - Loading... - - - False - vertical - 2 - - - False - True - end - - - - - - - - - False - False - 0 - - - - - - - - diff --git a/keymapper/gtk/loading.py b/keymapper/gtk/loading.py deleted file mode 100644 index 3e3441ad..00000000 --- a/keymapper/gtk/loading.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -# key-mapper - GUI for device specific keyboard mappings -# Copyright (C) 2020 sezanzeb -# -# This file is part of key-mapper. -# -# key-mapper is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# key-mapper is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with key-mapper. If not, see . - - -"""Error dialog.""" - - -import gi -gi.require_version('Gtk', '3.0') -gi.require_version('GLib', '2.0') -from gi.repository import Gtk - -from keymapper.data import get_data_path - - -class LoadingDialog: - """Displays 'Loading...' until Key Mapper is loaded.""" - def __init__(self): - """Open a dialog that says 'Loading...'.""" - gladefile = get_data_path('key-mapper.glade') - builder = Gtk.Builder() - builder.add_from_file(gladefile) - dialog = builder.get_object('loading') - dialog.show_all() - self.dialog = dialog - - def destroy(self): - """Destroy this dialog.""" - self.dialog.destroy() diff --git a/keymapper/gtk/window.py b/keymapper/gtk/window.py index ba8ecae0..4074a2db 100755 --- a/keymapper/gtk/window.py +++ b/keymapper/gtk/window.py @@ -23,6 +23,7 @@ import gi +import time gi.require_version('Gtk', '3.0') gi.require_version('GLib', '2.0') from gi.repository import Gtk, Gdk, GLib @@ -101,11 +102,10 @@ class Window: window = self.get('window') window.show() - window.set_sensitive(False) - self.get('wrapper').set_opacity(0) - loading = LoadingDialog() self.window = window + # if any of the next steps take a bit to complete, have the window + # already visible to make it look more responsive. gtk_iteration() self.populate_devices() @@ -114,10 +114,6 @@ class Window: self.timeout = GLib.timeout_add(100, self.check_add_row) - window.set_sensitive(True) - self.get('wrapper').set_opacity(1) - loading.destroy() - def get(self, name): """Get a widget from the window""" return self.builder.get_object(name) diff --git a/keymapper/linux.py b/keymapper/linux.py index da999fde..9dd3648b 100644 --- a/keymapper/linux.py +++ b/keymapper/linux.py @@ -23,15 +23,13 @@ import subprocess +import multiprocessing import evdev from keymapper.logger import logger -_devices = None - - def can_grab(path): """Can input events from the device be read? @@ -100,7 +98,7 @@ class KeycodeReader: # keycode_reader = KeycodeReader() -def get_devices(): +def _get_devices(pipe): """Group devices and get relevant infos per group. Returns a list containing mappings of @@ -112,10 +110,21 @@ def get_devices(): They are grouped by usb port. """ - # cache the result, this takes a second to complete - global _devices - if _devices is not None: - return _devices + """ + evdev.list_devices -> string[] dev/input/event# paths + device = evdev.InputDevice(path) + device.capabilities().keys() ein array mit evdev.ecodes.EV_KEY oder + irgendn stuff der nicht interessiert + + device.phys -> + + device.phys usb-0000:03:00.0-4/input2 + device.phys usb-0000:03:00.0-4/input1 + device.phys usb-0000:03:00.0-4/input0 + device.phys usb-0000:03:00.0-3/input1 + device.phys usb-0000:03:00.0-3/input1 + device.phys usb-0000:03:00.0-3/input0 + """ devices = [evdev.InputDevice(path) for path in evdev.list_devices()] @@ -144,6 +153,18 @@ def get_devices(): 'devices': names } - _devices = result - logger.info('Found %s', ', '.join([f'"{name}"' for name in result])) - return result + pipe.send(result) + + +# populate once for the whole app. Since InputDevice destructors take +# quite some time, do this in a process that can take as much time as it +# wants after piping the result. +pipe = multiprocessing.Pipe() +multiprocessing.Process(target=_get_devices, args=(pipe[1],)).start() +# block until devices are available +_devices = pipe[0].recv() +logger.info('Found %s', ', '.join([f'"{name}"' for name in _devices])) + + +def get_devices(): + return _devices