Skip to content

Commit

Permalink
Fix processing windows input events for window resizes, mouse and foc…
Browse files Browse the repository at this point in the history
…us, fixes #220
  • Loading branch information
gnodet committed Jan 30, 2018
1 parent fde358d commit 4910a5a
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,68 @@ protected boolean processConsoleInput() throws IOException {
return false;
}

boolean flush = false;
for (INPUT_RECORD event : events) {
KEY_EVENT_RECORD keyEvent = event.keyEvent;
processKeyEvent(keyEvent.keyDown , keyEvent.keyCode, keyEvent.uchar, keyEvent.controlKeyState);
if (event.eventType == INPUT_RECORD.KEY_EVENT) {
KEY_EVENT_RECORD keyEvent = event.keyEvent;
processKeyEvent(keyEvent.keyDown , keyEvent.keyCode, keyEvent.uchar, keyEvent.controlKeyState);
flush = true;
} else if (event.eventType == INPUT_RECORD.WINDOW_BUFFER_SIZE_EVENT) {
raise(Signal.WINCH);
} else if (event.eventType == INPUT_RECORD.MOUSE_EVENT) {
processMouseEvent(event.mouseEvent);
flush = true;
} else if (event.eventType == INPUT_RECORD.FOCUS_EVENT) {
processFocusEvent(event.focusEvent.setFocus);
}
}

return true;
return flush;
}

private char[] focus = new char[] { '\033', '[', ' ' };

private void processFocusEvent(boolean hasFocus) throws IOException {
if (focusTracking) {
focus[2] = hasFocus ? 'I' : 'O';
slaveInputPipe.write(focus);
}
}

private char[] mouse = new char[] { '\033', '[', 'M', ' ', ' ', ' ' };

private void processMouseEvent(Kernel32.MOUSE_EVENT_RECORD mouseEvent) throws IOException {
int dwEventFlags = mouseEvent.eventFlags;
int dwButtonState = mouseEvent.buttonState;
if (tracking == MouseTracking.Off
|| tracking == MouseTracking.Normal && dwEventFlags == Kernel32.MOUSE_EVENT_RECORD.MOUSE_MOVED
|| tracking == MouseTracking.Button && dwEventFlags == Kernel32.MOUSE_EVENT_RECORD.MOUSE_MOVED && dwButtonState == 0) {
return;
}
int cb = 0;
dwEventFlags &= ~ Kernel32.MOUSE_EVENT_RECORD.DOUBLE_CLICK; // Treat double-clicks as normal
if (dwEventFlags == Kernel32.MOUSE_EVENT_RECORD.MOUSE_WHEELED) {
cb |= 64;
if ((dwButtonState >> 16) < 0) {
cb |= 1;
}
} else if (dwEventFlags == Kernel32.MOUSE_EVENT_RECORD.MOUSE_HWHEELED) {
return;
} else if ((dwButtonState & Kernel32.MOUSE_EVENT_RECORD.FROM_LEFT_1ST_BUTTON_PRESSED) != 0) {
cb |= 0x00;
} else if ((dwButtonState & Kernel32.MOUSE_EVENT_RECORD.RIGHTMOST_BUTTON_PRESSED) != 0) {
cb |= 0x01;
} else if ((dwButtonState & Kernel32.MOUSE_EVENT_RECORD.FROM_LEFT_2ND_BUTTON_PRESSED) != 0) {
cb |= 0x02;
} else {
cb |= 0x03;
}
int cx = mouseEvent.mousePosition.x;
int cy = mouseEvent.mousePosition.y;
mouse[3] = (char) (' ' + cb);
mouse[4] = (char) (' ' + cx + 1);
mouse[5] = (char) (' ' + cy + 1);
slaveInputPipe.write(mouse);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ protected boolean processConsoleInput() throws IOException {
case Kernel32.INPUT_RECORD.MOUSE_EVENT:
processMouseEvent(event.Event.MouseEvent);
return true;
case Kernel32.INPUT_RECORD.FOCUS_EVENT:
processFocusEvent(event.Event.FocusEvent.bSetFocus);
return true;
default:
// Skip event
return false;
Expand All @@ -89,6 +92,15 @@ private void processKeyEvent(Kernel32.KEY_EVENT_RECORD keyEvent) throws IOExcept
processKeyEvent(keyEvent.bKeyDown, keyEvent.wVirtualKeyCode, keyEvent.uChar.UnicodeChar, keyEvent.dwControlKeyState);
}

private char[] focus = new char[] { '\033', '[', ' ' };

private void processFocusEvent(boolean hasFocus) throws IOException {
if (focusTracking) {
focus[2] = hasFocus ? 'I' : 'O';
slaveInputPipe.write(focus);
}
}

private char[] mouse = new char[] { '\033', '[', 'M', ' ', ' ', ' ' };

private void processMouseEvent(Kernel32.MOUSE_EVENT_RECORD mouseEvent) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,9 @@ class INPUT_RECORD extends Structure {
public static class EventUnion extends Union {
public KEY_EVENT_RECORD KeyEvent;
public MOUSE_EVENT_RECORD MouseEvent;
public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
// MENU_EVENT_RECORD MenuEvent;
// FOCUS_EVENT_RECORD FocusEvent;
public WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
public MENU_EVENT_RECORD MenuEvent;
public FOCUS_EVENT_RECORD FocusEvent;
}

@Override
Expand All @@ -445,6 +445,12 @@ public void read() {
case WINDOW_BUFFER_SIZE_EVENT:
Event.setType(WINDOW_BUFFER_SIZE_RECORD.class);
break;
case MENU_EVENT:
Event.setType(MENU_EVENT_RECORD.class);
break;
case FOCUS_EVENT:
Event.setType(MENU_EVENT_RECORD.class);
break;
}
super.read();
}
Expand Down Expand Up @@ -518,6 +524,35 @@ protected java.util.List<String> getFieldOrder() {
}
}

// typedef struct _MENU_EVENT_RECORD {
// UINT dwCommandId;
// } MENU_EVENT_RECORD, *PMENU_EVENT_RECORD;
class MENU_EVENT_RECORD extends Structure {

public int dwCommandId;

private static String[] fieldOrder = {"dwCommandId"};

@Override
protected java.util.List<String> getFieldOrder() {
return java.util.Arrays.asList(fieldOrder);
}
}

// typedef struct _FOCUS_EVENT_RECORD {
// BOOL bSetFocus;
//} FOCUS_EVENT_RECORD;
class FOCUS_EVENT_RECORD extends Structure {
public boolean bSetFocus;

private static String[] fieldOrder = {"bSetFocus"};

@Override
protected java.util.List<String> getFieldOrder() {
return java.util.Arrays.asList(fieldOrder);
}
}

// typedef struct _SMALL_RECT {
// SHORT Left;
// SHORT Top;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal {
protected final AtomicBoolean paused = new AtomicBoolean(true);

protected MouseTracking tracking = MouseTracking.Off;
protected boolean focusTracking = false;
private volatile boolean closing;

public AbstractWindowsTerminal(Writer writer, String name, String type, Charset encoding, int codepage, boolean nativeSignals, SignalHandler signalHandler) throws IOException {
Expand Down Expand Up @@ -405,6 +406,17 @@ private String translate(String str, Object... params) {
return null;
}

@Override
public boolean hasFocusSupport() {
return true;
}

@Override
public boolean trackFocus(boolean tracking) {
focusTracking = tracking;
return true;
}

@Override
public boolean canPauseResume() {
return true;
Expand Down

0 comments on commit 4910a5a

Please sign in to comment.