mirror of https://github.com/adamdruppe/arsd.git
modifier keys
This commit is contained in:
parent
0b8ddc2470
commit
67757c74a7
116
terminal.d
116
terminal.d
|
|
@ -1330,7 +1330,6 @@ struct RealTimeConsoleInput {
|
||||||
e.eventType = ev.bKeyDown ? CharacterEvent.Type.Pressed : CharacterEvent.Type.Released;
|
e.eventType = ev.bKeyDown ? CharacterEvent.Type.Pressed : CharacterEvent.Type.Released;
|
||||||
ne.eventType = ev.bKeyDown ? NonCharacterKeyEvent.Type.Pressed : NonCharacterKeyEvent.Type.Released;
|
ne.eventType = ev.bKeyDown ? NonCharacterKeyEvent.Type.Pressed : NonCharacterKeyEvent.Type.Released;
|
||||||
|
|
||||||
// FIXME standardize
|
|
||||||
e.modifierState = ev.dwControlKeyState;
|
e.modifierState = ev.dwControlKeyState;
|
||||||
ne.modifierState = ev.dwControlKeyState;
|
ne.modifierState = ev.dwControlKeyState;
|
||||||
|
|
||||||
|
|
@ -1406,16 +1405,17 @@ struct RealTimeConsoleInput {
|
||||||
InputEvent(CharacterEvent(CharacterEvent.Type.Released, character, 0)),
|
InputEvent(CharacterEvent(CharacterEvent.Type.Released, character, 0)),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
InputEvent[] keyPressAndRelease(NonCharacterKeyEvent.Key key) {
|
InputEvent[] keyPressAndRelease(NonCharacterKeyEvent.Key key, uint modifiers = 0) {
|
||||||
return [
|
return [
|
||||||
InputEvent(NonCharacterKeyEvent(NonCharacterKeyEvent.Type.Pressed, key, 0)),
|
InputEvent(NonCharacterKeyEvent(NonCharacterKeyEvent.Type.Pressed, key, modifiers)),
|
||||||
InputEvent(NonCharacterKeyEvent(NonCharacterKeyEvent.Type.Released, key, 0)),
|
InputEvent(NonCharacterKeyEvent(NonCharacterKeyEvent.Type.Released, key, modifiers)),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char[30] sequenceBuffer;
|
||||||
|
|
||||||
// this assumes you just read "\033["
|
// this assumes you just read "\033["
|
||||||
char[] readEscapeSequence() {
|
char[] readEscapeSequence(char[] sequence) {
|
||||||
char[30] sequence;
|
|
||||||
int sequenceLength = 2;
|
int sequenceLength = 2;
|
||||||
sequence[0] = '\033';
|
sequence[0] = '\033';
|
||||||
sequence[1] = '[';
|
sequence[1] = '[';
|
||||||
|
|
@ -1514,7 +1514,7 @@ struct RealTimeConsoleInput {
|
||||||
if(n == '\033') {
|
if(n == '\033') {
|
||||||
n = nextRaw();
|
n = nextRaw();
|
||||||
if(n == '[') {
|
if(n == '[') {
|
||||||
auto esc = readEscapeSequence();
|
auto esc = readEscapeSequence(sequenceBuffer);
|
||||||
if(esc == "\033[201~") {
|
if(esc == "\033[201~") {
|
||||||
// complete!
|
// complete!
|
||||||
break;
|
break;
|
||||||
|
|
@ -1566,7 +1566,7 @@ struct RealTimeConsoleInput {
|
||||||
m.buttons = 1 << (buttonNumber - 1); // I prefer flags so that's how we do it
|
m.buttons = 1 << (buttonNumber - 1); // I prefer flags so that's how we do it
|
||||||
m.x = x;
|
m.x = x;
|
||||||
m.y = y;
|
m.y = y;
|
||||||
m.modifierState = modifiers; // FIXME, standardize
|
m.modifierState = modifiers;
|
||||||
|
|
||||||
return [InputEvent(m)];
|
return [InputEvent(m)];
|
||||||
break;
|
break;
|
||||||
|
|
@ -1575,6 +1575,79 @@ struct RealTimeConsoleInput {
|
||||||
auto cap = terminal.findSequenceInTermcap(sequence);
|
auto cap = terminal.findSequenceInTermcap(sequence);
|
||||||
if(cap !is null)
|
if(cap !is null)
|
||||||
return translateTermcapName(cap);
|
return translateTermcapName(cap);
|
||||||
|
else {
|
||||||
|
if(terminal.terminalInFamily("xterm")) {
|
||||||
|
import std.conv, std.string;
|
||||||
|
auto terminator = sequence[$ - 1];
|
||||||
|
auto parts = sequence[2 .. $ - 1].split(";");
|
||||||
|
// parts[0] and terminator tells us the key
|
||||||
|
// parts[1] tells us the modifierState
|
||||||
|
|
||||||
|
uint modifierState;
|
||||||
|
|
||||||
|
int modGot = to!int(parts[1]);
|
||||||
|
mod_switch: switch(modGot) {
|
||||||
|
case 2: modifierState |= ModifierState.shift; break;
|
||||||
|
case 3: modifierState |= ModifierState.alt; break;
|
||||||
|
case 4: modifierState |= ModifierState.shift | ModifierState.alt; break;
|
||||||
|
case 5: modifierState |= ModifierState.control; break;
|
||||||
|
case 6: modifierState |= ModifierState.shift | ModifierState.control; break;
|
||||||
|
case 7: modifierState |= ModifierState.alt | ModifierState.control; break;
|
||||||
|
case 8: modifierState |= ModifierState.shift | ModifierState.alt | ModifierState.control; break;
|
||||||
|
case 9:
|
||||||
|
..
|
||||||
|
case 16:
|
||||||
|
modifierState |= ModifierState.meta;
|
||||||
|
if(modGot != 9) {
|
||||||
|
modGot -= 8;
|
||||||
|
goto mod_switch;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(terminator) {
|
||||||
|
case 'A': return keyPressAndRelease(NonCharacterKeyEvent.Key.UpArrow, modifierState);
|
||||||
|
case 'B': return keyPressAndRelease(NonCharacterKeyEvent.Key.DownArrow, modifierState);
|
||||||
|
case 'C': return keyPressAndRelease(NonCharacterKeyEvent.Key.RightArrow, modifierState);
|
||||||
|
case 'D': return keyPressAndRelease(NonCharacterKeyEvent.Key.LeftArrow, modifierState);
|
||||||
|
|
||||||
|
case 'H': return keyPressAndRelease(NonCharacterKeyEvent.Key.Home, modifierState);
|
||||||
|
case 'F': return keyPressAndRelease(NonCharacterKeyEvent.Key.End, modifierState);
|
||||||
|
|
||||||
|
case 'P': return keyPressAndRelease(NonCharacterKeyEvent.Key.F1, modifierState);
|
||||||
|
case 'Q': return keyPressAndRelease(NonCharacterKeyEvent.Key.F2, modifierState);
|
||||||
|
case 'R': return keyPressAndRelease(NonCharacterKeyEvent.Key.F3, modifierState);
|
||||||
|
case 'S': return keyPressAndRelease(NonCharacterKeyEvent.Key.F4, modifierState);
|
||||||
|
|
||||||
|
case '~': // others
|
||||||
|
switch(parts[0]) {
|
||||||
|
case "5": return keyPressAndRelease(NonCharacterKeyEvent.Key.PageUp, modifierState);
|
||||||
|
case "6": return keyPressAndRelease(NonCharacterKeyEvent.Key.PageDown, modifierState);
|
||||||
|
case "2": return keyPressAndRelease(NonCharacterKeyEvent.Key.Insert, modifierState);
|
||||||
|
case "3": return keyPressAndRelease(NonCharacterKeyEvent.Key.Delete, modifierState);
|
||||||
|
|
||||||
|
case "15": return keyPressAndRelease(NonCharacterKeyEvent.Key.F5, modifierState);
|
||||||
|
case "17": return keyPressAndRelease(NonCharacterKeyEvent.Key.F6, modifierState);
|
||||||
|
case "18": return keyPressAndRelease(NonCharacterKeyEvent.Key.F7, modifierState);
|
||||||
|
case "19": return keyPressAndRelease(NonCharacterKeyEvent.Key.F8, modifierState);
|
||||||
|
case "20": return keyPressAndRelease(NonCharacterKeyEvent.Key.F9, modifierState);
|
||||||
|
case "21": return keyPressAndRelease(NonCharacterKeyEvent.Key.F10, modifierState);
|
||||||
|
case "23": return keyPressAndRelease(NonCharacterKeyEvent.Key.F11, modifierState);
|
||||||
|
case "24": return keyPressAndRelease(NonCharacterKeyEvent.Key.F12, modifierState);
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
} else if(terminal.terminalInFamily("rxvt")) {
|
||||||
|
// FIXME: figure these out
|
||||||
|
} else {
|
||||||
|
// maybe we could do more terminals, but linux doesn't even send it and screen just seems to pass through, so i don't think so; xterm prolly covers most them anyway
|
||||||
|
// so this space is semi-intentionally left blank
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -1588,7 +1661,7 @@ struct RealTimeConsoleInput {
|
||||||
// escape sequence
|
// escape sequence
|
||||||
c = nextRaw();
|
c = nextRaw();
|
||||||
if(c == '[') { // CSI, ends on anything >= 'A'
|
if(c == '[') { // CSI, ends on anything >= 'A'
|
||||||
return doEscapeSequence(readEscapeSequence());
|
return doEscapeSequence(readEscapeSequence(sequenceBuffer));
|
||||||
} else if(c == 'O') {
|
} else if(c == 'O') {
|
||||||
// could be xterm function key
|
// could be xterm function key
|
||||||
auto n = nextRaw();
|
auto n = nextRaw();
|
||||||
|
|
@ -1631,7 +1704,7 @@ struct CharacterEvent {
|
||||||
|
|
||||||
Type eventType; /// .
|
Type eventType; /// .
|
||||||
dchar character; /// .
|
dchar character; /// .
|
||||||
uint modifierState; /// .
|
uint modifierState; /// Don't depend on this to be available for character events
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NonCharacterKeyEvent {
|
struct NonCharacterKeyEvent {
|
||||||
|
|
@ -1672,7 +1745,7 @@ struct NonCharacterKeyEvent {
|
||||||
}
|
}
|
||||||
Key key; /// .
|
Key key; /// .
|
||||||
|
|
||||||
uint modifierState; /// .
|
uint modifierState; /// A mask of ModifierState. Always use by checking modifierState & ModifierState.something, the actual value differs across platforms
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1705,7 +1778,7 @@ struct MouseEvent {
|
||||||
uint buttons; /// A mask of Button
|
uint buttons; /// A mask of Button
|
||||||
int x; /// 0 == left side
|
int x; /// 0 == left side
|
||||||
int y; /// 0 == top
|
int y; /// 0 == top
|
||||||
uint modifierState; /// shift, ctrl, alt, meta, altgr
|
uint modifierState; /// shift, ctrl, alt, meta, altgr. Not always available. Always check by using modifierState & ModifierState.something
|
||||||
}
|
}
|
||||||
|
|
||||||
/// .
|
/// .
|
||||||
|
|
@ -1721,6 +1794,25 @@ struct UserInterruptionEvent {}
|
||||||
|
|
||||||
interface CustomEvent {}
|
interface CustomEvent {}
|
||||||
|
|
||||||
|
version(Windows)
|
||||||
|
enum ModifierState : uint {
|
||||||
|
shift = 4,
|
||||||
|
ctrl = 8,
|
||||||
|
|
||||||
|
// i'm not sure if the next two are available
|
||||||
|
alt = 256,
|
||||||
|
// windows = 512,
|
||||||
|
|
||||||
|
meta = 4096, // FIXME sanity
|
||||||
|
}
|
||||||
|
else
|
||||||
|
enum ModifierState : uint {
|
||||||
|
shift = 4,
|
||||||
|
alt = 2,
|
||||||
|
control = 16,
|
||||||
|
meta = 8
|
||||||
|
}
|
||||||
|
|
||||||
/// GetNextEvent returns this. Check the type, then use get to get the more detailed input
|
/// GetNextEvent returns this. Check the type, then use get to get the more detailed input
|
||||||
struct InputEvent {
|
struct InputEvent {
|
||||||
/// .
|
/// .
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue