This option allows you to change the relationship" - " between the distance that the mouse pointer moves on the" - " screen and the relative movement of the physical device" - " itself (which may be a mouse, trackball, or some other" - " pointing device.)
" - " A high value for the acceleration will lead to large" - " movements of the mouse pointer on the screen even when" - " you only make a small movement with the physical device." - " Selecting very high values may result in the mouse pointer" - " flying across the screen, making it hard to control.
"); - accel->setWhatsThis(wtstr); - - thresh = new QSpinBox(advancedTab); - thresh->setRange(0, 20); - thresh->setSingleStep(1); - thresh->setValue(2); - thresh->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - formLayout->addRow(i18n("Pointer threshold:"), thresh); + connect(accel, SIGNAL(valueChanged(double)), this, SLOT(changed())); connect(thresh, SIGNAL(valueChanged(int)), this, SLOT(changed())); connect(thresh, SIGNAL(valueChanged(int)), this, SLOT(slotThreshChanged(int))); slotThreshChanged(thresh->value()); - wtstr = i18n("The threshold is the smallest distance that the" - " mouse pointer must move on the screen before acceleration" - " has any effect. If the movement is smaller than the threshold," - " the mouse pointer moves as if the acceleration was set to 1X;
" - " thus, when you make small movements with the physical device," - " there is no acceleration at all, giving you a greater degree" - " of control over the mouse pointer. With larger movements of" - " the physical device, you can move the mouse pointer" - " rapidly to different areas on the screen.
"); - thresh->setWhatsThis(wtstr); - // It would be nice if the user had a test field. // Selecting such values in milliseconds is not intuitive - doubleClickInterval = new QSpinBox(advancedTab); - doubleClickInterval->setRange(100, 2000); - doubleClickInterval->setSuffix(i18n(" msec")); - doubleClickInterval->setSingleStep(100); - doubleClickInterval->setValue(2000); - doubleClickInterval->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - formLayout->addRow(i18n("Double click interval:"), doubleClickInterval); connect(doubleClickInterval, SIGNAL(valueChanged(int)), this, SLOT(changed())); - wtstr = i18n("The double click interval is the maximal time" - " (in milliseconds) between two mouse clicks which" - " turns them into a double click. If the second" - " click happens later than this time interval after" - " the first click, they are recognized as two" - " separate clicks."); - doubleClickInterval->setWhatsThis(wtstr); - - dragStartTime = new QSpinBox(advancedTab); - dragStartTime->setRange(100, 2000); - dragStartTime->setSuffix(i18n(" msec")); - dragStartTime->setSingleStep(100); - dragStartTime->setValue(2000); - dragStartTime->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - formLayout->addRow(i18n("Drag start time:"), dragStartTime); connect(dragStartTime, SIGNAL(valueChanged(int)), this, SLOT(changed())); - wtstr = i18n("If you click with the mouse (e.g. in a multi-line" - " editor) and begin to move the mouse within the" - " drag start time, a drag operation will be initiated."); - dragStartTime->setWhatsThis(wtstr); - - dragStartDist = new QSpinBox(advancedTab); - dragStartDist->setRange(1, 20); - dragStartDist->setSingleStep(1); - dragStartDist->setValue(20); - dragStartDist->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - formLayout->addRow(i18n("Drag start distance:"), dragStartDist); connect(dragStartDist, SIGNAL(valueChanged(int)), this, SLOT(changed())); connect(dragStartDist, SIGNAL(valueChanged(int)), this, SLOT(slotDragStartDistChanged(int))); slotDragStartDistChanged(dragStartDist->value()); - wtstr = i18n("If you click with the mouse and begin to move the" - " mouse at least the drag start distance, a drag" - " operation will be initiated."); - dragStartDist->setWhatsThis(wtstr); - - wheelScrollLines = new QSpinBox(advancedTab); - wheelScrollLines->setRange(1, 12); - wheelScrollLines->setSingleStep(1); - wheelScrollLines->setValue(3); - wheelScrollLines->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - formLayout->addRow(i18n("Mouse wheel scrolls by:"), wheelScrollLines); connect(wheelScrollLines, SIGNAL(valueChanged(int)), this, SLOT(changed())); connect(wheelScrollLines, SIGNAL(valueChanged(int)), SLOT(slotWheelScrollLinesChanged(int))); slotWheelScrollLinesChanged(wheelScrollLines->value()); - wtstr = i18n("If you use the wheel of a mouse, this value determines the number" - " of lines to scroll for each wheel movement. Note that if this" - " number exceeds the number of visible lines, it will be ignored" - " and the wheel movement will be handled as a page up/down movement."); - wheelScrollLines->setWhatsThis(wtstr); - - QHBoxLayout *outerLayout = new QHBoxLayout(advancedTab); - outerLayout->addLayout(formLayout, 0); - outerLayout->addStretch(1); - - QWidget *keysTab = new QWidget(this); - keysTab->setObjectName("Mouse Navigation"); - tabwidget->addTab(keysTab, i18n("Keyboard Navigation")); - - formLayout = new QFormLayout; - formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); - - mouseKeys = new QCheckBox(i18n("&Move pointer with keyboard (using the num pad)"), keysTab); - formLayout->addRow(mouseKeys); - - mk_delay = new QSpinBox(keysTab); - mk_delay->setRange(1, 1000); - mk_delay->setSingleStep(50); - mk_delay->setSuffix(i18n(" msec")); - mk_delay->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - formLayout->addRow(i18n("&Acceleration delay:"), mk_delay); - - mk_interval = new QSpinBox(keysTab); - mk_interval->setRange(1, 1000); - mk_interval->setSingleStep(10); - mk_interval->setSuffix(i18n(" msec")); - mk_interval->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - formLayout->addRow(i18n("R&epeat interval:"), mk_interval); - - mk_time_to_max = new QSpinBox(keysTab); - mk_time_to_max->setRange(100, 10000); - mk_time_to_max->setSingleStep(200); - mk_time_to_max->setSuffix(i18n(" msec")); - mk_time_to_max->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - formLayout->addRow(i18n("Acceleration &time:"), mk_time_to_max); - - mk_max_speed = new QSpinBox(keysTab); - mk_max_speed->setRange(1, 2000); - mk_max_speed->setSingleStep(20); - mk_max_speed->setSuffix(i18n(" pixel/sec")); - mk_max_speed->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - formLayout->addRow(i18n("Ma&ximum speed:"), mk_max_speed); - - mk_curve = new QSpinBox(keysTab); - mk_curve->setRange(-1000, 1000); - mk_curve->setSingleStep(100); - mk_curve->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - formLayout->addRow(i18n("Acceleration &profile:"), mk_curve); - - outerLayout = new QHBoxLayout(keysTab); - outerLayout->addLayout(formLayout, 0); - outerLayout->addStretch(1); - connect(mouseKeys, SIGNAL(clicked()), this, SLOT(checkAccess())); connect(mouseKeys, SIGNAL(clicked()), this, SLOT(changed())); connect(mk_delay, SIGNAL(valueChanged(int)), this, SLOT(changed())); connect(mk_interval, SIGNAL(valueChanged(int)), this, SLOT(changed())); connect(mk_time_to_max, SIGNAL(valueChanged(int)), this, SLOT(changed())); connect(mk_max_speed, SIGNAL(valueChanged(int)), this, SLOT(changed())); connect(mk_curve, SIGNAL(valueChanged(int)), this, SLOT(changed())); settings = new MouseSettings; KAboutData* about = new KAboutData(QStringLiteral("kcmmouse"), i18n("Mouse"), QStringLiteral("1.0"), QString(), KAboutLicense::GPL, i18n("(c) 1997 - 2005 Mouse developers")); about->addAuthor(i18n("Patrick Dowler")); about->addAuthor(i18n("Dirk A. Mueller")); about->addAuthor(i18n("David Faure")); about->addAuthor(i18n("Bernd Gehrmann")); about->addAuthor(i18n("Rik Hemsley")); about->addAuthor(i18n("Brad Hughes")); about->addAuthor(i18n("Ralf Nolden")); about->addAuthor(i18n("Brad Hards")); setAboutData(about); } void MouseConfig::checkAccess() { mk_delay->setEnabled(mouseKeys->isChecked()); mk_interval->setEnabled(mouseKeys->isChecked()); mk_time_to_max->setEnabled(mouseKeys->isChecked()); mk_max_speed->setEnabled(mouseKeys->isChecked()); mk_curve->setEnabled(mouseKeys->isChecked()); } MouseConfig::~MouseConfig() { delete settings; } double MouseConfig::getAccel() { return accel->value(); } void MouseConfig::setAccel(double val) { accel->setValue(val); } int MouseConfig::getThreshold() { return thresh->value(); } void MouseConfig::setThreshold(int val) { thresh->setValue(val); } int MouseConfig::getHandedness() { - if (generalTab->rightHanded->isChecked()) + if (rightHanded->isChecked()) return RIGHT_HANDED; else return LEFT_HANDED; } void MouseConfig::setHandedness(int val) { - generalTab->rightHanded->setChecked(false); - generalTab->leftHanded->setChecked(false); + rightHanded->setChecked(false); + leftHanded->setChecked(false); if (val == RIGHT_HANDED) { - generalTab->rightHanded->setChecked(true); - generalTab->mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_rh.png")); + rightHanded->setChecked(true); + mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_rh.png")); } else { - generalTab->leftHanded->setChecked(true); - generalTab->mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_lh.png")); + leftHanded->setChecked(true); + mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_lh.png")); } settings->m_handedNeedsApply = true; } void MouseConfig::load() { KConfig config("kcminputrc"); settings->load(&config); - generalTab->rightHanded->setEnabled(settings->handedEnabled); - generalTab->leftHanded->setEnabled(settings->handedEnabled); - if (generalTab->cbScrollPolarity->isEnabled()) - generalTab->cbScrollPolarity->setEnabled(settings->handedEnabled); - generalTab->cbScrollPolarity->setChecked(settings->reverseScrollPolarity); + rightHanded->setEnabled(settings->handedEnabled); + leftHanded->setEnabled(settings->handedEnabled); + if (cbScrollPolarity->isEnabled()) + cbScrollPolarity->setEnabled(settings->handedEnabled); + cbScrollPolarity->setChecked(settings->reverseScrollPolarity); setAccel(settings->accelRate); setThreshold(settings->thresholdMove); setHandedness(settings->handed); doubleClickInterval->setValue(settings->doubleClickInterval); dragStartTime->setValue(settings->dragStartTime); dragStartDist->setValue(settings->dragStartDist); wheelScrollLines->setValue(settings->wheelScrollLines); - generalTab->singleClick->setChecked(settings->singleClick); - generalTab->doubleClick->setChecked(!settings->singleClick); + singleClick->setChecked(settings->singleClick); + doubleClick->setChecked(!settings->singleClick); KConfig ac("kaccessrc"); KConfigGroup group = ac.group("Mouse"); mouseKeys->setChecked(group.readEntry("MouseKeys", false)); mk_delay->setValue(group.readEntry("MKDelay", 160)); int interval = group.readEntry("MKInterval", 5); mk_interval->setValue(interval); // Default time to reach maximum speed: 5000 msec int time_to_max = group.readEntry("MKTimeToMax", (5000+interval/2)/interval); time_to_max = group.readEntry("MK-TimeToMax", time_to_max*interval); mk_time_to_max->setValue(time_to_max); // Default maximum speed: 1000 pixels/sec // (The old default maximum speed from KDE <= 3.4 // (100000 pixels/sec) was way too fast) long max_speed = group.readEntry("MKMaxSpeed", interval); max_speed = max_speed * 1000 / interval; if (max_speed > 2000) max_speed = 2000; max_speed = group.readEntry("MK-MaxSpeed", int(max_speed)); mk_max_speed->setValue(max_speed); mk_curve->setValue(group.readEntry("MKCurve", 0)); checkAccess(); emit changed(false); } void MouseConfig::save() { settings->accelRate = getAccel(); settings->thresholdMove = getThreshold(); settings->handed = getHandedness(); settings->doubleClickInterval = doubleClickInterval->value(); settings->dragStartTime = dragStartTime->value(); settings->dragStartDist = dragStartDist->value(); settings->wheelScrollLines = wheelScrollLines->value(); - settings->singleClick = !generalTab->doubleClick->isChecked(); - settings->reverseScrollPolarity = generalTab->cbScrollPolarity->isChecked(); + settings->singleClick = !doubleClick->isChecked(); + settings->reverseScrollPolarity = cbScrollPolarity->isChecked(); settings->apply(); KConfig config("kcminputrc"); settings->save(&config); KConfig ac("kaccessrc"); KConfigGroup group = ac.group("Mouse"); int interval = mk_interval->value(); group.writeEntry("MouseKeys", mouseKeys->isChecked()); group.writeEntry("MKDelay", mk_delay->value()); group.writeEntry("MKInterval", interval); group.writeEntry("MK-TimeToMax", mk_time_to_max->value()); group.writeEntry("MKTimeToMax", (mk_time_to_max->value() + interval/2)/interval); group.writeEntry("MK-MaxSpeed", mk_max_speed->value()); group.writeEntry("MKMaxSpeed", (mk_max_speed->value()*interval + 500)/1000); group.writeEntry("MKCurve", mk_curve->value()); group.sync(); // restart kaccess KToolInvocation::startServiceByDesktopName("kaccess"); emit changed(false); } void MouseConfig::defaults() { setThreshold(2); setAccel(2); setHandedness(RIGHT_HANDED); - generalTab->cbScrollPolarity->setChecked(false); + cbScrollPolarity->setChecked(false); doubleClickInterval->setValue(400); dragStartTime->setValue(500); dragStartDist->setValue(4); wheelScrollLines->setValue(3); - generalTab->doubleClick->setChecked(!KDE_DEFAULT_SINGLECLICK); - generalTab->singleClick->setChecked(KDE_DEFAULT_SINGLECLICK); + doubleClick->setChecked(!KDE_DEFAULT_SINGLECLICK); + singleClick->setChecked(KDE_DEFAULT_SINGLECLICK); mouseKeys->setChecked(false); mk_delay->setValue(160); mk_interval->setValue(5); mk_time_to_max->setValue(5000); mk_max_speed->setValue(1000); mk_curve->setValue(0); checkAccess(); changed(); } /** No descriptions */ void MouseConfig::slotHandedChanged(int val) { if (val==RIGHT_HANDED) - generalTab->mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_rh.png")); + mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_rh.png")); else - generalTab->mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_lh.png")); + mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_lh.png")); settings->m_handedNeedsApply = true; } void MouseSettings::load(KConfig *config, Display *dpy) { // TODO: what's a good threshold default value int threshold = 0; int h = RIGHT_HANDED; double accel = 1.0; if (QX11Info::isPlatformX11()) { int accel_num, accel_den; XGetPointerControl(dpy, &accel_num, &accel_den, &threshold); accel = float(accel_num) / float(accel_den); // get settings from X server unsigned char map[20]; num_buttons = XGetPointerMapping(dpy, map, 20); handedEnabled = true; // ## keep this in sync with KGlobalSettings::mouseSettings if (num_buttons == 1) { /* disable button remapping */ handedEnabled = false; } else if (num_buttons == 2) { if ((int)map[0] == 1 && (int)map[1] == 2) h = RIGHT_HANDED; else if ((int)map[0] == 2 && (int)map[1] == 1) h = LEFT_HANDED; else /* custom button setup: disable button remapping */ handedEnabled = false; } else { middle_button = (int)map[1]; if ((int)map[0] == 1 && (int)map[2] == 3) h = RIGHT_HANDED; else if ((int)map[0] == 3 && (int)map[2] == 1) h = LEFT_HANDED; else { /* custom button setup: disable button remapping */ handedEnabled = false; } } } else { // other platforms handedEnabled = true; } KConfigGroup group = config->group("Mouse"); double a = group.readEntry("Acceleration", -1.0); if (a == -1) accelRate = accel; else accelRate = a; int t = group.readEntry("Threshold", -1); if (t == -1) thresholdMove = threshold; else thresholdMove = t; QString key = group.readEntry("MouseButtonMapping"); if (key == "RightHanded") handed = RIGHT_HANDED; else if (key == "LeftHanded") handed = LEFT_HANDED; #ifdef __GNUC__ #warning was key == NULL how was this working? is key.isNull() what the coder meant? #endif else if (key.isNull()) handed = h; reverseScrollPolarity = group.readEntry("ReverseScrollPolarity", false); m_handedNeedsApply = false; // SC/DC/AutoSelect/ChangeCursor group = config->group("KDE"); doubleClickInterval = group.readEntry("DoubleClickInterval", 400); dragStartTime = group.readEntry("StartDragTime", 500); dragStartDist = group.readEntry("StartDragDist", 4); wheelScrollLines = group.readEntry("WheelScrollLines", 3); singleClick = group.readEntry("SingleClick", KDE_DEFAULT_SINGLECLICK); } void MouseConfig::slotThreshChanged(int value) { thresh->setSuffix(i18np(" pixel", " pixels", value)); } void MouseConfig::slotDragStartDistChanged(int value) { dragStartDist->setSuffix(i18np(" pixel", " pixels", value)); } void MouseConfig::slotWheelScrollLinesChanged(int value) { wheelScrollLines->setSuffix(i18np(" line", " lines", value)); } void MouseSettings::apply(bool force) { if (!QX11Info::isPlatformX11()) { return; } XChangePointerControl(QX11Info::display(), true, true, int(qRound(accelRate*10)), 10, thresholdMove); // 256 might seems extreme, but X has already been known to return 32, // and we don't want to truncate things. Xlib limits the table to 256 bytes, // so it's a good upper bound.. unsigned char map[256]; num_buttons = XGetPointerMapping(QX11Info::display(), map, 256); int remap=(num_buttons>=1); if (handedEnabled && (m_handedNeedsApply || force)) { if (num_buttons == 1) { map[0] = (unsigned char) 1; } else if (num_buttons == 2) { if (handed == RIGHT_HANDED) { map[0] = (unsigned char) 1; map[1] = (unsigned char) 3; } else { map[0] = (unsigned char) 3; map[1] = (unsigned char) 1; } } else // 3 buttons and more { if (handed == RIGHT_HANDED) { map[0] = (unsigned char) 1; map[1] = (unsigned char) middle_button; map[2] = (unsigned char) 3; } else { map[0] = (unsigned char) 3; map[1] = (unsigned char) middle_button; map[2] = (unsigned char) 1; } } int retval; if (remap) { while ((retval=XSetPointerMapping(QX11Info::display(), map, num_buttons)) == MappingBusy) /* keep trying until the pointer is free */ { }; } // apply reverseScrollPolarity Display *dpy = QX11Info::display(); Atom prop_wheel_emulation = XInternAtom(dpy, EVDEV_PROP_WHEEL, True); Atom prop_scroll_distance = XInternAtom(dpy, EVDEV_PROP_SCROLL_DISTANCE, True); Atom prop_wheel_emulation_axes = XInternAtom(dpy, EVDEV_PROP_WHEEL_AXES, True); int ndevices_return; XIDeviceInfo *info = XIQueryDevice(dpy, XIAllDevices, &ndevices_return); if (!info) { return; } for (int i = 0; i < ndevices_return; ++i) { if ((info + i)->use == XISlavePointer) { int deviceid = (info + i)->deviceid; Status status; Atom type_return; int format_return; unsigned long num_items_return; unsigned long bytes_after_return; unsigned char *data = nullptr; unsigned char *data2 = nullptr; //data returned is an 1 byte boolean status = XIGetProperty(dpy, deviceid, prop_wheel_emulation, 0, 1, False, XA_INTEGER, &type_return, &format_return, &num_items_return, &bytes_after_return, &data); if (status != Success) { continue; } // pointer device without wheel emulation if (type_return != XA_INTEGER || data == NULL || *data == False) { status = XIGetProperty(dpy, deviceid, prop_scroll_distance, 0, 3, False, XA_INTEGER, &type_return, &format_return, &num_items_return, &bytes_after_return, &data2); // negate scroll distance if (status == Success && type_return == XA_INTEGER && format_return == 32 && num_items_return == 3) { int32_t *vals = (int32_t*)data2; for (unsigned long i=0; i