Bagaimana membuat semua aplikasi menghargai tata letak xkb saya yang dimodifikasi?

15

Saya tidak suka melompat di antara keyboard utama dan tombol gerakan, jadi saya menambahkan yang berikut ini ke file layout xkb saya.

hidden partial xkb_symbols "movement"
{
    key <AD08> { [ NoSymbol, NoSymbol, Up,          Up          ] };
    key <AC08> { [ NoSymbol, NoSymbol, Down,        Down        ] };
    key <AC07> { [ NoSymbol, NoSymbol, Left,        Left        ] };
    key <AC09> { [ NoSymbol, NoSymbol, Right,       Right       ] };
    key <AD09> { [ NoSymbol, NoSymbol, Prior,       Prior       ] };
    key <AB09> { [ NoSymbol, NoSymbol, Next,        Next        ] };
    key <AB07> { [ NoSymbol, NoSymbol, Home,        Home        ] };
    key <AB08> { [ NoSymbol, NoSymbol, End,         End         ] };
    key <AC06> { [ NoSymbol, NoSymbol, Delete,      Delete      ] };
}

Lalu saya memasukkan ini ke tata letak di titik kemudian dalam file. Sekarang saya harus memiliki tombol kursor yang dapat diakses melalui AltGr + j, k, l, i (atau h, t, n, c karena saya menggunakan dvorak) dll. Ini berfungsi dalam banyak kasus (seperti Firefox, urxvt, Eclipse, area teks utama LyX) tetapi beberapa program tidak melakukan apa pun ketika saya mencoba, katakanlah, memindahkan kursor menggunakan "pintasan" ini (seperti dialog NetBeans dan LyX).

Jadi, adakah cara untuk membuat program-program lain ini juga menghargai keinginan saya? Dan mengapa mereka tidak bekerja sejak awal? Saya tidak menggunakan DE; hanya WM yang mengagumkan.

Edit:

  • Berikut ini adalah file layout keyboard yang lengkap namun disederhanakan. Saya memiliki ini /usr/share/X11/xkb/symbols/nonpopdan saya memuatnya setxkbmap nonpop.
  • Saya perhatikan bahwa di MonoDevelop bergerak di sekitar pekerjaan tetapi memilih tidak. Yaitu, jika saya menekan Shift + Kanan maka teks dipilih seperti biasa, tetapi jika saya menekan AltGr + Shift + n maka kursor hanya bergerak tanpa memilih. Sebagai contoh di Firefox kedua cara dapat digunakan untuk memilih.
  • Di sini pada akhirnya mereka berbicara tentang overlay yang terlihat seperti sesuatu yang mungkin bisa menjadi solusi, tetapi saya belum menemukan cara menggunakannya.
nonpop
sumber
1
Saya tidak punya solusi, tetapi jika Anda tidak berhasil mendapatkan jawaban terlepas dari karunia yang Anda masukkan, Anda dapat mencoba bertanya di unix.SE , situs Stackexchange yang lebih berpusat pada Unix / Linux.
Glutanimate

Jawaban:

16

Kenapa mereka tidak bekerja?

Menurut artikel ArchWiki yang Anda sebutkan:

  • Server X mendapatkan kode kunci dari perangkat input dan mengubahnya menjadi status dan kunci .

    • state adalah bitmask dari pengubah X (Ctrl / Shift / etc).

    • keysym adalah (menurut /usr/include/X11/keysymdef.h) bilangan bulat itu

      mengidentifikasi karakter atau fungsi yang terkait dengan setiap tombol (misalnya, melalui ukiran yang terlihat) dari tata letak keyboard.

      Setiap karakter dicetak memiliki Keysym sendiri, seperti plus, a, A, atau Cyrillic_a, tetapi kunci lain juga menghasilkan Keysyms mereka, seperti Shift_L, Leftatau F1.

  • Aplikasi dalam acara pers / pelepasan kunci mendapatkan semua informasi ini.

    Beberapa aplikasi melacak keyyms seperti Control_Lsendiri, yang lain hanya mencari bit pengubah di negara bagian .

