diff --git a/src/daemon/command.c b/src/daemon/command.c index 69a05dc0..8e279a0c 100644 --- a/src/daemon/command.c +++ b/src/daemon/command.c @@ -256,7 +256,7 @@ int readcmd(usbdevice* kb, const char* line){ continue; case POLLRATE: { uint rate; - if(sscanf(word, "%u", &rate) == 1 && (rate == 1 || rate == 2 || rate == 4 || rate == 8)) + if(HAS_FEATURES(kb, FEAT_ADJRATE) && sscanf(word, "%u", &rate) == 1 && (rate == 1 || rate == 2 || rate == 4 || rate == 8)) TRY_WITH_RESET(vt->pollrate(kb, mode, notifynumber, rate, 0)); continue; } diff --git a/src/daemon/device_mouse.c b/src/daemon/device_mouse.c index 36f6f541..e76fac4e 100644 --- a/src/daemon/device_mouse.c +++ b/src/daemon/device_mouse.c @@ -33,9 +33,6 @@ int cmd_pollrate_legacy(usbdevice* kb, usbmode* dummy1, int dummy2, int rate, co (void)dummy2; (void)dummy3; - if(rate > 1 && (rate % 2 || rate > 8)) - return 0; - usbsend_control(kb, NULL, 0, 10, rate, 0); // Device should disconnect+reconnect, but update the poll rate field in case it doesn't diff --git a/src/daemon/device_vtable.c b/src/daemon/device_vtable.c index bee5d6c9..196f7623 100644 --- a/src/daemon/device_vtable.c +++ b/src/daemon/device_vtable.c @@ -53,7 +53,7 @@ const devcmd vtable_keyboard = { .hwload = cmd_hwload_kb, .hwsave = cmd_hwsave_kb, .fwupdate = cmd_fwupdate, - .pollrate = cmd_io_none, + .pollrate = cmd_pollrate, .active = cmd_active_kb, .idle = cmd_idle_kb, diff --git a/src/daemon/usb.c b/src/daemon/usb.c index 0aded716..11882920 100644 --- a/src/daemon/usb.c +++ b/src/daemon/usb.c @@ -331,8 +331,10 @@ static void* _setupusb(void* context){ ushort vendor = kb->vendor, product = kb->product; const devcmd* vt = kb->vtable = get_vtable(vendor, product); kb->features = (IS_LEGACY(vendor, product) ? FEAT_STD_LEGACY : FEAT_STD_RGB) & features_mask; - if(IS_MOUSE(vendor, product)) kb->features |= FEAT_ADJRATE; - if(IS_MONOCHROME(vendor, product)) kb->features |= FEAT_MONOCHROME; + if(SUPPORTS_ADJRATE(kb)) + kb->features |= FEAT_ADJRATE; + if(IS_MONOCHROME(vendor, product)) + kb->features |= FEAT_MONOCHROME; kb->usbdelay = USB_DELAY_DEFAULT; /// Allocate memory for the os_usbrecv() buffer diff --git a/src/daemon/usb.h b/src/daemon/usb.h index 9eadbfef..c091abdb 100644 --- a/src/daemon/usb.h +++ b/src/daemon/usb.h @@ -195,6 +195,9 @@ const char* product_str(ushort product); /// Used for devices that use a file-based hardware animation system. #define USES_FILE_HWSAVE(kb) ((kb)->product == P_K95_PLATINUM || (kb)->product == P_K70_MK2 || (kb)->product == P_K70_MK2SE || (kb)->product == P_STRAFE_MK2 || (kb)->product == P_GLAIVE || (kb)->product == P_SCIMITAR_PRO || (kb)->product == P_K70_MK2LP || (kb)->product == P_M65_RGB_ELITE) +/// Devices here support setting the pollrate through software +#define SUPPORTS_ADJRATE(kb) ((kb)->product == P_K63_NRGB || (kb)->product == P_K66 || (kb)->product == P_K68 || (kb)->product == P_K68_NRGB || (kb)->product == P_K70_MK2 || (kb)->product == P_K70_MK2SE || (kb)->product == P_K70_MK2LP || (kb)->product == P_K95_PLATINUM || (kb)->product == P_STRAFE || (kb)->product == P_STRAFE_NRGB || (kb)->product == P_STRAFE_NRGB_2 || (kb)->product == P_STRAFE_MK2 || (kb)->product == P_M65 || (kb)->product == P_M65_PRO || (kb)->product == P_M65_RGB_ELITE || (kb)->product == P_M95 || (kb)->product == P_SABRE_O || (kb)->product == P_SABRE_L || (kb)->product == P_SABRE_N || (kb)->product == P_SABRE_O2 || (kb)->product == P_SCIMITAR || (kb)->product == P_SCIMITAR_PRO || (kb)->product == P_HARPOON || (kb)->product == P_GLAIVE || (kb)->product == P_KATAR) + /// USB delays for when the keyboards get picky about timing /// That was the original comment, but it is used anytime. diff --git a/src/gui/kb.cpp b/src/gui/kb.cpp index b708d6b2..ba140b4a 100644 --- a/src/gui/kb.cpp +++ b/src/gui/kb.cpp @@ -17,7 +17,7 @@ int Kb::_frameRate = 30, Kb::_scrollSpeed = 0; bool Kb::_dither = false, Kb::_mouseAccel = true, Kb::_delay = false; Kb::Kb(QObject *parent, const QString& path) : - QThread(parent), features("N/A"), firmware("N/A"), pollrate("N/A"), monochrome(false), hwload(false), + QThread(parent), features("N/A"), firmware("N/A"), pollrate("N/A"), monochrome(false), hwload(false), adjrate(false), devpath(path), cmdpath(path + "/cmd"), notifyPath(path + "/notify1"), macroPath(path + "/notify2"), _currentProfile(0), _currentMode(0), _model(KeyMap::NO_MODEL), lastAutoSave(QDateTime::currentMSecsSinceEpoch()), @@ -80,6 +80,8 @@ Kb::Kb(QObject *parent, const QString& path) : pollrate = ppath.read(100); pollrate = pollrate.trimmed(); ppath.close(); + if(features.contains("adjrate")) + adjrate = true; } if(hwlayoutPath.open(QIODevice::ReadOnly)){ @@ -834,3 +836,8 @@ void Kb::macroDelay(bool flag) { KeyMap::Layout Kb::getCurrentLayout(){ return _layout; } + +void Kb::setPollRate(QString poll) +{ + cmd.write(QString("\npollrate %1\n").arg(poll).toLatin1()); +} diff --git a/src/gui/kb.h b/src/gui/kb.h index b37aed0b..38bdee8d 100644 --- a/src/gui/kb.h +++ b/src/gui/kb.h @@ -19,6 +19,7 @@ public: bool monochrome; ushort productID; bool hwload; + bool adjrate; // Keyboard model inline KeyMap::Model model() const { return _model; } @@ -115,6 +116,7 @@ public: inline QString getMacroPath () { return macroPath; } inline ushort getMaxDpi () {return _maxDpi; } + void setPollRate(QString poll); ~Kb(); diff --git a/src/gui/kbwidget.cpp b/src/gui/kbwidget.cpp index 0bcd90bb..d55681be 100644 --- a/src/gui/kbwidget.cpp +++ b/src/gui/kbwidget.cpp @@ -57,7 +57,7 @@ KbWidget::KbWidget(QWidget *parent, Kb *_device) : // Hide poll rate and FW update as appropriate if(!device->features.contains("pollrate")){ - ui->pollLabel->hide(); + ui->pollRateBox->hide(); ui->pollLabel2->hide(); } if(!device->features.contains("fwupdate")){ @@ -135,6 +135,11 @@ KbWidget::KbWidget(QWidget *parent, Kb *_device) : // Set max DPI for mice if(device->isMouse()) ui->mPerfWidget->setMaxDpi(device->getMaxDpi()); + + if(!device->adjrate){ + ui->pollRateBox->setEnabled(false); + ui->pollRateBox->setToolTip(tr("This device does not support setting the poll rate through software.")); + } } KbWidget::~KbWidget(){ @@ -379,12 +384,29 @@ void KbWidget::on_modesList_customContextMenuRequested(const QPoint &pos){ } } +inline int KbWidget::getPollRateBoxIdx(QString poll){ + switch(poll.leftRef(1).toInt()){ + case 1: + return 0; + case 2: + return 1; + case 4: + return 2; + default: // Includes case 8 + return 3; + } +} + void KbWidget::devUpdate(){ // Update device tab ui->devLabel->setText(device->usbModel); ui->serialLabel->setText(device->usbSerial); ui->fwLabel->setText(device->firmware); - ui->pollLabel->setText(device->pollrate); + // This is needed so that the currentIndexChanged event doesn't fire + // If it does, we'll end up with an always greyed out box when pollrate != 1 + bool block = ui->pollRateBox->blockSignals(true); + ui->pollRateBox->setCurrentIndex(getPollRateBoxIdx(device->pollrate)); + ui->pollRateBox->blockSignals(block); } void KbWidget::modeUpdate(){ @@ -510,3 +532,9 @@ void KbWidget::switchToMode(QString mode){ return; } } + +void KbWidget::on_pollRateBox_currentIndexChanged(const QString &arg1) +{ + ui->pollRateBox->setEnabled(false); + device->setPollRate(arg1.left(1)); +} diff --git a/src/gui/kbwidget.h b/src/gui/kbwidget.h index 40fa2cb8..14f7b0c6 100644 --- a/src/gui/kbwidget.h +++ b/src/gui/kbwidget.h @@ -45,6 +45,7 @@ private: const static int GUID = Qt::UserRole; const static int NEW_FLAG = Qt::UserRole + 1; + int getPollRateBoxIdx(QString poll); private slots: void updateProfileList(); @@ -69,6 +70,7 @@ private slots: void on_layoutBox_activated(int index); void switchToProfile(QString profile); void switchToMode(QString mode); + void on_pollRateBox_currentIndexChanged(const QString &arg1); }; #endif // KBWIDGET_H diff --git a/src/gui/kbwidget.ui b/src/gui/kbwidget.ui index 84426fe1..455ecf02 100644 --- a/src/gui/kbwidget.ui +++ b/src/gui/kbwidget.ui @@ -194,47 +194,8 @@ 6 - - - - - 0 - 34 - - - - Poll rate: - - - - - - - - 0 - 34 - - - - Firmware version: - - - - - - - - 0 - 0 - - - - Qt::Horizontal - - - - - + + IBeamCursor @@ -262,35 +223,17 @@ - - - - - - Check for updates - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - + + + + IBeamCursor + N/A + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + @@ -306,19 +249,6 @@ - - - - - 0 - 34 - - - - Status: - - - @@ -332,16 +262,23 @@ - - - - IBeamCursor - + + - N/A + Layout: - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + 0 + 0 + + + + Qt::Horizontal @@ -414,13 +351,119 @@ - - + + + + + 0 + 34 + + - Layout: + Status: + + + + + 0 + 34 + + + + Firmware version: + + + + + + + + + Check for updates + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 34 + + + + Poll rate: + + + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + + 1 ms + + + + + 2 ms + + + + + 4 ms + + + + + 8 ms + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -469,11 +512,6 @@ - - RListWidget - QListWidget -
rlistwidget.h
-
KbLightWidget QWidget @@ -498,6 +536,16 @@
kperfwidget.h
1
+ + RListWidget + QListWidget +
rlistwidget.h
+
+ + NoWheelComboBox + QComboBox +
nowheelcombobox.h
+