1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-29 20:05:35 +02:00

Terminal: Bug 434294 Fix handling of multiple key bindings for copy/paste

- now considering all key bindings in EditActionsAccelerator
- fix incorrect creation of escape codes for a combination of modifiers

Change-Id: I2547bba7ef3ca13370b1abf3f8ad8f5956d76c58
Signed-off-by: Anton Leherbauer <anton.leherbauer@windriver.com>
This commit is contained in:
Anton Leherbauer 2014-05-09 15:13:10 +02:00
parent 049cba8a41
commit 5afca1ae70
2 changed files with 31 additions and 32 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2013 Wind River Systems, Inc. and others. * Copyright (c) 2013, 2014 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -19,8 +19,8 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.keys.IBindingService; import org.eclipse.ui.keys.IBindingService;
class EditActionAccelerators { class EditActionAccelerators {
private static final String COPY_COMMAND_ID = "org.eclipse.tm.terminal.copy"; private static final String COPY_COMMAND_ID = "org.eclipse.tm.terminal.copy"; //$NON-NLS-1$
private static final String PASTE_COMMAND_ID = "org.eclipse.tm.terminal.paste"; private static final String PASTE_COMMAND_ID = "org.eclipse.tm.terminal.paste"; //$NON-NLS-1$
private final Map commandIdsByAccelerator = new HashMap(); private final Map commandIdsByAccelerator = new HashMap();
@ -30,25 +30,21 @@ class EditActionAccelerators {
} }
private void addAccelerator(String commandId) { private void addAccelerator(String commandId) {
KeySequence keySequence = bindingFor(commandId); TriggerSequence[] bindings = bindingsFor(commandId);
if (keySequence == null) { for (int i=0; i<bindings.length; ++i) {
return; if (bindings[i] instanceof KeySequence) {
} KeyStroke[] keyStrokes = ((KeySequence) bindings[i]).getKeyStrokes();
KeyStroke[] keyStrokes = keySequence.getKeyStrokes(); if (keyStrokes.length != 0) {
if (keyStrokes.length != 0) { int accelerator = SWTKeySupport.convertKeyStrokeToAccelerator(keyStrokes[0]);
int accelerator = SWTKeySupport.convertKeyStrokeToAccelerator(keyStrokes[0]); commandIdsByAccelerator.put(new Integer(accelerator), commandId);
commandIdsByAccelerator.put(new Integer(accelerator), commandId); }
}
} }
} }
private static KeySequence bindingFor(String commandId) { private static TriggerSequence[] bindingsFor(String commandId) {
IBindingService bindingService = bindingService(); IBindingService bindingService = bindingService();
TriggerSequence binding = bindingService.getBestActiveBindingFor(commandId); return bindingService.getActiveBindingsFor(commandId);
if (binding instanceof KeySequence) {
KeySequence keySequence = (KeySequence) binding;
return keySequence;
}
return null;
} }
private static IBindingService bindingService() { private static IBindingService bindingService() {

View file

@ -570,13 +570,13 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC
// TODO: Make the ESCAPE-vs-highbit behavior user configurable. // TODO: Make the ESCAPE-vs-highbit behavior user configurable.
Logger.log("sending ESC + '" + byteToSend + "'"); //$NON-NLS-1$ //$NON-NLS-2$ Logger.log("sending ESC + '" + byteToSend + "'"); //$NON-NLS-1$ //$NON-NLS-2$
getOutputStream().write('\u001b'); os.write('\u001b');
getOutputStream().write(byteToSend); os.write(byteToSend);
} else { } else {
Logger.log("sending '" + byteToSend + "'"); //$NON-NLS-1$ //$NON-NLS-2$ Logger.log("sending '" + byteToSend + "'"); //$NON-NLS-1$ //$NON-NLS-2$
getOutputStream().write(byteToSend); os.write(byteToSend);
} }
getOutputStream().flush(); os.flush();
} }
} catch (SocketException socketException) { } catch (SocketException socketException) {
Logger.logException(socketException); Logger.logException(socketException);
@ -876,15 +876,16 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC
event.doit = false; event.doit = false;
char character = event.character; char character = event.character;
int modifierKeys = event.stateMask & SWT.MODIFIER_MASK;
boolean ctrlKeyPressed = (event.stateMask & SWT.CTRL) != 0; boolean ctrlKeyPressed = (event.stateMask & SWT.CTRL) != 0;
boolean altKeyPressed = (event.stateMask & SWT.ALT) != 0; boolean onlyCtrlKeyPressed = modifierKeys == SWT.CTRL;
boolean macCmdKeyPressed = (event.stateMask & SWT.COMMAND) != 0; boolean macCmdKeyPressed = (event.stateMask & SWT.COMMAND) != 0;
// To fix SPR 110341, we consider the Alt key to be pressed only when the // To fix SPR 110341, we consider the Alt key to be pressed only when the
// Control key is _not_ also pressed. This works around a bug in SWT where, // Control key is _not_ also pressed. This works around a bug in SWT where,
// on European keyboards, the AltGr key being pressed appears to us as Control // on European keyboards, the AltGr key being pressed appears to us as Control
// + Alt being pressed simultaneously. // + Alt being pressed simultaneously.
boolean onlyAltKeyPressed = altKeyPressed && !ctrlKeyPressed; boolean altKeyPressed = (event.stateMask & SWT.ALT) != 0 && !ctrlKeyPressed;
//if (!isConnected()) { //if (!isConnected()) {
if (fState==TerminalState.CLOSED) { if (fState==TerminalState.CLOSED) {
@ -926,7 +927,8 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC
// for the Terminal view. Do not delete those tags. // for the Terminal view. Do not delete those tags.
String escSeq = null; String escSeq = null;
boolean anyModifierPressed = (event.stateMask & SWT.MODIFIER_MASK) != 0; boolean anyModifierPressed = modifierKeys != 0;
boolean onlyMacCmdKeyPressed = modifierKeys == SWT.COMMAND;
switch (event.keyCode) { switch (event.keyCode) {
case 0x1000001: // Up arrow. case 0x1000001: // Up arrow.
@ -940,22 +942,22 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC
break; break;
case 0x1000003: // Left arrow. case 0x1000003: // Left arrow.
if (ctrlKeyPressed) { if (onlyCtrlKeyPressed) {
escSeq = "\u001b[1;5D"; //$NON-NLS-1$ escSeq = "\u001b[1;5D"; //$NON-NLS-1$
} else if (!anyModifierPressed) { } else if (!anyModifierPressed) {
escSeq = "\u001b[D"; //$NON-NLS-1$ escSeq = "\u001b[D"; //$NON-NLS-1$
} else if (macCmdKeyPressed) { } else if (onlyMacCmdKeyPressed) {
// Cmd-Left is "Home" on the Mac // Cmd-Left is "Home" on the Mac
escSeq = "\u001b[H"; //$NON-NLS-1$ escSeq = "\u001b[H"; //$NON-NLS-1$
} }
break; break;
case 0x1000004: // Right arrow. case 0x1000004: // Right arrow.
if (ctrlKeyPressed) { if (onlyCtrlKeyPressed) {
escSeq = "\u001b[1;5C"; //$NON-NLS-1$ escSeq = "\u001b[1;5C"; //$NON-NLS-1$
} else if (!anyModifierPressed) { } else if (!anyModifierPressed) {
escSeq = "\u001b[C"; //$NON-NLS-1$ escSeq = "\u001b[C"; //$NON-NLS-1$
} else if (macCmdKeyPressed) { } else if (onlyMacCmdKeyPressed) {
// Cmd-Right is "End" on the Mac // Cmd-Right is "End" on the Mac
escSeq = "\u001b[F"; //$NON-NLS-1$ escSeq = "\u001b[F"; //$NON-NLS-1$
} }
@ -1067,14 +1069,14 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC
Logger.log("stateMask = " + event.stateMask); //$NON-NLS-1$ Logger.log("stateMask = " + event.stateMask); //$NON-NLS-1$
if (!altKeyPressed && ctrlKeyPressed && character == ' ') { if (onlyCtrlKeyPressed && character == ' ') {
// Send a NUL character -- many terminal emulators send NUL when // Send a NUL character -- many terminal emulators send NUL when
// Control-Space is pressed. This is used to set the mark in Emacs. // Control-Space is pressed. This is used to set the mark in Emacs.
character = '\u0000'; character = '\u0000';
} }
sendChar(character, onlyAltKeyPressed); sendChar(character, altKeyPressed);
// Special case: When we are in a TCP connection and echoing characters // Special case: When we are in a TCP connection and echoing characters
// locally, send a LF after sending a CR. // locally, send a LF after sending a CR.
@ -1102,7 +1104,7 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC
// o The character is the DELETE character. // o The character is the DELETE character.
if (getTerminalConnector() == null if (getTerminalConnector() == null
|| getTerminalConnector().isLocalEcho() == false || onlyAltKeyPressed || getTerminalConnector().isLocalEcho() == false || altKeyPressed
|| (character >= '\u0001' && character < '\t') || (character >= '\u0001' && character < '\t')
|| (character > '\t' && character < '\r') || (character > '\t' && character < '\r')
|| (character > '\r' && character <= '\u001f') || (character > '\r' && character <= '\u001f')
@ -1139,6 +1141,7 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC
IHandlerService handlerService = (IHandlerService) PlatformUI IHandlerService handlerService = (IHandlerService) PlatformUI
.getWorkbench().getAdapter(IHandlerService.class); .getWorkbench().getAdapter(IHandlerService.class);
Event cmdEvent = new Event(); Event cmdEvent = new Event();
cmdEvent.type = SWT.KeyDown;
cmdEvent.display = event.display; cmdEvent.display = event.display;
cmdEvent.widget = event.widget; cmdEvent.widget = event.widget;
cmdEvent.character = event.character; cmdEvent.character = event.character;