Jadi apa yang terjadi, ketika Anda menekan AltGr+ j:

  • Anda menekan AltGr. Aplikasi mendapat acara KeyPressed dengan kode kunci 108 ( <RALT>) dan keysym 0xfe03 ( ISO_Level3_Shift), menyatakan 0.

  • Anda menekan j(yang memetakan ke "h" di dvorak tanpa pengubah). Aplikasi mendapat acara KeyPressed dengan kode kunci 44 ( <AC07>), keysym 0xff51 ( Left) dan status 0x80 (modifier Mod5 aktif).

  • Anda lepaskan j. Aplikasi mendapat acara KeyRelease untuk kunci <AC07>/ Leftdengan parameter yang sama.

  • Kemudian lepaskan AltGr- acara KeyRelease untuk AltGr. (Omong-omong, keadaan di sini masih 0x80, tapi itu tidak masalah.)

Ini bisa dilihat jika Anda menjalankan xevutilitas.

Jadi, itu semua berarti bahwa, meskipun aplikasi mendapatkan kode keysym yang sama ( Left) seperti dari tombol normal <LEFT>, ia juga mendapatkan kode keysym dan status pengubah dari AltGr. Kemungkinan besar, program-program yang tidak berfungsi, menonton modifikator dan tidak ingin bekerja ketika beberapa aktif.

Cara membuatnya bekerja

Tampaknya, kami tidak dapat mengubah setiap program untuk tidak mencari pengubah. Maka satu-satunya pilihan untuk keluar dari situasi ini adalah untuk tidak menghasilkan kunci pengubah dan bit negara.

1. Kelompok terpisah

Satu-satunya metode yang datang ke pikiran saya adalah: mendefinisikan kunci gerakan kursor dalam kelompok dan saklar yang terpisah, dengan tekan tombol terpisah, untuk kelompok yang sebelum menekan tombol j, k, l, i( h, t, n, c) (kelompok menempel adalah metode yang disukai untuk satu kali perubahan grup, seperti yang saya mengerti).

Sebagai contoh:

xkb_keymap {
    xkb_keycodes { include "evdev+aliases(qwerty)" };
    xkb_types { include "complete" };
    xkb_compatibility {
        include "complete"

        interpret ISO_Group_Latch { action = LatchGroup(group=2); };
    };
    xkb_symbols {
        include "pc+us(dvorak)+inet(evdev)"

        key <RALT> { [ ISO_Group_Latch ] };

        key <AC07> {
            type[Group2] = "ONE_LEVEL",
            symbols[Group2] = [ Left ]
        };
        key <AC08> {
            type[Group2] = "ONE_LEVEL",
            symbols[Group2] = [ Down ]
        };
        key <AC09> {
            type[Group2] = "ONE_LEVEL",
            symbols[Group2] = [ Right ]
        };
        key <AD08> {
            type[Group2] = "ONE_LEVEL",
            symbols[Group2] = [ Up ]
        };
    };
    xkb_geometry { include "pc(pc104)" };
};

Sekarang, jika Anda pertama kali menekan AltGrdan kemudian (secara terpisah) salah satu tombol gerakan, ini akan berfungsi.

Namun, ini tidak terlalu berguna, lebih tepat LockGroup daripada kait dan tekan AltGr sebelum dan sesudah beralih kelompok. Bahkan mungkin lebih baik untuk SetGroup- maka AltGr akan memilih grup itu hanya ketika sedang ditekan, tetapi yang mengungkapkan ke aplikasi keysym AltGr ( ISO_Group_Shift/ ISO_Group_Latch/ apa pun yang didefinisikan) (tetapi negara pengubah tetap bersih).

Tapi ... ada juga kemungkinan bahwa aplikasi tersebut juga membaca kode kunci (kode dari kunci asli). Maka akan terlihat kunci kursor "palsu".

2. Hamparan

