%3F.png)
Problem
Bei der Verwendung bestimmter Software wieMixer, ist es wichtig, den Nummernblock verwenden zu können, damit der Benutzer Dinge tun kann, wie sich im Designbereich zu orientieren, aber viele Laptops verfügen nicht über einen physischen Nummernblock. Dies wird dadurch komplizierter, dass die normalen Zifferntasten (1-9 oben auf der Tastatur) für den Computer tatsächlich unterschiedliche „Symbole“ darstellen und daher in dieser Art von Software oft völlig unterschiedliche Funktionen haben.
Lösungsversuche
Da viele Laptops keinen Nummernblock haben,Eine gängige Lösung auf vielen Plattformen ist die Emulation des Nummernblocks, indem Sie beispielsweise eine Taste gedrückt halten, während Sie andere Tasten auf der Tastatur verwenden (z. B. jkluio789, um 123456789 darzustellen). Viele Laptops implementieren dies auf BIOS-Ebene (z. B. mithilfe der Fn-Taste). Ohne eine solche Implementierung auf niedriger Ebene ist die Implementierung dieser Emulation jedoch sehr schwierig.
Einige Lösungen gibt es online, aberSie sind für die Verwendung mit Designsoftware oft unzureichend(da sie nicht das richtige Symbol implementieren und außerdem die Verwendung von Modifikatortasten erfordern) oderSie werden nicht ausführlich erklärtDie meisten Lösungen konzentrieren sich auf die Nutzungxkb, eine komplizierte Architektur, deren Einsatz bekanntermaßen schwierig ist.
Voraussetzungen für eine gute Lösung
Eine gute Lösung für dieses Problem wäre ein emuliertes Tastenfeld, das von Grafiksoftware als echte Tastenfeldeingabe akzeptiert wird und einfach zu verwenden ist. Eine weitere Einschränkung ist die Tatsache, dass Blender die Verwendung von Sondertasten (wie Shift
, Alt
, Super
(„Befehl“, „Windows-Taste“ usw.), Hyper
) erkennt, selbst wenn xkb
Sondertasten gelöscht werden sollen, und daher eine Lösung mit „Tastenfeldemulation bei gedrückter Sondertaste“ als völlig andere Eingabe interpretiert (d. h. [ Numpad1
+ Alt
] statt nur Numpad1
). Daher würde eine ideale Lösung tatsächlich einen Sperrmechanismus (z. B. Großschreibung der Feststelltaste) statt eines Haltemechanismus (z. B. Großschreibung der Umschalttaste) beinhalten, damit keine Sondertasten versehentlich an die Software weitergegeben werden.
Antwort1
Schnellstart
Wenn Sie sich für die Erklärung nicht interessieren (ich weiß, ich kann langatmig sein), folgen Sie einfach den{fettgedruckte Zahlen in geschweiften Klammern}am Anfang einiger Absätze. Befolgen Sie jeden dieser Schritte der Reihe nach, und Sie können dies wahrscheinlich in wenigen Minuten implementieren. Beachten Sie, dass diese Anleitung ein gewisses Maß an Unix-Kenntnissen voraussetzt (Verzeichnisse erstellen, Dateien erstellen, sudo
Root-Zugriff erlangen usw.). Beachten Sie auch, dassRoot-Zugriff ist nur dort erforderlich, wo angegeben, Sie müssen es also nicht verwenden, sudo
sofern Sie nicht dazu aufgefordert werden.
Allgemeine Beschreibung der Lösung
Wir werden xkb verwenden, um Linux eine „sperrende“ (wie die Feststelltaste) Nummernblock-Emulation hinzuzufügen. Ich möchte, dass meine Tasten „jkluio789“ die Nummernblock-Darstellungen der Zahlen „123456789“ darstellen, sowie einige andere Einschlüsse („m,“->„0“, „-=[]“->[Nummernblock]“-+*“, „.“->[Nummernblock]“.“). Ich werde diesen „Nummernblock-Modus“ umschalten, indem ich die Tastenkombination [ Shift
+ Mod4
+ [key]
] verwende, wobei Mod4
der Modifikatorcode für meine Betriebssystemtaste ist (auch „Befehlstaste“ oder „Windows-Taste“ genannt und manchmal dem Modifikatorcode Super
oder zugewiesen Hyper
) und [key]
eine der Tasten ist, die in meinem emulierten Nummernblock verwendet werden (wie „j“ oder „[“)). Einfache Änderungen an diesem Setup sollten nach dem Lesen der vollständigen Lösung relativ einfach sein.
Dazu definieren wir eine benutzerdefinierte xkb-Datei „Typ“, die xkb mitteilt, wie die verschiedenen Modifikatortasten zu interpretieren sind, die wir zum Initialisieren unserer Tastaturemulation verwenden, sowie eine benutzerdefinierte xkb-Datei „Symbole“, die xkb mitteilt, wie sich jede Taste, die wir drücken, normalerweise verhalten soll (Gruppe 1), wie sie sich während der Nummernblockemulation verhalten soll (Gruppe 2) und wie zwischen den beiden hin- und hergeschaltet wird (Aktion der Stufe 3 für beide Gruppen). Schließlich machen wir unsere Lösung dauerhaft, indem wir sie sed
jedes Mal, wenn wir eine neue Sitzung starten, in die aktuelle xkbmap integrieren (damit unsere Lösung nicht bei jeder xkb
Aktualisierung gelöscht wird).
Detaillierte Beschreibung der Lösung
Verzeichnisaufbau
{1}Als erstes definieren wir ein Verzeichnis, in dem wir unsere verschiedenen Dateien speichern. Ihr Verzeichnis kann so ziemlich alles Mögliche sein, aber meines sieht so aus:
/home
+-<username>
+-.xkb
+-symbols
+-types
+-keymap
+-log
Typ Datei
Sobald wir unseren Verzeichnisbaum haben, definieren wir die eigentlichen Dateien in unserer Lösung. Als Erstes definieren wir unsere „Typ“-Datei. Diese Datei gibt an, xkb
wie zwischen den „Ebenen“ gewechselt wird (z. B. wie Shift
ein Buchstabe groß geschrieben wird, von der ersten Ebene eines Kleinbuchstabens zu einer Ebene mit Großbuchstaben). Diese Ebenen sind etwas schwierig zu verstehen, insbesondere für englische Muttersprachler, aber internationale Tastaturen verwenden sie sehr effektiv für alternative Buchstaben und Symbole sowie diakritische Zeichen.
Wir werden es verwenden, um zu definieren, wie wir eine Änderung unserer Tasten anzeigen möchten. Mit anderen Worten, wir sagen ihm, dass wir ein „Level 1“-Verhalten erwarten, wenn kein Modifikator gedrückt wird (normalerweise ein normaler Kleinbuchstabe in unserem „Normalmodus“), ein „Level 2“-Verhalten, wenn wir die Shift
Taste gedrückt halten (normalerweise ein normaler Großbuchstabe in unserem „Normalmodus“) und ein „Level 3“-Verhalten, wenn wir beide Shift
+ gedrückt halten Mod4
(ein Sonderfall für unsere Zwecke, den wir verwenden, um anzuzeigen, dass die Taste, wenn sie zum Ändern einer Taste verwendet wird, nun zwischen den Modi wechselt).
{2}Öffnen Sie eine neue Datei, die wir nennen togglekeypad
. Kopieren Sie den folgenden Codeblock hinein und speichern Sie ihn in Ihrem types
Verzeichnis unter \home\<username>\.xkb\types
. HINWEIS: Möglicherweise müssen Sie alle Instanzen von in den Modifikator ändern, Mod4
dem Ihre „Befehlstaste“/„Windows-Taste“ entspricht (Sie müssen möglicherweise experimentieren, siehediese Webseite unter Modifikatortastenzur Orientierung) oder welchen anderen Modifikator Sie auch immer möchten.
partial default xkb_types "togglekeypad" { // Name of this type file
type "TOGGLEKEYPAD" { // Name of this "type"
modifiers = Shift+Mod4; // The modifiers that this type concerns itself with
map[Shift] = level2; // Shift brings us to level 2
map[Mod4+Shift] = level3; // Windows key plus shift brings us to level 3
level_name[Level1] = "Base"; // Human-readable names for each level (not really used, but convenient)
level_name[Level2] = "Shift";
level_name[Level3] = "Transfer";
};
};
{3}Wir müssen diese Datei auch in das Verzeichnis kopieren /usr/share/X11/xkb/types/
. Dazu sind Root-Rechte erforderlich, was leider den Zweck xkb
einer Userspace-Anwendung zunichte macht, aber setxkbmap
ohne dies scheine ich die Datei nicht erkennen zu können. Vorschläge sind willkommen!
Symboldatei
Als Nächstes legen wir fest, xkb
was jeder Schlüssel tun soll, wenn er auf die in der Typendatei beschriebenen Arten geändert wird.
Wir sagen, dass wir in unserer Symboldatei zwei Gruppen verwenden möchten. Das bedeutet, dass jede Taste zwei verschiedene allgemeine Verhaltensweisen hat, zwischen denen wir auf irgendeine Weise wechseln werden. Diese Verhaltensweisen sind das normale Tippverhalten und das neue Verhalten der Nummernblock-Emulation. Für jede Taste sagen wir, dass 1) wir den TOGGLEKEYPAD
Typ verwenden möchten, 2) wir die Symbole definieren (also was der Computer sieht), die mit jeder der physischen Tasten in beiden Gruppen für alle Ebenen verknüpft sind, und 3) wir alle Aktionen definieren (alle speziellen Dinge, die xkb
getan werden sollen), die mit jeder Taste für beide Gruppen auf allen Ebenen verknüpft sind. Das klingt ziemlich verwirrend, sollte aber anhand eines Beispiels etwas verständlicher sein.
Die erste Taste, die wir in der Symboldatei sehen, die ich unten eingefügt habe, ist die <AC07>
Taste. Dies entspricht der Taste "J" auf den meisten Tastaturen,gemäß der hier gezeigten Karte(Abbildung 2). Für diese physische Taste sagen wir, dass im Normalmodus: in Ebene 1 (keine Modifikatoren, gemäß unserer Typdatei) nur „j“ und in Ebene 2 ( Shift
Modifikator) nur „J“ eingegeben wird. In Ebene 3 macht sie etwas Besonderes: Ebene 3 ist kein Symbol zugeordnet, aber es gibt eine Aktion, und diese Aktion ist LockGroup(group=2)
. Mit anderen Worten, wir wechseln zu unserer zweiten Gruppe, unserer „Tastatur“-Gruppe. Wenn wir uns die nächsten Zeilen ansehen, sehen wir, dass wir für diese gleiche Taste weitere Symbole und Aktionen für Gruppe 2 definiert haben. Es heißt, dass in Ebene 1 (keine Modifikatoren) kein Symbol, sondern eingegeben wird RedirectKey(keycode=<KP1>)
. Mit anderen Worten, diese Taste registrieren, als ob wir tatsächlich gerade die <KP1>
Taste gedrückt hätten, was der „1“ auf einer Tastatur entspricht. (Hinweis: Wir hätten erneut NoAction() einfügen und das Symbol verwenden können KP_1
, das das Symbol ist, dem diese Taste <KP1>
entspricht, aber ich dachte, dies würde die beste Kompatibilität bieten). Für Ebene 2 machen wir dasselbe, aber fügen der Shift
Taste den Modifikator hinzu. Für Level 3 kehren wir schließlich wieder zur Gruppe 1, dem „Standard“-Modus, zurück.
{4}Öffnen Sie eine neue Datei, die wir nennen togglekeypad_symbols
. Kopieren Sie den folgenden Codeblock hinein und speichern Sie ihn in Ihrem symbols
Verzeichnis unter \home\<username>\.xkb\symbols
.
default partial
xkb_symbols "togglekeypad" {
name[Group1]= "Standard";
name[Group2]= "Keypad";
key <AC07> { // J
type = "TOGGLEKEYPAD",
symbols[Group1] = [ j, J, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP1>), RedirectKey(keyCode=<KP1>, modifiers=Shift), LockGroup(group=1)]
};
key <AC08> { // K
type = "TOGGLEKEYPAD",
symbols[Group1] = [ k, K, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP2>), RedirectKey(keyCode=<KP2>, modifiers=Shift), LockGroup(group=1)]
};
key <AC09> { // L
type = "TOGGLEKEYPAD",
symbols[Group1] = [ l, L, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP3>), RedirectKey(keyCode=<KP3>, modifiers=Shift), LockGroup(group=1)]
};
key <AD07> { // U
type = "TOGGLEKEYPAD",
symbols[Group1] = [ u, U, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP4>), RedirectKey(keyCode=<KP4>, modifiers=Shift), LockGroup(group=1)]
};
key <AD08> { // I
type = "TOGGLEKEYPAD",
symbols[Group1] = [ i, I, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP5>), RedirectKey(keyCode=<KP5>, modifiers=Shift), LockGroup(group=1)]
};
key <AD09> { // O
type = "TOGGLEKEYPAD",
symbols[Group1] = [ o, O, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP6>), RedirectKey(keyCode=<KP6>, modifiers=Shift), LockGroup(group=1)]
};
key <AE07> { // 7
type = "TOGGLEKEYPAD",
symbols[Group1] = [ 7, ampersand, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP7>), RedirectKey(keyCode=<KP7>, modifiers=Shift), LockGroup(group=1)]
};
key <AE08> { // 8
type = "TOGGLEKEYPAD",
symbols[Group1] = [ 8, asterisk, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP8>), RedirectKey(keyCode=<KP8>, modifiers=Shift), LockGroup(group=1)]
};
key <AE09> { // 9
type = "TOGGLEKEYPAD",
symbols[Group1] = [ 9, parenleft, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP9>), RedirectKey(keyCode=<KP9>), LockGroup(group=1)]
};
// NumLock
key <AE06> { // 6
type = "TOGGLEKEYPAD",
symbols[Group1] = [ 6, asciicircum, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<NMLK>), RedirectKey(keyCode=<NMLK>), LockGroup(group=1)]
};
// Bottom Row (and zero)
key <AB07> { // M
type = "TOGGLEKEYPAD",
symbols[Group1] = [ m, M, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP0>), RedirectKey(keyCode=<KP0>, modifiers=Shift), LockGroup(group=1)]
};
key <AE10> { // 0
type = "TOGGLEKEYPAD",
symbols[Group1] = [ 0, parenright, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KP0>), RedirectKey(keyCode=<KP0>, modifiers=Shift), LockGroup(group=1)]
};
key <AB09> { // .
type = "TOGGLEKEYPAD",
symbols[Group1] = [ period, greater, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KPDL>), RedirectKey(keyCode=<KPDL>, modifiers=Shift), LockGroup(group=1)]
};
// Arithmetic Operators
key <AE11> { // -
type = "TOGGLEKEYPAD",
symbols[Group1] = [ minus, underscore, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KPSU>), RedirectKey(keyCode=<KPSU>, modifiers=Shift), LockGroup(group=1)]
};
key <AE12> { // +
type = "TOGGLEKEYPAD",
symbols[Group1] = [ equal, plus, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KPAD>), RedirectKey(keyCode=<KPAD>, modifiers=Shift), LockGroup(group=1)]
};
key <AD12> { // [
type = "TOGGLEKEYPAD",
symbols[Group1] = [ bracketleft, braceleft, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KPDV>), RedirectKey(keyCode=<KPDV>, modifiers=Shift), LockGroup(group=1)]
};
key <AD12> { // ]
type = "TOGGLEKEYPAD",
symbols[Group1] = [ bracketright, braceright, NoSymbol],
actions[Group1] = [NoAction(), NoAction(), LockGroup(group=2)],
symbols[Group2] = [NoSymbol, NoSymbol, NoSymbol],
actions[Group2] = [RedirectKey(keyCode=<KPMU>), RedirectKey(keyCode=<KPMU>, modifiers=Shift), LockGroup(group=1)]
};
};
Testen Sie unser Keypad
{5}Um die Tastaturkonfiguration so zu testen, wie sie ist, öffnen Sie ein Terminal
Fenster und geben Sie ein
setxkbmap -types complete+togglekeypad -print | sed -e '/xkb_symbols/s/"[[:space:]]/+togglekeypad_symbols(togglekeypad)&/' > $HOME/.xkb/keymap/customMap
xkbcomp -I$HOME/.xkb -R$HOME/.xkb keymap/customMap $DISPLAY
Dadurch werden die aktuellen Einstellungen unserer xkb
Karte (mit setxkbmap - print
) abgerufen, während die verwendeten Typen auf complete+togglekeypad
(alles in der Datei /usr/share/X11/xkb/types/complete
und auch einschließlich unserer Typendatei unter /usr/share/X11/xkb/types/togglekeypad
) festgelegt werden. Dies wird dann in eingespeist , wodurch unsere Symbole aus unserer Datei in die verwendeten Symboldateien sed
eingefügt werden . Schließlich haben wir verwendet, um die neue Tastaturbelegung zu kompilieren.togglekeypad
togglekeypad_symbols
xkbcomp
Beachten Sie, dass auf meinem Computer davon ausgegangen wird, dass NumLock ausgeschaltet ist (da mein Computer keinen Nummernblock hat), sodass die Nummernblocktasten ihre primären Funktionen tatsächlich an den Computer senden, d. h. Home, End, PG Up, PG Down usw. Um Zahlen einzugeben, wenn Sie den emulierten Nummernblock verwenden, halten Sie die Umschalttaste gedrückt. Ich habe verschiedene Methoden ausprobiert, um dieses Verhalten umzukehren (das modifers
Argument zwischen den Ebenen in der Symboldatei vertauscht, eine neue Taste zugewiesen, um die NumLock-Taste zu emulieren <NMLK>
und sie umzuschalten), aber nichts hat bisher bei mir funktioniert. Glücklicherweise funktioniert es beim Testen in Blender genau wie erwartet, ohne dass die Umschalttaste gedrückt gehalten werden muss.
{6}Wenn an diesem Punkt etwas schrecklich schief gelaufen ist, dann machen Sie sich keine Sorgen. Melden Sie sich einfach ab und wieder an (oder im schlimmsten Fall neu), führen Sie ein Debugging durch und versuchen Sie es erneut. Wenn alles funktioniert, machen wir es dauerhaft.
Die Lösung dauerhaft machen
Es gibt sicherlich elegantere Möglichkeiten, unsere Lösung zwischen Sitzungen persistent zu machen, aber die einfachste und zuverlässigste Methode für mich war, die obigen Befehle einfach am Ende meiner ~/.bashrc
Datei einzufügen. Ich habe denhier vorgeschlagene Lösungdas fügt ein wenig Fehlerprüfung hinzu und hat noch etwas mehr hinzugefügt (damit ich alle Fehlerausgaben sehen konnte).
{7}Öffnen Sie die Datei ~/.bashrc
. Fügen Sie am Ende das folgende Skript hinzu:
# Setup custom keyboard remapping to emulate a number pad when "Shift+Cmd+numap_key" is pressed to initialize
if [ -d $HOME/.xkb/keymap ]; then
setxkbmap -types complete+togglekeypad -print | \
sed -e '/xkb_symbols/s/"[[:space:]]/+togglekeypad_symbols(togglekeypad)&/' > $HOME/.xkb/keymap/customMap 2> $HOME/.xkb/log/sedErrors
xkbcomp -w0 -I$HOME/.xkb -R$HOME/.xkb keymap/customMap $DISPLAY > $HOME/.xkb/log/outputOfCommand 2>&1
fi
{8}Beim Neustart sollte die Nummernblock-Emulation nun dauerhaft aktiviert sein!
Abschluss
Während die Erklärung lang ist, ist die Methode selbst relativ kurz. Die Nachteile sind, dass Blender eine Sperrmethode benötigt, um richtig zu funktionieren, während ich stattdessen eine Haltemethode vorgezogen hätte, und dass aus xkb
irgendeinem Grund Root-Zugriff erforderlich ist, um unsere benutzerdefinierten Typendateien zu erkennen. Insgesamt scheint dies jedoch für mich gut zu funktionieren. Wenn Sie Fragen oder Vorschläge haben, können Sie diese gerne unten hinterlassen!