Compare commits
25 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa668332a0 | ||
|
|
3a9f38bd16 | ||
|
|
e3034096c1 | ||
|
|
0fa22c8c5a | ||
|
|
0d9a2b7624 | ||
|
|
e42fb996dd | ||
|
|
4377518d44 | ||
|
|
a485371f2a | ||
|
|
66e43ea6ea | ||
|
|
7d8c546f58 | ||
|
|
35cbeb7eac | ||
|
|
8347c9b5b9 | ||
|
|
9c43f860ed | ||
|
|
a8c2b88936 | ||
|
|
e5e8c17460 | ||
|
|
b76171ca44 | ||
|
|
9cc446aed7 | ||
|
|
5f5efeb611 | ||
|
|
ff5186651b | ||
|
|
68f124b979 | ||
|
|
e1fe0cd5c5 | ||
|
|
ba29b3a96c | ||
|
|
3320c6df90 | ||
|
|
168aad057d | ||
|
|
156e53dc12 |
|
|
@ -1,82 +0,0 @@
|
||||||
AlignAfterOpenBracket: Align
|
|
||||||
# This option we want but it's frequently broken and causes bad
|
|
||||||
# misalignment. The canary is wheel_click_count_parser, if that works
|
|
||||||
# we can actually enable it.
|
|
||||||
# AlignArrayOfStructures: Left
|
|
||||||
AlignConsecutiveAssignments: false
|
|
||||||
AlignConsecutiveDeclarations: false
|
|
||||||
AlignConsecutiveMacros: true
|
|
||||||
AlignConsecutiveShortCaseStatements:
|
|
||||||
Enabled: true
|
|
||||||
AcrossEmptyLines: false
|
|
||||||
AcrossComments: true
|
|
||||||
AlignCaseColons: false
|
|
||||||
AlignEscapedNewlines: Right
|
|
||||||
AlignOperands: Align
|
|
||||||
AlignTrailingComments: true
|
|
||||||
AllowAllArgumentsOnNextLine: false
|
|
||||||
AllowAllParametersOfDeclarationOnNextLine: false
|
|
||||||
AllowShortBlocksOnASingleLine: false
|
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
|
||||||
AllowShortFunctionsOnASingleLine: false
|
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
|
||||||
AllowShortLoopsOnASingleLine: false
|
|
||||||
AlwaysBreakBeforeMultilineStrings: true
|
|
||||||
BinPackArguments: false
|
|
||||||
BinPackParameters: OnePerLine
|
|
||||||
BraceWrapping:
|
|
||||||
AfterFunction: true
|
|
||||||
BreakAfterReturnType: All
|
|
||||||
BreakBeforeBraces: Custom
|
|
||||||
BreakStringLiterals: false
|
|
||||||
ColumnLimit: 88
|
|
||||||
ContinuationIndentWidth: 8
|
|
||||||
Cpp11BracedListStyle: false
|
|
||||||
IncludeBlocks: Regroup
|
|
||||||
IncludeCategories:
|
|
||||||
- Regex: '^(<|")config\.h(>|")'
|
|
||||||
Priority: 0
|
|
||||||
SortPriority: 0
|
|
||||||
- Regex: '^<.*'
|
|
||||||
Priority: 1
|
|
||||||
SortPriority: 0
|
|
||||||
- Regex: '^"util-.*'
|
|
||||||
Priority: 2
|
|
||||||
SortPriority: 0
|
|
||||||
- Regex: '.*'
|
|
||||||
Priority: 3
|
|
||||||
SortPriority: 0
|
|
||||||
IndentCaseLabels: false
|
|
||||||
IndentGotoLabels: false
|
|
||||||
IndentWidth: 8
|
|
||||||
MaxEmptyLinesToKeep: 1
|
|
||||||
PointerAlignment: Right
|
|
||||||
ReflowComments: true
|
|
||||||
RemoveEmptyLinesInUnwrappedLines: true
|
|
||||||
RemoveParentheses: MultipleParentheses
|
|
||||||
RemoveSemicolon: true
|
|
||||||
SkipMacroDefinitionBody: true
|
|
||||||
SortIncludes: true
|
|
||||||
SpaceAfterCStyleCast: false
|
|
||||||
SpaceAfterLogicalNot: false
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
|
||||||
SpaceBeforeCaseColon: false
|
|
||||||
SpaceBeforeParens: ControlStatementsExceptControlMacros
|
|
||||||
SpacesInContainerLiterals: true
|
|
||||||
SpacesInParens: Custom
|
|
||||||
TabWidth: 8
|
|
||||||
UseTab: ForContinuationAndIndentation
|
|
||||||
|
|
||||||
ForEachMacros:
|
|
||||||
- ARRAY_FOR_EACH
|
|
||||||
- list_for_each
|
|
||||||
- list_for_each_safe
|
|
||||||
- tp_for_each_touch
|
|
||||||
- range_for_each
|
|
||||||
- litest_log_group
|
|
||||||
- litest_with_logcapture
|
|
||||||
- litest_with_parameters
|
|
||||||
- litest_with_event_frame
|
|
||||||
- udev_list_entry_foreach
|
|
||||||
# END_TEST is defined as something that enforces a line break
|
|
||||||
Macros: [ "CASE_RETURN_STRING(s)=case s: return s", "START_TEST(s)=static void s(void)", "END_TEST=enum foo;"]
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
include/**/*
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
# optin.core.unix.Malloc: disabled so we can use __attribute__((cleanup)) without leak complaints
|
|
||||||
# optin.core.EnumCastOutOfRange: disabled because we use a lot of "wrong" enum values for testing
|
|
||||||
# and internally and don't want those values leak into the public API
|
|
||||||
Checks: >
|
|
||||||
-clang-analyzer-unix.Malloc,
|
|
||||||
-clang-analyzer-optin.core.EnumCastOutOfRange
|
|
||||||
WarningsAsErrors: '*'
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
include/*
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
# https://editorconfig.org/
|
|
||||||
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
end_of_line = lf
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
||||||
|
|
||||||
[*.{c,h}]
|
|
||||||
indent_size = 8
|
|
||||||
indent_style = tab
|
|
||||||
|
|
||||||
[*.py]
|
|
||||||
indent_size = 4
|
|
||||||
indent_style = space
|
|
||||||
|
|
||||||
[{meson.build,meson_options.txt}]
|
|
||||||
indent_size = 8
|
|
||||||
indent_style = tab
|
|
||||||
|
|
||||||
[*.sym]
|
|
||||||
indent_size = 8
|
|
||||||
indent_style = tab
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
# This file contains revisions to be ignored by git blame.
|
|
||||||
# These revisions are expected to be formatting-only changes.
|
|
||||||
#
|
|
||||||
# Calling `git blame --ignore-revs-file .git-blame-ignore-revs` will
|
|
||||||
# tell git blame to ignore changes made by these revisions when assigning
|
|
||||||
# assigning blame, as if the change never happened.
|
|
||||||
#
|
|
||||||
# You can enable this as a default for your local repository by running
|
|
||||||
# `git config blame.ignoreRevsFile .git-blame-ignore-revs`
|
|
||||||
# Important: if you do this, then switch to a branch without this file,
|
|
||||||
# `git blame` will fail with an error.
|
|
||||||
#
|
|
||||||
|
|
||||||
# Run clang-format over the code
|
|
||||||
2a1095924b0be60f822bc0ff20d567e209a9db73
|
|
||||||
|
|
||||||
# Add trailing commas to prevent clang-format oddities
|
|
||||||
aebf3cd4915adc576cf055926caa621e098ec32b
|
|
||||||
|
|
||||||
# Fix some inconsistent whitespace.
|
|
||||||
60abf1575560cb8e2220ae48a67e7f74b5dc70dd
|
|
||||||
1683
.gitlab-ci.yml
|
|
@ -1,803 +0,0 @@
|
||||||
# vim: set expandtab shiftwidth=2 tabstop=8 textwidth=0 filetype=yaml:
|
|
||||||
|
|
||||||
{# You're looking at the template here, so you can ignore the below
|
|
||||||
warning. This is the right file to edit #}
|
|
||||||
########################################
|
|
||||||
# #
|
|
||||||
# THIS FILE IS GENERATED, DO NOT EDIT #
|
|
||||||
# #
|
|
||||||
########################################
|
|
||||||
|
|
||||||
# To change the gitlab CI, edit .gitlab-ci/ci.template and/or .gitlab-ci/config.yaml
|
|
||||||
# and run ci-fairy generate-template. For details, see
|
|
||||||
# https://freedesktop.pages.freedesktop.org/ci-templates/ci-fairy.html#templating-gitlab-ci-yml
|
|
||||||
|
|
||||||
# This is a bit complicated for two reasons:
|
|
||||||
# - we really want to run dnf/apt/... only once, updating on the test runner for
|
|
||||||
# each job takes forever. So we create a container image for each distribution
|
|
||||||
# tested, then run the tests on this container image.
|
|
||||||
#
|
|
||||||
# This is handled by the ci-templates, ensuring containers are only rebuilt
|
|
||||||
# when the TAG changes.
|
|
||||||
#
|
|
||||||
# - GitLab only allows one script: set per job but we have a bunch of commands
|
|
||||||
# we need to re-run for each build (meson && ninja && etc). YAML cannot merge
|
|
||||||
# arrays so we're screwed.
|
|
||||||
#
|
|
||||||
# So instead we use a default_build template and override everything with
|
|
||||||
# variables. The only two variables that matter:
|
|
||||||
# MESON_ARGS=-Denable-something=true
|
|
||||||
# NINJA_ARGS=dist ... to run 'ninja -C builddir dist'
|
|
||||||
# Note that you cannot use scripts: in any target if you expect default_build
|
|
||||||
# to work.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# All jobs must follow the naming scheme of
|
|
||||||
# <distribution>:<version>@activity:
|
|
||||||
# e.g. fedora:31@build-default
|
|
||||||
|
|
||||||
.templates_sha: &template_sha c6aeb16f86e32525fa630fb99c66c4f3e62fc3cb
|
|
||||||
|
|
||||||
include:
|
|
||||||
- project: 'freedesktop/ci-templates'
|
|
||||||
ref: *template_sha
|
|
||||||
file:
|
|
||||||
- '/templates/ci-fairy.yml'
|
|
||||||
{% for distro in distributions|sort(attribute="name") %}
|
|
||||||
# {{ distro.name.capitalize() }} container builder template
|
|
||||||
- '/templates/{{distro.name}}.yml'
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
workflow:
|
|
||||||
rules:
|
|
||||||
# do not duplicate pipelines on merge pipelines
|
|
||||||
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
|
|
||||||
when: never
|
|
||||||
# merge pipeline
|
|
||||||
- if: &is-merge-attempt $GITLAB_USER_LOGIN == "marge-bot" && $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
||||||
variables:
|
|
||||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64: priority:high
|
|
||||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM: priority:high-kvm
|
|
||||||
FDO_RUNNER_JOB_PRIORITY_TAG_AARCH64: priority:high-aarch64
|
|
||||||
# post-merge pipeline
|
|
||||||
- if: &is-post-merge $GITLAB_USER_LOGIN == "marge-bot" && $CI_PIPELINE_SOURCE == "push"
|
|
||||||
variables:
|
|
||||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64: priority:high
|
|
||||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM: priority:high-kvm
|
|
||||||
FDO_RUNNER_JOB_PRIORITY_TAG_AARCH64: priority:high-aarch64
|
|
||||||
# Pre-merge pipeline
|
|
||||||
- if: &is-pre-merge $CI_PIPELINE_SOURCE == "merge_request_event"
|
|
||||||
# Push to a branch on a fork
|
|
||||||
- if: $CI_COMMIT_BRANCH
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- sanity check # CI/commit checks
|
|
||||||
- prep # prep work like rebuilding the container images if there is a change
|
|
||||||
- build # for actually building and testing things in a container
|
|
||||||
- test-suite # for running the test suite in a VM
|
|
||||||
- test-suite-no-libwacom # for running the test suite in a VM (libwacom disabled)
|
|
||||||
- valgrind # for running the test suite under valgrind in a VM
|
|
||||||
- distro # distribs test
|
|
||||||
- deploy # trigger wayland's website generation
|
|
||||||
- container_clean # clean up unused container images (scheduled jobs only)
|
|
||||||
|
|
||||||
variables:
|
|
||||||
###############################################################################
|
|
||||||
# This is the list of packages required to build libinput with the default #
|
|
||||||
# configuration. #
|
|
||||||
# #
|
|
||||||
# Run dnf install/apt-get install/.. with the list of packages for your #
|
|
||||||
# distribution #
|
|
||||||
# #
|
|
||||||
# See the documentation here: #
|
|
||||||
# https://wayland.freedesktop.org/libinput/doc/latest/building.html #
|
|
||||||
###############################################################################
|
|
||||||
{% for distro in distributions %}
|
|
||||||
{{"%-17s" | format(distro.name.upper() + '_PACKAGES:')}} '{{ distro.packages|join(' ')}}'
|
|
||||||
{% endfor %}
|
|
||||||
############################ end of package lists #############################
|
|
||||||
|
|
||||||
# these tags should be updated each time the list of packages is updated
|
|
||||||
# changing these will force rebuilding the associated image
|
|
||||||
# Note: these tags have no meaning and are not tied to a particular
|
|
||||||
# libinput version
|
|
||||||
{% for distro in distributions %}
|
|
||||||
{{"%-13s"| format(distro.name.upper() + '_TAG:')}}'{{distro.tag}}'
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
FDO_UPSTREAM_REPO: libinput/libinput
|
|
||||||
|
|
||||||
MESON_BUILDDIR: "build dir"
|
|
||||||
NINJA_ARGS: ''
|
|
||||||
MESON_ARGS: ''
|
|
||||||
MESON_TEST_ARGS: '--no-suite=hardware'
|
|
||||||
|
|
||||||
# udev isn't available/working properly in the containers
|
|
||||||
UDEV_NOT_AVAILABLE: 1
|
|
||||||
GIT_DEPTH: 1
|
|
||||||
|
|
||||||
# Default priority for non-merge pipelines
|
|
||||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64: "" # Empty tags are ignored by gitlab
|
|
||||||
FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM: kvm
|
|
||||||
FDO_RUNNER_JOB_PRIORITY_TAG_AARCH64: aarch64
|
|
||||||
|
|
||||||
.policy:
|
|
||||||
retry:
|
|
||||||
max: 2
|
|
||||||
when:
|
|
||||||
- runner_system_failure
|
|
||||||
- stuck_or_timeout_failure
|
|
||||||
# cancel run when a newer version is pushed to the branch
|
|
||||||
interruptible: true
|
|
||||||
dependencies: []
|
|
||||||
|
|
||||||
.policy-retry-on-failure:
|
|
||||||
retry:
|
|
||||||
max: 1
|
|
||||||
when:
|
|
||||||
- runner_system_failure
|
|
||||||
- stuck_or_timeout_failure
|
|
||||||
# cancel run when a newer version is pushed to the branch
|
|
||||||
interruptible: true
|
|
||||||
dependencies: []
|
|
||||||
|
|
||||||
.default_artifacts:
|
|
||||||
artifacts:
|
|
||||||
name: "meson-logs-$CI_JOB_NAME"
|
|
||||||
when: always
|
|
||||||
expire_in: 1 week
|
|
||||||
paths:
|
|
||||||
- $MESON_BUILDDIR/meson-logs
|
|
||||||
- $MESON_BUILDDIR/valgrind.*.log
|
|
||||||
reports:
|
|
||||||
junit: $MESON_BUILDDIR/*junit*.xml
|
|
||||||
|
|
||||||
.fdo-runner-tags:
|
|
||||||
tags:
|
|
||||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################
|
|
||||||
# #
|
|
||||||
# sanity check stage #
|
|
||||||
# #
|
|
||||||
#################################################################
|
|
||||||
|
|
||||||
fail-if-fork-is-not-public:
|
|
||||||
extends:
|
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: sanity check
|
|
||||||
script:
|
|
||||||
- |
|
|
||||||
if [ $CI_PROJECT_VISIBILITY != "public" ]; then
|
|
||||||
echo "*************************************************************************************"
|
|
||||||
echo "Project visibility must be set to 'public'"
|
|
||||||
echo "Change this in $CI_PROJECT_URL/edit under 'Visibility, project features, permissions'"
|
|
||||||
echo "*************************************************************************************"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
except:
|
|
||||||
- main@libinput/libinput
|
|
||||||
|
|
||||||
# Re-generate the CI script and make sure it's the one currently checked in
|
|
||||||
# If this job fails, re-generate the gitlab-ci.yml script, see
|
|
||||||
# $SRCDIR/.gitlab-ci/generate-gitlab-ci.py
|
|
||||||
#
|
|
||||||
check-ci-script:
|
|
||||||
extends:
|
|
||||||
- .fdo.ci-fairy
|
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: sanity check
|
|
||||||
script:
|
|
||||||
- ci-fairy generate-template --verify && exit 0 || true
|
|
||||||
- >
|
|
||||||
printf "%s\n" \
|
|
||||||
"Committed gitlab-ci.yml differs from generated gitlab-ci.yml. Please verify" \
|
|
||||||
"https://wayland.freedesktop.org/libinput/doc/latest/contributing.html"
|
|
||||||
- exit 1
|
|
||||||
|
|
||||||
#
|
|
||||||
# Verify that commit messages are as expected, etc.
|
|
||||||
#
|
|
||||||
|
|
||||||
check-commit:
|
|
||||||
extends:
|
|
||||||
- .fdo.ci-fairy
|
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: sanity check
|
|
||||||
script:
|
|
||||||
- ci-fairy -vv check-commits --junit-xml=results.xml && exit 0 || true
|
|
||||||
- >
|
|
||||||
printf "%s\n" \
|
|
||||||
"Error checking commit format. Please verify" \
|
|
||||||
"https://wayland.freedesktop.org/libinput/doc/latest/contributing.html"
|
|
||||||
- exit 1
|
|
||||||
except:
|
|
||||||
- main@libinput/libinput
|
|
||||||
variables:
|
|
||||||
GIT_DEPTH: 100
|
|
||||||
artifacts:
|
|
||||||
reports:
|
|
||||||
junit: results.xml
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Check for trailing whitespaces
|
|
||||||
#
|
|
||||||
|
|
||||||
check-whitespace:
|
|
||||||
extends:
|
|
||||||
- .fdo.ci-fairy
|
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: sanity check
|
|
||||||
script:
|
|
||||||
- .gitlab-ci/whitespace-check.py $(git ls-files)
|
|
||||||
|
|
||||||
#
|
|
||||||
# pre-commit hooks
|
|
||||||
#
|
|
||||||
|
|
||||||
pre-commit-hooks:
|
|
||||||
extends:
|
|
||||||
- .fdo.ci-fairy
|
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: sanity check
|
|
||||||
script:
|
|
||||||
- python3 -m venv venv
|
|
||||||
- source venv/bin/activate
|
|
||||||
- pip3 install pre-commit
|
|
||||||
- pre-commit run --all-files
|
|
||||||
- git diff --exit-code || (echo "ERROR - Code style errors found, please fix" && false)
|
|
||||||
|
|
||||||
#################################################################
|
|
||||||
# #
|
|
||||||
# prep stage #
|
|
||||||
# #
|
|
||||||
#################################################################
|
|
||||||
|
|
||||||
{% for distro in distributions %}
|
|
||||||
{% for version in distro.versions %}
|
|
||||||
{{distro.name}}:{{version}}@container-prep:
|
|
||||||
extends:
|
|
||||||
{% if distro.qemu_based %}
|
|
||||||
- .fdo.qemu-build@{{distro.name}}
|
|
||||||
{% else %}
|
|
||||||
- .fdo.container-build@{{distro.name}}
|
|
||||||
{% endif %}
|
|
||||||
- .policy
|
|
||||||
- .fdo-runner-tags
|
|
||||||
{% if distro.qemu_based %}
|
|
||||||
tags:
|
|
||||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM
|
|
||||||
{% endif %}
|
|
||||||
stage: prep
|
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
|
||||||
FDO_DISTRIBUTION_PACKAGES: ${{distro.name.upper()}}_PACKAGES
|
|
||||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
|
|
||||||
#################################################################
|
|
||||||
# #
|
|
||||||
# container clean stage #
|
|
||||||
# run during the clean stage #
|
|
||||||
# #
|
|
||||||
#################################################################
|
|
||||||
|
|
||||||
#
|
|
||||||
# This stage will look for the container images we currently have in
|
|
||||||
# the registry and will remove any that are not tagged with the provided
|
|
||||||
# $container_image:$tag
|
|
||||||
#
|
|
||||||
.container-clean:
|
|
||||||
extends:
|
|
||||||
- .policy
|
|
||||||
- .fdo.ci-fairy
|
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: container_clean
|
|
||||||
script:
|
|
||||||
# Go to your Profile, Settings, Access Tokens
|
|
||||||
# Create a personal token with 'api' scope, copy the value.
|
|
||||||
# Go to CI/CD, Schedules, schedule a new monthly job (or edit the existing one)
|
|
||||||
# Define a variable of type File named AUTHFILE. Content is that token
|
|
||||||
# value.
|
|
||||||
- ci-fairy -v --authfile $AUTHFILE delete-image
|
|
||||||
--repository $FDO_DISTRIBUTION_NAME/$FDO_DISTRIBUTION_VERSION
|
|
||||||
--exclude-tag $FDO_DISTRIBUTION_TAG
|
|
||||||
allow_failure: true
|
|
||||||
only:
|
|
||||||
- schedules
|
|
||||||
|
|
||||||
{% for distro in distributions %}
|
|
||||||
{% for version in distro.versions %}
|
|
||||||
{{distro.name}}:{{version}}@container-clean:
|
|
||||||
extends:
|
|
||||||
- .policy
|
|
||||||
- .container-clean
|
|
||||||
variables:
|
|
||||||
GIT_STRATEGY: none
|
|
||||||
CURRENT_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/{{distro.name}}/$FDO_DISTRIBUTION_VERSION:$FDO_DISTRIBUTION_TAG
|
|
||||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
|
||||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
#################################################################
|
|
||||||
# #
|
|
||||||
# build stage #
|
|
||||||
# #
|
|
||||||
#################################################################
|
|
||||||
|
|
||||||
.build@template:
|
|
||||||
extends:
|
|
||||||
- .policy
|
|
||||||
- .default_artifacts
|
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: build
|
|
||||||
script:
|
|
||||||
- .gitlab-ci/meson-build.sh
|
|
||||||
|
|
||||||
|
|
||||||
# Run meson and meson test in the container image through qemu
|
|
||||||
.build-in-vng@template:
|
|
||||||
extends:
|
|
||||||
- .policy
|
|
||||||
- .default_artifacts
|
|
||||||
tags:
|
|
||||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM
|
|
||||||
variables:
|
|
||||||
MESON_BUILDDIR: build_dir
|
|
||||||
VNG_KERNEL: {{ vng.kernel }}
|
|
||||||
script:
|
|
||||||
# first build in the host container
|
|
||||||
- .gitlab-ci/meson-build.sh --skip-test
|
|
||||||
|
|
||||||
- mkdir -p $MESON_BUILDDIR
|
|
||||||
- curl -LO $VNG_KERNEL
|
|
||||||
|
|
||||||
- export -p > .vngenv
|
|
||||||
|
|
||||||
# runs the test suite only
|
|
||||||
- |
|
|
||||||
vng --run ./bzImage \
|
|
||||||
--user root \
|
|
||||||
--overlay-rwdir=$HOME \
|
|
||||||
--append HOME=$HOME \
|
|
||||||
--overlay-rwdir=$(pwd) \
|
|
||||||
--rwdir=$MESON_BUILDDIR \
|
|
||||||
--exec "source $PWD/.vngenv; rm $PWD/.vngenv; .gitlab-ci/meson-build.sh --skip-setup --skip-build --run-test"
|
|
||||||
|
|
||||||
#
|
|
||||||
# Fedora
|
|
||||||
#
|
|
||||||
|
|
||||||
.check_tainted: &check_tainted |
|
|
||||||
# make sure the kernel is not tainted
|
|
||||||
if [[ "$(ssh localhost -p 5555 cat /proc/sys/kernel/tainted)" -gt 0 ]];
|
|
||||||
then
|
|
||||||
echo tainted kernel ;
|
|
||||||
exit 1 ;
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Run meson and meson test in the qemu image
|
|
||||||
.build-in-qemu@template:
|
|
||||||
extends:
|
|
||||||
- .policy
|
|
||||||
tags:
|
|
||||||
- $FDO_RUNNER_JOB_PRIORITY_TAG_X86_64_KVM
|
|
||||||
variables:
|
|
||||||
MESON_BUILDDIR: build_dir
|
|
||||||
script:
|
|
||||||
# start our vm, no args required
|
|
||||||
- /app/vmctl start || (echo "Error - Failed to start the VM." && exit 1)
|
|
||||||
|
|
||||||
- *check_tainted
|
|
||||||
|
|
||||||
- "scp -r $PWD vm:"
|
|
||||||
- echo "CI_JOB_ID=\"$CI_JOB_ID\"" > sshenv
|
|
||||||
- echo "CI_JOB_NAME=\"$CI_JOB_NAME\"" >> sshenv
|
|
||||||
- echo "MESON_ARGS=\"$MESON_ARGS\"" >> sshenv
|
|
||||||
- echo "MESON_BUILDDIR=\"$MESON_BUILDDIR\"" >> sshenv
|
|
||||||
- echo "MESON_TEST_ARGS=\"$MESON_TEST_ARGS\"" >> sshenv
|
|
||||||
- echo "NINJA_ARGS=\"$NINJA_ARGS\"" >> sshenv
|
|
||||||
- "scp sshenv vm:~/$CI_PROJECT_NAME/.meson_environment"
|
|
||||||
- /app/vmctl exec "cd $CI_PROJECT_NAME ; .gitlab-ci/meson-build.sh" && touch .success || true
|
|
||||||
# no matter the results of the tests, we want to fetch the logs
|
|
||||||
- scp -r vm:$CI_PROJECT_NAME/$MESON_BUILDDIR .
|
|
||||||
|
|
||||||
- *check_tainted
|
|
||||||
|
|
||||||
- /app/vmctl stop
|
|
||||||
|
|
||||||
- if [[ ! -e .success ]] ;
|
|
||||||
then
|
|
||||||
exit 1 ;
|
|
||||||
fi
|
|
||||||
artifacts:
|
|
||||||
name: "qemu-meson-logs-$CI_JOB_NAME"
|
|
||||||
when: always
|
|
||||||
expire_in: 1 week
|
|
||||||
paths:
|
|
||||||
- $MESON_BUILDDIR/meson-logs
|
|
||||||
- console.out
|
|
||||||
reports:
|
|
||||||
junit: $MESON_BUILDDIR/*junit*.xml
|
|
||||||
|
|
||||||
|
|
||||||
# Run in a test suite. Special variables:
|
|
||||||
# - SUITES: the meson test suites to run, or
|
|
||||||
# - SUITE_NAMES: all elements will be expanded to libinput-test-suite-$value
|
|
||||||
# Set one or the other, not both.
|
|
||||||
.test-suite-vm:
|
|
||||||
extends:
|
|
||||||
- .build-in-vng@template
|
|
||||||
stage: test-suite
|
|
||||||
variables:
|
|
||||||
# remove the global --no-suite=hardware
|
|
||||||
MESON_TEST_ARGS: ''
|
|
||||||
LITEST_JOBS: 4
|
|
||||||
before_script:
|
|
||||||
- if ! [[ -z $SUITE_NAMES ]]; then SUITES=$(echo $SUITE_NAMES | sed 's/\([^ ]*\)/libinput-test-suite-\1/g'); fi
|
|
||||||
- echo "Testing $SUITES"
|
|
||||||
- export MESON_TEST_ARGS="$MESON_TEST_ARGS $SUITES"
|
|
||||||
|
|
||||||
|
|
||||||
{# qemu tests are only done for the latest version of any distribution #}
|
|
||||||
{% for distro in distributions if distro.use_for_qemu_tests %}
|
|
||||||
{% set version = "{}".format(distro.versions|last()) %}
|
|
||||||
.{{distro.name}}:{{version}}@test-suite-vm:
|
|
||||||
extends:
|
|
||||||
- .fdo.distribution-image@{{distro.name}}
|
|
||||||
- .test-suite-vm
|
|
||||||
variables:
|
|
||||||
FDO_DISTRIBUTION_VERSION: {{version}}
|
|
||||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
|
||||||
needs:
|
|
||||||
- "{{distro.name}}:{{version}}@container-prep"
|
|
||||||
|
|
||||||
|
|
||||||
{% for suite in test_suites %}
|
|
||||||
vm-{{suite.name}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}:{{version}}@test-suite-vm
|
|
||||||
variables:
|
|
||||||
SUITE_NAMES: '{{suite.suites|join(' ')}}'
|
|
||||||
|
|
||||||
vm-{{suite.name}}-no-libwacom:
|
|
||||||
extends:
|
|
||||||
- vm-{{suite.name}}
|
|
||||||
stage: test-suite-no-libwacom
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: '-Dlibwacom=false'
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% for suite in test_suites %}
|
|
||||||
vm-valgrind-{{suite.name}}:
|
|
||||||
stage: valgrind
|
|
||||||
extends:
|
|
||||||
- vm-{{suite.name}}
|
|
||||||
- .policy-retry-on-failure
|
|
||||||
variables:
|
|
||||||
MESON_TEST_ARGS: '--setup=valgrind'
|
|
||||||
LITEST_JOBS: 0
|
|
||||||
retry:
|
|
||||||
max: 2
|
|
||||||
rules:
|
|
||||||
- if: $GITLAB_USER_LOGIN != "marge-bot"
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% endfor %}{# for if distro.use_for_qemu_tests #}
|
|
||||||
|
|
||||||
{% for distro in distributions if distro.use_for_custom_build_tests %}
|
|
||||||
{% set version = "{}".format(distro.versions|last()) %}
|
|
||||||
.{{distro.name}}-build@template:
|
|
||||||
extends:
|
|
||||||
- .fdo.distribution-image@{{distro.name}}
|
|
||||||
- .build@template
|
|
||||||
variables:
|
|
||||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
|
||||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
|
||||||
needs:
|
|
||||||
- "{{distro.name}}:{{version}}@container-prep"
|
|
||||||
|
|
||||||
default-build-release@{{distro.name}}:{{version}}:
|
|
||||||
stage: distro
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: "-Dbuildtype=release"
|
|
||||||
CFLAGS: "-Werror"
|
|
||||||
|
|
||||||
clang-tidy@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
NINJA_ARGS: ''
|
|
||||||
MESON_TEST_ARGS: ''
|
|
||||||
CC: 'clang'
|
|
||||||
script:
|
|
||||||
- .gitlab-ci/meson-build.sh
|
|
||||||
- ninja -C "$MESON_BUILDDIR" clang-tidy
|
|
||||||
|
|
||||||
# Below jobs are build option combinations. We only
|
|
||||||
# run them on one image, they shouldn't fail on one distro
|
|
||||||
# when they succeed on another.
|
|
||||||
|
|
||||||
build-no-libwacom@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: "-Dlibwacom=false"
|
|
||||||
|
|
||||||
build-no-libwacom-nodeps@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: "-Dlibwacom=false"
|
|
||||||
before_script:
|
|
||||||
- dnf remove -y libwacom libwacom-devel
|
|
||||||
|
|
||||||
build-no-mtdev@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: "-Dmtdev=false"
|
|
||||||
|
|
||||||
build-no-mtdev-nodeps@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: "-Dmtdev=false"
|
|
||||||
before_script:
|
|
||||||
- dnf remove -y mtdev mtdev-devel
|
|
||||||
|
|
||||||
build-no-lua@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: "-Dlua-plugins=disabled"
|
|
||||||
|
|
||||||
build-no-lua-nodeps@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: "-Dlua-plugins=disabled"
|
|
||||||
before_script:
|
|
||||||
- dnf remove -y lua lua-devel
|
|
||||||
|
|
||||||
build-docs@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: "-Ddocumentation=true"
|
|
||||||
|
|
||||||
build-no-docs-nodeps@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: "-Ddocumentation=false"
|
|
||||||
before_script:
|
|
||||||
- dnf remove -y doxygen graphviz
|
|
||||||
|
|
||||||
build-no-debuggui@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: "-Ddebug-gui=false"
|
|
||||||
|
|
||||||
build-no-debuggui-nodeps@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: "-Ddebug-gui=false"
|
|
||||||
before_script:
|
|
||||||
- dnf remove -y gtk3-devel gtk4-devel
|
|
||||||
|
|
||||||
build-no-tests@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: "-Dtests=false"
|
|
||||||
|
|
||||||
build-no-tests-nodeps@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: "-Dtests=false"
|
|
||||||
before_script:
|
|
||||||
- dnf remove -y check-devel
|
|
||||||
|
|
||||||
valgrind@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
variables:
|
|
||||||
MESON_TEST_ARGS: '--suite=valgrind --no-suite=hardware --setup=valgrind'
|
|
||||||
|
|
||||||
# Python checks, only run on Fedora
|
|
||||||
|
|
||||||
usr-bin-env-python@{{distro.name}}:{{version}}:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
script:
|
|
||||||
- |
|
|
||||||
if git grep -l '^#!/usr/bin/python'; then
|
|
||||||
echo "Use '/usr/bin/env python3' in the above files";
|
|
||||||
/bin/false
|
|
||||||
fi
|
|
||||||
|
|
||||||
# A job to check we're actually running all test suites in the CI
|
|
||||||
check-test-suites:
|
|
||||||
extends:
|
|
||||||
- .{{distro.name}}-build@template
|
|
||||||
script:
|
|
||||||
- meson setup builddir
|
|
||||||
- meson introspect builddir --test | jq -r '.[].name' | grep 'libinput-test-suite' | sort > meson-testsuites
|
|
||||||
- |
|
|
||||||
cat <<EOF > ci-testsuites ;
|
|
||||||
{% for suite in test_suites %}
|
|
||||||
{% for name in suite.suites %}
|
|
||||||
libinput-test-suite-{{name}}
|
|
||||||
{% endfor %}
|
|
||||||
{% endfor %}
|
|
||||||
EOF
|
|
||||||
- sort -o ci-testsuites ci-testsuites
|
|
||||||
- diff -u8 -w ci-testsuites meson-testsuites || (echo "Some test suites are not run in the CI" && false)
|
|
||||||
only:
|
|
||||||
changes:
|
|
||||||
- "meson.build"
|
|
||||||
- ".gitlab-ci.yml"
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
#
|
|
||||||
# coverity run
|
|
||||||
#
|
|
||||||
# This requires the COVERITY_SCAN_TOKEN. Log into scan.coverity.com and get
|
|
||||||
# the token from the respective project settings page.
|
|
||||||
# Schedule a pipeline and set a variable COVERITY_SCAN_TOKEN with the token value.
|
|
||||||
# https://gitlab.freedesktop.org/$CI_PROJECT_PATH/-/pipeline_schedules
|
|
||||||
# Email from coverity will be sent to the GITLAB_USER_EMAIL that scheduled the
|
|
||||||
# job.
|
|
||||||
#
|
|
||||||
# Coverity ratelimits submissions and the coverity tools download is about
|
|
||||||
# 700M, do not run this too often.
|
|
||||||
#
|
|
||||||
coverity:
|
|
||||||
extends:
|
|
||||||
- .fdo.distribution-image@debian
|
|
||||||
- .policy
|
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: build
|
|
||||||
variables:
|
|
||||||
FDO_DISTRIBUTION_VERSION: 'stable'
|
|
||||||
FDO_DISTRIBUTION_TAG: $DEBIAN_TAG
|
|
||||||
# so git-describe works, or should work
|
|
||||||
GIT_DEPTH: 200
|
|
||||||
only:
|
|
||||||
variables:
|
|
||||||
- $COVERITY_SCAN_TOKEN
|
|
||||||
script:
|
|
||||||
- curl https://scan.coverity.com/download/linux64
|
|
||||||
-o /tmp/cov-analysis-linux64.tgz
|
|
||||||
--form project=$CI_PROJECT_NAME
|
|
||||||
--form token=$COVERITY_SCAN_TOKEN
|
|
||||||
- tar xfz /tmp/cov-analysis-linux64.tgz
|
|
||||||
# coverity has special build options in meson, make sure we enable those
|
|
||||||
- meson coverity-build -Ddocumentation=false -Dcoverity=true
|
|
||||||
- cov-analysis-linux64-*/bin/cov-build --dir cov-int ninja -C coverity-build
|
|
||||||
- tar cfz cov-int.tar.gz cov-int
|
|
||||||
- curl https://scan.coverity.com/builds?project=$CI_PROJECT_NAME
|
|
||||||
--form token=$COVERITY_SCAN_TOKEN --form email=$GITLAB_USER_EMAIL
|
|
||||||
--form file=@cov-int.tar.gz --form version="$(git describe --tags)"
|
|
||||||
--form description="$(git describe --tags) / $CI_COMMIT_TITLE / $CI_COMMIT_REF_NAME:$CI_PIPELINE_ID"
|
|
||||||
artifacts:
|
|
||||||
name: "coverity-submit-data"
|
|
||||||
when: always
|
|
||||||
expire_in: 1 week
|
|
||||||
paths:
|
|
||||||
- cov-int.tar.gz
|
|
||||||
needs:
|
|
||||||
- "debian:stable@container-prep"
|
|
||||||
|
|
||||||
#################################################################
|
|
||||||
# #
|
|
||||||
# distro stage #
|
|
||||||
# #
|
|
||||||
#################################################################
|
|
||||||
|
|
||||||
{% for distro in distributions %}
|
|
||||||
{% if not distro.qemu_based %}
|
|
||||||
{% for version in distro.versions %}
|
|
||||||
{{distro.name}}:{{version}}@default-build:
|
|
||||||
stage: distro
|
|
||||||
extends:
|
|
||||||
- .build@template
|
|
||||||
- .fdo.distribution-image@{{distro.name}}
|
|
||||||
variables:
|
|
||||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
|
||||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
|
||||||
{# Where we have extra_variables defined, add them to the list #}
|
|
||||||
{% if distro.build is defined and distro.build.extra_variables is defined %}
|
|
||||||
{% for var in distro.build.extra_variables %}
|
|
||||||
{{var}}
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
needs:
|
|
||||||
- "{{distro.name}}:{{version}}@container-prep"
|
|
||||||
|
|
||||||
|
|
||||||
{% endfor %}
|
|
||||||
{% else %}
|
|
||||||
{% set version = "{}".format(distro.versions|last()) %}
|
|
||||||
{{distro.name}}:{{version}}@default-build:
|
|
||||||
stage: distro
|
|
||||||
extends:
|
|
||||||
- .build-in-qemu@template
|
|
||||||
- .fdo.distribution-image@{{distro.name}}
|
|
||||||
variables:
|
|
||||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
|
||||||
FDO_DISTRIBUTION_TAG: ${{distro.name.upper()}}_TAG
|
|
||||||
{# Where we have extra_variables defined, add them to the list #}
|
|
||||||
{% if distro.build is defined and distro.build.extra_variables is defined %}
|
|
||||||
{% for var in distro.build.extra_variables %}
|
|
||||||
{{var}}
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
needs:
|
|
||||||
- "{{distro.name}}:{{version}}@container-prep"
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
#################################################################
|
|
||||||
# #
|
|
||||||
# deploy stage #
|
|
||||||
# #
|
|
||||||
#################################################################
|
|
||||||
|
|
||||||
{% for distro in distributions if distro.name == "fedora" %}
|
|
||||||
{% set version = "{}".format(distro.versions|last()) %}
|
|
||||||
build rpm:
|
|
||||||
extends:
|
|
||||||
- .fdo.distribution-image@fedora
|
|
||||||
- .policy
|
|
||||||
- .fdo-runner-tags
|
|
||||||
stage: deploy
|
|
||||||
variables:
|
|
||||||
FDO_DISTRIBUTION_VERSION: '{{version}}'
|
|
||||||
FDO_DISTRIBUTION_TAG: $FEDORA_TAG
|
|
||||||
needs:
|
|
||||||
- "fedora:{{version}}@container-prep"
|
|
||||||
script:
|
|
||||||
- meson "$MESON_BUILDDIR"
|
|
||||||
- VERSION=$(meson introspect "$MESON_BUILDDIR" --projectinfo | jq -r .version)
|
|
||||||
- sed -e "s/@PIPELINEID@/${CI_PIPELINE_ID}/"
|
|
||||||
-e "s/@GITVERSION@/${CI_COMMIT_SHA}/"
|
|
||||||
-e "s/@VERSION@/${VERSION}/" .gitlab-ci/libinput.spec.in > libinput.spec
|
|
||||||
- git config --local user.name 'gitlab CI'
|
|
||||||
- git config --local user.email 'noreply@nowhere'
|
|
||||||
- git add libinput.spec && git commit -m 'Add libinput.spec for build testing' libinput.spec
|
|
||||||
- cd "$MESON_BUILDDIR"
|
|
||||||
- meson dist --no-test
|
|
||||||
- rpmbuild -ta meson-dist/libinput*.tar.xz
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
|
|
||||||
wayland-web:
|
|
||||||
stage: deploy
|
|
||||||
trigger: wayland/wayland.freedesktop.org
|
|
||||||
variables:
|
|
||||||
MESON_ARGS: '-Ddocumentation=true -Ddebug-gui=false -Dlibwacom=false -Dtests=false'
|
|
||||||
MESON_BUILDDIR: 'builddir'
|
|
||||||
rules:
|
|
||||||
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
|
||||||
when: never
|
|
||||||
- if: '$CI_COMMIT_BRANCH == "main" && $GITLAB_USER_LOGIN != "marge-bot" && $CI_PROJECT_PATH == $FDO_UPSTREAM_REPO'
|
|
||||||
when: on_success
|
|
||||||
- when: never
|
|
||||||
|
|
@ -1,217 +0,0 @@
|
||||||
# This file contains the configuration for the gitlab ci.
|
|
||||||
# See the .gitlab-ci/generate-gitlab-ci.py file for more info
|
|
||||||
#
|
|
||||||
|
|
||||||
# We're happy to rebuild all containers when one changes.
|
|
||||||
.default_tag: &default_tag '2026-01-09.0'
|
|
||||||
|
|
||||||
distributions:
|
|
||||||
- name: fedora
|
|
||||||
tag: *default_tag
|
|
||||||
versions:
|
|
||||||
- '42'
|
|
||||||
- '43'
|
|
||||||
use_for_custom_build_tests: true
|
|
||||||
use_for_qemu_tests: true
|
|
||||||
packages:
|
|
||||||
- git-core
|
|
||||||
- gcc
|
|
||||||
- gcc-c++
|
|
||||||
- pkgconf-pkg-config
|
|
||||||
- meson
|
|
||||||
- check-devel
|
|
||||||
- libudev-devel
|
|
||||||
- libevdev-devel
|
|
||||||
- doxygen
|
|
||||||
- graphviz
|
|
||||||
- python3-sphinx
|
|
||||||
- python3-recommonmark
|
|
||||||
- python3-sphinx_rtd_theme
|
|
||||||
- python3-pytest-xdist
|
|
||||||
- libwacom-devel
|
|
||||||
- cairo-devel
|
|
||||||
- gtk4-devel
|
|
||||||
- glib2-devel
|
|
||||||
- mtdev-devel
|
|
||||||
- diffutils
|
|
||||||
- wayland-protocols-devel
|
|
||||||
- black # for the Python black job, optional
|
|
||||||
- clang # for the clang-tidy build, optional
|
|
||||||
- clang-tools-extra # for clang-tidy, optional
|
|
||||||
- jq # for the test suite check job, optional
|
|
||||||
- rpmdevtools # for the rpm build job, optional
|
|
||||||
- valgrind # for the valgrind run, optional
|
|
||||||
# below packages are for the qemu runs, so optional
|
|
||||||
- systemd-udev # for the qemu run
|
|
||||||
- qemu-img
|
|
||||||
- qemu-system-x86-core
|
|
||||||
- qemu-system-aarch64-core
|
|
||||||
- jq
|
|
||||||
- python3-click
|
|
||||||
- python3-rich
|
|
||||||
- virtme-ng
|
|
||||||
- lua-devel
|
|
||||||
- name: debian
|
|
||||||
tag: *default_tag
|
|
||||||
versions:
|
|
||||||
- 'stable'
|
|
||||||
packages:
|
|
||||||
- git
|
|
||||||
- gcc
|
|
||||||
- g++
|
|
||||||
- pkg-config
|
|
||||||
- meson
|
|
||||||
- check
|
|
||||||
- libudev-dev
|
|
||||||
- libevdev-dev
|
|
||||||
- doxygen
|
|
||||||
- graphviz
|
|
||||||
- python3-sphinx
|
|
||||||
- python3-recommonmark
|
|
||||||
- python3-sphinx-rtd-theme
|
|
||||||
- python3-pytest-xdist
|
|
||||||
- libwacom-dev
|
|
||||||
- libcairo2-dev
|
|
||||||
- libgtk-3-dev
|
|
||||||
- libglib2.0-dev
|
|
||||||
- libmtdev-dev
|
|
||||||
- curl # for the coverity job
|
|
||||||
- lua5.4-dev
|
|
||||||
- name: ubuntu
|
|
||||||
tag: *default_tag
|
|
||||||
versions:
|
|
||||||
- '25.10'
|
|
||||||
packages:
|
|
||||||
- git
|
|
||||||
- gcc
|
|
||||||
- g++
|
|
||||||
- pkg-config
|
|
||||||
- meson
|
|
||||||
- check
|
|
||||||
- libudev-dev
|
|
||||||
- libevdev-dev
|
|
||||||
- doxygen
|
|
||||||
- graphviz
|
|
||||||
- python3-sphinx
|
|
||||||
- python3-recommonmark
|
|
||||||
- python3-sphinx-rtd-theme
|
|
||||||
- python3-pytest-xdist
|
|
||||||
- libwacom-dev
|
|
||||||
- libcairo2-dev
|
|
||||||
- libgtk-3-dev
|
|
||||||
- libglib2.0-dev
|
|
||||||
- libmtdev-dev
|
|
||||||
- lua5.4-dev
|
|
||||||
- name: arch
|
|
||||||
tag: *default_tag
|
|
||||||
versions:
|
|
||||||
- 'rolling'
|
|
||||||
packages:
|
|
||||||
- git
|
|
||||||
- gcc
|
|
||||||
- pkgconfig
|
|
||||||
- meson
|
|
||||||
- check
|
|
||||||
- libsystemd
|
|
||||||
- libevdev
|
|
||||||
- python-pytest-xdist
|
|
||||||
- libwacom
|
|
||||||
- gtk4
|
|
||||||
- mtdev
|
|
||||||
- diffutils
|
|
||||||
- lua
|
|
||||||
build:
|
|
||||||
extra_variables:
|
|
||||||
- "MESON_ARGS: '-Ddocumentation=false'" # python-recommonmark is no longer in the repos
|
|
||||||
- name: alpine
|
|
||||||
tag: *default_tag
|
|
||||||
versions:
|
|
||||||
- 'latest'
|
|
||||||
packages:
|
|
||||||
- git
|
|
||||||
- gcc build-base
|
|
||||||
- pkgconfig
|
|
||||||
- meson
|
|
||||||
- check-dev
|
|
||||||
- eudev-dev
|
|
||||||
- libevdev-dev
|
|
||||||
- libwacom-dev
|
|
||||||
- cairo-dev
|
|
||||||
- gtk4.0-dev
|
|
||||||
- mtdev-dev
|
|
||||||
- bash
|
|
||||||
- lua5.4-dev
|
|
||||||
build:
|
|
||||||
extra_variables:
|
|
||||||
- "MESON_ARGS: '-Ddocumentation=false' # alpine does not have python-recommonmark"
|
|
||||||
# We don't run the tests on alpine. The litest-selftest fails
|
|
||||||
# for any tcase_add_exit_test/tcase_add_test_raise_signal
|
|
||||||
# but someone more invested in musl will have to figure that out.
|
|
||||||
- "MESON_TEST_ARGS: '' # litest-selftest fails on musl"
|
|
||||||
|
|
||||||
test_suites:
|
|
||||||
- name: touchpad
|
|
||||||
suites:
|
|
||||||
- touchpad
|
|
||||||
- name: touchpad_palm
|
|
||||||
suites:
|
|
||||||
- touchpad_palm
|
|
||||||
- name: touchpad_dwt
|
|
||||||
suites:
|
|
||||||
- touchpad_dwt
|
|
||||||
- name: tap
|
|
||||||
suites:
|
|
||||||
- touchpad_tap
|
|
||||||
- name: tap-drag
|
|
||||||
suites:
|
|
||||||
- touchpad_tap_drag
|
|
||||||
- name: tap-palm
|
|
||||||
suites:
|
|
||||||
- touchpad_tap_palm
|
|
||||||
- name: touchpad-buttons
|
|
||||||
suites:
|
|
||||||
- touchpad_buttons
|
|
||||||
- name: tablet
|
|
||||||
suites:
|
|
||||||
- tablet
|
|
||||||
- name: tablet_left_handed
|
|
||||||
suites:
|
|
||||||
- tablet_left_handed
|
|
||||||
- name: tablet_proximity_tip
|
|
||||||
suites:
|
|
||||||
- tablet_proximity
|
|
||||||
- tablet_tip
|
|
||||||
- name: tablet_eraser
|
|
||||||
suites:
|
|
||||||
- tablet_eraser
|
|
||||||
- name: gestures
|
|
||||||
suites:
|
|
||||||
- gestures
|
|
||||||
- name: backends
|
|
||||||
suites:
|
|
||||||
- path
|
|
||||||
- udev
|
|
||||||
- name: misc
|
|
||||||
suites:
|
|
||||||
- log
|
|
||||||
- misc
|
|
||||||
- quirks
|
|
||||||
- device
|
|
||||||
- name: other devices
|
|
||||||
suites:
|
|
||||||
- keyboard
|
|
||||||
- pad
|
|
||||||
- switch
|
|
||||||
- trackball
|
|
||||||
- trackpoint
|
|
||||||
- totem
|
|
||||||
- touch
|
|
||||||
- name: pointer
|
|
||||||
suites:
|
|
||||||
- pointer
|
|
||||||
- name: lua
|
|
||||||
suites:
|
|
||||||
- lua
|
|
||||||
|
|
||||||
vng:
|
|
||||||
kernel: https://gitlab.freedesktop.org/api/v4/projects/libevdev%2Fhid-tools/packages/generic/kernel-x86_64/v6.14/bzImage
|
|
||||||
|
|
@ -1,149 +0,0 @@
|
||||||
# This specfile should not be used outside the CI
|
|
||||||
# Its main purpose is to sound alarm if files disappear or are added that
|
|
||||||
# weren't intended.
|
|
||||||
|
|
||||||
%global udevdir %(pkg-config --variable=udevdir udev)
|
|
||||||
|
|
||||||
%global pipelineid @PIPELINEID@
|
|
||||||
%global gitversion @GITVERSION@
|
|
||||||
|
|
||||||
Name: libinput
|
|
||||||
Version: @VERSION@
|
|
||||||
Release: %{pipelineid}git%{gitversion}%{?dist}
|
|
||||||
Summary: Input device library
|
|
||||||
|
|
||||||
License: MIT
|
|
||||||
URL: http://www.freedesktop.org/wiki/Software/libinput/
|
|
||||||
Source0: %{name}-%{version}.tar.xz
|
|
||||||
|
|
||||||
# No BuildRequires, we rely on the container setup to have
|
|
||||||
# all the requires installed
|
|
||||||
|
|
||||||
%description
|
|
||||||
libinput is a library that handles input devices for display servers and other
|
|
||||||
applications that need to directly deal with input devices.
|
|
||||||
|
|
||||||
It provides device detection, device handling, input device event processing
|
|
||||||
and abstraction so minimize the amount of custom input code the user of
|
|
||||||
libinput need to provide the common set of functionality that users expect.
|
|
||||||
|
|
||||||
|
|
||||||
%package devel
|
|
||||||
Summary: Development files for %{name}
|
|
||||||
Requires: %{name}%{?_isa} = %{version}-%{release}
|
|
||||||
|
|
||||||
%description devel
|
|
||||||
The %{name}-devel package contains libraries and header files for
|
|
||||||
developing applications that use %{name}.
|
|
||||||
|
|
||||||
%package utils
|
|
||||||
Summary: Utilities and tools for debugging %{name}
|
|
||||||
Requires: %{name}%{?_isa} = %{version}-%{release}
|
|
||||||
Requires: python3-pyudev python3-libevdev
|
|
||||||
|
|
||||||
%description utils
|
|
||||||
The %{name}-utils package contains tools to debug hardware and analyze
|
|
||||||
%{name}.
|
|
||||||
|
|
||||||
%package test
|
|
||||||
Summary: libinput integration test suite
|
|
||||||
Requires: %{name}%{?_isa} = %{version}-%{release}
|
|
||||||
|
|
||||||
%description test
|
|
||||||
The %{name}-test package contains the libinput test suite. It is not
|
|
||||||
intended to be run by users.
|
|
||||||
|
|
||||||
%prep
|
|
||||||
%autosetup -S git -n %{name}-%{version}
|
|
||||||
|
|
||||||
%build
|
|
||||||
%meson -Dtests=true \
|
|
||||||
-Dinstall-tests=true \
|
|
||||||
-Dudev-dir=%{udevdir}
|
|
||||||
%meson_build
|
|
||||||
|
|
||||||
%install
|
|
||||||
%meson_install
|
|
||||||
|
|
||||||
%post
|
|
||||||
%{?ldconfig}
|
|
||||||
|
|
||||||
%ldconfig_postun
|
|
||||||
|
|
||||||
|
|
||||||
%files
|
|
||||||
%doc COPYING
|
|
||||||
%dir %{_sysconfdir}/libinput
|
|
||||||
%{_libdir}/libinput.so.*
|
|
||||||
%{udevdir}/libinput-device-group
|
|
||||||
%{udevdir}/libinput-fuzz-extract
|
|
||||||
%{udevdir}/libinput-fuzz-to-zero
|
|
||||||
%{udevdir}/rules.d/80-libinput-device-groups.rules
|
|
||||||
%{udevdir}/rules.d/90-libinput-fuzz-override.rules
|
|
||||||
%{_bindir}/libinput
|
|
||||||
%dir %{_libexecdir}/libinput/
|
|
||||||
%{_libexecdir}/libinput/libinput-debug-events
|
|
||||||
%{_libexecdir}/libinput/libinput-list-devices
|
|
||||||
%{_mandir}/man1/libinput.1*
|
|
||||||
%{_datadir}/libinput/*.quirks
|
|
||||||
%dir %{_datadir}/zsh
|
|
||||||
%dir %{_datadir}/zsh/site-functions
|
|
||||||
%{_datadir}/zsh/site-functions/*
|
|
||||||
%{_mandir}/man1/libinput-list-devices.1*
|
|
||||||
%{_mandir}/man1/libinput-debug-events.1*
|
|
||||||
|
|
||||||
%files devel
|
|
||||||
%{_includedir}/libinput.h
|
|
||||||
%{_libdir}/libinput.so
|
|
||||||
%{_libdir}/pkgconfig/libinput.pc
|
|
||||||
|
|
||||||
%files utils
|
|
||||||
%{_libexecdir}/libinput/libinput-debug-gui
|
|
||||||
%{_libexecdir}/libinput/libinput-debug-tablet
|
|
||||||
%{_libexecdir}/libinput/libinput-debug-tablet-pad
|
|
||||||
%{_libexecdir}/libinput/libinput-list-kernel-devices
|
|
||||||
%{_libexecdir}/libinput/libinput-measure
|
|
||||||
%{_libexecdir}/libinput/libinput-measure-fuzz
|
|
||||||
%{_libexecdir}/libinput/libinput-measure-touchpad-tap
|
|
||||||
%{_libexecdir}/libinput/libinput-measure-touchpad-pressure
|
|
||||||
%{_libexecdir}/libinput/libinput-measure-touch-size
|
|
||||||
%{_libexecdir}/libinput/libinput-measure-touchpad-size
|
|
||||||
%{_libexecdir}/libinput/libinput-quirks
|
|
||||||
%{_libexecdir}/libinput/libinput-record
|
|
||||||
%{_libexecdir}/libinput/libinput-replay
|
|
||||||
%{_libexecdir}/libinput/libinput-analyze
|
|
||||||
%{_libexecdir}/libinput/libinput-analyze-buttons
|
|
||||||
%{_libexecdir}/libinput/libinput-analyze-per-slot-delta
|
|
||||||
%{_libexecdir}/libinput/libinput-analyze-recording
|
|
||||||
%{_libexecdir}/libinput/libinput-analyze-touch-down-state
|
|
||||||
%{_mandir}/man1/libinput-debug-gui.1*
|
|
||||||
%{_mandir}/man1/libinput-debug-tablet.1*
|
|
||||||
%{_mandir}/man1/libinput-debug-tablet-pad.1*
|
|
||||||
%{_mandir}/man1/libinput-list-kernel-devices.1*
|
|
||||||
%{_mandir}/man1/libinput-measure.1*
|
|
||||||
%{_mandir}/man1/libinput-measure-fuzz.1*
|
|
||||||
%{_mandir}/man1/libinput-measure-touchpad-tap.1*
|
|
||||||
%{_mandir}/man1/libinput-measure-touch-size.1*
|
|
||||||
%{_mandir}/man1/libinput-measure-touchpad-size.1*
|
|
||||||
%{_mandir}/man1/libinput-measure-touchpad-pressure.1*
|
|
||||||
%{_mandir}/man1/libinput-quirks.1*
|
|
||||||
%{_mandir}/man1/libinput-quirks-list.1*
|
|
||||||
%{_mandir}/man1/libinput-quirks-validate.1*
|
|
||||||
%{_mandir}/man1/libinput-record.1*
|
|
||||||
%{_mandir}/man1/libinput-replay.1*
|
|
||||||
%{_mandir}/man1/libinput-analyze.1*
|
|
||||||
%{_mandir}/man1/libinput-analyze-buttons.1*
|
|
||||||
%{_mandir}/man1/libinput-analyze-per-slot-delta.1*
|
|
||||||
%{_mandir}/man1/libinput-analyze-recording.1*
|
|
||||||
%{_mandir}/man1/libinput-analyze-touch-down-state.1*
|
|
||||||
|
|
||||||
%files test
|
|
||||||
%{_libexecdir}/libinput/libinput-test
|
|
||||||
%{_libexecdir}/libinput/libinput-test-suite
|
|
||||||
%{_libexecdir}/libinput/libinput-test-utils
|
|
||||||
%{_mandir}/man1/libinput-test.1*
|
|
||||||
%{_mandir}/man1/libinput-test-suite.1*
|
|
||||||
|
|
||||||
%changelog
|
|
||||||
* Wed Jul 15 2020 Peter Hutterer <peter.hutterer@redhat.com>
|
|
||||||
- Add basic spec file for package build testing
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
#
|
|
||||||
# This script is sourced from here:
|
|
||||||
# https://gitlab.freedesktop.org/whot/meson-helper
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
set -x
|
|
||||||
if [[ -f .meson_environment ]]; then
|
|
||||||
. .meson_environment
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If test args are set, we assume we want to run the tests
|
|
||||||
MESON_RUN_TEST="$MESON_TEST_ARGS"
|
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case $1 in
|
|
||||||
--skip-setup)
|
|
||||||
shift
|
|
||||||
MESON_SKIP_SETUP="1"
|
|
||||||
;;
|
|
||||||
--skip-build)
|
|
||||||
shift
|
|
||||||
MESON_SKIP_BUILD="1"
|
|
||||||
;;
|
|
||||||
--skip-test)
|
|
||||||
shift
|
|
||||||
MESON_RUN_TEST=""
|
|
||||||
;;
|
|
||||||
--run-test)
|
|
||||||
shift
|
|
||||||
MESON_RUN_TEST="1"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Unknow commandline argument $1"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ -z "$MESON_BUILDDIR" ]]; then
|
|
||||||
echo "\$MESON_BUILDDIR undefined."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# emulate a few gitlab variables to make it easier to
|
|
||||||
# run and debug locally.
|
|
||||||
if [[ -z "$CI_JOB_ID" ]] || [[ -z "$CI_JOB_NAME" ]]; then
|
|
||||||
echo "Missing \$CI_JOB_ID or \$CI_JOB_NAME".
|
|
||||||
CI_PROJECT_NAME=$(basename "$PWD")
|
|
||||||
CI_JOB_ID=$(date +%s)
|
|
||||||
CI_JOB_NAME="$CI_PROJECT_NAME-job-local"
|
|
||||||
echo "Simulating gitlab environment: "
|
|
||||||
echo " CI_JOB_ID=$CI_JOB_ID"
|
|
||||||
echo " CI_JOB_NAME=$CI_JOB_NAME"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$FDO_CI_CONCURRENT" ]]; then
|
|
||||||
jobcount="-j$FDO_CI_CONCURRENT"
|
|
||||||
export MESON_TESTTHREADS="$FDO_CI_CONCURRENT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "*************************************************"
|
|
||||||
echo "builddir: $MESON_BUILDDIR"
|
|
||||||
echo "meson args: $MESON_ARGS"
|
|
||||||
echo "ninja args: $NINJA_ARGS"
|
|
||||||
echo "meson test args: $MESON_TEST_ARGS"
|
|
||||||
echo "job count: ${jobcount-0}"
|
|
||||||
echo "*************************************************"
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
if [[ -z "$MESON_SKIP_SETUP" ]]; then
|
|
||||||
rm -rf "$MESON_BUILDDIR"
|
|
||||||
meson setup "$MESON_BUILDDIR" $MESON_ARGS
|
|
||||||
fi
|
|
||||||
meson configure "$MESON_BUILDDIR"
|
|
||||||
|
|
||||||
if [[ -z "$MESON_SKIP_BUILD" ]]; then
|
|
||||||
if [[ -n "$NINJA_ARGS" ]]; then
|
|
||||||
ninja_args="--ninja-args $NINJA_ARGS"
|
|
||||||
fi
|
|
||||||
meson compile -v -C "$MESON_BUILDDIR" $jobcount $ninja_args
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$MESON_RUN_TEST" ]]; then
|
|
||||||
meson test -C "$MESON_BUILDDIR" $MESON_TEST_ARGS --print-errorlogs
|
|
||||||
fi
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
scan-build -v --status-bugs -plist-html "$@"
|
|
||||||
|
|
@ -1,119 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
from dataclasses import dataclass
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import itertools
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class WhitespaceError:
|
|
||||||
message: str
|
|
||||||
lineno: int
|
|
||||||
nlines: int = 1
|
|
||||||
column: None | int = None
|
|
||||||
ncolumns: int = 1
|
|
||||||
|
|
||||||
|
|
||||||
def test_duplicate_empty_lines(lines: list[str]) -> list[WhitespaceError]:
|
|
||||||
errors = []
|
|
||||||
for idx, (l1, l2) in enumerate(itertools.pairwise(lines)):
|
|
||||||
if not l1 and not l2:
|
|
||||||
errors.append(WhitespaceError("Duplicated empty lines", idx, nlines=2))
|
|
||||||
return errors
|
|
||||||
|
|
||||||
|
|
||||||
def test_tab_after_space(lines: list[str]) -> list[WhitespaceError]:
|
|
||||||
errors = []
|
|
||||||
for idx, l in enumerate(lines):
|
|
||||||
index = l.find(" \t")
|
|
||||||
if index > -1:
|
|
||||||
errors.append(
|
|
||||||
WhitespaceError(
|
|
||||||
"Tab after space", idx, nlines=index, column=index, ncolumns=2
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return errors
|
|
||||||
|
|
||||||
|
|
||||||
def test_trailing_whitespace(lines: list[str]) -> list[WhitespaceError]:
|
|
||||||
errors = []
|
|
||||||
for idx, l in enumerate(lines):
|
|
||||||
if l.rstrip() != l:
|
|
||||||
errors.append(WhitespaceError("Trailing whitespace", idx))
|
|
||||||
return errors
|
|
||||||
|
|
||||||
|
|
||||||
def test_empty_line_between_braces(lines: list[str]) -> list[WhitespaceError]:
|
|
||||||
errors = []
|
|
||||||
for idx in range(len(lines) - 3):
|
|
||||||
l1 = lines[idx]
|
|
||||||
l2 = lines[idx + 1]
|
|
||||||
l3 = lines[idx + 2]
|
|
||||||
if l1.strip() == "}" and l3.strip() == "}" and l2.strip() == "":
|
|
||||||
errors.append(WhitespaceError("Empty line between closing braces", idx + 1))
|
|
||||||
return errors
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser(description="Whitespace checker script")
|
|
||||||
parser.add_argument(
|
|
||||||
"files",
|
|
||||||
metavar="FILES",
|
|
||||||
type=Path,
|
|
||||||
nargs="+",
|
|
||||||
help="The files to check",
|
|
||||||
)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
have_errors: bool = False
|
|
||||||
|
|
||||||
if os.isatty(sys.stderr.fileno()):
|
|
||||||
red = "\x1b[0;31m"
|
|
||||||
reset = "\x1b[0m"
|
|
||||||
else:
|
|
||||||
red = ""
|
|
||||||
reset = ""
|
|
||||||
|
|
||||||
for file in args.files:
|
|
||||||
lines = [l.rstrip("\n") for l in file.open().readlines()]
|
|
||||||
|
|
||||||
errors = []
|
|
||||||
errors.extend(test_tab_after_space(lines))
|
|
||||||
errors.extend(test_trailing_whitespace(lines))
|
|
||||||
if any(file.name.endswith(suffix) for suffix in [".c", ".h"]):
|
|
||||||
if not file.parts[0] == "include":
|
|
||||||
errors.extend(test_duplicate_empty_lines(lines))
|
|
||||||
errors.extend(test_empty_line_between_braces(lines))
|
|
||||||
|
|
||||||
for e in errors:
|
|
||||||
print(f"{red}ERROR: {e.message} in {file}:{reset}", file=sys.stderr)
|
|
||||||
print(f"{'-' * 72}", file=sys.stderr)
|
|
||||||
lineno = max(0, e.lineno - 5)
|
|
||||||
for idx, l in enumerate(lines[lineno : lineno + 10]):
|
|
||||||
if e.lineno <= lineno + idx < e.lineno + e.nlines:
|
|
||||||
prefix = "->"
|
|
||||||
hl = red
|
|
||||||
nohl = reset
|
|
||||||
else:
|
|
||||||
prefix = " "
|
|
||||||
hl = ""
|
|
||||||
nohl = ""
|
|
||||||
print(f"{hl}{lineno + idx:3d}: {prefix} {l.rstrip()}{nohl}")
|
|
||||||
|
|
||||||
print(f"{'-' * 72}", file=sys.stderr)
|
|
||||||
|
|
||||||
if errors:
|
|
||||||
have_errors = True
|
|
||||||
|
|
||||||
if have_errors:
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
<!--
|
|
||||||
|
|
||||||
Before your file a feature request, please read
|
|
||||||
|
|
||||||
https://wayland.freedesktop.org/libinput/doc/latest/what-is-libinput.html
|
|
||||||
|
|
||||||
The amount of developer time libinput has available is very small.
|
|
||||||
Requesting a feature is no guarantee that it will get implemented. Someone
|
|
||||||
(you!) needs to step up to do the work.
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
|
|
||||||
<!-- Summarize the requested feature in a few sentences. -->
|
|
||||||
|
|
||||||
## Feature details
|
|
||||||
|
|
||||||
<!-- A step-by-step list of what the feature should achieve (where applicable) -->
|
|
||||||
|
|
||||||
## Affected Hardware
|
|
||||||
|
|
||||||
<!-- Which hardware types would be affected by this -->
|
|
||||||
|
|
||||||
## Implementation in Other Systems
|
|
||||||
|
|
||||||
<!-- Does this feature already exist elsewhere? How does it work there? Try
|
|
||||||
to provide as many details as possible -->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/label ~enhancement ~"needs triage"
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
## Summary
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Summarize the bug encountered concisely. See
|
|
||||||
https://wayland.freedesktop.org/libinput/doc/latest/reporting-bugs.html for
|
|
||||||
detailed instructions to report bugs
|
|
||||||
-->
|
|
||||||
|
|
||||||
## Steps to reproduce
|
|
||||||
|
|
||||||
<!-- How to reproduce the issue on a developer machine - this is very important -->
|
|
||||||
|
|
||||||
## Required information
|
|
||||||
|
|
||||||
<!-- Note: if your libinput version is older than the current stable version,
|
|
||||||
please reproduce with a current version instead -->
|
|
||||||
|
|
||||||
- libinput version:
|
|
||||||
- hardware information:
|
|
||||||
- `libinput record` output: do not paste, **attach** the file
|
|
||||||
- `libinput debug-events --verbose` output: do not paste, **attach the file**
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
Paste any other relevant logs - please use code blocks (```) to format
|
|
||||||
console output, logs, and code as it's very hard to read otherwise.)
|
|
||||||
|
|
||||||
Do not paste logs longer than 10 lines, **attach** those instead.
|
|
||||||
|
|
||||||
If your libinput record is longer than 5-10s, we will not be able to process
|
|
||||||
it.
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
/label ~"bug" ~"needs triage"
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
repos:
|
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
||||||
rev: v5.0.0
|
|
||||||
hooks:
|
|
||||||
- id: end-of-file-fixer
|
|
||||||
- id: trailing-whitespace
|
|
||||||
- id: no-commit-to-branch
|
|
||||||
args: ['--branch', 'main']
|
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
||||||
rev: v0.12.2
|
|
||||||
hooks:
|
|
||||||
- id: ruff-check
|
|
||||||
args: ['--ignore=E741,E501', '--extend-exclude=subprojects', '.']
|
|
||||||
- id: ruff-format
|
|
||||||
args: ['--check', '--diff']
|
|
||||||
- repo: https://gitlab.freedesktop.org/freedesktop/ci-templates.git
|
|
||||||
rev: e195d80f35b45cc73668be3767b923fd76c70ed5
|
|
||||||
hooks:
|
|
||||||
- id: check-commits
|
|
||||||
- id: generate-template
|
|
||||||
- repo: local
|
|
||||||
hooks:
|
|
||||||
- id: run-sed-script
|
|
||||||
name: Check for whitespace errors
|
|
||||||
entry: ./.gitlab-ci/whitespace-check.py
|
|
||||||
language: system
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
|
||||||
rev: v20.1.6
|
|
||||||
hooks:
|
|
||||||
- id: clang-format
|
|
||||||
types_or: [c]
|
|
||||||
|
|
@ -1,244 +0,0 @@
|
||||||
# This is a set of bugbot commands for issues and merge requests - setting any of the
|
|
||||||
# bugbot::foo labels will trigger gitlab-triage to run with this ruleset (well, the
|
|
||||||
# one we have on the main branch at the time)
|
|
||||||
#
|
|
||||||
# Note that for adding labels, the label must first created in the project.
|
|
||||||
|
|
||||||
# Re-used in issues and mrs
|
|
||||||
.close_needinfo: &close_needinfo
|
|
||||||
name: "Close stale needinfo bugs"
|
|
||||||
conditions:
|
|
||||||
labels:
|
|
||||||
- "bugbot::needinfo-timeout"
|
|
||||||
actions:
|
|
||||||
remove_labels:
|
|
||||||
- "bugbot::needinfo-timeout"
|
|
||||||
comment: |
|
|
||||||
I'm closing this bug because some information we requested a while ago was never supplied and
|
|
||||||
we're not able to continue without this information.
|
|
||||||
Please feel free to re-open.
|
|
||||||
status: "close"
|
|
||||||
|
|
||||||
.remind_needinfo: &remind_needinfo
|
|
||||||
name: "Remind users of needinfo bugs"
|
|
||||||
conditions:
|
|
||||||
labels:
|
|
||||||
- "bugbot::needinfo-reminder"
|
|
||||||
actions:
|
|
||||||
labels:
|
|
||||||
- "waiting on reporter"
|
|
||||||
remove_labels:
|
|
||||||
- "bugbot::needinfo-reminder"
|
|
||||||
comment: |
|
|
||||||
Hi. This is a friendly reminder that the maintainers are waiting on some information by
|
|
||||||
you (or maybe someone cc'd on this bug). If the information is not provided we may not
|
|
||||||
be able to proceed with this issue or merge request. Please check the recent comments, thanks.
|
|
||||||
|
|
||||||
.help_needed: &help_needed
|
|
||||||
name: "Remind users help is needed"
|
|
||||||
conditions:
|
|
||||||
labels:
|
|
||||||
- "bugbot::help-needed"
|
|
||||||
actions:
|
|
||||||
labels:
|
|
||||||
- "help needed"
|
|
||||||
remove_labels:
|
|
||||||
- "bugbot::help-needed"
|
|
||||||
comment: |
|
|
||||||
Hi. This issue or merge request needs help. This simply means that for
|
|
||||||
the foreseeable future, the maintainers will not have time to work on
|
|
||||||
this.
|
|
||||||
|
|
||||||
If this is a request for a new feature, then the feature is unlikely to
|
|
||||||
be implemented unless you or another contributor files a merge request.
|
|
||||||
If a merge request already exists maybe it needs finishing which often
|
|
||||||
involves adding documentation or tests.
|
|
||||||
|
|
||||||
If this is an issue affecting a specific device then it is unlikely to be
|
|
||||||
fixed. This may be because it requires specific hardware to reproduce or
|
|
||||||
it may be that the use case is niche enough that the maintainers do not
|
|
||||||
have time to implement it.
|
|
||||||
|
|
||||||
In short, to resolve this issue or get this merge request into libinput
|
|
||||||
help is needed.
|
|
||||||
|
|
||||||
.libinput_record: &libinput_record
|
|
||||||
name: "Request libinput record output"
|
|
||||||
conditions:
|
|
||||||
labels:
|
|
||||||
- "bugbot::libinput-record"
|
|
||||||
actions:
|
|
||||||
remove_labels:
|
|
||||||
- "bugbot::libinput-record"
|
|
||||||
comment: |
|
|
||||||
Looks like we may need some extra information. Please **attach** (do not paste) the full output
|
|
||||||
of `libinput record` and `libinput debug-events --verbose` (if you haven't yet).
|
|
||||||
The [documentation](https://wayland.freedesktop.org/libinput/doc/latest/tools.html#libinput-record-and-libinput-replay)
|
|
||||||
has some information on what we're looking for to be able to triage bugs.
|
|
||||||
|
|
||||||
.hid_recorder: &hid_recorder
|
|
||||||
name: "Request hid-recorder output"
|
|
||||||
conditions:
|
|
||||||
labels:
|
|
||||||
- "bugbot::hid-recorder"
|
|
||||||
actions:
|
|
||||||
remove_labels:
|
|
||||||
- "bugbot::hid-recorder"
|
|
||||||
comment: |
|
|
||||||
Looks like we may need some extra information that isn't yet available in this issue.
|
|
||||||
Please **attach** (do not paste) the output of [`hid-recorder`](https://github.com/hidutils/hid-recorder/)
|
|
||||||
for this device (run `sudo hid-recorder` without argument and it will let you pick the device).
|
|
||||||
This should show the data the kernel receives from the device and may provide a hint on what's going on here.
|
|
||||||
|
|
||||||
.udev_hid_bpf: &udev_hid_bpf
|
|
||||||
name: "Punt to udev-hid-bpf"
|
|
||||||
conditions:
|
|
||||||
labels:
|
|
||||||
- "bugbot::udev-hid-bpf"
|
|
||||||
actions:
|
|
||||||
remove_labels:
|
|
||||||
- "bugbot::udev-hid-bpf"
|
|
||||||
comment: |
|
|
||||||
This issue looks like it could or should be fixed with [udev-hid-bpf](https://gitlab.freedesktop.org/libevdev/udev-hid-bpf/).
|
|
||||||
udev-hid-bpf is a collection of BPF programs that modify the HID Report Descriptor and/or HID Reports from the device,
|
|
||||||
making it possible to change the properties of a device and/or the events to make them compatible with the
|
|
||||||
expectations the kernel and userspace has of such devices.
|
|
||||||
|
|
||||||
Please see the [udev-hid-bpf documentation](https://libevdev.pages.freedesktop.org/udev-hid-bpf/) for details
|
|
||||||
and/or in particular the [udev-hid-bpf tutorial](https://libevdev.pages.freedesktop.org/udev-hid-bpf/tutorial.html)
|
|
||||||
if you need to enable a new device.
|
|
||||||
status: "close"
|
|
||||||
|
|
||||||
resource_rules:
|
|
||||||
issues:
|
|
||||||
rules:
|
|
||||||
- name: "Close kernel bugs"
|
|
||||||
conditions:
|
|
||||||
labels:
|
|
||||||
- "bugbot::kernel"
|
|
||||||
actions:
|
|
||||||
labels:
|
|
||||||
- "kernel"
|
|
||||||
remove_labels:
|
|
||||||
- "bugbot::kernel"
|
|
||||||
comment: |
|
|
||||||
This bug looks like a kernel issue and it cannot be fixed
|
|
||||||
in libinput directly. I'm closing this bug but do feel free
|
|
||||||
to continue discussing the issue here.
|
|
||||||
|
|
||||||
Kernel bugs are usually best sent to the [`linux-input` list](https://lore.kernel.org/linux-input/).
|
|
||||||
status: "close"
|
|
||||||
- name: "Expect a merge request"
|
|
||||||
conditions:
|
|
||||||
labels:
|
|
||||||
- "bugbot::expect-mr"
|
|
||||||
actions:
|
|
||||||
remove_labels:
|
|
||||||
- "bugbot::expect-mr"
|
|
||||||
comment: |
|
|
||||||
I'm closing this bug in anticipation of a merge request that fixes this issue.
|
|
||||||
|
|
||||||
If you are a new contributor, please see
|
|
||||||
[the freedesktop.org wiki](https://gitlab.freedesktop.org/freedesktop/freedesktop/-/wikis/home)
|
|
||||||
on how to get permissions to fork a project and file a merge request.
|
|
||||||
|
|
||||||
The [libinput documentation](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html)
|
|
||||||
also has more details on how to get started.
|
|
||||||
status: "close"
|
|
||||||
- name: "Point to 60-evdev.hwdb"
|
|
||||||
conditions:
|
|
||||||
labels:
|
|
||||||
- "bugbot::evdev-hwdb"
|
|
||||||
actions:
|
|
||||||
remove_labels:
|
|
||||||
- "bugbot::evdev-hwdb"
|
|
||||||
comment: |
|
|
||||||
Looks like this issue may be solved with a device-specific entry in systemd's hwdb.
|
|
||||||
|
|
||||||
You should have a /usr/lib/udev/hwdb.d/60-evdev.hwdb file which includes those quirks. Please see
|
|
||||||
the top of the file for instructions and follow those. Once the quirk is confirmed working
|
|
||||||
this issue (or parts thereof) should be fixed and you can submit a pull request to the
|
|
||||||
[systemd](https://github.com/systemd/systemd/) repository to get that quirk included.
|
|
||||||
Please link to the systemd issue here, thanks.
|
|
||||||
|
|
||||||
I'm closing this issue now, if the hwdb entry does not fix this issue here, please re-open.
|
|
||||||
status: "close"
|
|
||||||
- name: "Close bug for reopening"
|
|
||||||
conditions:
|
|
||||||
labels:
|
|
||||||
- "bugbot::close"
|
|
||||||
actions:
|
|
||||||
remove_labels:
|
|
||||||
- "bugbot::close"
|
|
||||||
comment: |
|
|
||||||
I'm temporarily closing this bug. The bug may not be fixed yet (see any comments above)
|
|
||||||
and we **want you to reopen it when/if it becomes actionable again**.
|
|
||||||
|
|
||||||
This process may feel unfamiliar but unfortunately closing/re-opening is the only action
|
|
||||||
all GitLab users are permitted to do. So we close it, you re-open it when whatever
|
|
||||||
above has been addressed and then we know we need to look at it again.
|
|
||||||
This issue may be closed more than once in a similar fashion but I only leave this
|
|
||||||
comment once since now you understand how it works. :smile:
|
|
||||||
|
|
||||||
For a detailed explanation on the how and why of this process please see
|
|
||||||
the [Closed Issues wiki page](https://gitlab.freedesktop.org/libinput/libinput/-/wikis/Closed-Issues).
|
|
||||||
status: "close"
|
|
||||||
- name: "Re-close bug for reopening"
|
|
||||||
conditions:
|
|
||||||
labels:
|
|
||||||
- "bugbot::re-close"
|
|
||||||
actions:
|
|
||||||
remove_labels:
|
|
||||||
- "bugbot::re-close"
|
|
||||||
comment: |
|
|
||||||
I'm temporarily closing this bug again. This is not a final close, see my comments above for the open/close process.
|
|
||||||
status: "close"
|
|
||||||
- *udev_hid_bpf
|
|
||||||
- *libinput_record
|
|
||||||
- *hid_recorder
|
|
||||||
- *close_needinfo
|
|
||||||
- *remind_needinfo
|
|
||||||
- *help_needed
|
|
||||||
merge_requests:
|
|
||||||
rules:
|
|
||||||
- name: "Remind contributor of commit rules"
|
|
||||||
conditions:
|
|
||||||
labels:
|
|
||||||
- "bugbot::commit-rules"
|
|
||||||
actions:
|
|
||||||
remove_labels:
|
|
||||||
- "bugbot::commit-rules"
|
|
||||||
comment: |
|
|
||||||
Hi. Looks like the pipeline failed because one or more of the commits in this MR do not meet our requirements.
|
|
||||||
Most commonly this the format of the commit message itself. The "Test summary" above has the details.
|
|
||||||
|
|
||||||
Please see [our docs for commit messages](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html#commit-messages)
|
|
||||||
and [our docs for submitting code](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html#submitting-code)
|
|
||||||
that explain how to amend and force-push to this repo.
|
|
||||||
- name: "Remind contributor that info needs to be in commit messages"
|
|
||||||
conditions:
|
|
||||||
labels:
|
|
||||||
- "bugbot::info-in-commit-message"
|
|
||||||
actions:
|
|
||||||
remove_labels:
|
|
||||||
- "bugbot::info-in-commit-message"
|
|
||||||
comment: |
|
|
||||||
Hi. Thanks for the merge request. I'm here to request that you add
|
|
||||||
some documentation about this merge request to the
|
|
||||||
**commit message** (or messages). You may have already written some
|
|
||||||
in the merge request description and in many cases it's fine to
|
|
||||||
copy/paste that into the commit message(s).
|
|
||||||
|
|
||||||
The reason is simple: once merged, no-one really looks at this this
|
|
||||||
page here anymore. The git log on the other hand is what developers
|
|
||||||
will use to understand the code so the information must be quickly
|
|
||||||
accessible via git.
|
|
||||||
|
|
||||||
Please see [our docs for submitting code](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html#submitting-code)
|
|
||||||
that explain how to amend and force-push to this repo.
|
|
||||||
- *udev_hid_bpf
|
|
||||||
- *libinput_record
|
|
||||||
- *hid_recorder
|
|
||||||
- *close_needinfo
|
|
||||||
- *remind_needinfo
|
|
||||||
- *help_needed
|
|
||||||
117
CODING_STYLE
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
- Indentation in tabs, 8 characters wide, spaces after the tabs where
|
||||||
|
vertical alignment is required (see below)
|
||||||
|
|
||||||
|
- Max line width 80ch, do not break up printed strings though
|
||||||
|
|
||||||
|
- Break up long lines at logical groupings, one line for each logical group
|
||||||
|
|
||||||
|
int a = somelongname() +
|
||||||
|
someotherlongname();
|
||||||
|
|
||||||
|
if (a < 0 &&
|
||||||
|
(b > 20 & d < 10) &&
|
||||||
|
d != 0.0)
|
||||||
|
|
||||||
|
|
||||||
|
somelongfunctioncall(arg1,
|
||||||
|
arg2,
|
||||||
|
arg3);
|
||||||
|
|
||||||
|
- Function declarations: return type on separate line, {} on separate line,
|
||||||
|
arguments broken up as above.
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
foobar(int a, int b)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
somenamethatiswaytoolong(int a,
|
||||||
|
int b,
|
||||||
|
int c)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* comments only */, no // comments
|
||||||
|
|
||||||
|
- variable_name, not VariableName or variableName. same for functions.
|
||||||
|
|
||||||
|
- no typedefs of structs, enums, unions
|
||||||
|
|
||||||
|
- if it generates a compiler warning, it needs to be fixed
|
||||||
|
- if it generates a static checker warning, it needs to be fixed or
|
||||||
|
commented
|
||||||
|
|
||||||
|
- declare variables at the top, try to keep them as local as possible.
|
||||||
|
Exception: if the same variable is re-used in multiple blocks, declare it
|
||||||
|
at the top.
|
||||||
|
Exception: basic loop variables, e.g. for (int i = 0; ...)
|
||||||
|
|
||||||
|
int a;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
if (foo) {
|
||||||
|
int b;
|
||||||
|
|
||||||
|
c = get_value();
|
||||||
|
usevalue(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bar) {
|
||||||
|
c = get_value();
|
||||||
|
useit(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
- do not mix function invocations and variable definitions.
|
||||||
|
|
||||||
|
wrong:
|
||||||
|
|
||||||
|
{
|
||||||
|
int a = foo();
|
||||||
|
int b = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
right:
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
int b = 7;
|
||||||
|
|
||||||
|
a = foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
There are exceptions here, e.g. tp_libinput_context(),
|
||||||
|
litest_current_device()
|
||||||
|
|
||||||
|
- if/else: { on the same line, no curly braces if both blocks are a single
|
||||||
|
statement. If either if or else block are multiple statements, both must
|
||||||
|
have curly braces.
|
||||||
|
|
||||||
|
if (foo) {
|
||||||
|
blah();
|
||||||
|
bar();
|
||||||
|
} else {
|
||||||
|
a = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
- public functions MUST be doxygen-commented, use doxygen's @foo rather than
|
||||||
|
\foo notation
|
||||||
|
|
||||||
|
- include "config.h" comes first, followed by system headers, followed by
|
||||||
|
external library headers, followed by internal headers.
|
||||||
|
sort alphabetically where it makes sense (specifically system headers)
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <libevdev/libevdev.h>
|
||||||
|
|
||||||
|
#include "libinput-private.h"
|
||||||
|
|
||||||
|
- goto jumps only to the end of the function, and only for good reasons
|
||||||
|
(usually cleanup). goto never jumps backwards
|
||||||
|
|
||||||
|
- Use stdbool.h's bool for booleans within the library (instead of 'int').
|
||||||
|
Exception: the public API uses int, not bool.
|
||||||
244
CODING_STYLE.md
|
|
@ -1,244 +0,0 @@
|
||||||
# Coding style
|
|
||||||
|
|
||||||
- Indentation in tabs, 8 characters wide, spaces after the tabs where
|
|
||||||
vertical alignment is required (see below)
|
|
||||||
|
|
||||||
**Note: this file uses spaces due to markdown rendering issues for tabs.
|
|
||||||
Code must be implemented using tabs.**
|
|
||||||
|
|
||||||
- Max line width 80ch, do not break up printed strings though
|
|
||||||
|
|
||||||
- Break up long lines at logical groupings, one line for each logical group
|
|
||||||
|
|
||||||
```c
|
|
||||||
int a = somelongname() +
|
|
||||||
someotherlongname();
|
|
||||||
|
|
||||||
if (a < 0 &&
|
|
||||||
(b > 20 & d < 10) &&
|
|
||||||
d != 0.0)
|
|
||||||
|
|
||||||
|
|
||||||
somelongfunctioncall(arg1,
|
|
||||||
arg2,
|
|
||||||
arg3);
|
|
||||||
```
|
|
||||||
|
|
||||||
- Function declarations: return type on separate line, {} on separate line,
|
|
||||||
arguments broken up as above.
|
|
||||||
|
|
||||||
```c
|
|
||||||
static inline int
|
|
||||||
foobar(int a, int b)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
somenamethatiswaytoolong(int a,
|
|
||||||
int b,
|
|
||||||
int c)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `/* comments only */`, no `// comments`
|
|
||||||
|
|
||||||
- `variable_name`, not `VariableName` or `variableName`. same for functions.
|
|
||||||
|
|
||||||
- no typedefs of structs, enums, unions
|
|
||||||
|
|
||||||
- if it generates a compiler warning, it needs to be fixed
|
|
||||||
- if it generates a static checker warning, it needs to be fixed or
|
|
||||||
commented
|
|
||||||
|
|
||||||
- declare variables when they are used first and try to keep them as local as possible.
|
|
||||||
Exception: basic loop variables, e.g. for (int i = 0; ...) should always be
|
|
||||||
declared inside the loop even where multiple loops exist
|
|
||||||
|
|
||||||
```c
|
|
||||||
int a;
|
|
||||||
|
|
||||||
if (foo) {
|
|
||||||
int b = 10;
|
|
||||||
|
|
||||||
a = get_value();
|
|
||||||
usevalue(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bar) {
|
|
||||||
a = get_value();
|
|
||||||
useit(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
int c = a * 100;
|
|
||||||
useit(c);
|
|
||||||
```
|
|
||||||
|
|
||||||
- avoid uninitialized variables where possible, declare them late instead.
|
|
||||||
Note that most of libinput predates this style, try to stick with the code
|
|
||||||
around you if in doubt.
|
|
||||||
|
|
||||||
wrong:
|
|
||||||
|
|
||||||
```c
|
|
||||||
int *a;
|
|
||||||
int b = 7;
|
|
||||||
|
|
||||||
... some code ...
|
|
||||||
|
|
||||||
a = zalloc(32);
|
|
||||||
```
|
|
||||||
|
|
||||||
right:
|
|
||||||
|
|
||||||
```c
|
|
||||||
int b = 7;
|
|
||||||
... some code ...
|
|
||||||
|
|
||||||
int *a = zalloc(32);
|
|
||||||
```
|
|
||||||
|
|
||||||
- avoid calling non-obvious functions inside declaration blocks for multiple
|
|
||||||
variables.
|
|
||||||
|
|
||||||
bad:
|
|
||||||
|
|
||||||
```c
|
|
||||||
{
|
|
||||||
int a = 7;
|
|
||||||
int b = some_complicated_function();
|
|
||||||
int *c = zalloc(32);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
better:
|
|
||||||
```c
|
|
||||||
{
|
|
||||||
int a = 7;
|
|
||||||
int *c = zalloc(32);
|
|
||||||
|
|
||||||
int b = some_complicated_function();
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
There is a bit of gut-feeling involved with this, but the goal is to make
|
|
||||||
the variable values immediately recognizable.
|
|
||||||
|
|
||||||
- Where statements are near-identical and repeated, try to keep them
|
|
||||||
identical:
|
|
||||||
|
|
||||||
bad:
|
|
||||||
```c
|
|
||||||
int a = get_some_value(x++);
|
|
||||||
do_something(a);
|
|
||||||
a = get_some_value(x++);
|
|
||||||
do_something(a);
|
|
||||||
a = get_some_value(x++);
|
|
||||||
do_something(a);
|
|
||||||
```
|
|
||||||
better:
|
|
||||||
|
|
||||||
```c
|
|
||||||
int a;
|
|
||||||
a = = get_some_value(x++);
|
|
||||||
do_something(a);
|
|
||||||
a = get_some_value(x++);
|
|
||||||
do_something(a);
|
|
||||||
a = get_some_value(x++);
|
|
||||||
do_something(a);
|
|
||||||
```
|
|
||||||
|
|
||||||
- if/else: { on the same line, no curly braces if both blocks are a single
|
|
||||||
statement. If either if or else block are multiple statements, both must
|
|
||||||
have curly braces.
|
|
||||||
|
|
||||||
```c
|
|
||||||
if (foo) {
|
|
||||||
blah();
|
|
||||||
bar();
|
|
||||||
} else {
|
|
||||||
a = 10;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- public functions MUST be doxygen-commented, use doxygen's `@foo` rather than
|
|
||||||
`\foo` notation
|
|
||||||
|
|
||||||
- `#include "config.h"` comes first, followed by system headers, followed by
|
|
||||||
external library headers, followed by internal headers.
|
|
||||||
sort alphabetically where it makes sense (specifically system headers)
|
|
||||||
|
|
||||||
```c
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <libevdev/libevdev.h>
|
|
||||||
|
|
||||||
#include "libinput-private.h"
|
|
||||||
```
|
|
||||||
|
|
||||||
- goto jumps only to the end of the function, and only for good reasons
|
|
||||||
(usually cleanup). goto never jumps backwards
|
|
||||||
|
|
||||||
- Use stdbool.h's bool for booleans within the library (instead of `int`).
|
|
||||||
Exception: the public API uses int, not bool.
|
|
||||||
|
|
||||||
# Git commit message requirements
|
|
||||||
|
|
||||||
Our CI will check the commit messages for a few requirements. Below is the
|
|
||||||
list of what we expect from a git commit.
|
|
||||||
|
|
||||||
## Commit message content
|
|
||||||
|
|
||||||
A [good commit message](http://who-t.blogspot.com/2009/12/on-commit-messages.html) needs to
|
|
||||||
answer three questions:
|
|
||||||
|
|
||||||
- Why is it necessary? It may fix a bug, it may add a feature, it may
|
|
||||||
improve performance, reliabilty, stability, or just be a change for the
|
|
||||||
sake of correctness.
|
|
||||||
- How does it address the issue? For short obvious patches this part can be
|
|
||||||
omitted, but it should be a high level description of what the approach
|
|
||||||
was.
|
|
||||||
- What effects does the patch have? (In addition to the obvious ones, this
|
|
||||||
may include benchmarks, side effects, etc.)
|
|
||||||
|
|
||||||
These three questions establish the context for the actual code changes, put
|
|
||||||
reviewers and others into the frame of mind to look at the diff and check if
|
|
||||||
the approach chosen was correct. A good commit message also helps
|
|
||||||
maintainers to decide if a given patch is suitable for stable branches or
|
|
||||||
inclusion in a distribution.
|
|
||||||
|
|
||||||
## Commit message format
|
|
||||||
|
|
||||||
The canonical git commit message format is:
|
|
||||||
|
|
||||||
```
|
|
||||||
one line as the subject line with a high-level note
|
|
||||||
|
|
||||||
full explanation of the patch follows after an empty line. This explanation
|
|
||||||
can be multiple paragraphs and is largely free-form. Markdown is not
|
|
||||||
supported.
|
|
||||||
|
|
||||||
You can include extra data where required like:
|
|
||||||
- benchmark one says 10s
|
|
||||||
- benchmark two says 12s
|
|
||||||
```
|
|
||||||
|
|
||||||
The subject line is the first thing everyone sees about this commit, so make
|
|
||||||
sure it's on point.
|
|
||||||
|
|
||||||
## Commit message technical requirements
|
|
||||||
|
|
||||||
- The commit message should use present tense (not past tense). Do write
|
|
||||||
"change foo to bar", not "changed foo to bar".
|
|
||||||
- The text width of the commit should be 78 chars or less, especially the
|
|
||||||
subject line.
|
|
||||||
- The author must be the name you usually identify as and email address. We do
|
|
||||||
not accept the default `@users.noreply` gitlab addresses.
|
|
||||||
```
|
|
||||||
git config --global user.name Your Name
|
|
||||||
git config --global user.email your@email
|
|
||||||
```
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
Thank you for your interest in contributing to libinput.
|
|
||||||
|
|
||||||
Please find more information about how to contribute in
|
|
||||||
[the documentation](https://wayland.freedesktop.org/libinput/doc/latest/contributing.html).
|
|
||||||
2
COPYING
|
|
@ -31,4 +31,4 @@ This copy is provided to provide consistent behavior regardless which kernel
|
||||||
version libinput is compiled against. The header is used during compilation
|
version libinput is compiled against. The header is used during compilation
|
||||||
only, libinput does not link against GPL libraries.
|
only, libinput does not link against GPL libraries.
|
||||||
|
|
||||||
[1] https://gitlab.freedesktop.org/libinput/libinput/blob/main/include/linux/input.h
|
[1] https://gitlab.freedesktop.org/libinput/libinput/blob/master/include/linux/input.h
|
||||||
|
|
|
||||||
54
README.md
|
|
@ -5,22 +5,36 @@ libinput is a library that provides a full input stack for display servers
|
||||||
and other applications that need to handle input devices provided by the
|
and other applications that need to handle input devices provided by the
|
||||||
kernel.
|
kernel.
|
||||||
|
|
||||||
libinput provides device detection, event handling and abstraction to
|
libinput provides device detection, event handling and abstraction so
|
||||||
minimize the amount of custom input code the user of libinput needs to
|
minimize the amount of custom input code the user of libinput need to
|
||||||
provide the common set of functionality that users expect. Input event
|
provide the common set of functionality that users expect. Input event
|
||||||
processing includes scaling touch coordinates, generating
|
processing includes scaling touch coordinates, generating
|
||||||
relative pointer events from touchpads, pointer acceleration, etc.
|
relative pointer events from touchpads, pointer acceleration, etc.
|
||||||
|
|
||||||
User documentation
|
Architecture
|
||||||
------------------
|
------------
|
||||||
|
|
||||||
Documentation explaining features available in libinput is available
|
libinput is not used directly by applications. Think of it more as a device
|
||||||
[here](https://wayland.freedesktop.org/libinput/doc/latest/features.html).
|
driver than an application library. It is used by the xf86-input-libinput
|
||||||
|
X.Org driver or Wayland compositors. The typical software stack for a system
|
||||||
|
running Wayland is:
|
||||||
|
|
||||||
This includes the [FAQ](https://wayland.freedesktop.org/libinput/doc/latest/faqs.html)
|
@dotfile libinput-stack-wayland.gv
|
||||||
and the instructions on
|
|
||||||
[reporting bugs](https://wayland.freedesktop.org/libinput/doc/latest/reporting-bugs.html).
|
|
||||||
|
|
||||||
|
The Wayland compositor may be Weston, mutter, KWin, etc. Note that
|
||||||
|
Wayland encourages the use of toolkits, so the Wayland client (your
|
||||||
|
application) does not usually talk directly to the compositor but rather
|
||||||
|
employs a toolkit (e.g. GTK) to do so. The Wayland client does not know
|
||||||
|
whether libinput is in use.
|
||||||
|
|
||||||
|
The simplified software stack for a system running X.Org is:
|
||||||
|
|
||||||
|
@dotfile libinput-stack-xorg.gv
|
||||||
|
|
||||||
|
libinput is not employed directly by the X server but by the
|
||||||
|
xf86-input-libinput driver instead. That driver is loaded by the server
|
||||||
|
on demand, depending on the xorg.conf.d configuration snippets. The X client
|
||||||
|
does not know whether libinput is in use.
|
||||||
|
|
||||||
Source code
|
Source code
|
||||||
-----------
|
-----------
|
||||||
|
|
@ -32,7 +46,7 @@ For a list of current and past releases visit:
|
||||||
https://www.freedesktop.org/wiki/Software/libinput/
|
https://www.freedesktop.org/wiki/Software/libinput/
|
||||||
|
|
||||||
Build instructions:
|
Build instructions:
|
||||||
https://wayland.freedesktop.org/libinput/doc/latest/building.html
|
https://wayland.freedesktop.org/libinput/doc/latest/building_libinput.html
|
||||||
|
|
||||||
Reporting Bugs
|
Reporting Bugs
|
||||||
--------------
|
--------------
|
||||||
|
|
@ -43,25 +57,24 @@ https://gitlab.freedesktop.org/libinput/libinput/issues/
|
||||||
Where possible, please provide the `libinput record` output
|
Where possible, please provide the `libinput record` output
|
||||||
of the input device and/or the event sequence in question.
|
of the input device and/or the event sequence in question.
|
||||||
|
|
||||||
See https://wayland.freedesktop.org/libinput/doc/latest/reporting-bugs.html
|
See @ref reporting_bugs for more info.
|
||||||
for more info.
|
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
- Developer API documentation: https://wayland.freedesktop.org/libinput/doc/latest/development.html
|
- Developer API documentation: https://wayland.freedesktop.org/libinput/doc/latest/modules.html
|
||||||
- High-level documentation about libinput's features:
|
- High-level documentation about libinput's features:
|
||||||
https://wayland.freedesktop.org/libinput/doc/latest/features.html
|
https://wayland.freedesktop.org/libinput/doc/latest/pages.html
|
||||||
- Build instructions:
|
- Build instructions:
|
||||||
https://wayland.freedesktop.org/libinput/doc/latest/building.html
|
https://wayland.freedesktop.org/libinput/doc/latest/building_libinput.html
|
||||||
- Documentation for previous versions of libinput: https://wayland.freedesktop.org/libinput/doc/
|
- Documentation for previous versions of libinput: https://wayland.freedesktop.org/libinput/doc/
|
||||||
|
|
||||||
Examples of how to use libinput are the debugging tools in the libinput
|
Examples of how to use libinput are the debugging tools in the libinput
|
||||||
repository. Developers are encouraged to look at those tools for a
|
repository. Developers are encouraged to look at those tools for a
|
||||||
real-world (yet simple) example on how to use libinput.
|
real-world (yet simple) example on how to use libinput.
|
||||||
|
|
||||||
- A commandline debugging tool: https://gitlab.freedesktop.org/libinput/libinput/tree/main/tools/libinput-debug-events.c
|
- A commandline debugging tool: https://gitlab.freedesktop.org/libinput/libinput/tree/master/tools/libinput-debug-events.c
|
||||||
- A GTK application that draws cursor/touch/tablet positions: https://gitlab.freedesktop.org/libinput/libinput/tree/main/tools/libinput-debug-gui.c
|
- A GTK application that draws cursor/touch/tablet positions: https://gitlab.freedesktop.org/libinput/libinput/tree/master/tools/libinput-debug-gui.c
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|
@ -75,10 +88,5 @@ libinput is licensed under the MIT license.
|
||||||
> and/or sell copies of the Software, and to permit persons to whom the
|
> and/or sell copies of the Software, and to permit persons to whom the
|
||||||
> Software is furnished to do so, subject to the following conditions: [...]
|
> Software is furnished to do so, subject to the following conditions: [...]
|
||||||
|
|
||||||
See the [COPYING](https://gitlab.freedesktop.org/libinput/libinput/tree/main/COPYING)
|
See the [COPYING](https://gitlab.freedesktop.org/libinput/libinput/tree/master/COPYING)
|
||||||
file for the full license information.
|
file for the full license information.
|
||||||
|
|
||||||
About
|
|
||||||
-----
|
|
||||||
|
|
||||||
Documentation generated from git commit [__GIT_VERSION__](https://gitlab.freedesktop.org/libinput/libinput/commit/__GIT_VERSION__)
|
|
||||||
|
|
|
||||||
144
circle.yml
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
# vim: set expandtab shiftwidth=2 tabstop=8 textwidth=0:
|
||||||
|
|
||||||
|
libinput_jobs:
|
||||||
|
default_settings: &default_settings
|
||||||
|
working_directory: ~/libinput
|
||||||
|
# Define a couple of standardized build targets
|
||||||
|
# that we call from every build container
|
||||||
|
build_and_test_default: &build_and_test_default
|
||||||
|
name: Build
|
||||||
|
command: |
|
||||||
|
rm -rf build
|
||||||
|
meson build ${MESON_PARAMS}
|
||||||
|
meson configure build
|
||||||
|
ninja -v -C build ${NINJA_ARGS}
|
||||||
|
environment:
|
||||||
|
MESON_PARAMS: --prefix=/opt/libinput
|
||||||
|
build_and_test: &build_and_test
|
||||||
|
run:
|
||||||
|
<<: *build_and_test_default
|
||||||
|
build_no_libwacom: &build_no_libwacom
|
||||||
|
run:
|
||||||
|
<<: *build_and_test_default
|
||||||
|
name: Build - No libwacom
|
||||||
|
environment:
|
||||||
|
MESON_PARAMS: -Dlibwacom=false
|
||||||
|
build_no_debug_gui: &build_no_debug_gui
|
||||||
|
run:
|
||||||
|
<<: *build_and_test_default
|
||||||
|
name: Build - No debug-gui
|
||||||
|
environment:
|
||||||
|
MESON_PARAMS: -Ddebug-gui=false
|
||||||
|
build_no_tests: &build_no_tests
|
||||||
|
run:
|
||||||
|
<<: *build_and_test_default
|
||||||
|
name: Build - No tests
|
||||||
|
environment:
|
||||||
|
MESON_PARAMS: -Dtests=false
|
||||||
|
build_no_docs: &build_no_docs
|
||||||
|
run:
|
||||||
|
<<: *build_and_test_default
|
||||||
|
name: Build - No docs
|
||||||
|
environment:
|
||||||
|
MESON_PARAMS: -Ddocumentation=false
|
||||||
|
build_dist: &build_dist
|
||||||
|
run:
|
||||||
|
<<: *build_and_test_default
|
||||||
|
name: Build - ninja dist
|
||||||
|
environment:
|
||||||
|
NINJA_ARGS: dist
|
||||||
|
ninja_scan_build: &ninja_scan_build
|
||||||
|
run:
|
||||||
|
<<: *build_and_test_default
|
||||||
|
name: Ninja scan-build
|
||||||
|
environment:
|
||||||
|
NINJA_ARGS: scan-build
|
||||||
|
install: &install
|
||||||
|
run:
|
||||||
|
name: Installing
|
||||||
|
command: ninja -v -C build install
|
||||||
|
export_logs: &export_logs
|
||||||
|
store_artifacts:
|
||||||
|
path: ~/libinput/build/meson-logs
|
||||||
|
|
||||||
|
fedora_install: &fedora_install
|
||||||
|
run:
|
||||||
|
name: Install prerequisites
|
||||||
|
command: |
|
||||||
|
dnf upgrade -y libsolv
|
||||||
|
dnf install -y git gcc gcc-c++ meson check-devel libudev-devel libevdev-devel doxygen graphviz valgrind binutils libwacom-devel cairo-devel gtk3-devel glib2-devel mtdev-devel
|
||||||
|
|
||||||
|
fedora_build_all: &fedora_build_all
|
||||||
|
<<: *default_settings
|
||||||
|
steps:
|
||||||
|
- *fedora_install
|
||||||
|
- checkout
|
||||||
|
- *build_and_test
|
||||||
|
- *install
|
||||||
|
- *export_logs
|
||||||
|
- *build_no_libwacom
|
||||||
|
- *build_no_debug_gui
|
||||||
|
- *build_no_tests
|
||||||
|
- *build_no_docs
|
||||||
|
- *build_dist
|
||||||
|
|
||||||
|
ubuntu_install: &ubuntu_install
|
||||||
|
run:
|
||||||
|
name: Install prerequisites
|
||||||
|
command: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y software-properties-common
|
||||||
|
add-apt-repository universe
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y git gcc g++ meson check libudev-dev libevdev-dev doxygen graphviz valgrind binutils libwacom-dev libcairo2-dev libgtk-3-dev libglib2.0-dev libmtdev-dev
|
||||||
|
|
||||||
|
ubuntu_build_all: &ubuntu_build_all
|
||||||
|
<<: *default_settings
|
||||||
|
steps:
|
||||||
|
- *ubuntu_install
|
||||||
|
- checkout
|
||||||
|
- *build_and_test
|
||||||
|
- *install
|
||||||
|
- *export_logs
|
||||||
|
- *build_no_libwacom
|
||||||
|
- *build_no_debug_gui
|
||||||
|
- *build_no_tests
|
||||||
|
- *build_no_docs
|
||||||
|
- *build_dist
|
||||||
|
|
||||||
|
scan_build_run: &scan_build_run
|
||||||
|
<<: *default_settings
|
||||||
|
steps:
|
||||||
|
- *fedora_install
|
||||||
|
- run:
|
||||||
|
name: Install clang and find
|
||||||
|
command: dnf install -y clang-analyzer findutils
|
||||||
|
- checkout
|
||||||
|
- *ninja_scan_build
|
||||||
|
- *export_logs
|
||||||
|
- run:
|
||||||
|
name: Check scan-build results
|
||||||
|
command: test ! -d ~/libinput/build/meson-logs/scanbuild || test $(find ~/libinput/build/meson-logs/scanbuild -maxdepth 0 ! -empty -exec echo "not empty" \; | wc -l) -eq 0 || (echo "Check scan-build results" && false)
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
jobs:
|
||||||
|
fedora_latest:
|
||||||
|
<<: *fedora_build_all
|
||||||
|
docker:
|
||||||
|
- image: fedora:latest
|
||||||
|
ubuntu_17_10:
|
||||||
|
<<: *ubuntu_build_all
|
||||||
|
docker:
|
||||||
|
- image: ubuntu:artful
|
||||||
|
scan_build:
|
||||||
|
<<: *scan_build_run
|
||||||
|
docker:
|
||||||
|
- image: fedora:latest
|
||||||
|
|
||||||
|
workflows:
|
||||||
|
version: 2
|
||||||
|
compile:
|
||||||
|
jobs:
|
||||||
|
- fedora_latest
|
||||||
|
- scan_build
|
||||||
|
- ubuntu_17_10
|
||||||
|
|
@ -1,282 +0,0 @@
|
||||||
#compdef libinput
|
|
||||||
|
|
||||||
(( $+functions[_libinput_commands] )) || _libinput_commands()
|
|
||||||
{
|
|
||||||
local -a commands
|
|
||||||
commands=(
|
|
||||||
"list-devices:List all devices recognized by libinput"
|
|
||||||
"debug-events:Print all events as seen by libinput"
|
|
||||||
"debug-gui:Show a GUI to visualize libinput's events"
|
|
||||||
"debug-tablet:Show tablet axis and button values"
|
|
||||||
"measure:Measure various properties of devices"
|
|
||||||
"analyze:Analyze device data"
|
|
||||||
"record:Record the events from a device"
|
|
||||||
"replay:Replay the events from a device"
|
|
||||||
)
|
|
||||||
|
|
||||||
_describe -t commands 'command' commands
|
|
||||||
}
|
|
||||||
|
|
||||||
__all_seats()
|
|
||||||
{
|
|
||||||
# Obviously only works with logind
|
|
||||||
local -a seats
|
|
||||||
seats=${(f)"$(loginctl --no-legend --no-pager list-seats 2>/dev/null)"}
|
|
||||||
if [[ -z $seats ]]; then
|
|
||||||
# Can always offer seat0, even if we can't enumerate the seats
|
|
||||||
compadd "$@" - seat0
|
|
||||||
else
|
|
||||||
compadd "$@" - $seats
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_list-devices] )) || _libinput_list-devices()
|
|
||||||
{
|
|
||||||
_arguments \
|
|
||||||
'--help[Show help and exit]' \
|
|
||||||
'--version[show version information and exit]'
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_debug-events] )) || _libinput_debug-events()
|
|
||||||
{
|
|
||||||
_arguments \
|
|
||||||
'--help[Show debug-events help and exit]' \
|
|
||||||
'--quiet[Only print libinput messages and nothing from this tool]' \
|
|
||||||
'--verbose[Use verbose output]' \
|
|
||||||
'--show-keycodes[Make all keycodes visible]' \
|
|
||||||
'--grab[Exclusively grab all opened devices]' \
|
|
||||||
'--compress-motion-events[Compress repeated motion events on a TTY]' \
|
|
||||||
'--device=[Use the given device with the path backend]:device:_files -W /dev/input/ -P /dev/input/' \
|
|
||||||
'--udev=[Listen for notifications on the given seat]:seat:__all_seats' \
|
|
||||||
'--apply-to=[Apply configuration options where the device name matches the pattern]:pattern' \
|
|
||||||
'--disable-sendevents=[Disable send-events option for the devices matching the pattern]:pattern' \
|
|
||||||
'--set-area=[Set the desired area as "x1/y1 x2/y2" (within \[0.0, 1.0\]) ]' \
|
|
||||||
'--set-calibration=[Set the first 6 elements of the 3x3 calibration matrix ("1.0 0.0 0.0 0.0 1.0 0.0")]' \
|
|
||||||
'--set-click-method=[Set the desired click method]:click-method:(none clickfinger buttonareas)' \
|
|
||||||
'--set-clickfinger-map=[Set button mapping for clickfinger]:tap-map:(( \
|
|
||||||
lrm\:2-fingers\ right-click\ /\ 3-fingers\ middle-click \
|
|
||||||
lmr\:2-fingers\ middle-click\ /\ 3-fingers\ right-click \
|
|
||||||
))' \
|
|
||||||
'--set-eraser-button-button=[Set button mapping for the eraser button]:eraser-button:(BTN_STYLUS BTN_STYLUS2 BTN_STYLUS3)' \
|
|
||||||
'--set-eraser-button-mode=[Set the eraser button mode]:eraser-mode:(default button)' \
|
|
||||||
'--set-pressure-range=[Set the tablet tool pressure range (within range \[0.0, 1.0\])]' \
|
|
||||||
'--set-profile=[Set pointer acceleration profile]:accel-profile:(adaptive flat custom)' \
|
|
||||||
'--set-rotation-angle=[Set the rotation angle in degrees]' \
|
|
||||||
'--set-scroll-button=[Set the button to the given button code]' \
|
|
||||||
'--set-scroll-method=[Set the desired scroll method]:scroll-method:(none twofinger edge button)' \
|
|
||||||
'--set-speed=[Set pointer acceleration speed (within range \[-1, 1\])]' \
|
|
||||||
'--set-tap-map=[Set button mapping for tapping]:tap-map:(( \
|
|
||||||
lrm\:2-fingers\ right-click\ /\ 3-fingers\ middle-click \
|
|
||||||
lmr\:2-fingers\ middle-click\ /\ 3-fingers\ right-click \
|
|
||||||
))' \
|
|
||||||
+ '(custom pointer acceleration)' \
|
|
||||||
'--set-custom-points=[Set n points defining a custom acceleration function]' \
|
|
||||||
'--set-custom-step=[Set the distance along the x axis between the custom points]' \
|
|
||||||
'--set-custom-type=[Set the type of the acceleration function]:custom-type:(fallback motion scroll)' \
|
|
||||||
+ '(drag)' \
|
|
||||||
'--enable-drag[Enable tap-and-drag]' \
|
|
||||||
'--disable-drag[Disable tap-and-drag]' \
|
|
||||||
+ '(drag-lock)' \
|
|
||||||
'--enable-drag-lock[Enable drag-lock]' \
|
|
||||||
'--disable-drag-lock[Disable drag-lock]' \
|
|
||||||
+ '(dwt)' \
|
|
||||||
'--enable-dwt[Enable disable-while-typing]' \
|
|
||||||
'--disable-dwt[Disable disable-while-typing]' \
|
|
||||||
+ '(dwtp)' \
|
|
||||||
'--enable-dwtp[Enable disable-while-trackpointing]' \
|
|
||||||
'--disable-dwtp[Disable disable-while-trackpointing]' \
|
|
||||||
+ '(left-handed)' \
|
|
||||||
'--enable-left-handed[Enable left handed button configuration]' \
|
|
||||||
'--disable-left-handed[Disable left handed button configuration]' \
|
|
||||||
+ '(middlebutton)' \
|
|
||||||
'--enable-middlebutton[Enable middle button emulation]' \
|
|
||||||
'--disable-middlebutton[Disable middle button emulation]' \
|
|
||||||
+ '(natural-scrolling)' \
|
|
||||||
'--enable-natural-scrolling[Enable natural scrolling]' \
|
|
||||||
'--disable-natural-scrolling[Disable natural scrolling]' \
|
|
||||||
+ '(plugins)' \
|
|
||||||
'--enable-plugins[Enable plugins]' \
|
|
||||||
'--disable-plugins[Disable plugins]' \
|
|
||||||
+ '(tap-to-click)' \
|
|
||||||
'--enable-tap[Enable tap-to-click]' \
|
|
||||||
'--disable-tap[Disable tap-to-click]'
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_debug-gui] )) || _libinput_debug-gui()
|
|
||||||
{
|
|
||||||
_arguments \
|
|
||||||
'--help[Show debug-gui help and exit]' \
|
|
||||||
'--verbose[Use verbose output]' \
|
|
||||||
'--grab[Exclusively grab all opened devices]' \
|
|
||||||
'--device=[Use the given device with the path backend]:device:_files -W /dev/input/ -P /dev/input/' \
|
|
||||||
'--udev=[Listen for notifications on the given seat]:seat:_libinput_all_seats'
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_debug-tablet] )) || _libinput_debug-tablet()
|
|
||||||
{
|
|
||||||
_arguments \
|
|
||||||
'--help[Show debug-tablet help and exit]' \
|
|
||||||
'--device=[Use the given device with the path backend]:device:_files -W /dev/input/ -P /dev/input/' \
|
|
||||||
'--udev=[Use the first tablet device on the given seat]:seat:_libinput_all_seats'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
(( $+functions[_libinput_measure] )) || _libinput_measure()
|
|
||||||
{
|
|
||||||
local curcontext=$curcontext state line ret=1
|
|
||||||
local features
|
|
||||||
features=(
|
|
||||||
"fuzz:Measure touch fuzz to avoid pointer jitter"
|
|
||||||
"touch-size:Measure touch size and orientation"
|
|
||||||
"touchpad-tap:Measure tap-to-click time"
|
|
||||||
"touchpad-pressure:Measure touch pressure"
|
|
||||||
)
|
|
||||||
|
|
||||||
_arguments -C \
|
|
||||||
'--help[Print help and exit]' \
|
|
||||||
':feature:->feature' \
|
|
||||||
'*:: :->option-or-argument'
|
|
||||||
|
|
||||||
case $state in
|
|
||||||
(feature)
|
|
||||||
_describe -t features 'feature' features
|
|
||||||
;;
|
|
||||||
(option-or-argument)
|
|
||||||
curcontext=${curcontext%:*:*}:libinput-measure-$words[1]:
|
|
||||||
if ! _call_function ret _libinput_measure_$words[1]; then
|
|
||||||
_message "unknown feature: $words[1]"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_measure_fuzz] )) || _libinput_measure_fuzz()
|
|
||||||
{
|
|
||||||
_arguments \
|
|
||||||
'--help[Show help message and exit]' \
|
|
||||||
':device:_files -W /dev/input/ -P /dev/input/'
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_measure_touch-size] )) || _libinput_measure_touch-size()
|
|
||||||
{
|
|
||||||
_arguments \
|
|
||||||
'--help[Show help message and exit]' \
|
|
||||||
'--touch-threshold=[Assume a touch pressure threshold of "down:up"]' \
|
|
||||||
'--palm-threshold=[Assume a palm threshold of N]' \
|
|
||||||
':device:_files -W /dev/input/ -P /dev/input/'
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_measure_touchpad-pressure] )) || _libinput_measure_touchpad-pressure()
|
|
||||||
{
|
|
||||||
_arguments \
|
|
||||||
'--help[Show help message and exit]' \
|
|
||||||
'--touch-threshold=[Assume a touch pressure threshold of "down:up"]' \
|
|
||||||
'--palm-threshold=[Assume a palm threshold of N]' \
|
|
||||||
':device:_files -W /dev/input/ -P /dev/input/'
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_measure_touchpad-tap] )) || _libinput_measure_touchpad-tap()
|
|
||||||
{
|
|
||||||
_arguments \
|
|
||||||
'--help[Show help message and exit]' \
|
|
||||||
'--format=dat[Specify the data format to be printed. The default is "summary"]' \
|
|
||||||
':device:_files -W /dev/input/ -P /dev/input/'
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_analyze_per-slot-delta] )) || _libinput_analyze_per-slot-delta()
|
|
||||||
{
|
|
||||||
_arguments \
|
|
||||||
'--help[Show help message and exit]' \
|
|
||||||
':recording:_files'
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_analyze_touch-down-state] )) || _libinput_analyze_touch-down-state()
|
|
||||||
{
|
|
||||||
_arguments \
|
|
||||||
'--help[Show help message and exit]' \
|
|
||||||
':recording:_files'
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_analyze_recording] )) || _libinput_analyze_recording()
|
|
||||||
{
|
|
||||||
_arguments \
|
|
||||||
'--help[Show help message and exit]' \
|
|
||||||
':recording:_files'
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_analyze] )) || _libinput_analyze()
|
|
||||||
{
|
|
||||||
local curcontext=$curcontext state line ret=1
|
|
||||||
local features
|
|
||||||
features=(
|
|
||||||
"per-slot-delta:analyze relative movement per touch per slot"
|
|
||||||
"recording:analyze a recording by printing a pretty table"
|
|
||||||
"touch-down-state:analyze a recording for logical touch down states"
|
|
||||||
)
|
|
||||||
|
|
||||||
_arguments -C \
|
|
||||||
'--help[Print help and exit]' \
|
|
||||||
':feature:->feature' \
|
|
||||||
'*:: :->option-or-argument'
|
|
||||||
|
|
||||||
case $state in
|
|
||||||
(feature)
|
|
||||||
_describe -t features 'feature' features
|
|
||||||
;;
|
|
||||||
(option-or-argument)
|
|
||||||
curcontext=${curcontext%:*:*}:libinput-analyze-$words[1]:
|
|
||||||
if ! _call_function ret _libinput_analyze_$words[1]; then
|
|
||||||
_message "unknown feature: $words[1]"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_record] )) || _libinput_record()
|
|
||||||
{
|
|
||||||
_arguments \
|
|
||||||
'--help[Show help message and exit]' \
|
|
||||||
'--all[Record all /dev/input/event* devices available on the system]' \
|
|
||||||
'--autorestart=[Terminate the current recording after s seconds of device inactivity]' \
|
|
||||||
{-o+,--output=}'[Specify the output file to use]:file:_files -g "*.yml"' \
|
|
||||||
'--multiple[Record multiple devices at once]' \
|
|
||||||
'--show-keycodes[Show keycodes as-is in the recording]' \
|
|
||||||
'--with-libinput[Record libinput events alongside device events]' \
|
|
||||||
'--with-hidraw[Record hidraw events alongside device events]' \
|
|
||||||
'*::device:_files -W /dev/input/ -P /dev/input/'
|
|
||||||
}
|
|
||||||
|
|
||||||
(( $+functions[_libinput_replay] )) || _libinput_replay()
|
|
||||||
{
|
|
||||||
_arguments \
|
|
||||||
'--help[Show help message and exit]' \
|
|
||||||
':recording:_files'
|
|
||||||
}
|
|
||||||
|
|
||||||
_libinput()
|
|
||||||
{
|
|
||||||
local curcontext=$curcontext state line ret=1
|
|
||||||
|
|
||||||
_arguments -C \
|
|
||||||
{-h,--help}'[Show help message and exit]' \
|
|
||||||
'--version[Show version information and exit]' \
|
|
||||||
':command:->command' \
|
|
||||||
'*:: :->option-or-argument' && return
|
|
||||||
|
|
||||||
case $state in
|
|
||||||
(command)
|
|
||||||
_libinput_commands && ret=0
|
|
||||||
;;
|
|
||||||
(option-or-argument)
|
|
||||||
curcontext=${curcontext%:*:*}:libinput-$words[1]:
|
|
||||||
if ! _call_function ret _libinput_$words[1]; then
|
|
||||||
_message "unknown libinput command: $words[1]"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
_libinput
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
zshcompletiondir = get_option('zshcompletiondir')
|
|
||||||
if zshcompletiondir == ''
|
|
||||||
zshcompletiondir = get_option('datadir') / 'zsh' / 'site-functions'
|
|
||||||
endif
|
|
||||||
|
|
||||||
if zshcompletiondir != 'no'
|
|
||||||
install_data(
|
|
||||||
'_libinput',
|
|
||||||
install_dir: zshcompletiondir,
|
|
||||||
install_mode: 'rw-r--r--',
|
|
||||||
)
|
|
||||||
endif
|
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
.. _absolute_axes:
|
/**
|
||||||
|
@page absolute_axes Absolute axes
|
||||||
==============================================================================
|
|
||||||
Absolute axes
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
Devices with absolute axes are those that send positioning data for an axis in
|
Devices with absolute axes are those that send positioning data for an axis in
|
||||||
a device-specific coordinate range, defined by a minimum and a maximum value.
|
a device-specific coordinate range, defined by a minimum and a maximum value.
|
||||||
|
|
@ -13,7 +10,7 @@ libinput supports three types of devices with absolute axes:
|
||||||
|
|
||||||
- multi-touch screens
|
- multi-touch screens
|
||||||
- single-touch screens
|
- single-touch screens
|
||||||
- :ref:`graphics tablets <tablet-support>`
|
- @ref tablet-support "graphics tablets"
|
||||||
|
|
||||||
Touchpads are technically absolute devices but libinput converts the axis values
|
Touchpads are technically absolute devices but libinput converts the axis values
|
||||||
to directional motion and posts events as relative events. Touchpads do not count
|
to directional motion and posts events as relative events. Touchpads do not count
|
||||||
|
|
@ -22,15 +19,11 @@ as absolute devices in libinput.
|
||||||
For all absolute devices in libinput, the default unit for x/y coordinates is
|
For all absolute devices in libinput, the default unit for x/y coordinates is
|
||||||
in mm off the top left corner on the device, or more specifically off the
|
in mm off the top left corner on the device, or more specifically off the
|
||||||
device's sensor. If the device is physically rotated from its natural
|
device's sensor. If the device is physically rotated from its natural
|
||||||
position and this rotation was communicated to libinput (e.g. by setting
|
position and this rotation was communicated to libinput (e.g.
|
||||||
the device left-handed),
|
@ref libinput_device_config_left_handed_set "by setting the device left-handed"),
|
||||||
the coordinate origin is the top left corner in the current rotation.
|
the coordinate origin is the top left corner of in the current rotation.
|
||||||
|
|
||||||
.. _absolute_axes_handling:
|
@section absolute_axes_handling Handling of absolute coordinates
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Handling of absolute coordinates
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
In most use-cases, absolute input devices are mapped to a single screen. For
|
In most use-cases, absolute input devices are mapped to a single screen. For
|
||||||
direct input devices such as touchscreens the aspect ratio of the screen and
|
direct input devices such as touchscreens the aspect ratio of the screen and
|
||||||
|
|
@ -38,8 +31,8 @@ the device match. Mapping the input device position to the output position is
|
||||||
thus a simple mapping between two coordinates. libinput provides the API for
|
thus a simple mapping between two coordinates. libinput provides the API for
|
||||||
this with
|
this with
|
||||||
|
|
||||||
- **libinput_event_pointer_get_absolute_x_transformed()** for pointer events
|
- libinput_event_pointer_get_absolute_x_transformed() for pointer events
|
||||||
- **libinput_event_touch_get_x_transformed()** for touch events
|
- libinput_event_touch_get_x_transformed() for touch events
|
||||||
|
|
||||||
libinput's API only provides the call to map into a single coordinate range.
|
libinput's API only provides the call to map into a single coordinate range.
|
||||||
If the coordinate range has an offset, the compositor is responsible for
|
If the coordinate range has an offset, the compositor is responsible for
|
||||||
|
|
@ -47,29 +40,21 @@ applying that offset after the mapping. For example, if the device is mapped
|
||||||
to the right of two outputs, add the output offset to the transformed
|
to the right of two outputs, add the output offset to the transformed
|
||||||
coordinate.
|
coordinate.
|
||||||
|
|
||||||
.. _absolute_axes_nores:
|
@section absolute_axes_nores Devices without x/y resolution
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Devices without x/y resolution
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
An absolute device that does not provide a valid resolution is considered
|
An absolute device that does not provide a valid resolution is considered
|
||||||
buggy and must be fixed in the kernel. Some touchpad devices do not
|
buggy and must be fixed in the kernel. Some touchpad devices do not
|
||||||
provide resolution, those devices are correctly handled within libinput
|
provide resolution, those devices are correctly handled within libinput
|
||||||
(touchpads are not absolute devices, as mentioned above).
|
(touchpads are not absolute devices, as mentioned above).
|
||||||
|
|
||||||
.. _calibration:
|
@section calibration Calibration of absolute devices
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Calibration of absolute devices
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Absolute devices may require calibration to map precisely into the output
|
Absolute devices may require calibration to map precisely into the output
|
||||||
range required. This is done by setting a transformation matrix, see
|
range required. This is done by setting a transformation matrix, see
|
||||||
**libinput_device_config_calibration_set_matrix()** which is applied to
|
libinput_device_config_calibration_set_matrix() which is applied to
|
||||||
each input coordinate.
|
each input coordinate.
|
||||||
|
|
||||||
.. math::
|
@f[
|
||||||
\begin{pmatrix}
|
\begin{pmatrix}
|
||||||
cos\theta & -sin\theta & xoff \\
|
cos\theta & -sin\theta & xoff \\
|
||||||
sin\theta & cos\theta & yoff \\
|
sin\theta & cos\theta & yoff \\
|
||||||
|
|
@ -77,68 +62,75 @@ each input coordinate.
|
||||||
\end{pmatrix} \begin{pmatrix}
|
\end{pmatrix} \begin{pmatrix}
|
||||||
x \\ y \\ 1
|
x \\ y \\ 1
|
||||||
\end{pmatrix}
|
\end{pmatrix}
|
||||||
|
@f]
|
||||||
|
|
||||||
:math:`\theta` is the rotation angle. The offsets :math:`xoff` and :math:`yoff` are
|
@f$\theta@f$ is the rotation angle. The offsets @f$xoff@f$ and @f$yoff@f$ are
|
||||||
specified in device dimensions, i.e. a value of 1 equals one device width or
|
specified in device dimensions, i.e. a value of 1 equals one device width
|
||||||
height. Note that rotation applies to the device's origin, rotation usually
|
or height. Note that rotation applies to the device's origin, rotation
|
||||||
requires an offset to move the coordinates back into the original range.
|
usually requires an offset to move the coordinates back into the original
|
||||||
|
range.
|
||||||
|
|
||||||
The most common matrices are:
|
The most common matrices are:
|
||||||
|
|
||||||
- 90 degree clockwise:
|
- 90 degree clockwise:
|
||||||
.. math::
|
@f$
|
||||||
\begin{pmatrix}
|
\begin{pmatrix}
|
||||||
0 & -1 & 1 \\
|
0 & -1 & 1 \\
|
||||||
1 & 0 & 0 \\
|
1 & 0 & 0 \\
|
||||||
0 & 0 & 1
|
0 & 0 & 1
|
||||||
\end{pmatrix}
|
\end{pmatrix}
|
||||||
|
@f$
|
||||||
|
|
||||||
- 180 degree clockwise:
|
- 180 degree clockwise:
|
||||||
.. math::
|
@f$
|
||||||
\begin{pmatrix}
|
\begin{pmatrix}
|
||||||
-1 & 0 & 1 \\
|
-1 & 0 & 1 \\
|
||||||
0 & -1 & 1 \\
|
0 & -1 & 1 \\
|
||||||
0 & 0 & 1
|
0 & 0 & 1
|
||||||
\end{pmatrix}
|
\end{pmatrix}
|
||||||
|
@f$
|
||||||
|
|
||||||
- 270 degree clockwise:
|
- 270 degree clockwise:
|
||||||
.. math::
|
@f$
|
||||||
\begin{pmatrix}
|
\begin{pmatrix}
|
||||||
0 & 1 & 0 \\
|
0 & 1 & 0 \\
|
||||||
-1 & 0 & 1 \\
|
-1 & 0 & 1 \\
|
||||||
0 & 0 & 1
|
0 & 0 & 1
|
||||||
\end{pmatrix}
|
\end{pmatrix}
|
||||||
|
@f$
|
||||||
|
|
||||||
- reflection along y axis:
|
- reflection along y axis:
|
||||||
.. math::
|
@f$
|
||||||
\begin{pmatrix}
|
\begin{pmatrix}
|
||||||
-1 & 0 & 1 \\
|
-1 & 0 & 1 \\
|
||||||
1 & 0 & 0 \\
|
1 & 0 & 0 \\
|
||||||
0 & 0 & 1
|
0 & 0 & 1
|
||||||
\end{pmatrix}
|
\end{pmatrix}
|
||||||
|
@f$
|
||||||
|
|
||||||
See Wikipedia's
|
See Wikipedia's
|
||||||
`Transformation Matrix article <http://en.wikipedia.org/wiki/Transformation_matrix>`_
|
<a href="http://en.wikipedia.org/wiki/Transformation_matrix">Transformation
|
||||||
for more information on the matrix maths. See
|
Matrix article</a> for more information on the matrix maths. See
|
||||||
**libinput_device_config_calibration_get_default_matrix()** for how these
|
libinput_device_config_calibration_get_default_matrix() for how these
|
||||||
matrices must be supplied to libinput.
|
matrices must be supplied to libinput.
|
||||||
|
|
||||||
Once applied, any x and y axis value has the calibration applied before it
|
Once applied, any x and y axis value has the calibration applied before it
|
||||||
is made available to the caller. libinput does not provide access to the
|
is made available to the caller. libinput does not provide access to the
|
||||||
raw coordinates before the calibration is applied.
|
raw coordinates before the calibration is applied.
|
||||||
|
|
||||||
.. _absolute_axes_nonorm:
|
@section absolute_axes_nonorm Why x/y coordinates are not normalized
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
x/y are not given in @ref motion_normalization "normalized coordinates"
|
||||||
Why x/y coordinates are not normalized
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
x/y are not given in :ref:`normalized coordinates <motion_normalization>`
|
|
||||||
([0..1]) for one simple reason: the aspect ratio of virtually all current
|
([0..1]) for one simple reason: the aspect ratio of virtually all current
|
||||||
devices is something other than 1:1. A normalized axes thus is only useful to
|
devices is something other than 1:1. A normalized axes thus is only useful to
|
||||||
determine that the stylus is e.g. at 78% from the left, 34% from the top of
|
determine that the stylus is e.g. at 78% from the left, 34% from the top of
|
||||||
the device. Without knowing the per-axis resolution, these numbers are
|
the device. Without knowing the per-axis resolution, these numbers are
|
||||||
meaningless. Worse, calculation based on previous coordinates is simply wrong:
|
meaningless. Worse, calculation based on previous coordinates is simply wrong:
|
||||||
a movement from 0/0 to 50%/50% is not a 45-degree line.
|
a movement from 0/0 to 50%/50% is not a 45% degree line.
|
||||||
|
|
||||||
This could be alleviated by providing resolution and information about the
|
This could be alleviated by providing resolution and information about the
|
||||||
aspect ratio to the caller. Which shifts processing and likely errors into the
|
aspect ratio to the caller. Which shifts processing and likely errors into the
|
||||||
caller for little benefit. Providing the x/y axes in mm from the outset
|
caller for little benefit. Providing the x/y axes in mm from the outset
|
||||||
removes these errors.
|
removes these errors.
|
||||||
|
|
||||||
|
*/
|
||||||
117
doc/absolute-coordinate-ranges.dox
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
/**
|
||||||
|
@page absolute_coordinate_ranges Coordinate ranges for absolute axes
|
||||||
|
|
||||||
|
libinput requires that all touchpads provide a correct axis range and
|
||||||
|
resolution. These are used to enable or disable certain features or adapt
|
||||||
|
the interaction with the touchpad. For example, the software button area is
|
||||||
|
narrower on small touchpads to avoid reducing the interactive surface too
|
||||||
|
much. Likewise, palm detection works differently on small touchpads as palm
|
||||||
|
interference is less likely to happen.
|
||||||
|
|
||||||
|
Touchpads with incorrect axis ranges generate error messages
|
||||||
|
in the form:
|
||||||
|
<blockquote>
|
||||||
|
Axis 0x35 value 4000 is outside expected range [0, 3000]
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
This error message indicates that the ABS_MT_POSITION_X axis (i.e. the x
|
||||||
|
axis) generated an event outside the expected range of 0-3000. In this case
|
||||||
|
the value was 4000.
|
||||||
|
This discrepancy between the coordinate range the kernels advertises vs.
|
||||||
|
what the touchpad sends can be the source of a number of perceived
|
||||||
|
bugs in libinput.
|
||||||
|
|
||||||
|
@section absolute_coordinate_ranges_fix Measuring and fixing touchpad ranges
|
||||||
|
|
||||||
|
To fix the touchpad you need to:
|
||||||
|
-# measure the physical size of your touchpad in mm
|
||||||
|
-# run touchpad-edge-detector
|
||||||
|
-# trim the udev match rule to something sensible
|
||||||
|
-# replace the resolution with the calculated resolution based on physical
|
||||||
|
settings
|
||||||
|
-# test locally
|
||||||
|
-# send a patch to the systemd project
|
||||||
|
|
||||||
|
Detailed explanations are below.
|
||||||
|
|
||||||
|
[libevdev](http://freedesktop.org/wiki/Software/libevdev/) provides a tool
|
||||||
|
called **touchpad-edge-detector** that allows measuring the touchpad's input
|
||||||
|
ranges. Run the tool as root against the device node of your touchpad device
|
||||||
|
and repeatedly move a finger around the whole outside area of the
|
||||||
|
touchpad. Then control+c the process and note the output.
|
||||||
|
An example output is below:
|
||||||
|
|
||||||
|
@code
|
||||||
|
$> sudo touchpad-edge-detector /dev/input/event4
|
||||||
|
Touchpad SynPS/2 Synaptics TouchPad on /dev/input/event4
|
||||||
|
Move one finger around the touchpad to detect the actual edges
|
||||||
|
Kernel says: x [1024..3112], y [2024..4832]
|
||||||
|
Touchpad sends: x [2445..4252], y [3464..4071]
|
||||||
|
|
||||||
|
Touchpad size as listed by the kernel: 49x66mm
|
||||||
|
Calculate resolution as:
|
||||||
|
x axis: 2088/<width in mm>
|
||||||
|
y axis: 2808/<height in mm>
|
||||||
|
|
||||||
|
Suggested udev rule:
|
||||||
|
# <Laptop model description goes here>
|
||||||
|
evdev:name:SynPS/2 Synaptics TouchPad:dmi:bvnLENOVO:bvrGJET72WW(2.22):bd02/21/2014:svnLENOVO:pn20ARS25701:pvrThinkPadT440s:rvnLENOVO:rn20ARS25701:rvrSDK0E50512STD:cvnLENOVO:ct10:cvrNotAvailable:*
|
||||||
|
EVDEV_ABS_00=2445:4252:<x resolution>
|
||||||
|
EVDEV_ABS_01=3464:4071:<y resolution>
|
||||||
|
EVDEV_ABS_35=2445:4252:<x resolution>
|
||||||
|
EVDEV_ABS_36=3464:4071:<y resolution>
|
||||||
|
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Note the discrepancy between the coordinate range the kernels advertises vs.
|
||||||
|
what the touchpad sends.
|
||||||
|
To fix the advertised ranges, the udev rule should be taken and trimmed
|
||||||
|
before being sent to the [systemd project](https://github.com/systemd/systemd).
|
||||||
|
An example commit can be found
|
||||||
|
[here](https://github.com/systemd/systemd/commit/26f667eac1c5e89b689aa0a1daef6a80f473e045).
|
||||||
|
|
||||||
|
In most cases the match can and should be trimmed to the system vendor (svn)
|
||||||
|
and the product version (pvr), with everything else replaced by a wildcard
|
||||||
|
(*). In this case, a Lenovo T440s, a suitable match string would be: @code
|
||||||
|
evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*pvrThinkPadT440s*
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@note hwdb match strings only allow for alphanumeric ascii characters. Use a
|
||||||
|
wildcard (* or ?, whichever appropriate) for special characters.
|
||||||
|
|
||||||
|
The actual axis overrides are in the form:
|
||||||
|
@code
|
||||||
|
# axis number=min:max:resolution
|
||||||
|
EVDEV_ABS_00=2445:4252:42
|
||||||
|
@endcode
|
||||||
|
or, if the range is correct but the resolution is wrong
|
||||||
|
@code
|
||||||
|
# axis number=::resolution
|
||||||
|
EVDEV_ABS_00=::42
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Note the leading single space. The axis numbers are in hex and can be found
|
||||||
|
in *linux/input-event-codes.h*. For touchpads ABS_X, ABS_Y,
|
||||||
|
ABS_MT_POSITION_X and ABS_MT_POSITION_Y are required.
|
||||||
|
|
||||||
|
@note The touchpad's ranges and/or resolution should only be fixed when
|
||||||
|
there is a significant discrepancy. A few units do not make a difference and
|
||||||
|
a resolution that is off by 2 or less usually does not matter either.
|
||||||
|
|
||||||
|
Once a match and override rule has been found, follow the instructions at
|
||||||
|
the top of the
|
||||||
|
[60-evdev.hwdb](https://github.com/systemd/systemd/blob/master/hwdb/60-evdev.hwdb)
|
||||||
|
file to save it locally and trigger the udev hwdb reload. Rebooting is
|
||||||
|
always a good idea. If the match string is correct, the new properties will
|
||||||
|
show up in the
|
||||||
|
output of
|
||||||
|
@code
|
||||||
|
udevadm info /sys/class/input/event4
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Adjust the command for the event node of your touchpad.
|
||||||
|
A udev builtin will apply the new axis ranges automatically.
|
||||||
|
|
||||||
|
When the axis override is confirmed to work, please submit it as a pull
|
||||||
|
request to the [systemd project](https://github.com/systemd/systemd).
|
||||||
|
*/
|
||||||
|
|
@ -1,135 +0,0 @@
|
||||||
/**
|
|
||||||
@mainpage
|
|
||||||
|
|
||||||
This is the libinput API reference.
|
|
||||||
|
|
||||||
This documentation is aimed at developers of Wayland compositors. User
|
|
||||||
documentation is available
|
|
||||||
[here](https://wayland.freedesktop.org/libinput/doc/latest).
|
|
||||||
|
|
||||||
@section concepts Concepts
|
|
||||||
|
|
||||||
@subsection concepts_initialization Initialization of a libinput context
|
|
||||||
|
|
||||||
libinput provides two different backends:
|
|
||||||
- a @ref libinput_udev_create_context "udev backend" where notifications
|
|
||||||
about new and removed devices are provided by udev, and
|
|
||||||
- a @ref libinput_path_create_context "path backend" where
|
|
||||||
@ref libinput_path_add_device "device addition" and
|
|
||||||
@ref libinput_path_remove_device "device removal" need to be handled by
|
|
||||||
the caller.
|
|
||||||
|
|
||||||
See section @ref base for information about initializing a libinput context.
|
|
||||||
|
|
||||||
@subsection concepts_events Monitoring for events
|
|
||||||
|
|
||||||
libinput exposes a single @ref libinput_get_fd "file descriptor" to the
|
|
||||||
caller. This file descriptor should be monitored by the caller, whenever
|
|
||||||
data is available the caller **must** immediately call libinput_dispatch().
|
|
||||||
Failure to do so will result in erroneous behavior.
|
|
||||||
|
|
||||||
libinput_dispatch() may result in one or more events being available to the
|
|
||||||
caller. After libinput_dispatch() a caller **should** call
|
|
||||||
libinput_get_event() to retrieve and process this event. Whenever
|
|
||||||
libinput_get_event() returns `NULL`, no further events are available.
|
|
||||||
|
|
||||||
See section @ref event for more information about events.
|
|
||||||
|
|
||||||
@subsection concepts_seats Device grouping into seats
|
|
||||||
|
|
||||||
All devices are grouped into physical and logical seats. Button and key
|
|
||||||
states are available per-device and per-seat. See @ref seat for more
|
|
||||||
information.
|
|
||||||
|
|
||||||
@subsection concepts_devices Device capabilities
|
|
||||||
|
|
||||||
libinput does not use device types. All devices have @ref
|
|
||||||
libinput_device_has_capability "capabilities" that define which events may
|
|
||||||
be generated. See @ref device for more information about devices.
|
|
||||||
|
|
||||||
Specific event types include:
|
|
||||||
- @ref event_keyboard
|
|
||||||
- @ref event_pointer
|
|
||||||
- @ref event_touch
|
|
||||||
- @ref event_gesture
|
|
||||||
- @ref event_tablet
|
|
||||||
- @ref event_tablet_pad
|
|
||||||
- @ref event_switch
|
|
||||||
|
|
||||||
|
|
||||||
@subsection concepts_configuration Device configuration
|
|
||||||
|
|
||||||
libinput relies on the caller for device configuration. See
|
|
||||||
@ref config for more information.
|
|
||||||
|
|
||||||
@subsection example An example libinput program
|
|
||||||
|
|
||||||
The simplest libinput program looks like this:
|
|
||||||
|
|
||||||
@code
|
|
||||||
static int open_restricted(const char *path, int flags, void *user_data)
|
|
||||||
{
|
|
||||||
int fd = open(path, flags);
|
|
||||||
return fd < 0 ? -errno : fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void close_restricted(int fd, void *user_data)
|
|
||||||
{
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
const static struct libinput_interface interface = {
|
|
||||||
.open_restricted = open_restricted,
|
|
||||||
.close_restricted = close_restricted,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct libinput *li;
|
|
||||||
struct libinput_event *event;
|
|
||||||
|
|
||||||
li = libinput_udev_create_context(&interface, NULL, udev);
|
|
||||||
libinput_udev_assign_seat(li, "seat0");
|
|
||||||
libinput_dispatch(li);
|
|
||||||
|
|
||||||
while ((event = libinput_get_event(li)) != NULL) {
|
|
||||||
|
|
||||||
// handle the event here
|
|
||||||
|
|
||||||
libinput_event_destroy(event);
|
|
||||||
libinput_dispatch(li);
|
|
||||||
}
|
|
||||||
|
|
||||||
libinput_unref(li);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@section building_against Building against libinput
|
|
||||||
|
|
||||||
libinput provides a
|
|
||||||
[pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/) file.
|
|
||||||
Software that uses libinput should use pkg-config and the
|
|
||||||
`PKG_CHECK_MODULES` autoconf macro.
|
|
||||||
Otherwise, the most rudimentary way to compile and link a program against
|
|
||||||
libinput is:
|
|
||||||
|
|
||||||
@verbatim
|
|
||||||
gcc -o myprogram myprogram.c `pkg-config --cflags --libs libinput`
|
|
||||||
@endverbatim
|
|
||||||
|
|
||||||
For further information on using pkgconfig see the pkg-config documentation.
|
|
||||||
|
|
||||||
@section stability Backwards-compatibility
|
|
||||||
|
|
||||||
libinput promises backwards-compatibility across all the 1.x.y version. An
|
|
||||||
application built against libinput 1.x.y will work with any future 1.*.*
|
|
||||||
release.
|
|
||||||
|
|
||||||
@section About
|
|
||||||
|
|
||||||
Documentation generated from git commit [__GIT_VERSION__](https://gitlab.freedesktop.org/libinput/libinput/commit/__GIT_VERSION__)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
prg_install = find_program('install')
|
|
||||||
|
|
||||||
doxygen = find_program('doxygen', required : false)
|
|
||||||
if not doxygen.found()
|
|
||||||
error('Program "doxygen" not found or not executable. Try building with -Ddocumentation=false')
|
|
||||||
endif
|
|
||||||
dot = find_program('dot', required : false)
|
|
||||||
if not dot.found()
|
|
||||||
error('Program "dot" not found or not executable. Try building with -Ddocumentation=false')
|
|
||||||
endif
|
|
||||||
|
|
||||||
mainpage = vcs_tag(command : ['git', 'log', '-1', '--format=%h'],
|
|
||||||
fallback : 'unknown',
|
|
||||||
input : 'mainpage.dox',
|
|
||||||
output : 'mainpage.dox',
|
|
||||||
replace_string: '__GIT_VERSION__')
|
|
||||||
|
|
||||||
src_doxygen = files(
|
|
||||||
# source files
|
|
||||||
'../../src/libinput.h',
|
|
||||||
# style files
|
|
||||||
'style/header.html',
|
|
||||||
'style/footer.html',
|
|
||||||
'style/customdoxygen.css',
|
|
||||||
'style/bootstrap.css',
|
|
||||||
'style/libinputdoxygen.css',
|
|
||||||
)
|
|
||||||
|
|
||||||
doxyfiles = []
|
|
||||||
foreach f : src_doxygen
|
|
||||||
df = configure_file(input: f,
|
|
||||||
output: '@PLAINNAME@',
|
|
||||||
copy : true)
|
|
||||||
doxyfiles += [ df ]
|
|
||||||
endforeach
|
|
||||||
|
|
||||||
doc_config = configuration_data()
|
|
||||||
doc_config.set('PACKAGE_NAME', meson.project_name())
|
|
||||||
doc_config.set('PACKAGE_VERSION', meson.project_version())
|
|
||||||
doc_config.set('builddir', meson.current_build_dir())
|
|
||||||
|
|
||||||
doxyfile = configure_file(input : 'libinput.doxygen.in',
|
|
||||||
output : 'libinput.doxygen',
|
|
||||||
configuration : doc_config)
|
|
||||||
|
|
||||||
custom_target('doxygen',
|
|
||||||
input : [ doxyfiles, doxyfile, mainpage ] + src_doxygen,
|
|
||||||
output : [ 'html' ],
|
|
||||||
command : [ doxygen, doxyfile ],
|
|
||||||
install : false,
|
|
||||||
depends: [ mainpage ],
|
|
||||||
build_by_default : true)
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
/**
|
|
||||||
|
|
||||||
@page Tablets
|
|
||||||
|
|
||||||
- @subpage tablet serial numbers
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
@ -1,120 +0,0 @@
|
||||||
@import url("https://fonts.googleapis.com/css?family=Roboto+Mono");
|
|
||||||
|
|
||||||
dd {
|
|
||||||
margin-left: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 200%;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title .ingroups {
|
|
||||||
font-size: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 150%;
|
|
||||||
color: #354C7B;
|
|
||||||
background: none;
|
|
||||||
border-bottom: 1px solid #879ECB;
|
|
||||||
font-size: 150%;
|
|
||||||
font-weight: normal;
|
|
||||||
padding-top: 8px;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
padding-left: 0px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: 120%;
|
|
||||||
color: #354C7B;
|
|
||||||
background: none;
|
|
||||||
border-bottom: 1px solid #879ECB;
|
|
||||||
font-size: 150%;
|
|
||||||
font-weight: normal;
|
|
||||||
padding-top: 8px;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
padding-left: 0px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm-dox li {
|
|
||||||
float:left;
|
|
||||||
border-top: 0;
|
|
||||||
padding-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm li, .sm a {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm, .sm ul, .sm li {
|
|
||||||
list-style: none;
|
|
||||||
display: block;
|
|
||||||
line-height: normal;
|
|
||||||
direction: ltr;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm, .sm *, .sm *::before, .sm *::after {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
#main-nav {
|
|
||||||
padding: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main menu sub-items like file-list, etc */
|
|
||||||
#main-menu li ul {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.paramname {
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.memtitle {
|
|
||||||
background-image: none;
|
|
||||||
background-color: #F0F0F0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.memproto {
|
|
||||||
background-color: #F0F0F0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.headertitle {
|
|
||||||
background-image: none;
|
|
||||||
background-color: #F0F0F0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.header {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
td.fieldname {
|
|
||||||
font-family: 'Roboto Mono', monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fieldtable th {
|
|
||||||
background-image: none;
|
|
||||||
background-color: #F0F0F0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
letter-spacing: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams {
|
|
||||||
background-color: #F0F0F0;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #2873b0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.navpath ul {
|
|
||||||
background-image: none;
|
|
||||||
background-color: #F0F0F0;
|
|
||||||
}
|
|
||||||
282
doc/architecture.dox
Normal file
|
|
@ -0,0 +1,282 @@
|
||||||
|
/**
|
||||||
|
@page architecture libinput's internal architecture
|
||||||
|
|
||||||
|
This page provides an outline of libinput's internal architecture. The goal
|
||||||
|
here is to get the high-level picture across and point out the components
|
||||||
|
and their interplay to new developers.
|
||||||
|
|
||||||
|
The public facing API is in `libinput.c`, this file is thus the entry point
|
||||||
|
for almost all API calls. General device handling is in `evdev.c` with the
|
||||||
|
device-type-specific implementations in `evdev-<type>.c`. It is not
|
||||||
|
necessary to understand all of libinput to contribute a patch.
|
||||||
|
|
||||||
|
@ref architecture-contexts is the only user-visible implementation detail,
|
||||||
|
everything else is purely internal implementation and may change when
|
||||||
|
required.
|
||||||
|
|
||||||
|
@section architecture-contexts The udev and path contexts
|
||||||
|
|
||||||
|
The first building block is the "context" which can be one of
|
||||||
|
two types, "path" and "udev". See libinput_path_create_context() and
|
||||||
|
libinput_udev_create_context(). The path/udev specific bits are in
|
||||||
|
`path-seat.c` and `udev-seat.c`. This includes the functions that add new
|
||||||
|
devices to a context.
|
||||||
|
|
||||||
|
@dot
|
||||||
|
digraph context
|
||||||
|
{
|
||||||
|
compound=true;
|
||||||
|
rankdir="LR";
|
||||||
|
node [
|
||||||
|
shape="box";
|
||||||
|
]
|
||||||
|
|
||||||
|
libudev [label="libudev 'add' event"]
|
||||||
|
udev [label="libinput_udev_create_context()"];
|
||||||
|
udev_backend [label="udev-specific backend"];
|
||||||
|
context [label="libinput context"]
|
||||||
|
udev -> udev_backend;
|
||||||
|
libudev -> udev_backend;
|
||||||
|
udev_backend -> context;
|
||||||
|
}
|
||||||
|
@enddot
|
||||||
|
|
||||||
|
The udev context provides automatic device hotplugging as udev's "add"
|
||||||
|
events are handled directly by libinput. The path context requires that the
|
||||||
|
caller adds devices.
|
||||||
|
|
||||||
|
@dot
|
||||||
|
digraph context
|
||||||
|
{
|
||||||
|
compound=true;
|
||||||
|
rankdir="LR";
|
||||||
|
node [
|
||||||
|
shape="box";
|
||||||
|
]
|
||||||
|
|
||||||
|
path [label="libinput_path_create_context()"];
|
||||||
|
path_backend [label="path-specific backend"];
|
||||||
|
xdriver [label="libinput_path_add_device()"]
|
||||||
|
context [label="libinput context"]
|
||||||
|
path -> path_backend;
|
||||||
|
xdriver -> path_backend;
|
||||||
|
path_backend -> context;
|
||||||
|
}
|
||||||
|
@enddot
|
||||||
|
|
||||||
|
As a general rule: all Wayland compositors use a udev context, the X.org
|
||||||
|
stack uses a path context.
|
||||||
|
|
||||||
|
Which context was initialized only matters for creating/destroying a context
|
||||||
|
and adding devices. The device handling itself is the same for both types of
|
||||||
|
context.
|
||||||
|
|
||||||
|
@section architecture-device Device initialization
|
||||||
|
|
||||||
|
libinput only supports evdev devices, all the device initialization is done
|
||||||
|
in `evdev.c`. Much of the libinput public API is also a thin wrapper around
|
||||||
|
the matching implementation in the evdev device.
|
||||||
|
|
||||||
|
There is a 1:1 mapping between libinput devices and `/dev/input/eventX`
|
||||||
|
device nodes.
|
||||||
|
|
||||||
|
|
||||||
|
@dot
|
||||||
|
digraph context
|
||||||
|
{
|
||||||
|
compound=true;
|
||||||
|
rankdir="LR";
|
||||||
|
node [
|
||||||
|
shape="box";
|
||||||
|
]
|
||||||
|
|
||||||
|
devnode [label="/dev/input/event0"]
|
||||||
|
|
||||||
|
libudev [label="libudev 'add' event"]
|
||||||
|
xdriver [label="libinput_path_add_device()"]
|
||||||
|
context [label="libinput context"]
|
||||||
|
|
||||||
|
evdev [label="evdev_device_create()"]
|
||||||
|
|
||||||
|
devnode -> xdriver;
|
||||||
|
devnode -> libudev;
|
||||||
|
xdriver -> context;
|
||||||
|
libudev -> context;
|
||||||
|
|
||||||
|
context->evdev;
|
||||||
|
|
||||||
|
}
|
||||||
|
@enddot
|
||||||
|
|
||||||
|
Entry point for all devices is `evdev_device_create()`, this function
|
||||||
|
decides to create a `struct evdev_device` for the given device node.
|
||||||
|
Based on the udev tags (e.g. `ID_INPUT_TOUCHPAD`), a @ref
|
||||||
|
architecture-dispatch is initialized. All event handling is then in this
|
||||||
|
dispatch.
|
||||||
|
|
||||||
|
Rejection of devices and the application of quirks is generally handled in
|
||||||
|
`evdev.c` as well. Common functionality shared across multiple device types
|
||||||
|
(like button-scrolling) is also handled here.
|
||||||
|
|
||||||
|
@section architecture-dispatch Device-type specific event dispatch
|
||||||
|
|
||||||
|
Depending on the device type, `evdev_configure_device` creates the matching
|
||||||
|
`struct evdev_dispatch`. This dispatch interface contains the function
|
||||||
|
pointers to handle events. Four such dispatch methods are currently
|
||||||
|
implemented: touchpad, tablet, tablet pad, and the fallback dispatch which
|
||||||
|
handles mice, keyboards and touchscreens.
|
||||||
|
|
||||||
|
@dot
|
||||||
|
digraph context
|
||||||
|
{
|
||||||
|
compound=true;
|
||||||
|
rankdir="LR";
|
||||||
|
node [
|
||||||
|
shape="box";
|
||||||
|
]
|
||||||
|
|
||||||
|
evdev [label="evdev_device_create()"]
|
||||||
|
|
||||||
|
fallback [label="evdev-fallback.c"]
|
||||||
|
touchpad [label="evdev-mt-touchpad.c"]
|
||||||
|
tablet [label="evdev-tablet.c"]
|
||||||
|
pad [label="evdev-tablet-pad.c"]
|
||||||
|
|
||||||
|
evdev -> fallback;
|
||||||
|
evdev -> touchpad;
|
||||||
|
evdev -> tablet;
|
||||||
|
evdev -> pad;
|
||||||
|
|
||||||
|
}
|
||||||
|
@enddot
|
||||||
|
|
||||||
|
While `evdev.c` pulls the event out of libevdev, the actual handling of the
|
||||||
|
events is performed within the dispatch method.
|
||||||
|
|
||||||
|
@dot
|
||||||
|
digraph context
|
||||||
|
{
|
||||||
|
compound=true;
|
||||||
|
rankdir="LR";
|
||||||
|
node [
|
||||||
|
shape="box";
|
||||||
|
]
|
||||||
|
|
||||||
|
evdev [label="evdev_device_dispatch()"]
|
||||||
|
|
||||||
|
fallback [label="fallback_interface_process()"];
|
||||||
|
touchpad [label="tp_interface_process()"]
|
||||||
|
tablet [label="tablet_process()"]
|
||||||
|
pad [label="pad_process()"]
|
||||||
|
|
||||||
|
evdev -> fallback;
|
||||||
|
evdev -> touchpad;
|
||||||
|
evdev -> tablet;
|
||||||
|
evdev -> pad;
|
||||||
|
}
|
||||||
|
@enddot
|
||||||
|
|
||||||
|
The dispatch methods then look at the `struct input_event` and proceed to
|
||||||
|
update the state. Note: the serialized nature of the kernel evdev protocol
|
||||||
|
requires that the device updates the state with each event but to delay
|
||||||
|
processing until the `SYN_REPORT` event is received.
|
||||||
|
|
||||||
|
@section architecture-configuration Device configuration
|
||||||
|
|
||||||
|
All device-specific configuration is handled through `struct
|
||||||
|
libinput_device_config_FOO` instances. These are set up during device init
|
||||||
|
and provide the function pointers for the `get`, `set`, `get_default`
|
||||||
|
triplet of configuration queries (or more, where applicable).
|
||||||
|
|
||||||
|
For example, the `struct tablet_dispatch` for tablet devices has a
|
||||||
|
`struct libinput_device_config_accel`. This struct is set up with the
|
||||||
|
required function pointers to change the profiles.
|
||||||
|
|
||||||
|
@dot
|
||||||
|
digraph context
|
||||||
|
{
|
||||||
|
compound=true;
|
||||||
|
rankdir="LR";
|
||||||
|
node [
|
||||||
|
shape="box";
|
||||||
|
]
|
||||||
|
|
||||||
|
tablet [label="struct tablet_dispatch"]
|
||||||
|
config [label="struct libinput_device_config_accel"];
|
||||||
|
tablet_config [label="tablet_accel_config_set_profile()"];
|
||||||
|
tablet->config;
|
||||||
|
config->tablet_config;
|
||||||
|
}
|
||||||
|
@enddot
|
||||||
|
|
||||||
|
When the matching `libinput_device_config_set_FOO()` is called, this goes
|
||||||
|
through to the config struct and invokes the function there. Thus, it is
|
||||||
|
possible to have different configuration functions for a mouse vs a
|
||||||
|
touchpad, even though the interface is the same.
|
||||||
|
|
||||||
|
@dot
|
||||||
|
digraph context
|
||||||
|
{
|
||||||
|
compound=true;
|
||||||
|
rankdir="LR";
|
||||||
|
node [
|
||||||
|
shape="box";
|
||||||
|
]
|
||||||
|
|
||||||
|
libinput [label="libinput_device_config_accel_set_profile()"];
|
||||||
|
tablet_config [label="tablet_accel_config_set_profile()"];
|
||||||
|
libinput->tablet_config;
|
||||||
|
}
|
||||||
|
@enddot
|
||||||
|
|
||||||
|
@section architecture-filter Pointer acceleration filters
|
||||||
|
|
||||||
|
All pointer acceleration is handled in the `filter.c` file and its
|
||||||
|
associated files.
|
||||||
|
|
||||||
|
The `struct motion_filter` is initialized during device init, whenever
|
||||||
|
deltas are available they are passed to `filter_dispatch()`. This function
|
||||||
|
returns a set of @ref motion_normalization_customization "normalized coordinates".
|
||||||
|
|
||||||
|
All actual acceleration is handled within the filter, the device itself has
|
||||||
|
no further knowledge. Thus it is possible to have different acceleration
|
||||||
|
filters for the same device types (e.g. the Lenovo X230 touchpad has a
|
||||||
|
custom filter).
|
||||||
|
|
||||||
|
@dot
|
||||||
|
digraph context
|
||||||
|
{
|
||||||
|
compound=true;
|
||||||
|
rankdir="LR";
|
||||||
|
node [
|
||||||
|
shape="box";
|
||||||
|
]
|
||||||
|
|
||||||
|
fallback [label="fallback deltas"];
|
||||||
|
touchpad [label="touchpad deltas"];
|
||||||
|
tablet [label="tablet deltas"];
|
||||||
|
|
||||||
|
filter [label="filter_dispatch"];
|
||||||
|
|
||||||
|
fallback->filter;
|
||||||
|
touchpad->filter;
|
||||||
|
tablet->filter;
|
||||||
|
|
||||||
|
flat [label="accelerator_interface_flat()"];
|
||||||
|
x230 [label="accelerator_filter_x230()"];
|
||||||
|
pen [label="tablet_accelerator_filter_flat_pen()"];
|
||||||
|
|
||||||
|
filter->flat;
|
||||||
|
filter->x230;
|
||||||
|
filter->pen;
|
||||||
|
|
||||||
|
}
|
||||||
|
@enddot
|
||||||
|
|
||||||
|
Most filters convert the deltas (incl. timestamps) to a motion speed and
|
||||||
|
then apply a so-called profile function. This function returns a factor that
|
||||||
|
is then applied to the current delta, converting it into an accelerated
|
||||||
|
delta. See @ref pointer-acceleration for more details.
|
||||||
|
the current
|
||||||
|
|
||||||
|
*/
|
||||||
250
doc/building.dox
Normal file
|
|
@ -0,0 +1,250 @@
|
||||||
|
/**
|
||||||
|
@page building_libinput libinput build instructions
|
||||||
|
|
||||||
|
@tableofcontents
|
||||||
|
|
||||||
|
Instructions on how to build libinput and its tools and how to build against
|
||||||
|
libinput.
|
||||||
|
|
||||||
|
The build instruction on this page detail how to overwrite your
|
||||||
|
system-provided libinput with one from the git repository, see
|
||||||
|
see @ref reverting_install to revert to the previous state.
|
||||||
|
|
||||||
|
@section building Building libinput
|
||||||
|
|
||||||
|
libinput uses [meson](https://www.mesonbuild.com) and
|
||||||
|
[ninja](https://www.ninja-build.org). A build is usually the three-step
|
||||||
|
process below. A successful build requires the @ref
|
||||||
|
building_dependencies to be installed before running meson.
|
||||||
|
|
||||||
|
@code
|
||||||
|
$> git clone https://gitlab.freedesktop.org/libinput/libinput
|
||||||
|
$> cd libinput
|
||||||
|
$> meson --prefix=/usr builddir/
|
||||||
|
$> ninja -C builddir/
|
||||||
|
$> sudo ninja -C builddir/ install
|
||||||
|
$> sudo udevadm hwdb --update
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Additional options may also be specified. For example:
|
||||||
|
@code
|
||||||
|
$> meson --prefix=/usr -Ddocumentation=false builddir/
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
We recommend that users disable the documentation, it's not usually required
|
||||||
|
for testing and reduces the number of dependencies needed.
|
||||||
|
|
||||||
|
The ```prefix``` or other options can be changed later with the
|
||||||
|
```mesonconf``` command. For example:
|
||||||
|
@code
|
||||||
|
$> mesonconf builddir/ -Dprefix=/some/other/prefix -Ddocumentation=true
|
||||||
|
$> ninja -C builddir
|
||||||
|
$> sudo ninja -C builddir/ install
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Running ``mesonconf builddir/`` with no other arguments lists all
|
||||||
|
configurable options meson provides.
|
||||||
|
|
||||||
|
To rebuild from scratch, simply remove the build directory and run meson
|
||||||
|
again:
|
||||||
|
@code
|
||||||
|
$> rm -r builddir/
|
||||||
|
$> meson --prefix=....
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@subsection verifying_install Verifying the install
|
||||||
|
|
||||||
|
To verify the install worked correctly, check that libinput.so.x.x.x is in
|
||||||
|
the library path and that all symlinks point to the new library.
|
||||||
|
<pre>
|
||||||
|
$> ls -l /usr/lib64/libinput.*
|
||||||
|
-rwxr-xr-x 1 root root 946 Apr 28 2015 /usr/lib64/libinput.la
|
||||||
|
lrwxrwxrwx 1 root root 19 Feb 1 15:12 /usr/lib64/libinput.so -> libinput.so.10.13.0
|
||||||
|
lrwxrwxrwx 1 root root 19 Feb 1 15:12 /usr/lib64/libinput.so.10 -> libinput.so.10.13.0
|
||||||
|
-rwxr-xr-x 1 root root 204992 Feb 1 15:12 /usr/lib64/libinput.so.10.13.0
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
@subsection reverting_install Reverting to the system-provided libinput package
|
||||||
|
|
||||||
|
The recommended way to revert to the system install is to use the package
|
||||||
|
manager to reinstall the libinput package. In some cases, this may leave
|
||||||
|
files in the system (e.g. ```/usr/lib/libinput.la```) but these files are
|
||||||
|
usually harmless. To definitely remove all files, run the following command
|
||||||
|
from the libinput source directory:
|
||||||
|
|
||||||
|
@code
|
||||||
|
$> sudo ninja -C builddir/ uninstall
|
||||||
|
# WARNING: Do not restart the computer/X/the Wayland compositor after
|
||||||
|
# uninstall, reinstall the system package immediately!
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
The following commands reinstall the current system package for libinput,
|
||||||
|
overwriting manually installed files.
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><b>Debian/Ubuntu</b> based distributions: ```sudo apt-get install
|
||||||
|
--reinstall libinput```</li>
|
||||||
|
<li><b>Fedora 22</b> and later: ```sudo dnf reinstall libinput```</li>
|
||||||
|
<li><b>RHEL/CentOS/Fedora 21</b> and earlier: ```sudo yum reinstall libinput```</li>
|
||||||
|
<li><b>openSUSE</b>: ```sudo zypper install --force libinput10```</li>
|
||||||
|
<li><b>Arch</b>: ```sudo packman -S libinput```</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
@subsection building_selinux SELinux adjustments
|
||||||
|
|
||||||
|
On systems with SELinux, overwriting the distribution-provided package with
|
||||||
|
a manually built libinput may cause SELinux denials. This usually manifests
|
||||||
|
when gdm does not start because it is denied access to libinput. The journal
|
||||||
|
shows a log message in the form of:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
May 25 15:28:42 localhost.localdomain audit[23268]: AVC avc: denied { execute } for pid=23268 comm="gnome-shell" path="/usr/lib64/libinput.so.10.12.2" dev="dm-0" ino=1709093 scontext=system_u:system_r:xdm_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0
|
||||||
|
May 25 15:28:42 localhost.localdomain org.gnome.Shell.desktop[23270]: /usr/bin/gnome-shell: error while loading shared libraries: libinput.so.10: failed to map segment from shared object
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
The summary of this error message is that gdm's gnome-shell runs in the
|
||||||
|
```system_u:system_r:xdm_t``` context but libinput is installed with the
|
||||||
|
context ```unconfined_u:object_r:user_home_t```.
|
||||||
|
|
||||||
|
To avoid this issue, restore the SELinux context for any system files.
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
$> sudo restorecon /usr/lib*/libinput.so.*
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
This issue is tracked in https://github.com/mesonbuild/meson/issues/1967.
|
||||||
|
|
||||||
|
@subsection building_dependencies Build dependencies
|
||||||
|
|
||||||
|
libinput has a few build-time dependencies that must be installed prior to
|
||||||
|
running configure.
|
||||||
|
|
||||||
|
@note The build dependencies for some distributions can be found in the
|
||||||
|
<a href="https://gitlab.freedesktop.org/libinput/libinput/blob/master/.gitlab-ci.yml">
|
||||||
|
GitLab Continuous Integration file</a>. Search for <b>FEDORA_RPMS</b> in the
|
||||||
|
<b>variables:</b> definition and check the list for an entry for your
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
|
||||||
|
In most cases, it is sufficient to install the dependencies that your
|
||||||
|
distribution uses to build the libinput package. These can be installed
|
||||||
|
with one of the following commands:
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><b>Debian/Ubuntu</b> based distributions: ```sudo apt-get build-dep
|
||||||
|
libinput```</li>
|
||||||
|
<li><b>Fedora 22</b> and later: ```sudo dnf builddep libinput```</li>
|
||||||
|
<li><b>RHEL/CentOS/Fedora 21</b> and earlier: ```sudo yum-builddep libinput```</li>
|
||||||
|
<li><b>openSUSE</b>:
|
||||||
|
<pre>
|
||||||
|
$> sudo zypper modifyrepo --enable `zypper repos | grep source | awk '{print $5}'`
|
||||||
|
$> sudo zypper source-install -d libinput10
|
||||||
|
$> sudo zypper install autoconf automake libtool
|
||||||
|
$> sudo zypper modifyrepo --disable `zypper repos | grep source | awk '{print $5}'`
|
||||||
|
</pre>
|
||||||
|
</li>
|
||||||
|
<li><b>Arch</b>:
|
||||||
|
<pre>
|
||||||
|
$> sudo pacman -S asp
|
||||||
|
$> cd $(mktemp -d)
|
||||||
|
$> asp export libinput
|
||||||
|
$> cd libinput
|
||||||
|
$> makepkg --syncdeps --nobuild --noextract
|
||||||
|
</pre>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
If dependencies are missing, a message ```No package 'foo' found``` will be
|
||||||
|
shown during the configure stage. See
|
||||||
|
<a href="https://who-t.blogspot.com.au/2014/05/configure-fails-with-no-package-foo.html">this blog post here</a>.
|
||||||
|
for instructions on how to fix it.
|
||||||
|
|
||||||
|
@subsection building_libwacom Building without libwacom
|
||||||
|
|
||||||
|
libwacom is required by libinput's tablet code to gather additional
|
||||||
|
information about tablets that is not available from the kernel device
|
||||||
|
itself. libwacom is required by default but can be skipped when @ref
|
||||||
|
building.
|
||||||
|
|
||||||
|
@code
|
||||||
|
$> meson --prefix=/usr -Dlibwacom=false builddir
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
It is not recommended to disable libwacom unless libinput is used in an
|
||||||
|
environment where tablet support is not required. libinput provides tablet
|
||||||
|
support even without libwacom, but some features may be missing or working
|
||||||
|
differently.
|
||||||
|
|
||||||
|
@subsection building_debug_gui Building without the graphical helper tool
|
||||||
|
|
||||||
|
The @ref tools provide commandline features as well as graphical debugging
|
||||||
|
features. To keep dependencies in check on some builds, the graphical
|
||||||
|
features of the @ref tools can be disabled. By default, the `debug-gui`
|
||||||
|
feature of the `libinput` tool is enabled and if the required libraries are
|
||||||
|
not available, the build will fail. If the feature is not required, use the
|
||||||
|
``--disable-debug-gui`` argument when @ref building.
|
||||||
|
|
||||||
|
@code
|
||||||
|
$> meson --prefix=/usr -Ddebug-gui=false builddir
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@subsection building_autotools Building with autotools
|
||||||
|
|
||||||
|
<b>libinput no longer supports building with autotools.</b> These
|
||||||
|
instructions are kept for users for libinput versions up to 1.8.x.
|
||||||
|
|
||||||
|
A build with automake is usually the process below. A successful build
|
||||||
|
requires the @ref building_dependencies to be installed at configure
|
||||||
|
time.
|
||||||
|
|
||||||
|
@code
|
||||||
|
$> git clone https://gitlab.freedesktop.org/libinput/libinput
|
||||||
|
$> cd libinput
|
||||||
|
$> ./autogen.sh --prefix=/usr --libdir=/usr/lib64
|
||||||
|
$> make
|
||||||
|
$> sudo make install
|
||||||
|
$> sudo udevadm hwdb --update
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@note On Debian-based distributions including Ubuntu and its derivatives skip the
|
||||||
|
```--libdir=/usr/lib64``` argument.
|
||||||
|
|
||||||
|
To uninstall libinput as detailed in section @ref reverting_install, run
|
||||||
|
|
||||||
|
@code
|
||||||
|
$> sudo make uninstall
|
||||||
|
# WARNING: Do not restart the computer/X/the Wayland compositor after make
|
||||||
|
# uninstall, reinstall the system package immediately!
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
To disable libwacom as detailed in section @ref building_libwacom, run
|
||||||
|
|
||||||
|
@code
|
||||||
|
$> ./autogen.sh --disable-libwacom --prefix=/usr --libdir=/usr/lib64
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
To disable the graphical helper tool as detailed in section @ref
|
||||||
|
building_debug_gui, run
|
||||||
|
|
||||||
|
@code
|
||||||
|
$> ./autogen.sh --disable-debug-gui --prefix=/usr --libdir=/usr/lib64
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@section building_against Building against libinput
|
||||||
|
|
||||||
|
libinput provides a
|
||||||
|
[pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/) file.
|
||||||
|
Software that uses libinput should use pkg-config and the
|
||||||
|
`PKG_CHECK_MODULES` autoconf macro.
|
||||||
|
Otherwise, the most rudimentary way to compile and link a program against
|
||||||
|
libinput is:
|
||||||
|
|
||||||
|
@code
|
||||||
|
gcc -o myprogram myprogram.c `pkg-config --cflags --libs libinput`
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
For further information on using pkgconfig see the pkg-config documentation.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 78 KiB |
|
|
@ -1,9 +1,6 @@
|
||||||
|
/**
|
||||||
|
|
||||||
.. _button_debouncing:
|
@page button_debouncing Button debouncing
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
Button debouncing
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
Physical buttons experience wear-and-tear with usage. On some devices this
|
Physical buttons experience wear-and-tear with usage. On some devices this
|
||||||
can result in an effect called "contact bouncing" or "chatter". This effect
|
can result in an effect called "contact bouncing" or "chatter". This effect
|
||||||
|
|
@ -32,8 +29,8 @@ immediately and most release events are delivered immediately. The
|
||||||
does not enable this method unless a faulty event sequence is detected. A
|
does not enable this method unless a faulty event sequence is detected. A
|
||||||
message is printed to the log when spurious deboucing was detected.
|
message is printed to the log when spurious deboucing was detected.
|
||||||
|
|
||||||
libinput's debouncing is supposed to correct hardware damage or
|
Note that libinput's debouncing intended to correct hardware damage or
|
||||||
substandard hardware. Debouncing also exists as an accessibility feature
|
substandard hardware. Debouncing is also used as an accessibility feature
|
||||||
but the requirements are different. In the accessibility feature, multiple
|
but the requirements are different. In the accessibility feature, multiple
|
||||||
physical key presses, usually caused by involuntary muscle movement, must be
|
physical key presses, usually caused by involuntary muscle movement, must be
|
||||||
filtered to only one key press. This feature must be implemented higher in
|
filtered to only one key press. This feature must be implemented higher in
|
||||||
|
|
@ -45,12 +42,6 @@ extra line is added to show the timeouts used by libinput that
|
||||||
affect the button state handling. The waveform's high and low states
|
affect the button state handling. The waveform's high and low states
|
||||||
correspond to the buttons 'pressed' and 'released' states, respectively.
|
correspond to the buttons 'pressed' and 'released' states, respectively.
|
||||||
|
|
||||||
.. figure:: button-debouncing-wave-diagram.svg
|
@image html button-debouncing-wave-diagram.svg "Diagram illustrating button debouncing"
|
||||||
:align: center
|
|
||||||
|
|
||||||
Diagram illustrating button debouncing
|
*/
|
||||||
|
|
||||||
|
|
||||||
Some devices send events in bursts, erroneously triggering the button
|
|
||||||
debouncing detection. Please :ref:`file a bug <reporting_bugs>` if that
|
|
||||||
occurs for your device.
|
|
||||||
103
doc/clickpad-softbuttons.dox
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
/**
|
||||||
|
@page clickpad_softbuttons Clickpad software button behavior
|
||||||
|
|
||||||
|
Clickpad is the name given to touchpads without physical buttons below the
|
||||||
|
touchpad. Instead, the whole touchpad acts as a button and left or right
|
||||||
|
button clicks are distinguished by the location and/or number of fingers on
|
||||||
|
the touchpad. <a href="http://www.synaptics.com/en/clickpad.php">"ClickPad" is
|
||||||
|
a trademark by Synaptics Inc.</a> but for simplicity we refer to any
|
||||||
|
touchpad with the above feature as Clickpad, regardless of the manufacturer.
|
||||||
|
|
||||||
|
A clickpad is always marked with the <a
|
||||||
|
href="https://www.kernel.org/doc/Documentation/input/event-codes.txt">INPUT_PROP_BUTTONPAD</a> property.
|
||||||
|
To perform a right-click on a Clickpad, libinput provides @ref
|
||||||
|
software_buttons and @ref clickfinger.
|
||||||
|
|
||||||
|
In the page below, the term "click" shall refer to a physical button press
|
||||||
|
and/or release of the touchpad, the term "button event" refers to the events
|
||||||
|
generated by libinput and passed to the caller in response to a click.
|
||||||
|
|
||||||
|
@section software_buttons Software button areas
|
||||||
|
|
||||||
|
On most clickpads, this is the default behavior. The bottom of the touchpad
|
||||||
|
is split into three distinct areas generate left, middle or right button
|
||||||
|
events on click. The height of the button area depends on the hardware but
|
||||||
|
is usually around 10mm.
|
||||||
|
|
||||||
|
Left, right and middle button events can be triggered as follows:
|
||||||
|
- if a finger is in the main area or the left button area, a click generates
|
||||||
|
left button events.
|
||||||
|
- if a finger is in the right area, a click generates right button events.
|
||||||
|
- if a finger is in the middle area, a click generates middle button events.
|
||||||
|
|
||||||
|
The middle button is always centered on the touchpad and smaller in size
|
||||||
|
than the left or right button. The actual size is device-dependent though as
|
||||||
|
many touchpads do not have visible markings for the middle button the exact
|
||||||
|
location of the button is not visibly obvious.
|
||||||
|
|
||||||
|
@image html software-buttons.svg "Left, right and middle-button click with software button areas"
|
||||||
|
|
||||||
|
@note If middle button emulation is enabled on a clickpad, only left and right
|
||||||
|
button areas are available. For more details, see
|
||||||
|
libinput_device_config_middle_emulation_set_enabled().
|
||||||
|
|
||||||
|
If fingers are down in the main area in addition to fingers in the
|
||||||
|
left or right button area, those fingers are are ignored.
|
||||||
|
A release event always releases the buttons logically down, regardless of
|
||||||
|
the current finger position
|
||||||
|
|
||||||
|
The movement of a finger can alter the button area behavior:
|
||||||
|
- if a finger starts in the main area and moves into the software button
|
||||||
|
area, the software buttons do not apply to that finger
|
||||||
|
- a finger in the software button area does not move the pointer
|
||||||
|
- if a finger moves out out of the button area it will control the pointer
|
||||||
|
if it's the first finger in the main area
|
||||||
|
- once a finger has moved out of the button area, it cannot move back in and
|
||||||
|
trigger a right or middle button event
|
||||||
|
|
||||||
|
On some touchpads, notably the 2015 Lenovo X1 Carbon 3rd series, the very
|
||||||
|
bottom end of the touchpad is outside of the sensor range but it is possible
|
||||||
|
to trigger a physical click there. To libinput, the click merely shows up as
|
||||||
|
a left button click without any positional finger data and it is
|
||||||
|
impossible to determine whether it is a left or a right click. libinput
|
||||||
|
ignores such button clicks, this behavior is intentional.
|
||||||
|
|
||||||
|
@section clickfinger Clickfinger behavior
|
||||||
|
|
||||||
|
This is the default behavior on Apple touchpads.
|
||||||
|
Here, a left, right, middle button event is generated when one, two, or
|
||||||
|
three fingers are held down on the touchpad when a physical click is
|
||||||
|
generated. The location of the fingers does not matter and there are no
|
||||||
|
software-defined button areas.
|
||||||
|
|
||||||
|
@image html clickfinger.svg "One, two and three-finger click with Clickfinger behavior"
|
||||||
|
|
||||||
|
On some touchpads, libinput imposes a limit on how the fingers may be placed
|
||||||
|
on the touchpad. In the most common use-case this allows for a user to
|
||||||
|
trigger a click with the thumb while leaving the pointer-moving finger on
|
||||||
|
the touchpad.
|
||||||
|
|
||||||
|
@image html clickfinger-distance.svg "Illustration of the distance detection algorithm"
|
||||||
|
|
||||||
|
In the illustration above the red area marks the proximity area around the
|
||||||
|
first finger. Since the thumb is outside of that area libinput considers the
|
||||||
|
click a single-finger click rather than a two-finger click.
|
||||||
|
|
||||||
|
Clickfinger configuration can be enabled through the
|
||||||
|
libinput_device_config_click_set_method() call. If clickfingers are
|
||||||
|
enabled on a touchpad with top software buttons, the top area will keep
|
||||||
|
acting as softbuttons for use with the trackpoint. Clickfingers will be used
|
||||||
|
everywhere else on the touchpad.
|
||||||
|
|
||||||
|
@section special_clickpads Special Clickpads
|
||||||
|
|
||||||
|
The Lenovo *40 series laptops have a clickpad that provides two software button sections, one at
|
||||||
|
the top and one at the bottom. See @ref t440_support "Lenovo *40 series touchpad support"
|
||||||
|
for details on the top software button.
|
||||||
|
|
||||||
|
Some Clickpads, notably some Cypress ones, perform right button detection in
|
||||||
|
firmware and appear to userspace as if the touchpad had physical buttons.
|
||||||
|
While physically clickpads, these are not handled by the software and
|
||||||
|
treated like traditional touchpads.
|
||||||
|
|
||||||
|
*/
|
||||||
18
doc/contributing.dox
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
/**
|
||||||
|
|
||||||
|
@page contributing Contributing to libinput
|
||||||
|
|
||||||
|
Contributions to libinput are always welcome. Any patches should be sent to
|
||||||
|
the
|
||||||
|
[wayland-devel](https://lists.freedesktop.org/mailman/listinfo/wayland-devel)
|
||||||
|
email list with a subject prefix of ````[PATCH libinput]````. The easiest
|
||||||
|
way to achieve that is to run the following command in the libinput
|
||||||
|
repository:
|
||||||
|
|
||||||
|
git config --add format.subjectprefix "PATCH libinput"
|
||||||
|
|
||||||
|
Likewise, any new features should also be discussed publicly on the
|
||||||
|
wayland-devel list.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
303
doc/device-configuration-via-udev.dox
Normal file
|
|
@ -0,0 +1,303 @@
|
||||||
|
/**
|
||||||
|
@page udev_config Static device configuration via udev
|
||||||
|
|
||||||
|
libinput supports some static configuration through udev properties.
|
||||||
|
These properties are read when the device is initially added
|
||||||
|
to libinput's device list, i.e. before the @ref
|
||||||
|
LIBINPUT_EVENT_DEVICE_ADDED event is generated.
|
||||||
|
|
||||||
|
The following udev properties are supported:
|
||||||
|
<dl>
|
||||||
|
<dt>LIBINPUT_CALIBRATION_MATRIX</dt>
|
||||||
|
<dd>Sets the calibration matrix, see
|
||||||
|
libinput_device_config_calibration_get_default_matrix(). If unset,
|
||||||
|
defaults to the identity matrix.
|
||||||
|
|
||||||
|
The udev property is parsed as 6 floating point numbers separated by a
|
||||||
|
single space each (scanf(3) format "%f %f %f %f %f %f").
|
||||||
|
The 6 values represent the first two rows of the calibration matrix as
|
||||||
|
described in libinput_device_config_calibration_set_matrix().
|
||||||
|
|
||||||
|
Example values are:
|
||||||
|
@code
|
||||||
|
ENV{LIBINPUT_CALIBRATION_MATRIX}="1 0 0 0 1 0" # default
|
||||||
|
ENV{LIBINPUT_CALIBRATION_MATRIX}="0 -1 1 1 0 0" # 90 degree clockwise
|
||||||
|
ENV{LIBINPUT_CALIBRATION_MATRIX}="-1 0 1 0 -1 1" # 180 degree clockwise
|
||||||
|
ENV{LIBINPUT_CALIBRATION_MATRIX}="0 1 0 -1 0 1" # 270 degree clockwise
|
||||||
|
ENV{LIBINPUT_CALIBRATION_MATRIX}="-1 0 1 0 1 0" # reflect along y axis
|
||||||
|
@endcode
|
||||||
|
</dd>
|
||||||
|
<dt>LIBINPUT_DEVICE_GROUP</dt>
|
||||||
|
<dd>A string identifying the @ref libinput_device_group for this device. Two
|
||||||
|
devices with the same property value are grouped into the same device group,
|
||||||
|
the value itself is irrelevant otherwise.
|
||||||
|
</dd>
|
||||||
|
<dt>LIBINPUT_IGNORE_DEVICE</dt>
|
||||||
|
<dd>If set to anything other than "0", the device is ignored by libinput.
|
||||||
|
See @ref ignoring_devices for more details.
|
||||||
|
</dd>
|
||||||
|
<dt>ID_SEAT</dt>
|
||||||
|
<dd>Assigns the physical @ref seats "seat" for this device. See
|
||||||
|
libinput_seat_get_physical_name(). Defaults to "seat0".</dd>
|
||||||
|
<dt>ID_INPUT</dt>
|
||||||
|
<dd>If this property is set, the device is considered an input device. Any
|
||||||
|
device with this property missing will be ignored, see @ref
|
||||||
|
udev_device_type.</dt>
|
||||||
|
</dd>
|
||||||
|
<dt>ID_INPUT_KEYBOARD, ID_INPUT_KEY, ID_INPUT_MOUSE, ID_INPUT_TOUCHPAD,
|
||||||
|
ID_INPUT_TOUCHSCREEN, ID_INPUT_TABLET, ID_INPUT_JOYSTICK,
|
||||||
|
ID_INPUT_ACCELEROMETER</dt>
|
||||||
|
<dd>If any of the above is set, libinput initializes the device as the given
|
||||||
|
type, see @ref udev_device_type. Note that for historical reasons more than
|
||||||
|
one of these may be set at any time, libinput will select only one of these
|
||||||
|
to determine the device type. To ensure libinput selects the correct device
|
||||||
|
type, only set one of them.</dd>
|
||||||
|
<dt>WL_SEAT</dt>
|
||||||
|
<dd>Assigns the logical @ref seats "seat" for this device. See
|
||||||
|
libinput_seat_get_logical_name()
|
||||||
|
context. Defaults to "default".</dd>
|
||||||
|
<dt>MOUSE_DPI</dt>
|
||||||
|
<dd>HW resolution and sampling frequency of a relative pointer device.
|
||||||
|
See @ref motion_normalization for details.
|
||||||
|
</dd>
|
||||||
|
<dt>MOUSE_WHEEL_CLICK_ANGLE</dt>
|
||||||
|
<dd>The angle in degrees for each click on a mouse wheel. See
|
||||||
|
libinput_pointer_get_axis_source() for details.
|
||||||
|
</dd>
|
||||||
|
<dt>LIBINPUT_MODEL_*</dt>
|
||||||
|
<dd><b>This prefix is reserved as private API, do not use.</b> See @ref
|
||||||
|
model_specific_configuration for details.
|
||||||
|
</dd>
|
||||||
|
<dt>LIBINPUT_ATTR_*</dt>
|
||||||
|
<dd><b>This prefix is reserved as private API, do not use.</b> See @ref
|
||||||
|
model_specific_configuration for details.
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
Below is an example udev rule to assign "seat1" to a device from vendor
|
||||||
|
0x012a with the model ID of 0x034b.
|
||||||
|
@code
|
||||||
|
ACTION=="add|change", KERNEL=="event[0-9]*", ENV{ID_VENDOR_ID}=="012a", \
|
||||||
|
ENV{ID_MODEL_ID}=="034b", ENV{ID_SEAT}="seat1"
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@section udev_device_type Device type assignment via udev
|
||||||
|
|
||||||
|
libinput requires the <b>ID_INPUT</b> property to be set on a device,
|
||||||
|
otherwise the device will be ignored. In addition, one of <b>
|
||||||
|
ID_INPUT_KEYBOARD, ID_INPUT_KEY, ID_INPUT_MOUSE, ID_INPUT_TOUCHPAD,
|
||||||
|
ID_INPUT_TOUCHSCREEN, ID_INPUT_TABLET, ID_INPUT_JOYSTICK,
|
||||||
|
ID_INPUT_ACCELEROMETER</b> must be set on the device to determine the
|
||||||
|
device type. The usual error handling applies within libinput and a device
|
||||||
|
type label does not guarantee that the device is initialized by libinput.
|
||||||
|
If a device fails to meet the requirements for a device type (e.g. a keyboard
|
||||||
|
labelled as touchpad) the device will not be available through libinput.
|
||||||
|
|
||||||
|
Only one device type should be set per device at a type, though libinput can
|
||||||
|
handle some combinations for historical reasons.
|
||||||
|
|
||||||
|
Below is an example udev rule to remove an <b>ID_INPUT_TOUCHPAD</b> setting
|
||||||
|
and change it into an <b>ID_INPUT_TABLET</b> setting. This rule would apply
|
||||||
|
for a device with the vendor/model ID of 012a/034b.
|
||||||
|
|
||||||
|
@code
|
||||||
|
ACTION=="add|change", KERNEL=="event[0-9]*", ENV{ID_VENDOR_ID}=="012a", \
|
||||||
|
ENV{ID_MODEL_ID}=="034b", ENV{ID_INPUT_TOUCHPAD}="", ENV{ID_INPUT_TABLET}="1"
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@section ignoring_devices Ignoring specific devices
|
||||||
|
|
||||||
|
If a device has the <b>LIBINPUT_IGNORE_DEVICE</b> udev property set to any
|
||||||
|
value but "0", that device is not initialized by libinput. For a context
|
||||||
|
created with libinput_udev_create_context(), the device is silently ignored
|
||||||
|
and never shows up. If the device is added with libinput_path_add_device()
|
||||||
|
to a context created with libinput_path_create_context(), adding the device
|
||||||
|
will fail and return NULL (see that function's documentation for more
|
||||||
|
information).
|
||||||
|
|
||||||
|
If the property value is exactly "0", then the property is considered unset
|
||||||
|
and libinput initializes the device normally.
|
||||||
|
|
||||||
|
This property should be used for devices that are correctly detected as
|
||||||
|
input devices (see @ref udev_device_type) but that should not be used by
|
||||||
|
libinput. It is recommended that devices that should not be handled as input
|
||||||
|
devices at all unset the <b>ID_INPUT</b> and related properties instead. The
|
||||||
|
<b>LIBINPUT_IGNORE_DEVICE</b> property signals that only libinput should
|
||||||
|
ignore this property but other parts of the stack (if any) should continue
|
||||||
|
treating this device normally.
|
||||||
|
|
||||||
|
|
||||||
|
@section model_specific_configuration Model-specific configuration
|
||||||
|
|
||||||
|
libinput reserves the property prefixes <b>LIBINPUT_MODEL_</b> and
|
||||||
|
<b>LIBINPUT_ATTR_</b> for model-specific configuration. <b>These prefixes
|
||||||
|
are reserved as private API, do not use.</b>
|
||||||
|
|
||||||
|
The effect of these properties may be to enable or disable certain
|
||||||
|
features on a specific device or set of devices, to change configuration
|
||||||
|
defaults or any other reason. The effects of setting these properties, the
|
||||||
|
format of the property and the value of the property are subject to change
|
||||||
|
at any time.
|
||||||
|
|
||||||
|
@subsection model_specific_configuration_x220fw81 Lenovo x220 with touchpad firmware v8.1
|
||||||
|
|
||||||
|
The property <b>LIBINPUT_MODEL_LENOVO_X220_TOUCHPAD_FW81</b> may be set by a
|
||||||
|
user in a local hwdb file. This property designates the touchpad on a Lenovo
|
||||||
|
x220 with a touchpad firmware version 8.1. When this firmware version is
|
||||||
|
installed, the touchpad is imprecise. The touchpad device does not send
|
||||||
|
continuos x/y axis position updates, a behavior also observed on its
|
||||||
|
successor model, the Lenovo x230 which has the same firmware version. If the
|
||||||
|
above property is set, libinput adjusts its behavior to better suit this
|
||||||
|
particular model.
|
||||||
|
|
||||||
|
The touchpad firmware version cannot be detected automatically by libinput,
|
||||||
|
local configuration is required to set this property. Refer to the libinput
|
||||||
|
model quirks hwdb for instructions.
|
||||||
|
|
||||||
|
This property must not be used for any other purpose, no specific behavior
|
||||||
|
is guaranteed.
|
||||||
|
|
||||||
|
|
||||||
|
@section hwdb Configuring the hwdb
|
||||||
|
|
||||||
|
This section outlines how to add an entry to the <a
|
||||||
|
href="https://www.freedesktop.org/software/systemd/man/hwdb.html">udev
|
||||||
|
hwdb</a> and reload properties so they are available to libinput.
|
||||||
|
|
||||||
|
The hwdb contains a set of match rules that assign udev properties that are
|
||||||
|
available to libinput when the device is connected and/or libinput is
|
||||||
|
initialized. This section only describes the hwdb in relation to libinput,
|
||||||
|
it is not a full documentation on how the hwdb works.
|
||||||
|
|
||||||
|
@note **The use of the hwdb by libinput is not part of the public API. It may
|
||||||
|
change at any time. Once tested, changes to the hwdb must be submitted
|
||||||
|
upstream.**
|
||||||
|
|
||||||
|
@subsection hwdb_querying Querying the hwdb
|
||||||
|
|
||||||
|
libinput only uses device nodes in the form of `/dev/input/eventX` where X
|
||||||
|
is the number of the specific device. Running `libinput debug-events` lists
|
||||||
|
all devices currently available to libinput and their event node name:
|
||||||
|
|
||||||
|
$> sudo libinput debug-events
|
||||||
|
-event2 DEVICE_ADDED Power Button seat0 default group1 cap:k
|
||||||
|
-event5 DEVICE_ADDED Video Bus seat0 default group2 cap:k
|
||||||
|
-event0 DEVICE_ADDED Lid Switch seat0 default group3 cap:S
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
Note the event node name for your device and translate it into a syspath in
|
||||||
|
the form of `/sys/class/input/eventX`. This path can be supplied to `udevadm
|
||||||
|
info`
|
||||||
|
|
||||||
|
$> udevadm info
|
||||||
|
P: /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0D:00/input/input0/event0
|
||||||
|
N: input/event0
|
||||||
|
E: DEVNAME=/dev/input/event0
|
||||||
|
E: DEVPATH=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0D:00/input/input0/event0
|
||||||
|
E: ID_INPUT=1
|
||||||
|
E: ID_INPUT_SWITCH=1
|
||||||
|
E: MAJOR=13
|
||||||
|
E: MINOR=64
|
||||||
|
E: SUBSYSTEM=input
|
||||||
|
E: TAGS=:power-switch:
|
||||||
|
E: USEC_INITIALIZED=7167898
|
||||||
|
|
||||||
|
Lines starting with `E:` are udev properties available to libinput. For
|
||||||
|
example, the above device's `ID_INPUT_SWITCH` property will cause libinput
|
||||||
|
to treat this device as switch device.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection hwdb_reloading Reloading the hwdb
|
||||||
|
|
||||||
|
The actual hwdb is stored in binary file on-disk and must be updated
|
||||||
|
manually whenever a `.hwdb` file changes. This is required both when a user
|
||||||
|
manually edits the `.hwdb` file but also when the git tree is updated (and
|
||||||
|
that update causes a hwdb change).
|
||||||
|
|
||||||
|
To update the binary file on-disk, run:
|
||||||
|
|
||||||
|
sudo udevadm hwdb --update
|
||||||
|
|
||||||
|
Then, to trigger a reload of all properties on your device, run:
|
||||||
|
|
||||||
|
sudo udevadm trigger /sys/class/input/eventX
|
||||||
|
|
||||||
|
Then check with `udevadm info` whether the properties were updated, see @ref
|
||||||
|
hwdb_querying. If a new property does not appear on the device, use `udevadm
|
||||||
|
test` to check for error messages by udev and the hwdb (e.g. syntax errors
|
||||||
|
in the udev rules files).
|
||||||
|
|
||||||
|
sudo udevadm test /sys/class/input/eventX
|
||||||
|
|
||||||
|
@subsection hwdb_modifying Modifying the hwdb
|
||||||
|
|
||||||
|
This section applies to users that need to add, change, or remove a hwdb
|
||||||
|
entry for their device. Note that **the hwdb is not part of the public API
|
||||||
|
and may change at any time**. Once a device has been made to work, the
|
||||||
|
change must be submitted to the libinput bugzilla, see @ref reporting_bugs.
|
||||||
|
|
||||||
|
hwdb entries are only applied if a udev rules calls out to the hwdb with the
|
||||||
|
right match format. libinput ships with a set of rules to query the hwdb,
|
||||||
|
the different rules are reflected by their prefix. Again, **this is not part
|
||||||
|
of the public API**. libinput's matches are
|
||||||
|
composed of a literal "libinput", then either the device name and dmi
|
||||||
|
modalias, or the device types and the input modalias. Any part of the hwdb
|
||||||
|
match line can be a glob by using a literal `*`. For example:
|
||||||
|
|
||||||
|
libinput:keyboard:input:b0011v*
|
||||||
|
libinput:touchpad:input:b0003v05ACp*
|
||||||
|
libinput:touchpad:input:b0003v05ACp021A*
|
||||||
|
|
||||||
|
This type of matching is the preferred one for any removable device (USB,
|
||||||
|
Bluetooth, ...) that can be uniquely identified by the bustype, vendor and
|
||||||
|
product ID. The first line matches any keyboard device on the
|
||||||
|
serial bus (0x0011). The second line matches any touchpad device
|
||||||
|
with a vendor ID of 0x05AC. The third line matches any touchpad device
|
||||||
|
with a vendor ID of 0x05AC and a product ID of 0x021A. The `input:b...`
|
||||||
|
string is available in the device's modalias file
|
||||||
|
`/sys/class/input/eventX/device/modalias`.
|
||||||
|
|
||||||
|
In the case of built-in devices that do not have a unique id, we
|
||||||
|
need to use the host system's dmi information. For example:
|
||||||
|
|
||||||
|
libinput:name:*Lid Switch*:dmi:*svnLENOVO:*pvrThinkPadT440*
|
||||||
|
|
||||||
|
This match applies to any device with a name **containing** "Led Switch"
|
||||||
|
that is on a Lenovo T440 system. The dmi modalias is available in
|
||||||
|
`/sys/class/dmi/id/modalias`. For example, on the T440 matched above, the
|
||||||
|
modalias is
|
||||||
|
|
||||||
|
dmi:bvnLENOVO:bvrGJET72WW(2.22):bd02/21/2014:svnLENOVO:pn3453453678:pvrThinkPadT440s:rvnLENOVO:rn2012345223:rvrABC123KKK123B:cvnLENOVO:ct10:cvrNotAvailable:
|
||||||
|
|
||||||
|
The dmi should always be shortened to the sections that uniquely identify
|
||||||
|
the type system, in this case the vendor (svn) and the product version (pvr).
|
||||||
|
Failing to shorten the system may mean that the hwdb match rule only applies
|
||||||
|
to your specific system, rather than all systems of that type, or that the
|
||||||
|
rule no longer applies after a firmware update.
|
||||||
|
|
||||||
|
The hwdb match string is the first portion of the hwdb entry. The second
|
||||||
|
portion is the property to set. Each hwdb entry may match on multiple
|
||||||
|
devices and may apply multiple properties. For example:
|
||||||
|
|
||||||
|
|
||||||
|
libinput:touchpad:input:b0003v05ACp*
|
||||||
|
THIS_IS_AN_APPLE_DEVICE=1
|
||||||
|
|
||||||
|
libinput:touchpad:input:b0003v05ACp*
|
||||||
|
libinput:name:*Lid Switch*:dmi:*svnLENOVO:*pvrThinkPadT440*
|
||||||
|
FOO=1
|
||||||
|
BAR=2
|
||||||
|
|
||||||
|
In the example above, any matching touchpad device will have all three
|
||||||
|
properties applied, the lid switch device only has FOO and BAR.
|
||||||
|
|
||||||
|
The hwdb does not allow removing properties. Where a property must be unset,
|
||||||
|
it should be set to 0.
|
||||||
|
|
||||||
|
Any user-specific hwdb entries should be placed in a file
|
||||||
|
`/etc/udev/hwdb.d/99-somename.hwdb`. See @ref hwdb_reloading for
|
||||||
|
instructions on how to reload the hwdb once the file is in place.
|
||||||
|
*/
|
||||||
223
doc/faqs.dox
Normal file
|
|
@ -0,0 +1,223 @@
|
||||||
|
/**
|
||||||
|
@page faq FAQs - Frequently Asked Questions
|
||||||
|
|
||||||
|
Frequently asked questions about libinput.
|
||||||
|
|
||||||
|
@tableofcontents
|
||||||
|
|
||||||
|
@section faq_feature Why doesn't libinput support ...?
|
||||||
|
|
||||||
|
First, read @ref what_is_libinput If you have a feature that you think
|
||||||
|
libinput needs to support, please file a bug report. See @ref reporting_bugs
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
@section faq_fast_mouse My mouse moves too fast, even at the slowest setting
|
||||||
|
|
||||||
|
This is a symptom of high-dpi mice (greater than 1000dpi). These devices
|
||||||
|
need a udev hwdb entry to normalize their motion. See @ref
|
||||||
|
motion_normalization for a detailed explanation.
|
||||||
|
|
||||||
|
@section faq_fast_trackpoint My trackpoint moves too slow or too fast
|
||||||
|
|
||||||
|
This is a symptom of an invalid trackpoint range. These devices need a udev
|
||||||
|
hwdb entry to specify the range available so libinput can adjust the pointer
|
||||||
|
acceleration accordingly. See @ref trackpoint_range for a detailed explanation.
|
||||||
|
|
||||||
|
@section faq_enable_tapping Why isn't touchpad tap-to-click enabled by default
|
||||||
|
|
||||||
|
See @ref tapping_default
|
||||||
|
|
||||||
|
@section faq_touchpad_pressure Why does my touchpad lose track of touches
|
||||||
|
|
||||||
|
The most common cause for this is an incorrect pressure threshold range.
|
||||||
|
See @ref touchpad_pressure for more info.
|
||||||
|
|
||||||
|
@section faq_kinetic_scrolling Kinetic scrolling does not work
|
||||||
|
|
||||||
|
The X.Org synaptics driver implemented kinetic scrolling in the driver. It
|
||||||
|
measures the scroll speed and once the finger leaves the touchpad the driver
|
||||||
|
keeps sending scroll events for a predetermined time. This effectively
|
||||||
|
provides for kinetic scrolling without client support but triggers an
|
||||||
|
unfixable [bug](https://bugs.freedesktop.org/show_bug.cgi?id=38909): the
|
||||||
|
client cannot know that the events are from a kinetic scroll source. Scroll
|
||||||
|
events in X are always sent to the current cursor position, a movement of the
|
||||||
|
cursor after lifting the finger will send the kinetic scroll events to the
|
||||||
|
new client, something the user does not usually expect. A key event during
|
||||||
|
the kinetic scroll procedure causes side-effects such as triggering zoom.
|
||||||
|
|
||||||
|
libinput does not implement kinetic scrolling for touchpads. Instead it
|
||||||
|
provides the libinput_event_pointer_get_axis_source() function that enables
|
||||||
|
callers to implement kinetic scrolling on a per-widget basis, see @ref
|
||||||
|
scroll_sources.
|
||||||
|
|
||||||
|
@section faq_gpl Is libinput GPL-licensed?
|
||||||
|
|
||||||
|
No, libinput is MIT licensed. The Linux kernel header file linux/input.h in
|
||||||
|
libinput's tree is provided to ensure the same behavior regardless of which
|
||||||
|
kernel version libinput is built on. It does not make libinput GPL-licensed.
|
||||||
|
|
||||||
|
@section faq_config_options Where is the configuration stored?
|
||||||
|
|
||||||
|
libinput does not store configuration options, it is up to the caller to
|
||||||
|
manage these and decide which configuration option to apply to each device.
|
||||||
|
This must be done at startup, after a resume and whenever a new device is
|
||||||
|
detected.
|
||||||
|
|
||||||
|
One commonly used way to configure libinput is to have the Wayland
|
||||||
|
compositor expose a compositor-specific configuration option. For example,
|
||||||
|
in a GNOME stack, the gnome-control-center modifies dconf entries. These
|
||||||
|
changes are read by mutter and applied to libinput. Changing these entries
|
||||||
|
via the gsettings commandline tool has the same effect.
|
||||||
|
|
||||||
|
Another commonly used way to configure libinput is to have xorg.conf.d
|
||||||
|
snippets. When libinput is used with the xf86-input-libinput driver in an
|
||||||
|
X.Org stack, these options are read on startup and apply to each device.
|
||||||
|
Changing properties at runtime with the xinput commandline tool has the same
|
||||||
|
effect.
|
||||||
|
|
||||||
|
In both cases, the selection of available options and how they are exposed
|
||||||
|
depends on the libinput caller (e.g. mutter or xf86-input-libinput).
|
||||||
|
|
||||||
|
@dotfile libinput-stack-gnome.gv
|
||||||
|
|
||||||
|
This has an effect on the availability of configuration options: if an
|
||||||
|
option is not exposed by the intermediary, it cannot be configured by the
|
||||||
|
client. Also some configuration options that are provided by the
|
||||||
|
intermediary may not be libinput-specific configuration options.
|
||||||
|
|
||||||
|
@section faq_configure_wayland How do I configure my device on Wayland?
|
||||||
|
|
||||||
|
See @ref faq_config_options Use the configuration tool provided by your
|
||||||
|
desktop environment (e.g. gnome-control-center) or direct access to your
|
||||||
|
desktop environment's configuration storage (e.g. gsettings).
|
||||||
|
|
||||||
|
@section faq_configure_xorg How do I configure my device on X?
|
||||||
|
|
||||||
|
See @ref faq_config_options If your desktop environment does not provide a
|
||||||
|
graphical configuration tool you can use an
|
||||||
|
<a href="https://www.x.org/archive/current/doc/man/man5/xorg.conf.5.xhtml">xorg.conf.d snippet</a>.
|
||||||
|
Usually, such a snippet looks like this:
|
||||||
|
<pre>
|
||||||
|
$> cat /etc/X11/xorg.conf.d/99-libinput-custom-config.conf
|
||||||
|
Section "InputClass"
|
||||||
|
Identifier "something to identify this snippet"
|
||||||
|
MatchDriver "libinput"
|
||||||
|
MatchProduct "substring of the device name"
|
||||||
|
Option "some option name" "the option value"
|
||||||
|
EndSection
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
The identifier is merely a human-readable string that shows up in the log
|
||||||
|
file. The MatchProduct line should contain the device name or a substring of
|
||||||
|
the device name that the snippet should apply to. For a full list of option
|
||||||
|
names and permitted values, see the
|
||||||
|
<a href="https://www.mankier.com/4/libinput">libinput man page</a>.
|
||||||
|
xorg.conf.d snippets like the above apply to hotplugged devices but can be
|
||||||
|
overwritten at runtime by desktop tools. Multiple snippets may be placed
|
||||||
|
into the same file.
|
||||||
|
|
||||||
|
For run-time configuration and testing, the
|
||||||
|
<a href="https://www.x.org/archive/X11R7.5/doc/man/man1/xinput.1.html">xinput</a>
|
||||||
|
debugging tool can modify a devices' properties. See the
|
||||||
|
<a href="https://www.mankier.com/4/libinput">libinput man page</a>
|
||||||
|
for supported property names and values. Usually, an invocation looks like
|
||||||
|
this:
|
||||||
|
<pre>
|
||||||
|
$> xinput set-prop "the device name" "the property name" value [value2] [value3]
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
@note
|
||||||
|
Changes performed by xinput do not persist across device hotplugs. xinput is
|
||||||
|
considered a debugging and testing tool only and should not be used for
|
||||||
|
permanent configurations.
|
||||||
|
|
||||||
|
@section faq_configuration Can you add a configuration option for $FEATURE?
|
||||||
|
|
||||||
|
No. At least that's going to be the initial answer. Read <a
|
||||||
|
href="http://who-t.blogspot.com/2016/04/why-libinput-doesnt-have-lot-of-config.html">Why
|
||||||
|
libinput doesn't have a lot of configuration options</a> first.
|
||||||
|
Configuration options for most features are a signal that we are incapable
|
||||||
|
of handling it correctly. To get to that point, we want to be sure we're
|
||||||
|
truly incapable of doing so. libinput has several features that
|
||||||
|
are handled automatically (and correctly) that users wanted to have
|
||||||
|
configuration options for initially.
|
||||||
|
|
||||||
|
So the answer to this question will almost always be 'no'. A configuration
|
||||||
|
option is, in most cases, a cop-out.
|
||||||
|
|
||||||
|
@section faq_synclient Why don't synclient and syndaemon work with libinput?
|
||||||
|
|
||||||
|
Synclient and syndaemon rely on X input device properties that are specific
|
||||||
|
to the xf86-input-synaptics X.Org input driver. Both were written when the
|
||||||
|
synaptics driver was the only commmon touchpad driver in existence. They
|
||||||
|
assume that if the properties aren't available, no touchpad is available
|
||||||
|
either. The xf86-input-libinput X.Org input driver does not export these
|
||||||
|
driver-specific properties, synclient/syndaemon will thus not detect the
|
||||||
|
touchpad and refuse to work. Other tools that rely on synclient/syndaemon or
|
||||||
|
those same properties also do not work with xf86-input-libinput.
|
||||||
|
|
||||||
|
Most of syndaemon's functionality is built into libinput, see @ref
|
||||||
|
disable-while-typing. synclient is merely a configuration tool, see
|
||||||
|
@ref faq_configure_xorg for similar functionality.
|
||||||
|
|
||||||
|
See also the blog posts
|
||||||
|
<a
|
||||||
|
href="http://who-t.blogspot.com.au/2017/01/the-definitive-guide-to-synclient.html">The
|
||||||
|
definitive guide to synclient</a> and
|
||||||
|
<a href="http://who-t.blogspot.com.au/2016/12/the-future-of-xinput-xmodmap-setxkbmap.html">
|
||||||
|
The future of xinput, xmodmap, setxkbmap, xsetwacom and other tools under
|
||||||
|
Wayland</a>
|
||||||
|
|
||||||
|
@section faq_tablets Does libinput support non-Wacom tablets?
|
||||||
|
|
||||||
|
Yes, though unfortunately many non-Wacom tablets suffer from bad firmware
|
||||||
|
and don't send the required events. But they should all work nonetheless. If
|
||||||
|
you have a tablet that does not work with libinput, please @ref
|
||||||
|
reporting_bugs "file a bug".
|
||||||
|
|
||||||
|
@section faq_tablet_capabilities My tablet doesn't work
|
||||||
|
|
||||||
|
If you see the message
|
||||||
|
<pre>
|
||||||
|
libinput bug: device does not meet tablet criteria. Ignoring this device.
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
or the message
|
||||||
|
<pre>
|
||||||
|
missing tablet capabilities [...] Ignoring this device.
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
your tablet device does not have the required capabilities to be treated as
|
||||||
|
a tablet. This is usually a problem with the device and the kernel driver.
|
||||||
|
See @ref tablet-capabilities for more details.
|
||||||
|
|
||||||
|
@section faq_hwdb_changes How to apply hwdb changes
|
||||||
|
|
||||||
|
Sometimes users are asked to test updates to the <a
|
||||||
|
href="https://www.freedesktop.org/software/systemd/man/hwdb.html">udev
|
||||||
|
hwdb</a> or patches that include a change to the hwdb. See @ref hwdb for
|
||||||
|
details on the hwdb and how to modify it locally.
|
||||||
|
|
||||||
|
@section faq_timer_offset What causes the "timer offset negative" warning?
|
||||||
|
|
||||||
|
libinput relies on the caller to call libinput_dispatch() whenever data is
|
||||||
|
available on the epoll-fd. Doing so will process the state of all devices
|
||||||
|
and can trigger some timers to be set (e.g. palm detection, tap-to-click,
|
||||||
|
disable-while-typing, etc.). Internally, libinput's time offsets are always
|
||||||
|
based on the event time of the triggering event.
|
||||||
|
|
||||||
|
For example, a touch event with time T may trigger a timer for the time T +
|
||||||
|
180ms. When setting a timer, libinput checks the wall clock time to ensure
|
||||||
|
that this time T + offset is still in the future. If not, the warning is
|
||||||
|
logged.
|
||||||
|
|
||||||
|
When this warning appears, it simply means that too much time has passed
|
||||||
|
between the event occurring (and the epoll-fd triggering) and the current
|
||||||
|
time. In almost all cases this is an indication of the caller being
|
||||||
|
overloaded and not handling events as speedily as required.
|
||||||
|
|
||||||
|
The warning has no immediate effect on libinput's behavior but some of the
|
||||||
|
functionality that relies on the timer may be impeded (e.g. palms are not
|
||||||
|
detected as they should be).
|
||||||
|
|
||||||
|
*/
|
||||||
129
doc/gestures.dox
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
/**
|
||||||
|
@page gestures Gestures
|
||||||
|
|
||||||
|
libinput supports basic gestures on touchpads and other indirect input
|
||||||
|
devices. Two types of gestures are supported: @ref gestures_pinch and @ref
|
||||||
|
gestures_swipe. Support for gestures depends on the hardware device, most
|
||||||
|
touchpads support both gestures and any device that may send gesture events
|
||||||
|
has the @ref LIBINPUT_DEVICE_CAP_GESTURE capability set.
|
||||||
|
|
||||||
|
Note that libinput **does not** support gestures on touchscreens, see
|
||||||
|
@ref gestures_touchscreens.
|
||||||
|
|
||||||
|
@section gestures_lifetime Lifetime of a gesture
|
||||||
|
|
||||||
|
A gesture's lifetime has three distinct stages: begin, update and end, each
|
||||||
|
with their own event types. Begin is sent when the fingers are first set
|
||||||
|
down or libinput decides that the gesture begins. For @ref gestures_pinch
|
||||||
|
this sets the initial scale. Any events changing properties of the gesture
|
||||||
|
are sent as update events. On termination of the gesture, an end event is
|
||||||
|
sent.
|
||||||
|
|
||||||
|
A gesture includes the finger count (see
|
||||||
|
libinput_event_gesture_get_finger_count()) and that finger count remains the
|
||||||
|
same for the lifetime of a gesture. Thus, if a user puts down a fourth
|
||||||
|
finger during a three-finger swipe gesture, libinput will end
|
||||||
|
the three-finger gesture and, if applicable, start a four-finger swipe
|
||||||
|
gesture. A caller may decide that those gestures are semantically identical
|
||||||
|
and continue the two gestures as one single gesture.
|
||||||
|
|
||||||
|
@see LIBINPUT_EVENT_GESTURE_PINCH_BEGIN
|
||||||
|
@see LIBINPUT_EVENT_GESTURE_PINCH_UPDATE
|
||||||
|
@see LIBINPUT_EVENT_GESTURE_PINCH_END
|
||||||
|
@see LIBINPUT_EVENT_GESTURE_PINCH_BEGIN
|
||||||
|
@see LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE
|
||||||
|
@see LIBINPUT_EVENT_GESTURE_SWIPE_END
|
||||||
|
|
||||||
|
@section gestures_pinch Pinch gestures
|
||||||
|
|
||||||
|
Pinch gestures are executed when two or more fingers are located on the
|
||||||
|
touchpad and are either changing the relative distance to each other
|
||||||
|
(pinching) or are changing the relative angle (rotate). Pinch gestures may
|
||||||
|
change both rotation and distance at the same time. For such gestures,
|
||||||
|
libinput calculates a logical center for the gestures and provides the
|
||||||
|
caller with the delta x/y coordinates of that center, the relative angle of
|
||||||
|
the fingers compared to the previous event, and the absolute scale compared
|
||||||
|
to the initial finger position.
|
||||||
|
|
||||||
|
@image html pinch-gestures.svg "The pinch and rotate gestures"
|
||||||
|
|
||||||
|
The illustration above shows a basic pinch in the left image and a rotate in
|
||||||
|
the right angle. Not shown is a movement of the logical center if the
|
||||||
|
fingers move unevenly. Such a movement is supported by libinput, it is
|
||||||
|
merely left out of the illustration.
|
||||||
|
|
||||||
|
Note that while position and angle is relative to the previous event, the
|
||||||
|
scale is always absolute and a multiplier of the initial finger position's
|
||||||
|
scale.
|
||||||
|
|
||||||
|
@section gestures_swipe Swipe gestures
|
||||||
|
|
||||||
|
Swipe gestures are executed when three or more fingers are moved
|
||||||
|
synchronously in the same direction. libinput provides x and y coordinates
|
||||||
|
in the gesture and thus allows swipe gestures in any direction, including
|
||||||
|
the tracing of complex paths. It is up to the caller to interpret the
|
||||||
|
gesture into an action or limit a gesture to specific directions only.
|
||||||
|
|
||||||
|
@image html swipe-gestures.svg "The swipe gestures"
|
||||||
|
|
||||||
|
The illustration above shows a vertical three-finger swipe. The coordinates
|
||||||
|
provided during the gesture are the movements of the logical center.
|
||||||
|
|
||||||
|
@section gestures_touchscreens Touchscreen gestures
|
||||||
|
|
||||||
|
Touchscreen gestures are **not** interpreted by libinput. Rather, any touch
|
||||||
|
point is passed to the caller and any interpretation of gestures is up to
|
||||||
|
the caller or, eventually, the X or Wayland client.
|
||||||
|
|
||||||
|
Interpreting gestures on a touchscreen requires context that libinput does
|
||||||
|
not have, such as the location of windows and other virtual objects on the
|
||||||
|
screen as well as the context of those virtual objects:
|
||||||
|
|
||||||
|
@image html touchscreen-gestures.svg "Context-sensitivity of touchscreen gestures"
|
||||||
|
|
||||||
|
In this example, the finger movements are identical but in the left case
|
||||||
|
both fingers are located within the same window, thus suggesting an attempt
|
||||||
|
to zoom. In the right case both fingers are located on a window border,
|
||||||
|
thus suggesting a window movement. libinput only has knowledge of the finger
|
||||||
|
coordinates (and even then only in device coordinates, not in screen
|
||||||
|
coordinates) and thus cannot differentiate the two.
|
||||||
|
|
||||||
|
@section gestures_softbuttons Gestures with enabled software buttons
|
||||||
|
|
||||||
|
If the touchpad device is a @ref touchpads_buttons_clickpads "Clickpad", it
|
||||||
|
is recommended that a caller switches to @ref clickfinger.
|
||||||
|
Usually fingers placed in a @ref software_buttons "software button area" is not
|
||||||
|
considered for gestures, resulting in some gestures to be interpreted as
|
||||||
|
pointer motion or two-finger scroll events.
|
||||||
|
|
||||||
|
@image html pinch-gestures-softbuttons.svg "Interference of software buttons and pinch gestures"
|
||||||
|
|
||||||
|
In the example above, the software button area is highlighted in red. The
|
||||||
|
user executes a three-finger pinch gesture, with the thumb remaining in the
|
||||||
|
software button area. libinput ignores fingers within the software button
|
||||||
|
areas, the movement of the remaining fingers is thus interpreted as a
|
||||||
|
two-finger scroll motion.
|
||||||
|
|
||||||
|
@section gestures_twofinger_touchpads Gestures on two-finger touchpads
|
||||||
|
|
||||||
|
As of kernel 4.2, many @ref touchpads_touch_partial_mt provide only two
|
||||||
|
slots. This affects how gestures can be interpreted. Touchpads with only two
|
||||||
|
slots can identify two touches by position but can usually tell that there
|
||||||
|
is a third (or fourth) finger down on the touchpad - without providing
|
||||||
|
positional information for that finger.
|
||||||
|
|
||||||
|
Touchpoints are assigned in sequential order and only the first two touch
|
||||||
|
points are trackable. For libinput this produces an ambiguity where it is
|
||||||
|
impossible to detect whether a gesture is a pinch gesture or a swipe gesture
|
||||||
|
whenever a user puts the index and middle finger down first. Since the third
|
||||||
|
finger does not have positional information, it's location cannot be
|
||||||
|
determined.
|
||||||
|
|
||||||
|
@image html gesture-2fg-ambiguity.svg "Ambiguity of three-finger gestures on two-finger touchpads"
|
||||||
|
|
||||||
|
The image above illustrates this ambiguity. The index and middle finger are
|
||||||
|
set down first, the data stream from both finger positions looks identical.
|
||||||
|
In this case, libinput assumes the fingers are in a horizontal arrangement
|
||||||
|
(the right image above) and use a swipe gesture.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
@ -7,13 +7,11 @@ OPTIMIZE_OUTPUT_FOR_C = YES
|
||||||
EXTRACT_ALL = YES
|
EXTRACT_ALL = YES
|
||||||
EXTRACT_STATIC = YES
|
EXTRACT_STATIC = YES
|
||||||
MAX_INITIALIZER_LINES = 0
|
MAX_INITIALIZER_LINES = 0
|
||||||
WARNINGS = YES
|
|
||||||
QUIET = YES
|
QUIET = YES
|
||||||
INPUT = "@builddir@"
|
INPUT = @INPUT@
|
||||||
IMAGE_PATH = "@builddir@"
|
IMAGE_PATH = "@top_srcdir@/doc/svg" \
|
||||||
OUTPUT_DIRECTORY = doc
|
"@top_srcdir@/doc/dot"
|
||||||
GENERATE_HTML = YES
|
GENERATE_HTML = YES
|
||||||
HTML_OUTPUT = html
|
|
||||||
SEARCHENGINE = NO
|
SEARCHENGINE = NO
|
||||||
USE_MATHJAX = YES
|
USE_MATHJAX = YES
|
||||||
MATHJAX_RELPATH = https://cdn.mathjax.org/mathjax/latest
|
MATHJAX_RELPATH = https://cdn.mathjax.org/mathjax/latest
|
||||||
|
|
@ -22,13 +20,11 @@ MACRO_EXPANSION = YES
|
||||||
EXPAND_ONLY_PREDEF = YES
|
EXPAND_ONLY_PREDEF = YES
|
||||||
PREDEFINED = LIBINPUT_ATTRIBUTE_PRINTF(f, a)= \
|
PREDEFINED = LIBINPUT_ATTRIBUTE_PRINTF(f, a)= \
|
||||||
LIBINPUT_ATTRIBUTE_DEPRECATED
|
LIBINPUT_ATTRIBUTE_DEPRECATED
|
||||||
DOTFILE_DIRS = "@builddir@"
|
DOTFILE_DIRS = "@top_srcdir@/doc/dot"
|
||||||
EXAMPLE_PATH = "@builddir@"
|
|
||||||
SHOW_NAMESPACES = NO
|
|
||||||
HAVE_DOT = YES
|
|
||||||
|
|
||||||
HTML_HEADER = "@builddir@/header.html"
|
HTML_HEADER = "@top_srcdir@/doc/style/header.html"
|
||||||
HTML_FOOTER = "@builddir@/footer.html"
|
HTML_FOOTER = "@top_srcdir@/doc/style/footer.html"
|
||||||
HTML_EXTRA_STYLESHEET = "@builddir@/bootstrap.css" \
|
HTML_EXTRA_STYLESHEET = "@top_srcdir@/doc/style/bootstrap.css" \
|
||||||
"@builddir@/customdoxygen.css" \
|
"@top_srcdir@/doc/style/customdoxygen.css" \
|
||||||
"@builddir@/libinputdoxygen.css"
|
"@top_srcdir@/doc/style/libinputdoxygen.css"
|
||||||
|
USE_MDFILE_AS_MAINPAGE = "@top_srcdir@/README.md"
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
.. _middle_button_emulation:
|
/**
|
||||||
|
@page middle_button_emulation Middle button emulation
|
||||||
==============================================================================
|
|
||||||
Middle button emulation
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
Middle button emulation provides users with the ability to generate a middle
|
Middle button emulation provides users with the ability to generate a middle
|
||||||
click even when the device does not have a physical middle button available.
|
click even when the device does not have a physical middle button available.
|
||||||
|
|
@ -19,7 +16,7 @@ appropriate to the physical device.
|
||||||
|
|
||||||
The middle button emulation behavior when combined with other device
|
The middle button emulation behavior when combined with other device
|
||||||
buttons, including a physical middle button is device-dependent.
|
buttons, including a physical middle button is device-dependent.
|
||||||
For example, :ref:`clickpad_softbuttons` provides a middle button area when
|
For example, @ref clickpad_softbuttons provides a middle button area when
|
||||||
middle button emulation is disabled. That middle button area disappears
|
middle button emulation is disabled. That middle button area disappears
|
||||||
when middle button emulation is enabled - a middle click can then only be
|
when middle button emulation is enabled - a middle click can then only be
|
||||||
triggered by a simultaneous left + right click.
|
triggered by a simultaneous left + right click.
|
||||||
|
|
@ -29,7 +26,9 @@ enabling/disabling that emulation. Likewise, some devices may allow middle
|
||||||
button emulation but have it disabled by default. This is the case for most
|
button emulation but have it disabled by default. This is the case for most
|
||||||
mouse-like devices where a middle button is detected.
|
mouse-like devices where a middle button is detected.
|
||||||
|
|
||||||
libinput provides **libinput_device_config_middle_emulation_set_enabled()** to
|
libinput provides libinput_device_config_middle_emulation_set_enabled() to
|
||||||
enable or disable middle button emulation. See :ref:`faq_configure_wayland`
|
enable or disable middle button emulation. See @ref faq_configure_wayland
|
||||||
and :ref:`faq_configure_xorg` for info on how to enable or disable middle
|
and @ref faq_configure_xorg for info on how to enable or disable middle
|
||||||
button emulation in the Wayland compositor or the X stack.
|
button emulation in the Wayland compositor or the X stack.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
.. _motion_normalization:
|
/**
|
||||||
|
@page motion_normalization Normalization of relative motion
|
||||||
==============================================================================
|
|
||||||
Normalization of relative motion
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
Most relative input devices generate input in so-called "mickeys". A
|
Most relative input devices generate input in so-called "mickeys". A
|
||||||
mickey is in device-specific units that depend on the resolution
|
mickey is in device-specific units that depend on the resolution
|
||||||
|
|
@ -27,20 +24,11 @@ libinput applies a dpi-dependent acceleration function. At low speeds, a
|
||||||
movement speed increases, acceleration is applied - at high speeds a low-dpi
|
movement speed increases, acceleration is applied - at high speeds a low-dpi
|
||||||
device will roughly feel the same as a higher-dpi mouse.
|
device will roughly feel the same as a higher-dpi mouse.
|
||||||
|
|
||||||
The reason for the normalization is convenience: a caller can assume that a
|
|
||||||
delta of 1 should result in a movement of 1 pixel on a traditional
|
|
||||||
(low-dpi) screen. On screens with high resolutions, the caller must scale
|
|
||||||
according to the UI scale factors.
|
|
||||||
|
|
||||||
This normalization only applies to accelerated coordinates, unaccelerated
|
This normalization only applies to accelerated coordinates, unaccelerated
|
||||||
coordinates are left in device-units. It is up to the caller to interpret
|
coordinates are left in device-units. It is up to the caller to interpret
|
||||||
those coordinates correctly.
|
those coordinates correctly.
|
||||||
|
|
||||||
.. _motion_normalization_touchpad:
|
@section motion_normalization_touchpad Normalization of touchpad coordinates
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Normalization of touchpad coordinates
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Touchpads may have a different resolution for the horizontal and vertical
|
Touchpads may have a different resolution for the horizontal and vertical
|
||||||
axis. Interpreting coordinates from the touchpad without taking resolution
|
axis. Interpreting coordinates from the touchpad without taking resolution
|
||||||
|
|
@ -48,50 +36,49 @@ into account results in uneven motion.
|
||||||
|
|
||||||
libinput scales unaccelerated touchpad motion to the resolution of the
|
libinput scales unaccelerated touchpad motion to the resolution of the
|
||||||
touchpad's x axis, i.e. the unaccelerated value for the y axis is:
|
touchpad's x axis, i.e. the unaccelerated value for the y axis is:
|
||||||
``y = (x / resolution_x) * resolution_y``.
|
y = (x / resolution_x) * resolution_y
|
||||||
|
|
||||||
.. _motion_normalization_tablet:
|
@section motion_normalization_tablet Normalization of tablet coordinates
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
See @ref tablet-relative-motion
|
||||||
Normalization of tablet coordinates
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
See :ref:`tablet-relative-motion`
|
@section motion_normalization_customization Setting custom DPI settings
|
||||||
|
|
||||||
.. _motion_normalization_customization:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Setting custom DPI settings
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Devices usually do not advertise their resolution and libinput relies on
|
Devices usually do not advertise their resolution and libinput relies on
|
||||||
the udev property **MOUSE_DPI** for this information. This property is usually
|
the udev property <b>MOUSE_DPI</b> for this information. This property is usually
|
||||||
set via the
|
set via the <a
|
||||||
`udev hwdb <http://cgit.freedesktop.org/systemd/systemd/tree/hwdb/70-mouse.hwdb>`_.
|
href="http://cgit.freedesktop.org/systemd/systemd/tree/hwdb/70-mouse.hwdb">udev hwdb</a>.
|
||||||
The ``mouse-dpi-tool`` utility provided by
|
The "mouse-dpi-tool" utility provided by <a
|
||||||
`libevdev <https://freedesktop.org/wiki/Software/libevdev/>`_ should be
|
href="https://freedesktop.org/wiki/Software/libevdev/">libevdev</a> should be
|
||||||
used to measure a device's resolution.
|
used to measure a device's resolution.
|
||||||
|
|
||||||
The format of the property for single-resolution mice is: ::
|
The format of the property for single-resolution mice is:
|
||||||
|
@code
|
||||||
MOUSE_DPI=resolution@frequency
|
MOUSE_DPI=resolution@frequency
|
||||||
|
@endcode
|
||||||
|
|
||||||
The resolution is in dots per inch, the frequency in Hz.
|
The resolution is in dots per inch, the frequency in Hz.
|
||||||
The format of the property for multi-resolution mice may list multiple
|
The format of the property for multi-resolution mice may list multiple
|
||||||
resolutions and frequencies: ::
|
resolutions and frequencies:
|
||||||
|
@code
|
||||||
MOUSE_DPI=r1@f1 *r2@f2 r3@f3
|
MOUSE_DPI=r1@f1 *r2@f2 r3@f3
|
||||||
|
@endcode
|
||||||
|
|
||||||
The default frequency must be pre-fixed with an asterisk.
|
The default frequency must be pre-fixed with an asterisk.
|
||||||
|
|
||||||
For example, these two properties are valid: ::
|
For example, these two properties are valid:
|
||||||
|
@code
|
||||||
MOUSE_DPI=800@125
|
MOUSE_DPI=800@125
|
||||||
MOUSE_DPI=400@125 800@125 *1000@500 5500@500
|
MOUSE_DPI=400@125 800@125 *1000@500 5500@500
|
||||||
|
@endcode
|
||||||
|
|
||||||
The behavior for a malformed property is undefined. If the property is
|
The behavior for a malformed property is undefined.
|
||||||
unset, libinput assumes the resolution is 1000dpi.
|
|
||||||
|
If the property is unset, libinput assumes the resolution is 1000dpi.
|
||||||
|
|
||||||
Note that HW does not usually provide information about run-time
|
Note that HW does not usually provide information about run-time
|
||||||
resolution changes, libinput will thus not detect when a resolution
|
resolution changes, libinput will thus not detect when a resolution
|
||||||
changes to the non-default value.
|
changes to the non-default value.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
57
doc/page-hierarchy.dox
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
|
||||||
|
@page misc Users
|
||||||
|
|
||||||
|
- @subpage what_is_libinput
|
||||||
|
- @subpage faq
|
||||||
|
- @subpage tools
|
||||||
|
- @subpage reporting_bugs
|
||||||
|
|
||||||
|
@page touchpads Touchpads
|
||||||
|
|
||||||
|
- @subpage scrolling
|
||||||
|
- @subpage clickpad_softbuttons
|
||||||
|
- @subpage tapping
|
||||||
|
- @subpage gestures
|
||||||
|
- @subpage touchpad_pressure
|
||||||
|
- @subpage palm_detection
|
||||||
|
- @subpage t440_support
|
||||||
|
- @subpage touchpad_jumping_cursor
|
||||||
|
- @subpage absolute_coordinate_ranges
|
||||||
|
- @subpage touchpad_jitter
|
||||||
|
|
||||||
|
@page touchscreens Touchscreens
|
||||||
|
|
||||||
|
- @subpage absolute_axes
|
||||||
|
|
||||||
|
@page pointers Mice, Trackballs, etc.
|
||||||
|
|
||||||
|
- @subpage motion_normalization
|
||||||
|
- @subpage middle_button_emulation
|
||||||
|
- @subpage button_debouncing
|
||||||
|
- @subpage trackpoints
|
||||||
|
|
||||||
|
@page tablets Graphics Tablets
|
||||||
|
|
||||||
|
- @subpage tablet-support
|
||||||
|
|
||||||
|
@page general General
|
||||||
|
|
||||||
|
- @subpage udev_config
|
||||||
|
- @subpage seats
|
||||||
|
- @subpage timestamps
|
||||||
|
|
||||||
|
@page developers Developers
|
||||||
|
|
||||||
|
Contributions to libinput are always welcome. See the links below for
|
||||||
|
specific documentation.
|
||||||
|
|
||||||
|
- @subpage what_is_libinput
|
||||||
|
- @subpage contributing
|
||||||
|
- @subpage architecture
|
||||||
|
- @subpage building_libinput
|
||||||
|
- @subpage test-suite
|
||||||
|
- @subpage tools
|
||||||
|
- @subpage pointer-acceleration
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
.. _palm_detection:
|
/**
|
||||||
|
@page palm_detection Palm detection
|
||||||
==============================================================================
|
|
||||||
Palm detection
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
Palm detection tries to identify accidental touches while typing, while
|
Palm detection tries to identify accidental touches while typing, while
|
||||||
using the trackpoint and/or during general use of the touchpad area.
|
using the trackpoint and/or during general use of the touchpad area.
|
||||||
|
|
@ -21,34 +18,25 @@ touchpads are less affected by palm touches.
|
||||||
libinput has multiple ways of detecting a palm, each of which depends on
|
libinput has multiple ways of detecting a palm, each of which depends on
|
||||||
hardware-specific capabilities.
|
hardware-specific capabilities.
|
||||||
|
|
||||||
- :ref:`palm_tool`
|
- @ref palm_tool
|
||||||
- :ref:`palm_pressure`
|
- @ref palm_pressure
|
||||||
- :ref:`palm_touch_size`
|
- @ref palm_touch_size
|
||||||
- :ref:`palm_exclusion_zones`
|
- @ref palm_exclusion_zones
|
||||||
- :ref:`trackpoint-disabling`
|
- @ref trackpoint-disabling
|
||||||
- :ref:`disable-while-typing`
|
- @ref disable-while-typing
|
||||||
- :ref:`disable-while-trackpointing`
|
- @ref stylus-touch-arbitration
|
||||||
- :ref:`stylus-touch-arbitration`
|
|
||||||
|
|
||||||
Palm detection is always enabled, with the exception of
|
Palm detection is always enabled, with the exception of
|
||||||
disable-while-typing.
|
disable-while-typing.
|
||||||
|
|
||||||
.. _palm_tool:
|
@section palm_tool Palm detection based on firmware labelling
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Palm detection based on firmware labelling
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Some devices provide palm detection in the firmware, forwarded by the kernel
|
Some devices provide palm detection in the firmware, forwarded by the kernel
|
||||||
as the ``EV_ABS/ABS_MT_TOOL`` axis with a value of ``MT_TOOL_PALM``
|
as the ```EV_ABS/ABS_MT_TOOL``` axis with a value of ```MT_TOOL_PALM```
|
||||||
(whenever a palm is detected). libinput honors that value and switches that
|
(whenever a palm is detected). libinput honors that value and switches that
|
||||||
touch to a palm.
|
touch to a palm.
|
||||||
|
|
||||||
.. _palm_pressure:
|
@section palm_pressure Palm detection based on pressure
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Palm detection based on pressure
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The simplest form of palm detection labels a touch as palm when the pressure
|
The simplest form of palm detection labels a touch as palm when the pressure
|
||||||
value goes above a certain threshold. This threshold is usually high enough
|
value goes above a certain threshold. This threshold is usually high enough
|
||||||
|
|
@ -58,27 +46,19 @@ the threshold again. This ensures that a palm remains a palm even when the
|
||||||
pressure changes as the user is typing.
|
pressure changes as the user is typing.
|
||||||
|
|
||||||
For some information on how to detect pressure on a touch and debug the
|
For some information on how to detect pressure on a touch and debug the
|
||||||
pressure ranges, see :ref:`touchpad_pressure`.
|
pressure ranges, see @ref touchpad_pressure.
|
||||||
|
|
||||||
.. _palm_touch_size:
|
@section palm_touch_size Palm detection based on touch size
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
On touchads that support the `ABS_MT_TOUCH_MAJOR` axes, libinput can perform
|
||||||
Palm detection based on touch size
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
On touchpads that support the ``ABS_MT_TOUCH_MAJOR`` axes, libinput can perform
|
|
||||||
palm detection based on the size of the touch ellipse. This works similar to
|
palm detection based on the size of the touch ellipse. This works similar to
|
||||||
the pressure-based palm detection in that a touch is labelled as palm when
|
the pressure-based palm detection in that a touch is labelled as palm when
|
||||||
it exceeds the (device-specific) touch size threshold.
|
it exceeds the (device-specific) touch size threshold.
|
||||||
|
|
||||||
For some information on how to detect the size of a touch and debug the
|
For some information on how to detect the size of a touch and debug the
|
||||||
touch size ranges, see :ref:`touchpad_pressure`.
|
touch size ranges, see @ref touchpad_pressure.
|
||||||
|
|
||||||
.. _palm_exclusion_zones:
|
@section palm_exclusion_zones Palm exclusion zones
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Palm exclusion zones
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
libinput enables palm detection on the left, right and top edges of the
|
libinput enables palm detection on the left, right and top edges of the
|
||||||
touchpad. Two exclusion zones are defined on the left and right edge of the
|
touchpad. Two exclusion zones are defined on the left and right edge of the
|
||||||
|
|
@ -92,8 +72,9 @@ Another exclusion zone is defined on the top edge of the touchpad. As with
|
||||||
the edge zones, libinput detects vertical movements out of the edge zone and
|
the edge zones, libinput detects vertical movements out of the edge zone and
|
||||||
avoids palm detection on such touch sequences.
|
avoids palm detection on such touch sequences.
|
||||||
|
|
||||||
A touch starting in the exclusion zone does not trigger a tap (see
|
Each side edge exclusion zone is divided into a top part and a bottom part.
|
||||||
:ref:`tapping`).
|
A touch starting in the top part of the exclusion zone does not trigger a
|
||||||
|
tap (see @ref tapping).
|
||||||
|
|
||||||
In the diagram below, the exclusion zones are painted red.
|
In the diagram below, the exclusion zones are painted red.
|
||||||
Touch 'A' starts inside the exclusion zone and moves
|
Touch 'A' starts inside the exclusion zone and moves
|
||||||
|
|
@ -103,20 +84,17 @@ despite moving out of the exclusion zone.
|
||||||
Touch 'B' starts inside the exclusion zone but moves horizontally out of the
|
Touch 'B' starts inside the exclusion zone but moves horizontally out of the
|
||||||
zone. It is considered a valid touch and controls the cursor.
|
zone. It is considered a valid touch and controls the cursor.
|
||||||
|
|
||||||
Touch 'C' occurs in the exclusion zone. Despite being a tapping motion, it does
|
Touch 'C' occurs in the top part of the exclusion zone. Despite being a
|
||||||
not generate an emulated button event.
|
tapping motion, it does not generate an emulated button event. Touch 'D'
|
||||||
|
likewise occurs within the exclusion zone but in the bottom half. libinput
|
||||||
|
will generate a button event for this touch.
|
||||||
|
|
||||||
.. figure:: palm-detection.svg
|
@image html palm-detection.svg
|
||||||
:align: center
|
|
||||||
|
|
||||||
.. _trackpoint-disabling:
|
@section trackpoint-disabling Palm detection during trackpoint use
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
If a device provides a <a
|
||||||
Palm detection during trackpoint use
|
href="http://en.wikipedia.org/wiki/Pointing_stick">trackpoint</a>, it is
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
If a device provides a
|
|
||||||
`trackpoint <http://en.wikipedia.org/wiki/Pointing_stick>`_, it is
|
|
||||||
usually located above the touchpad. This increases the likelihood of
|
usually located above the touchpad. This increases the likelihood of
|
||||||
accidental touches whenever the trackpoint is used.
|
accidental touches whenever the trackpoint is used.
|
||||||
|
|
||||||
|
|
@ -125,25 +103,20 @@ certain timeout until after trackpoint activity stops. Touches generated
|
||||||
during this timeout will not move the pointer, and touches started during
|
during this timeout will not move the pointer, and touches started during
|
||||||
this timeout will likewise not move the pointer (allowing for a user to rest
|
this timeout will likewise not move the pointer (allowing for a user to rest
|
||||||
the palm on the touchpad while using the trackstick).
|
the palm on the touchpad while using the trackstick).
|
||||||
If the touchpad is disabled, the :ref:`top software buttons <t440_support>`
|
If the touchpad is disabled, the @ref t440_support "top software buttons"
|
||||||
remain enabled.
|
remain enabled.
|
||||||
|
|
||||||
.. _disable-while-typing:
|
@section disable-while-typing Disable-while-typing
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Disable-while-typing
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
libinput automatically disables the touchpad for a timeout after a key
|
libinput automatically disables the touchpad for a timeout after a key
|
||||||
press, a feature traditionally referred to as "disable while typing" and
|
press, a feature traditionally referred to as "disable while typing" and
|
||||||
previously available through the
|
previously available through the
|
||||||
`syndaemon(1) <http://linux.die.net/man/1/syndaemon>`_ command. libinput does
|
[syndaemon(1)](http://linux.die.net/man/1/syndaemon) command. libinput does
|
||||||
not require an external command and the feature is currently enabled for all
|
not require an external command and the feature is currently enabled for all
|
||||||
touchpads but will be reduced in the future to only apply to touchpads where
|
touchpads but will be reduced in the future to only apply to touchpads where
|
||||||
finger width or pressure data is unreliable.
|
finger width or pressure data is unreliable.
|
||||||
|
|
||||||
Notable behaviors of libinput's disable-while-typing feature:
|
Notable behaviors of libinput's disable-while-typing feature:
|
||||||
|
|
||||||
- Two different timeouts are used, after a single key press the timeout is
|
- Two different timeouts are used, after a single key press the timeout is
|
||||||
short to ensure responsiveness. After multiple key events, the timeout is
|
short to ensure responsiveness. After multiple key events, the timeout is
|
||||||
longer to avoid accidental pointer manipulation while typing.
|
longer to avoid accidental pointer manipulation while typing.
|
||||||
|
|
@ -154,35 +127,12 @@ Notable behaviors of libinput's disable-while-typing feature:
|
||||||
has stopped, it is thus possible to rest the palm on the touchpad while
|
has stopped, it is thus possible to rest the palm on the touchpad while
|
||||||
typing.
|
typing.
|
||||||
- Physical buttons work even while the touchpad is disabled. This includes
|
- Physical buttons work even while the touchpad is disabled. This includes
|
||||||
:ref:`software-emulated buttons <t440_support>`.
|
@ref t440_support "software-emulated buttons".
|
||||||
- libinput pairs touchpads and keyboards for the disable-while-typing
|
|
||||||
feature. In the most common case, the internal touchpad is paired only
|
|
||||||
with the internal keyboard. Typing on an external keyboard will thus not
|
|
||||||
disable the touchpad. Some devices require a :ref:`quirk <device-quirks>`
|
|
||||||
to be correctly paired.
|
|
||||||
|
|
||||||
Disable-while-typing can be enabled and disabled by calling
|
Disable-while-typing can be enabled and disabled by calling
|
||||||
**libinput_device_config_dwt_set_enabled()**.
|
libinput_device_config_dwt_set_enabled().
|
||||||
|
|
||||||
.. _disable-while-trackpointing:
|
@section stylus-touch-arbitration Stylus-touch arbitration
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Disable-while-trackpointing
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
libinput automatically disables the touchpad for a timeout after the trackpoint
|
|
||||||
is moved, a feature referred to as "disable while trackpointing". libinput does
|
|
||||||
not require an external command and the feature is currently enabled for all
|
|
||||||
touchpads.
|
|
||||||
|
|
||||||
Disable-while-trackpointing can be enabled and disabled by calling
|
|
||||||
**libinput_device_config_dwtp_set_enabled()**.
|
|
||||||
|
|
||||||
.. _stylus-touch-arbitration:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Stylus-touch arbitration
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
A special case of palm detection is touch arbitration on devices that
|
A special case of palm detection is touch arbitration on devices that
|
||||||
support styli. When interacting with a stylus on the screen, parts of the
|
support styli. When interacting with a stylus on the screen, parts of the
|
||||||
|
|
@ -190,27 +140,23 @@ hand may touch the surface and trigger touches. As the user is currently
|
||||||
interacting with the stylus, these touches would interfer with the correct
|
interacting with the stylus, these touches would interfer with the correct
|
||||||
working of the stylus.
|
working of the stylus.
|
||||||
|
|
||||||
libinput employs a method similar to :ref:`disable-while-typing` to detect
|
libinput employs a method similar to @ref disable-while-typing to detect
|
||||||
these touches and disables the touchpad accordingly.
|
these touches and disables the touchpad accordingly.
|
||||||
|
|
||||||
.. _thumb-detection:
|
@section thumb-detection Thumb detection
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Thumb detection
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Many users rest their thumb on the touchpad while using the index finger to
|
Many users rest their thumb on the touchpad while using the index finger to
|
||||||
move the finger around. For clicks, often the thumb is used rather than the
|
move the finger around. For clicks, often the thumb is used rather than the
|
||||||
finger. The thumb should otherwise be ignored as a touch, i.e. it should not
|
finger. The thumb should otherwise be ignored as a touch, i.e. it should not
|
||||||
count towards :ref:`clickfinger` and it should not cause a single-finger
|
count towards @ref clickfinger and it should not cause a single-finger
|
||||||
movement to trigger :ref:`twofinger_scrolling`.
|
movement to trigger @ref twofinger_scrolling.
|
||||||
|
|
||||||
libinput uses two triggers for thumb detection: pressure and
|
libinput uses two triggers for thumb detection: pressure and
|
||||||
location. A touch exceeding a pressure threshold is considered a thumb if it
|
location. A touch exceeding a pressure threshold is considered a thumb if it
|
||||||
is within the thumb detection zone.
|
is within the thumb detection zone.
|
||||||
|
|
||||||
.. note:: "Pressure" on touchpads is synonymous with "contact area." A large touch
|
@note "Pressure" on touchpads is synonymous with "contact area", a large
|
||||||
surface area has a higher pressure and thus hints at a thumb or palm
|
touch surface area has a higher pressure and thus hints at a thumb or palm
|
||||||
touching the surface.
|
touching the surface.
|
||||||
|
|
||||||
Pressure readings are unreliable at the far bottom of the touchpad as a
|
Pressure readings are unreliable at the far bottom of the touchpad as a
|
||||||
|
|
@ -218,10 +164,11 @@ thumb hanging mostly off the touchpad will have a small surface area.
|
||||||
libinput has a definitive thumb zone where any touch is considered a resting
|
libinput has a definitive thumb zone where any touch is considered a resting
|
||||||
thumb.
|
thumb.
|
||||||
|
|
||||||
.. figure:: thumb-detection.svg
|
@image html thumb-detection.svg
|
||||||
:align: center
|
|
||||||
|
|
||||||
The picture above shows the two detection areas. In the larger (light red)
|
The picture above shows the two detection areas. In the larger (light red)
|
||||||
area, a touch is labelled as thumb when it exceeds a device-specific
|
area, a touch is labelled as thumb when it exceeds a device-specific
|
||||||
pressure threshold. In the lower (dark red) area, a touch is labelled as
|
pressure threshold. In the lower (dark red) area, a touch is labelled as
|
||||||
thumb if it remains in that area for a time without moving outside.
|
thumb if it remains in that area for a time without moving outside.
|
||||||
|
|
||||||
|
*/
|
||||||
156
doc/pointer-acceleration.dox
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
/**
|
||||||
|
@page pointer-acceleration Pointer acceleration
|
||||||
|
|
||||||
|
libinput uses device-specific pointer acceleration methods, with the default
|
||||||
|
being the @ref ptraccel-linear. The methods share common properties, such as
|
||||||
|
@ref ptraccel-velocity.
|
||||||
|
|
||||||
|
This page explains the high-level concepts used in the code. It aims to
|
||||||
|
provide an overview for developers and is not necessarily useful for
|
||||||
|
users.
|
||||||
|
|
||||||
|
@section ptraccel-profiles Pointer acceleration profiles
|
||||||
|
|
||||||
|
The profile decides the general method of pointer acceleration.
|
||||||
|
libinput currently supports two profiles: "adaptive" and "flat". The adaptive
|
||||||
|
profile is the default profile for all devices and takes the current speed
|
||||||
|
of the device into account when deciding on acceleration. The flat profile
|
||||||
|
is simply a constant factor applied to all device deltas, regardless of the
|
||||||
|
speed of motion (see @ref ptraccel-profile-flat). Most of this document
|
||||||
|
describes the adaptive pointer acceleration.
|
||||||
|
|
||||||
|
@section ptraccel-velocity Velocity calculation
|
||||||
|
|
||||||
|
The device's speed of movement is measured across multiple input events
|
||||||
|
through so-called "trackers". Each event prepends a the tracker item, each
|
||||||
|
subsequent tracker contains the delta of that item to the current position,
|
||||||
|
the timestamp of the event that created it and the cardinal direction of the
|
||||||
|
movement at the time. If a device moves into the same direction, the
|
||||||
|
velocity is calculated across multiple trackers. For example, if a device
|
||||||
|
moves steadily for 10 events to the left, the velocity is calculated across
|
||||||
|
all 10 events.
|
||||||
|
|
||||||
|
Whenever the movement changes direction or significantly changes speed, the
|
||||||
|
velocity is calculated from the direction/speed change only. For example, if
|
||||||
|
a device moves steadily for 8 events to the left and then 2 events to the
|
||||||
|
right, the velocity is only that of the last 2 events.
|
||||||
|
|
||||||
|
An extra time limit prevents events that are too old to factor into the
|
||||||
|
velocity calculation. For example, if a device moves steadily for 5 events
|
||||||
|
to the left, then pauses, then moves again for 5 events to the left, only
|
||||||
|
the last 5 events are used for velocity calculation.
|
||||||
|
|
||||||
|
The velocity is then used to calculate the acceleration factor
|
||||||
|
|
||||||
|
@section ptraccel-factor Acceleration factor
|
||||||
|
|
||||||
|
The acceleration factor is the final outcome of the pointer acceleration
|
||||||
|
calculations. It is a unitless factor that is applied to the current delta,
|
||||||
|
a factor of 2 doubles the delta (i.e. speeds up the movement), a factor of
|
||||||
|
less than 1 reduces the delta (i.e. slows the movement).
|
||||||
|
|
||||||
|
Any factor less than 1 requires the user to move the device further to move
|
||||||
|
the visible pointer. This is called deceleration and enables high precision
|
||||||
|
target selection through subpixel movements. libinput's current maximum
|
||||||
|
deceleration factor is 0.3 (i.e. slow down to 30% of the pointer speed).
|
||||||
|
|
||||||
|
A factor higher than 1 moves the pointer further than the physical device
|
||||||
|
moves. This is acceleration and allows a user to cross the screen quickly
|
||||||
|
but effectively skips pixels. libinput's current maximum acceleration factor
|
||||||
|
is 3.5.
|
||||||
|
|
||||||
|
@section ptraccel-linear Linear pointer acceleration
|
||||||
|
|
||||||
|
The linear pointer acceleration method is the default for most pointer
|
||||||
|
devices. It provides deceleration at very slow movements, a 1:1 mapping for
|
||||||
|
regular movements and a linear increase to the maximum acceleration factor
|
||||||
|
for fast movements.
|
||||||
|
|
||||||
|
Linear pointer acceleration applies to devices with above 1000dpi resolution
|
||||||
|
and after @ref motion_normalization is applied.
|
||||||
|
|
||||||
|
@image html ptraccel-linear.svg "Linear pointer acceleration"
|
||||||
|
|
||||||
|
The image above shows the linear pointer acceleration settings at various
|
||||||
|
speeds. The line for 0.0 is the default acceleration curve, speed settings
|
||||||
|
above 0.0 accelerate sooner, faster and to a higher maximum acceleration.
|
||||||
|
Speed settings below 0 delay when acceleration kicks in, how soon the
|
||||||
|
maximum acceleration is reached and the maximum acceleration factor.
|
||||||
|
|
||||||
|
Extremely low speed settings provide no acceleration and additionally
|
||||||
|
decelerate all movement by a constant factor.
|
||||||
|
|
||||||
|
@section ptraccel-low-dpi Pointer acceleration for low-dpi devices
|
||||||
|
|
||||||
|
Low-dpi devices are those with a physical resolution of less than 1000 dots
|
||||||
|
per inch (dpi). The pointer acceleration is adjusted to provide roughly the
|
||||||
|
same feel for all devices at normal to high speeds. At slow speeds, the
|
||||||
|
pointer acceleration works on device-units rather than normalized
|
||||||
|
coordinates (see @ref motion_normalization).
|
||||||
|
|
||||||
|
@image html ptraccel-low-dpi.svg "Pointer acceleration for low-dpi devices"
|
||||||
|
|
||||||
|
The image above shows the default pointer acceleration curve for a speed of
|
||||||
|
0.0 at different DPI settings. A device with low DPI has the acceleration
|
||||||
|
applied sooner and with a stronger acceleration factor.
|
||||||
|
|
||||||
|
@section ptraccel-touchpad Pointer acceleration on touchpads
|
||||||
|
|
||||||
|
Touchpad pointer acceleration uses the same approach as the @ref
|
||||||
|
ptraccel-linear profile, with a constant deceleration factor applied. The
|
||||||
|
user expectation of how much a pointer should move in response to finger
|
||||||
|
movement is different to that of a mouse device, hence the constant
|
||||||
|
deceleration factor.
|
||||||
|
|
||||||
|
@image html ptraccel-touchpad.svg "Pointer acceleration curve for touchpads"
|
||||||
|
|
||||||
|
The image above shows the touchpad acceleration profile in comparison to the
|
||||||
|
@ref ptraccel-linear. The shape of the curve is identical but vertically squashed.
|
||||||
|
|
||||||
|
@section ptraccel-trackpoint Pointer acceleration on trackpoints
|
||||||
|
|
||||||
|
The main difference between trackpoint hardware and mice or touchpads is
|
||||||
|
that trackpoint speed is a function of pressure rather than moving speed.
|
||||||
|
But trackpoint hardware is quite varied in how it reacts to user pressure
|
||||||
|
and unlike other devices it cannot easily be normalized for physical
|
||||||
|
properties. Measuring pressure objectively across a variety of hardware is
|
||||||
|
nontrivial.
|
||||||
|
|
||||||
|
libinput's pointer acceleration is a function of the total available
|
||||||
|
pressure range on a device. See @ref trackpoint_range for details.
|
||||||
|
|
||||||
|
libinput relies on some system-wide configured properties, specifically the
|
||||||
|
@ref udev_config. The property that influences trackpoint acceleration is
|
||||||
|
`LIBINPUT_ATTR_TRACKPOINT_RANGE` which specifies the total delta range for
|
||||||
|
the trackpoint. See @ref trackpoint_range for details.
|
||||||
|
|
||||||
|
Additionally, some trackpoints provide the ability to adjust the sensitivity in
|
||||||
|
hardware by modifying a sysfs file on the serio node. The udev property
|
||||||
|
`POINTINGSTICK_SENSITIVITY` indicates the desired value, a udev
|
||||||
|
builtin is expected to apply this to the device, i.e. libinput does not
|
||||||
|
handle this property. Once applied, the sensitivity adjusts the deltas
|
||||||
|
coming out of the hardware. When the sensitivity changes, the trackpoint
|
||||||
|
range changes and thus the `LIBINPUT_ATTR_TRACKPOINT_RANGE` property
|
||||||
|
becomes invalid.
|
||||||
|
|
||||||
|
As of version 1.9, libinput does not parse the `POINTINGSTICK_CONST_ACCEL` property anymore.
|
||||||
|
|
||||||
|
@image html ptraccel-trackpoint.svg "Pointer acceleration curves for trackpoints"
|
||||||
|
|
||||||
|
The image above shows the trackpoint acceleration profile for each input
|
||||||
|
delta.
|
||||||
|
|
||||||
|
@section ptraccel-profile-flat The flat pointer acceleration profile
|
||||||
|
|
||||||
|
In a flat profile, the acceleration factor is constant regardless of the
|
||||||
|
velocity of the pointer and each delta (dx, dy) results in an accelerated delta
|
||||||
|
(dx * factor, dy * factor). This provides 1:1 movement between the device
|
||||||
|
and the pointer on-screen.
|
||||||
|
|
||||||
|
@section ptraccel-tablet Pointer acceleration on tablets
|
||||||
|
|
||||||
|
Pointer acceleration for relative motion on tablet devices is a flat
|
||||||
|
acceleration, with the speed setting slowing down or speeding up the pointer
|
||||||
|
motion by a constant factor. Tablets do not allow for switchable profiles.
|
||||||
|
|
||||||
|
*/
|
||||||
295
doc/reporting-bugs.dox
Normal file
|
|
@ -0,0 +1,295 @@
|
||||||
|
/**
|
||||||
|
@page reporting_bugs Reporting bugs
|
||||||
|
|
||||||
|
A new bug can be filed here:
|
||||||
|
https://gitlab.freedesktop.org/libinput/libinput
|
||||||
|
|
||||||
|
When reporting bugs against libinput, please follow the instructions below
|
||||||
|
and provide the required data. You will need:
|
||||||
|
|
||||||
|
- a reliable @ref reporting_bugs_reproducer "reproducer" for the bug
|
||||||
|
- an @ref evemu "evemu recording" of the device while the bug is reproduced
|
||||||
|
- device-specific information, see
|
||||||
|
- @ref reporting_bugs_touchpad
|
||||||
|
- @ref reporting_bugs_mouse
|
||||||
|
- @ref reporting_bugs_keyboard
|
||||||
|
- @ref reporting_bugs_trackpoint
|
||||||
|
- @ref reporting_bugs_other
|
||||||
|
- the @ref reporting_bugs_version "libinput version" you are on.
|
||||||
|
- the @ref reporting_bugs_options "configuration options" you have set
|
||||||
|
- a bugzilla account
|
||||||
|
|
||||||
|
If you don't have all of the above, provide a reason why not. Unless the
|
||||||
|
reason is justified, the bug will have low priority. Remember, libinput has
|
||||||
|
a lot of users but very few developers.
|
||||||
|
|
||||||
|
Stay technical, on-topic, and keep the description concise.
|
||||||
|
|
||||||
|
@section reporting_bugs_version Obtaining the libinput version
|
||||||
|
|
||||||
|
If your libinput version is older than the current stable branch, you will
|
||||||
|
get asked to try the latest version.
|
||||||
|
|
||||||
|
If you run a distribution-provided libinput, use the package manager to get
|
||||||
|
the **full** package name and version of libinput, e.g.
|
||||||
|
- `rpm -q libinput`
|
||||||
|
- `dpkg -s libinput10`
|
||||||
|
|
||||||
|
If you run a self-compiled version of libinput provide the git commit you
|
||||||
|
have built or the tarball name.
|
||||||
|
|
||||||
|
As a last resort, use `libinput-list-devices --version`
|
||||||
|
|
||||||
|
@section reporting_bugs_reproducer Reproducing bugs
|
||||||
|
|
||||||
|
Try to identify the bug by reproducing it reliably. Bugs without a
|
||||||
|
reliable reproducer will have lowest priority. The more specific a bug
|
||||||
|
description and reproducer is, the easier it is to fix.
|
||||||
|
|
||||||
|
Try to replicate the series of events that lead to the bug being triggered.
|
||||||
|
Narrow it down until you have a reliable sequence that can trigger the bug.
|
||||||
|
For the vast majority of bugs you should not take longer than 5 seconds or
|
||||||
|
three interactions (clicks, touches, taps, ...) with the device to
|
||||||
|
reproduce. If it takes longer than that, you can narrow it down further.
|
||||||
|
|
||||||
|
Once you can reproduce it, use the @ref libinput-debug-events helper tool.
|
||||||
|
The output is textual and can help identify whether the bug is in libinput
|
||||||
|
at all. Note that any configuration options you have set must be specified
|
||||||
|
on the commandline, see the @ref libinput-debug-events
|
||||||
|
"libinput-debug-events" man page. Use the `--verbose` flag to get more
|
||||||
|
information about how libinput processes events.
|
||||||
|
|
||||||
|
If the bug cannot be reproduced with the @ref libinput-debug-events helper,
|
||||||
|
even with the correct configuration options set, it is likely not a bug in
|
||||||
|
libinput.
|
||||||
|
|
||||||
|
@section reporting_bugs_options libinput configuration settings
|
||||||
|
|
||||||
|
libinput has a number of device-specific default configuration settings that
|
||||||
|
may differ from the ones your desktop environment picks by default. You may
|
||||||
|
have changed some options in a settings panel or in an the xorg.conf snippet
|
||||||
|
yourself.
|
||||||
|
|
||||||
|
You must provide these options in the bug report, otherwise a developer
|
||||||
|
reproducing the issue may not be able to do so.
|
||||||
|
|
||||||
|
If you are on X11, the current settings can be can be obtained with
|
||||||
|
`xinput list-props "your device name"`. Use `xinput list` to
|
||||||
|
obtain the device name.
|
||||||
|
|
||||||
|
If you are on Wayland, provide a manual summary of the options you have
|
||||||
|
changed from the default (e.g. "I enabled tap-to-click").
|
||||||
|
|
||||||
|
@section reporting_bugs_touchpad Reporting touchpad bugs
|
||||||
|
|
||||||
|
When you file a bug, please attach the following information:
|
||||||
|
|
||||||
|
- a virtual description of your input device, see @ref evemu. This is the
|
||||||
|
most important piece of information, do not forget it!
|
||||||
|
- the output from udevadm info, see @ref udev_info.
|
||||||
|
- the vendor model number of your laptop (e.g. "Lenovo Thinkpad T440s")
|
||||||
|
- and the content of `/sys/class/dmi/id/modalias`.
|
||||||
|
- run the `touchpad-edge-detectior` tool (provided by libevdev) and verify
|
||||||
|
that the ranges and sizes it prints match the touchpad (up to 5mm
|
||||||
|
difference is ok)
|
||||||
|
|
||||||
|
If you are reporting a bug related to button event generation:
|
||||||
|
|
||||||
|
- does your touchpad have (separate) physical hardware buttons or is the
|
||||||
|
whole touchpad clickable?
|
||||||
|
- Are you using software buttons or clickfinger? See @ref
|
||||||
|
clickpad_softbuttons.
|
||||||
|
- Do you have @ref tapping enabled?
|
||||||
|
|
||||||
|
@section reporting_bugs_mouse Reporting mouse bugs
|
||||||
|
|
||||||
|
When you file a bug, please attach the following information:
|
||||||
|
|
||||||
|
- a virtual description of your input device, see @ref evemu. This is the
|
||||||
|
most important piece of information, do not forget it!
|
||||||
|
- the vendor model number of the device (e.g. "Logitech M325")
|
||||||
|
- the output from udevadm info, see @ref udev_info.
|
||||||
|
|
||||||
|
If the bug is related to the @ref motion_normalization_customization "speed of the mouse":
|
||||||
|
|
||||||
|
- the resolution of the mouse as specified by the vendor (in DPI)
|
||||||
|
- the output of the `mouse-dpi-tool` (provided by libevdev)
|
||||||
|
|
||||||
|
@section reporting_bugs_keyboard Reporting keyboard bugs
|
||||||
|
|
||||||
|
Is your bug related to a keyboard layout? libinput does not handle keyboard
|
||||||
|
layouts and merely forwards the physical key events. File the bug with your
|
||||||
|
desktop environment instead (e.g. GNOME, KDE, ...), that's most likely where
|
||||||
|
the issue is.
|
||||||
|
|
||||||
|
When you file a bug, please attach the following information:
|
||||||
|
|
||||||
|
- a virtual description of your input device, see @ref evemu. This is the
|
||||||
|
most important piece of information, do not forget it!
|
||||||
|
|
||||||
|
@section reporting_bugs_trackpoint Reporting trackpoint bugs
|
||||||
|
|
||||||
|
When you file a bug, please attach the following information:
|
||||||
|
|
||||||
|
- a virtual description of your input device, see @ref evemu. This is the
|
||||||
|
most important piece of information, do not forget it!
|
||||||
|
- the vendor model number of the device (e.g. "Logitech M325")
|
||||||
|
- the output from udevadm info, see @ref udev_info.
|
||||||
|
- the output of `libinput measure trackpoint-range`
|
||||||
|
- the sensitivity of the trackpoint (adjust the event node number as needed):
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
$ cat /sys/class/input/event17/device/device/sensitivity
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
@section reporting_bugs_other All other devices
|
||||||
|
|
||||||
|
When you file a bug, please attach the following information:
|
||||||
|
|
||||||
|
- a virtual description of your input device, see @ref evemu. This is the
|
||||||
|
most important piece of information, do not forget it!
|
||||||
|
- the vendor model number of the device (e.g. "Sony Plastation3 controller")
|
||||||
|
|
||||||
|
@section udev_info udev information for the device
|
||||||
|
|
||||||
|
In many cases, we require the udev properties assigned to the device to
|
||||||
|
verify whether device-specific quirks were applied. This can be obtained
|
||||||
|
with ````udevadm info /sys/class/input/eventX```, with the correct event
|
||||||
|
node for your device. An example output is below:
|
||||||
|
|
||||||
|
@code
|
||||||
|
$ udevadm info /sys/class/input/event4
|
||||||
|
P: /devices/platform/i8042/serio1/input/input5/event4
|
||||||
|
N: input/event4
|
||||||
|
E: DEVNAME=/dev/input/event4
|
||||||
|
E: DEVPATH=/devices/platform/i8042/serio1/input/input5/event4
|
||||||
|
E: EVDEV_ABS_00=::41
|
||||||
|
E: EVDEV_ABS_01=::37
|
||||||
|
E: EVDEV_ABS_35=::41
|
||||||
|
E: EVDEV_ABS_36=::37
|
||||||
|
E: ID_INPUT=1
|
||||||
|
E: ID_INPUT_HEIGHT_MM=66
|
||||||
|
E: ID_INPUT_TOUCHPAD=1
|
||||||
|
E: ID_INPUT_WIDTH_MM=97
|
||||||
|
E: MAJOR=13
|
||||||
|
E: MINOR=68
|
||||||
|
E: SUBSYSTEM=input
|
||||||
|
E: USEC_INITIALIZED=5463031
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@section evemu Recording devices with evemu
|
||||||
|
|
||||||
|
@note Where available, the @ref libinput-record tools should be used instead
|
||||||
|
of evemu
|
||||||
|
|
||||||
|
<a href="https://www.freedesktop.org/wiki/Evemu/">evemu</a> records the
|
||||||
|
device capabilities together with the event stream from the kernel. On our
|
||||||
|
side, this allows us to recreate a virtual device identical to your device
|
||||||
|
and re-play the event sequence, hopefully triggering the same bug.
|
||||||
|
|
||||||
|
evemu-record takes a <tt>/dev/input/eventX</tt> event node, but without arguments
|
||||||
|
it will simply show the list of devices and let you select:
|
||||||
|
@code
|
||||||
|
$ sudo evemu-record > scroll.evemu
|
||||||
|
Available devices:
|
||||||
|
/dev/input/event0: Lid Switch
|
||||||
|
/dev/input/event1: Sleep Button
|
||||||
|
/dev/input/event2: Power Button
|
||||||
|
/dev/input/event3: AT Translated Set 2 keyboard
|
||||||
|
/dev/input/event4: SynPS/2 Synaptics TouchPad
|
||||||
|
/dev/input/event5: Video Bus
|
||||||
|
/dev/input/event6: ELAN Touchscreen
|
||||||
|
/dev/input/event10: ThinkPad Extra Buttons
|
||||||
|
/dev/input/event11: HDA Intel HDMI HDMI/DP,pcm=3
|
||||||
|
/dev/input/event12: HDA Intel HDMI HDMI/DP,pcm=7
|
||||||
|
/dev/input/event13: HDA Intel HDMI HDMI/DP,pcm=8
|
||||||
|
/dev/input/event14: HDA Intel PCH Dock Mic
|
||||||
|
/dev/input/event15: HDA Intel PCH Mic
|
||||||
|
/dev/input/event16: HDA Intel PCH Dock Headphone
|
||||||
|
/dev/input/event17: HDA Intel PCH Headphone
|
||||||
|
/dev/input/event18: Integrated Camera
|
||||||
|
/dev/input/event19: TPPS/2 IBM TrackPoint
|
||||||
|
Select the device event number [0-19]:
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Select the device that triggers the issue, then reproduce the bug and Ctrl+C
|
||||||
|
the process. The resulting recording, ("scroll.evemu" in this example) will
|
||||||
|
contain the sequence required to reproduce the bug. If the bug fails to
|
||||||
|
reproduce during recording, simply Ctrl+C and restart evemu-record.
|
||||||
|
Always start the recording from a neutral state, i.e. without any buttons or
|
||||||
|
keys down, with the position of the device in the neutral position, without
|
||||||
|
touching the screen/touchpad.
|
||||||
|
|
||||||
|
@note The longer the recording, the harder it is to identify the event
|
||||||
|
sequence triggering the bug. Please keep the event sequence as short as possible.
|
||||||
|
|
||||||
|
To verify that the recording contains the bug, you can replay it on your
|
||||||
|
device. For example, to replay the sequence recorded in the example above:
|
||||||
|
@code
|
||||||
|
$ sudo evemu-play /dev/input/event4 < scroll.evemu
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
If the bug is triggered by replaying on your device, attach the recording to
|
||||||
|
the bug report.
|
||||||
|
|
||||||
|
@note libinput does not affect the evemu recording. libinput and evemu talk
|
||||||
|
directly to the kernel's device nodes. An evemu recording is not influenced
|
||||||
|
by the libinput version or whether a libinput context is currently active.
|
||||||
|
|
||||||
|
@dotfile evemu.gv
|
||||||
|
|
||||||
|
@section fixed_bugs My bug was closed as fixed, what now?
|
||||||
|
|
||||||
|
libinput's policy on closing bugs is: once the fix for a given bug is on git
|
||||||
|
master, the bug is considered fixed and the bugzilla entry will be closed
|
||||||
|
accordingly.
|
||||||
|
|
||||||
|
Of course, unless you actually run git master, the bug will continue to
|
||||||
|
affect you on your local machine. You are most likely running the
|
||||||
|
distribution's package and you will need to wait until the distribution has
|
||||||
|
updated its package accordingly.
|
||||||
|
|
||||||
|
<b>Do not re-open a bug just because it hasn't trickled down to your
|
||||||
|
distribution's package version yet.</b>
|
||||||
|
|
||||||
|
Whether the bug fix ends up in your distribution depends on a number of
|
||||||
|
things. Any given bug fix **may** be cherry-picked into the current stable
|
||||||
|
branch, depending on its severity, impact, and likelyhood to cause
|
||||||
|
regressions. Once cherry-picked it will land in the next stable branch
|
||||||
|
release. These are usually a few weeks apart.
|
||||||
|
|
||||||
|
<b>Do not re-open a bug because it wasn't picked into a stable branch
|
||||||
|
release or because your distribution didn't update to the latest stable
|
||||||
|
branch release.</b>
|
||||||
|
|
||||||
|
Stable branches are usually discontinued when the next release comes out.
|
||||||
|
|
||||||
|
Your distribution may pick a patch up immediately and ship the fix
|
||||||
|
even before the next stable branch update is released. For example, Fedora
|
||||||
|
does this frequently.
|
||||||
|
|
||||||
|
<b>If a bug needs to be fixed urgently, file a bug in your distribution's
|
||||||
|
bug tracker.</b>
|
||||||
|
|
||||||
|
Patches on git master will end up in the next libinput release. Once your
|
||||||
|
distribution updates to that release, your local libinput version will
|
||||||
|
contain the fix.
|
||||||
|
|
||||||
|
<b>Do not re-open a bug because your distribution didn't update to the
|
||||||
|
release.</b>
|
||||||
|
|
||||||
|
You can always run libinput from git master (see @ref building_libinput).
|
||||||
|
Even while in development, libinput is very stable so this option isn't as
|
||||||
|
scary as it may sounds.
|
||||||
|
|
||||||
|
@subsection reporting_bugs_reopen When is it ok to re-open a fixed bug?
|
||||||
|
|
||||||
|
Any time the bug was considered fixed but it turns out that the fix is
|
||||||
|
insufficient and/or causes a regression.
|
||||||
|
|
||||||
|
However, if the regression is in behavior unrelated to the fix itself it is
|
||||||
|
usually better to file a new bug to reduce the noise. For example, if a fix
|
||||||
|
to improve tapping breaks two-finger scrolling behavior, you should file a
|
||||||
|
new bug but reference the original bug.
|
||||||
|
|
||||||
|
*/
|
||||||
106
doc/scrolling.dox
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
/**
|
||||||
|
@page scrolling Scrolling
|
||||||
|
|
||||||
|
libinput supports three different types of scrolling methods: @ref
|
||||||
|
twofinger_scrolling, @ref edge_scrolling and @ref button_scrolling. Some
|
||||||
|
devices support multiple methods, though only one can be enabled at a time.
|
||||||
|
As a general overview:
|
||||||
|
- touchpad devices with physical buttons below the touchpad support edge and
|
||||||
|
two-finger scrolling
|
||||||
|
- touchpad devices without physical buttons (@ref clickpad_softbuttons
|
||||||
|
"clickpads") support two-finger scrolling only
|
||||||
|
- pointing sticks provide on-button scrolling by default
|
||||||
|
- mice and other pointing devices support on-button scrolling but it is not
|
||||||
|
enabled by default
|
||||||
|
|
||||||
|
A device may differ from the above based on its capabilities. See
|
||||||
|
libinput_device_config_scroll_set_method() for documentation on how to
|
||||||
|
switch methods and libinput_device_config_scroll_get_methods() for
|
||||||
|
documentation on how to query a device for available scroll methods.
|
||||||
|
|
||||||
|
@section horizontal_scrolling Horizontal scrolling
|
||||||
|
|
||||||
|
Scroll movements provide vertical and horizontal directions, each
|
||||||
|
scroll event contains both directions where applicable, see
|
||||||
|
libinput_event_pointer_get_axis_value(). libinput does not provide separate
|
||||||
|
toggles to enable or disable horizontal scrolling. Instead, horizontal
|
||||||
|
scrolling is always enabled. This is intentional, libinput does not have
|
||||||
|
enough context to know when horizontal scrolling is appropriate for a given
|
||||||
|
widget. The task of filtering horizontal movements is up to the caller.
|
||||||
|
|
||||||
|
@section twofinger_scrolling Two-finger scrolling
|
||||||
|
|
||||||
|
The default on two-finger capable touchpads (almost all modern touchpads are
|
||||||
|
capable of detecting two fingers). Scrolling is triggered by two fingers
|
||||||
|
being placed on the surface of the touchpad, then moving those fingers
|
||||||
|
vertically or horizontally.
|
||||||
|
|
||||||
|
@image html twofinger-scrolling.svg "Vertical and horizontal two-finger scrolling"
|
||||||
|
|
||||||
|
For scrolling to trigger, a built-in distance threshold has to be met but once
|
||||||
|
engaged any movement will scroll. In other words, to start scrolling a
|
||||||
|
sufficiently large movement is required, once scrolling tiny amounts of
|
||||||
|
movements will translate into tiny scroll movements.
|
||||||
|
Scrolling in both directions at once is possible by meeting the required
|
||||||
|
distance thresholds to enable each direction separately.
|
||||||
|
|
||||||
|
Two-finger scrolling requires the touchpad to track both touch points with
|
||||||
|
reasonable precision. Unfortunately, some so-called "semi-mt" touchpads can
|
||||||
|
only track the bounding box of the two fingers rather than the actual
|
||||||
|
position of each finger. In addition, that bounding box usually suffers from
|
||||||
|
a low resolution, causing jumpy movement during two-finger scrolling.
|
||||||
|
libinput does not provide two-finger scrolling on those touchpads.
|
||||||
|
|
||||||
|
@section edge_scrolling Edge scrolling
|
||||||
|
|
||||||
|
On some touchpads, edge scrolling is available, triggered by moving a single
|
||||||
|
finger along the right edge (vertical scroll) or bottom edge (horizontal
|
||||||
|
scroll).
|
||||||
|
|
||||||
|
@image html edge-scrolling.svg "Vertical and horizontal edge scrolling"
|
||||||
|
|
||||||
|
Due to the layout of the edges, diagonal scrolling is not possible. The
|
||||||
|
behavior of edge scrolling using both edges at the same time is undefined.
|
||||||
|
|
||||||
|
Edge scrolling overlaps with @ref clickpad_softbuttons. A physical click on
|
||||||
|
a clickpad ends scrolling.
|
||||||
|
|
||||||
|
@section button_scrolling On-Button scrolling
|
||||||
|
|
||||||
|
On-button scrolling converts the motion of a device into scroll events while
|
||||||
|
a designated button is held down. For example, Lenovo devices provide a
|
||||||
|
<a href="http://en.wikipedia.org/wiki/Pointing_stick">pointing stick</a> that emulates
|
||||||
|
scroll events when the trackstick's middle mouse button is held down.
|
||||||
|
|
||||||
|
@note On-button scrolling is enabled by default for pointing sticks. This
|
||||||
|
prevents middle-button dragging; all motion events while the middle button is
|
||||||
|
down are converted to scroll events.
|
||||||
|
|
||||||
|
@image html button-scrolling.svg "Button scrolling"
|
||||||
|
|
||||||
|
The button may be changed with
|
||||||
|
libinput_device_config_scroll_set_button() but must be on the same device as
|
||||||
|
the motion events. Cross-device scrolling is not supported but
|
||||||
|
for one exception: libinput's @ref t440_support enables the use of the middle
|
||||||
|
button for button scrolling (even when the touchpad is disabled).
|
||||||
|
|
||||||
|
@section scroll_sources Scroll sources
|
||||||
|
|
||||||
|
libinput provides a pointer axis *source* for each scroll event. The
|
||||||
|
source can be obtained with the libinput_event_pointer_get_axis_source()
|
||||||
|
function and is one of **wheel**, **finger**, or **continuous**. The source
|
||||||
|
information lets a caller decide when to implement kinetic scrolling.
|
||||||
|
Usually, a caller will process events of source wheel as they come in.
|
||||||
|
For events of source finger a caller should calculate the velocity of the
|
||||||
|
scroll motion and upon finger release start a kinetic scrolling motion (i.e.
|
||||||
|
continue executing a scroll according to some friction factor).
|
||||||
|
libinput expects the caller to be in charge of widget handling, the source
|
||||||
|
information is thus enough to provide kinetic scrolling on a per-widget
|
||||||
|
basis. A caller should cancel kinetic scrolling when the pointer leaves the
|
||||||
|
current widget or when a key is pressed.
|
||||||
|
|
||||||
|
See the libinput_event_pointer_get_axis_source() for details on the
|
||||||
|
behavior of each scroll source.
|
||||||
|
|
||||||
|
See also http://who-t.blogspot.com.au/2015/03/libinput-scroll-sources.html
|
||||||
|
*/
|
||||||
|
|
@ -1,8 +1,5 @@
|
||||||
.. _seats:
|
/**
|
||||||
|
@page seats Seats
|
||||||
==============================================================================
|
|
||||||
Seats
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
Each device in libinput is assigned to one seat.
|
Each device in libinput is assigned to one seat.
|
||||||
A seat has two identifiers, the physical name and the logical name. The
|
A seat has two identifiers, the physical name and the logical name. The
|
||||||
|
|
@ -13,15 +10,11 @@ seats as independent device sets. Alternatively, a compositor may limit
|
||||||
itself to a single logical seat, leaving a second compositor to manage
|
itself to a single logical seat, leaving a second compositor to manage
|
||||||
devices on the other logical seats.
|
devices on the other logical seats.
|
||||||
|
|
||||||
.. _seats_overview:
|
@section Overview
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Overview
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Below is an illustration of how physical seats and logical seats interact:
|
Below is an illustration of how physical seats and logical seats interact:
|
||||||
|
|
||||||
.. graphviz:: seats-sketch.gv
|
@dotfile seats-sketch.gv
|
||||||
|
|
||||||
The devices "Foo", "Bar" and "Spam" share the same physical seat and are
|
The devices "Foo", "Bar" and "Spam" share the same physical seat and are
|
||||||
thus available in the same libinput context. Only "Foo" and "Bar" share the
|
thus available in the same libinput context. Only "Foo" and "Bar" share the
|
||||||
|
|
@ -29,19 +22,15 @@ same logical seat. The device "Egg" is not available in the libinput context
|
||||||
associated with the physical seat 0.
|
associated with the physical seat 0.
|
||||||
|
|
||||||
The above graph is for illustration purposes only. In libinput, a struct
|
The above graph is for illustration purposes only. In libinput, a struct
|
||||||
**libinput_seat** comprises both physical seat and logical seat. From a
|
@ref libinput_seat comprises both physical seat and logical seat. From a
|
||||||
caller's point-of-view the above device layout is presented as:
|
caller's point-of-view the above device layout is presented as:
|
||||||
|
|
||||||
.. graphviz:: seats-sketch-libinput.gv
|
@dotfile seats-sketch-libinput.gv
|
||||||
|
|
||||||
Thus, devices "Foo" and "Bar" both reference the same struct
|
Thus, devices "Foo" and "Bar" both reference the same struct @ref
|
||||||
**libinput_seat**, all other devices reference their own respective seats.
|
libinput_seat, all other devices reference their own respective seats.
|
||||||
|
|
||||||
.. _seats_and_features:
|
@section seats_and_features The effect of seat assignment
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
The effect of seat assignment
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
A logical set is interpreted as a group of devices that usually belong to a
|
A logical set is interpreted as a group of devices that usually belong to a
|
||||||
single user that interacts with a computer. Thus, the devices are
|
single user that interacts with a computer. Thus, the devices are
|
||||||
|
|
@ -59,27 +48,26 @@ semantically related. This means for devices within the same logical seat:
|
||||||
two touches down.
|
two touches down.
|
||||||
|
|
||||||
libinput provides functions to aid with the above:
|
libinput provides functions to aid with the above:
|
||||||
**libinput_event_pointer_get_seat_button_count()**,
|
libinput_event_pointer_get_seat_button_count(),
|
||||||
**libinput_event_keyboard_get_seat_key_count()**, and
|
libinput_event_keyboard_get_seat_key_count(), and
|
||||||
**libinput_event_touch_get_seat_slot()**.
|
libinput_event_touch_get_seat_slot().
|
||||||
|
|
||||||
Internally, libinput counts devices within the same logical seat as related.
|
Internally, libinput counts devices within the same logical seat as related.
|
||||||
Cross-device features only activate if all required devices are in the same
|
Cross-device features only activate if all required devices are in the same
|
||||||
logical seat. For example, libinput will only activate the top software
|
logical seat. For example, libinput will only activate the top software
|
||||||
buttons (see :ref:`t440_support`) if both trackstick and touchpad are assigned
|
buttons (see @ref t440_support) if both trackstick and touchpad are assigned
|
||||||
to the same logical seat.
|
to the same logical seat.
|
||||||
|
|
||||||
|
|
||||||
.. _changing_seats:
|
@section changing_seats Changing seats
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Changing seats
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
A device may change the logical seat it is assigned to at runtime with
|
A device may change the logical seat it is assigned to at runtime with
|
||||||
**libinput_device_set_seat_logical_name()**. The physical seat is immutable and
|
libinput_device_set_seat_logical_name(). The physical seat is immutable and
|
||||||
may not be changed.
|
may not be changed.
|
||||||
|
|
||||||
Changing the logical seat for a device is equivalent to unplugging the
|
Changing the logical seat for a device is equivalent to unplugging the
|
||||||
device and plugging it back in with the new logical seat. No device state
|
device and plugging it back in with the new logical seat. No device state
|
||||||
carries over across a logical seat change.
|
carries over across a logical seat change.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
@ -252,3 +252,4 @@ blockquote {
|
||||||
margin: 0 24px 0 4px;
|
margin: 0 24px 0 4px;
|
||||||
padding: 0 12px 0 16px;
|
padding: 0 12px 0 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
47
doc/style/libinputdoxygen.css
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
dd {
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 400%;
|
||||||
|
font-weight: 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 300%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 200%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm-dox li {
|
||||||
|
float:left;
|
||||||
|
border-top: 0;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm li, .sm a {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm, .sm ul, .sm li {
|
||||||
|
list-style: none;
|
||||||
|
display: block;
|
||||||
|
line-height: normal;
|
||||||
|
direction: ltr;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sm, .sm *, .sm *::before, .sm *::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-nav {
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main menu sub-items like file-list, etc */
|
||||||
|
#main-menu li ul {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 7 KiB After Width: | Height: | Size: 7 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
|
@ -138,6 +138,13 @@
|
||||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6, 1;stroke-dashoffset:0;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow1Lend-2)"
|
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:6, 1;stroke-dashoffset:0;stroke-opacity:1;marker-mid:none;marker-end:url(#Arrow1Lend-2)"
|
||||||
id="path13492"
|
id="path13492"
|
||||||
d="m 38.928571,67.914286 c 0,0 3.508205,24.810617 9.642857,57.857144 6.134651,33.04652 23.277202,79.68584 89.642852,90.35714" />
|
d="m 38.928571,67.914286 c 0,0 3.508205,24.810617 9.642857,57.857144 6.134651,33.04652 23.277202,79.68584 89.642852,90.35714" />
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:0.3559322;fill-rule:evenodd;stroke:none;stroke-width:3.30510259px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
id="rect3490"
|
||||||
|
width="65.310997"
|
||||||
|
height="136.12065"
|
||||||
|
x="7.0411549"
|
||||||
|
y="7.1355872" />
|
||||||
<text
|
<text
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:0%;font-family:Utopia;-inkscape-font-specification:Utopia;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none"
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:0%;font-family:Utopia;-inkscape-font-specification:Utopia;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none"
|
||||||
xml:space="preserve"
|
xml:space="preserve"
|
||||||
|
|
@ -148,6 +155,13 @@
|
||||||
id="tspan13876"
|
id="tspan13876"
|
||||||
y="63.628628"
|
y="63.628628"
|
||||||
x="33.214291">A</tspan></text>
|
x="33.214291">A</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:#000000;fill-opacity:0.3559322;fill-rule:evenodd;stroke:none;stroke-width:3.30527353px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
id="rect3490-2"
|
||||||
|
width="65.272476"
|
||||||
|
height="136.21509"
|
||||||
|
x="321.22849"
|
||||||
|
y="6.8830237" />
|
||||||
<text
|
<text
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:0%;font-family:Utopia;-inkscape-font-specification:Utopia;text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:0%;font-family:Utopia;-inkscape-font-specification:Utopia;text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||||
xml:space="preserve"
|
xml:space="preserve"
|
||||||
|
|
@ -177,6 +191,16 @@
|
||||||
id="tspan13876-7-9"
|
id="tspan13876-7-9"
|
||||||
y="46.009491"
|
y="46.009491"
|
||||||
x="342.27759">C</tspan></text>
|
x="342.27759">C</tspan></text>
|
||||||
|
<text
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:0%;font-family:Utopia;-inkscape-font-specification:Utopia;text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
xml:space="preserve"
|
||||||
|
id="text13874-8-1-4"
|
||||||
|
y="215.65927"
|
||||||
|
x="37.970726"><tspan
|
||||||
|
style="font-size:18px;font-family:Arial;-inkscape-font-specification:Arial"
|
||||||
|
id="tspan13876-7-9-5"
|
||||||
|
y="215.65927"
|
||||||
|
x="37.970726">D</tspan></text>
|
||||||
<circle
|
<circle
|
||||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-opacity:1"
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||||
id="path4401"
|
id="path4401"
|
||||||
|
|
@ -184,6 +208,13 @@
|
||||||
cy="24.53549"
|
cy="24.53549"
|
||||||
r="4.0658817"
|
r="4.0658817"
|
||||||
transform="scale(-1,1)" />
|
transform="scale(-1,1)" />
|
||||||
|
<circle
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||||
|
id="path4401-9"
|
||||||
|
cx="-36.452721"
|
||||||
|
cy="194.8819"
|
||||||
|
r="4.0658817"
|
||||||
|
transform="scale(-1,1)" />
|
||||||
<rect
|
<rect
|
||||||
width="248.87633"
|
width="248.87633"
|
||||||
height="6.8111157"
|
height="6.8111157"
|
||||||
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
|
@ -516,3 +516,4 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
|
@ -3745,3 +3745,4 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 377 KiB After Width: | Height: | Size: 377 KiB |
|
|
@ -577,3 +577,4 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
|
@ -77,28 +77,23 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
<path stroke='black' d='M159.2,422.4 L159.2,413.4 M159.2,16.7 L159.2,25.7 '/> <g transform="translate(159.2,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
|
<path stroke='black' d='M185.2,422.4 L185.2,413.4 M185.2,16.7 L185.2,25.7 '/> <g transform="translate(185.2,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
|
||||||
<text><tspan font-family="Arial" > 0.2</tspan></text>
|
<text><tspan font-family="Arial" > 5</tspan></text>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
<path stroke='black' d='M263.2,422.4 L263.2,413.4 M263.2,16.7 L263.2,25.7 '/> <g transform="translate(263.2,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
|
<path stroke='black' d='M315.2,422.4 L315.2,413.4 M315.2,16.7 L315.2,25.7 '/> <g transform="translate(315.2,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
|
||||||
<text><tspan font-family="Arial" > 0.4</tspan></text>
|
<text><tspan font-family="Arial" > 10</tspan></text>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
<path stroke='black' d='M367.1,422.4 L367.1,413.4 M367.1,16.7 L367.1,25.7 '/> <g transform="translate(367.1,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
|
<path stroke='black' d='M445.1,422.4 L445.1,413.4 M445.1,16.7 L445.1,25.7 '/> <g transform="translate(445.1,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
|
||||||
<text><tspan font-family="Arial" > 0.6</tspan></text>
|
<text><tspan font-family="Arial" > 15</tspan></text>
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
|
||||||
<path stroke='black' d='M471.1,422.4 L471.1,413.4 M471.1,16.7 L471.1,25.7 '/> <g transform="translate(471.1,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
|
|
||||||
<text><tspan font-family="Arial" > 0.8</tspan></text>
|
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
<path stroke='black' d='M575.0,422.4 L575.0,413.4 M575.0,16.7 L575.0,25.7 '/> <g transform="translate(575.0,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
|
<path stroke='black' d='M575.0,422.4 L575.0,413.4 M575.0,16.7 L575.0,25.7 '/> <g transform="translate(575.0,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
|
||||||
<text><tspan font-family="Arial" > 1</tspan></text>
|
<text><tspan font-family="Arial" > 20</tspan></text>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
|
|
@ -112,7 +107,7 @@
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
<g transform="translate(315.1,471.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
|
<g transform="translate(315.1,471.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
|
||||||
<text><tspan font-family="Arial" >delta (units/ms)</tspan></text>
|
<text><tspan font-family="Arial" >delta (units)</tspan></text>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
|
|
@ -124,10 +119,19 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
<path stroke='rgb(148, 0, 211)' d='M516.2,34.7 L558.4,34.7 M55.3,421.2 L75.8,420.3 L96.2,419.2 L116.7,418.0 L137.1,416.9 L157.6,415.8
|
<path stroke='rgb(148, 0, 211)' d='M516.2,34.7 L558.4,34.7 M55.3,422.4 L60.5,418.5 L65.7,414.6 L70.9,410.7 L76.1,406.8 L81.3,402.9
|
||||||
L178.1,414.7 L198.5,413.7 L219.0,412.8 L239.4,411.8 L259.9,410.9 L280.4,410.1 L300.8,409.3 L321.3,408.5
|
L86.5,399.0 L91.7,395.1 L96.9,391.2 L102.1,387.3 L107.3,383.5 L112.5,379.6 L117.7,375.7 L122.9,371.8
|
||||||
L341.7,407.8 L362.2,407.1 L382.7,406.4 L403.1,405.8 L423.6,405.2 L444.1,404.6 L464.5,404.1 L485.0,403.5
|
L128.1,367.9 L133.3,364.0 L138.5,360.1 L143.6,356.2 L148.8,352.3 L154.0,348.4 L159.2,344.5 L164.4,340.6
|
||||||
L505.4,403.0 L525.9,402.6 L546.4,402.1 L566.8,401.7 L575.0,401.5 '/></g>
|
L169.6,336.7 L174.8,332.8 L180.0,328.9 L185.2,325.0 L190.4,321.1 L195.6,317.2 L200.8,313.3 L206.0,310.0
|
||||||
|
L211.2,310.0 L216.4,310.0 L221.6,310.0 L226.8,310.0 L232.0,310.0 L237.2,310.0 L242.4,310.0 L247.6,310.0
|
||||||
|
L252.8,310.0 L258.0,310.0 L263.2,310.0 L268.4,310.0 L273.6,310.0 L278.8,310.0 L284.0,310.0 L289.2,310.0
|
||||||
|
L294.4,310.0 L299.6,310.0 L304.8,310.0 L310.0,310.0 L315.2,310.0 L320.3,310.0 L325.5,310.0 L330.7,310.0
|
||||||
|
L335.9,310.0 L341.1,310.0 L346.3,310.0 L351.5,310.0 L356.7,310.0 L361.9,310.0 L367.1,310.0 L372.3,310.0
|
||||||
|
L377.5,310.0 L382.7,310.0 L387.9,310.0 L393.1,310.0 L398.3,310.0 L403.5,310.0 L408.7,310.0 L413.9,310.0
|
||||||
|
L419.1,310.0 L424.3,310.0 L429.5,310.0 L434.7,310.0 L439.9,310.0 L445.1,310.0 L450.3,310.0 L455.5,310.0
|
||||||
|
L460.7,310.0 L465.9,310.0 L471.1,310.0 L476.3,310.0 L481.5,310.0 L486.7,310.0 L491.8,310.0 L497.0,310.0
|
||||||
|
L502.2,310.0 L507.4,310.0 L512.6,310.0 L517.8,310.0 L523.0,310.0 L528.2,310.0 L533.4,310.0 L538.6,310.0
|
||||||
|
L543.8,310.0 L549.0,310.0 L554.2,310.0 L559.4,310.0 L564.6,310.0 L569.8,310.0 L575.0,310.0 '/></g>
|
||||||
</g>
|
</g>
|
||||||
<g id="gnuplot_plot_2" ><title>-0.75</title>
|
<g id="gnuplot_plot_2" ><title>-0.75</title>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
|
|
@ -136,10 +140,19 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
<path stroke='rgb( 0, 158, 115)' d='M516.2,52.7 L558.4,52.7 M55.3,420.4 L75.8,418.7 L96.2,416.7 L116.7,414.8 L137.1,412.8 L157.6,410.9
|
<path stroke='rgb( 0, 158, 115)' d='M516.2,52.7 L558.4,52.7 M55.3,422.4 L60.5,415.3 L65.7,408.1 L70.9,401.0 L76.1,393.8 L81.3,386.7
|
||||||
L178.1,409.1 L198.5,407.3 L219.0,405.6 L239.4,404.0 L259.9,402.4 L280.4,401.0 L300.8,399.6 L321.3,398.2
|
L86.5,379.6 L91.7,372.4 L96.9,365.3 L102.1,358.1 L107.3,351.0 L112.5,343.9 L117.7,336.7 L122.9,329.6
|
||||||
L341.7,397.0 L362.2,395.8 L382.7,394.6 L403.1,393.5 L423.6,392.5 L444.1,391.4 L464.5,390.5 L485.0,389.6
|
L128.1,322.4 L133.3,315.3 L138.5,308.2 L143.6,301.0 L148.8,293.9 L154.0,286.7 L159.2,279.6 L164.4,272.5
|
||||||
L505.4,388.7 L525.9,387.8 L546.4,387.0 L566.8,386.3 L575.0,386.0 '/></g>
|
L169.6,270.7 L174.8,270.7 L180.0,270.7 L185.2,270.7 L190.4,270.7 L195.6,270.7 L200.8,270.7 L206.0,270.7
|
||||||
|
L211.2,270.7 L216.4,270.7 L221.6,270.7 L226.8,270.7 L232.0,270.7 L237.2,270.7 L242.4,270.7 L247.6,270.7
|
||||||
|
L252.8,270.7 L258.0,270.7 L263.2,270.7 L268.4,270.7 L273.6,270.7 L278.8,270.7 L284.0,270.7 L289.2,270.7
|
||||||
|
L294.4,270.7 L299.6,270.7 L304.8,270.7 L310.0,270.7 L315.2,270.7 L320.3,270.7 L325.5,270.7 L330.7,270.7
|
||||||
|
L335.9,270.7 L341.1,270.7 L346.3,270.7 L351.5,270.7 L356.7,270.7 L361.9,270.7 L367.1,270.7 L372.3,270.7
|
||||||
|
L377.5,270.7 L382.7,270.7 L387.9,270.7 L393.1,270.7 L398.3,270.7 L403.5,270.7 L408.7,270.7 L413.9,270.7
|
||||||
|
L419.1,270.7 L424.3,270.7 L429.5,270.7 L434.7,270.7 L439.9,270.7 L445.1,270.7 L450.3,270.7 L455.5,270.7
|
||||||
|
L460.7,270.7 L465.9,270.7 L471.1,270.7 L476.3,270.7 L481.5,270.7 L486.7,270.7 L491.8,270.7 L497.0,270.7
|
||||||
|
L502.2,270.7 L507.4,270.7 L512.6,270.7 L517.8,270.7 L523.0,270.7 L528.2,270.7 L533.4,270.7 L538.6,270.7
|
||||||
|
L543.8,270.7 L549.0,270.7 L554.2,270.7 L559.4,270.7 L564.6,270.7 L569.8,270.7 L575.0,270.7 '/></g>
|
||||||
</g>
|
</g>
|
||||||
<g id="gnuplot_plot_3" ><title>-0.5</title>
|
<g id="gnuplot_plot_3" ><title>-0.5</title>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
|
|
@ -148,10 +161,19 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
<path stroke='rgb( 86, 180, 233)' d='M516.2,70.7 L558.4,70.7 M55.3,416.8 L75.8,412.1 L96.2,406.6 L116.7,401.1 L137.1,395.6 L157.6,390.3
|
<path stroke='rgb( 86, 180, 233)' d='M516.2,70.7 L558.4,70.7 M55.3,422.4 L60.5,412.0 L65.7,401.6 L70.9,391.2 L76.1,380.9 L81.3,370.5
|
||||||
L178.1,385.2 L198.5,380.3 L219.0,375.6 L239.4,371.1 L259.9,366.8 L280.4,362.7 L300.8,358.8 L321.3,355.1
|
L86.5,360.1 L91.7,349.7 L96.9,339.3 L102.1,328.9 L107.3,318.5 L112.5,308.2 L117.7,297.8 L122.9,287.4
|
||||||
L341.7,351.6 L362.2,348.2 L382.7,345.0 L403.1,341.9 L423.6,338.9 L444.1,336.1 L464.5,333.5 L485.0,330.9
|
L128.1,277.0 L133.3,266.6 L138.5,256.2 L143.6,245.8 L148.8,235.5 L154.0,225.1 L159.2,217.6 L164.4,217.6
|
||||||
L505.4,328.5 L525.9,326.1 L546.4,323.9 L566.8,321.7 L575.0,320.9 '/></g>
|
L169.6,217.6 L174.8,217.6 L180.0,217.6 L185.2,217.6 L190.4,217.6 L195.6,217.6 L200.8,217.6 L206.0,217.6
|
||||||
|
L211.2,217.6 L216.4,217.6 L221.6,217.6 L226.8,217.6 L232.0,217.6 L237.2,217.6 L242.4,217.6 L247.6,217.6
|
||||||
|
L252.8,217.6 L258.0,217.6 L263.2,217.6 L268.4,217.6 L273.6,217.6 L278.8,217.6 L284.0,217.6 L289.2,217.6
|
||||||
|
L294.4,217.6 L299.6,217.6 L304.8,217.6 L310.0,217.6 L315.2,217.6 L320.3,217.6 L325.5,217.6 L330.7,217.6
|
||||||
|
L335.9,217.6 L341.1,217.6 L346.3,217.6 L351.5,217.6 L356.7,217.6 L361.9,217.6 L367.1,217.6 L372.3,217.6
|
||||||
|
L377.5,217.6 L382.7,217.6 L387.9,217.6 L393.1,217.6 L398.3,217.6 L403.5,217.6 L408.7,217.6 L413.9,217.6
|
||||||
|
L419.1,217.6 L424.3,217.6 L429.5,217.6 L434.7,217.6 L439.9,217.6 L445.1,217.6 L450.3,217.6 L455.5,217.6
|
||||||
|
L460.7,217.6 L465.9,217.6 L471.1,217.6 L476.3,217.6 L481.5,217.6 L486.7,217.6 L491.8,217.6 L497.0,217.6
|
||||||
|
L502.2,217.6 L507.4,217.6 L512.6,217.6 L517.8,217.6 L523.0,217.6 L528.2,217.6 L533.4,217.6 L538.6,217.6
|
||||||
|
L543.8,217.6 L549.0,217.6 L554.2,217.6 L559.4,217.6 L564.6,217.6 L569.8,217.6 L575.0,217.6 '/></g>
|
||||||
</g>
|
</g>
|
||||||
<g id="gnuplot_plot_4" ><title>-0.25</title>
|
<g id="gnuplot_plot_4" ><title>-0.25</title>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
|
|
@ -160,10 +182,19 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
<path stroke='rgb(230, 159, 0)' d='M516.2,88.7 L558.4,88.7 M55.3,409.5 L75.8,398.8 L96.2,386.3 L116.7,373.7 L137.1,361.2 L157.6,349.1
|
<path stroke='rgb(230, 159, 0)' d='M516.2,88.7 L558.4,88.7 M55.3,422.4 L60.5,408.8 L65.7,395.1 L70.9,381.5 L76.1,367.9 L81.3,354.2
|
||||||
L178.1,337.4 L198.5,326.1 L219.0,315.3 L239.4,305.0 L259.9,295.2 L280.4,285.9 L300.8,276.9 L321.3,268.4
|
L86.5,340.6 L91.7,327.0 L96.9,313.3 L102.1,299.7 L107.3,286.1 L112.5,272.5 L117.7,258.8 L122.9,245.2
|
||||||
L341.7,260.3 L362.2,252.6 L382.7,245.2 L403.1,238.2 L423.6,231.5 L444.1,225.1 L464.5,218.9 L485.0,213.1
|
L128.1,231.6 L133.3,217.9 L138.5,204.3 L143.6,190.7 L148.8,177.0 L154.0,163.4 L159.2,149.8 L164.4,145.9
|
||||||
L505.4,207.5 L525.9,202.1 L546.4,197.0 L566.8,192.1 L575.0,190.2 '/></g>
|
L169.6,145.9 L174.8,145.9 L180.0,145.9 L185.2,145.9 L190.4,145.9 L195.6,145.9 L200.8,145.9 L206.0,145.9
|
||||||
|
L211.2,145.9 L216.4,145.9 L221.6,145.9 L226.8,145.9 L232.0,145.9 L237.2,145.9 L242.4,145.9 L247.6,145.9
|
||||||
|
L252.8,145.9 L258.0,145.9 L263.2,145.9 L268.4,145.9 L273.6,145.9 L278.8,145.9 L284.0,145.9 L289.2,145.9
|
||||||
|
L294.4,145.9 L299.6,145.9 L304.8,145.9 L310.0,145.9 L315.2,145.9 L320.3,145.9 L325.5,145.9 L330.7,145.9
|
||||||
|
L335.9,145.9 L341.1,145.9 L346.3,145.9 L351.5,145.9 L356.7,145.9 L361.9,145.9 L367.1,145.9 L372.3,145.9
|
||||||
|
L377.5,145.9 L382.7,145.9 L387.9,145.9 L393.1,145.9 L398.3,145.9 L403.5,145.9 L408.7,145.9 L413.9,145.9
|
||||||
|
L419.1,145.9 L424.3,145.9 L429.5,145.9 L434.7,145.9 L439.9,145.9 L445.1,145.9 L450.3,145.9 L455.5,145.9
|
||||||
|
L460.7,145.9 L465.9,145.9 L471.1,145.9 L476.3,145.9 L481.5,145.9 L486.7,145.9 L491.8,145.9 L497.0,145.9
|
||||||
|
L502.2,145.9 L507.4,145.9 L512.6,145.9 L517.8,145.9 L523.0,145.9 L528.2,145.9 L533.4,145.9 L538.6,145.9
|
||||||
|
L543.8,145.9 L549.0,145.9 L554.2,145.9 L559.4,145.9 L564.6,145.9 L569.8,145.9 L575.0,145.9 '/></g>
|
||||||
</g>
|
</g>
|
||||||
<g id="gnuplot_plot_5" ><title>0</title>
|
<g id="gnuplot_plot_5" ><title>0</title>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
|
|
@ -172,10 +203,19 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
<path stroke='rgb(240, 228, 66)' d='M516.2,106.7 L558.4,106.7 M55.3,398.0 L75.8,377.7 L96.2,354.1 L116.7,330.2 L137.1,306.6 L157.6,283.6
|
<path stroke='rgb(240, 228, 66)' d='M516.2,106.7 L558.4,106.7 M55.3,422.4 L60.5,405.5 L65.7,388.6 L70.9,371.8 L76.1,354.9 L81.3,338.0
|
||||||
L178.1,261.4 L198.5,240.1 L219.0,219.7 L239.4,200.2 L259.9,181.7 L280.4,163.9 L300.8,147.0 L321.3,130.9
|
L86.5,321.1 L91.7,304.3 L96.9,287.4 L102.1,270.5 L107.3,253.6 L112.5,236.8 L117.7,219.9 L122.9,203.0
|
||||||
L341.7,115.6 L362.2,101.0 L382.7,87.0 L403.1,73.7 L423.6,61.0 L444.1,48.8 L464.5,37.3 L485.0,26.2
|
L128.1,186.1 L133.3,169.2 L138.5,152.4 L143.6,135.5 L148.8,118.6 L154.0,101.7 L159.2,84.9 L164.4,68.0
|
||||||
L503.2,16.7 '/></g>
|
L169.6,51.1 L174.8,49.2 L180.0,49.2 L185.2,49.2 L190.4,49.2 L195.6,49.2 L200.8,49.2 L206.0,49.2
|
||||||
|
L211.2,49.2 L216.4,49.2 L221.6,49.2 L226.8,49.2 L232.0,49.2 L237.2,49.2 L242.4,49.2 L247.6,49.2
|
||||||
|
L252.8,49.2 L258.0,49.2 L263.2,49.2 L268.4,49.2 L273.6,49.2 L278.8,49.2 L284.0,49.2 L289.2,49.2
|
||||||
|
L294.4,49.2 L299.6,49.2 L304.8,49.2 L310.0,49.2 L315.2,49.2 L320.3,49.2 L325.5,49.2 L330.7,49.2
|
||||||
|
L335.9,49.2 L341.1,49.2 L346.3,49.2 L351.5,49.2 L356.7,49.2 L361.9,49.2 L367.1,49.2 L372.3,49.2
|
||||||
|
L377.5,49.2 L382.7,49.2 L387.9,49.2 L393.1,49.2 L398.3,49.2 L403.5,49.2 L408.7,49.2 L413.9,49.2
|
||||||
|
L419.1,49.2 L424.3,49.2 L429.5,49.2 L434.7,49.2 L439.9,49.2 L445.1,49.2 L450.3,49.2 L455.5,49.2
|
||||||
|
L460.7,49.2 L465.9,49.2 L471.1,49.2 L476.3,49.2 L481.5,49.2 L486.7,49.2 L491.8,49.2 L497.0,49.2
|
||||||
|
L502.2,49.2 L507.4,49.2 L512.6,49.2 L517.8,49.2 L523.0,49.2 L528.2,49.2 L533.4,49.2 L538.6,49.2
|
||||||
|
L543.8,49.2 L549.0,49.2 L554.2,49.2 L559.4,49.2 L564.6,49.2 L569.8,49.2 L575.0,49.2 '/></g>
|
||||||
</g>
|
</g>
|
||||||
<g id="gnuplot_plot_6" ><title>0.5</title>
|
<g id="gnuplot_plot_6" ><title>0.5</title>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
|
|
@ -184,8 +224,9 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
<path stroke='rgb( 0, 114, 178)' d='M516.2,124.7 L558.4,124.7 M55.3,360.4 L75.8,308.6 L96.2,248.7 L116.7,187.8 L137.1,127.6 L157.6,69.2
|
<path stroke='rgb( 0, 114, 178)' d='M516.2,124.7 L558.4,124.7 M55.3,422.4 L60.5,399.0 L65.7,375.7 L70.9,352.3 L76.1,328.9 L81.3,305.6
|
||||||
L176.6,16.7 '/></g>
|
L86.5,282.2 L91.7,258.8 L96.9,235.5 L102.1,212.1 L107.3,188.7 L112.5,165.3 L117.7,142.0 L122.9,118.6
|
||||||
|
L128.1,95.2 L133.3,71.9 L138.5,48.5 L143.6,25.1 L145.5,16.7 '/></g>
|
||||||
</g>
|
</g>
|
||||||
<g id="gnuplot_plot_7" ><title>1</title>
|
<g id="gnuplot_plot_7" ><title>1</title>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
|
|
@ -194,7 +235,9 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
<path stroke='rgb(229, 30, 16)' d='M516.2,142.7 L558.4,142.7 M55.3,300.7 L75.8,199.0 L96.2,81.4 L107.3,16.7 '/></g>
|
<path stroke='rgb(229, 30, 16)' d='M516.2,142.7 L558.4,142.7 M55.3,422.4 L60.5,392.5 L65.7,362.7 L70.9,332.8 L76.1,303.0 L81.3,273.1
|
||||||
|
L86.5,243.2 L91.7,213.4 L96.9,183.5 L102.1,153.7 L107.3,123.8 L112.5,93.9 L117.7,64.1 L122.9,34.2
|
||||||
|
L125.9,16.7 '/></g>
|
||||||
</g>
|
</g>
|
||||||
<g fill="none" color="#FFFFFF" stroke="rgb(229, 30, 16)" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
|
<g fill="none" color="#FFFFFF" stroke="rgb(229, 30, 16)" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
|
||||||
</g>
|
</g>
|
||||||
|
|
@ -208,3 +251,4 @@
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
50
doc/switches.dox
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
@page switches Switches
|
||||||
|
|
||||||
|
libinput supports a couple of switches. Unlike button events that come in
|
||||||
|
press and release pairs, switches are usually toggled once and left at the
|
||||||
|
setting for an extended period of time.
|
||||||
|
|
||||||
|
Only some switches are handled by libinput, see @ref libinput_switch for a
|
||||||
|
list of supported switches. Switch events are exposed to the caller, but
|
||||||
|
libinput may handle some switch events internally and enable or disable
|
||||||
|
specific features based on a switch state.
|
||||||
|
|
||||||
|
The order of switch events is guaranteed to be correct, i.e., a switch will
|
||||||
|
never send consecutive switch on, or switch off, events.
|
||||||
|
|
||||||
|
@section switches_lid Lid switch handling
|
||||||
|
|
||||||
|
Where available, libinput listens to devices providing a lid switch.
|
||||||
|
The evdev event code `EV_SW` `SW_LID` is provided as @ref
|
||||||
|
LIBINPUT_SWITCH_LID. If devices with a lid switch have a touchpad device,
|
||||||
|
the device is disabled while the lid is logically closed. This is to avoid
|
||||||
|
ghost touches that can be caused by interference with touchpads and the
|
||||||
|
closed lid. The touchpad is automatically re-enabled whenever the lid is
|
||||||
|
openend.
|
||||||
|
|
||||||
|
This handling of lid switches is transparent to the user, no notifications
|
||||||
|
are sent and the device appears as enabled at all times.
|
||||||
|
|
||||||
|
On some devices, the device's lid state does not always reflect the physical
|
||||||
|
state and the lid state may report as closed even when the lid is physicall
|
||||||
|
open. libinput employs some heuristics to detect user input (specificially
|
||||||
|
typing) to re-enable the touchpad on those devices.
|
||||||
|
|
||||||
|
@section switches_tablet_mode Tablet mode switch handling
|
||||||
|
|
||||||
|
Where available, libinput listens to devices providing a tablet mode switch.
|
||||||
|
This switch is usually triggered on devices that can switch between a normal
|
||||||
|
laptop layout and a tablet-like layout. One example for such a device is the
|
||||||
|
Lenovo Yoga.
|
||||||
|
|
||||||
|
The event sent by the kernel is `EV_SW` `SW_TABLET_MODE` and is provided as
|
||||||
|
@ref LIBINPUT_SWITCH_TABLET_MODE. When the device switches to tablet mode,
|
||||||
|
the touchpad and internal keyboard are disabled. If a trackpoint exists,
|
||||||
|
it is disabled too. The input devices are automatically re-enabled whenever
|
||||||
|
tablet mode is disengaged.
|
||||||
|
|
||||||
|
This handling of tablet mode switches is transparent to the user, no
|
||||||
|
notifications are sent and the device appears as enabled at all times.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
@ -1,43 +1,29 @@
|
||||||
.. _t440_support:
|
/**
|
||||||
|
@page t440_support Lenovo *40 series touchpad support
|
||||||
|
|
||||||
==============================================================================
|
The Lenovo *40 series emulates trackstick buttons on the top part of the
|
||||||
Lenovo \*40 series touchpad support
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
The Lenovo \*40 series emulates trackstick buttons on the top part of the
|
|
||||||
touchpads.
|
touchpads.
|
||||||
|
|
||||||
.. _t440_support_overview:
|
@section t440_support_overview Overview
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
The Lenovo *40 series introduced a new type of touchpad. Previously, all
|
||||||
Overview
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The Lenovo \*40 series introduced a new type of touchpad. Previously, all
|
|
||||||
laptops had a separate set of physical buttons for the
|
laptops had a separate set of physical buttons for the
|
||||||
`trackstick <http://en.wikipedia.org/wiki/Pointing_stick>`_. This
|
<a href="http://en.wikipedia.org/wiki/Pointing_stick">trackstick</a>. This
|
||||||
series removed these buttons, relying on a software emulation of the top
|
series removed these buttons, relying on a software emulation of the top
|
||||||
section of the touchpad. This is visually marked on the trackpad itself,
|
section of the touchpad. This is visually marked on the trackpad itself,
|
||||||
and clicks can be triggered by pressing the touchpad down with a finger in
|
and clicks can be triggered by pressing the touchpad down with a finger in
|
||||||
the respective area:
|
the respective area:
|
||||||
|
|
||||||
.. figure:: top-software-buttons.svg
|
@image html top-software-buttons.svg "Left, right and middle-button click with top software button areas"
|
||||||
:align: center
|
|
||||||
|
|
||||||
Left, right and middle-button click with top software button areas
|
|
||||||
|
|
||||||
This page only covers the top software buttons, the bottom button behavior
|
This page only covers the top software buttons, the bottom button behavior
|
||||||
is covered in :ref:`Clickpad software buttons <clickpad_softbuttons>`.
|
is covered in @ref clickpad_softbuttons "Clickpad software buttons".
|
||||||
|
|
||||||
Clickpads with a top button area are marked with the
|
Clickpads with a top button area are marked with the <a
|
||||||
`INPUT_PROP_TOPBUTTONPAD <https://www.kernel.org/doc/Documentation/input/event-codes.txt>`_
|
href="https://www.kernel.org/doc/Documentation/input/event-codes.txt">INPUT_PROP_TOPBUTTONPAD</a>
|
||||||
property.
|
property.
|
||||||
|
|
||||||
.. _t440_support_btn_size:
|
@section t440_support_btn_size Size of the buttons
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Size of the buttons
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The size of the buttons matches the visual markings on this touchpad.
|
The size of the buttons matches the visual markings on this touchpad.
|
||||||
The width of the left and right buttons is approximately 42% of the
|
The width of the left and right buttons is approximately 42% of the
|
||||||
|
|
@ -49,21 +35,14 @@ measurements of button presses showed that the size of the buttons needs to
|
||||||
be approximately 10mm high to work reliable (especially when using the
|
be approximately 10mm high to work reliable (especially when using the
|
||||||
thumb to press the button).
|
thumb to press the button).
|
||||||
|
|
||||||
.. _t440_support_btn_behavior:
|
@section t440_support_btn_behavior Button behavior
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Button behavior
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Movement in the top button area does not generate pointer movement. These
|
Movement in the top button area does not generate pointer movement. These
|
||||||
buttons are not replacement buttons for the bottom button area but have
|
buttons are not replacement buttons for the bottom button area but have
|
||||||
their own behavior. Semantically attached to the trackstick device, libinput
|
their own behavior. Semantically attached to the trackstick device, libinput
|
||||||
re-routes events from these buttons to appear through the trackstick device.
|
re-routes events from these buttons to appear through the trackstick device.
|
||||||
|
|
||||||
|
@dot
|
||||||
.. graphviz::
|
|
||||||
|
|
||||||
|
|
||||||
digraph top_button_routing
|
digraph top_button_routing
|
||||||
{
|
{
|
||||||
rankdir="LR";
|
rankdir="LR";
|
||||||
|
|
@ -96,7 +75,7 @@ re-routes events from these buttons to appear through the trackstick device.
|
||||||
libinput_tp -> events_tp [arrowhead="none"]
|
libinput_tp -> events_tp [arrowhead="none"]
|
||||||
libinput_ts -> events_topbutton [color="red4"]
|
libinput_ts -> events_topbutton [color="red4"]
|
||||||
}
|
}
|
||||||
|
@enddot
|
||||||
|
|
||||||
|
|
||||||
The top button areas work even if the touchpad is disabled but will be
|
The top button areas work even if the touchpad is disabled but will be
|
||||||
|
|
@ -106,23 +85,20 @@ and must be lifted to generate future buttons. Likewise, movement into the
|
||||||
top button area does not trigger button events, a click has to start inside
|
top button area does not trigger button events, a click has to start inside
|
||||||
this area to take effect.
|
this area to take effect.
|
||||||
|
|
||||||
.. _t440_support_identification:
|
@section t440_support_identification Kernel support
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Kernel support
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The firmware on the first generation of touchpads providing top software
|
The firmware on the first generation of touchpads providing top software
|
||||||
buttons is buggy and announces wrong ranges.
|
buttons is buggy and announces wrong ranges.
|
||||||
`Kernel patches <https://lkml.org/lkml/2014/3/7/722>`_ are required;
|
<a href="https://lkml.org/lkml/2014/3/7/722">Kernel patches</a> are required;
|
||||||
these fixes are available in kernels 3.14.1, 3.15 and later but each
|
these fixes are available in kernels 3.14.1, 3.15 and later but each
|
||||||
touchpad needs a separate fix.
|
touchpad needs a separate fix.
|
||||||
|
|
||||||
The October 2014 refresh of these laptops do not have this firmware bug
|
The October 2014 refresh of these laptops do not have this firmware bug
|
||||||
anymore and should work without per-device patches, though
|
anymore and should work without per-device patches, though
|
||||||
`this kernel commit <http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=02e07492cdfae9c86e3bd21c0beec88dbcc1e9e8>`_
|
<a href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=02e07492cdfae9c86e3bd21c0beec88dbcc1e9e8">this kernel commit</a> is required.
|
||||||
is required.
|
|
||||||
|
|
||||||
For a complete list of supported touchpads check
|
For a complete list of supported touchpads check <a
|
||||||
`the kernel source <http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/input/mouse/synaptics.c>`_
|
href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/input/mouse/synaptics.c">the
|
||||||
(search for "topbuttonpad_pnp_ids").
|
kernel source</a> (search for "topbuttonpad_pnp_ids").
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
@ -1,60 +1,43 @@
|
||||||
.. _tablet-support:
|
/**
|
||||||
|
@page tablet-support Tablet support
|
||||||
==============================================================================
|
|
||||||
Tablet support
|
|
||||||
==============================================================================
|
|
||||||
|
|
||||||
This page provides details about the graphics tablet
|
This page provides details about the graphics tablet
|
||||||
support in libinput. Note that the term "tablet" in libinput refers to
|
support in libinput. Note that the term "tablet" in libinput refers to
|
||||||
graphics tablets only (e.g. Wacom Intuos), not to tablet devices like the
|
graphics tablets only (e.g. Wacom Intuos), not to tablet devices like the
|
||||||
Apple iPad.
|
Apple iPad.
|
||||||
|
|
||||||
.. figure:: tablet.svg
|
@image html tablet.svg "Illustration of a graphics tablet"
|
||||||
:align: center
|
|
||||||
|
|
||||||
Illustration of a graphics tablet
|
@section tablet-tools Pad buttons vs. tablet tools
|
||||||
|
|
||||||
.. _tablet-tools:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Pad buttons vs. tablet tools
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Most tablets provide two types of devices. The physical tablet often
|
Most tablets provide two types of devices. The physical tablet often
|
||||||
provides a number of buttons and a touch ring or strip. Interaction on the
|
provides a number of buttons and a touch ring or strip. Interaction on the
|
||||||
drawing surface of the tablet requires a tool, usually in the shape of a
|
drawing surface of the tablet requires a tool, usually in the shape of a
|
||||||
stylus. The libinput interface exposed by devices with the
|
stylus. The libinput interface exposed by devices with the @ref
|
||||||
**LIBINPUT_DEVICE_CAP_TABLET_TOOL** capability applies only to events generated
|
LIBINPUT_DEVICE_CAP_TABLET_TOOL capability applies only to events generated
|
||||||
by tools.
|
by tools.
|
||||||
|
|
||||||
Buttons, rings or strips on the physical tablet hardware (the "pad") are
|
Buttons, rings or strips on the physical tablet hardware (the "pad") are
|
||||||
exposed by devices with the **LIBINPUT_DEVICE_CAP_TABLET_PAD** capability.
|
exposed by devices with the @ref LIBINPUT_DEVICE_CAP_TABLET_PAD capability.
|
||||||
Pad events do not require a tool to be in proximity. Note that both
|
Pad events do not require a tool to be in proximity. Note that both
|
||||||
capabilities may exist on the same device though usually they are split
|
capabilities may exist on the same device though usually they are split
|
||||||
across multiple kernel devices.
|
across multiple kernel devices.
|
||||||
|
|
||||||
.. figure:: tablet-interfaces.svg
|
@image html tablet-interfaces.svg "Difference between Pad and Tool buttons"
|
||||||
:align: center
|
|
||||||
|
|
||||||
Difference between Pad and Tool buttons
|
|
||||||
|
|
||||||
Touch events on the tablet integrated into a screen itself are exposed
|
Touch events on the tablet integrated into a screen itself are exposed
|
||||||
through the **LIBINPUT_DEVICE_CAP_TOUCH** capability. Touch events on a
|
through the @ref LIBINPUT_DEVICE_CAP_TOUCH capability. Touch events on a
|
||||||
standalone tablet are exposed through the **LIBINPUT_DEVICE_CAP_POINTER**
|
standalone tablet are exposed through the @ref LIBINPUT_DEVICE_CAP_POINTER
|
||||||
capability. In both cases, the kernel usually provides a separate event
|
capability. In both cases, the kernel usually provides a separate event
|
||||||
node for the touch device, resulting in a separate libinput device.
|
node for the touch device, resulting in a separate libinput device.
|
||||||
See **libinput_device_get_device_group()** for information on how to associate
|
See libinput_device_get_device_group() for information on how to associate
|
||||||
the touch part with other devices exposed by the same physical hardware.
|
the touch part with other devices exposed by the same physical hardware.
|
||||||
|
|
||||||
.. _tablet-tip:
|
@section tablet-tip Tool tip events vs. tool button events
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Tool tip events vs. tool button events
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The primary use of a tablet tool is to draw on the surface of the tablet.
|
The primary use of a tablet tool is to draw on the surface of the tablet.
|
||||||
When the tool tip comes into contact with the surface, libinput sends an
|
When the tool tip comes into contact with the surface, libinput sends an
|
||||||
event of type **LIBINPUT_EVENT_TABLET_TOOL_TIP**, and again when the tip
|
event of type @ref LIBINPUT_EVENT_TABLET_TOOL_TIP, and again when the tip
|
||||||
ceases contact with the surface.
|
ceases contact with the surface.
|
||||||
|
|
||||||
Tablet tools may send button events; these are exclusively for extra buttons
|
Tablet tools may send button events; these are exclusively for extra buttons
|
||||||
|
|
@ -68,8 +51,8 @@ tools are capable of detecting 1 gram of pressure.
|
||||||
libinput uses a device-specific pressure threshold to determine when the tip
|
libinput uses a device-specific pressure threshold to determine when the tip
|
||||||
is considered logically down. As a result, libinput may send a nonzero
|
is considered logically down. As a result, libinput may send a nonzero
|
||||||
pressure value while the tip is logically up. Most application can and
|
pressure value while the tip is logically up. Most application can and
|
||||||
should ignore pressure information until they receive the event of type
|
should ignore pressure information until they receive the event of type @ref
|
||||||
**LIBINPUT_EVENT_TABLET_TOOL_TIP**. Applications that require extremely
|
LIBINPUT_EVENT_TABLET_TOOL_TIP. Applications that require extremely
|
||||||
fine-grained pressure sensitivity should use the pressure data instead of
|
fine-grained pressure sensitivity should use the pressure data instead of
|
||||||
the tip events to determine a logical tip down state and treat the tip
|
the tip events to determine a logical tip down state and treat the tip
|
||||||
events like axis events otherwise.
|
events like axis events otherwise.
|
||||||
|
|
@ -78,17 +61,13 @@ Note that the pressure threshold to trigger a logical tip event may be zero
|
||||||
on some devices. On tools without pressure sensitivity, determining when a
|
on some devices. On tools without pressure sensitivity, determining when a
|
||||||
tip is down is device-specific.
|
tip is down is device-specific.
|
||||||
|
|
||||||
.. _tablet-relative-motion:
|
@section tablet-relative-motion Relative motion for tablet tools
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Relative motion for tablet tools
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
libinput calculates the relative motion vector for each event and converts
|
libinput calculates the relative motion vector for each event and converts
|
||||||
it to the same coordinate space that a normal mouse device would use. For
|
it to the same coordinate space that a normal mouse device would use. For
|
||||||
the caller, this means that the delta coordinates returned by
|
the caller, this means that the delta coordinates returned by
|
||||||
**libinput_event_tablet_tool_get_dx()** and
|
libinput_event_tablet_tool_get_dx() and
|
||||||
**libinput_event_tablet_tool_get_dy()** can be used identical to the delta
|
libinput_event_tablet_tool_get_dy() can be used identical to the delta
|
||||||
coordinates from any other pointer event. Any resolution differences between
|
coordinates from any other pointer event. Any resolution differences between
|
||||||
the x and y axes are accommodated for, a delta of N/N represents a 45 degree
|
the x and y axes are accommodated for, a delta of N/N represents a 45 degree
|
||||||
diagonal move on the tablet.
|
diagonal move on the tablet.
|
||||||
|
|
@ -100,25 +79,18 @@ all pen-like tools to absolute mode.
|
||||||
|
|
||||||
If a tool in relative mode must not use pointer acceleration, callers
|
If a tool in relative mode must not use pointer acceleration, callers
|
||||||
should use the absolute coordinates returned by
|
should use the absolute coordinates returned by
|
||||||
**libinput_event_tablet_tool_get_x()** and libinput_event_tablet_tool_get_y()
|
libinput_event_tablet_tool_get_x() and libinput_event_tablet_tool_get_y()
|
||||||
and calculate the delta themselves. Callers that require exact physical
|
and calculate the delta themselves. Callers that require exact physical
|
||||||
distance should also use these functions to calculate delta movements.
|
distance should also use these functions to calculate delta movements.
|
||||||
|
|
||||||
.. _tablet-axes:
|
@section tablet-axes Special axes on tablet tools
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Special axes on tablet tools
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
A tablet tool usually provides additional information beyond x/y positional
|
A tablet tool usually provides additional information beyond x/y positional
|
||||||
information and the tip state. A tool may provide the distance to the tablet
|
information and the tip state. A tool may provide the distance to the tablet
|
||||||
surface and the pressure exerted on the tip when in contact. Some tablets
|
surface and the pressure exerted on the tip when in contact. Some tablets
|
||||||
additionally provide tilt information along the x and y axis.
|
additionally provide tilt information along the x and y axis.
|
||||||
|
|
||||||
.. figure:: tablet-axes.svg
|
@image html tablet-axes.svg "Illustration of the distance, pressure and tilt axes"
|
||||||
:align: center
|
|
||||||
|
|
||||||
Illustration of the distance, pressure and tilt axes
|
|
||||||
|
|
||||||
The granularity and precision of the distance and pressure axes varies
|
The granularity and precision of the distance and pressure axes varies
|
||||||
between tablet devices and cannot usually be mapped into a physical unit.
|
between tablet devices and cannot usually be mapped into a physical unit.
|
||||||
|
|
@ -133,13 +105,9 @@ the tablet and the top of the stylus. The angle is measured along the x and
|
||||||
y axis, respectively, a positive tilt angle thus means that the stylus' top
|
y axis, respectively, a positive tilt angle thus means that the stylus' top
|
||||||
is tilted towards the logical right and/or bottom of the tablet.
|
is tilted towards the logical right and/or bottom of the tablet.
|
||||||
|
|
||||||
.. _tablet-fake-proximity:
|
@section tablet-fake-proximity Handling of proximity events
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
libinput's @ref LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY events notify a caller
|
||||||
Handling of proximity events
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
libinput's **LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY** events notify a caller
|
|
||||||
when a tool comes into sensor range or leaves the sensor range. On some
|
when a tool comes into sensor range or leaves the sensor range. On some
|
||||||
tools this range does not represent the physical range but a reduced
|
tools this range does not represent the physical range but a reduced
|
||||||
tool-specific logical range. If the range is reduced, this is done
|
tool-specific logical range. If the range is reduced, this is done
|
||||||
|
|
@ -155,11 +123,7 @@ provides software-emulated proximity.
|
||||||
|
|
||||||
Events from the pad do not require proximity, they may be sent any time.
|
Events from the pad do not require proximity, they may be sent any time.
|
||||||
|
|
||||||
.. _tablet-pressure-offset:
|
@section tablet-pressure-offset Pressure offset on worn-out tools
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Pressure offset on worn-out tools
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
When a tool is used for an extended period it can wear down physically. A
|
When a tool is used for an extended period it can wear down physically. A
|
||||||
worn-down tool may never return a zero pressure value. Even when hovering
|
worn-down tool may never return a zero pressure value. Even when hovering
|
||||||
|
|
@ -175,83 +139,32 @@ than that offset.
|
||||||
|
|
||||||
Some limitations apply to avoid misdetection of pressure offsets,
|
Some limitations apply to avoid misdetection of pressure offsets,
|
||||||
specifically:
|
specifically:
|
||||||
|
|
||||||
- pressure offset is only detected on proximity in, and if a device is
|
- pressure offset is only detected on proximity in, and if a device is
|
||||||
capable of detection distances,
|
capable of detection distances,
|
||||||
- pressure offset is only detected if the distance between the tool and the
|
- pressure offset is only detected if the distance between the tool and the
|
||||||
tablet is high enough,
|
tablet is high enough,
|
||||||
- pressure offset is only used if it is 50% or less of the pressure range
|
- pressure offset is only used if it is 20% or less of the pressure range
|
||||||
available to the tool. A pressure offset higher than 50% indicates either
|
available to the tool. A pressure offset higher than 20% indicates either
|
||||||
a misdetection or a tool that should be replaced, and
|
a misdetection or a tool that should be replaced, and
|
||||||
- if a pressure value less than the current pressure offset is seen, the
|
- if a pressure value less than the current pressure offset is seen, the
|
||||||
offset resets to that value.
|
offset resets to that value.
|
||||||
|
|
||||||
Pressure offsets are not detected on **LIBINPUT_TABLET_TOOL_TYPE_MOUSE**
|
Pressure offsets are not detected on @ref LIBINPUT_TABLET_TOOL_TYPE_MOUSE
|
||||||
and **LIBINPUT_TABLET_TOOL_TYPE_LENS** tools.
|
and @ref LIBINPUT_TABLET_TOOL_TYPE_LENS tools.
|
||||||
|
|
||||||
|
@section tablet-serial-numbers Tracking unique tools
|
||||||
.. _tablet-pressure-range:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Custom tablet tool pressure ranges
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
On tablets supporting pressure, libinput provides that hardware pressure as
|
|
||||||
a logical range of ``0.0`` up to ``1.0`` for the maximum supported pressure.
|
|
||||||
By default, the hardware range thus maps into the following logical range::
|
|
||||||
|
|
||||||
|
|
||||||
hw minimum hw maximum
|
|
||||||
hw range: |------|-----------------------------------|
|
|
||||||
logical range: |----|-----------------------------------|
|
|
||||||
0.0 | 1.0
|
|
||||||
Tip
|
|
||||||
|
|
||||||
Note that libinput always has some built-in thresholds to filter out erroneous
|
|
||||||
touches with near-zero pressure but otherwise the hardware range maps as-is
|
|
||||||
into the logical range. The :ref:`tip event <tablet-tip>` threshold is defined
|
|
||||||
within this range.
|
|
||||||
|
|
||||||
For some use-cases the full hardware range is not suitable, it may require either
|
|
||||||
too light a pressure for the user to interact or it may require too hard a
|
|
||||||
pressure before the logical maximum is reached. libinput provides
|
|
||||||
the **libinput_tablet_tool_config_pressure_range_set()** function that allows
|
|
||||||
reducing the usable range of the tablet::
|
|
||||||
|
|
||||||
hw minimum hw maximum
|
|
||||||
hw range: |----------|-------------------------------|
|
|
||||||
adjusted range: |------|---------------------|
|
|
||||||
logical range: |----|---------------------|
|
|
||||||
0.0 | 1.0
|
|
||||||
Tip
|
|
||||||
|
|
||||||
A reduced range as shown above will result in
|
|
||||||
|
|
||||||
- all hw pressure below the new minimum to register as logical pressure ``0.0``
|
|
||||||
- all hw pressure above the new maximum to register as logical pressure ``1.0``
|
|
||||||
- the tip event threshold to be relative to the new minimum
|
|
||||||
|
|
||||||
In other words, adjusting the pressure range of a tablet tool is equivalent to
|
|
||||||
reducing the hardware range of said tool. Note that where a custom pressure
|
|
||||||
range is set, detection of :ref:`tablet-pressure-offset` is disabled.
|
|
||||||
|
|
||||||
.. _tablet-serial-numbers:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Tracking unique tools
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Some tools provide hardware information that enables libinput to uniquely
|
Some tools provide hardware information that enables libinput to uniquely
|
||||||
identify the physical device. For example, tools compatible with the Wacom
|
identify the physical device. For example, tools compatible with the Wacom
|
||||||
Intuos 4, Intuos 5, Intuos Pro and Cintiq series are uniquely identifiable
|
Intuos 4, Intuos 5, Intuos Pro and Cintiq series are uniquely identifiable
|
||||||
through a serial number. libinput does not specify how a tool can be
|
through a serial number. libinput does not specify how a tool can be
|
||||||
identified uniquely, a caller should use **libinput_tablet_tool_is_unique()** to
|
identified uniquely, a caller should use libinput_tablet_tool_is_unique() to
|
||||||
check if the tool is unique.
|
check if the tool is unique.
|
||||||
|
|
||||||
libinput creates a struct libinput_tablet_tool on the first proximity in of
|
libinput creates a struct libinput_tablet_tool on the first proximity in of
|
||||||
this tool. By default, this struct is destroyed on proximity out and
|
this tool. By default, this struct is destroyed on proximity out and
|
||||||
re-initialized on the next proximity in. If a caller keeps a reference to
|
re-initialized on the next proximity in. If a caller keeps a reference to
|
||||||
the tool by using **libinput_tablet_tool_ref()** libinput re-uses this struct
|
the tool by using libinput_tablet_tool_ref() libinput re-uses this struct
|
||||||
whenever that same physical tool comes into proximity on any tablet
|
whenever that same physical tool comes into proximity on any tablet
|
||||||
recognized by libinput. It is possible to attach tool-specific virtual state
|
recognized by libinput. It is possible to attach tool-specific virtual state
|
||||||
to the tool. For example, a graphics program such as the GIMP may assign a
|
to the tool. For example, a graphics program such as the GIMP may assign a
|
||||||
|
|
@ -263,24 +176,20 @@ If the tool does not have a unique identifier, libinput creates a single
|
||||||
struct libinput_tablet_tool per tool type on each tablet the tool is used
|
struct libinput_tablet_tool per tool type on each tablet the tool is used
|
||||||
on.
|
on.
|
||||||
|
|
||||||
.. _tablet-tool-types:
|
@section tablet-tool-types Vendor-specific tablet tool types
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Vendor-specific tablet tool types
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
libinput supports a number of high-level tool types that describe the
|
libinput supports a number of high-level tool types that describe the
|
||||||
general interaction expected with the tool. For example, a user would expect
|
general interaction expected with the tool. For example, a user would expect
|
||||||
a tool of type **LIBINPUT_TABLET_TOOL_TYPE_PEN** to interact with a
|
a tool of type @ref LIBINPUT_TABLET_TOOL_TYPE_PEN to interact with a
|
||||||
graphics application taking pressure and tilt into account. The default
|
graphics application taking pressure and tilt into account. The default
|
||||||
virtual tool assigned should be a drawing tool, e.g. a virtual pen or brush.
|
virtual tool assigned should be a drawing tool, e.g. a virtual pen or brush.
|
||||||
A tool of type **LIBINPUT_TABLET_TOOL_TYPE_ERASER** would normally be
|
A tool of type @ref LIBINPUT_TABLET_TOOL_TYPE_ERASER would normally be
|
||||||
mapped to an eraser-like virtual tool. See **libinput_tablet_tool_type**
|
mapped to an eraser-like virtual tool. See @ref libinput_tablet_tool_type
|
||||||
for the list of all available tools.
|
for the list of all available tools.
|
||||||
|
|
||||||
Vendors may provide more fine-grained information about the tool in use by
|
Vendors may provide more fine-grained information about the tool in use by
|
||||||
adding a hardware-specific tool ID. libinput provides this ID to the caller
|
adding a hardware-specific tool ID. libinput provides this ID to the caller
|
||||||
with **libinput_tablet_tool_get_tool_id()** but makes no promises about the
|
with libinput_tablet_tool_get_tool_id() but makes no promises about the
|
||||||
content or format of the ID.
|
content or format of the ID.
|
||||||
|
|
||||||
libinput currently supports Wacom-style tool IDs as provided on the Wacom
|
libinput currently supports Wacom-style tool IDs as provided on the Wacom
|
||||||
|
|
@ -288,11 +197,7 @@ Intuos 3, 4, 5, Wacon Cintiq and Wacom Intuos Pro series. The tool ID can
|
||||||
be used to distinguish between e.g. a Wacom Classic Pen or a Wacom Pro Pen.
|
be used to distinguish between e.g. a Wacom Classic Pen or a Wacom Pro Pen.
|
||||||
It is the caller's responsibility to interpret the tool ID.
|
It is the caller's responsibility to interpret the tool ID.
|
||||||
|
|
||||||
.. _tablet-bounds:
|
@section tablet-bounds Out-of-bounds motion events
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Out-of-bounds motion events
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Some tablets integrated into a screen (e.g. Wacom Cintiq 24HD, 27QHD and
|
Some tablets integrated into a screen (e.g. Wacom Cintiq 24HD, 27QHD and
|
||||||
13HD series, etc.) have a sensor larger than the display area. libinput uses
|
13HD series, etc.) have a sensor larger than the display area. libinput uses
|
||||||
|
|
@ -301,10 +206,7 @@ quirks are present. Events outside this range will produce coordinates that
|
||||||
may be negative or larger than the tablet's width and/or height. It is up to
|
may be negative or larger than the tablet's width and/or height. It is up to
|
||||||
the caller to ignore these events.
|
the caller to ignore these events.
|
||||||
|
|
||||||
.. figure:: tablet-out-of-bounds.svg
|
@image html tablet-out-of-bounds.svg "Illustration of the out-of-bounds area on a tablet"
|
||||||
:align: center
|
|
||||||
|
|
||||||
Illustration of the out-of-bounds area on a tablet
|
|
||||||
|
|
||||||
In the image above, the display area is shown in black. The red area around
|
In the image above, the display area is shown in black. The red area around
|
||||||
the display illustrates the sensor area that generates input events. Events
|
the display illustrates the sensor area that generates input events. Events
|
||||||
|
|
@ -312,21 +214,17 @@ within this area will have negative coordinate or coordinates larger than
|
||||||
the width/height of the tablet.
|
the width/height of the tablet.
|
||||||
|
|
||||||
If events outside the logical bounds of the input area are scaled into a
|
If events outside the logical bounds of the input area are scaled into a
|
||||||
custom range with **libinput_event_tablet_tool_get_x_transformed()** and
|
custom range with libinput_event_tablet_tool_get_x_transformed() and
|
||||||
**libinput_event_tablet_tool_get_y_transformed()** the resulting value may be
|
libinput_event_tablet_tool_get_y_transformed() the resulting value may be
|
||||||
less than 0 or larger than the upper range provided. It is up to the caller
|
less than 0 or larger than the upper range provided. It is up to the caller
|
||||||
to test for this and handle or ignore these events accordingly.
|
to test for this and handle or ignore these events accordingly.
|
||||||
|
|
||||||
.. _tablet-pad-buttons:
|
@section tablet-pad-buttons Tablet pad button numbers
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Tablet pad button numbers
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Tablet Pad buttons are numbered sequentially, starting with button 0. Thus
|
Tablet Pad buttons are numbered sequentially, starting with button 0. Thus
|
||||||
button numbers returned by **libinput_event_tablet_pad_get_button_number()**
|
button numbers returned by libinput_event_tablet_pad_get_button_number()
|
||||||
have no semantic meaning, a notable difference to the button codes returned
|
have no semantic meaning, a notable difference to the button codes returned
|
||||||
by other libinput interfaces (e.g. **libinput_event_tablet_tool_get_button()**).
|
by other libinput interfaces (e.g. libinput_event_tablet_tool_get_button()).
|
||||||
|
|
||||||
The Linux kernel requires all input events to have semantic event codes,
|
The Linux kernel requires all input events to have semantic event codes,
|
||||||
but generic buttons like those on a pad cannot easily be assigned semantic
|
but generic buttons like those on a pad cannot easily be assigned semantic
|
||||||
|
|
@ -342,20 +240,16 @@ tablet.
|
||||||
|
|
||||||
Some buttons may have expected default behaviors. For example, on Wacom
|
Some buttons may have expected default behaviors. For example, on Wacom
|
||||||
Intuos Pro series tablets, the button inside the touch ring is expected to
|
Intuos Pro series tablets, the button inside the touch ring is expected to
|
||||||
switch between modes, see :ref:`tablet-pad-modes`. Callers should use
|
switch between modes, see @ref tablet-pad-modes. Callers should use
|
||||||
external sources like libwacom to identify which buttons have semantic
|
external sources like libwacom to identify which buttons have semantic
|
||||||
behaviors.
|
behaviors.
|
||||||
|
|
||||||
.. _tablet-left-handed:
|
@section tablet-left-handed Tablets in left-handed mode
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Tablets in left-handed mode
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Left-handed mode on tablet devices usually means rotating the physical
|
Left-handed mode on tablet devices usually means rotating the physical
|
||||||
tablet by 180 degrees to move the tablet pad button area to right side of
|
tablet by 180 degrees to move the tablet pad button area to right side of
|
||||||
the tablet. When left-handed mode is enabled on a tablet device (see
|
the tablet. When left-handed mode is enabled on a tablet device (see
|
||||||
**libinput_device_config_left_handed_set()**) the tablet tool and tablet pad
|
libinput_device_config_left_handed_set()) the tablet tool and tablet pad
|
||||||
behavior changes. In left-handed mode, the tools' axes are adjusted
|
behavior changes. In left-handed mode, the tools' axes are adjusted
|
||||||
so that the origin of each axis remains the logical north-east of
|
so that the origin of each axis remains the logical north-east of
|
||||||
the physical tablet. For example, the x and y axes are inverted and the
|
the physical tablet. For example, the x and y axes are inverted and the
|
||||||
|
|
@ -364,15 +258,11 @@ in its current orientation. On a tablet pad, the ring and strip are
|
||||||
similarly adjusted. The origin of the ring and strips remain the top-most
|
similarly adjusted. The origin of the ring and strips remain the top-most
|
||||||
point.
|
point.
|
||||||
|
|
||||||
.. figure:: tablet-left-handed.svg
|
@image html tablet-left-handed.svg "Tablet axes in right- and left-handed mode"
|
||||||
:align: center
|
|
||||||
|
|
||||||
Tablet axes in right- and left-handed mode
|
|
||||||
|
|
||||||
Pad buttons are not affected by left-handed mode; the number of each button
|
Pad buttons are not affected by left-handed mode; the number of each button
|
||||||
remains the same even when the perceived physical location of the button
|
remains the same even when the perceived physical location of the button
|
||||||
changes. This is a conscious design decision:
|
changes. This is a conscious design decision:
|
||||||
|
|
||||||
- Tablet pad buttons do not have intrinsic semantic meanings. Re-ordering
|
- Tablet pad buttons do not have intrinsic semantic meanings. Re-ordering
|
||||||
the button numbers would not change any functionality.
|
the button numbers would not change any functionality.
|
||||||
- Button numbers should not be exposed directly to the user but handled in
|
- Button numbers should not be exposed directly to the user but handled in
|
||||||
|
|
@ -385,11 +275,7 @@ symmetric and thus do not support left-handed mode. libinput requires
|
||||||
libwacom to determine if a tablet is capable of being switched to
|
libwacom to determine if a tablet is capable of being switched to
|
||||||
left-handed mode.
|
left-handed mode.
|
||||||
|
|
||||||
.. _tablet-pad-modes:
|
@section tablet-pad-modes Tablet pad modes
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Tablet pad modes
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Tablet pad modes are virtual groupings of button, ring and strip
|
Tablet pad modes are virtual groupings of button, ring and strip
|
||||||
functionality. A caller may assign different functionalities depending on
|
functionality. A caller may assign different functionalities depending on
|
||||||
|
|
@ -420,42 +306,32 @@ libinput handles the mode groups independently and returns the mode for each
|
||||||
button as appropriate. The mode group is static for the lifetime of the
|
button as appropriate. The mode group is static for the lifetime of the
|
||||||
device.
|
device.
|
||||||
|
|
||||||
.. figure:: tablet-intuos-modes.svg
|
@image html tablet-intuos-modes.svg "Modes on an Intuos Pro-like tablet"
|
||||||
:align: center
|
|
||||||
|
|
||||||
Modes on an Intuos Pro-like tablet
|
|
||||||
|
|
||||||
In the image above, the Intuos Pro-like tablet provides 4 LEDs to indicate
|
In the image above, the Intuos Pro-like tablet provides 4 LEDs to indicate
|
||||||
the currently active modes. The button inside the touch ring cycles through
|
the currently active modes. The button inside the touch ring cycles through
|
||||||
the modes in a clockwise fashion. The upper-right LED indicates that the
|
the modes in a clockwise fashion. The upper-right LED indicates that the
|
||||||
currently active mode is 1, based on 0-indexed mode numbering.
|
currently active mode is 1, based on 0-indexed mode numbering.
|
||||||
**libinput_event_tablet_pad_get_mode()** would thus return 1 for all button and
|
libinput_event_tablet_pad_get_mode() would thus return 1 for all button and
|
||||||
ring events on this tablet. When the center button is pressed, the mode
|
ring events on this tablet. When the center button is pressed, the mode
|
||||||
switches to mode 2, the LED changes to the bottom-right and
|
switches to mode 2, the LED changes to the bottom-right and
|
||||||
**libinput_event_tablet_pad_get_mode()** returns 2 for the center button event
|
libinput_event_tablet_pad_get_mode() returns 2 for the center button event
|
||||||
and all subsequent events.
|
and all subsequent events.
|
||||||
|
|
||||||
.. figure:: tablet-cintiq24hd-modes.svg
|
@image html tablet-cintiq24hd-modes.svg "Modes on an Cintiq 24HD-like tablet"
|
||||||
:align: center
|
|
||||||
|
|
||||||
Modes on an Cintiq 24HD-like tablet
|
|
||||||
|
|
||||||
In the image above, the Cintiq 24HD-like tablet provides 3 LEDs on each side
|
In the image above, the Cintiq 24HD-like tablet provides 3 LEDs on each side
|
||||||
of the tablet to indicate the currently active mode for that group of
|
of the tablet to indicate the currently active mode for that group of
|
||||||
buttons and the respective ring. The buttons next to the touch ring select
|
buttons and the respective ring. The buttons next to the touch ring select
|
||||||
the mode directly. The two LEDs indicate that the mode for the left set of
|
the mode directly. The two LEDs indicate that the mode for the left set of
|
||||||
buttons is currently 0, the mode for the right set of buttons is currently
|
buttons is currently 0, the mode for the right set of buttons is currently
|
||||||
1, based on 0-indexed mode numbering. **libinput_event_tablet_pad_get_mode()**
|
1, based on 0-indexed mode numbering. libinput_event_tablet_pad_get_mode()
|
||||||
would thus return 0 for all button and ring events on the left and 1 for all
|
would thus return 0 for all button and ring events on the left and 1 for all
|
||||||
button and ring events on the right. When one of the three mode toggle
|
button and ring events on the right. When one of the three mode toggle
|
||||||
buttons on the right is pressed, the right mode switches to that button's
|
buttons on the right is pressed, the right mode switches to that button's
|
||||||
mode but the left mode remains unchanged.
|
mode but the left mode remains unchanged.
|
||||||
|
|
||||||
.. _tablet-touch-arbitration:
|
@section tablet-touch-arbitration Tablet touch arbitration
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Tablet touch arbitration
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
"Touch arbitration" is the terminology used when touch events are suppressed
|
"Touch arbitration" is the terminology used when touch events are suppressed
|
||||||
while the pen is in proximity. Since it is almost impossible to use a stylus
|
while the pen is in proximity. Since it is almost impossible to use a stylus
|
||||||
|
|
@ -464,81 +340,35 @@ touch arbitration serves to reduce the number of accidental inputs.
|
||||||
The wacom kernel driver currently provides touch arbitration but for other
|
The wacom kernel driver currently provides touch arbitration but for other
|
||||||
devices arbitration has to be done in userspace.
|
devices arbitration has to be done in userspace.
|
||||||
|
|
||||||
libinput uses the **libinput_device_group** to decide on touch arbitration
|
libinput uses the @ref libinput_device_group to decide on touch arbitration
|
||||||
and automatically discards touch events whenever a tool is in proximity.
|
and automatically discards touch events whenever a tool is in proximity.
|
||||||
The exact behavior is device-dependent.
|
The exact behavior is device-dependent.
|
||||||
|
|
||||||
.. _tablet-area:
|
@section tablet-capabilities Required tablet capabilities
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
To handle a tablet correctly, libinput requires a set of capabilities
|
||||||
Tablet area
|
on the device. When these capabilities are missing, libinput ignores the
|
||||||
------------------------------------------------------------------------------
|
device and prints an error to the log. This error messages reads
|
||||||
|
<pre>
|
||||||
|
missing tablet capabilities: xy pen btn-stylus resolution. Ignoring this device.
|
||||||
|
</pre>
|
||||||
|
or in older versions of libinput simply:
|
||||||
|
<pre>
|
||||||
|
libinput bug: device does not meet tablet criteria. Ignoring this device.
|
||||||
|
</pre>
|
||||||
|
|
||||||
External tablet devices such as e.g. the Wacom Intuos series can be configured
|
When a tablet is rejected, it is usually possible to check the issue with
|
||||||
to reduce the available logical input area. Typically the logical input area
|
the `evemu-descibe` tool.
|
||||||
is equivalent to the physical input area but it can be reduced with the
|
|
||||||
**libinput_device_config_area_set_rectangle()** call. Once reduced, input
|
|
||||||
events outside the logical input area are ignored and the logical input area
|
|
||||||
acts as if it represented the extents of the physical tablet.
|
|
||||||
|
|
||||||
.. figure:: tablet-area.svg
|
- **xy** indicates that the tablet is missing the `ABS_X` and/or `ABS_Y`
|
||||||
:align: center
|
axis. This indicates that the device is mislabelled and the udev tag
|
||||||
|
`ID_INPUT_TABLET` is applied to a device that is not a tablet.
|
||||||
|
- **pen** or **btn-stylus** indicates that the tablet does not have the
|
||||||
|
`BTN_TOOL_PEN` or `BTN_STYLUS` bit set. libinput requires either or both
|
||||||
|
of them to be present. This usually indicates a bug in the kernel driver
|
||||||
|
or the HID descriptors of the device.
|
||||||
|
- **resolution** indicates that the device does not have a resolution set
|
||||||
|
for the x and y axes. This can be fixed with a hwdb entry, locate and read
|
||||||
|
the 60-evdev.hwdb file on your machine to address this.
|
||||||
|
|
||||||
Tablet area configuration example
|
*/
|
||||||
|
|
||||||
In the image above, the area is set to the rectangle 0.25/0.25 to 0.5/0.75.
|
|
||||||
Even though the tool is roughly at the physical position ``0.5 * width`` and
|
|
||||||
``0.75 * height``, the return values of
|
|
||||||
**libinput_event_tablet_tool_get_x_transformed()** and
|
|
||||||
**libinput_event_tablet_tool_get_y_transformed()** would be close to the
|
|
||||||
maximum provided in this call.
|
|
||||||
|
|
||||||
The size of the tablet reported by **libinput_device_get_size()** always reflects
|
|
||||||
the physical area, not the logical area.
|
|
||||||
|
|
||||||
.. _tablet-eraser-button:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
Tablet eraser buttons
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Tablet tools come in a variety of forms but the most common one is a
|
|
||||||
pen-like tool. Some of these pen-like tools have a virtual eraser at the
|
|
||||||
tip of the tool - inverting the tool brings the eraser into proximity.
|
|
||||||
|
|
||||||
.. figure:: tablet-eraser-invert.svg
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
An pen-like tool used as pen and as eraser by inverting it
|
|
||||||
|
|
||||||
Having an eraser as a separate tool is beneficial in many applications as the
|
|
||||||
eraser tool can be assigned different functionality (colors, paint tools, etc.)
|
|
||||||
that is easily available.
|
|
||||||
|
|
||||||
However, a large proportion of tablet pens have an "eraser button". By
|
|
||||||
pressing the button the pen switches to be an eraser tool.
|
|
||||||
On the data level this is not done via a button event, instead the firmware
|
|
||||||
will pretend the pen tool going out of proximity and the eraser coming
|
|
||||||
into proximity immediately after - as if the tool was physically inverted.
|
|
||||||
|
|
||||||
.. figure:: tablet-eraser-button.svg
|
|
||||||
:align: center
|
|
||||||
|
|
||||||
An pen-like tool used as pen and as eraser by pressing the eraser button
|
|
||||||
|
|
||||||
Microsoft mandates this behavior (see
|
|
||||||
`Windows Pen States <https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states>`_
|
|
||||||
for details) and thus the overwhelming majority of devices will have
|
|
||||||
an eraser button that virtually inverts the pen.
|
|
||||||
|
|
||||||
Enforcing an eraser button means that users have one button less on the
|
|
||||||
stylus that they would have otherwise. For some users the eraser button
|
|
||||||
is in an inconvenient location, others don't want an eraser button at all.
|
|
||||||
|
|
||||||
libinput provides an eraser button configuration that allows disabling the
|
|
||||||
eraser button and turning it into a normal button event. If the eraser button
|
|
||||||
is disabled, pressing that button will generate a normal tablet tool button
|
|
||||||
event.
|
|
||||||
|
|
||||||
This configuration is only available on pens with an eraser button, not on
|
|
||||||
with an invert-type eraser.
|
|
||||||
76
doc/tapping.dox
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
@page tapping Tap-to-click behaviour
|
||||||
|
|
||||||
|
"Tapping" or "tap-to-click" is the name given to the behavior where a short
|
||||||
|
finger touch down/up sequence maps into a button click. This is most
|
||||||
|
commonly used on touchpads, but may be available on other devices.
|
||||||
|
|
||||||
|
libinput implements tapping for one, two, and three fingers, where supported
|
||||||
|
by the hardware, and maps those taps into a left, right, and middle button
|
||||||
|
click, respectively. Not all devices support three fingers, libinput will
|
||||||
|
support tapping up to whatever is supported by the hardware. libinput does
|
||||||
|
not support four-finger taps or any tapping with more than four fingers,
|
||||||
|
even though some hardware can distinguish between that many fingers.
|
||||||
|
|
||||||
|
@section tapping_default Tap-to-click default setting
|
||||||
|
|
||||||
|
Tapping is **disabled** by default on most devices, see [this
|
||||||
|
commit](https://gitlab.freedesktop.org/libinput/libinput/commit/2219c12c3aa45b80f235e761e87c17fb9ec70eae)
|
||||||
|
because:
|
||||||
|
- if you don't know that tapping is a thing (or enabled by default), you get
|
||||||
|
spurious button events that make the desktop feel buggy.
|
||||||
|
- if you do know what tapping is and you want it, you usually know where to
|
||||||
|
enable it, or at least you can search for it.
|
||||||
|
|
||||||
|
Tapping is **enabled** by default on devices where tapping is the only
|
||||||
|
method to trigger button clicks. This includes devices without physical
|
||||||
|
buttons such as touch-capable graphics tablets.
|
||||||
|
|
||||||
|
Tapping can be enabled/disabled on a per-device basis. See
|
||||||
|
libinput_device_config_tap_set_enabled() for details.
|
||||||
|
|
||||||
|
@section tapndrag Tap-and-drag
|
||||||
|
|
||||||
|
libinput also supports "tap-and-drag" where a tap immediately followed by a
|
||||||
|
finger down and that finger being held down emulates a button press. Moving
|
||||||
|
the finger around can thus drag the selected item on the screen.
|
||||||
|
Tap-and-drag is optional and can be enabled or disabled with
|
||||||
|
libinput_device_config_tap_set_drag_enabled(). Most devices have
|
||||||
|
tap-and-drag enabled by default.
|
||||||
|
|
||||||
|
Also optional is a feature called "drag lock". With drag lock disabled, lifting
|
||||||
|
the finger will stop any drag process. When enabled, libinput will ignore a
|
||||||
|
finger up event during a drag process, provided the finger is set down again
|
||||||
|
within a implementation-specific timeout. Drag lock can be enabled and
|
||||||
|
disabled with libinput_device_config_tap_set_drag_lock_enabled().
|
||||||
|
Note that drag lock only applies if tap-and-drag is be enabled.
|
||||||
|
|
||||||
|
@image html tap-n-drag.svg "Tap-and-drag process"
|
||||||
|
|
||||||
|
The above diagram explains the process, a tap (a) followed by a finger held
|
||||||
|
down (b) starts the drag process and logically holds the left mouse button
|
||||||
|
down. A movement of the finger (c) will drag the selected item until the
|
||||||
|
finger is released (e). If needed and drag lock is enabled, the finger's
|
||||||
|
position can be reset by lifting and quickly setting it down again on the
|
||||||
|
touchpad (d). This will be interpreted as continuing move and is especially
|
||||||
|
useful on small touchpads or with slow pointer acceleration.
|
||||||
|
If drag lock is enabled, the release of the mouse buttons after the finger
|
||||||
|
release (e) is triggered by a timeout. To release the button immediately,
|
||||||
|
simply tap again (f).
|
||||||
|
|
||||||
|
If two fingers are supported by the hardware, a second finger can be used to
|
||||||
|
drag while the first is held in-place.
|
||||||
|
|
||||||
|
@section tap_constraints Constraints while tapping
|
||||||
|
|
||||||
|
A couple of constraints apply to the contact to be converted into a press, the most common ones are:
|
||||||
|
- the touch down and touch up must happen within an implementation-defined timeout
|
||||||
|
- if a finger moves more than an implementation-defined distance while in contact, it's not a tap
|
||||||
|
- tapping within @ref clickpad_softbuttons "clickpad software buttons" may not trigger an event
|
||||||
|
- a tap not meeting required pressure thresholds can be ignored as accidental touch
|
||||||
|
- a tap exceeding certain pressure thresholds can be ignored (see @ref
|
||||||
|
palm_detection)
|
||||||
|
- a tap on the edges of the touchpad can usually be ignored (see @ref
|
||||||
|
palm_detection)
|
||||||
|
|
||||||
|
*/
|
||||||
134
doc/test-suite.dox
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
/**
|
||||||
|
@page test-suite libinput test suite
|
||||||
|
|
||||||
|
libinput ships with a number of tests all run automatically on `ninja test`.
|
||||||
|
The primary test suite is the `libinput-test-suite-runner`. When testing,
|
||||||
|
the `libinput-test-suite-runner` should always be invoked to check for
|
||||||
|
behavior changes.
|
||||||
|
|
||||||
|
The test suite runner uses
|
||||||
|
[Check](http://check.sourceforge.net/doc/check_html/) underneath the hood
|
||||||
|
but most of the functionality is abstracted into *litest* wrappers.
|
||||||
|
|
||||||
|
The test suite runner has a make-like job control enabled by the `-j` or
|
||||||
|
`--jobs` flag and will fork off as many parallel processes as given by this
|
||||||
|
flag. The default if unspecified is 8. When debugging a specific test case
|
||||||
|
failure it is recommended to employ test filtures (see @ref test-filtering)
|
||||||
|
and disable parallel tests. The test suite automatically disables parallel
|
||||||
|
make when run in gdb.
|
||||||
|
|
||||||
|
@section test-config X.Org config to avoid interference
|
||||||
|
|
||||||
|
uinput devices created by the test suite are usually recognised by X as
|
||||||
|
input devices. All events sent through these devices will generate X events
|
||||||
|
and interfere with your desktop.
|
||||||
|
|
||||||
|
Copy the file `$srcdir/test/50-litest.conf` into your `/etc/X11/xorg.conf.d`
|
||||||
|
and restart X. This will ignore any litest devices and thus not interfere
|
||||||
|
with your desktop.
|
||||||
|
|
||||||
|
@section test-root Permissions required to run tests
|
||||||
|
|
||||||
|
Most tests require the creation of uinput devices and access to the
|
||||||
|
resulting `/dev/input/eventX` nodes. Some tests require temporary udev rules.
|
||||||
|
<b>This usually requires the tests to be run as root</b>. If not run as
|
||||||
|
root, the test suite runner will exit with status 77, interpreted as
|
||||||
|
"skipped" by ninja.
|
||||||
|
|
||||||
|
@section test-filtering Selective running of tests
|
||||||
|
|
||||||
|
litest's tests are grouped into test groups, test names and devices. A test
|
||||||
|
group is e.g. "touchpad:tap" and incorporates all tapping-related tests for
|
||||||
|
touchpads. Each test function is (usually) run with one or more specific
|
||||||
|
devices. The `--list` commandline argument shows the list of suites and
|
||||||
|
tests. This is useful when trying to figure out if a specific test is
|
||||||
|
run for a device.
|
||||||
|
|
||||||
|
@code
|
||||||
|
$ ./test/libinput-test-suite-runner --list
|
||||||
|
...
|
||||||
|
pointer:left-handed:
|
||||||
|
pointer_left_handed_during_click_multiple_buttons:
|
||||||
|
trackpoint
|
||||||
|
ms-surface-cover
|
||||||
|
mouse-wheelclickcount
|
||||||
|
mouse-wheelclickangle
|
||||||
|
low-dpi-mouse
|
||||||
|
mouse-roccat
|
||||||
|
mouse-wheel-tilt
|
||||||
|
mouse
|
||||||
|
logitech-trackball
|
||||||
|
cyborg-rat
|
||||||
|
magicmouse
|
||||||
|
pointer_left_handed_during_click:
|
||||||
|
trackpoint
|
||||||
|
ms-surface-cover
|
||||||
|
mouse-wheelclickcount
|
||||||
|
mouse-wheelclickangle
|
||||||
|
low-dpi-mouse
|
||||||
|
mouse-roccat
|
||||||
|
mouse-wheel-tilt
|
||||||
|
mouse
|
||||||
|
logitech-trackball
|
||||||
|
cyborg-rat
|
||||||
|
litest-magicmouse-device
|
||||||
|
pointer_left_handed:
|
||||||
|
trackpoint
|
||||||
|
ms-surface-cover
|
||||||
|
mouse-wheelclickcount
|
||||||
|
mouse-wheelclickangle
|
||||||
|
low-dpi-mouse
|
||||||
|
mouse-roccat
|
||||||
|
mouse-wheel-tilt
|
||||||
|
mouse
|
||||||
|
...
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
In the above example, the "pointer:left-handed" suite contains multiple
|
||||||
|
tests, e.g. "pointer_left_handed_during_click" (this is also the function
|
||||||
|
name of the test, making it easy to grep for). This particular test is run
|
||||||
|
for various devices including the trackpoint device and the magic mouse
|
||||||
|
device.
|
||||||
|
|
||||||
|
The "no device" entry signals that litest does not instantiate a uinput
|
||||||
|
device for a specific test (though the test itself may
|
||||||
|
instantiate one).
|
||||||
|
|
||||||
|
The `--filter-test` argument enables selective running of tests through
|
||||||
|
basic shell-style function name matching. For example:
|
||||||
|
|
||||||
|
@code
|
||||||
|
$ ./test/libinput-test-suite-runner --filter-test="*1fg_tap*"
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
The `--filter-device` argument enables selective running of tests through
|
||||||
|
basic shell-style device name matching. The device names matched are the
|
||||||
|
litest-specific shortnames, see the output of `--list`. For example:
|
||||||
|
|
||||||
|
@code
|
||||||
|
$ ./test/libinput-test-suite-runner --filter-device="synaptics*"
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
The `--filter-group` argument enables selective running of test groups
|
||||||
|
through basic shell-style test group matching. The test groups matched are
|
||||||
|
litest-specific test groups, see the output of `--list`. For example:
|
||||||
|
|
||||||
|
@code
|
||||||
|
$ ./test/libinput-test-suite-runner --filter-group="touchpad:*hover*"
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
The `--filter-device` and `--filter-group` arguments can be combined with
|
||||||
|
`--list` to show which groups and devices will be affected.
|
||||||
|
|
||||||
|
@section test-verbosity Controlling test output
|
||||||
|
|
||||||
|
Each test supports the `--verbose` commandline option to enable debugging
|
||||||
|
output, see libinput_log_set_priority() for details. The `LITEST_VERBOSE`
|
||||||
|
environment variable, if set, also enables verbose mode.
|
||||||
|
|
||||||
|
@code
|
||||||
|
$ ./test/libinput-test-suite-runner --verbose
|
||||||
|
$ LITEST_VERBOSE=1 ninja test
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
*/
|
||||||
36
doc/timestamps.dox
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
/**
|
||||||
|
|
||||||
|
@page timestamps Timestamps
|
||||||
|
|
||||||
|
@section event_timestamps Event timestamps
|
||||||
|
|
||||||
|
Most libinput events provide a timestamp in millisecond and/or microsecond
|
||||||
|
resolution. These timestamp usually increase monotonically, but libinput
|
||||||
|
does not guarantee that this always the case. In other words, it is possible
|
||||||
|
to receive an event with a timestamp earlier than the previous event.
|
||||||
|
|
||||||
|
For example, if a touchpad has @ref tapping enabled, a button event may have a
|
||||||
|
lower timestamp than an event from a different device. Tapping requires the
|
||||||
|
use of timeouts to detect multi-finger taps and/or @ref tapndrag.
|
||||||
|
|
||||||
|
Consider the following event sequences from a touchpad and a mouse:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
Time Touchpad Mouse
|
||||||
|
---------------------------------
|
||||||
|
t1 finger down
|
||||||
|
t2 finger up
|
||||||
|
t3 movement
|
||||||
|
t4 tap timeout
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
For this event sequence, the first event to be sent to a caller is in
|
||||||
|
response to the mouse movement: an event of type @ref
|
||||||
|
LIBINPUT_EVENT_POINTER_MOTION with the timestamp t3.
|
||||||
|
Once the timeout expires at t4, libinput generates an event of
|
||||||
|
@ref LIBINPUT_EVENT_POINTER_BUTTON (press) with a timestamp t1 and an event
|
||||||
|
@ref LIBINPUT_EVENT_POINTER_BUTTON (release) with a timestamp t2.
|
||||||
|
|
||||||
|
Thus, the caller gets events with timestamps in the order t3, t1, t2,
|
||||||
|
despite t3 > t2 > t1.
|
||||||
|
*/
|
||||||
237
doc/tools.dox
Normal file
|
|
@ -0,0 +1,237 @@
|
||||||
|
/**
|
||||||
|
@page tools Helper tools
|
||||||
|
|
||||||
|
libinput provides a `libinput` tool to query state and events. This tool
|
||||||
|
takes a subcommand as argument, similar to the **git** command. A full
|
||||||
|
explanation of the various commands available in the libinput tool is
|
||||||
|
available in the **libinput(1)** man page.
|
||||||
|
|
||||||
|
The most common tools used are:
|
||||||
|
- `libinput list-devices`: to list locally available devices, see @ref
|
||||||
|
libinput-list-devices "here"
|
||||||
|
- `libinput debug-events`: to monitor and debug events, see @ref
|
||||||
|
libinput-debug-events "here"
|
||||||
|
- `libinput debug-gui`: to visualize events, see @ref libinput-debug-gui
|
||||||
|
"here"
|
||||||
|
- `libinput record`: to record an event sequence for replaying, see @ref
|
||||||
|
libinput-record "here"
|
||||||
|
- `libinput measure`: measure properties on a kernel device, see @ref
|
||||||
|
libinput-measure "here"
|
||||||
|
|
||||||
|
Most the tools must be run as root to have access to the kernel's @c
|
||||||
|
/dev/input/event* device files.
|
||||||
|
|
||||||
|
@section libinput-list-devices libinput list-devices
|
||||||
|
|
||||||
|
The `libinput list-devices` command shows information about devices
|
||||||
|
recognized by libinput and can help identifying why a device behaves
|
||||||
|
different than expected. For example, if a device does not show up in the
|
||||||
|
output, it is not a supported input device.
|
||||||
|
|
||||||
|
@note This tool does **not** show your desktop's configuration, just the
|
||||||
|
libinput built-in defaults.
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
$ sudo libinput list-devices
|
||||||
|
[...]
|
||||||
|
Device: SynPS/2 Synaptics TouchPad
|
||||||
|
Kernel: /dev/input/event4
|
||||||
|
Group: 9
|
||||||
|
Seat: seat0, default
|
||||||
|
Size: 97.33x66.86mm
|
||||||
|
Capabilities: pointer
|
||||||
|
Tap-to-click: disabled
|
||||||
|
Tap drag lock: disabled
|
||||||
|
Left-handed: disabled
|
||||||
|
Nat.scrolling: disabled
|
||||||
|
Middle emulation: n/a
|
||||||
|
Calibration: n/a
|
||||||
|
Scroll methods: *two-finger
|
||||||
|
Click methods: *button-areas clickfinger
|
||||||
|
[...]
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
The above listing shows example output for a touchpad. The
|
||||||
|
`libinput list-devices` command lists general information about the device
|
||||||
|
(the kernel event node) but also the configuration options. If an option is
|
||||||
|
"n/a" it does not exist on this device. Otherwise, the tool will show the
|
||||||
|
default configuration for this device, for options that have more than a
|
||||||
|
binary state all available options are listed, with the default one prefixed
|
||||||
|
with an asterisk (*). In the example above, the default click method is
|
||||||
|
button-areas but clickinger is available.
|
||||||
|
|
||||||
|
@note This tool is intended to be human-readable and may change its output
|
||||||
|
at any time.
|
||||||
|
|
||||||
|
@section libinput-debug-events libinput debug-events
|
||||||
|
The `libinput debug-events` command prints events from devices and can help
|
||||||
|
to identify why a device behaves different than expected.
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
$ sudo libinput debug-events --enable-tapping --set-click-method=clickfinger
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
All configuration options (enable/disable tapping,
|
||||||
|
etc.) are available as commandline arguments. To reproduce the event
|
||||||
|
sequence as your desktop session sees it, ensure that all options are turned
|
||||||
|
on or off as required. See the **libinput-debug-events(1)** man page or the
|
||||||
|
`--help` output for information about the available options.
|
||||||
|
|
||||||
|
@note When submitting a bug report, always use the `--verbose` flag to get
|
||||||
|
additional information: `libinput debug-events --verbose <other options>`
|
||||||
|
|
||||||
|
An example output from this tool may look like the snippet below.
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
$ sudo libinput debug-events --enable-tapping --set-click-method=clickfinger
|
||||||
|
-event2 DEVICE_ADDED Power Button seat0 default group1 cap:k
|
||||||
|
-event5 DEVICE_ADDED Video Bus seat0 default group2 cap:k
|
||||||
|
-event0 DEVICE_ADDED Lid Switch seat0 default group3 cap:S
|
||||||
|
-event1 DEVICE_ADDED Sleep Button seat0 default group4 cap:k
|
||||||
|
-event4 DEVICE_ADDED HDA Intel HDMI HDMI/DP,pcm=3 seat0 default group5 cap:
|
||||||
|
-event11 DEVICE_ADDED HDA Intel HDMI HDMI/DP,pcm=7 seat0 default group6 cap:
|
||||||
|
-event12 DEVICE_ADDED HDA Intel HDMI HDMI/DP,pcm=8 seat0 default group7 cap:
|
||||||
|
-event13 DEVICE_ADDED HDA Intel HDMI HDMI/DP,pcm=9 seat0 default group8 cap:
|
||||||
|
-event14 DEVICE_ADDED HDA Intel HDMI HDMI/DP,pcm=10 seat0 default group9 cap:
|
||||||
|
-event19 DEVICE_ADDED Integrated Camera: Integrated C seat0 default group10 cap:k
|
||||||
|
-event15 DEVICE_ADDED HDA Intel PCH Dock Mic seat0 default group11 cap:
|
||||||
|
-event16 DEVICE_ADDED HDA Intel PCH Mic seat0 default group12 cap:
|
||||||
|
-event17 DEVICE_ADDED HDA Intel PCH Dock Headphone seat0 default group13 cap:
|
||||||
|
-event18 DEVICE_ADDED HDA Intel PCH Headphone seat0 default group14 cap:
|
||||||
|
-event6 DEVICE_ADDED ELAN Touchscreen seat0 default group15 cap:t size 305x172mm ntouches 10 calib
|
||||||
|
-event3 DEVICE_ADDED AT Translated Set 2 keyboard seat0 default group16 cap:k
|
||||||
|
-event20 DEVICE_ADDED SynPS/2 Synaptics TouchPad seat0 default group17 cap:pg size 100x76mm tap(dl off) left scroll-nat scroll-2fg-edge click-buttonareas-clickfinger dwt-on
|
||||||
|
-event21 DEVICE_ADDED TPPS/2 IBM TrackPoint seat0 default group18 cap:p left scroll-nat scroll-button
|
||||||
|
-event7 DEVICE_ADDED ThinkPad Extra Buttons seat0 default group19 cap:k
|
||||||
|
-event20 POINTER_MOTION +3.62s 2.72/ -0.93
|
||||||
|
event20 POINTER_MOTION +3.63s 1.80/ -1.42
|
||||||
|
event20 POINTER_MOTION +3.65s 6.16/ -2.28
|
||||||
|
event20 POINTER_MOTION +3.66s 6.42/ -1.99
|
||||||
|
event20 POINTER_MOTION +3.67s 8.99/ -1.42
|
||||||
|
event20 POINTER_MOTION +3.68s 11.30/ 0.00
|
||||||
|
event20 POINTER_MOTION +3.69s 21.32/ 1.42
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
@section libinput-debug-gui libinput debug-gui
|
||||||
|
|
||||||
|
A simple GTK-based graphical tool that shows the behavior and location of
|
||||||
|
touch events, pointer motion, scroll axes and gestures. Since this tool
|
||||||
|
gathers data directly from libinput, it is thus suitable for
|
||||||
|
pointer-acceleration testing.
|
||||||
|
|
||||||
|
@note This tool does **not** use your desktop's configuration, just the
|
||||||
|
libinput built-in defaults.
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
$ sudo libinput debug-gui --enable-tapping
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
As with @ref libinput-debug-events, all options must be specified on the
|
||||||
|
commandline to emulate the correct behavior.
|
||||||
|
See the **libinput-debug-gui(1)** man page or the `--help` output for information about
|
||||||
|
the available options.
|
||||||
|
|
||||||
|
@section libinput-record libinput record and libinput replay
|
||||||
|
|
||||||
|
The `libinput record` command records the **kernel** events from a specific
|
||||||
|
device node. The recorded sequence can be replayed with the `libinput
|
||||||
|
replay` command. This pair of tools is crucial to capturing bugs and
|
||||||
|
reproducing them on a developer's machine.
|
||||||
|
|
||||||
|
@note These tools are shipped with libinput, but the recorded events
|
||||||
|
are **kernel events** and independent of the libinput context. libinput does not
|
||||||
|
need to be running, it does not matter whether a user is running X.Org or
|
||||||
|
Wayland or even what version of libinput is currently running.
|
||||||
|
|
||||||
|
The use of the tools is straightforward, just run without arguments, piping
|
||||||
|
the output into a file:
|
||||||
|
@verbatim
|
||||||
|
$ sudo libinput record > touchpad.log
|
||||||
|
Available devices:
|
||||||
|
/dev/input/event0: Lid Switch
|
||||||
|
/dev/input/event1: Sleep Button
|
||||||
|
/dev/input/event2: Power Button
|
||||||
|
/dev/input/event3: AT Translated Set 2 keyboard
|
||||||
|
/dev/input/event4: ThinkPad Extra Buttons
|
||||||
|
/dev/input/event5: ELAN Touchscreen
|
||||||
|
/dev/input/event6: Video Bus
|
||||||
|
/dev/input/event7: HDA Intel HDMI HDMI/DP,pcm=3
|
||||||
|
/dev/input/event8: HDA Intel HDMI HDMI/DP,pcm=7
|
||||||
|
/dev/input/event9: HDA Intel HDMI HDMI/DP,pcm=8
|
||||||
|
/dev/input/event10: HDA Intel HDMI HDMI/DP,pcm=9
|
||||||
|
/dev/input/event11: HDA Intel HDMI HDMI/DP,pcm=10
|
||||||
|
/dev/input/event12: HDA Intel PCH Dock Mic
|
||||||
|
/dev/input/event13: HDA Intel PCH Mic
|
||||||
|
/dev/input/event14: HDA Intel PCH Dock Headphone
|
||||||
|
/dev/input/event15: HDA Intel PCH Headphone
|
||||||
|
/dev/input/event16: Integrated Camera: Integrated C
|
||||||
|
/dev/input/event17: SynPS/2 Synaptics TouchPad
|
||||||
|
/dev/input/event18: TPPS/2 IBM TrackPoint
|
||||||
|
Select the device event number: 17
|
||||||
|
/dev/input/event17 recording to stdout
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
Without arguments, `libinput record` displays the available devices and lets
|
||||||
|
the user select one. Supply the number (17 in this case for
|
||||||
|
`/dev/input/event17`) and the tool will print the device information and
|
||||||
|
events to the file it is redirected to. More arguments are available, see
|
||||||
|
the **libinput-record(1)** man page.
|
||||||
|
|
||||||
|
Reproduce the bug, ctrl+c and attach the output file to a bug report.
|
||||||
|
For data protection, `libinput record` obscures key codes by default, any
|
||||||
|
alphanumeric key shows up as letter "a".
|
||||||
|
|
||||||
|
@note When reproducing a bug that crashes libinput, run inside `screen` or
|
||||||
|
`tmux`.
|
||||||
|
|
||||||
|
The recording can be replayed with the `libinput replay` command:
|
||||||
|
@verbatim
|
||||||
|
$ sudo libinput replay touchpad.log
|
||||||
|
SynPS/2 Synaptics TouchPad: /dev/input/event19
|
||||||
|
Hit enter to start replaying
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
`libinput replay` creates a new virtual device based on the description in
|
||||||
|
the log file. Hitting enter replays the event sequence once and the tool
|
||||||
|
stops once all events have been replayed. Hitting enter again replays the
|
||||||
|
sequence again, Ctrl+C stops it and removes the virtual device.
|
||||||
|
|
||||||
|
Users are advised to always replay a recorded event sequence to ensure they
|
||||||
|
have captured the bug.
|
||||||
|
|
||||||
|
More arguments are available, see the **libinput-record(1)** and
|
||||||
|
**libinput-replay(1)** man pages.
|
||||||
|
|
||||||
|
@subsection libinput-record-multiple Recording multiple devices at once
|
||||||
|
|
||||||
|
In some cases, an interaction between multiple devices is the cause for a
|
||||||
|
specific bug. For example, a touchpad may not work in response to keyboard
|
||||||
|
events. To accurately reproduce this sequence, the timing between multiple
|
||||||
|
devices must be correct and we need to record the events in one go.
|
||||||
|
|
||||||
|
`libinput record` has a `--multiple` argument to record multiple devices at
|
||||||
|
once. Unlike the normal invocation, this one requires a number of arguments:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
$ sudo libinput record --multiple --output-file=touchpad-bug.log /dev/input/event17 /dev/input/event3
|
||||||
|
recording to 'touchpad-bug.log'
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
As seen above, a user must specify `--multiple` and the `--output-file`.
|
||||||
|
Finally, all devices to be recorded must be specified on the commandline as
|
||||||
|
well.
|
||||||
|
|
||||||
|
Replaying events is the same as for a single recording:
|
||||||
|
@verbatim
|
||||||
|
$ sudo libinput replay touchpad-bug.log
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
@subsection libinput-measure Measuring device properties with libinput measure
|
||||||
|
|
||||||
|
The `libinput measure` tool is a multiplexer for various sub-tools that can
|
||||||
|
measure specific properties on the device. These tools generally measure one
|
||||||
|
thing and one thing only and their usage is highly specific to the tool.
|
||||||
|
Please see the **libinput-measure(1)** man page for information about what
|
||||||
|
tools are available and the man page for each respective tool.
|
||||||
|
|
||||||
|
*/
|
||||||
|
Before Width: | Height: | Size: 147 KiB |
90
doc/touchpad-jitter.dox
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
/**
|
||||||
|
@page touchpad_jitter Touchpad jitter
|
||||||
|
|
||||||
|
Touchpad jitter describes random movement by a few pixels even when the
|
||||||
|
user's finger is unmoving.
|
||||||
|
|
||||||
|
libinput has a mechanism called a **hysteresis** to avoid that jitter. When
|
||||||
|
active, movement with in the **hysteresis margin** is discarded. If the
|
||||||
|
movement delta is larger than the margin, the movement is passed on as
|
||||||
|
pointer movement. This is a simplified summary, developers should
|
||||||
|
read the implementation of the hysteresis in `src/evdev.c`.
|
||||||
|
|
||||||
|
libinput uses the kernel `fuzz` value to determine the size of the
|
||||||
|
hysteresis. Users should override this with a udev hwdb entry where the
|
||||||
|
device itself does not provide the correct value.
|
||||||
|
|
||||||
|
@section touchpad_jitter_fuzz_override Overriding the hysteresis margins
|
||||||
|
|
||||||
|
libinput provides the debugging tool `libinput measure fuzz` to help edit or
|
||||||
|
test a fuzz value. This tool is interactive and provides a udev hwdb entry
|
||||||
|
that matches the device. To check if a fuzz is currently present, simply run
|
||||||
|
without arguments or with the touchpad's device node:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
$ sudo libinput measure fuzz
|
||||||
|
Using Synaptics TM2668-002: /dev/input/event17
|
||||||
|
Checking udev property... not set
|
||||||
|
Checking axes... x=16 y=16
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
In the above output, the axis fuzz is set to 16. To set a specific fuzz, run
|
||||||
|
with the `--fuzz=<value>` argument.
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
$ sudo libinput measure fuzz --fuzz=8
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
The tool will attempt to construct a hwdb file that matches your touchpad
|
||||||
|
device. Follow the printed prompts.
|
||||||
|
|
||||||
|
In the ideal case, the tool will provide you with a file that can be
|
||||||
|
submitted to the systemd repo for inclusion.
|
||||||
|
|
||||||
|
However, hwdb entry creation is difficult to automate and it's likely
|
||||||
|
that the tools fails in doing so, especially if an existing entry is already
|
||||||
|
present.
|
||||||
|
|
||||||
|
Below is the outline of what a user needs to do to override a device's fuzz
|
||||||
|
value in case the `libinput measure fuzz` tool fails.
|
||||||
|
|
||||||
|
Check with `udevadm info /sys/class/input/eventX` (replace your device node
|
||||||
|
number) whether an existing hwdb override exists. If the `EVDEV_ABS_`
|
||||||
|
properties are present, the hwdb overried exists. Find the file that
|
||||||
|
contains that entry, most likely in `/etc/udev/hwdb.d` or
|
||||||
|
`/usr/lib/udev/hwdb.d`.
|
||||||
|
|
||||||
|
The content of the property is a set of values in the format
|
||||||
|
`EVDEV_ABS_00=min:max:resolution:fuzz`. You need to set the `fuzz` part,
|
||||||
|
leaving the remainder of the property as-is. Values may be empty, e.g. a
|
||||||
|
property that only sets resolution and fuzz reads as `EVDEV_ABS_00=::32:8`.
|
||||||
|
|
||||||
|
If no properties exist, your hwdb.entry should look approximately like this:
|
||||||
|
@verbatim
|
||||||
|
evdev:name:Synaptics TM2668-002:dmi:*:svnLENOVO*:pvrThinkPadT440s*:
|
||||||
|
EVDEV_ABS_00=:::8
|
||||||
|
EVDEV_ABS_01=:::8
|
||||||
|
EVDEV_ABS_35=:::8
|
||||||
|
EVDEV_ABS_36=:::8
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
Substitute the `name` field with the device name (see the output of
|
||||||
|
`libinput measure fuzz` and the DMI match content with your hardware. See
|
||||||
|
@ref hwdb_modifying for details.
|
||||||
|
|
||||||
|
Once the hwdb entry has been modified, added, or created, @ref
|
||||||
|
hwdb_reloading "reload the hwdb". Once reloaded, @ref libinput-record
|
||||||
|
"libinput record" should show the new fuzz value for the axes.
|
||||||
|
|
||||||
|
Restart the host and libinput should pick up the revised fuzz values.
|
||||||
|
|
||||||
|
@section kernel_fuzz Kernel fuzz
|
||||||
|
|
||||||
|
A fuzz set on an absolute axis in the kernel causes the kernel to apply
|
||||||
|
hysteresis-like behavior to the axis. Unfortunately, this behavior leads to
|
||||||
|
inconsistent deltas. To avoid this, libinput sets the kernel fuzz on the
|
||||||
|
device to 0 to disable this kernel behavior but remembers what the fuzz was
|
||||||
|
on startup. The fuzz is stored in the `LIBINPUT_FUZZ_XX` udev property, on
|
||||||
|
startup libinput will check that property as well as the axis itself.
|
||||||
|
|
||||||
|
*/
|
||||||
54
doc/touchpad-jumping-cursors.dox
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
@page touchpad_jumping_cursor Touchpad jumping cursor bugs
|
||||||
|
|
||||||
|
A common bug encountered on touchpads is a cursor jump when alternating
|
||||||
|
between fingers on a multi-touch-capable touchpad. For example, after moving
|
||||||
|
the cursor a user may use a second finger in the software button area to
|
||||||
|
physically click the touchpad. Upon setting the finger down, the cursor
|
||||||
|
exhibits a jump towards the bottom left or right, depending on the finger
|
||||||
|
position.
|
||||||
|
|
||||||
|
When libinput detects a cursor jump it prints a bug warning to the log with
|
||||||
|
the text <b>"Touch jump detected and discarded."</b> and a link to this page.
|
||||||
|
|
||||||
|
In most cases, this is a bug in the 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 evemu-record output for the device:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
E: 249.206319 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
|
||||||
|
E: 249.218008 0003 0035 3764 # EV_ABS / ABS_MT_POSITION_X 3764
|
||||||
|
E: 249.218008 0003 0036 2221 # EV_ABS / ABS_MT_POSITION_Y 2221
|
||||||
|
E: 249.218008 0003 003a 0065 # EV_ABS / ABS_MT_PRESSURE 65
|
||||||
|
E: 249.218008 0003 0000 3764 # EV_ABS / ABS_X 3764
|
||||||
|
E: 249.218008 0003 0001 2216 # EV_ABS / ABS_Y 2216
|
||||||
|
E: 249.218008 0003 0018 0065 # EV_ABS / ABS_PRESSURE 65
|
||||||
|
E: 249.218008 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
|
||||||
|
E: 249.230881 0003 0035 3752 # EV_ABS / ABS_MT_POSITION_X 3752
|
||||||
|
E: 249.230881 0003 003a 0046 # EV_ABS / ABS_MT_PRESSURE 46
|
||||||
|
E: 249.230881 0003 0000 3758 # EV_ABS / ABS_X 3758
|
||||||
|
E: 249.230881 0003 0018 0046 # EV_ABS / ABS_PRESSURE 46
|
||||||
|
E: 249.230881 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
|
||||||
|
E: 249.242648 0003 0035 1640 # EV_ABS / ABS_MT_POSITION_X 1640
|
||||||
|
E: 249.242648 0003 0036 4681 # EV_ABS / ABS_MT_POSITION_Y 4681
|
||||||
|
E: 249.242648 0003 003a 0025 # EV_ABS / ABS_MT_PRESSURE 25
|
||||||
|
E: 249.242648 0003 0000 1640 # EV_ABS / ABS_X 1640
|
||||||
|
E: 249.242648 0003 0001 4681 # EV_ABS / ABS_Y 4681
|
||||||
|
E: 249.242648 0003 0018 0025 # EV_ABS / ABS_PRESSURE 25
|
||||||
|
E: 249.242648 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
|
||||||
|
E: 249.254568 0003 0035 1648 # EV_ABS / ABS_MT_POSITION_X 1648
|
||||||
|
E: 249.254568 0003 003a 0027 # EV_ABS / ABS_MT_PRESSURE 27
|
||||||
|
E: 249.254568 0003 0000 1644 # EV_ABS / ABS_X 1644
|
||||||
|
E: 249.254568 0003 0018 0027 # EV_ABS / ABS_PRESSURE 27
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
In this recording, the pointer jumps from its position 3752/2216 to
|
||||||
|
1640/4681 within a single frame. On this particular touchpad, this would
|
||||||
|
represent a physical move of almost 50mm. libinput detects some of these
|
||||||
|
jumps and discards the movement but otherwise continues as usual. However,
|
||||||
|
the bug should be fixed at the kernel level.
|
||||||
|
|
||||||
|
When you encounter the warning in the log, please generate an evemu
|
||||||
|
recording of your touchpad and file a bug. See @ref reporting_bugs for more
|
||||||
|
details.
|
||||||
|
*/
|
||||||
217
doc/touchpad-pressure.dox
Normal file
|
|
@ -0,0 +1,217 @@
|
||||||
|
/**
|
||||||
|
@page touchpad_pressure Touchpad pressure-based touch detection
|
||||||
|
|
||||||
|
libinput uses the touchpad pressure values and/or touch size values to
|
||||||
|
detect wether a finger has been placed on the touchpad. This is @ref
|
||||||
|
kernel_pressure_information and combines with a libinput-specific hardware
|
||||||
|
database to adjust the thresholds on a per-device basis. libinput uses
|
||||||
|
these thresholds primarily to filter out accidental light touches but
|
||||||
|
the information is also used for some @ref palm_detection.
|
||||||
|
|
||||||
|
Pressure and touch size thresholds are **not** directly configurable by the
|
||||||
|
user. Instead, libinput provides these thresholds for each device where
|
||||||
|
necessary. See @ref touchpad_pressure_hwdb for instructions on how to adjust
|
||||||
|
the pressure ranges and @ref touchpad_touch_size_hwdb for instructions on
|
||||||
|
how to adjust the touch size ranges.
|
||||||
|
|
||||||
|
@section kernel_pressure_information Information provided by the kernel
|
||||||
|
|
||||||
|
The kernel sends multiple values to inform userspace about a finger touching
|
||||||
|
the touchpad. The most basic is the ```EV_KEY/BTN_TOUCH``` boolean event
|
||||||
|
that simply announces physical contact with the touchpad. The decision when
|
||||||
|
this event is sent is usually made by the kernel driver and may depend on
|
||||||
|
device-specific thresholds. These thresholds are transparent to userspace
|
||||||
|
and cannot be modified. On touchpads where pressure or touch size is not
|
||||||
|
available, libinput uses ```BTN_TOUCH``` to determine when a finger is
|
||||||
|
logically down.
|
||||||
|
|
||||||
|
Many contemporary touchpad devices provide an absolute pressure axis in
|
||||||
|
addition to ```BTN_TOUCH```. This pressure generally increases as the pressure
|
||||||
|
increases, however few touchpads are capable of detecting true pressure. The
|
||||||
|
pressure value is usually related to the covered area - as the pressure
|
||||||
|
increases a finger flattens and thus covers a larger area. The range
|
||||||
|
provided by the kernel is not mapped to a specific physical range and
|
||||||
|
often requires adjustment. Pressure is sent by the ```ABS_PRESSURE``` axis
|
||||||
|
for single-touch touchpads or ```ABS_MT_PRESSURE``` on multi-touch capable
|
||||||
|
touchpads. Some devices can detect multiple fingers but only provide
|
||||||
|
```ABS_PRESSURE```.
|
||||||
|
|
||||||
|
Some devices provide additional touch size information through
|
||||||
|
the ```ABS_MT_TOUCH_MAJOR/ABS_MT_TOUCH_MINOR``` axes and/or
|
||||||
|
the ```ABS_MT_WIDTH_MAJOR/ABS_MT_WIDTH_MINOR``` axes. These axes specifcy
|
||||||
|
the size of the touch ellipse. While the kernel documentation specifies how
|
||||||
|
these axes are supposed to be mapped, few devices forward reliable
|
||||||
|
information. libinput uses these values together with a device-specific hwdb
|
||||||
|
entry. In other words, touch size detection does not work unless a hwdb
|
||||||
|
entry is present for the device.
|
||||||
|
|
||||||
|
@section touchpad_pressure_hwdb Debugging touchpad pressure ranges
|
||||||
|
|
||||||
|
This section describes how to determine the touchpad pressure ranges
|
||||||
|
required for a touchpad device and how to add the required hwdb entry
|
||||||
|
locally. Note that the hwdb entry is **not public API** and **may change at
|
||||||
|
any time**. Users are advised to @ref reporting_bugs "report a bug" with the
|
||||||
|
updated pressure ranges when testing has completed.
|
||||||
|
|
||||||
|
Use the ```libinput measure touchpad-pressure``` tool provided by libinput.
|
||||||
|
This tool will search for your touchpad device and print some pressure
|
||||||
|
statistics, including whether a touch is/was considered logically down.
|
||||||
|
|
||||||
|
@note This tool will only work on touchpads with pressure.
|
||||||
|
|
||||||
|
Example output of the tool is below:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
$ sudo libinput measure touchpad-pressure
|
||||||
|
Ready for recording data.
|
||||||
|
Pressure range used: 8:10
|
||||||
|
Palm pressure range used: 65535
|
||||||
|
Place a single finger on the touchpad to measure pressure values.
|
||||||
|
Ctrl+C to exit
|
||||||
|
|
||||||
|
Sequence 1190 pressure: min: 39 max: 48 avg: 43 median: 44 tags: down
|
||||||
|
Sequence 1191 pressure: min: 49 max: 65 avg: 62 median: 64 tags: down
|
||||||
|
Sequence 1192 pressure: min: 40 max: 78 avg: 64 median: 66 tags: down
|
||||||
|
Sequence 1193 pressure: min: 36 max: 83 avg: 70 median: 73 tags: down
|
||||||
|
Sequence 1194 pressure: min: 43 max: 76 avg: 72 median: 74 tags: down
|
||||||
|
Touchpad pressure: 47 min: 47 max: 86 tags: down
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
The example output shows five completed touch sequences and one ongoing one.
|
||||||
|
For each, the respective minimum and maximum pressure values are printed as
|
||||||
|
well as some statistics. The ```tags``` show that sequence was considered
|
||||||
|
logically down at some point. This is an interactive tool and its output may
|
||||||
|
change frequently. Refer to the <i>libinput-measure-touchpad-pressure(1)</i> man
|
||||||
|
page for more details.
|
||||||
|
|
||||||
|
By default, this tool uses the udev hwdb entries for the pressure range. To
|
||||||
|
narrow down on the best values for your device, specify the 'logically down'
|
||||||
|
and 'logically up' pressure thresholds with the ```--touch-thresholds``
|
||||||
|
argument:
|
||||||
|
<pre>
|
||||||
|
$ sudo libinput measure touchpad-pressure --touch-thresholds=10:8 --palm-threshold=20
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Interact with the touchpad and check if the output of this tool matches your
|
||||||
|
expectations.
|
||||||
|
|
||||||
|
@note **This is an interactive process. You will need to re-run the
|
||||||
|
tool with varying thresholds until you find the right range for your
|
||||||
|
touchpad. Attaching output logs to a bug will not help, only you with access
|
||||||
|
to the hardware can figure out the correct ranges.**
|
||||||
|
|
||||||
|
Once the thresholds are decided on (e.g. 10 and 8), they can be enabled with
|
||||||
|
the following hwdb file:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
$> cat /etc/udev/hwdb.d/99-touchpad-pressure.hwdb
|
||||||
|
libinput:name:*SynPS/2 Synaptics TouchPad:dmi:*svnHewlett-Packard:*pnHPCompaq6910p*
|
||||||
|
LIBINPUT_ATTR_PRESSURE_RANGE=10:8
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
The first line is the match line and should be adjusted for the device name
|
||||||
|
(see evemu-record's output) and for the local system, based on the
|
||||||
|
information in ```/sys/class/dmi/id/modalias```. The modalias should be
|
||||||
|
shortened to the specific system's information, usually system vendor (svn)
|
||||||
|
and product name (pn).
|
||||||
|
|
||||||
|
Once in place, you need to run the following to commands, adjusted for your
|
||||||
|
device's event node (see @ref faq_hwdb_changes):
|
||||||
|
<pre>
|
||||||
|
sudo udevadm hwdb --update
|
||||||
|
sudo udevadm test /sys/class/input/eventX
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
If the pressure range property shows up correctly, restart X or the
|
||||||
|
Wayland compositor and libinput should now use the correct pressure
|
||||||
|
thresholds. The @ref tools can be used to verify the correct
|
||||||
|
functionality first without the need for a restart.
|
||||||
|
|
||||||
|
Once the pressure ranges are deemed correct,
|
||||||
|
@ref reporting_bugs "report a bug" to get the pressure ranges into the
|
||||||
|
repository.
|
||||||
|
|
||||||
|
@section touchpad_touch_size_hwdb Debugging touch size ranges
|
||||||
|
|
||||||
|
This section describes how to determine the touchpad touch size ranges
|
||||||
|
required for a touchpad device and how to add the required hwdb entry
|
||||||
|
locally. Note that the hwdb entry is **not public API** and **may change at
|
||||||
|
any time**. Users are advised to @ref reporting_bugs "report a bug" with the
|
||||||
|
updated pressure ranges when testing has completed.
|
||||||
|
|
||||||
|
Use the ```libinput measure touch-size``` tool provided by libinput.
|
||||||
|
This tool will search for your touchpad device and print some touch size
|
||||||
|
statistics, including whether a touch is/was considered logically down.
|
||||||
|
|
||||||
|
@note This tool will only work on touchpads with the ```ABS_MT_MAJOR``` axis.
|
||||||
|
|
||||||
|
Example output of the tool is below:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
$ sudo libinput measure touch-size --touch-thresholds 10:8 --palm-threshold 14
|
||||||
|
Using ELAN Touchscreen: /dev/input/event5
|
||||||
|
|
||||||
|
Ready for recording data.
|
||||||
|
Touch sizes used: 10:8
|
||||||
|
Palm size used: 14
|
||||||
|
Place a single finger on the device to measure touch size.
|
||||||
|
Ctrl+C to exit
|
||||||
|
|
||||||
|
Sequence: major: [ 9.. 11] minor: [ 7.. 9]
|
||||||
|
Sequence: major: [ 9.. 10] minor: [ 7.. 7]
|
||||||
|
Sequence: major: [ 9.. 14] minor: [ 6.. 9] down
|
||||||
|
Sequence: major: [ 11.. 11] minor: [ 9.. 9] down
|
||||||
|
Sequence: major: [ 4.. 33] minor: [ 1.. 5] down palm
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
The example output shows five completed touch sequences. For each, the
|
||||||
|
respective minimum and maximum pressure values are printed as well as some
|
||||||
|
statistics. The ```down``` and ```palm``` tags show that sequence was considered
|
||||||
|
logically down or a palm at some point. This is an interactive tool and its
|
||||||
|
output may change frequently. Refer to the <i>libinput-measure-touch-size(1)</i> man
|
||||||
|
page for more details.
|
||||||
|
|
||||||
|
By default, this tool uses the udev hwdb entries for the touch size range. To
|
||||||
|
narrow down on the best values for your device, specify the 'logically down'
|
||||||
|
and 'logically up' pressure thresholds with the ```--touch-thresholds``
|
||||||
|
arguments as in the example above.
|
||||||
|
|
||||||
|
Interact with the touchpad and check if the output of this tool matches your
|
||||||
|
expectations.
|
||||||
|
|
||||||
|
@note **This is an interactive process. You will need to re-run the
|
||||||
|
tool with varying thresholds until you find the right range for your
|
||||||
|
touchpad. Attaching output logs to a bug will not help, only you with access
|
||||||
|
to the hardware can figure out the correct ranges.**
|
||||||
|
|
||||||
|
Once the thresholds are decided on (e.g. 10 and 8), they can be enabled with
|
||||||
|
the following hwdb file:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
$> cat /etc/udev/hwdb.d/99-touchpad-pressure.hwdb
|
||||||
|
libinput:name:*SynPS/2 Synaptics TouchPad:dmi:*svnHewlett-Packard:*pnHPCompaq6910p*
|
||||||
|
LIBINPUT_ATTR_TOUCH_SIZE_RANGE=10:8
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
The first line is the match line and should be adjusted for the device name
|
||||||
|
(see evemu-record's output) and for the local system, based on the
|
||||||
|
information in ```/sys/class/dmi/id/modalias```. The modalias should be
|
||||||
|
shortened to the specific system's information, usually system vendor (svn)
|
||||||
|
and product name (pn).
|
||||||
|
|
||||||
|
Once in place, you need to run the following to commands, adjusted for your
|
||||||
|
device's event node (see @ref faq_hwdb_changes):
|
||||||
|
<pre>
|
||||||
|
sudo udevadm hwdb --update
|
||||||
|
sudo udevadm test /sys/class/input/eventX
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
If the touch size range property shows up correctly, restart X or the
|
||||||
|
Wayland compositor and libinput should now use the correct thresholds.
|
||||||
|
The @ref tools can be used to verify the correct functionality first without
|
||||||
|
the need for a restart.
|
||||||
|
|
||||||
|
Once the touch size ranges are deemed correct, @ref reporting_bugs "report a
|
||||||
|
bug" to get the thresholds into the repository.
|
||||||
|
|
||||||
|
*/
|
||||||
|
Before Width: | Height: | Size: 181 KiB After Width: | Height: | Size: 166 KiB |