Solusi "tingkat rendah" yang lebih banyak adalah overlay (seperti yang dijelaskan artikel yang sama ).

Overlay berarti bahwa beberapa (keyboard nyata) kunci mengembalikan kode kunci tombol lain. Server X mengubah kode kunci dan menghitung status pengubah dan kode kunci untuk kode kunci baru tersebut, sehingga aplikasi tidak akan memperhatikan perubahan tersebut.

Namun overlay sangat terbatas:

  • Hanya ada 2 bit kontrol overlay di server X (yaitu maksimum 2 overlay).
  • Setiap kunci hanya dapat memiliki 1 kode kunci alternatif.

Adapun sisanya, implementasi sangat mirip dengan metode dengan grup terpisah:

xkb_keymap {
    xkb_keycodes { include "evdev+aliases(qwerty)" };
    xkb_types { include "complete" };
    xkb_compatibility {
        include "complete"

        interpret Overlay1_Enable {
            action = SetControls(controls=overlay1);
        };
    };
    xkb_symbols {
        include "pc+us(dvorak)+inet(evdev)"

        key <RALT> {
            type[Group1] = "ONE_LEVEL",
            symbols[Group1] = [ Overlay1_Enable ]
        };
        key <AC07> { overlay1 = <LEFT> };
        key <AC08> { overlay1 = <DOWN> };
        key <AC09> { overlay1 = <RGHT> };
        key <AD08> { overlay1 = <UP> };
    };
    xkb_geometry { include "pc(pc104)" };
};

SetControlsberarti mengubah bit kontrol saat tombol ditekan dan mengembalikannya pada rilis kunci. Seharusnya ada fungsi yang serupa LatchControls, tetapi xkbcompmemberi saya

Error:            Unknown action LatchControls

pada kompilasi keymap.

(Ngomong-ngomong, saya juga menggunakan dvorak dan juga telah memetakan kembali beberapa tombol gerakan ke tingkat tinggi dari tombol alfabet. Dan juga menemukan beberapa fungsi yang rusak (pemilihan catatan Xfce dan pergantian desktop dengan Ctrl-Alt-Kiri / Kanan). Terima kasih kepada pertanyaan Anda dan jawaban ini, sekarang saya tahu apa itu overlay :).)

