From d2c7cfa5fa472c67be5eb16fa60182078e5f00c7 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Thu, 9 Nov 2017 15:42:29 +0100 Subject: [PATCH] input_filter: avoid closing input sessions The input filter used to temporarily close all input sessions upon its reconfiguration. In most cases, the same set of sessions is re-established immediately afterwards. However, at the server (driver) side, the closing of the session implicitly disables the input-event queue. Hence events generated by the hardware while the session is closed are dropped. This becomes a noticeable problem when using the recently added modifier feature for handling capslock. The change of the ROM always triggers the re-configuration of the input filter. When pressing capslock and other keys at a high rate, press/release events may get lost. This patch solves this problem by maintaining all input sessions that are defined in both the old and new configuration. It thereby removes the short duration where the input event queues are temporarily disabled at the drivers. --- repos/os/src/server/input_filter/main.cc | 26 +++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/repos/os/src/server/input_filter/main.cc b/repos/os/src/server/input_filter/main.cc index e291ecf101..46b35b6f50 100644 --- a/repos/os/src/server/input_filter/main.cc +++ b/repos/os/src/server/input_filter/main.cc @@ -378,15 +378,35 @@ struct Input_filter::Main : Input_connection::Avail_handler, void _apply_config() { - _input_connections.for_each([&] (Registered &conn) { - destroy(_heap, &conn); }); + Xml_node const config = _config.xml(); - _config.xml().for_each_sub_node("input", [&] (Xml_node input_node) { + /* close input sessions that are no longer needed */ + _input_connections.for_each([&] (Registered &conn) { + + bool obsolete = true; + config.for_each_sub_node("input", [&] (Xml_node input_node) { + if (conn.label() == input_node.attribute_value("label", Label())) + obsolete = false; }); + + if (obsolete) + destroy(_heap, &conn); + }); + + /* open new input sessions */ + config.for_each_sub_node("input", [&] (Xml_node input_node) { try { Label const label = input_node.attribute_value("label", Label()); + bool already_exists = false; + _input_connections.for_each([&] (Input_connection const &conn) { + if (conn.label() == label) + already_exists = true; }); + + if (already_exists) + return; + try { new (_heap) Registered(_input_connections, _env,