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 <rom> 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.
This commit is contained in:
Norman Feske 2017-11-09 15:42:29 +01:00 committed by Christian Helmuth
parent c05ab9c310
commit d2c7cfa5fa

View File

@ -378,15 +378,35 @@ struct Input_filter::Main : Input_connection::Avail_handler,
void _apply_config() void _apply_config()
{ {
_input_connections.for_each([&] (Registered<Input_connection> &conn) { Xml_node const config = _config.xml();
destroy(_heap, &conn); });
_config.xml().for_each_sub_node("input", [&] (Xml_node input_node) { /* close input sessions that are no longer needed */
_input_connections.for_each([&] (Registered<Input_connection> &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 { try {
Label const label = Label const label =
input_node.attribute_value("label", 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 { try {
new (_heap) new (_heap)
Registered<Input_connection>(_input_connections, _env, Registered<Input_connection>(_input_connections, _env,