Chel
sumber
Terima kasih! Saya sebenarnya mendapat jawaban lain di unix.se yang pada awalnya tampak sempurna tetapi ternyata beberapa aplikasi masih melakukan kesalahan. Solusi ini (overlay) berfungsi dalam kasus-kasus itu juga.
nonpop
Saya hanya memperhatikan bahwa google chrom [e | ium] juga tidak peduli! :( Untungnya saya tidak terlalu menggunakannya.
nonpop
@nonpop goddamn chromium ... Saya telah menambahkan pembaruan ke balasan saya superuser.com/a/1000320/521612
Aleks-Daniel Jakimenko
Luar biasa! Saya sudah mencari ini selama bertahun-tahun! Masih ada masalah kecil dengan Chromium yang mengartikan penekanan tombol Overlay1_Enable. Saya memiliki gejala yang sama seperti di sini: github.com/GalliumOS/galliumos-distro/issues/362
Tarrasch
1
Saya baru saja berhasil memperbaiki masalah di atas. Tombol panah baris beranda saya sekarang juga berfungsi di Chromium! Saya membutuhkan perubahan berikut untuk jawaban ini. gist.github.com/Tarrasch/1293692/…
Tarrasch
4

Saya memiliki masalah yang sama. Sangat menyakitkan.

Jadi judulnya adalah "Bagaimana membuat semua aplikasi menghargai tata letak xkb yang dimodifikasi?" Yah, saya pikir satu-satunya cara adalah memperbaiki semua program yang melakukannya secara tidak benar. Ayo lakukan itu!

Nah, setelah melaporkan bug itu di NetBeans ( Pembaruan: Saya sudah mencoba versi terbaru dan berfungsi sekarang! ), Saya pikir saya akan terus melaporkan bug ini untuk setiap aplikasi. Aplikasi berikutnya dalam daftar adalah Speedcrunch .

Namun, setelah mencari laporan bug serupa saya menemukan masalah ini . Orang lain mengalami masalah yang sama, hebat!

Setelah membaca komentar, Anda akan memahami bahwa bug ini harus ada di semua aplikasi QT. Berikut ini adalah laporan bug QT . Tidak diselesaikan, tetapi sepertinya masalah ini diselesaikan di Qt5 .

Namun, jika Anda melihat komentar, ada solusinya! Inilah cara kerjanya. Jika Anda melakukan ini:

key <SPCE> { [ ISO_Level3_Shift ] };

Maka Anda dapat mengubahnya ke ini:

key <SPCE> {
  type[Group1]="ONE_LEVEL",
  symbols[Group1] = [ ISO_Level3_Shift ]
};

Dan itu benar-benar akan menyelesaikan masalah untuk beberapa aplikasi! Misalnya, Speedcrunch sekarang berfungsi untuk saya! Yay!

Ringkasan

Saat ini aplikasi apa pun harus berfungsi dengan benar. Jika tidak, maka Anda harus menggunakannya type[Group1]="ONE_LEVEL". Jika sudah memilikinya, maka Anda harus memperbarui perangkat lunak Anda. Jika masih tidak berfungsi, maka itu khusus untuk aplikasi dan Anda harus mengirimkan laporan bug.

UPDATE (2017-09-23)

Sampai hari ini, semua aplikasi menghargai tata letak keyboard saya. Semua kecuali satu.

Serius, penanganan keyboard di Chromium adalah sampah . Ada beberapa masalah dengan itu:

  • Pilihan shift tidak dengan tombol panah khusus (tetapi tombol panah sendiri berfungsi dengan baik)
  • Jika Anda memiliki beberapa tata letak dan pada salah satu tata letak beberapa tombol khusus (misalnya panah, Backspace, dll.), Maka pada tata letak lain kunci ini akan diperbaiki untuk apa pun yang Anda miliki pada tata letak pertama Anda. Misalnya, jika Anda memiliki dua layout: foo, bardan beberapa kunci tidak Backspace di foo, maka akan tetap bekerja sebagai Backspace di barbahkan jika didefinisikan ulang di sana.

Selama bertahun-tahun saya mengabaikan masalah ini dengan tidak menggunakan kromium. Namun, saat ini banyak hal yang cenderung menggunakan Electron , yang sayangnya dibangun di atas Chromium.

Cara yang tepat untuk menyelesaikan ini adalah dengan mengirimkan laporan bug di Chromium dan berharap yang terbaik. Saya tidak tahu berapa lama waktu yang dibutuhkan untuk menyelesaikan masalah yang hanya memengaruhi beberapa pengguna ... tapi itu sepertinya satu-satunya jalan keluar. Masalah dengan ini adalah bahwa kromium sebenarnya berfungsi dengan baik dengan neo(de)tata letak. Tata letak Neo memiliki tombol panah pada level5, tapi saya tidak bisa membuatnya berfungsi di tata letak khusus saya.

Laporan bug yang masih terbuka:

Aleks-Daniel Jakimenko
sumber
Terimakasih atas infonya! Solusi tidak membantu saya, jadi saya kira saya harus melaporkan bug saja dan menunggu konversi qt5.
nonpop
4

Cara membuatnya bekerja - Solusi 3

Menggunakan Level tambahan dan Aksi RedirectKey

Solusi berikut menggunakan tombol Alt kiri untuk memberikan kunci kursor pada jkli, Home / End / PageUp / PageDown pada uopö dan Delete pada Backspace.

Tombol Alt kiri tetap dapat digunakan untuk keperluan lain untuk semua kunci lainnya (seperti untuk menu aplikasi). Alt kiri (Mod1) dihapus dari keadaan pengubah ketika blok kursor digunakan sehingga aplikasi tidak dapat melihatnya.

xkb_keymap {
    xkb_keycodes { 
        include "evdev+aliases(qwertz)" 
    };
    xkb_types { 
        include "complete"  
    };
    xkb_compat { 
        include "complete"
        interpret osfLeft {
            action = RedirectKey(keycode=<LEFT>, clearmodifiers=Mod1);
        };
        interpret osfRight {
            action = RedirectKey(keycode=<RGHT>, clearmodifiers=Mod1);
        };
        interpret osfUp {
            action = RedirectKey(keycode=<UP>, clearmodifiers=Mod1);
        };
        interpret osfDown {
            action = RedirectKey(keycode=<DOWN>, clearmodifiers=Mod1);
        };
        interpret osfBeginLine {
            action = RedirectKey(keycode=<HOME>, clearmodifiers=Mod1);
        };
        interpret osfEndLine {
            action = RedirectKey(keycode=<END>, clearmodifiers=Mod1);
        };
        interpret osfPageUp {
            action = RedirectKey(keycode=<PGUP>, clearmodifiers=Mod1);
        };
        interpret osfPageDown {
            action = RedirectKey(keycode=<PGDN>, clearmodifiers=Mod1);
        };
        interpret osfDelete {
            action = RedirectKey(keycode=<DELE>, clearmodifiers=Mod1);
        };
    };
    xkb_symbols { 
        include "pc+de(nodeadkeys)"
        include "inet(evdev)"
        include "compose(rwin)"
        key <LALT> {
            type[Group1] = "ONE_LEVEL",
            symbols[Group1] = [ ISO_Level5_Shift ]
        };
        modifier_map Mod1 { <LALT> };
        key <AC07> {
            type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
            symbols[Group1] = [ j, J, dead_belowdot, dead_abovedot, osfLeft, osfLeft, osfLeft, osfLeft ]
        };
        key <AC08> {
            type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
            symbols[Group1] = [ k, K, kra, ampersand, osfDown, osfDown, osfDown, osfDown ]
        };
        key <AC09> {
            type[Group1] = "EIGHT_LEVEL_ALPHABETIC",
            symbols[Group1] = [ l, L, lstroke, Lstroke, osfRight, osfRight, osfRight, osfRight ]
        };
        key <AC10> {
            type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
            symbols[Group1] = [ odiaeresis, Odiaeresis, doubleacute, doubleacute, osfPageDown, osfPageDown, osfPageDown, osfPageDown ]
        };
        key <AD07> {
            type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
            symbols[Group1] = [ u, U, downarrow, uparrow, osfBeginLine, osfBeginLine, osfBeginLine, osfBeginLine ]
        };
        key <AD08> {
            type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC",
            symbols[Group1] = [ i, I, rightarrow, idotless, osfUp, osfUp, osfUp, osfUp ]
        };
        key <AD09> {
            type[Group1] = "EIGHT_LEVEL_ALPHABETIC",
            symbols[Group1] = [ o, O, oslash, Oslash, osfEndLine, osfEndLine, osfEndLine, osfEndLine ]
        };
        key <AD10> {
            type[Group1] = "EIGHT_LEVEL_ALPHABETIC",
            symbols[Group1] = [ p, P, thorn, THORN, osfPageUp, osfPageUp, osfPageUp, osfPageUp ]
        };
        key <BKSP> {
            type[Group1] = "EIGHT_LEVEL_ALPHABETIC",
            symbols[Group1] = [ BackSpace, BackSpace, BackSpace, BackSpace, osfDelete, osfDelete, osfDelete, osfDelete ] 
        };
    };
    xkb_geometry { 
        include "pc(pc105)" 
    };
};
mgl
sumber
Moly suci! Itu benar-benar berfungsi! Ini berfungsi di sekitar aplikasi yang rusak seperti Chromium. Bisakah Anda menjelaskan apa definisi osf ini? Tampaknya sudah ditentukan sebelumnya sehingga Anda tidak dapat menamainya secara acak.
Aleks-Daniel Jakimenko