diff --git a/kcms/input/main.cpp b/kcms/input/main.cpp --- a/kcms/input/main.cpp +++ b/kcms/input/main.cpp @@ -21,63 +21,54 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include +#include "klauncher_iface.h" +#include "mouse.h" -#include #include - -#include "mouse.h" #include -#include +#include +#include #include #ifdef HAVE_XCURSOR # include #endif -extern "C" +extern "C" Q_DECL_EXPORT void kcminit_mouse() { - Q_DECL_EXPORT void kcminit_mouse() - { - KConfig *config = new KConfig("kcminputrc", KConfig::NoGlobals ); - - Display *dpy = nullptr; - const bool platformX11 = QX11Info::isPlatformX11(); - if (platformX11) { - dpy = QX11Info::display(); - } else { - // let's hope we have a compatibility system like Xwayland ready - dpy = XOpenDisplay(nullptr); - } + KConfig config("kcminputrc", KConfig::NoGlobals); MouseSettings settings; - settings.load(config, dpy); + settings.load(&config); settings.apply(true); // force #ifdef HAVE_XCURSOR - KConfigGroup group = config->group("Mouse"); + // let's hope we have a compatibility system like Xwayland ready + Display *dpy = QX11Info::isPlatformX11() ? QX11Info::display() : XOpenDisplay(nullptr); + + KConfigGroup group = config.group("Mouse"); QString theme = group.readEntry("cursorTheme", QString()); QString size = group.readEntry("cursorSize", QString()); // Note: If you update this code, update kapplymousetheme as well. // use a default value for theme only if it's not configured at all, not even in X resources - if( theme.isEmpty() - && (!dpy || - (QByteArray( XGetDefault( dpy, "Xcursor", "theme" )).isEmpty() - && QByteArray( XcursorGetTheme( dpy)).isEmpty()))) + if (theme.isEmpty() + && (!dpy || + (QByteArray(XGetDefault(dpy, "Xcursor", "theme")).isEmpty() + && QByteArray(XcursorGetTheme(dpy)).isEmpty()))) { theme = "breeze_cursors"; } - // Apply the KDE cursor theme to ourselves + // Apply the KDE cursor theme to ourselves if (dpy) { - if( !theme.isEmpty()) + if(!theme.isEmpty()) XcursorSetTheme(dpy, QFile::encodeName(theme)); if (!size.isEmpty()) - XcursorSetDefaultSize(dpy, size.toUInt()); + XcursorSetDefaultSize(dpy, size.toInt()); // Load the default cursor from the theme and apply it to the root window. Cursor handle = XcursorLibraryLoadCursor(dpy, "left_ptr"); @@ -95,15 +86,9 @@ if( !size.isEmpty()) klauncher.setLaunchEnv(QStringLiteral("XCURSOR_SIZE"), size); -#endif - - if (!platformX11) { + if (!QX11Info::isPlatformX11()) { XFlush(dpy); XCloseDisplay(dpy); } - - delete config; - } +#endif } - - diff --git a/kcms/input/mouse.h b/kcms/input/mouse.h --- a/kcms/input/mouse.h +++ b/kcms/input/mouse.h @@ -28,18 +28,16 @@ */ -#ifndef __MOUSECONFIG_H__ -#define __MOUSECONFIG_H__ +#ifndef MOUSECONFIG_H +#define MOUSECONFIG_H #include -#include +#include -#include -#include "ui_kmousedlg.h" +#include "config-workspace.h" -#define RIGHT_HANDED 0 -#define LEFT_HANDED 1 +#include "ui_kmousedlg.h" class QCheckBox; class QDoubleSpinBox; @@ -50,32 +48,37 @@ class KMouseDlg : public QWidget, public Ui::KMouseDlg { public: - KMouseDlg( QWidget *parent ) : QWidget( parent ) { - setupUi( this ); - } + KMouseDlg(QWidget *parent); }; class MouseSettings { public: void save(KConfig *); - void load(KConfig *, Display *dpy = QX11Info::display()); + void load(KConfig *); void apply(bool force=false); public: + enum class Handedness : int + { + Right = 0, + Left = 1, + }; + int num_buttons; - int middle_button; + unsigned char middle_button; bool handedEnabled; - bool m_handedNeedsApply; - int handed; + bool handednessChanged; + Handedness handed; double accelRate; int thresholdMove; int doubleClickInterval; int dragStartTime; int dragStartDist; bool singleClick; int wheelScrollLines; bool reverseScrollPolarity; + bool scrollPolarityChanged; }; class MouseConfig : public KCModule @@ -100,11 +103,11 @@ private: double getAccel(); int getThreshold(); - int getHandedness(); + MouseSettings::Handedness getHandedness(); void setAccel(double); void setThreshold(int); - void setHandedness(int); + void setHandedness(MouseSettings::Handedness); QDoubleSpinBox *accel; QSpinBox *thresh; @@ -127,4 +130,3 @@ }; #endif - diff --git a/kcms/input/mouse.cpp b/kcms/input/mouse.cpp --- a/kcms/input/mouse.cpp +++ b/kcms/input/mouse.cpp @@ -47,42 +47,45 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "mouse.h" + +#include "config-workspace.h" + +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include #include #include #include +#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "mouse.h" - +#include #include #include #include #include #include -#include -#include -#include #undef Below #include "../migrationlib/kdelibs4config.h" K_PLUGIN_FACTORY(MouseConfigFactory, registerPlugin(); // mouse ) -K_EXPORT_PLUGIN(MouseConfigFactory("kcminput")) + +KMouseDlg::KMouseDlg(QWidget *parent) : QWidget( parent ) { + setupUi( this ); +} MouseConfig::MouseConfig(QWidget *parent, const QVariantList &args) : KCModule(parent, args) @@ -108,8 +111,8 @@ group = new QButtonGroup(generalTab); group->setExclusive(true); - group->addButton(generalTab->rightHanded,RIGHT_HANDED); - group->addButton(generalTab->leftHanded,LEFT_HANDED); + group->addButton(generalTab->rightHanded, static_cast(MouseSettings::Handedness::Right)); + group->addButton(generalTab->leftHanded, static_cast(MouseSettings::Handedness::Left)); connect(group, SIGNAL(buttonClicked(int)), this, SLOT(changed())); connect(group, SIGNAL(buttonClicked(int)), this, SLOT(slotHandedChanged(int))); @@ -138,8 +141,8 @@ connect(generalTab->singleClick, SIGNAL(clicked()), this, SLOT(changed())); // Only allow setting reversing scroll polarity if we have scroll buttons - unsigned char map[20]; - if (QX11Info::isPlatformX11() && XGetPointerMapping(QX11Info::display(), map, 20) >= 5) + unsigned char map[256]; + if (QX11Info::isPlatformX11() && XGetPointerMapping(QX11Info::display(), map, 256) >= 5) { generalTab->cbScrollPolarity->setEnabled(true); generalTab->cbScrollPolarity->show(); @@ -253,7 +256,13 @@ dragStartDist->setWhatsThis(wtstr); wheelScrollLines = new QSpinBox(advancedTab); - wheelScrollLines->setRange(1, 12); + wheelScrollLines->setRange(0, 12); + /* + * FIXME: wheelScrollLines = 0 allows user to disable scrolling in Qt/KDE apps, + * but not in apps that handle scrolling on their own (e.g. Google Chrome) + * which ignore the setting completely. + * This requires a separate solution (like changing scrolling distance or unmapping scroll buttons) + */ wheelScrollLines->setSingleStep(1); wheelScrollLines->setValue(3); wheelScrollLines->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); @@ -380,28 +389,27 @@ thresh->setValue(val); } - -int MouseConfig::getHandedness() +MouseSettings::Handedness MouseConfig::getHandedness() { if (generalTab->rightHanded->isChecked()) - return RIGHT_HANDED; + return MouseSettings::Handedness::Right; else - return LEFT_HANDED; + return MouseSettings::Handedness::Left; } -void MouseConfig::setHandedness(int val) +void MouseConfig::setHandedness(MouseSettings::Handedness val) { generalTab->rightHanded->setChecked(false); generalTab->leftHanded->setChecked(false); - if (val == RIGHT_HANDED) { + if (val == MouseSettings::Handedness::Right) { generalTab->rightHanded->setChecked(true); - generalTab->mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_rh.png")); + generalTab->mousePix->setPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kcminput/pics/mouse_rh.png")); } else { generalTab->leftHanded->setChecked(true); - generalTab->mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_lh.png")); + generalTab->mousePix->setPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kcminput/pics/mouse_lh.png")); } - settings->m_handedNeedsApply = true; + settings->handednessChanged = true; } void MouseConfig::load() @@ -499,7 +507,7 @@ { setThreshold(2); setAccel(2); - setHandedness(RIGHT_HANDED); + setHandedness(MouseSettings::Handedness::Right); generalTab->cbScrollPolarity->setChecked(false); doubleClickInterval->setValue(400); dragStartTime->setValue(500); @@ -522,28 +530,30 @@ /** No descriptions */ void MouseConfig::slotHandedChanged(int val) { - if (val==RIGHT_HANDED) - generalTab->mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_rh.png")); + if (val == static_cast(MouseSettings::Handedness::Right)) + generalTab->mousePix->setPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kcminput/pics/mouse_rh.png")); else - generalTab->mousePix->setPixmap(KStandardDirs::locate("data", "kcminput/pics/mouse_lh.png")); - settings->m_handedNeedsApply = true; + generalTab->mousePix->setPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kcminput/pics/mouse_lh.png")); + settings->handednessChanged = true; } -void MouseSettings::load(KConfig *config, Display *dpy) +void MouseSettings::load(KConfig *config) { // TODO: what's a good threshold default value int threshold = 0; - int h = RIGHT_HANDED; + Handedness h = Handedness::Right; double accel = 1.0; if (QX11Info::isPlatformX11()) { - int accel_num, accel_den; + auto display = QX11Info::display(); + int accel_num = 1; + int accel_den = 1; - XGetPointerControl(dpy, &accel_num, &accel_den, &threshold); - accel = float(accel_num) / float(accel_den); + XGetPointerControl(display, &accel_num, &accel_den, &threshold); + accel = static_cast(accel_num) / accel_den; // get settings from X server - unsigned char map[20]; - num_buttons = XGetPointerMapping(dpy, map, 20); + unsigned char map[256]; + num_buttons = XGetPointerMapping(display, map, 256); handedEnabled = true; @@ -555,25 +565,25 @@ } 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; + if (map[0] == 1 && map[1] == 2) + h = Handedness::Right; + else if (map[0] == 2 && map[1] == 1) + h = Handedness::Left; 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; + middle_button = map[1]; + if (map[0] == 1 && map[2] == 3) + h = Handedness::Right; + else if (map[0] == 3 && map[2] == 1) + h = Handedness::Left; else { - /* custom button setup: disable button remapping */ - handedEnabled = false; + /* custom button setup: disable button remapping */ + handedEnabled = false; } } } else { @@ -596,16 +606,14 @@ QString key = group.readEntry("MouseButtonMapping"); if (key == "RightHanded") - handed = RIGHT_HANDED; + handed = Handedness::Right; 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 + handed = Handedness::Left; else if (key.isNull()) handed = h; reverseScrollPolarity = group.readEntry("ReverseScrollPolarity", false); - m_handedNeedsApply = false; + handednessChanged = false; + scrollPolarityChanged = false; // SC/DC/AutoSelect/ChangeCursor group = config->group("KDE"); @@ -637,60 +645,59 @@ if (!QX11Info::isPlatformX11()) { return; } - XChangePointerControl(QX11Info::display(), - true, true, int(qRound(accelRate*10)), 10, thresholdMove); + + const auto dpy = QX11Info::display(); + XChangePointerControl(dpy, + true, true, 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); + num_buttons = XGetPointerMapping(dpy, 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 (num_buttons > 1 + && handedEnabled + && (handednessChanged || force)) { + if (num_buttons == 2) { - if (handed == RIGHT_HANDED) + if (handed == Handedness::Right) { - map[0] = (unsigned char) 1; - map[1] = (unsigned char) 3; + map[0] = 1; + map[1] = 2; } else { - map[0] = (unsigned char) 3; - map[1] = (unsigned char) 1; + map[0] = 2; + map[1] = 1; } } else // 3 buttons and more { - if (handed == RIGHT_HANDED) + if (handed == Handedness::Right) { - map[0] = (unsigned char) 1; - map[1] = (unsigned char) middle_button; - map[2] = (unsigned char) 3; + map[0] = 1; + map[1] = middle_button; + map[2] = 3; } else { - map[0] = (unsigned char) 3; - map[1] = (unsigned char) middle_button; - map[2] = (unsigned char) 1; + map[0] = 3; + map[1] = middle_button; + map[2] = 1; } } - int retval; - if (remap) { - while ((retval=XSetPointerMapping(QX11Info::display(), map, - num_buttons)) == MappingBusy) - /* keep trying until the pointer is free */ - { }; - } + while (XSetPointerMapping(dpy, map, + num_buttons) == MappingBusy) + /* keep trying until the pointer is free */ + { }; + + handednessChanged = false; + } + if (scrollPolarityChanged || force) { // 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); @@ -719,13 +726,13 @@ } // pointer device without wheel emulation - if (type_return != XA_INTEGER || data == NULL || *data == False) { + if (type_return != XA_INTEGER || data == nullptr || *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) { + format_return == 32 && num_items_return == 3) { int32_t *vals = (int32_t*)data2; for (unsigned long i=0; im_handedNeedsApply = true; + settings->scrollPolarityChanged = true; } #include "mouse.moc"