#83 SGR-Pixels in TTerminal

This commit is contained in:
Autumn Lamonte 2021-12-27 16:30:10 -06:00
parent 3b8185ffb1
commit d638dee6a4
7 changed files with 138 additions and 19 deletions

View file

@ -1438,6 +1438,7 @@ public class TApplication implements Runnable {
setCustomMousePointerLocation(mouse);
}
setCustomWidgetMousePointerLocation(mouse);
setMouseStyle(mouse);
if (mouse.isMouse1() && (mouse.isShift() || mouse.isCtrl())) {
// Screen selection.
@ -1477,6 +1478,7 @@ public class TApplication implements Runnable {
TMouseEvent.Type.MOUSE_DOUBLE_CLICK,
mouse.getX(), mouse.getY(),
mouse.getAbsoluteX(), mouse.getAbsoluteY(),
mouse.getPixelOffsetX(), mouse.getPixelOffsetY(),
mouse.isMouse1(), mouse.isMouse2(),
mouse.isMouse3(),
mouse.isMouseWheelUp(), mouse.isMouseWheelDown(),
@ -1671,6 +1673,7 @@ public class TApplication implements Runnable {
setCustomMousePointerLocation(mouse);
}
setCustomWidgetMousePointerLocation(mouse);
setMouseStyle(mouse);
if ((mouseX != mouse.getX()) || (mouseY != mouse.getY())) {
mouseX = mouse.getX();
@ -1688,6 +1691,7 @@ public class TApplication implements Runnable {
TMouseEvent.Type.MOUSE_DOUBLE_CLICK,
mouse.getX(), mouse.getY(),
mouse.getAbsoluteX(), mouse.getAbsoluteY(),
mouse.getPixelOffsetX(), mouse.getPixelOffsetY(),
mouse.isMouse1(), mouse.isMouse2(),
mouse.isMouse3(),
mouse.isMouseWheelUp(), mouse.isMouseWheelDown(),
@ -2234,6 +2238,46 @@ public class TApplication implements Runnable {
}
}
/**
* Set the mouse style to the widget under the mouse.
*
* @param mouse the mouse position
*/
private void setMouseStyle(final TMouseEvent mouse) {
if (!(backend instanceof SwingBackend)) {
return;
}
SwingTerminal terminal = (SwingTerminal) getScreen();
// A bit of a hassle to find the active widget...
TWidget activeWidget = null;
for (TMenu menu: menus) {
if (menu.isActive()) {
terminal.setMouseStyle(System.getProperty(
"jexer.Swing.mouseStyle", "default"));
return;
}
}
TWindow window = getActiveWindow();
if (window == null) {
terminal.setMouseStyle(System.getProperty(
"jexer.Swing.mouseStyle", "default"));
return;
}
for (TWidget widget: window.getChildren()) {
if (widget.mouseWouldHit(mouse)) {
activeWidget = widget;
}
}
if (activeWidget == null) {
terminal.setMouseStyle(System.getProperty(
"jexer.Swing.mouseStyle", "default"));
return;
}
terminal.setMouseStyle(activeWidget.getMouseStyle());
}
/**
* Set the custom mouse pointer for the widget under the mouse.
*

View file

@ -403,10 +403,10 @@ public class TEditorWindow extends TScrollableWindow {
/**
* Returns true if this window does not want the application-wide mouse
* cursor drawn over it.
* pointer drawn over it.
*
* @return true if this window does not want the application-wide mouse
* cursor drawn over it
* pointer drawn over it
*/
@Override
public boolean hasHiddenMouse() {

View file

@ -911,10 +911,17 @@ public class TTerminalWidget extends TScrollableWidget
* cursor drawn over it
*/
public boolean hasHiddenMouse() {
if (emulator == null) {
return false;
if (emulator != null) {
boolean hiddenMouse = (emulator.hasHiddenMousePointer()
|| typingHidMouse);
if (hiddenMouse) {
setMouseStyle("none");
} else {
setMouseStyle("default");
}
return hiddenMouse;
}
return (emulator.hasHiddenMousePointer() || typingHidMouse);
return false;
}
/**

View file

@ -382,10 +382,10 @@ public class TTerminalWindow extends TScrollableWindow {
/**
* Returns true if this window does not want the application-wide mouse
* cursor drawn over it.
* pointer drawn over it.
*
* @return true if this window does not want the application-wide mouse
* cursor drawn over it
* pointer drawn over it
*/
@Override
public boolean hasHiddenMouse() {

View file

@ -1553,21 +1553,21 @@ public class TWindow extends TWidget {
/**
* Returns true if this window does not want the application-wide mouse
* cursor drawn over it.
* pointer drawn over it.
*
* @return true if this window does not want the application-wide mouse
* cursor drawn over it
* pointer drawn over it
*/
public boolean hasHiddenMouse() {
return hideMouse;
}
/**
* Set request to prevent the application-wide mouse cursor from being
* Set request to prevent the application-wide mouse pointer from being
* drawn over this window.
*
* @param hideMouse if true, this window does not want the
* application-wide mouse cursor drawn over it
* application-wide mouse pointer drawn over it
*/
public final void setHiddenMouse(final boolean hideMouse) {
this.hideMouse = hideMouse;

View file

@ -728,9 +728,11 @@ public class SwingTerminal extends LogicalScreen
* "hand", "text", "move", or "crosshair"
*/
public void setMouseStyle(final String style) {
this.mouseStyle = style;
if (swing != null) {
swing.setMouseStyle(mouseStyle);
if (!style.equals(mouseStyle)) {
this.mouseStyle = style;
if (swing != null) {
swing.setMouseStyle(mouseStyle);
}
}
}

View file

@ -237,7 +237,8 @@ public class ECMA48 implements Runnable {
private enum MouseEncoding {
X10,
UTF8,
SGR
SGR,
SGR_PIXELS
}
// ------------------------------------------------------------------------
@ -1967,7 +1968,7 @@ public class ECMA48 implements Runnable {
/*
System.err.printf("mouse(): protocol %s encoding %s mouse %s\n",
mouseProtocol, mouseEncoding, mouse);
*/
*/
if (mouseEncoding == MouseEncoding.X10) {
// We will support X10 but only for (160,94) and smaller.
@ -2022,7 +2023,9 @@ public class ECMA48 implements Runnable {
// Now encode the event
StringBuilder sb = new StringBuilder(6);
if (mouseEncoding == MouseEncoding.SGR) {
if ((mouseEncoding == MouseEncoding.SGR)
|| (mouseEncoding == MouseEncoding.SGR_PIXELS)
) {
sb.append((char) 0x1B);
sb.append("[<");
int buttons = 0;
@ -2063,8 +2066,13 @@ public class ECMA48 implements Runnable {
buttons |= 0x04;
}
sb.append(String.format("%d;%d;%d", buttons, mouse.getX() + 1,
mouse.getY() + 1));
int cols = mouse.getX() + 1;
int rows = mouse.getY() + 1;
if (mouseEncoding == MouseEncoding.SGR_PIXELS) {
cols = (mouse.getX() * textWidth) + mouse.getPixelOffsetX() + 1;
rows = (mouse.getY() * textHeight) + mouse.getPixelOffsetY() + 1;
}
sb.append(String.format("%d;%d;%d", buttons, cols, rows));
if (mouse.getType() == TMouseEvent.Type.MOUSE_UP) {
sb.append("m");
@ -3613,6 +3621,26 @@ public class ECMA48 implements Runnable {
}
break;
case 1016:
if ((type == DeviceType.XTERM)
&& (decPrivateModeFlag == true)
) {
// Mouse: SGR coordinates in pixels
if (value == true) {
mouseEncoding = MouseEncoding.SGR_PIXELS;
// We need our host widget to report in pixels too.
if (backend != null) {
backend.setPixelMouse(true);
}
} else {
mouseEncoding = MouseEncoding.X10;
if (backend != null) {
backend.setPixelMouse(false);
}
}
}
break;
case 1070:
if (type == DeviceType.XTERM) {
if (decPrivateModeFlag == true) {
@ -5358,6 +5386,37 @@ public class ECMA48 implements Runnable {
writeRemote(String.format("\033[?%d;%dS", item, action));
}
/**
* DECRQM - Request DEC private mode flags.
*/
private void decrqm() {
boolean decPrivateModeFlag = false;
for (int i = 0; i < collectBuffer.length(); i++) {
if (collectBuffer.charAt(i) == '?') {
decPrivateModeFlag = true;
break;
}
}
int i = getCsiParam(0, 0);
if (decPrivateModeFlag) {
switch (i) {
case 1016:
// Report SGR-Pixels support
int Ps = 2; // Reset
if (mouseEncoding == MouseEncoding.SGR_PIXELS) {
Ps = 1; // Set
}
writeRemote(String.format("\033[?%d;%d$y", i, Ps));
break;
default:
break;
}
}
}
/**
* Run this input character through the ECMA48 state machine.
*
@ -7049,6 +7108,13 @@ public class ECMA48 implements Runnable {
// DECSTR - Soft terminal reset
decstr();
}
if ((type == DeviceType.XTERM)
&& (collectBuffer.length() > 0)
&& (collectBuffer.charAt(collectBuffer.length() - 1) == '$')
) {
// DECRQM - Query DEC private mode flags
decrqm();
}
break;
case 'q':
if (((type == DeviceType.VT220)