Saya telah mencoba membuat tambalan yang tepat untuk bug ini. Ini adalah masalah pada kernel daripada dengan keyboard, meskipun dapat dikatakan bahwa keyboard berperilaku aneh. Pokoknya, tambalan dikirim ke daftar input linux untuk ditinjau tetapi belum ada komentar.
Ini seharusnya memperbaiki masalah yang disebutkan di sini dengan QPAD MK-85, tetapi masalah yang sama terjadi pada Corsair K70, Gigabyte Osmium, dan keyboard serupa lainnya. Jika Anda memiliki keyboard yang memiliki bug, alangkah baiknya Anda dapat menguji tambalan. Jika Anda mengujinya beri tahu saya apakah itu berfungsi dan juga keyboard apa yang Anda miliki, penting juga versi bahasa apa yang Anda gunakan, keyboard AS dan non-AS akan berperilaku berbeda. Perhatikan bahwa tombol garis miring terbalik pada keyboard AS akan memiliki label lain pada versi keyboard lainnya.
Ini email dari linux-input dengan tambalan:
http://article.gmane.org/gmane.linux.kernel.input/37583
Baiklah, saya berhasil menyusun retasan yang menyelesaikan masalah. Saya akan menulisnya di sini kalau-kalau ada yang mengalami masalah yang sama.
Pertama, jika Anda tidak tertarik mengutak-atik sumber kernel, Anda mungkin memiliki opsi lain:http://kbd-mangler.sourceforge.net/ - Saya tidak mengujinya, tetapi deskripsinya terlihat cukup menjanjikan. Ini memungkinkan Anda mengubah input sebelum diteruskan ke sistem.
Solusi saya adalah mengedit file driver/hid/hid-input.c. Di awal file saya menambahkan tiga definisi variabel baru;
static bool CODE43TRUE = 0; // If true, code43 has been pressed
static bool CODEXXTRUE = 0; // If true, any other key has been pressed
static int CODESKIP = 0; // Counter for skipping extra code43 events
Temukan fungsinya
void hidinput_hid_event
Di bagian bawah fungsi ini adalah
input_event(input, usage->type, usage->code, value);
Input adalah pengontrol, jenis mengacu pada jenis peristiwa (1 adalah penekanan tombol.. 2 adalah gerakan mouse?), kode adalah kode kunci dan nilainya adalah 0 untuk ditekan dan 1 untuk ditekan.
Setiap tombol ditekan, sistem HID berputar 4 kali melalui semua tombol keyboard. Mengapa melakukannya 4 kali saya tidak tahu, tetapi 4 sesuai dengan jumlah penekanan tombol ekstra yang saya dapatkan dengan kunci saya yang bermasalah. Pada loop pertama tombol yang ditekan memiliki nilai 0, pada loop kedua bernilai 1, dan pada loop ketiga dan keempat lagi bernilai 0.
Solusinya adalah memodifikasi fungsi ini sehingga tidak memungkinkan tombol yang bermasalah ditekan lagi saat tombol lain ditekan ATAU dalam 4 putaran dari penekanan tombol asli. Ini dicapai dengan kode berikut (Apakah saya menyebutkan bahwa saya belum membuat kode C setidaknya selama satu dekade? Maaf)
/* report the usage code as scancode if the key status has changed */
if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
input_event(input, EV_MSC, MSC_SCAN, usage->hid);
// NEW CODE STARTS HERE
if (usage->type == 1 && value == 1) // Keypress ahead
{
if (usage->code == 43) { // Keypress is code 43
if (CODE43TRUE == 0) { // Key not yet pressed
CODE43TRUE = 1;
printk(KERN_INFO "CODE43 SET TRUE\n");
}
else { // Key already pressed, so force value 1
printk(KERN_INFO "CODE43 ALREADY TRUE SET VALUE 1\n");
value = 0;
}
}
else { // Some other key pressed, set XX true
CODEXXTRUE = 1;
printk(KERN_INFO "CODEXX SET TRUE\n");
}
printk(KERN_INFO "Keypress type:%u code:%u value%d\n", (unsigned int) usage->type, (unsigned int) usage->code, (int) value);
}
if (usage->type == 1 && value == 0) { // Non-pressed key ahead
if (usage->code == 43) { // If its a 43
printk(KERN_INFO "43 call..\n");
if (CODE43TRUE == 1) { // And 43 is fake pressed still
if (CODEXXTRUE == 1 || CODESKIP < 4) { // If other buttons are pressed OR we are less than 5 ticks into the press..
printk(KERN_INFO "FAKE PRESS 43. CODESKIP %d\n",CODESKIP);
value = 0;
CODESKIP ++;
}
else { // No other buttons pressed and over five ticks have passed
printk(KERN_INFO "43 RELEASED\n");
CODE43TRUE = 0;
CODESKIP = 0;
}
}
// Reset the CODEXXTRUE (next time we get info about 43, we have looped through all the other keys so we know if something is pressed)
CODEXXTRUE = 0;
}
}
// NEW CODE ENDS HERE
input_event(input, usage->type, usage->code, value);
Jika Anda menerapkan ini, Anda mungkin ingin menghapus pernyataan printk setelah Anda memverifikasi bahwa itu berfungsi sebagaimana mestinya. Mereka hanya ada untuk membantu proses debug.