mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-03-27 07:00:41 +01:00
Compare commits
8 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b500c0e74 | ||
|
|
7658efbd71 | ||
|
|
c2fa055fa3 | ||
|
|
ce1c4c5008 | ||
|
|
aec607ecb4 | ||
|
|
560ba890b3 | ||
|
|
f7a6f751dd | ||
|
|
2189fd2c2e |
11 changed files with 120 additions and 36 deletions
|
|
@ -10,7 +10,6 @@ MAX_INITIALIZER_LINES = 0
|
||||||
WARNINGS = YES
|
WARNINGS = YES
|
||||||
QUIET = YES
|
QUIET = YES
|
||||||
INPUT = "@builddir@"
|
INPUT = "@builddir@"
|
||||||
FILTER_PATTERNS = *.h *.dox
|
|
||||||
IMAGE_PATH = "@builddir@"
|
IMAGE_PATH = "@builddir@"
|
||||||
GENERATE_HTML = YES
|
GENERATE_HTML = YES
|
||||||
HTML_OUTPUT = api
|
HTML_OUTPUT = api
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,13 @@ position.
|
||||||
When libinput detects a cursor jump it prints a bug warning to the log with
|
When libinput detects a cursor jump it prints a bug warning to the log with
|
||||||
the text **"Touch jump detected and discarded."** and a link to this page.
|
the text **"Touch jump detected and discarded."** and a link to this page.
|
||||||
|
|
||||||
In most cases, this is a bug in the kernel driver and to libinput it appears
|
.. note:: This warning is ratelimited and will stop appearing after a few
|
||||||
that the touch point moves from its previous position. The pointer jump can
|
times, even if the touchpad jumps continue.
|
||||||
usually be seen in the :ref:`libinput record <libinput-record>` output for the device:
|
|
||||||
|
|
||||||
|
In most cases, this is a bug in the firmware (or kernel driver) and to
|
||||||
|
libinput it appears that the touch point moves from its previous position.
|
||||||
|
The pointer jump can usually be seen in the :ref:`libinput record
|
||||||
|
<libinput-record>` output for the device:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|
@ -50,9 +53,14 @@ usually be seen in the :ref:`libinput record <libinput-record>` output for the d
|
||||||
In this recording, the pointer jumps from its position 3752/2216 to
|
In this recording, the pointer jumps from its position 3752/2216 to
|
||||||
1640/4681 within a single frame. On this particular touchpad, this would
|
1640/4681 within a single frame. On this particular touchpad, this would
|
||||||
represent a physical move of almost 50mm. libinput detects some of these
|
represent a physical move of almost 50mm. libinput detects some of these
|
||||||
jumps and discards the movement but otherwise continues as usual. However,
|
jumps and discards the movement but otherwise continues as usual.
|
||||||
the bug should be fixed at the kernel level.
|
If your only encounter with these jumps is the warning printed to the log,
|
||||||
|
libinput functions as intended.
|
||||||
|
|
||||||
When you encounter the warning in the log, please generate a recording of
|
When you encounter the warning in the log, please generate a recording of
|
||||||
your touchpad with :ref:`libinput record <libinput-record>` and file a bug.
|
your touchpad with :ref:`libinput record <libinput-record>` and file a bug.
|
||||||
See :ref:`reporting_bugs` for more details.
|
See :ref:`reporting_bugs` for more details.
|
||||||
|
|
||||||
|
Note that it most cases, libinput cannot actually fix the issue. Filing a
|
||||||
|
bug is useful to figure out if there are other factors at play or whether
|
||||||
|
there are heuristics we can employ to reduce the impact.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
project('libinput', 'c',
|
project('libinput', 'c',
|
||||||
version : '1.15.3',
|
version : '1.15.5',
|
||||||
license : 'MIT/Expat',
|
license : 'MIT/Expat',
|
||||||
default_options : [ 'c_std=gnu99', 'warning_level=2' ],
|
default_options : [ 'c_std=gnu99', 'warning_level=2' ],
|
||||||
meson_version : '>= 0.41.0')
|
meson_version : '>= 0.41.0')
|
||||||
|
|
|
||||||
|
|
@ -1718,10 +1718,11 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
|
||||||
|
|
||||||
if (tp_detect_jumps(tp, t, time)) {
|
if (tp_detect_jumps(tp, t, time)) {
|
||||||
if (!tp->semi_mt)
|
if (!tp->semi_mt)
|
||||||
evdev_log_bug_kernel(tp->device,
|
evdev_log_bug_kernel_ratelimit(tp->device,
|
||||||
"Touch jump detected and discarded.\n"
|
&tp->jump.warning,
|
||||||
"See %stouchpad-jumping-cursors.html for details\n",
|
"Touch jump detected and discarded.\n"
|
||||||
HTTP_DOC_LINK);
|
"See %stouchpad-jumping-cursors.html for details\n",
|
||||||
|
HTTP_DOC_LINK);
|
||||||
tp_motion_history_reset(t);
|
tp_motion_history_reset(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3581,6 +3582,9 @@ tp_init(struct tp_dispatch *tp,
|
||||||
if (!use_touch_size)
|
if (!use_touch_size)
|
||||||
tp_init_pressure(tp, device);
|
tp_init_pressure(tp, device);
|
||||||
|
|
||||||
|
/* 5 warnings per 2 hours should be enough */
|
||||||
|
ratelimit_init(&tp->jump.warning, s2us(2 * 60 * 60), 5);
|
||||||
|
|
||||||
/* Set the dpi to that of the x axis, because that's what we normalize
|
/* Set the dpi to that of the x axis, because that's what we normalize
|
||||||
to when needed*/
|
to when needed*/
|
||||||
device->dpi = device->abs.absinfo_x->resolution * 25.4;
|
device->dpi = device->abs.absinfo_x->resolution * 25.4;
|
||||||
|
|
|
||||||
|
|
@ -279,6 +279,10 @@ struct tp_dispatch {
|
||||||
*/
|
*/
|
||||||
unsigned int fake_touches;
|
unsigned int fake_touches;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct ratelimit warning;
|
||||||
|
} jump;
|
||||||
|
|
||||||
/* if pressure goes above high -> touch down,
|
/* if pressure goes above high -> touch down,
|
||||||
if pressure then goes below low -> touch up */
|
if pressure then goes below low -> touch up */
|
||||||
struct {
|
struct {
|
||||||
|
|
|
||||||
|
|
@ -312,3 +312,29 @@ error:
|
||||||
free(result);
|
free(result);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip any of the characters in what from the beginning and end of the
|
||||||
|
* input string.
|
||||||
|
*
|
||||||
|
* @return a newly allocated string with none of "what" at the beginning or
|
||||||
|
* end of string
|
||||||
|
*/
|
||||||
|
static inline char *
|
||||||
|
strstrip(const char *input, const char *what)
|
||||||
|
{
|
||||||
|
char *str, *last;
|
||||||
|
|
||||||
|
str = safe_strdup(&input[strspn(input, what)]);
|
||||||
|
|
||||||
|
last = str;
|
||||||
|
|
||||||
|
for (char *c = str; *c != '\0'; c++) {
|
||||||
|
if (!strchr(what, *c))
|
||||||
|
last = c + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*last = '\0';
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -725,7 +725,7 @@ litest_init_device_udev_rules(struct litest_test_device *dev, FILE *f)
|
||||||
if (need_keyboard_builtin) {
|
if (need_keyboard_builtin) {
|
||||||
fprintf(f, ""
|
fprintf(f, ""
|
||||||
"ATTRS{name}==\"litest %s*\","
|
"ATTRS{name}==\"litest %s*\","
|
||||||
" IMPORT{builtin}+=\"keyboard\"\n",
|
" IMPORT{builtin}=\"keyboard\"\n",
|
||||||
dev->name);
|
dev->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1033,6 +1033,44 @@ START_TEST(strjoin_test)
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(strstrip_test)
|
||||||
|
{
|
||||||
|
struct strstrip_test {
|
||||||
|
const char *string;
|
||||||
|
const char *expected;
|
||||||
|
const char *what;
|
||||||
|
} tests[] = {
|
||||||
|
{ "foo", "foo", "1234" },
|
||||||
|
{ "\"bar\"", "bar", "\"" },
|
||||||
|
{ "'bar'", "bar", "'" },
|
||||||
|
{ "\"bar\"", "\"bar\"", "'" },
|
||||||
|
{ "'bar'", "'bar'", "\"" },
|
||||||
|
{ "\"bar\"", "bar", "\"" },
|
||||||
|
{ "\"\"", "", "\"" },
|
||||||
|
{ "\"foo\"bar\"", "foo\"bar", "\"" },
|
||||||
|
{ "\"'foo\"bar\"", "foo\"bar", "\"'" },
|
||||||
|
{ "abcfooabcbarbca", "fooabcbar", "abc" },
|
||||||
|
{ "xxxxfoo", "foo", "x" },
|
||||||
|
{ "fooyyyy", "foo", "y" },
|
||||||
|
{ "xxxxfooyyyy", "foo", "xy" },
|
||||||
|
{ "x xfooy y", " xfooy ", "xy" },
|
||||||
|
{ " foo\n", "foo", " \n" },
|
||||||
|
{ "", "", "abc" },
|
||||||
|
{ "", "", "" },
|
||||||
|
{ NULL , NULL, NULL }
|
||||||
|
};
|
||||||
|
struct strstrip_test *t = tests;
|
||||||
|
|
||||||
|
while (t->string) {
|
||||||
|
char *str;
|
||||||
|
str = strstrip(t->string, t->what);
|
||||||
|
ck_assert_str_eq(str, t->expected);
|
||||||
|
free(str);
|
||||||
|
t++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
START_TEST(list_test_insert)
|
START_TEST(list_test_insert)
|
||||||
{
|
{
|
||||||
struct list_test {
|
struct list_test {
|
||||||
|
|
@ -1138,6 +1176,7 @@ litest_utils_suite(void)
|
||||||
tcase_add_test(tc, strsplit_test);
|
tcase_add_test(tc, strsplit_test);
|
||||||
tcase_add_test(tc, kvsplit_double_test);
|
tcase_add_test(tc, kvsplit_double_test);
|
||||||
tcase_add_test(tc, strjoin_test);
|
tcase_add_test(tc, strjoin_test);
|
||||||
|
tcase_add_test(tc, strstrip_test);
|
||||||
tcase_add_test(tc, time_conversion);
|
tcase_add_test(tc, time_conversion);
|
||||||
|
|
||||||
tcase_add_test(tc, list_test_insert);
|
tcase_add_test(tc, list_test_insert);
|
||||||
|
|
|
||||||
|
|
@ -1430,37 +1430,26 @@ print_system_header(struct record_context *ctx)
|
||||||
struct utsname u;
|
struct utsname u;
|
||||||
const char *kernel = "unknown";
|
const char *kernel = "unknown";
|
||||||
FILE *dmi, *osrelease;
|
FILE *dmi, *osrelease;
|
||||||
char buf[2048] = "unknown";
|
char dmistr[2048] = "unknown";
|
||||||
|
|
||||||
if (uname(&u) != -1)
|
|
||||||
kernel = u.release;
|
|
||||||
|
|
||||||
dmi = fopen("/sys/class/dmi/id/modalias", "r");
|
|
||||||
if (dmi) {
|
|
||||||
if (fgets(buf, sizeof(buf), dmi)) {
|
|
||||||
buf[strlen(buf) - 1] = '\0'; /* linebreak */
|
|
||||||
} else {
|
|
||||||
sprintf(buf, "unknown");
|
|
||||||
}
|
|
||||||
fclose(dmi);
|
|
||||||
}
|
|
||||||
|
|
||||||
iprintf(ctx, "system:\n");
|
iprintf(ctx, "system:\n");
|
||||||
indent_push(ctx);
|
indent_push(ctx);
|
||||||
|
|
||||||
|
/* /etc/os-release version and distribution name */
|
||||||
osrelease = fopen("/etc/os-release", "r");
|
osrelease = fopen("/etc/os-release", "r");
|
||||||
if (!osrelease)
|
if (!osrelease)
|
||||||
osrelease = fopen("/usr/lib/os-release", "r");
|
osrelease = fopen("/usr/lib/os-release", "r");
|
||||||
if (osrelease) {
|
if (osrelease) {
|
||||||
char *distro = NULL, *version = NULL;
|
char *distro = NULL, *version = NULL;
|
||||||
|
char osrstr[256] = "unknown";
|
||||||
|
|
||||||
while (fgets(buf, sizeof(buf), osrelease)) {
|
while (fgets(osrstr, sizeof(osrstr), osrelease)) {
|
||||||
buf[strlen(buf) - 1] = '\0'; /* linebreak */
|
osrstr[strlen(osrstr) - 1] = '\0'; /* linebreak */
|
||||||
|
|
||||||
if (!distro && strneq(buf, "ID=", 3))
|
if (!distro && strneq(osrstr, "ID=", 3))
|
||||||
distro = safe_strdup(&buf[3]);
|
distro = strstrip(&osrstr[3], "\"'");
|
||||||
else if (!version && strneq(buf, "VERSION_ID=", 11))
|
else if (!version && strneq(osrstr, "VERSION_ID=", 11))
|
||||||
version = safe_strdup(&buf[11]);
|
version = strstrip(&osrstr[11], "\"'");
|
||||||
|
|
||||||
if (distro && version) {
|
if (distro && version) {
|
||||||
iprintf(ctx, "os: \"%s:%s\"\n", distro, version);
|
iprintf(ctx, "os: \"%s:%s\"\n", distro, version);
|
||||||
|
|
@ -1471,8 +1460,23 @@ print_system_header(struct record_context *ctx)
|
||||||
free(version);
|
free(version);
|
||||||
fclose(osrelease);
|
fclose(osrelease);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* kernel version */
|
||||||
|
if (uname(&u) != -1)
|
||||||
|
kernel = u.release;
|
||||||
iprintf(ctx, "kernel: \"%s\"\n", kernel);
|
iprintf(ctx, "kernel: \"%s\"\n", kernel);
|
||||||
iprintf(ctx, "dmi: \"%s\"\n", buf);
|
|
||||||
|
/* dmi modalias */
|
||||||
|
dmi = fopen("/sys/class/dmi/id/modalias", "r");
|
||||||
|
if (dmi) {
|
||||||
|
if (fgets(dmistr, sizeof(dmistr), dmi)) {
|
||||||
|
dmistr[strlen(dmistr) - 1] = '\0'; /* linebreak */
|
||||||
|
} else {
|
||||||
|
sprintf(dmistr, "unknown");
|
||||||
|
}
|
||||||
|
fclose(dmi);
|
||||||
|
}
|
||||||
|
iprintf(ctx, "dmi: \"%s\"\n", dmistr);
|
||||||
indent_pop(ctx);
|
indent_pop(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
ACTION!="add|change", GOTO="libinput_device_group_end"
|
ACTION!="add|change", GOTO="libinput_device_group_end"
|
||||||
KERNEL!="event[0-9]*", GOTO="libinput_device_group_end"
|
KERNEL!="event[0-9]*", GOTO="libinput_device_group_end"
|
||||||
|
|
||||||
ATTRS{phys}=="?*", IMPORT{program}+="@UDEV_TEST_PATH@libinput-device-group %S%p"
|
ATTRS{phys}=="?*", IMPORT{program}="@UDEV_TEST_PATH@libinput-device-group %S%p"
|
||||||
|
|
||||||
LABEL="libinput_device_group_end"
|
LABEL="libinput_device_group_end"
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@ KERNEL!="event*", GOTO="libinput_fuzz_override_end"
|
||||||
# about that.
|
# about that.
|
||||||
ATTRS{capabilities/abs}!="0", \
|
ATTRS{capabilities/abs}!="0", \
|
||||||
ENV{ID_INPUT_TOUCHPAD}=="1", \
|
ENV{ID_INPUT_TOUCHPAD}=="1", \
|
||||||
IMPORT{program}+="@UDEV_TEST_PATH@libinput-fuzz-extract %S%p", \
|
IMPORT{program}="@UDEV_TEST_PATH@libinput-fuzz-extract %S%p", \
|
||||||
RUN{program}+="@UDEV_TEST_PATH@libinput-fuzz-to-zero %S%p", \
|
RUN{program}+="@UDEV_TEST_PATH@libinput-fuzz-to-zero %S%p", \
|
||||||
GOTO="libinput_fuzz_override_end"
|
GOTO="libinput_fuzz_override_end"
|
||||||
ATTRS{capabilities/abs}!="0", \
|
ATTRS{capabilities/abs}!="0", \
|
||||||
ENV{ID_INPUT_TOUCHSCREEN}=="1", \
|
ENV{ID_INPUT_TOUCHSCREEN}=="1", \
|
||||||
IMPORT{program}+="@UDEV_TEST_PATH@libinput-fuzz-extract %S%p", \
|
IMPORT{program}="@UDEV_TEST_PATH@libinput-fuzz-extract %S%p", \
|
||||||
RUN{program}+="@UDEV_TEST_PATH@libinput-fuzz-to-zero %S%p", \
|
RUN{program}+="@UDEV_TEST_PATH@libinput-fuzz-to-zero %S%p", \
|
||||||
GOTO="libinput_fuzz_override_end"
|
GOTO="libinput_fuzz_override_end"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue