kcontrol: the touchpad module is no longer usefull

This commit is contained in:
Ivailo Monev 2016-07-14 18:58:18 +00:00
parent c56989d2d9
commit 090ebdf0b7
77 changed files with 0 additions and 6930 deletions

View file

@ -20,8 +20,6 @@ if(X11_Xkb_FOUND)
endif(X11_Xkb_FOUND)
add_subdirectory( input )
# TODO: make conditional?
add_subdirectory( touchpad )
add_subdirectory( access )
add_subdirectory( screensaver )
add_subdirectory( dateandtime )

View file

@ -1,6 +0,0 @@
project(kcm-touchpad)
set(TOUCHPAD_KCM_VERSION "1.1")
add_subdirectory(src)
add_subdirectory(icon)

View file

@ -1,347 +0,0 @@
NOTE! The GPL below is copyrighted by the Free Software Foundation, but
the instance of code that it refers to (the kde programs) are copyrighted
by the authors who actually wrote it.
---------------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View file

@ -1,6 +0,0 @@
#!/bin/sh
$EXTRACTRC `find src -path src/applet -prune -o \( -name \*.rc -o -name \*.ui -o -name \*.kcfg \) -print` >> rc.cpp
$XGETTEXT rc.cpp `find src -path src/applet -prune -o \( -name \*.cpp -o -name \*.h \) -print` -o $podir/kcm_touchpad.pot
$XGETTEXT `find src/applet -name \*.qml -o -name \*.js` -o $podir/plasma_applet_touchpad.pot

View file

@ -1,63 +0,0 @@
Touchpad KCM
============
* KCModule
* Daemon
- Automatically enable/disable touchpad when typing and/or when mouse is plugged in
- Enable/disable touchpad with keyboard shortcuts
* Applet
- Shows touchpad's state
- Toggle touchpad with single click
Dependencies
------------
* KDElibs 4
* Xlib
* xcb
* xf86-input-synaptics (headers are required to build)
How to install
--------------
$ mkdir build
$ cd build
$ cmake -DCMAKE_INSTALL_PREFIX="$(kde4-config --prefix)" ..
$ make
# make install
### Packages
* [Ubuntu][1]
- [Kubuntu Experimental PPA][2]
* [Arch Linux][3]
- [AUR (from git master)][4]
Translations
------------
Translations live in KDE's svn repository.
If they aren't shipped as part of KDE l10n packages, translations could be built and installed by adding -DTRANSLATIONS="lang1 lang2 ..." to cmake command line.
Language names are the same as in .desktop files.
.po files are fetched from svn repository automatically.
If downloading isn't possible, .po files could be placed in source directory under names "kcm_touchpad_lang1.po" and "plasma_applet_touchpad_lang1.po", where "lang1" is replaced with proper language name.
Bugs
----
Bugs should be reported to [KDE Bugzilla, product: Touchpad KCM][5]
Patches
-------
I'm always happy to accept patches at:
* [KDE reviewboard][6], repository "kcm-touchpad". The repository contains a .reviewboardrc file.
* [GitHub with pull request][7].
[1]: http://packages.ubuntu.com/trusty/kde/kde-touchpad
[2]: https://code.launchpad.net/~rohangarg/+recipe/touchpad-daily
[3]: https://www.archlinux.org/packages/community/x86_64/kcm-touchpad/
[4]: https://aur.archlinux.org/packages/kcm-touchpad-git/
[5]: https://bugs.kde.org/enter_bug.cgi?product=Touchpad%20KCM
[6]: https://git.reviewboard.kde.org/
[7]: https://github.com/sanya-m/kde-touchpad-config

View file

@ -1 +0,0 @@
kde4_install_icons(${ICON_INSTALL_DIR})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 920 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

View file

@ -1,4 +0,0 @@
#!/bin/sh
for size in 16 22 24 32 48 64 96 128 256; do
convert -background none hisc-devices-input-touchpad.svgz -resize "$size"x"$size" hi"$size"-devices-input-touchpad.png
done

View file

@ -1,81 +0,0 @@
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/version.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/version.h
)
SET(SRCS
plugins.cpp
touchpadbackend.cpp
)
include(x11/x11.cmake)
set(SRCS
${SRCS}
kcm/customslider.cpp
kcm/sliderpair.cpp
kcm/testarea.cpp
kcm/testbutton.cpp
kcm/touchpadconfig.cpp
kcm/touchpadparametersbase.cpp
kcm/customconfigdialogmanager.cpp
kcm/pointermotion.ui
kcm/tap.ui
kcm/scroll.ui
kcm/sensitivity.ui
kcm/kded.ui
kcm/testarea.ui
)
qt4_add_dbus_interfaces(SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.touchpad.xml)
kde4_add_kcfg_files(SRCS kcm/touchpadparameters.kcfgc)
qt4_generate_dbus_interface(kded/kded.h org.kde.touchpad.xml)
SET(SRCS
${SRCS}
kded/kded.cpp
kded/kdedactions.cpp
)
kde4_add_kcfg_files(SRCS kded/kdedsettings.kcfgc)
kde4_add_plugin(kded_touchpad
${SRCS}
${backend_SRCS}
)
target_link_libraries(kded_touchpad
${backend_LIBS}
${KDE4_KDEUI_LIBS}
${KDE4_PLASMA_LIBS}
${KDE4_KNOTIFYCONFIG_LIBS}
)
add_subdirectory(applet)
install(FILES kcm/kcm_touchpad.desktop
DESTINATION ${SERVICES_INSTALL_DIR}
)
install(FILES kded/touchpaddaemon.kcfg
DESTINATION ${KCFG_INSTALL_DIR}
)
install(FILES kded/kded_touchpad.desktop
DESTINATION ${SERVICES_INSTALL_DIR}/kded
RENAME touchpad.desktop
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.touchpad.xml
DESTINATION ${DBUS_INTERFACES_INSTALL_DIR}
)
install(FILES kded/kcm_touchpad.notifyrc
DESTINATION ${DATA_INSTALL_DIR}/kcm_touchpad
)
install(TARGETS kded_touchpad
DESTINATION ${PLUGIN_INSTALL_DIR}
)
install(FILES kcm/touchpad.kcfg
DESTINATION ${KCFG_INSTALL_DIR}
)

View file

@ -1,36 +0,0 @@
add_subdirectory(qml)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/dataengine.desktop"
"${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-touchpad.desktop"
)
set(Applet_SRCS
touchpadengine.cpp
touchpadservice.cpp
)
qt4_generate_dbus_interface(../kded/kded.h org.kde.touchpad.xml)
qt4_add_dbus_interfaces(Applet_SRCS
${CMAKE_CURRENT_BINARY_DIR}/org.kde.touchpad.xml
)
qt4_add_dbus_interfaces(Applet_SRCS
${KDE4_DBUS_INTERFACES_DIR}/org.kde.kded.xml
)
kde4_add_plugin(plasma_engine_touchpad ${Applet_SRCS})
target_link_libraries(plasma_engine_touchpad
${KDE4_PLASMA_LIBS}
)
install(TARGETS plasma_engine_touchpad
DESTINATION ${PLUGIN_INSTALL_DIR}
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/plasma-dataengine-touchpad.desktop
DESTINATION ${SERVICES_INSTALL_DIR}
)
install(FILES touchpad.operations
DESTINATION ${DATA_INSTALL_DIR}/plasma/services
)
install(FILES touchpad.svg
DESTINATION ${DATA_INSTALL_DIR}/desktoptheme/default/icons
)

View file

@ -1,40 +0,0 @@
[Desktop Entry]
Name=Touchpad DataEngine
Name[bs]=Pogon podataka za dodirnu površinu
Name[cs]=Datový stroj pro touchpad
Name[da]=Datamotor-motor
Name[de]=Touchpad-Datenquelle
Name[el]=Μηχανή δεδομένων επιφάνειας αφής
Name[es]=Motor de datos del panel táctil
Name[fi]=Kosketuslevyn tietomoottori
Name[fr]=Moteur de données du pavé tactile
Name[hu]=Érintőtábla adatmotor
Name[ko]=
Name[lt]=Jutiklinio kilimėlio Duomenų variklis
Name[nl]=Gegevensengine voor touchpad
Name[pl]=Silnik danych gładzika
Name[pt]=Motor de Dados do Rato por Toque
Name[pt_BR]=Mecanismo de dados do touchpad
Name[ro]=Motor de date Zonă tactilă
Name[sk]=Touchpad DataEngine
Name[sl]=PodatkovniPogon za sledilno ploščico
Name[sv]=Datagränssnitt för tryckplatta
Name[tr]=Dokunmatik Yüzey Veri Motoru
Name[uk]=Рушій даних сенсорної панелі
Name[x-test]=xxTouchpad DataEnginexx
Icon=input-touchpad
Type=Service
X-KDE-ServiceTypes=Plasma/DataEngine
X-KDE-Library=plasma_engine_touchpad
X-KDE-PluginInfo-Name=touchpad
X-KDE-PluginInfo-Category=System Information
X-KDE-PluginInfo-Author=Alexander Mezin
X-KDE-PluginInfo-Email=mezin.alexander@gmail.com
X-KDE-PluginInfo-Version=@TOUCHPAD_KCM_VERSION@
X-KDE-PluginInfo-Website=https://projects.kde.org/projects/playground/utils/kcm-touchpad/
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-EnabledByDefault=true
X-Plasma-EngineName=touchpad

View file

@ -1,16 +0,0 @@
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/metadata.desktop
${CMAKE_CURRENT_BINARY_DIR}/metadata.desktop
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/metadata.desktop
DESTINATION ${DATA_INSTALL_DIR}/plasma/plasmoids/touchpad
)
install(DIRECTORY contents/
DESTINATION ${DATA_INSTALL_DIR}/plasma/plasmoids/touchpad/contents
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/metadata.desktop
DESTINATION ${SERVICES_INSTALL_DIR}
RENAME plasma-applet-touchpad.desktop
)

View file

@ -1,140 +0,0 @@
// -*- coding: iso-8859-1 -*-
/*
* Copyright 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import QtQuick 1.1
import org.kde.plasma.core 0.1 as PlasmaCore
import org.kde.plasma.components 0.1 as PlasmaComponents
import org.kde.qtextracomponents 0.1
Item {
id: root
Component.onCompleted: {
plasmoid.aspectRatioMode = Square
}
PlasmaCore.DataSource {
id: dataSource
engine: "touchpad"
connectedSources: dataSource.sources
onNewData: {
if (data.enabled === null) {
return
}
if (data.enabled) {
//Hide plasmoid from notification area after short delay
delayedStatusUpdate.restart()
} else {
plasmoid.status = ActiveStatus
}
icon.elementId = data.enabled ? "touchpad_enabled"
: "touchpad_disabled"
plasmoid.setAction("toggle", data.enabled ? i18n("Disable touchpad")
: i18n("Enable touchpad"))
}
}
property bool hasTouchpad: typeof dataSource.data.touchpad != 'undefined'
property bool enabled: hasTouchpad ? dataSource.data.touchpad.enabled
: false
property bool mouse: hasTouchpad ? dataSource.data.touchpad.mousePluggedIn
: false
Timer {
id: delayedStatusUpdate
interval: 1000
running: true
onTriggered: {
if (!hasTouchpad) {
//Setting this in Component.onCompleted didn't work
plasmoid.status = PassiveStatus
return
}
plasmoid.status = enabled ? PassiveStatus : ActiveStatus
}
}
PlasmaCore.SvgItem {
id: icon
anchors.fill: parent
svg: PlasmaCore.Svg {
multipleImages: true
imagePath: "icons/touchpad"
}
}
QIconItem {
anchors.fill: parent
visible: !hasTouchpad
icon: "dialog-warning"
}
PlasmaCore.ToolTip {
target: root
mainText: {
if (!hasTouchpad) {
return i18n("No touchpad was found");
}
return enabled ? i18n("Touchpad is enabled")
: i18n("Touchpad is disabled")
}
image: {
if (!hasTouchpad) {
return "dialog-error"
}
return enabled ? "input-touchpad" : "process-stop"
}
}
MouseArea {
anchors.fill: parent
onClicked: action_toggle()
enabled: hasTouchpad
}
function action_toggle() {
if (!mouse && enabled) {
confirmDialog.open()
return
}
execOp("toggle")
}
function execOp(op) {
var service = dataSource.serviceForSource("touchpad")
service.startOperationCall(service.operationDescription(op))
}
PlasmaComponents.QueryDialog {
id: confirmDialog
visualParent: root
titleText: i18n("Touchpad")
titleIcon: "dialog-warning"
message: i18n("No mouse was detected.\nAre you sure you want to disable the touchpad?")
acceptButtonText: i18n("Disable")
onAccepted: execOp("disable")
}
}

View file

@ -1,89 +0,0 @@
[Desktop Entry]
Comment=Shows current touchpad state
Comment[bs]=Prikazuje trenutno stanje dodirne površine
Comment[cs]=Zobrazí současný stav touchpadu
Comment[da]=Vis aktuel touchpad-tilstand
Comment[de]=Zeigt den aktuellen Status des Touchpads an
Comment[el]=Εμφανίζει την τρέχουσα κατάσταση της επιφάνειας αφής
Comment[es]=Muestra el estado actual del panel táctil
Comment[fi]=Näyttää kosketuslevyn nykyisen tilan
Comment[fr]=Affiche l'état courant du pavé tactile
Comment[hu]=Megjeleníti a jelenlegi érintőtábla állapotot
Comment[ko]=
Comment[lt]=Rodo dabartinę kilimėlio būsena
Comment[nl]=Huidige status van touchpad tonen
Comment[pl]=Pokazuje bieżący stan gładzika
Comment[pt]=Mostra o estado actual do rato por toque
Comment[pt_BR]=Mostra o estado atual do touchpad
Comment[ro]=Arată starea curentă a zonei tactile
Comment[sk]=Zobrazí aktuálny stav touchpadu
Comment[sl]=Prikazuje trenutno stanje sledilne ploščice
Comment[sv]=Visar tryckplattans aktuellt tillstånd
Comment[tr]=Geçerli dokunmatik yüzey durumunu gösterir
Comment[uk]=Показує поточний стан сенсорної панелі
Comment[x-test]=xxShows current touchpad statexx
Encoding=UTF-8
Icon=input-touchpad
Keywords=Touchpad
Keywords[bs]=Dodirna površina
Keywords[cs]=Touchpad
Keywords[da]=Touchpad
Keywords[de]=Touchpad
Keywords[el]=Επιφάνεια αφής
Keywords[es]=Panel táctil
Keywords[fi]=Kosketuslevy
Keywords[fr]=Pavé tactile
Keywords[hu]=Érintőtábla
Keywords[ko]=
Keywords[lt]=Jutiklinis kilimėlis
Keywords[nl]=Touchpad
Keywords[pl]=Gładzik
Keywords[pt]=Rato por Toque
Keywords[pt_BR]=Touchpad
Keywords[ro]=Zonă tactilă
Keywords[sk]=Touchpad
Keywords[sl]=Sledilna ploščica
Keywords[sv]=Tryckplatta
Keywords[tr]=Dokunmatik Yüzey
Keywords[uk]=Сенсорна панель
Keywords[x-test]=xxTouchpadxx
Name=Touchpad
Name[bs]=Dodirna površina
Name[cs]=Touchpad
Name[da]=Touchpad
Name[de]=Touchpad
Name[el]=Επιφάνεια αφής
Name[es]=Panel táctil
Name[fi]=Kosketuslevy
Name[fr]=Pavé tactile
Name[hu]=Érintőtábla
Name[ko]=
Name[lt]=Jutiklinis kilimėlis
Name[nl]=Touchpad
Name[pl]=Gładzik
Name[pt]=Rato por Toque
Name[pt_BR]=Touchpad
Name[ro]=Zonă tactilă
Name[sk]=Touchpad
Name[sl]=Sledilna ploščica
Name[sv]=Tryckplatta
Name[tr]=Dokunmatik Yüzey
Name[uk]=Сенсорна панель
Name[x-test]=xxTouchpadxx
Type=Service
X-KDE-ParentApp=
X-KDE-PluginInfo-Author=Alexander Mezin
X-KDE-PluginInfo-Category=System Information
X-KDE-PluginInfo-Email=mezin.alexander@gmail.com
X-KDE-PluginInfo-EnabledByDefault=true
X-KDE-PluginInfo-License=GPL
X-KDE-PluginInfo-Name=touchpad
X-KDE-PluginInfo-Version=@TOUCHPAD_KCM_VERSION@
X-KDE-PluginInfo-Website=https://projects.kde.org/projects/playground/utils/kcm-touchpad/
X-KDE-ServiceTypes=Plasma/Applet
X-Plasma-API=declarativeappletscript
X-Plasma-ConfigPlugins=kcm_touchpad
X-Plasma-DefaultSize=32,32
X-Plasma-MainScript=ui/touchpad.qml
X-Plasma-NotificationArea=true
X-Plasma-RemoteLocation=

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE kcfg SYSTEM "http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
<kcfg>
<group name="toggle">
</group>
<group name="disable">
</group>
<group name="enable">
</group>
</kcfg>

View file

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="128" height="64" id="svg2" version="1.1" inkscape:version="0.48.4 r9939" sodipodi:docname="touchpad.svg">
<defs id="defs4" />
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="3.959798" inkscape:cx="51.717623" inkscape:cy="35.126778" inkscape:document-units="px" inkscape:current-layer="touchpad_disabled" showgrid="false" showguides="true" inkscape:guide-bbox="true" inkscape:window-width="1366" inkscape:window-height="724" inkscape:window-x="-4" inkscape:window-y="21" inkscape:window-maximized="1" />
<metadata id="metadata7">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(0,-988.36218)">
<g id="touchpad_enabled">
<title id="title3772">touchpad_enabled</title>
<rect ry="5" rx="5" transform="translate(0,988.36218)" y="2.7595019" x="2.9041886" height="43.184021" width="58.210041" id="rect3755" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#353535;stroke-width:1.50000000000000000;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect ry="5" rx="5" y="1036.7048" x="2.9041886" height="13.889598" width="28.031733" id="rect3757" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#353535;stroke-width:1.50000000000000000;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#353535;stroke-width:1.50000000000000000;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" id="rect3759" width="28.031733" height="13.889598" x="32.829956" y="1036.5786" rx="5" ry="5" />
</g>
<g id="touchpad_disabled">
<title id="title3779">touchpad_disabled</title>
<rect style="fill:#ffffff;fill-opacity:0.19711539;fill-rule:nonzero;stroke:#323232;stroke-width:1.50000000000000000;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" id="rect3761" width="58.210041" height="43.184021" x="66.29126" y="990.61658" rx="5" ry="5" />
<rect style="fill:#ffffff;fill-opacity:0.19711539;fill-rule:nonzero;stroke:#323232;stroke-width:1.50000000000000000;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" id="rect3763" width="28.031733" height="13.889598" x="66.29126" y="1036.1997" rx="5" ry="5" />
<rect ry="5" rx="5" y="1036.0735" x="96.217026" height="13.889598" width="28.031733" id="rect3765" style="fill:#ffffff;fill-opacity:0.19711539;fill-rule:nonzero;stroke:#323232;stroke-width:1.50000000000000000;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

View file

@ -1,82 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "touchpadengine.h"
#include <QDBusConnection>
#include <QDBusInterface>
#include "touchpadinterface.h"
#include "touchpadservice.h"
#include "kdedinterface.h"
TouchpadEngine::TouchpadEngine(QObject *parent, const QVariantList &args)
: Plasma::DataEngine(parent, args), m_source("touchpad"), m_daemon(0)
{
}
void TouchpadEngine::init()
{
OrgKdeKdedInterface kded(QLatin1String("org.kde.kded"),
QLatin1String("/kded"),
QDBusConnection::sessionBus());
kded.loadModule("touchpad").waitForFinished();
m_daemon = new OrgKdeTouchpadInterface("org.kde.kded", "/modules/touchpad",
QDBusConnection::sessionBus(), this);
if (!m_daemon->isValid()) {
return;
}
QDBusPendingReply<bool> check(m_daemon->workingTouchpadFound());
check.waitForFinished();
if (!check.isValid() || !check.value()) {
return;
}
connect(m_daemon, SIGNAL(enabledChanged(bool)), SLOT(enabledChanged(bool)));
connect(m_daemon, SIGNAL(mousePluggedInChanged(bool)),
SLOT(mousePluggedInChanged(bool)));
enabledChanged(m_daemon->isEnabled());
mousePluggedInChanged(m_daemon->isMousePluggedIn());
}
void TouchpadEngine::mousePluggedInChanged(bool value)
{
setData(m_source, "mousePluggedIn", value);
}
void TouchpadEngine::enabledChanged(bool value)
{
setData(m_source, "enabled", value);
}
Plasma::Service *TouchpadEngine::serviceForSource(const QString &source)
{
if (source == m_source) {
return new TouchpadService(m_daemon, source, this);
}
return Plasma::DataEngine::serviceForSource(source);
}
TouchpadEngine::~TouchpadEngine()
{
}
K_EXPORT_PLASMA_DATAENGINE(touchpad, TouchpadEngine)

View file

@ -1,47 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef TOUCHPADENGINE_H
#define TOUCHPADENGINE_H
#include <Plasma/DataEngine>
class OrgKdeTouchpadInterface;
class TouchpadEngine : public Plasma::DataEngine
{
Q_OBJECT
public:
TouchpadEngine(QObject *parent, const QVariantList &args);
~TouchpadEngine();
Plasma::Service *serviceForSource(const QString &source);
protected:
void init();
private Q_SLOTS:
void mousePluggedInChanged(bool);
void enabledChanged(bool);
private:
QString m_source;
OrgKdeTouchpadInterface *m_daemon;
};
#endif // TOUCHPADENGINE_H

View file

@ -1,63 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "touchpadservice.h"
#include <Plasma/ServiceJob>
#include "touchpadinterface.h"
TouchpadService::TouchpadService(OrgKdeTouchpadInterface *daemon,
const QString &destination,
QObject *parent)
: Plasma::Service(parent), m_daemon(daemon), m_destination(destination)
{
setName("touchpad");
}
TouchpadService::~TouchpadService()
{
}
class TouchpadJob : public Plasma::ServiceJob
{
public:
TouchpadJob(OrgKdeTouchpadInterface *daemon,
const QString &destination, const QString &operation,
const QMap<QString, QVariant> &parameters, QObject *parent = 0)
: Plasma::ServiceJob(destination, operation, parameters, parent),
m_daemon(daemon)
{
}
void start()
{
if (m_daemon) {
QMetaObject::invokeMethod(m_daemon, operationName().toAscii());
}
emitResult();
}
private:
OrgKdeTouchpadInterface *m_daemon;
};
Plasma::ServiceJob *TouchpadService::createJob(const QString &operation,
QMap<QString, QVariant> &params)
{
return new TouchpadJob(m_daemon, m_destination, operation, params, this);
}

View file

@ -1,42 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef TOUCHPADSERVICE_H
#define TOUCHPADSERVICE_H
#include <Plasma/Service>
class OrgKdeTouchpadInterface;
class TouchpadService : public Plasma::Service
{
Q_OBJECT
public:
TouchpadService(OrgKdeTouchpadInterface *daemon, const QString &destination,
QObject *parent = 0);
~TouchpadService();
protected:
Plasma::ServiceJob *createJob(const QString &operation,
QMap<QString, QVariant> &parameters);
private:
OrgKdeTouchpadInterface *m_daemon;
QString m_destination;
};
#endif // TOUCHPADSERVICE_H

View file

@ -1,172 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "customconfigdialogmanager.h"
#include <cmath>
#include <QWidget>
#include <KConfigSkeleton>
#include <KComboBox>
#include <KDebug>
#include "customslider.h"
CustomConfigDialogManager::CustomConfigDialogManager(QWidget *parent,
KCoreConfigSkeleton *conf,
const QStringList &supported)
: KConfigDialogManager(parent, conf), m_config(conf)
{
static const QString kcfgPrefix("kcfg_");
Q_FOREACH(KConfigSkeletonItem *i, conf->items()) {
QString name(i->name());
QWidget *child = parent->findChild<QWidget*>(kcfgPrefix + name);
if (!child) {
continue;
}
m_widgets[name] = child;
if (!supported.contains(name)) {
child->setEnabled(false);
}
KCoreConfigSkeleton::ItemEnum *asEnum =
dynamic_cast<KCoreConfigSkeleton::ItemEnum *>(i);
if (!asEnum) {
continue;
}
QStringList choiceList;
Q_FOREACH(const KCoreConfigSkeleton::ItemEnum::Choice &c,
asEnum->choices())
{
if (c.label.isEmpty()) {
choiceList.append(c.name);
} else {
choiceList.append(c.label);
}
}
KComboBox *asComboBox = qobject_cast<KComboBox *>(child);
if (asComboBox) {
asComboBox->addItems(choiceList);
}
}
}
CustomConfigDialogManager::~CustomConfigDialogManager()
{
}
QVariantHash CustomConfigDialogManager::currentWidgetProperties() const
{
QVariantHash r;
for (QMap<QString, QWidget *>::ConstIterator i = m_widgets.begin();
i != m_widgets.end(); ++i)
{
r[i.key()] = property(i.value());
}
return r;
}
void CustomConfigDialogManager::setWidgetProperties(const QVariantHash &p)
{
for (QVariantHash::ConstIterator i = p.begin(); i != p.end(); ++i) {
QMap<QString, QWidget *>::ConstIterator j = m_widgets.find(i.key());
if (j != m_widgets.end()) {
setProperty(j.value(), i.value());
}
}
}
static bool variantFuzzyCompare(const QVariant &a, const QVariant &b)
{
if (a == b) {
return true;
}
bool isDouble_a = false, isDouble_b = false;
float d_a = static_cast<float>(a.toDouble(&isDouble_a)),
d_b = static_cast<float>(b.toDouble(&isDouble_b));
if (!isDouble_a || !isDouble_b) {
return false;
}
return (qFuzzyIsNull(d_a) && qFuzzyIsNull(d_b)) || qFuzzyCompare(d_a, d_b);
}
QVariant CustomConfigDialogManager::fixup(QWidget *widget, QVariant v) const
{
bool isDouble = false;
double value = v.toDouble(&isDouble);
if (!isDouble) {
return v;
}
QVariant decimals(widget->property("decimals"));
if (decimals.type() != QVariant::Int) {
CustomSlider *asSlider = qobject_cast<CustomSlider *>(widget);
if (asSlider) {
return asSlider->fixup(value);
}
return value;
}
double k = std::pow(10.0, decimals.toInt());
return std::floor(value * k + 0.5) / k; //round
}
bool CustomConfigDialogManager::compareWidgetProperties(const QVariantHash &p) const
{
bool result = true;
for (QVariantHash::ConstIterator i = p.begin(); i != p.end(); ++i) {
QMap<QString, QWidget *>::ConstIterator j = m_widgets.find(i.key());
if (j == m_widgets.end()) {
continue;
}
QWidget *widget = j.value();
QVariant widgetValue(fixup(widget, property(widget)));
QVariant fixed(fixup(widget, i.value()));
if (!variantFuzzyCompare(widgetValue, fixed)) {
result = false;
kDebug() << "Config mismatch:"
<< widget->objectName() << widgetValue << fixed;
}
}
return result;
}
bool CustomConfigDialogManager::hasChangedFuzzy() const
{
for (QMap<QString, QWidget *>::ConstIterator i = m_widgets.begin();
i != m_widgets.end(); ++i)
{
KConfigSkeletonItem *config = m_config->findItem(i.key());
QWidget *widget = i.value();
QVariant widgetValue(fixup(widget, property(widget)));
QVariant configValue(fixup(widget, config->property()));
if (!variantFuzzyCompare(widgetValue, configValue)) {
return true;
}
}
return false;
}

View file

@ -1,48 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef CUSTOMCONFIGDIALOGMANAGER_H
#define CUSTOMCONFIGDIALOGMANAGER_H
#include <QMap>
#include <QtCore/qvariant.h>
#include <KConfigDialogManager>
class CustomConfigDialogManager : public KConfigDialogManager
{
Q_OBJECT
public:
CustomConfigDialogManager(QWidget *parent,
KCoreConfigSkeleton *config,
const QStringList &supported);
~CustomConfigDialogManager();
QVariantHash currentWidgetProperties() const;
void setWidgetProperties(const QVariantHash &);
bool compareWidgetProperties(const QVariantHash &) const;
bool hasChangedFuzzy() const;
private:
QVariant fixup(QWidget *widget, QVariant value) const;
QMap<QString, QWidget *> m_widgets;
KCoreConfigSkeleton *m_config;
};
#endif // CUSTOMCONFIGDIALOGMANAGER_H

View file

@ -1,159 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "customslider.h"
#include <cmath>
#include <QtGui/qevent.h>
CustomSlider::Interpolator::~Interpolator()
{
}
double CustomSlider::Interpolator::absolute(double relative,
double minimum,
double maximum) const
{
return relative * (maximum - minimum) + minimum;
}
double CustomSlider::Interpolator::relative(double absolute,
double minimum,
double maximum) const
{
return (absolute - minimum) / (maximum - minimum);
}
double CustomSlider::SqrtInterpolator::absolute(
double relative, double minimum, double maximum) const
{
relative *= relative;
return Interpolator::absolute(relative, minimum, maximum);
}
double CustomSlider::SqrtInterpolator::relative(
double absolute, double minimum, double maximum) const
{
double value = Interpolator::relative(absolute, minimum, maximum);
return std::sqrt(value);
}
const CustomSlider::Interpolator CustomSlider::lerp;
CustomSlider::CustomSlider(QWidget *parent) :
QSlider(parent), m_min(0.0), m_max(1.0), m_interpolator(&lerp)
{
setSingleStep(10);
setPageStep(100);
updateValue();
updateRange(size());
connect(this, SIGNAL(actionTriggered(int)), SLOT(updateValue()));
}
void CustomSlider::resizeEvent(QResizeEvent *e)
{
QSlider::resizeEvent(e);
updateRange(e->size());
}
const CustomSlider::Interpolator *CustomSlider::interpolator() const
{
return m_interpolator;
}
void CustomSlider::setInterpolator(const CustomSlider::Interpolator *v)
{
m_interpolator = v;
}
void CustomSlider::setDoubleMinimum(double v)
{
m_min = v;
}
double CustomSlider::doubleMinimum() const
{
return m_min;
}
void CustomSlider::setDoubleMaximum(double v)
{
m_max = v;
}
double CustomSlider::doubleMaximum() const
{
return m_max;
}
double CustomSlider::doubleValue() const
{
return qBound(m_min, m_value, m_max);
}
void CustomSlider::setDoubleValue(double v)
{
if (m_value == v) {
return;
}
m_value = v;
int oldIntValue = value();
moveSlider();
if (value() != oldIntValue) {
Q_EMIT valueChanged(doubleValue());
}
}
double CustomSlider::intToDouble(int v) const
{
double relative = lerp.relative(v, minimum(), maximum());
return m_interpolator->absolute(relative, m_min, m_max);
}
void CustomSlider::updateValue()
{
m_value = intToDouble(sliderPosition());
Q_EMIT valueChanged(doubleValue());
}
double CustomSlider::fixup(double v) const
{
return intToDouble(doubleToInt(v));
}
int CustomSlider::doubleToInt(double v) const
{
double relative = m_interpolator->relative(v, m_min, m_max);
double absolute = lerp.absolute(relative, minimum(), maximum());
return static_cast<int>(std::floor(absolute + 0.5));
}
void CustomSlider::moveSlider()
{
setValue(doubleToInt(doubleValue()));
}
void CustomSlider::updateRange(const QSize &s)
{
setRange(0, (orientation() == Qt::Horizontal) ? s.width() : s.height());
moveSlider();
}

View file

@ -1,92 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef CUSTOMSLIDER_H
#define CUSTOMSLIDER_H
#include <QSlider>
class CustomSlider : public QSlider
{
Q_OBJECT
Q_PROPERTY(double minimum READ doubleMinimum WRITE setDoubleMinimum)
Q_PROPERTY(double maximum READ doubleMaximum WRITE setDoubleMaximum)
Q_PROPERTY(double value READ doubleValue WRITE setDoubleValue \
NOTIFY valueChanged USER true)
public:
explicit CustomSlider(QWidget *parent = 0);
void setDoubleMinimum(double);
double doubleMinimum() const;
void setDoubleMaximum(double);
double doubleMaximum() const;
class Interpolator
{
public:
Interpolator() { }
virtual double absolute(double relative,
double minimum, double maximum) const;
virtual double relative(double absolute,
double minimum, double maximum) const;
virtual ~Interpolator();
};
class SqrtInterpolator : public Interpolator
{
public:
SqrtInterpolator() { }
double absolute(double relative, double minimum, double maximum) const;
double relative(double absolute, double minimum, double maximum) const;
};
const Interpolator *interpolator() const;
void setInterpolator(const Interpolator *);
double doubleValue() const;
double fixup(double) const;
public Q_SLOTS:
void setDoubleValue(double);
Q_SIGNALS:
void valueChanged(double);
protected:
virtual void resizeEvent(QResizeEvent *);
private Q_SLOTS:
void updateValue();
private:
void updateRange(const QSize &);
void moveSlider();
int doubleToInt(double) const;
double intToDouble(int) const;
static const Interpolator lerp;
double m_min, m_max, m_value;
const Interpolator *m_interpolator;
};
#endif // CUSTOMSLIDER_H

View file

@ -1,84 +0,0 @@
[Desktop Entry]
Exec=kcmshell4 kcm_touchpad
Icon=input-touchpad
Type=Service
Categories=Qt;KDE;X-KDE-settings-hardware;
OnlyShowIn=KDE;
X-KDE-ServiceTypes=KCModule,KCModuleInit
X-KDE-Init-Symbol=touchpad
X-KDE-Init-Phase=0
X-KDE-Library=kded_touchpad
X-KDE-PluginKeyword=kcm
X-KDE-ParentApp=kcontrol
X-KDE-System-Settings-Parent-Category=input-devices
Name=Touchpad
Name[bs]=Dodirna površina
Name[cs]=Touchpad
Name[da]=Touchpad
Name[de]=Touchpad
Name[el]=Επιφάνεια αφής
Name[es]=Panel táctil
Name[fi]=Kosketuslevy
Name[fr]=Pavé tactile
Name[hu]=Érintőtábla
Name[ko]=
Name[lt]=Jutiklinis kilimėlis
Name[nl]=Touchpad
Name[pl]=Gładzik
Name[pt]=Rato por Toque
Name[pt_BR]=Touchpad
Name[ro]=Zonă tactilă
Name[sk]=Touchpad
Name[sl]=Sledilna ploščica
Name[sv]=Tryckplatta
Name[tr]=Dokunmatik Yüzey
Name[uk]=Сенсорна панель
Name[x-test]=xxTouchpadxx
Comment=Touchpad settings
Comment[bs]=Postavke dodirne površine
Comment[cs]=Nastavení touchpadu
Comment[da]=Touchpad-indstillinger
Comment[de]=Touchpadeinstellungen
Comment[el]=Ρυθμίσεις επιφάνειας αφής
Comment[es]=Preferencias del panel táctil
Comment[fi]=Kosketuslevyn asetukset
Comment[fr]=Configuration du pavé tactile
Comment[hu]=Érintőtábla beállítások
Comment[ko]=
Comment[lt]=Jutiklinio kilimėlio nustatymai
Comment[nl]=Instellingen van touchpad
Comment[pl]=Ustawienia gładzika
Comment[pt]=Configuração do rato por toque
Comment[pt_BR]=Configurações do touchpad
Comment[ro]=Configurări zonă tactilă
Comment[sk]=Nastavenia touchpadu
Comment[sl]=Nastavitve sledilne ploščice
Comment[sv]=Inställning av tryckplatta
Comment[tr]=Dokunmatik yüzey ayarları
Comment[uk]=Параметри сенсорної панелі
Comment[x-test]=xxTouchpad settingsxx
X-KDE-Keywords=Touchpad,Synaptics
X-KDE-Keywords[bs]=Dodirna površina,Synatics
X-KDE-Keywords[cs]=Touchpad,Synaptics
X-KDE-Keywords[da]=Touchpad,Synaptics
X-KDE-Keywords[de]=Touchpad,Synaptics
X-KDE-Keywords[el]=Επιφάνεια αφής,Synaptics
X-KDE-Keywords[es]=Panel táctil,Touchpad,Synaptics
X-KDE-Keywords[fi]=Touchpad,Synaptics,Kosketuslevy
X-KDE-Keywords[fr]=Pavé tactile,Synaptics
X-KDE-Keywords[hu]=Érintőtábla,Szinaptikusok
X-KDE-Keywords[ko]=Touchpad,Synaptics,
X-KDE-Keywords[lt]=Jutiklinis kilimėlis,Synaptics
X-KDE-Keywords[nl]=Touchpad,Synaptics
X-KDE-Keywords[pl]=Gładzik,Synaptics
X-KDE-Keywords[pt]=Rato,Toque,Synaptics
X-KDE-Keywords[pt_BR]=Touchpad,Synaptics
X-KDE-Keywords[ro]=Touchpad,Synaptics,Zonă tactilă,Tactil
X-KDE-Keywords[sk]=Touchpad,Synaptics
X-KDE-Keywords[sl]=Sledilna ploščica,Synaptics
X-KDE-Keywords[sv]=Tryckplatta,Synaptics
X-KDE-Keywords[tr]=Dokunmatik Yüzey,Synaptics
X-KDE-Keywords[uk]=Touchpad,Synaptics,сенсорна,панель,тачпад,синаптикс
X-KDE-Keywords[x-test]=xxTouchpad,Synapticsxx

View file

@ -1,200 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>KdedForm</class>
<widget class="QWidget" name="KdedForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>486</width>
<height>351</height>
</rect>
</property>
<property name="windowTitle">
<string>Enable/Disable Touchpad</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item alignment="Qt::AlignHCenter">
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="1">
<widget class="QPushButton" name="configureShortcutsButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Configure</string>
</property>
<property name="icon">
<iconset theme="configure">
<normaloff/>
</iconset>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Keyboard shortcuts:</string>
</property>
<property name="buddy">
<cstring>configureShortcutsButton</cstring>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="kcfg_DisableOnKeyboardActivity">
<property name="title">
<string>Disable touchpad when typing</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout_3">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Timeout:</string>
</property>
<property name="buddy">
<cstring>kcfg_KeyboardActivityTimeoutMs</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="KIntNumInput" name="kcfg_KeyboardActivityTimeoutMs">
<property name="toolTip">
<string>If there was no keyboard activity for more than specified
number of milliseconds, touchpad will be enabled again</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="suffix">
<string> ms</string>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="kcfg_OnlyDisableTapAndScrollOnKeyboardActivity">
<property name="toolTip">
<string>Disable click emulation and scrolling.
You will be still able to move pointer using touchpad and perform clicks with hardware buttons.</string>
</property>
<property name="text">
<string>Disable taps and scrolling only</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="kcfg_DisableWhenMousePluggedIn">
<property name="title">
<string>Disable touchpad when mouse is plugged in</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QFormLayout" name="formLayout_2">
<property name="formAlignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
<item row="0" column="0">
<widget class="QLabel" name="notificationsLabel">
<property name="text">
<string>Notifications:</string>
</property>
<property name="buddy">
<cstring>configureNotificationsButton</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="configureNotificationsButton">
<property name="text">
<string>Configure</string>
</property>
<property name="icon">
<iconset theme="configure">
<normaloff/>
</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="KEditListWidget" name="kcfg_MouseBlacklist">
<property name="toolTip">
<string>Some devices might be incorrectly treated as a mouse.
You can add them to this list so that they will be ignored when they're plugged in.</string>
</property>
<property name="buttons">
<set>KEditListWidget::Add|KEditListWidget::Remove</set>
</property>
<property name="title" stdset="0">
<string>Ignored devices:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KEditListWidget</class>
<extends>QWidget</extends>
<header>keditlistwidget.h</header>
</customwidget>
<customwidget>
<class>KIntNumInput</class>
<extends>QWidget</extends>
<header>knuminput.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>configureShortcutsButton</tabstop>
<tabstop>kcfg_DisableOnKeyboardActivity</tabstop>
<tabstop>kcfg_KeyboardActivityTimeoutMs</tabstop>
<tabstop>kcfg_OnlyDisableTapAndScrollOnKeyboardActivity</tabstop>
<tabstop>kcfg_DisableWhenMousePluggedIn</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -1,310 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PointerMotionForm</class>
<widget class="QWidget" name="PointerMotionForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>407</height>
</rect>
</property>
<property name="windowTitle">
<string>Pointer Motion</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string comment="Mouse pointer motion parameters">Speed</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string comment="Minimum pointer movement speed">Minimum:</string>
</property>
<property name="buddy">
<cstring>kcfg_MinSpeed</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="CustomSlider" name="kcfg_MinSpeed">
<property name="toolTip">
<string>Minimum pointer speed</string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string comment="Maximum pointer movement speed">Maximum:</string>
</property>
<property name="buddy">
<cstring>kcfg_MaxSpeed</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="CustomSlider" name="kcfg_MaxSpeed">
<property name="toolTip">
<string>Maximum pointer speed</string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string comment="Pointer acceleration">Acceleration:</string>
</property>
<property name="buddy">
<cstring>kcfg_AccelFactor</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="CustomSlider" name="kcfg_AccelFactor">
<property name="toolTip">
<string>Acceleration factor for normal pointer movements</string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string comment="Pointer motion">Pressure-Dependent Motion</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string comment="Pressure-dependent pointer motion">Minimum pressure:</string>
</property>
<property name="buddy">
<cstring>kcfg_PressureMotionMinZ</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string comment="Pressure-dependent pointer motion">Minimum factor:</string>
</property>
<property name="buddy">
<cstring>kcfg_PressureMotionMinFactor</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string comment="Pressure-dependent pointer motion">Maximum pressure:</string>
</property>
<property name="buddy">
<cstring>kcfg_PressureMotionMaxZ</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string comment="Pressure-dependent pointer motion">Maximum factor:</string>
</property>
<property name="buddy">
<cstring>kcfg_PressureMotionMaxFactor</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="kcfg_PressureMotionMinZ">
<property name="toolTip">
<string>Finger pressure at which minimum pressure motion factor is applied</string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSlider" name="kcfg_PressureMotionMaxZ">
<property name="toolTip">
<string>Finger pressure at which maximum pressure motion factor is applied</string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="KDoubleNumInput" name="kcfg_PressureMotionMinFactor">
<property name="toolTip">
<string>Lowest setting for pressure motion factor</string>
</property>
<property name="suffix">
<string notr="true" comment="Speed multiplier suffix"> x</string>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="KDoubleNumInput" name="kcfg_PressureMotionMaxFactor">
<property name="toolTip">
<string>Greatest setting for pressure motion factor</string>
</property>
<property name="suffix">
<string notr="true" comment="Speed multiplier suffix"> x</string>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string comment="Pointer motion">Noise Cancellation</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string comment="Noise cancellation">Vertical:</string>
</property>
<property name="buddy">
<cstring>kcfg_VertHysteresis</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string comment="Noise cancellation">Horizontal:</string>
</property>
<property name="buddy">
<cstring>kcfg_HorizHysteresis</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="KIntNumInput" name="kcfg_VertHysteresis">
<property name="toolTip">
<string>The minimum vertical hardware distance required to generate motion events</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>10</number>
</property>
<property name="suffix">
<string> units</string>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="KIntNumInput" name="kcfg_HorizHysteresis">
<property name="toolTip">
<string>The minimum horizontal hardware distance required to generate motion events</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>10</number>
</property>
<property name="suffix">
<string> units</string>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KDoubleNumInput</class>
<extends>QWidget</extends>
<header>knuminput.h</header>
</customwidget>
<customwidget>
<class>KIntNumInput</class>
<extends>QWidget</extends>
<header>knuminput.h</header>
</customwidget>
<customwidget>
<class>CustomSlider</class>
<extends>QSlider</extends>
<header>kcm/customslider.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>kcfg_MinSpeed</tabstop>
<tabstop>kcfg_MaxSpeed</tabstop>
<tabstop>kcfg_AccelFactor</tabstop>
<tabstop>kcfg_PressureMotionMinZ</tabstop>
<tabstop>kcfg_PressureMotionMinFactor</tabstop>
<tabstop>kcfg_PressureMotionMaxZ</tabstop>
<tabstop>kcfg_PressureMotionMaxFactor</tabstop>
<tabstop>kcfg_VertHysteresis</tabstop>
<tabstop>kcfg_HorizHysteresis</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -1,401 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ScrollForm</class>
<widget class="QWidget" name="ScrollForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>610</width>
<height>503</height>
</rect>
</property>
<property name="windowTitle">
<string>Scrolling</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::FieldsStayAtSizeHint</enum>
</property>
<property name="formAlignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Edge scrolling:</string>
</property>
<property name="buddy">
<cstring>kcfg_VertEdgeScroll</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="kcfg_VertEdgeScroll">
<property name="toolTip">
<string>Enable vertical scrolling when dragging along the right edge</string>
</property>
<property name="text">
<string comment="Scrolling direction">Vertical</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="kcfg_HorizEdgeScroll">
<property name="toolTip">
<string>Enable horizontal scrolling when dragging along the bottom edge</string>
</property>
<property name="text">
<string comment="Scrolling direction">Horizontal</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="kcfg_VertTwoFingerScroll">
<property name="toolTip">
<string>Enable vertical scrolling when dragging with two fingers anywhere on the touchpad</string>
</property>
<property name="text">
<string comment="Scrolling direction">Vertical</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="kcfg_HorizTwoFingerScroll">
<property name="toolTip">
<string>Enable horizontal scrolling when dragging with two fingers anywhere on the touchpad</string>
</property>
<property name="text">
<string comment="Scrolling direction">Horizontal</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="kcfg_InvertVertScroll">
<property name="toolTip">
<string>Reverse vertical scrolling</string>
</property>
<property name="text">
<string comment="Scrolling direction">Vertical</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="kcfg_InvertHorizScroll">
<property name="toolTip">
<string>Reverse horizontal scrolling</string>
</property>
<property name="text">
<string comment="Scrolling direction">Horizontal</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Two-finger scrolling:</string>
</property>
<property name="buddy">
<cstring>kcfg_VertTwoFingerScroll</cstring>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Reverse scrolling:</string>
</property>
<property name="buddy">
<cstring>kcfg_InvertVertScroll</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="title">
<string comment="Touchpad - Scrolling">Scrolling Distance</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string comment="Scrolling distance">Vertical:</string>
</property>
<property name="buddy">
<cstring>kcfg_VertScrollDelta</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="KDoubleNumInput" name="kcfg_VertScrollDelta">
<property name="toolTip">
<string>Move distance of the finger for a scroll event</string>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="suffix">
<string> mm</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string comment="Scrolling distance">Horizontal:</string>
</property>
<property name="buddy">
<cstring>kcfg_HorizScrollDelta</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="KDoubleNumInput" name="kcfg_HorizScrollDelta">
<property name="toolTip">
<string>Move distance of the finger for a scroll event</string>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="suffix">
<string> mm</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="kcfg_Coasting">
<property name="toolTip">
<string>Continue scrolling after the finger is released from the edge of the touchpad</string>
</property>
<property name="title">
<string comment="Touchpad - Scrolling">Coasting</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout_5">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string comment="Coasting">Minimum speed:</string>
</property>
<property name="buddy">
<cstring>kcfg_CoastingSpeed</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="KDoubleNumInput" name="kcfg_CoastingSpeed">
<property name="toolTip">
<string>Your finger needs to produce this many scrolls per second in order to start coasting</string>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="suffix">
<string> scrolls/sec</string>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string comment="Coasting">Deceleration:</string>
</property>
<property name="buddy">
<cstring>kcfg_CoastingFriction</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="KDoubleNumInput" name="kcfg_CoastingFriction">
<property name="toolTip">
<string>Number of scrolls/second² to decrease the coasting speed</string>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="suffix">
<string> scrolls/sec²</string>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Corner coasting:</string>
</property>
<property name="buddy">
<cstring>kcfg_CornerCoasting</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="kcfg_CornerCoasting">
<property name="toolTip">
<string>Enable edge scrolling to continue while the finger stays in an edge corner</string>
</property>
<property name="text">
<string comment="Coasting">Enable</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="kcfg_CircularScrolling">
<property name="toolTip">
<string>Scrolling is engaged when a drag starts in the given trigger region.
Moving your finger in clockwise circles around the center of the touchpad
will scroll down and counter clockwise motion will scroll up</string>
</property>
<property name="title">
<string comment="Touchpad - Scrolling">Circular Scrolling</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout_6">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string comment="Circular scrolling">Trigger region:</string>
</property>
<property name="buddy">
<cstring>kcfg_CircScrollTrigger</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="KComboBox" name="kcfg_CircScrollTrigger">
<property name="toolTip">
<string>Trigger region on the touchpad to start circular scrolling</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string comment="Circular scrolling">Angle:</string>
</property>
<property name="buddy">
<cstring>kcfg_CircScrollDelta</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="KDoubleNumInput" name="kcfg_CircScrollDelta">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Move angle (radians) of finger to generate a scroll event</string>
</property>
<property name="suffix">
<string comment="suffix - degrees (angle)">°</string>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>When used together with vertical scrolling, hitting the upper or lower right corner will seamlessly switch over from vertical to circular scrolling</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KDoubleNumInput</class>
<extends>QWidget</extends>
<header>knuminput.h</header>
</customwidget>
<customwidget>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>kcfg_VertEdgeScroll</tabstop>
<tabstop>kcfg_HorizEdgeScroll</tabstop>
<tabstop>kcfg_VertTwoFingerScroll</tabstop>
<tabstop>kcfg_HorizTwoFingerScroll</tabstop>
<tabstop>kcfg_InvertVertScroll</tabstop>
<tabstop>kcfg_InvertHorizScroll</tabstop>
<tabstop>kcfg_VertScrollDelta</tabstop>
<tabstop>kcfg_HorizScrollDelta</tabstop>
<tabstop>kcfg_Coasting</tabstop>
<tabstop>kcfg_CoastingSpeed</tabstop>
<tabstop>kcfg_CoastingFriction</tabstop>
<tabstop>kcfg_CornerCoasting</tabstop>
<tabstop>kcfg_CircularScrolling</tabstop>
<tabstop>kcfg_CircScrollTrigger</tabstop>
<tabstop>kcfg_CircScrollDelta</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -1,153 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SensitivityForm</class>
<widget class="QWidget" name="SensitivityForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>430</width>
<height>210</height>
</rect>
</property>
<property name="windowTitle">
<string>Sensitivity</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string comment="Touchpad">Sensitivity</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Pressure for detecting a touch:</string>
</property>
<property name="buddy">
<cstring>kcfg_FingerHigh</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Pressure for detecting a release:</string>
</property>
<property name="buddy">
<cstring>kcfg_FingerLow</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="kcfg_FingerHigh">
<property name="toolTip">
<string>When finger pressure goes above this value, the driver counts it as a touch</string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSlider" name="kcfg_FingerLow">
<property name="toolTip">
<string>When finger pressure drops below this value, the driver counts it as a release</string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="kcfg_PalmDetect">
<property name="toolTip">
<string>If palm detection should be enabled. Note that this also requires hardware/firmware support from the touchpad</string>
</property>
<property name="title">
<string comment="Touchpad">Palm Detection</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string comment="Palm detection">Minimum width:</string>
</property>
<property name="buddy">
<cstring>kcfg_PalmMinWidth</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string comment="Palm detection">Minimum pressure:</string>
</property>
<property name="buddy">
<cstring>kcfg_PalmMinZ</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="kcfg_PalmMinWidth">
<property name="toolTip">
<string>Minimum finger width at which touch is considered a palm</string>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSlider" name="kcfg_PalmMinZ">
<property name="toolTip">
<string>Minimum finger pressure at which touch is considered a palm</string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>kcfg_FingerHigh</tabstop>
<tabstop>kcfg_FingerLow</tabstop>
<tabstop>kcfg_PalmDetect</tabstop>
<tabstop>kcfg_PalmMinWidth</tabstop>
<tabstop>kcfg_PalmMinZ</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -1,38 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "sliderpair.h"
#include <QSlider>
SliderPair::SliderPair(QSlider *minSlider, QSlider *maxSlider, QObject *parent)
: QObject(parent), m_minSlider(minSlider), m_maxSlider(maxSlider)
{
connect(m_minSlider, SIGNAL(valueChanged(int)), SLOT(adjustMaxSlider()));
connect(m_maxSlider, SIGNAL(valueChanged(int)), SLOT(adjustMinSlider()));
}
void SliderPair::adjustMaxSlider()
{
m_maxSlider->setValue(qMax(m_maxSlider->value(), m_minSlider->value()));
}
void SliderPair::adjustMinSlider()
{
m_minSlider->setValue(qMin(m_maxSlider->value(), m_minSlider->value()));
}

View file

@ -1,40 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef SLIDERPAIR_H
#define SLIDERPAIR_H
#include <QObject>
class QSlider;
class SliderPair : public QObject
{
Q_OBJECT
public:
SliderPair(QSlider *minSlider, QSlider *maxSlider, QObject *parent = 0);
private Q_SLOTS:
void adjustMinSlider();
void adjustMaxSlider();
private:
QSlider *m_minSlider, *m_maxSlider;
};
#endif // SLIDERPAIR_H

View file

@ -1,511 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TapForm</class>
<widget class="QWidget" name="TapForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>516</width>
<height>531</height>
</rect>
</property>
<property name="windowTitle">
<string comment="Touchpad gesture">Taps</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Mouse Click Emulation</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout_3">
<property name="formAlignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string comment="Tapping">One finger:</string>
</property>
<property name="buddy">
<cstring>kcfg_OneFingerTapButton</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="KComboBox" name="kcfg_OneFingerTapButton">
<property name="toolTip">
<string>Which mouse button is reported on a non-corner one-finger tap</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string comment="Tapping">Two fingers:</string>
</property>
<property name="buddy">
<cstring>kcfg_TwoFingerTapButton</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="KComboBox" name="kcfg_TwoFingerTapButton">
<property name="toolTip">
<string>Which mouse button is reported on a non-corner two-finger tap</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string comment="Tapping">Three fingers:</string>
</property>
<property name="buddy">
<cstring>kcfg_ThreeFingerTapButton</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="KComboBox" name="kcfg_ThreeFingerTapButton">
<property name="toolTip">
<string>Which mouse button is reported on a non-corner three-finger tap</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string comment="Touchpad">Corners</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,1,0,0">
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string comment="Touchpad corner">Top left:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_LTCornerButton</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="KComboBox" name="kcfg_LTCornerButton">
<property name="toolTip">
<string>Which mouse button is reported on a left top corner tap</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string comment="Touchpad corner">Bottom left:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_LBCornerButton</cstring>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_6">
<property name="text">
<string comment="Touchpad corner">Top right:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_RTCornerButton</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="KComboBox" name="kcfg_LBCornerButton">
<property name="toolTip">
<string>Which mouse button is reported on a left bottom corner tap</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="KComboBox" name="kcfg_RTCornerButton">
<property name="toolTip">
<string>Which mouse button is reported on a right top corner tap</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="KComboBox" name="kcfg_RBCornerButton">
<property name="toolTip">
<string>Which mouse button is reported on a right bottom corner tap</string>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="3">
<widget class="QLabel" name="label_8">
<property name="text">
<string comment="Touchpad corner">Bottom right:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>kcfg_RBCornerButton</cstring>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="kcfg_TapAndDragGesture">
<property name="toolTip">
<string>This gesture is an alternative way of dragging. It is performed by tapping (touching and releasing the finger), then touching again and moving the finger on the touchpad</string>
</property>
<property name="title">
<string>Tap-and-Drag Gesture</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QGroupBox" name="kcfg_LockedDrags">
<property name="toolTip">
<string>If off, a tap-and-drag gesture ends when you release the finger. If on, the gesture is active until you tap a second time, or until timeout expires</string>
</property>
<property name="title">
<string comment="Touchpad gesture">Locked Drags</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string comment="Locked drags">Timeout:</string>
</property>
<property name="buddy">
<cstring>kcfg_LockedDragTimeout</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="KIntNumInput" name="kcfg_LockedDragTimeout">
<property name="toolTip">
<string>How long it takes (in milliseconds) for the &quot;Locked Drags&quot; mode to be automatically turned off after the finger is released from the touchpad</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>1000</number>
</property>
<property name="suffix">
<string> ms</string>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>Tap Detection</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="toolTip">
<string comment="Tap detection"/>
</property>
<property name="text">
<string>Maximum time:</string>
</property>
<property name="buddy">
<cstring>kcfg_MaxTapTime</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_11">
<property name="toolTip">
<string comment="Tap detection"/>
</property>
<property name="text">
<string>Maximum finger movement:</string>
</property>
<property name="buddy">
<cstring>kcfg_MaxTapMove</cstring>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<property name="toolTip">
<string comment="Tap detection"/>
</property>
<property name="text">
<string>Maximum time for double tap:</string>
</property>
<property name="buddy">
<cstring>kcfg_MaxDoubleTapTime</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_13">
<property name="toolTip">
<string comment="Tap detection"/>
</property>
<property name="text">
<string>Single tap timeout:</string>
</property>
<property name="buddy">
<cstring>kcfg_SingleTapTimeout</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="KIntNumInput" name="kcfg_MaxTapTime">
<property name="toolTip">
<string>Maximum time (in milliseconds) for detecting a tap</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="suffix">
<string> ms</string>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="KDoubleNumInput" name="kcfg_MaxTapMove">
<property name="toolTip">
<string>Maximum movement of the finger for detecting a tap</string>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="suffix">
<string> mm</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="KIntNumInput" name="kcfg_MaxDoubleTapTime">
<property name="toolTip">
<string>Maximum time (in milliseconds) for detecting a double tap</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="suffix">
<string> ms</string>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="KIntNumInput" name="kcfg_SingleTapTimeout">
<property name="toolTip">
<string>Timeout after a tap to recognize it as a single tap</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="suffix">
<string> ms</string>
</property>
<property name="sliderEnabled">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KDoubleNumInput</class>
<extends>QWidget</extends>
<header>knuminput.h</header>
</customwidget>
<customwidget>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
</customwidget>
<customwidget>
<class>KIntNumInput</class>
<extends>QWidget</extends>
<header>knuminput.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>kcfg_OneFingerTapButton</tabstop>
<tabstop>kcfg_TwoFingerTapButton</tabstop>
<tabstop>kcfg_ThreeFingerTapButton</tabstop>
<tabstop>kcfg_LTCornerButton</tabstop>
<tabstop>kcfg_RTCornerButton</tabstop>
<tabstop>kcfg_LBCornerButton</tabstop>
<tabstop>kcfg_RBCornerButton</tabstop>
<tabstop>kcfg_TapAndDragGesture</tabstop>
<tabstop>kcfg_LockedDrags</tabstop>
<tabstop>kcfg_LockedDragTimeout</tabstop>
<tabstop>kcfg_MaxTapTime</tabstop>
<tabstop>kcfg_MaxTapMove</tabstop>
<tabstop>kcfg_MaxDoubleTapTime</tabstop>
<tabstop>kcfg_SingleTapTimeout</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -1,56 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "testarea.h"
#include <QtGui/qevent.h>
#include <QtGui/qevent.h>
#include <QScopedPointer>
#include <QStandardItemModel>
#include <KLocale>
#include <KIcon>
#include <Plasma/Theme>
TestArea::TestArea(QWidget *parent) : QWidget(parent)
{
m_ui.setupUi(this);
QStandardItemModel *model = new QStandardItemModel(m_ui.listView);
m_ui.listView->setModel(model);
QScopedPointer<QStandardItem> item(
new QStandardItem(KIcon("folder"), i18n("Drag me")));
model->appendRow(item.data());
item.take();
QString wallpaper = Plasma::Theme::defaultTheme()->wallpaperPath();
static const QString stylesheet("background-image: url(%1)");
m_ui.scrollAreaWidgetContents->setStyleSheet(stylesheet.arg(wallpaper));
}
void TestArea::enterEvent(QEvent *e)
{
Q_EMIT enter();
QWidget::enterEvent(e);
}
void TestArea::leaveEvent(QEvent *e)
{
Q_EMIT leave();
QWidget::leaveEvent(e);
}

View file

@ -1,42 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef TESTAREA_H
#define TESTAREA_H
#include "ui_testarea.h"
class TestArea : public QWidget
{
Q_OBJECT
public:
explicit TestArea(QWidget *);
Q_SIGNALS:
void enter();
void leave();
protected:
void enterEvent(QEvent *);
void leaveEvent(QEvent *);
private:
Ui::TestArea m_ui;
};
#endif // TESTAREA_H

View file

@ -1,72 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TestArea</class>
<widget class="QWidget" name="TestArea">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>200</width>
<height>629</height>
</rect>
</property>
<property name="mouseTracking">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Testing area</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="TestButton" name="pushButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Click me</string>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="minimumSize">
<size>
<width>2000</width>
<height>2000</height>
</size>
</property>
</widget>
</widget>
</item>
<item>
<widget class="QListView" name="listView">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>TestButton</class>
<extends>QPushButton</extends>
<header>kcm/testbutton.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View file

@ -1,60 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "testbutton.h"
#include <QtGui/qevent.h>
#include <QTimer>
#include <KLocalizedString>
TestButton::TestButton(QWidget *parent)
: QPushButton(parent), m_firstClick(true)
{
}
void TestButton::mousePressEvent(QMouseEvent *e)
{
if (m_firstClick) {
m_originalText = text();
m_firstClick = false;
}
switch (e->button()) {
case Qt::LeftButton:
setText(i18nc("Mouse button", "Left button"));
break;
case Qt::RightButton:
setText(i18nc("Mouse button", "Right button"));
break;
case Qt::MiddleButton:
setText(i18nc("Mouse button", "Middle button"));
break;
default:
break;
}
QTimer::singleShot(500, this, SLOT(resetText()));
QPushButton::mousePressEvent(e);
}
void TestButton::resetText()
{
setText(m_originalText);
}

View file

@ -1,42 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef TESTBUTTON_H
#define TESTBUTTON_H
#include <QPushButton>
class TestButton : public QPushButton
{
Q_OBJECT
public:
explicit TestButton(QWidget *);
protected:
void mousePressEvent(QMouseEvent *);
private Q_SLOTS:
void resetText();
private:
QString m_originalText;
bool m_firstClick;
};
#endif // TESTBUTTON_H

View file

@ -1,312 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
<kcfgfile name="touchpadrc"/>
<group name="parameters">
<entry name="$(TapAction)Button" type="Enum">
<parameter name="TapAction" type="Enum">
<values>
<value>OneFingerTap</value>
<value>TwoFingerTap</value>
<value>ThreeFingerTap</value>
<value>LTCorner</value>
<value>LBCorner</value>
<value>RTCorner</value>
<value>RBCorner</value>
</values>
</parameter>
<choices name="Button">
<choice name="NoButton">
<label context="Emulated mouse button">No action</label>
</choice>
<choice name="LeftButton">
<label context="Emulated mouse button">Left button</label>
</choice>
<choice name="MiddleButton">
<label context="Emulated mouse button">Middle button</label>
</choice>
<choice name="RightButton">
<label context="Emulated mouse button">Right button</label>
</choice>
</choices>
<default param="OneFingerTap" code="true">
systemDefaultEnum("OneFingerTapButton", LeftButton)
</default>
<default param="TwoFingerTap" code="true">
systemDefaultEnum("TwoFingerTapButton", RightButton)
</default>
<default param="ThreeFingerTap" code="true">
systemDefaultEnum("ThreeFingerTapButton", MiddleButton)
</default>
<default param="LTCorner" code="true">
systemDefaultEnum("LTCornerButton", NoButton)
</default>
<default param="LBCorner" code="true">
systemDefaultEnum("LBCornerButton", NoButton)
</default>
<default param="RTCorner" code="true">
systemDefaultEnum("RTCornerButton", NoButton)
</default>
<default param="RBCorner" code="true">
systemDefaultEnum("RBCornerButton", NoButton)
</default>
</entry>
<entry name="VertEdgeScroll" type="Bool">
<default code="true">
systemDefault("VertEdgeScroll", true)
</default>
</entry>
<entry name="VertTwoFingerScroll" type="Bool">
<default code="true">
systemDefault("VertTwoFingerScroll", true)
</default>
</entry>
<entry name="HorizEdgeScroll" type="Bool">
<default code="true">
systemDefault("HorizEdgeScroll", true)
</default>
</entry>
<entry name="HorizTwoFingerScroll" type="Bool">
<default code="true">
systemDefault("HorizTwoFingerScroll", true)
</default>
</entry>
<entry name="MinSpeed" type="Double">
<min>0</min>
<max>255</max>
<default code="true">
systemDefault("MinSpeed", 0.0)
</default>
</entry>
<entry name="MaxSpeed" type="Double">
<min>0</min>
<max>255</max>
<default code="true">
systemDefault("MaxSpeed", 255.0)
</default>
</entry>
<entry name="AccelFactor" type="Double">
<min>0</min>
<max>1</max>
<default code="true">
systemDefault("AccelFactor", 0.0)
</default>
</entry>
<entry name="HorizHysteresis" type="Int">
<min>0</min>
<max>100</max>
<default code="true">
systemDefault("HorizHysteresis", 0)
</default>
</entry>
<entry name="VertHysteresis" type="Int">
<min>0</min>
<max>100</max>
<default code="true">
systemDefault("VertHysteresis", 0)
</default>
</entry>
<entry name="TapAndDragGesture" type="Bool">
<default code="true">
systemDefault("TapAndDragGesture", true)
</default>
</entry>
<entry name="LockedDrags" type="Bool">
<default code="true">
systemDefault("LockedDrags", false)
</default>
</entry>
<entry name="LockedDragTimeout" type="Int">
<min>0</min>
<max>30000</max>
<default code="true">
systemDefault("LockedDragTimeout", 5000)
</default>
</entry>
<entry name="VertScrollDelta" type="Double">
<min>0</min>
<max>10</max>
<default code="true">
systemDefault("VertScrollDelta", 1.0)
</default>
</entry>
<entry name="InvertVertScroll" type="Bool">
<default code="true">
systemDefault("InvertVertScroll", false)
</default>
</entry>
<entry name="HorizScrollDelta" type="Double">
<min>0</min>
<max>10</max>
<default code="true">
systemDefault("HorizScrollDelta", 1.0)
</default>
</entry>
<entry name="InvertHorizScroll" type="Bool">
<default code="true">
systemDefault("InvertHorizScroll", false)
</default>
</entry>
<entry name="CornerCoasting" type="Bool">
<default code="true">
systemDefault("CornerCoasting", false)
</default>
</entry>
<entry name="CoastingSpeed" type="Double">
<min>0.1</min>
<max>255</max>
<default code="true">
systemDefault("CoastingSpeed", 20.0)
</default>
</entry>
<entry name="CoastingFriction" type="Double">
<min>0</min>
<max>255</max>
<default code="true">
systemDefault("CoastingFriction", 50.0)
</default>
</entry>
<entry name="Coasting" type="Bool">
<default code="true">
systemDefault("Coasting", true)
</default>
</entry>
<entry name="FingerHigh" type="Int">
<min>0</min>
<max>255</max>
<default code="true">
systemDefault("FingerHigh", 30)
</default>
</entry>
<entry name="FingerLow" type="Int">
<min>0</min>
<max>255</max>
<default code="true">
systemDefault("FingerLow", 25)
</default>
</entry>
<entry name="PalmDetect" type="Bool">
<default code="true">
systemDefault("PalmDetect", false)
</default>
</entry>
<entry name="PalmMinZ" type="Int">
<min>0</min>
<max>255</max>
<default code="true">
systemDefault("PalmMinZ", 200)
</default>
</entry>
<entry name="PalmMinWidth" type="Int">
<min>0</min>
<max>15</max>
<default code="true">
systemDefault("PalmMinWidth", 10)
</default>
</entry>
<entry name="MaxTapTime" type="Int">
<min>0</min>
<max>1000</max>
<default code="true">
systemDefault("MaxTapTime", 180)
</default>
</entry>
<entry name="MaxDoubleTapTime" type="Int">
<min>0</min>
<max>1000</max>
<default code="true">
systemDefault("MaxDoubleTapTime", 180)
</default>
</entry>
<entry name="SingleTapTimeout" type="Int">
<min>0</min>
<max>1000</max>
<default code="true">
systemDefault("SingleTapTimeout", 180)
</default>
</entry>
<entry name="MaxTapMove" type="Double">
<min>0</min>
<max>20</max>
<default code="true">
systemDefault("MaxTapMove", 2.0)
</default>
</entry>
<entry name="PressureMotionMinZ" type="Int">
<min>1</min>
<max>255</max>
<default code="true">
systemDefault("PressureMotionMinZ", 30)
</default>
</entry>
<entry name="PressureMotionMaxZ" type="Int">
<min>1</min>
<max>255</max>
<default code="true">
systemDefault("PressureMotionMaxZ", 160)
</default>
</entry>
<entry name="PressureMotionMinFactor" type="Double">
<min>0</min>
<max>10</max>
<default code="true">
systemDefault("PressureMotionMinFactor", 1.0)
</default>
</entry>
<entry name="PressureMotionMaxFactor" type="Double">
<min>0</min>
<max>10</max>
<default code="true">
systemDefault("PressureMotionMaxFactor", 1.0)
</default>
</entry>
<entry name="CircularScrolling" type="Bool">
<default code="true">
systemDefault("CircularScrolling", false)
</default>
</entry>
<entry name="CircScrollDelta" type="Double">
<default code="true">
systemDefault("CircScrollDelta", 10.0)
</default>
<min>0</min>
<max>45</max>
</entry>
<entry name="CircScrollTrigger" type="Enum">
<choices name="Edge">
<choice name="AllEdges">
<label context="Touchpad Edge">All edges</label>
</choice>
<choice name="TopEdge">
<label context="Touchpad Edge">Top edge</label>
</choice>
<choice name="TopRightCorner">
<label context="Touchpad Edge">Top right corner</label>
</choice>
<choice name="RightEdge">
<label context="Touchpad Edge">Right edge</label>
</choice>
<choice name="BottomRightCorner">
<label context="Touchpad Edge">Bottom right corner</label>
</choice>
<choice name="BottomEdge">
<label context="Touchpad Edge">Bottom edge</label>
</choice>
<choice name="BottomLeftCorner">
<label context="Touchpad Edge">Bottom left corner</label>
</choice>
<choice name="LeftEdge">
<label context="Touchpad Edge">Left edge</label>
</choice>
<choice name="TopLeftCorner">
<label context="Touchpad Edge">Top left corner</label>
</choice>
</choices>
<default code="true">
systemDefaultEnum("CircScrollTrigger", AllEdges)
</default>
</entry>
</group>
</kcfg>

View file

@ -1,373 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "touchpadconfig.h"
#include <QScrollArea>
#include <QDBusInterface>
#include <KAboutData>
#include <KAction>
#include <KLocalizedString>
#include <KMessageWidget>
#include <KNotifyConfigWidget>
#include <KShortcutsDialog>
#include <KTabWidget>
#include "customslider.h"
#include "sliderpair.h"
#include "touchpadbackend.h"
#include "plugins.h"
#include "testarea.h"
#include "touchpadinterface.h"
#include "customconfigdialogmanager.h"
#include "kded/kdedactions.h"
void touchpadApplySavedConfig()
{
TouchpadBackend *backend = TouchpadBackend::implementation();
if (!backend) {
return;
}
TouchpadParameters config;
backend->applyConfig(config.values());
}
extern "C"
{
KDE_EXPORT void kcminit_touchpad()
{
TouchpadParameters::setSystemDefaults();
touchpadApplySavedConfig();
}
}
static void copyHelpFromBuddy(QObject *root)
{
QLabel *asLabel = qobject_cast<QLabel*>(root);
if (asLabel && asLabel->buddy()) {
if (asLabel->toolTip().isEmpty()) {
asLabel->setToolTip(asLabel->buddy()->toolTip());
}
if (asLabel->statusTip().isEmpty()) {
asLabel->setStatusTip(asLabel->buddy()->statusTip());
}
if (asLabel->whatsThis().isEmpty()) {
asLabel->setWhatsThis(asLabel->buddy()->whatsThis());
}
}
Q_FOREACH(QObject *child, root->children()) {
copyHelpFromBuddy(child);
}
}
template<typename T>
QWidget *addTab(KTabWidget *tabs, T &form)
{
QScrollArea *container = new QScrollArea(tabs);
container->setWidgetResizable(true);
container->setFrameStyle(QFrame::NoFrame);
container->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
QWidget *widget = new QWidget(container);
form.setupUi(widget);
copyHelpFromBuddy(widget);
widget->setContentsMargins(20, 20, 20, 20);
widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
container->setWidget(widget);
tabs->addTab(container, widget->windowTitle());
return widget;
}
TouchpadConfig::TouchpadConfig(QWidget *parent, const QVariantList &args)
: KCModule(TouchpadPluginFactory::componentData(), parent, args),
m_configOutOfSync(false)
{
setAboutData(new KAboutData(*componentData().aboutData()));
QGridLayout *layout = new QGridLayout(this);
QVBoxLayout *messageLayout = new QVBoxLayout();
layout->addLayout(messageLayout, 0, 0, 1, 2);
// Messages
m_errorMessage = new KMessageWidget(this);
m_errorMessage->setMessageType(KMessageWidget::Error);
m_errorMessage->setVisible(false);
messageLayout->addWidget(m_errorMessage);
m_configOutOfSyncMessage = new KMessageWidget(this);
m_configOutOfSyncMessage->setMessageType(KMessageWidget::Warning);
m_configOutOfSyncMessage->setText(
i18n("Active settings don't match saved settings.\n"
"You currently see saved settings."));
m_configOutOfSyncMessage->setVisible(false);
messageLayout->addWidget(m_configOutOfSyncMessage);
m_loadActiveConfiguration = new KAction(m_configOutOfSyncMessage);
m_loadActiveConfiguration->setText(i18n("Show active settings"));
connect(m_loadActiveConfiguration, SIGNAL(triggered()),
SLOT(loadActiveConfig()));
m_configOutOfSyncMessage->addAction(m_loadActiveConfiguration);
layout->setColumnStretch(0, 3);
layout->setColumnStretch(1, 1);
// Main UI
m_tabs = new KTabWidget(this);
layout->addWidget(m_tabs, 1, 0, 1, 1);
addTab(m_tabs, m_tapping);
addTab(m_tabs, m_scrolling);
addTab(m_tabs, m_pointerMotion);
addTab(m_tabs, m_sensitivity);
static const CustomSlider::SqrtInterpolator interpolator;
m_pointerMotion.kcfg_MinSpeed->setInterpolator(&interpolator);
m_pointerMotion.kcfg_MaxSpeed->setInterpolator(&interpolator);
m_pointerMotion.kcfg_AccelFactor->setInterpolator(&interpolator);
new SliderPair(m_pointerMotion.kcfg_MinSpeed,
m_pointerMotion.kcfg_MaxSpeed, this);
new SliderPair(m_sensitivity.kcfg_FingerLow,
m_sensitivity.kcfg_FingerHigh, this);
new SliderPair(m_pointerMotion.kcfg_PressureMotionMinZ,
m_pointerMotion.kcfg_PressureMotionMaxZ, this);
m_backend = TouchpadBackend::implementation();
KConfigDialogManager::changedMap()->insert("CustomSlider",
SIGNAL(valueChanged(double)));
m_manager = new CustomConfigDialogManager(this, &m_config,
m_backend->supportedParameters());
connect(m_manager, SIGNAL(widgetModified()), SLOT(checkChanges()),
Qt::QueuedConnection);
// KDED settings
m_kdedTab = addTab(m_tabs, m_kded);
m_daemonConfigManager = addConfig(&m_daemonSettings, m_kdedTab);
KMessageWidget *kdedMessage = new KMessageWidget(m_kdedTab);
kdedMessage->setMessageType(KMessageWidget::Information);
kdedMessage->setCloseButtonVisible(false);
kdedMessage->setText(
i18n("These settings won't take effect in the testing area"));
qobject_cast<QVBoxLayout *>(m_kdedTab->layout())->
insertWidget(0, kdedMessage);
connect(m_kded.configureNotificationsButton, SIGNAL(clicked()),
SLOT(showConfigureNotificationsDialog()));
m_shortcutsDialog.reset(new KShortcutsDialog(KShortcutsEditor::GlobalAction,
KShortcutsEditor::LetterShortcutsDisallowed));
m_shortcutsDialog->addCollection(new TouchpadGlobalActions(this),
i18n("Enable/Disable Touchpad"));
connect(m_kded.configureShortcutsButton, SIGNAL(clicked()),
m_shortcutsDialog.data(), SLOT(show()));
m_mouseCombo = new KComboBox(true, m_kded.kcfg_MouseBlacklist);
m_kded.kcfg_MouseBlacklist->setCustomEditor(m_mouseCombo);
connect(m_backend, SIGNAL(mousesChanged()), SLOT(updateMouseList()));
m_backend->watchForEvents(false);
updateMouseList();
m_daemon = new OrgKdeTouchpadInterface("org.kde.kded", "/modules/touchpad",
QDBusConnection::sessionBus(), this);
m_kdedTab->setEnabled(false);
QDBusPendingCallWatcher *watch;
watch = new QDBusPendingCallWatcher(m_daemon->workingTouchpadFound(), this);
connect(watch, SIGNAL(finished(QDBusPendingCallWatcher*)),
SLOT(gotReplyFromDaemon(QDBusPendingCallWatcher*)));
// Testing area
m_testArea = new TestArea(this);
layout->addWidget(m_testArea, 1, 1);
connect(m_testArea, SIGNAL(enter()), SLOT(beginTesting()));
connect(m_testArea, SIGNAL(leave()), SLOT(endTesting()));
connect(this, SIGNAL(changed(bool)), SLOT(onChanged()));
connect(m_tabs, SIGNAL(currentChanged(int)), SLOT(updateTestAreaEnabled()));
updateTestAreaEnabled();
}
void TouchpadConfig::gotReplyFromDaemon(QDBusPendingCallWatcher *watch)
{
QDBusPendingReply<bool> reply = *watch;
if (reply.isValid() && reply.value()) {
m_kdedTab->setEnabled(true);
}
watch->deleteLater();
}
void TouchpadConfig::updateMouseList()
{
QStringList mouses(
m_backend->listMouses(m_daemonSettings.mouseBlacklist()));
for (int i = 0; i < m_mouseCombo->count(); ) {
if (!mouses.contains(m_mouseCombo->itemText(i))) {
m_mouseCombo->removeItem(i);
} else {
i++;
}
}
Q_FOREACH (const QString &i, mouses) {
if (!m_mouseCombo->contains(i)) {
m_mouseCombo->addItem(i);
}
}
}
QVariantHash TouchpadConfig::getActiveConfig()
{
if (m_prevConfig) {
return *m_prevConfig;
}
QVariantHash activeConfig;
if (!m_backend->getConfig(activeConfig)) {
m_errorMessage->setText(m_backend->errorString());
QMetaObject::invokeMethod(m_errorMessage, "animatedShow",
Qt::QueuedConnection);
}
return activeConfig;
}
void TouchpadConfig::loadActiveConfig()
{
m_manager->setWidgetProperties(getActiveConfig());
m_configOutOfSync = false;
m_configOutOfSyncMessage->animatedHide();
}
void TouchpadConfig::load()
{
m_manager->updateWidgets();
KCModule::load();
m_configOutOfSync = !m_manager->compareWidgetProperties(getActiveConfig());
}
void TouchpadConfig::save()
{
m_manager->updateSettings();
m_configOutOfSync = false;
m_configOutOfSyncMessage->animatedHide();
bool daemonSettingsChanged = m_daemonConfigManager->hasChanged();
KCModule::save();
if (m_backend->applyConfig(m_config.values())) {
m_errorMessage->animatedHide();
} else {
m_errorMessage->setText(m_backend->errorString());
m_errorMessage->animatedShow();
}
if (daemonSettingsChanged) {
m_daemon->reloadSettings();
updateMouseList();
}
}
void TouchpadConfig::defaults()
{
m_manager->updateWidgetsDefault();
KCModule::defaults();
}
void TouchpadConfig::checkChanges()
{
unmanagedWidgetChangeState(m_manager->hasChangedFuzzy()
|| m_configOutOfSync);
if (m_configOutOfSync) {
m_configOutOfSyncMessage->animatedShow();
} else {
m_configOutOfSyncMessage->animatedHide();
}
}
void TouchpadConfig::hideEvent(QHideEvent *e)
{
endTesting();
KCModule::hideEvent(e);
}
TouchpadConfig::~TouchpadConfig()
{
endTesting();
}
void TouchpadConfig::onChanged()
{
if (m_testArea->underMouse()) {
beginTesting();
}
}
void TouchpadConfig::beginTesting()
{
if (!m_prevConfig) {
m_prevConfig.reset(new QVariantHash());
m_backend->getConfig(*m_prevConfig.data());
}
m_backend->applyConfig(m_manager->currentWidgetProperties());
}
void TouchpadConfig::endTesting()
{
if (!m_prevConfig) {
return;
}
m_backend->applyConfig(*m_prevConfig.data());
m_prevConfig.reset();
}
void TouchpadConfig::updateTestAreaEnabled()
{
bool enable = true;
for (QWidget *i = m_kdedTab; i; i = i->parentWidget()) {
if (i == m_tabs->currentWidget()) {
enable = false;
break;
}
}
m_testArea->setEnabled(enable);
m_testArea->setMouseTracking(enable);
if (!enable) {
endTesting();
}
}
void TouchpadConfig::showConfigureNotificationsDialog()
{
KNotifyConfigWidget *widget =
KNotifyConfigWidget::configure(0, componentData().componentName());
KDialog *dialog = qobject_cast<KDialog*>(widget->topLevelWidget());
connect(dialog, SIGNAL(finished()), dialog, SLOT(deleteLater()));
}

View file

@ -1,100 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef TOUCHPADCONFIG_H
#define TOUCHPADCONFIG_H
#include <KCModule>
#include <KConfigDialogManager>
#include <QScopedPointer>
#include "touchpadparameters.h"
#include "testarea.h"
#include "kdedsettings.h"
#include "ui_pointermotion.h"
#include "ui_tap.h"
#include "ui_scroll.h"
#include "ui_sensitivity.h"
#include "ui_kded.h"
class TouchpadBackend;
class KMessageWidget;
class OrgKdeTouchpadInterface;
class CustomConfigDialogManager;
class KAction;
class KShortcutsDialog;
class KTabWidget;
class KComboBox;
class QDBusPendingCallWatcher;
class TouchpadConfig : public KCModule
{
Q_OBJECT
public:
explicit TouchpadConfig(QWidget *parent,
const QVariantList &args = QVariantList());
virtual ~TouchpadConfig();
virtual void load();
virtual void save();
virtual void defaults();
protected:
virtual void hideEvent(QHideEvent *);
private Q_SLOTS:
void beginTesting();
void endTesting();
void onChanged();
void checkChanges();
void loadActiveConfig();
void updateTestAreaEnabled();
void updateMouseList();
void showConfigureNotificationsDialog();
void gotReplyFromDaemon(QDBusPendingCallWatcher *);
private:
QVariantHash getActiveConfig();
TouchpadBackend *m_backend;
TouchpadParameters m_config;
QScopedPointer<QVariantHash> m_prevConfig;
CustomConfigDialogManager *m_manager;
TouchpadDisablerSettings m_daemonSettings;
KConfigDialogManager *m_daemonConfigManager;
KMessageWidget *m_errorMessage, *m_configOutOfSyncMessage;
TestArea *m_testArea;
OrgKdeTouchpadInterface *m_daemon;
KAction *m_loadActiveConfiguration;
bool m_configOutOfSync;
QScopedPointer<KShortcutsDialog> m_shortcutsDialog;
QWidget *m_kdedTab;
KTabWidget *m_tabs;
KComboBox *m_mouseCombo;
Ui::PointerMotionForm m_pointerMotion;
Ui::TapForm m_tapping;
Ui::ScrollForm m_scrolling;
Ui::SensitivityForm m_sensitivity;
Ui::KdedForm m_kded;
};
#endif // TOUCHPADCONFIG_H

View file

@ -1,9 +0,0 @@
File=touchpad.kcfg
ClassName=TouchpadParameters
Mutators=true
MemberVariables=private
GlobalEnums=true
UseEnumTypes=true
Inherits=TouchpadParametersBase
IncludeFiles=\"kcm/touchpadparametersbase.h\"
SetUserTexts=true

View file

@ -1,83 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "touchpadparametersbase.h"
#include "touchpadbackend.h"
namespace
{
KConfigGroup &systemDefaults()
{
static KSharedConfig::Ptr p(KSharedConfig::openConfig(".touchpaddefaults",
KConfig::SimpleConfig,
"tmp"));
static KConfigGroup group(p->group("parameters"));
return group;
}
}
TouchpadParametersBase::TouchpadParametersBase(const QString &configname,
QObject *parent)
: KCoreConfigSkeleton(configname, parent)
{
if (!systemDefaults().exists()) {
setSystemDefaults();
}
}
QVariantHash TouchpadParametersBase::values() const
{
QVariantHash r;
Q_FOREACH(const KConfigSkeletonItem *i, items()) {
r[i->name()] = i->property();
}
return r;
}
void TouchpadParametersBase::setValues(const QVariantHash &v)
{
for (QVariantHash::ConstIterator i = v.begin(); i != v.end(); ++i) {
KConfigSkeletonItem *j = findItem(i.key());
if (j) {
j->setProperty(i.value());
}
}
}
void TouchpadParametersBase::setSystemDefaults()
{
TouchpadBackend *backend = TouchpadBackend::implementation();
if (!backend) {
return;
}
QVariantHash v;
backend->getConfig(v);
for (QVariantHash::ConstIterator i = v.begin(); i != v.end(); ++i) {
systemDefaults().writeEntry(i.key(), i.value());
}
systemDefaults().sync();
}
QVariant TouchpadParametersBase::systemDefault(const QString &name,
const QVariant &hardcoded)
{
return systemDefaults().readEntry(name, hardcoded);
}

View file

@ -1,51 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef TOUCHPADPARAMETERSBASE_H
#define TOUCHPADPARAMETERSBASE_H
#include <QtCore/qvariant.h>
#include <KConfigSkeleton>
class TouchpadParametersBase : public KCoreConfigSkeleton
{
public:
explicit TouchpadParametersBase(const QString &configname = QString(),
QObject *parent = 0);
QVariantHash values() const;
void setValues(const QVariantHash &);
static void setSystemDefaults();
static QVariant systemDefault(const QString &name,
const QVariant &hardcoded = QVariant());
template<typename T>
static T systemDefault(const QString &name, const T &hardcoded = T())
{
return qvariant_cast<T>(systemDefault(name, QVariant(hardcoded)));
}
template<typename T>
static T systemDefaultEnum(const QString &name, const T &hardcoded = T())
{
return static_cast<T>(systemDefault(name, static_cast<int>(hardcoded)));
}
};
#endif // TOUCHPADPARAMETERSBASE_H

View file

@ -1,148 +0,0 @@
[Global]
Name=Touchpad
Name[bs]=Dodirna površina
Name[cs]=Touchpad
Name[da]=Touchpad
Name[de]=Touchpad
Name[el]=Επιφάνεια αφής
Name[es]=Panel táctil
Name[fi]=Kosketuslevy
Name[fr]=Pavé tactile
Name[hu]=Érintőtábla
Name[ko]=터치패드
Name[lt]=Jutiklinis kilimėlis
Name[nl]=Touchpad
Name[pl]=Gładzik
Name[pt]=Rato por Toque
Name[pt_BR]=Touchpad
Name[ro]=Zonă tactilă
Name[sk]=Touchpad
Name[sl]=Sledilna ploščica
Name[sv]=Tryckplatta
Name[tr]=Dokunmatik Yüzey
Name[uk]=Сенсорна панель
Name[x-test]=xxTouchpadxx
IconName=input-touchpad
Comment=Touchpad
Comment[bs]=Dodirna površina
Comment[cs]=Touchpad
Comment[da]=Touchpad
Comment[de]=Touchpad
Comment[el]=Επιφάνεια αφής
Comment[es]=Panel táctil
Comment[fi]=Kosketuslevy
Comment[fr]=Pavé tactile
Comment[hu]=Érintőtábla
Comment[ko]=터치패드
Comment[lt]=Jutiklinis kilimėlis
Comment[nl]=Touchpad
Comment[pl]=Gładzik
Comment[pt]=Rato por Toque
Comment[pt_BR]=Touchpad
Comment[ro]=Zonă tactilă
Comment[sk]=Touchpad
Comment[sl]=Sledilna ploščica
Comment[sv]=Tryckplatta
Comment[tr]=Dokunmatik Yüzey
Comment[uk]=Сенсорна панель
Comment[x-test]=xxTouchpadxx
[Event/TouchpadDisabled]
Name=Touchpad was disabled
Name[bs]=Dodirna površina je isključena
Name[cs]=Touchpad byl zakázán
Name[da]=Touchpad blev deaktiveret
Name[de]=Das Touchpad wurde deaktiviert
Name[el]=Η επιφάνεια αφής απενεργοποιήθηκε
Name[es]=El panel táctil se ha desactivado
Name[fi]=Kosketuslevy poistettiin käytöstä
Name[fr]=Le pavé tactile a été désactivé
Name[hu]=Az érintőtábla le lett tiltva
Name[ko]=터치패드 비활성화됨
Name[lt]=Jutiklinis kilimėlis išjungtas
Name[nl]=Touchpad was uitgeschakeld
Name[pl]=Gładzik został wyłączony
Name[pt]=O rato por toque foi desactivado
Name[pt_BR]=O touchpad foi desativado
Name[ro]=Zona tactilă a fost dezactivată
Name[sk]=Touchpad bol zakázaný
Name[sl]=Sledilna ploščica je bila onemogočena
Name[sv]=Tryckplattan stängdes av
Name[tr]=Dokunmatik yüzey devre dışı bırakıldı
Name[uk]=Сенсорну панель вимкнено
Name[x-test]=xxTouchpad was disabledxx
Comment=Touchpad was disabled because mouse is detected
Comment[bs]=Dodirna površina je isključena jer je miš prepoznat
Comment[cs]=Touchpad byl zakázán protože byla zjištěna myš
Comment[da]=Touchpad blev deaktiveret fordi musen blev detekteret
Comment[de]=Das Touchpad wurde deaktiviert, weil eine Maus erkannt wurde
Comment[el]=Η επιφάνειας αφής απενεργοποιήθηκε επειδή το ποντίκι ανιχνεύτηκε
Comment[es]=El panel táctil se ha desactivado porque se ha detectado un ratón
Comment[fi]=Kosketuslevy poistettiin käytöstä, koska havaittiin hiiri
Comment[fr]=Le pavé tactile a été désactivé car une souris a été détectée
Comment[hu]=Az érintőtábla le lett tiltva, mert érzékelhető egy egér
Comment[ko]=마우스가 감지되어 터치패드 비활성화됨
Comment[lt]=Jutiklinis kilimėlis išjungtas, nes aptikta pelė
Comment[nl]=Touchpad was uitgeschakeld omdat er een muis is gedetecteerd
Comment[pl]=Gładzik został wyłączony, bo podłączono mysz
Comment[pt]=O rato por toque foi desactivado porque foi detectado um rato
Comment[pt_BR]=O touchpad foi desativado porque o mouse foi detectado
Comment[ro]=Zona tactilă a fost dezactivată deoarece s-a detectat un maus
Comment[sk]=Touchpad bol zakázaný, lebo bola zistená myš
Comment[sl]=Sledilna ploščica je bila onemogočena, ker je bila zaznana miška
Comment[sv]=Tryckplattan stängdes av eftersom en mus detekterades
Comment[tr]=Dokunmatik yüzey fare tespit edildiğinden devre dışı bırakıldı
Comment[uk]=Сенсорну панель вимкнено, оскільки виявлено мишу
Comment[x-test]=xxTouchpad was disabled because mouse is detectedxx
Sound=KDE-Sys-App-Positive.ogg
Action=Popup
[Event/TouchpadEnabled]
Name=Touchpad was enabled
Name[bs]=Dodirna površina je uključena
Name[cs]=Touchpad byl povolen
Name[da]=Touchpad blev aktiveret
Name[de]=Das Touchpad wurde aktiviert
Name[el]=Η επιφάνεια αφής ενεργοποιήθηκε
Name[es]=El panel táctil se ha activado
Name[fi]=Kosketuslevy otettiin käyttöön
Name[fr]=Le pavé tactile a été activé
Name[hu]=Az érintőtábla engedélyezve lett
Name[ko]=터치패드 활성화됨
Name[lt]=Jutiklinis kilimėlis įjungtas
Name[nl]=Touchpad was ingeschakeld
Name[pl]=Gładzik został włączony
Name[pt]=O rato por toque foi activado
Name[pt_BR]=O touchpad foi ativado
Name[ro]=Zona tactilă a fost activată
Name[sk]=Touchpad bol povolený
Name[sl]=Sledilna ploščica je bila omogočena
Name[sv]=Tryckplattan aktiverades
Name[tr]=Dokunmatik yüzey etkinleştirildi
Name[uk]=Сенсорну панель увімкнено
Name[x-test]=xxTouchpad was enabledxx
Comment=Touchpad was enabled because the mouse was unplugged
Comment[bs]=Dodirna površina je uključena jer je miš isključen
Comment[cs]=Touchpad byl povolen protože byla odpojena myš
Comment[da]=Touchpad blev aktiveret fordi musen blev frakoblet
Comment[de]=Das Touchpad wurde aktiviert, weil eine Maus abgezogen wurde
Comment[el]=Η επιφάνειας αφής ενεργοποιήθηκε επειδή το ποντίκι αποσυνδέθηκε
Comment[es]=El panel táctil se ha activado porque se ha desconectado el ratón
Comment[fi]=Kosketuslevy otettiin käyttöön, koska hiiri irrotettiin
Comment[fr]=Le pavé tactile a été activé car la souris a été débranchée
Comment[hu]=Az érintőtábla engedélyezve lett, mert az egér ki lett húzva
Comment[ko]=마우스가 연결 해제되어 터치패드 활성화됨
Comment[lt]=Jutiklinis kilimėlis įjungtas, nes buvo atjungta pelė
Comment[nl]=Touchpad was ingeschakeld omdat er een muis is uitgetrokken
Comment[pl]=Gładzik został włączony, bo odłączono mysz
Comment[pt]=O rato por toque foi activado porque o rato foi desligado
Comment[pt_BR]=O touchpad foi ativado porque o mouse foi desconectado
Comment[ro]=Zona tactilă a fost activată deoarece mausul a fost deconectat
Comment[sk]=Touchpad bol povolený, pretože myš bola odpojená
Comment[sl]=Sledilna ploščica je bila omogočena, ker je bila miška odklopljena
Comment[sv]=Tryckplattan aktiverades eftersom en mus kopplades bort
Comment[tr]=Dokunmatik yüzey fare çıkarıldığından etkinleştirildi
Comment[uk]=Сенсорну панель увімкнено, оскільки мишу було від’єднано
Comment[x-test]=xxTouchpad was enabled because the mouse was unpluggedxx
Sound=KDE-Sys-App-Negative.ogg
Action=Sound

View file

@ -1,217 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kded.h"
#include <KNotification>
#include <KLocale>
#include "plugins.h"
#include "kdedactions.h"
bool TouchpadDisabler::workingTouchpadFound() const
{
return m_backend && !(m_backend->supportedParameters().isEmpty());
}
void TouchpadDisabler::serviceRegistered(const QString &service)
{
if (!m_dependecies.removeWatchedService(service)) {
return;
}
if (m_dependecies.watchedServices().isEmpty()) {
lateInit();
}
}
TouchpadDisabler::TouchpadDisabler(QObject *parent, const QVariantList &)
: KDEDModule(parent), m_backend(TouchpadBackend::implementation()),
m_enabled(true), m_keyboardActivity(false), m_mouse(false)
{
if (!workingTouchpadFound()) {
return;
}
m_dependecies.addWatchedService("org.kde.plasma-desktop");
m_dependecies.addWatchedService("org.kde.kglobalaccel");
connect(&m_dependecies, SIGNAL(serviceRegistered(QString)),
SLOT(serviceRegistered(QString)));
connect(m_backend, SIGNAL(mousesChanged()), SLOT(mousePlugged()));
connect(m_backend, SIGNAL(keyboardActivityStarted()),
SLOT(keyboardActivityStarted()));
connect(m_backend, SIGNAL(keyboardActivityFinished()),
SLOT(keyboardActivityFinished()));
connect(m_backend, SIGNAL(touchpadStateChanged()),
SLOT(updateCurrentState()));
connect(m_backend, SIGNAL(touchpadReset()), SLOT(handleReset()));
m_keyboardActivityTimeout.setSingleShot(true);
connect(&m_keyboardActivityTimeout, SIGNAL(timeout()),
SLOT(timerElapsed()));
updateCurrentState();
reloadSettings();
m_dependecies.setWatchMode(QDBusServiceWatcher::WatchForRegistration);
m_dependecies.setConnection(QDBusConnection::sessionBus());
Q_FOREACH (const QString &service, m_dependecies.watchedServices()) {
QDBusReply<bool> registered = QDBusConnection::sessionBus().interface()
->isServiceRegistered(service);
if (!registered.isValid() || registered.value()) {
serviceRegistered(service);
}
}
}
bool TouchpadDisabler::isEnabled() const
{
return m_enabled;
}
void TouchpadDisabler::updateCurrentState()
{
bool newEnabled = m_backend->isTouchpadEnabled();
if (newEnabled != m_enabled) {
m_enabled = newEnabled;
Q_EMIT enabledChanged(m_enabled);
}
}
void TouchpadDisabler::toggle()
{
m_backend->setTouchpadEnabled(!isEnabled());
}
void TouchpadDisabler::disable()
{
m_backend->setTouchpadEnabled(false);
}
void TouchpadDisabler::enable()
{
m_backend->setTouchpadEnabled(true);
}
void TouchpadDisabler::reloadSettings()
{
m_settings.readConfig();
m_keyboardActivityTimeout.setInterval(
m_settings.keyboardActivityTimeoutMs());
m_keyboardDisableState =
m_settings.onlyDisableTapAndScrollOnKeyboardActivity() ?
TouchpadBackend::TouchpadTapAndScrollDisabled :
TouchpadBackend::TouchpadFullyDisabled;
mousePlugged();
m_backend->watchForEvents(m_settings.disableOnKeyboardActivity());
}
void TouchpadDisabler::keyboardActivityStarted()
{
if (m_keyboardActivity || !m_settings.disableOnKeyboardActivity()) {
return;
}
m_keyboardActivityTimeout.stop();
m_keyboardActivity = true;
m_backend->setTouchpadOff(m_keyboardDisableState);
}
void TouchpadDisabler::keyboardActivityFinished()
{
if (!m_keyboardActivity) {
keyboardActivityStarted();
}
m_keyboardActivityTimeout.start();
}
void TouchpadDisabler::timerElapsed()
{
if (!m_keyboardActivity) {
return;
}
m_keyboardActivity = false;
m_backend->setTouchpadOff(TouchpadBackend::TouchpadEnabled);
}
void TouchpadDisabler::mousePlugged()
{
if (!m_dependecies.watchedServices().isEmpty()) {
return;
}
bool pluggedIn = isMousePluggedIn();
Q_EMIT mousePluggedInChanged(pluggedIn);
bool disable = pluggedIn && m_settings.disableWhenMousePluggedIn();
if (m_mouse == disable) {
return;
}
m_mouse = disable;
if (m_enabled == !disable) {
return;
}
if (disable) {
showNotification("TouchpadDisabled",
i18n("Touchpad was disabled because a mouse was plugged in"));
} else {
showNotification("TouchpadEnabled",
i18n("Touchpad was enabled because the mouse was unplugged"));
}
m_backend->setTouchpadEnabled(!disable);
}
void TouchpadDisabler::showNotification(const QString &name, const QString &text)
{
KNotification::event(name, text, QPixmap(), //Icon is specified in .notifyrc
0, KNotification::CloseOnTimeout,
TouchpadPluginFactory::componentData());
}
bool TouchpadDisabler::isMousePluggedIn() const
{
return !m_backend->listMouses(m_settings.mouseBlacklist()).isEmpty();
}
void TouchpadDisabler::lateInit()
{
TouchpadGlobalActions *actions = new TouchpadGlobalActions(this);
connect(actions, SIGNAL(enableTriggered()), SLOT(enable()));
connect(actions, SIGNAL(disableTriggered()), SLOT(disable()));
connect(actions, SIGNAL(toggleTriggered()), SLOT(toggle()));
updateCurrentState();
mousePlugged();
}
void touchpadApplySavedConfig();
void TouchpadDisabler::handleReset()
{
m_backend->setTouchpadEnabled(m_enabled);
touchpadApplySavedConfig();
}

View file

@ -1,74 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KDED_H
#define KDED_H
#include <QtCore/qvariant.h>
#include <QTimer>
#include <QtDBus>
#include <KDEDModule>
#include "touchpadbackend.h"
#include "kdedsettings.h"
class TouchpadDisabler : public KDEDModule
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.touchpad")
public:
TouchpadDisabler(QObject *, const QVariantList &);
Q_SIGNALS:
Q_SCRIPTABLE void enabledChanged(bool);
Q_SCRIPTABLE void mousePluggedInChanged(bool);
public Q_SLOTS:
Q_SCRIPTABLE Q_NOREPLY void reloadSettings();
Q_SCRIPTABLE Q_NOREPLY void toggle();
Q_SCRIPTABLE Q_NOREPLY void disable();
Q_SCRIPTABLE Q_NOREPLY void enable();
Q_SCRIPTABLE bool isEnabled() const;
Q_SCRIPTABLE bool workingTouchpadFound() const;
Q_SCRIPTABLE bool isMousePluggedIn() const;
private Q_SLOTS:
void keyboardActivityStarted();
void keyboardActivityFinished();
void timerElapsed();
void mousePlugged();
void updateCurrentState();
void serviceRegistered(const QString &);
void handleReset();
private:
void showNotification(const QString &name, const QString &text);
void lateInit();
TouchpadBackend *m_backend;
TouchpadDisablerSettings m_settings;
QTimer m_keyboardActivityTimeout;
QDBusServiceWatcher m_dependecies;
TouchpadBackend::TouchpadOffState m_keyboardDisableState;
bool m_enabled, m_keyboardActivity, m_mouse;
};
#endif // KDED_H

View file

@ -1,53 +0,0 @@
[Desktop Entry]
Type=Service
X-KDE-ServiceTypes=KDEDModule
X-KDE-Library=touchpad
X-KDE-DBus-ModuleName=touchpad
X-KDE-Kded-autoload=true
X-KDE-Kded-load-on-demand=true
Name=Touchpad
Name[bs]=Dodirna površina
Name[cs]=Touchpad
Name[da]=Touchpad
Name[de]=Touchpad
Name[el]=Επιφάνεια αφής
Name[es]=Panel táctil
Name[fi]=Kosketuslevy
Name[fr]=Pavé tactile
Name[hu]=Érintőtábla
Name[ko]=
Name[lt]=Jutiklinis kilimėlis
Name[nl]=Touchpad
Name[pl]=Gładzik
Name[pt]=Rato por Toque
Name[pt_BR]=Touchpad
Name[ro]=Zonă tactilă
Name[sk]=Touchpad
Name[sl]=Sledilna ploščica
Name[sv]=Tryckplatta
Name[tr]=Dokunmatik Yüzey
Name[uk]=Сенсорна панель
Name[x-test]=xxTouchpadxx
Comment=Enables or disables touchpad
Comment[bs]=Uključuje ili isključuje dodirnu površinu
Comment[cs]=Povolí/zakáže touchpad
Comment[da]=Aktiverer eller deaktiverer touchpad
Comment[de]=Aktiviert oder deaktiviert das Touchpad
Comment[el]=Ενεργοποιεί ή απενεργοποιεί την επιφάνεια αφής
Comment[es]=Activa o desactiva el panel táctil
Comment[fi]=Ottaa kosketuslevyn käyttöön tai poistaa sen käytöstä
Comment[fr]=Active ou désactive le pavé tactile
Comment[hu]=Engedélyezi vagy letiltja az érintőtáblát
Comment[ko]= /
Comment[lt]=Įjungia/išjungia jutiklinį kilimėlį
Comment[nl]=Schakelt het touchpad in of uit
Comment[pl]=Włącza lub wyłącza gładzik
Comment[pt]=Activa ou desactiva o rato por toque
Comment[pt_BR]=Ativa ou desativa o touchpad
Comment[ro]=Activează sau dezactivează zona tactilă
Comment[sk]=Povolí alebo zakáže touchpad
Comment[sl]=Omogoči ali onemogoči sledilno ploščico
Comment[sv]=Aktiverar eller stänger av tryckplatta
Comment[tr]=Dokunmatik yüzeyi etkinleştirir veya devre dışı bırakır
Comment[uk]=Вмикає або вимикає сенсорну панель
Comment[x-test]=xxEnables or disables touchpadxx

View file

@ -1,48 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kdedactions.h"
#include <KAction>
#include <KLocale>
#include "plugins.h"
TouchpadGlobalActions::TouchpadGlobalActions(QObject *parent)
: KActionCollection(parent)
{
setComponentData(TouchpadPluginFactory::componentData());
KAction *enable = addAction("Enable Touchpad");
enable->setText(i18n("Enable Touchpad"));
connect(enable, SIGNAL(triggered()), SIGNAL(enableTriggered()));
KAction *disable = addAction("Disable Touchpad");
disable->setText(i18n("Disable Touchpad"));
connect(disable, SIGNAL(triggered()), SIGNAL(disableTriggered()));
KAction *toggle = addAction("Toggle Touchpad");
toggle->setText(i18n("Toggle Touchpad"));
connect(toggle, SIGNAL(triggered()), SIGNAL(toggleTriggered()));
Q_FOREACH (QAction *i, actions()) {
KAction *act = qobject_cast<KAction *>(i);
act->setGlobalShortcut(KShortcut());
act->setShortcutConfigurable(true);
}
}

View file

@ -1,36 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KDEDACTIONS_H
#define KDEDACTIONS_H
#include <KActionCollection>
class TouchpadGlobalActions : public KActionCollection
{
Q_OBJECT
public:
explicit TouchpadGlobalActions(QObject *parent);
Q_SIGNALS:
void enableTriggered();
void disableTriggered();
void toggleTriggered();
};
#endif // KDEDACTIONS_H

View file

@ -1,5 +0,0 @@
File=touchpaddaemon.kcfg
ClassName=TouchpadDisablerSettings
Mutators=true
MemberVariables=private
Inherits=KCoreConfigSkeleton

View file

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
<kcfgfile name="touchpadrc"/>
<group name="autodisable">
<entry name="DisableWhenMousePluggedIn" type="Bool">
<default>false</default>
</entry>
<entry name="DisableOnKeyboardActivity" type="Bool">
<default>true</default>
</entry>
<entry name="OnlyDisableTapAndScrollOnKeyboardActivity" type="Bool">
<default>true</default>
</entry>
<entry name="KeyboardActivityTimeoutMs" type="Int">
<min>0</min>
<max>10000</max>
<default>250</default>
</entry>
<entry name="MouseBlacklist" type="StringList">
<default>TPPS/2 IBM TrackPoint,USB Trackpoint pointing device,DualPoint Stick,ThinkPad USB Keyboard with TrackPoint</default>
</entry>
</group>
</kcfg>

View file

@ -1,60 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "plugins.h"
#include <KAboutData>
#include <KPluginFactory>
#include "kcm/touchpadconfig.h"
#include "kded/kded.h"
#include "version.h"
namespace {
KAboutData buildAboutData()
{
KAboutData data("kcm_touchpad",
QByteArray(),
ki18n("Touchpad KCM"),
TOUCHPAD_KCM_VERSION,
ki18n("System Settings module, daemon and Plasma applet for managing your touchpad"),
KAboutData::License_GPL_V2,
ki18n("Copyright © 2013 Alexander Mezin"),
ki18n("This program incorporates work covered by this copyright notice:\n"
"Copyright © 2002-2005,2007 Peter Osterlund"),
"https://projects.kde.org/projects/playground/utils/kcm-touchpad/");
data.addAuthor(ki18n("Alexander Mezin"),
ki18n("Developer"),
"mezin.alexander@gmail.com");
data.addCredit(ki18n("Thomas Pfeiffer"), ki18nc("Credits", "Usability, testing"));
data.addCredit(ki18n("Alex Fiestas"), ki18nc("Credits", "Helped a bit"));
data.addCredit(ki18n("Peter Osterlund"), ki18nc("Credits", "Developer of synclient"));
data.addCredit(ki18n("Vadim Zaytsev"), ki18nc("Credits", "Testing"));
data.addCredit(ki18n("Violetta Raspryagayeva"), ki18nc("Credits", "Testing"));
return data;
}
}
K_PLUGIN_FACTORY_DEFINITION(TouchpadPluginFactory,
registerPlugin<TouchpadDisabler>();
registerPlugin<TouchpadConfig>("kcm");)
K_EXPORT_PLUGIN(TouchpadPluginFactory(buildAboutData()))

View file

@ -1,26 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef PLUGINS_H
#define PLUGINS_H
#include <KPluginFactory>
K_PLUGIN_FACTORY_DECLARATION(TouchpadPluginFactory)
#endif // PLUGINS_H

View file

@ -1,38 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "touchpadbackend.h"
#include <QThreadStorage>
#include <QSharedPointer>
#include "x11/xlibbackend.h"
TouchpadBackend::TouchpadBackend(QObject *parent) : QObject(parent)
{
}
TouchpadBackend *TouchpadBackend::implementation()
{
//There will be multiple backends later
static QThreadStorage<QSharedPointer<XlibBackend> > backend;
if (!backend.hasLocalData()) {
backend.setLocalData(QSharedPointer<XlibBackend>(new XlibBackend()));
}
return backend.localData().data();
}

View file

@ -1,61 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef TOUCHPADBACKEND_H
#define TOUCHPADBACKEND_H
#include <QObject>
#include <QtCore/qvariant.h>
#include <kdemacros.h>
class KDE_EXPORT TouchpadBackend : public QObject
{
Q_OBJECT
public:
explicit TouchpadBackend(QObject *parent);
static TouchpadBackend *implementation();
virtual bool applyConfig(const QVariantHash &) = 0;
virtual bool getConfig(QVariantHash &) = 0;
virtual const QStringList &supportedParameters() const = 0;
virtual const QString &errorString() const = 0;
enum TouchpadOffState {
TouchpadEnabled, TouchpadTapAndScrollDisabled, TouchpadFullyDisabled
};
virtual void setTouchpadOff(TouchpadOffState) = 0;
virtual TouchpadOffState getTouchpadOff() = 0;
virtual bool isTouchpadEnabled() = 0;
virtual void setTouchpadEnabled(bool) = 0;
virtual QStringList listMouses(const QStringList &blacklist) = 0;
virtual void watchForEvents(bool keyboard) = 0;
Q_SIGNALS:
void touchpadStateChanged();
void mousesChanged();
void touchpadReset();
void keyboardActivityStarted();
void keyboardActivityFinished();
};
#endif // TOUCHPADBACKEND_H

View file

@ -1,6 +0,0 @@
#ifndef VERSION_H
#define VERSION_H
#define TOUCHPAD_KCM_VERSION "@TOUCHPAD_KCM_VERSION@"
#endif // VERSION_H

View file

@ -1,53 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//Debug tool
//Must NOT be translated/localized
#include <iostream>
#include <X11/Xlib.h>
#include <X11/extensions/XInput.h>
int main(void)
{
Display *display = XOpenDisplay(0);
int nDevices = 0;
XDeviceInfo *devices = XListInputDevices(display, &nDevices);
for (int i = 0; i < nDevices; i++) {
const char *name = devices[i].name;
char *type = 0;
if (devices[i].type) {
type = XGetAtomName(display, devices[i].type);
}
const char *use;
switch (devices[i].use) {
case IsXPointer: use = "Pointer"; break;
case IsXKeyboard: use = "Keyboard"; break;
case IsXExtensionDevice: use = "Extension Device"; break;
case IsXExtensionPointer: use = "Extension Pointer"; break;
case IsXExtensionKeyboard: use = "Extension Keyboard"; break;
default: use = "Unknown";
}
std::cout << "Name: " << name << " Type: " << (type ? type : "unknown")
<< " Use: " << use << std::endl;
XFree(type);
}
XFreeDeviceList(devices);
XCloseDisplay(display);
}

View file

@ -1,126 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
//krazy:excludeall=copyright
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright © 2002-2005,2007 Peter Osterlund
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of Red Hat
* not be used in advertising or publicity pertaining to distribution
* of the software without specific, written prior permission. Red
* Hat makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied
* warranty.
*
* THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Authors:
* Peter Osterlund (petero2@telia.com)
*/
#include "synclientproperties.h"
#include <stddef.h>
#include <limits.h>
#include <xorg/synaptics-properties.h>
#define SYN_MAX_BUTTONS 12
const struct Parameter synapticsProperties[] = {
{"LeftEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_EDGES, 32, 0},
{"RightEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_EDGES, 32, 1},
{"TopEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_EDGES, 32, 2},
{"BottomEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_EDGES, 32, 3},
{"FingerLow", PT_INT, 0, 255, SYNAPTICS_PROP_FINGER, 32, 0},
{"FingerHigh", PT_INT, 0, 255, SYNAPTICS_PROP_FINGER, 32, 1},
{"MaxTapTime", PT_INT, 0, 1000, SYNAPTICS_PROP_TAP_TIME, 32, 0},
{"MaxTapMove", PT_INT, 0, 2000, SYNAPTICS_PROP_TAP_MOVE, 32, 0},
{"MaxDoubleTapTime", PT_INT, 0, 1000, SYNAPTICS_PROP_TAP_DURATIONS,32, 1},
{"SingleTapTimeout", PT_INT, 0, 1000, SYNAPTICS_PROP_TAP_DURATIONS,32, 0},
{"ClickTime", PT_INT, 0, 1000, SYNAPTICS_PROP_TAP_DURATIONS,32, 2},
{"FastTaps", PT_BOOL, 0, 1, SYNAPTICS_PROP_TAP_FAST, 8, 0},
{"EmulateMidButtonTime", PT_INT, 0, 1000, SYNAPTICS_PROP_MIDDLE_TIMEOUT,32, 0},
{"EmulateTwoFingerMinZ", PT_INT, 0, 1000, SYNAPTICS_PROP_TWOFINGER_PRESSURE, 32, 0},
{"EmulateTwoFingerMinW", PT_INT, 0, 15, SYNAPTICS_PROP_TWOFINGER_WIDTH, 32, 0},
{"VertScrollDelta", PT_INT, -1000, 1000, SYNAPTICS_PROP_SCROLL_DISTANCE, 32, 0},
{"HorizScrollDelta", PT_INT, -1000, 1000, SYNAPTICS_PROP_SCROLL_DISTANCE, 32, 1},
{"VertEdgeScroll", PT_BOOL, 0, 1, SYNAPTICS_PROP_SCROLL_EDGE, 8, 0},
{"HorizEdgeScroll", PT_BOOL, 0, 1, SYNAPTICS_PROP_SCROLL_EDGE, 8, 1},
{"CornerCoasting", PT_BOOL, 0, 1, SYNAPTICS_PROP_SCROLL_EDGE, 8, 2},
{"VertTwoFingerScroll", PT_BOOL, 0, 1, SYNAPTICS_PROP_SCROLL_TWOFINGER, 8, 0},
{"HorizTwoFingerScroll", PT_BOOL, 0, 1, SYNAPTICS_PROP_SCROLL_TWOFINGER, 8, 1},
{"MinSpeed", PT_DOUBLE, 0, 255.0, SYNAPTICS_PROP_SPEED, 0, /*float */ 0},
{"MaxSpeed", PT_DOUBLE, 0, 255.0, SYNAPTICS_PROP_SPEED, 0, /*float */ 1},
{"AccelFactor", PT_DOUBLE, 0, 1.0, SYNAPTICS_PROP_SPEED, 0, /*float */ 2},
/*{"TouchpadOff", PT_INT, 0, 2, SYNAPTICS_PROP_OFF, 8, 0},*/
{"LockedDrags", PT_BOOL, 0, 1, SYNAPTICS_PROP_LOCKED_DRAGS, 8, 0},
{"LockedDragTimeout", PT_INT, 0, 30000, SYNAPTICS_PROP_LOCKED_DRAGS_TIMEOUT, 32, 0},
{"RTCornerButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 0},
{"RBCornerButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 1},
{"LTCornerButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 2},
{"LBCornerButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 3},
{"OneFingerTapButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 4},
{"TwoFingerTapButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 5},
{"ThreeFingerTapButton", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_TAP_ACTION, 8, 6},
{"ClickFinger1", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_CLICK_ACTION, 8, 0},
{"ClickFinger2", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_CLICK_ACTION, 8, 1},
{"ClickFinger3", PT_INT, 0, SYN_MAX_BUTTONS, SYNAPTICS_PROP_CLICK_ACTION, 8, 2},
{"CircularScrolling", PT_BOOL, 0, 1, SYNAPTICS_PROP_CIRCULAR_SCROLLING, 8, 0},
{"CircScrollDelta", PT_DOUBLE, .01, 3, SYNAPTICS_PROP_CIRCULAR_SCROLLING_DIST, 0 /* float */, 0},
{"CircScrollTrigger", PT_INT, 0, 8, SYNAPTICS_PROP_CIRCULAR_SCROLLING_TRIGGER, 8, 0},
{"PalmDetect", PT_BOOL, 0, 1, SYNAPTICS_PROP_PALM_DETECT, 8, 0},
{"PalmMinWidth", PT_INT, 0, 15, SYNAPTICS_PROP_PALM_DIMENSIONS, 32, 0},
{"PalmMinZ", PT_INT, 0, 255, SYNAPTICS_PROP_PALM_DIMENSIONS, 32, 1},
{"CoastingSpeed", PT_DOUBLE, 0, 255, SYNAPTICS_PROP_COASTING_SPEED, 0 /* float*/, 0},
{"CoastingFriction", PT_DOUBLE, 0, 255, SYNAPTICS_PROP_COASTING_SPEED, 0 /* float*/, 1},
{"PressureMotionMinZ", PT_INT, 1, 255, SYNAPTICS_PROP_PRESSURE_MOTION, 32, 0},
{"PressureMotionMaxZ", PT_INT, 1, 255, SYNAPTICS_PROP_PRESSURE_MOTION, 32, 1},
{"PressureMotionMinFactor", PT_DOUBLE, 0, 10.0,SYNAPTICS_PROP_PRESSURE_MOTION_FACTOR, 0 /*float*/, 0},
{"PressureMotionMaxFactor", PT_DOUBLE, 0, 10.0,SYNAPTICS_PROP_PRESSURE_MOTION_FACTOR, 0 /*float*/, 1},
{"GrabEventDevice", PT_BOOL, 0, 1, SYNAPTICS_PROP_GRAB, 8, 0},
{"TapAndDragGesture", PT_BOOL, 0, 1, SYNAPTICS_PROP_GESTURES, 8, 0},
{"AreaLeftEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 0},
{"AreaRightEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 1},
{"AreaTopEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 2},
{"AreaBottomEdge", PT_INT, 0, 10000, SYNAPTICS_PROP_AREA, 32, 3},
{"HorizHysteresis", PT_INT, 0, 10000, SYNAPTICS_PROP_NOISE_CANCELLATION, 32, 0},
{"VertHysteresis", PT_INT, 0, 10000, SYNAPTICS_PROP_NOISE_CANCELLATION, 32, 1},
{"ClickPad", PT_BOOL, 0, 1, SYNAPTICS_PROP_CLICKPAD, 8, 0},
{"RightButtonAreaLeft", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 0},
{"RightButtonAreaRight", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 1},
{"RightButtonAreaTop", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 2},
{"RightButtonAreaBottom", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 3},
{"MiddleButtonAreaLeft", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 4},
{"MiddleButtonAreaRight", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 5},
{"MiddleButtonAreaTop", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 6},
{"MiddleButtonAreaBottom", PT_INT, INT_MIN, INT_MAX, SYNAPTICS_PROP_SOFTBUTTON_AREAS, 32, 7},
{ NULL, 0, 0, 0, 0, 0, 0 }
};

View file

@ -1,70 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
//krazy:excludeall=copyright
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright © 2002-2005,2007 Peter Osterlund
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of Red Hat
* not be used in advertising or publicity pertaining to distribution
* of the software without specific, written prior permission. Red
* Hat makes no representations about the suitability of this software
* for any purpose. It is provided "as is" without express or implied
* warranty.
*
* THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Authors:
* Peter Osterlund (petero2@telia.com)
*/
#ifndef SYNCLIENTPROPERTIES_H
#define SYNCLIENTPROPERTIES_H
enum ParaType {
PT_INT,
PT_BOOL,
PT_DOUBLE
};
struct Parameter {
const char *name; /* Name of parameter */
enum ParaType type; /* Type of parameter */
double min_val; /* Minimum allowed value */
double max_val; /* Maximum allowed value */
const char *prop_name; /* Property name */
int prop_format; /* Property format (0 for floats) */
unsigned prop_offset; /* Offset inside property */
};
extern const struct Parameter synapticsProperties[];
#endif

View file

@ -1,48 +0,0 @@
# // krazy:excludeall=copyright,license
find_package(X11 REQUIRED)
find_package(X11_XCB REQUIRED)
find_package(XCB REQUIRED)
find_package(PkgConfig REQUIRED)
if(NOT X11_Xinput_FOUND)
message(FATAL_ERROR "Xinput not found")
endif()
pkg_search_module(SYNAPTICS REQUIRED xorg-synaptics)
pkg_search_module(XORG REQUIRED xorg-server)
include_directories(${XCB_INCLUDE_DIR}
${X11_XCB_INCLUDE_DIR}
${X11_Xinput_INCLUDE_PATH}
${X11_X11_INCLUDE_PATH}
${SYNAPTICS_INCLUDE_DIRS}
${XORG_INCLUDE_DIRS}
)
add_definitions(${X11_XCB_DEFINITIONS} ${XCB_DEFINITIONS})
SET(backend_SRCS
${backend_SRCS}
${CMAKE_CURRENT_SOURCE_DIR}/x11/synclientproperties.c
${CMAKE_CURRENT_SOURCE_DIR}/x11/xcbatom.cpp
${CMAKE_CURRENT_SOURCE_DIR}/x11/xlibbackend.cpp
${CMAKE_CURRENT_SOURCE_DIR}/x11/xlibnotifications.cpp
${CMAKE_CURRENT_SOURCE_DIR}/x11/xrecordkeyboardmonitor.cpp
)
SET(backend_LIBS
${backend_LIBS}
${XCB_LIBRARIES}
${X11_X11_LIB}
${X11_XCB_LIBRARIES}
${X11_Xinput_LIB}
)
add_executable(kcm-touchpad-list-devices ${CMAKE_CURRENT_SOURCE_DIR}/x11/listdevices.cpp)
target_link_libraries(kcm-touchpad-list-devices
${X11_X11_LIB}
${X11_Xinput_LIB}
)
install(TARGETS kcm-touchpad-list-devices
DESTINATION ${INSTALL_TARGETS_DEFAULT_ARGS}
)

View file

@ -1,56 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "xcbatom.h"
#include <cstdlib>
#include <cstring>
XcbAtom::XcbAtom() : m_connection(0), m_reply(0), m_fetched(false)
{
}
XcbAtom::XcbAtom(xcb_connection_t *c, const char *name, bool onlyIfExists)
: m_reply(0), m_fetched(false)
{
intern(c, name, onlyIfExists);
}
void XcbAtom::intern(xcb_connection_t *c, const char *name, bool onlyIfExists)
{
m_connection = c;
m_cookie = xcb_intern_atom(c, onlyIfExists, std::strlen(name), name);
}
XcbAtom::~XcbAtom()
{
std::free(m_reply);
}
xcb_atom_t XcbAtom::atom()
{
if (!m_fetched) {
m_fetched = true;
m_reply = xcb_intern_atom_reply(m_connection, m_cookie, 0);
}
if (m_reply) {
return m_reply->atom;
} else {
return 0;
}
}

View file

@ -1,45 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef XCBATOM_H
#define XCBATOM_H
#include <xcb/xcb.h>
class XcbAtom
{
public:
XcbAtom();
XcbAtom(xcb_connection_t *, const char *name, bool onlyIfExists = true);
~XcbAtom();
void intern(xcb_connection_t *, const char *name, bool onlyIfExists = true);
xcb_atom_t atom();
operator xcb_atom_t() { return atom(); }
private:
XcbAtom(const XcbAtom &);
XcbAtom &operator =(const XcbAtom &);
xcb_connection_t *m_connection;
xcb_intern_atom_cookie_t m_cookie;
xcb_intern_atom_reply_t *m_reply;
bool m_fetched;
};
#endif // XCBATOM_H

View file

@ -1,705 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <cstring>
#include <cmath>
#include <algorithm>
#include <QtCore/qalgorithms.h>
#include <QScopedPointer>
#include <KLocalizedString>
#include <KDebug>
//Includes are ordered this way because of #defines in Xorg's headers
#include "xrecordkeyboardmonitor.h" // krazy:exclude=includes
#include "xlibbackend.h" // krazy:exclude=includes
#include "xlibnotifications.h" // krazy:exclude=includes
#include <X11/Xlib-xcb.h>
#include <X11/Xatom.h>
#include <X11/extensions/XInput.h>
#include <X11/extensions/XInput2.h>
#include <synaptics-properties.h>
#include <xserver-properties.h>
#include "synclientproperties.h"
static void XDeleter(void *p)
{
if (p) {
XFree(p);
}
}
static void XIDeviceInfoDeleter(XIDeviceInfo *p)
{
if (p) {
XIFreeDeviceInfo(p);
}
}
void XlibBackend::XDisplayCleanup::cleanup(Display *p)
{
if (p) {
XCloseDisplay(p);
}
}
struct PropertyInfo
{
Atom type;
int format;
QSharedPointer<unsigned char> data;
unsigned long nitems;
float *f;
int *i;
char *b;
Display *display;
int device;
Atom prop;
PropertyInfo() :
type(0), format(0), nitems(0), f(0), i(0), b(0),
display(0), device(0), prop(0)
{
}
PropertyInfo(Display *display, int device, Atom prop, Atom floatType)
: type(0), format(0), nitems(0), f(0), i(0), b(0),
display(display), device(device), prop(prop)
{
unsigned char *dataPtr = 0;
unsigned long bytes_after;
XIGetProperty(display, device, prop, 0, 1000, False,
AnyPropertyType, &type, &format, &nitems,
&bytes_after, &dataPtr);
data = QSharedPointer<unsigned char>(dataPtr, XDeleter);
if (format == CHAR_BIT && type == XA_INTEGER) {
b = reinterpret_cast<char *>(dataPtr);
}
if (format == sizeof(int) * CHAR_BIT &&
(type == XA_INTEGER || type == XA_CARDINAL))
{
i = reinterpret_cast<int *>(dataPtr);
}
if (format == sizeof(float) * CHAR_BIT &&
floatType && type == floatType)
{
f = reinterpret_cast<float *>(dataPtr);
}
}
QVariant value(unsigned offset) const
{
QVariant v;
if (offset >= nitems) {
return v;
}
if (b) {
v = QVariant(static_cast<int>(b[offset]));
}
if (i) {
v = QVariant(i[offset]);
}
if (f) {
v = QVariant(f[offset]);
}
return v;
}
void set()
{
XIChangeProperty(display, device, prop, type, format,
XIPropModeReplace, data.data(), nitems);
}
};
XlibBackend::~XlibBackend()
{
}
XlibBackend::XlibBackend(QObject *parent) :
TouchpadBackend(parent),
m_display(XOpenDisplay(0)), m_connection(0),
m_resX(1), m_resY(1)
{
if (m_display) {
m_connection = XGetXCBConnection(m_display.data());
}
if (!m_connection) {
m_errorString = i18n("Cannot connect to X server");
return;
}
m_floatType.intern(m_connection, "FLOAT");
m_capsAtom.intern(m_connection, SYNAPTICS_PROP_CAPABILITIES);
m_enabledAtom.intern(m_connection, XI_PROP_ENABLED);
m_touchpadOffAtom.intern(m_connection, SYNAPTICS_PROP_OFF);
m_mouseAtom.intern(m_connection, XI_MOUSE);
m_keyboardAtom.intern(m_connection, XI_KEYBOARD);
XcbAtom resolutionAtom(m_connection, SYNAPTICS_PROP_RESOLUTION);
XcbAtom edgesAtom(m_connection, SYNAPTICS_PROP_EDGES);
for (const Parameter *param = synapticsProperties; param->name; param++) {
QLatin1String name(param->prop_name);
if (!m_atoms.contains(name)) {
m_atoms.insert(name, QSharedPointer<XcbAtom>(
new XcbAtom(m_connection, param->prop_name)));
}
}
if (!m_capsAtom.atom()) {
m_errorString =
i18n("Synaptics driver is not installed (or is not used)");
return;
}
m_device = findTouchpad();
if (m_device == XIAllDevices) {
m_errorString = i18n("No touchpad found");
return;
}
for (const Parameter *p = synapticsProperties; p->name; p++) {
if (getParameter(p).isValid()) {
m_supported.append(p->name);
}
}
if (m_supported.isEmpty()) {
m_errorString = i18n("Cannot read any of touchpad's properties");
return;
}
m_toRadians.append("CircScrollDelta");
PropertyInfo edges(m_display.data(), m_device, edgesAtom, 0);
if (edges.i && edges.nitems == 4) {
int w = qAbs(edges.i[1] - edges.i[0]);
int h = qAbs(edges.i[3] - edges.i[2]);
m_resX = w / 90;
m_resY = h / 50;
kDebug() << "Width: " << w << " height: " << h;
kDebug() << "Approx. resX: " << m_resX << " resY: " << m_resY;
}
PropertyInfo resolution(m_display.data(), m_device, resolutionAtom, 0);
if (resolution.i && resolution.nitems == 2 &&
resolution.i[0] > 1 && resolution.i[1] > 1)
{
m_resY = qMin(static_cast<unsigned long>(resolution.i[0]),
static_cast<unsigned long>(INT_MAX));
m_resX = qMin(static_cast<unsigned long>(resolution.i[1]),
static_cast<unsigned long>(INT_MAX));
kDebug() << "Touchpad resolution: x: " << m_resX << " y: " << m_resY;
}
m_scaleByResX.append("HorizScrollDelta");
m_scaleByResY.append("VertScrollDelta");
m_scaleByResX.append("MaxTapMove");
m_scaleByResY.append("MaxTapMove");
m_resX = qMax(10, m_resX);
m_resY = qMax(10, m_resY);
kDebug() << "Final resolution x:" << m_resX << " y:" << m_resY;
m_negate["HorizScrollDelta"] = "InvertHorizScroll";
m_negate["VertScrollDelta"] = "InvertVertScroll";
m_supported.append(m_negate.values());
m_supported.append("Coasting");
PropertyInfo caps(m_display.data(), m_device, m_capsAtom.atom(), 0);
if (!caps.b) {
m_errorString = i18n("Cannot read touchpad's capabilities");
return;
}
enum TouchpadCapabilitiy
{
TouchpadHasLeftButton,
TouchpadHasMiddleButton,
TouchpadHasRightButton,
TouchpadTwoFingerDetect,
TouchpadThreeFingerDetect,
TouchpadPressureDetect,
TouchpadPalmDetect,
TouchpadCapsCount
};
QVector<bool> cap(TouchpadCapsCount, false);
qCopy(caps.b, caps.b + qMin(cap.size(), static_cast<int>(caps.nitems)),
cap.begin());
if (!cap[TouchpadTwoFingerDetect]) {
m_supported.removeAll("HorizTwoFingerScroll");
m_supported.removeAll("VertTwoFingerScroll");
m_supported.removeAll("TwoFingerTapButton");
}
if (!cap[TouchpadThreeFingerDetect]) {
m_supported.removeAll("ThreeFingerTapButton");
}
if (!cap[TouchpadPressureDetect]) {
m_supported.removeAll("FingerHigh");
m_supported.removeAll("FingerLow");
m_supported.removeAll("PalmMinZ");
m_supported.removeAll("PressureMotionMinZ");
m_supported.removeAll("PressureMotionMinFactor");
m_supported.removeAll("PressureMotionMaxZ");
m_supported.removeAll("PressureMotionMaxFactor");
m_supported.removeAll("EmulateTwoFingerMinZ");
}
if (!cap[TouchpadPalmDetect]) {
m_supported.removeAll("PalmDetect");
m_supported.removeAll("PalmMinWidth");
m_supported.removeAll("PalmMinZ");
m_supported.removeAll("EmulateTwoFingerMinW");
}
for (QMap<QString, QString>::Iterator i = m_negate.begin();
i != m_negate.end(); ++i)
{
if (!m_supported.contains(i.key())) {
m_supported.removeAll(i.value());
}
}
}
int XlibBackend::findTouchpad()
{
int nDevices = 0;
QSharedPointer<XIDeviceInfo> deviceInfo(
XIQueryDevice(m_display.data(), XIAllDevices, &nDevices),
XIDeviceInfoDeleter);
for (XIDeviceInfo *info = deviceInfo.data();
info < deviceInfo.data() + nDevices; info++)
{
int nProperties = 0;
QSharedPointer<Atom> properties(
XIListProperties(m_display.data(), info->deviceid,
&nProperties), XDeleter);
if (std::count(properties.data(), properties.data() + nProperties,
m_capsAtom.atom()))
{
return info->deviceid;
}
}
return XIAllDevices;
}
static const Parameter *findParameter(const QString &name)
{
for (const Parameter *par = synapticsProperties; par->name; par++) {
if (name == par->name) {
return par;
}
}
return 0;
}
double XlibBackend::getPropertyScale(const QString &name) const
{
if (m_scaleByResX.contains(name) && m_scaleByResY.contains(name)) {
return std::sqrt(static_cast<double>(m_resX) * m_resX
+ static_cast<double>(m_resY) * m_resY);
} else if (m_scaleByResX.contains(name)) {
return m_resX;
} else if (m_scaleByResY.contains(name)) {
return m_resY;
} else if (m_toRadians.contains(name)) {
return M_PI_4 / 45.0;
}
return 1.0;
}
static QVariant negateVariant(const QVariant &value)
{
if (value.type() == QVariant::Double) {
return QVariant(-value.toDouble());
} else if (value.type() == QVariant::Int) {
return QVariant(-value.toInt());
}
return value;
}
bool XlibBackend::applyConfig(const QVariantHash &p)
{
if (m_supported.isEmpty()) {
return false;
}
m_props.clear();
bool error = false;
Q_FOREACH(const QString &name, m_supported) {
QVariantHash::ConstIterator i = p.find(name);
if (i == p.end()) {
continue;
}
const Parameter *par = findParameter(name);
if (par) {
QVariant value(i.value());
double k = getPropertyScale(name);
if (k != 1.0) {
bool ok = false;
value = QVariant(value.toDouble(&ok) * k);
if (!ok) {
error = true;
continue;
}
}
if (m_negate.contains(name)) {
QVariantHash::ConstIterator i = p.find(m_negate[name]);
if (i != p.end() && i.value().toBool()) {
value = negateVariant(value);
}
}
if (name == "CoastingSpeed") {
QVariantHash::ConstIterator coastingEnabled = p.find("Coasting");
if (coastingEnabled != p.end() &&
!coastingEnabled.value().toBool())
{
value = QVariant(0);
}
}
if (!setParameter(par, value)) {
error = true;
}
}
}
flush();
if (error) {
m_errorString = i18n("Cannot apply touchpad configuration");
}
return !error;
}
void XlibBackend::flush()
{
Q_FOREACH(const QLatin1String &name, m_changed) {
m_props[name].set();
}
m_changed.clear();
XFlush(m_display.data());
}
bool XlibBackend::getConfig(QVariantHash &p)
{
if (m_supported.isEmpty()) {
return false;
}
m_props.clear();
bool error = false;
Q_FOREACH(const QString &name, m_supported) {
const Parameter *par = findParameter(name);
if (!par) {
continue;
}
QVariant value(getParameter(par));
if (!value.isValid()) {
error = true;
continue;
}
double k = getPropertyScale(name);
if (k != 1.0) {
bool ok = false;
value = QVariant(value.toDouble(&ok) / k);
if (!ok) {
error = true;
continue;
}
}
if (m_negate.contains(name)) {
bool negative = value.toDouble() < 0.0;
p[m_negate[name]] = QVariant(negative);
if (negative) {
value = negateVariant(value);
}
}
if (name == "CoastingSpeed") {
bool coasting = value.toDouble() != 0.0;
p["Coasting"] = QVariant(coasting);
if (!coasting) {
continue;
}
}
p[name] = value;
}
if (error) {
m_errorString = i18n("Cannot read touchpad configuration");
}
return !error;
}
QVariant XlibBackend::getParameter(const Parameter *par)
{
PropertyInfo *p = getDevProperty(QLatin1String(par->prop_name));
if (!p || par->prop_offset >= p->nitems) {
return QVariant();
}
return p->value(par->prop_offset);
}
PropertyInfo *XlibBackend::getDevProperty(const QLatin1String &propName)
{
if (m_props.contains(propName)) {
return &m_props[propName];
}
if (!m_atoms.contains(propName) || !m_atoms[propName]) {
return 0;
}
xcb_atom_t prop = m_atoms[propName]->atom();
if (!prop) {
return 0;
}
PropertyInfo p(m_display.data(), m_device, prop, m_floatType.atom());
if (!p.b && !p.f && !p.i) {
return 0;
}
return &m_props.insert(propName, p).value();
}
bool XlibBackend::setParameter(const Parameter *par, const QVariant &value)
{
QLatin1String propName(par->prop_name);
PropertyInfo *p = getDevProperty(propName);
if (!p || par->prop_offset >= p->nitems) {
return false;
}
QVariant converted(value);
QVariant::Type convType = QVariant::Int;
if (p->f) {
convType = QVariant::Double;
} else if (value.type() == QVariant::Double) {
converted = QVariant(qRound(static_cast<qreal>(value.toDouble())));
}
if (!converted.convert(convType)) {
return false;
}
if (converted == p->value(par->prop_offset)) {
return true;
}
if (p->b) {
p->b[par->prop_offset] = static_cast<char>(converted.toInt());
} else if (p->i) {
p->i[par->prop_offset] = converted.toInt();
} else if (p->f) {
p->f[par->prop_offset] = converted.toDouble();
}
m_changed.insert(propName);
return true;
}
void XlibBackend::setTouchpadEnabled(bool enable)
{
PropertyInfo enabled(m_display.data(), m_device, m_enabledAtom.atom(), 0);
if (enabled.b && *(enabled.b) != enable) {
*(enabled.b) = enable;
enabled.set();
}
flush();
}
void XlibBackend::setTouchpadOff(TouchpadBackend::TouchpadOffState state)
{
int touchpadOff = 0;
switch (state) {
case TouchpadEnabled:
touchpadOff = 0;
break;
case TouchpadFullyDisabled:
touchpadOff = 1;
break;
case TouchpadTapAndScrollDisabled:
touchpadOff = 2;
break;
default:
kError() << "Unknown TouchpadOffState" << state;
return;
}
PropertyInfo off(m_display.data(), m_device, m_touchpadOffAtom.atom(), 0);
if (off.b && *(off.b) != touchpadOff) {
*(off.b) = touchpadOff;
off.set();
}
flush();
}
bool XlibBackend::isTouchpadEnabled()
{
PropertyInfo enabled(m_display.data(), m_device, m_enabledAtom.atom(), 0);
return enabled.value(0).toBool();
}
TouchpadBackend::TouchpadOffState XlibBackend::getTouchpadOff()
{
PropertyInfo off(m_display.data(), m_device, m_touchpadOffAtom.atom(), 0);
switch (off.value(0).toInt()) {
case 0:
return TouchpadEnabled;
case 1:
return TouchpadFullyDisabled;
case 2:
return TouchpadTapAndScrollDisabled;
default:
kError() << "Unknown TouchpadOff value" << off.value(0).toInt();
return TouchpadFullyDisabled;
}
}
void XlibBackend::touchpadDetached()
{
kWarning() << "Touchpad detached";
m_device = XIAllDevices;
}
void XlibBackend::devicePlugged(int device)
{
if (m_device == XIAllDevices) {
m_device = findTouchpad();
if (m_device != XIAllDevices) {
kWarning() << "Touchpad reset";
m_notifications.reset();
watchForEvents(m_keyboard);
Q_EMIT touchpadReset();
}
}
if (device != m_device) {
Q_EMIT mousesChanged();
}
}
void XlibBackend::propertyChanged(xcb_atom_t prop)
{
if (prop == m_touchpadOffAtom.atom() ||
prop == m_enabledAtom.atom())
{
Q_EMIT touchpadStateChanged();
}
}
struct DeviceListDeleter
{
static void cleanup(XDeviceInfo *p)
{
if (p) {
XFreeDeviceList(p);
}
}
};
QStringList XlibBackend::listMouses(const QStringList &blacklist)
{
int nDevices = 0;
QScopedPointer<XDeviceInfo, DeviceListDeleter>
info(XListInputDevices(m_display.data(), &nDevices));
QStringList list;
for (XDeviceInfo *i = info.data(); i != info.data() + nDevices; i++) {
if (i->id == static_cast<XID>(m_device)) {
continue;
}
if (i->use != IsXExtensionPointer && i->use != IsXPointer) {
continue;
}
//type = KEYBOARD && use = Pointer means usb receiver for both keyboard
//and mouse
if (i->type != m_mouseAtom.atom() && i->type != m_keyboardAtom.atom()) {
continue;
}
QString name(i->name);
if (blacklist.contains(name, Qt::CaseInsensitive)) {
continue;
}
PropertyInfo enabled(m_display.data(), i->id, m_enabledAtom.atom(), 0);
if (enabled.value(0) == false) {
continue;
}
list.append(name);
}
return list;
}
void XlibBackend::watchForEvents(bool keyboard)
{
if (!m_notifications) {
m_notifications.reset(new XlibNotifications(m_display.data(), m_device));
connect(m_notifications.data(), SIGNAL(devicePlugged(int)),
SLOT(devicePlugged(int)));
connect(m_notifications.data(), SIGNAL(touchpadDetached()),
SLOT(touchpadDetached()));
connect(m_notifications.data(), SIGNAL(propertyChanged(xcb_atom_t)),
SLOT(propertyChanged(xcb_atom_t)));
}
if (keyboard == !m_keyboard.isNull()) {
return;
}
if (!keyboard) {
m_keyboard.reset();
return;
}
m_keyboard.reset(new XRecordKeyboardMonitor(m_display.data()));
connect(m_keyboard.data(), SIGNAL(keyboardActivityStarted()),
SIGNAL(keyboardActivityStarted()));
connect(m_keyboard.data(), SIGNAL(keyboardActivityFinished()),
SIGNAL(keyboardActivityFinished()));
}

View file

@ -1,99 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef XLIBBACKEND_H
#define XLIBBACKEND_H
#include <QMap>
#include <QSet>
#include <QScopedPointer>
#include <QtCore/qstring.h>
#include <QStringList>
#include <QSharedPointer>
#include <QtGui/qx11info_x11.h>
#include "touchpadbackend.h"
#include <xcb/xcb.h>
#include "xcbatom.h"
class XlibNotifications;
class XRecordKeyboardMonitor;
class XlibBackend : public TouchpadBackend
{
Q_OBJECT
public:
explicit XlibBackend(QObject *parent = 0);
~XlibBackend();
bool applyConfig(const QVariantHash &);
bool getConfig(QVariantHash &);
const QStringList &supportedParameters() const { return m_supported; }
const QString &errorString() const { return m_errorString; }
void setTouchpadOff(TouchpadOffState);
TouchpadOffState getTouchpadOff();
void setTouchpadEnabled(bool);
bool isTouchpadEnabled();
void watchForEvents(bool keyboard);
QStringList listMouses(const QStringList &blacklist);
private slots:
void propertyChanged(xcb_atom_t);
void touchpadDetached();
void devicePlugged(int);
private:
struct PropertyInfo *getDevProperty(const QLatin1String &propName);
bool setParameter(const struct Parameter *, const QVariant &);
QVariant getParameter(const struct Parameter *);
void flush();
double getPropertyScale(const QString &name) const;
struct XDisplayCleanup {
static void cleanup(Display *);
};
QScopedPointer<Display, XDisplayCleanup> m_display;
xcb_connection_t *m_connection;
XcbAtom m_floatType, m_capsAtom, m_enabledAtom, m_touchpadOffAtom,
m_mouseAtom, m_keyboardAtom;
int findTouchpad();
int m_device;
QMap<QLatin1String, QSharedPointer<XcbAtom> > m_atoms;
QMap<QLatin1String, struct PropertyInfo> m_props;
QSet<QLatin1String> m_changed;
QStringList m_supported;
QString m_errorString;
int m_resX, m_resY;
QStringList m_scaleByResX, m_scaleByResY, m_toRadians;
QMap<QString, QString> m_negate;
QScopedPointer<XlibNotifications> m_notifications;
QScopedPointer<XRecordKeyboardMonitor> m_keyboard;
};
#endif // XLIBBACKEND_H

View file

@ -1,156 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "xlibnotifications.h"
#include <cstring>
#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h>
#include <X11/extensions/XI.h>
#include <X11/extensions/XI2proto.h>
#include <X11/extensions/XInput2.h>
XlibNotifications::XlibNotifications(Display *display, int device)
: m_display(display), m_device(device)
{
m_connection = XGetXCBConnection(display);
m_notifier = new QSocketNotifier(xcb_get_file_descriptor(m_connection),
QSocketNotifier::Read, this);
xcb_query_extension_cookie_t inputExtCookie =
xcb_query_extension(m_connection, std::strlen(INAME), INAME);
QScopedPointer<xcb_query_extension_reply_t, QScopedPointerPodDeleter>
inputExt(xcb_query_extension_reply(m_connection, inputExtCookie, 0));
if (!inputExt) {
return;
}
m_inputOpcode = inputExt->major_opcode;
const xcb_setup_t *setup = xcb_get_setup(m_connection);
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
xcb_screen_t *screen = iter.data;
m_inputWindow = xcb_generate_id(m_connection);
xcb_create_window(m_connection, 0, m_inputWindow, screen->root, 0, 0, 1, 1,
0, XCB_WINDOW_CLASS_INPUT_ONLY, 0, 0, 0);
xcb_flush(m_connection);
XIEventMask masks[2];
unsigned char touchpadMask[] = { 0, 0, 0, 0 };
masks[0].deviceid = device;
masks[0].mask = touchpadMask;
masks[0].mask_len = sizeof(touchpadMask);
XISetMask(touchpadMask, XI_PropertyEvent);
unsigned char allMask[] = { 0, 0, 0, 0 };
masks[1].deviceid = XIAllDevices;
masks[1].mask = allMask;
masks[1].mask_len = sizeof(allMask);
XISetMask(allMask, XI_HierarchyChanged);
XISelectEvents(display, XDefaultRootWindow(display), masks,
sizeof(masks) / sizeof(XIEventMask));
XFlush(display);
connect(m_notifier, SIGNAL(activated(int)), SLOT(processEvents()));
m_notifier->setEnabled(true);
}
void XlibNotifications::processEvents()
{
while (XPending(m_display)) {
XEvent event;
XNextEvent(m_display, &event);
processEvent(&event);
}
}
struct XEventDataDeleter
{
XEventDataDeleter(Display *display, XGenericEventCookie *cookie)
: m_display(display), m_cookie(cookie)
{
XGetEventData(m_display, m_cookie);
}
~XEventDataDeleter()
{
if (m_cookie->data) {
XFreeEventData(m_display, m_cookie);
}
}
Display *m_display;
XGenericEventCookie *m_cookie;
};
void XlibNotifications::processEvent(XEvent *event)
{
if (event->xcookie.type != GenericEvent) {
return;
}
if (event->xcookie.extension != m_inputOpcode) {
return;
}
if (event->xcookie.evtype == XI_PropertyEvent) {
XEventDataDeleter helper(m_display, &event->xcookie);
if (!event->xcookie.data) {
return;
}
XIPropertyEvent *propEvent =
reinterpret_cast<XIPropertyEvent *>(event->xcookie.data);
Q_EMIT propertyChanged(propEvent->property);
} else if (event->xcookie.evtype == XI_HierarchyChanged) {
XEventDataDeleter helper(m_display, &event->xcookie);
if (!event->xcookie.data) {
return;
}
XIHierarchyEvent *hierarchyEvent =
reinterpret_cast<XIHierarchyEvent *>(event->xcookie.data);
for (uint16_t i = 0; i < hierarchyEvent->num_info; i++) {
if (hierarchyEvent->info[i].deviceid == m_device) {
if (hierarchyEvent->info[i].flags & XISlaveRemoved) {
Q_EMIT touchpadDetached();
return;
}
}
if (hierarchyEvent->info[i].use != XISlavePointer) {
continue;
}
if (hierarchyEvent->info[i].flags &
(XIDeviceEnabled | XIDeviceDisabled))
{
Q_EMIT devicePlugged(hierarchyEvent->info[i].deviceid);
}
}
}
}
XlibNotifications::~XlibNotifications()
{
xcb_destroy_window(m_connection, m_inputWindow);
xcb_flush(m_connection);
}
#include "moc_xlibnotifications.cpp"

View file

@ -1,54 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef XLIBNOTIFICATIONS_H
#define XLIBNOTIFICATIONS_H
#include <QtGui/qx11info_x11.h>
#include <QWidget>
#include <QSocketNotifier>
#include <xcb/xcb.h>
class XlibNotifications : public QObject
{
Q_OBJECT
public:
XlibNotifications(Display *display, int device);
~XlibNotifications();
Q_SIGNALS:
void propertyChanged(xcb_atom_t);
void devicePlugged(int);
void touchpadDetached();
private Q_SLOTS:
void processEvents();
private:
void processEvent(XEvent *);
Display *m_display;
xcb_connection_t *m_connection;
QSocketNotifier *m_notifier;
xcb_window_t m_inputWindow;
uint8_t m_inputOpcode;
int m_device;
};
#endif // XLIBNOTIFICATIONS_H

View file

@ -1,150 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "xrecordkeyboardmonitor.h"
#include <cstdlib>
#include <limits>
#include <QScopedPointer>
#include <xcb/xcbext.h>
#include <X11/Xlib.h>
XRecordKeyboardMonitor::XRecordKeyboardMonitor(Display *display)
: m_connection(xcb_connect(XDisplayString(display), 0)),
m_modifiersPressed(0), m_keysPressed(0)
{
if (!m_connection) {
return;
}
xcb_get_modifier_mapping_cookie_t modmapCookie =
xcb_get_modifier_mapping(m_connection);
m_context = xcb_generate_id(m_connection);
xcb_record_range_t range;
memset(&range, 0, sizeof(range));
range.device_events.first = XCB_KEY_PRESS;
range.device_events.last = XCB_KEY_RELEASE;
xcb_record_client_spec_t cs = XCB_RECORD_CS_ALL_CLIENTS;
xcb_record_create_context(m_connection, m_context, 0, 1, 1, &cs, &range);
xcb_flush(m_connection);
QScopedPointer<xcb_get_modifier_mapping_reply_t, QScopedPointerPodDeleter>
modmap(xcb_get_modifier_mapping_reply(m_connection, modmapCookie, 0));
if (!modmap) {
return;
}
int nModifiers = xcb_get_modifier_mapping_keycodes_length(modmap.data());
xcb_keycode_t *modifiers = xcb_get_modifier_mapping_keycodes(modmap.data());
m_modifier.fill(false, std::numeric_limits<xcb_keycode_t>::max() + 1);
for (xcb_keycode_t *i = modifiers; i < modifiers + nModifiers; i++) {
m_modifier[*i] = true;
}
m_ignore.fill(false, std::numeric_limits<xcb_keycode_t>::max() + 1);
for (xcb_keycode_t *i = modifiers;
i < modifiers + modmap->keycodes_per_modifier; i++)
{
m_ignore[*i] = true;
}
m_pressed.fill(false, std::numeric_limits<xcb_keycode_t>::max() + 1);
m_cookie = xcb_record_enable_context(m_connection, m_context);
xcb_flush(m_connection);
m_notifier = new QSocketNotifier(xcb_get_file_descriptor(m_connection),
QSocketNotifier::Read, this);
connect(m_notifier, SIGNAL(activated(int)), SLOT(processNextReply()));
m_notifier->setEnabled(true);
}
XRecordKeyboardMonitor::~XRecordKeyboardMonitor()
{
if (!m_connection) {
return;
}
xcb_record_disable_context(m_connection, m_context);
xcb_record_free_context(m_connection, m_context);
xcb_disconnect(m_connection);
}
void XRecordKeyboardMonitor::processNextReply()
{
xcb_generic_event_t *event;
while ((event = xcb_poll_for_event(m_connection))) {
std::free(event);
}
void *reply = 0;
while (xcb_poll_for_reply(m_connection, m_cookie.sequence, &reply, 0)) {
if (!reply) {
continue;
}
QScopedPointer<xcb_record_enable_context_reply_t, QScopedPointerPodDeleter>
data(reinterpret_cast<xcb_record_enable_context_reply_t*>(reply));
process(data.data());
}
}
void XRecordKeyboardMonitor::process(xcb_record_enable_context_reply_t *reply)
{
bool prevActivity = activity();
xcb_key_press_event_t *events = reinterpret_cast<xcb_key_press_event_t*>
(xcb_record_enable_context_data(reply));
int nEvents = xcb_record_enable_context_data_length(reply) /
sizeof(xcb_key_press_event_t);
bool wasActivity = prevActivity;
for (xcb_key_press_event_t *e = events; e < events + nEvents; e++) {
if (e->response_type != XCB_KEY_PRESS &&
e->response_type != XCB_KEY_RELEASE)
{
continue;
}
if (m_ignore[e->detail]) {
continue;
}
bool pressed = (e->response_type == XCB_KEY_PRESS);
if (m_pressed[e->detail] == pressed) {
continue;
}
m_pressed[e->detail] = pressed;
int &counter = m_modifier[e->detail] ? m_modifiersPressed :
m_keysPressed;
if (pressed) {
counter++;
} else {
counter--;
}
wasActivity = wasActivity || activity();
}
if (!prevActivity && activity()) {
Q_EMIT keyboardActivityStarted();
} else if (!activity() && wasActivity) {
Q_EMIT keyboardActivityFinished();
}
}

View file

@ -1,57 +0,0 @@
/*
* Copyright (C) 2013 Alexander Mezin <mezin.alexander@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef XRECORDKEYBOARDMONITOR_H
#define XRECORDKEYBOARDMONITOR_H
#include <QVector>
#include <QSocketNotifier>
#include <QtGui/qx11info_x11.h>
#include <xcb/xcb.h>
#include <xcb/record.h>
class XRecordKeyboardMonitor : public QObject
{
Q_OBJECT
public:
XRecordKeyboardMonitor(Display *display);
~XRecordKeyboardMonitor();
Q_SIGNALS:
void keyboardActivityStarted();
void keyboardActivityFinished();
private Q_SLOTS:
void processNextReply();
private:
void process(xcb_record_enable_context_reply_t *reply);
bool activity() const { return m_keysPressed && !m_modifiersPressed; }
QSocketNotifier *m_notifier;
xcb_connection_t *m_connection;
xcb_record_context_t m_context;
xcb_record_enable_context_cookie_t m_cookie;
QVector<bool> m_modifier, m_ignore, m_pressed;
int m_modifiersPressed, m_keysPressed;
};
#endif // XRECORDKEYBOARDMONITOR_H