From 0e02e7fcf386e89560b65556f2759268b512451c Mon Sep 17 00:00:00 2001 From: Anton Leherbauer Date: Tue, 13 May 2014 12:00:25 +0200 Subject: [PATCH] Terminal: Bug 434478 Stop capturing key events in disconnected state In disconnected state no input is accepted by the terminal, therefore key bindings are allowed to be processed by Eclipse. Change-Id: I119a25ce9cf366eefe92d2d9490472280e6dfd79 Signed-off-by: Anton Leherbauer --- .../emulator/VT100TerminalControl.java | 81 ++++++++++++------- 1 file changed, 51 insertions(+), 30 deletions(-) diff --git a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100TerminalControl.java b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100TerminalControl.java index d8016fe8472..b00380e79cd 100644 --- a/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100TerminalControl.java +++ b/terminal/plugins/org.eclipse.tm.terminal/src/org/eclipse/tm/internal/terminal/emulator/VT100TerminalControl.java @@ -133,7 +133,7 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC private KeyListener fKeyHandler; private final ITerminalListener fTerminalListener; private String fMsg = ""; //$NON-NLS-1$ - private FocusListener fFocusListener; + private TerminalFocusListener fFocusListener; private ITerminalConnector fConnector; private final ITerminalConnector[] fConnectors; private final boolean fUseCommonPrefs; @@ -456,9 +456,13 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC disconnectTerminal(); return; } - getCtlText().setFocus(); + if (getCtlText().isFocusControl()) { + if (getState() == TerminalState.CONNECTED) + fFocusListener.captureKeyEvents(true); + } else { + getCtlText().setFocus(); + } startReaderJob(); - } private synchronized void startReaderJob() { @@ -804,8 +808,8 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC return fTerminalText; } protected class TerminalFocusListener implements FocusListener { - private IContextActivation contextActivation = null; - private IContextActivation contextActivation1 = null; + private IContextActivation terminalContextActivation = null; + private IContextActivation editContextActivation = null; protected TerminalFocusListener() { super(); @@ -815,40 +819,50 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC // Disable all keyboard accelerators (e.g., Control-B) so the Terminal view // can see every keystroke. Without this, Emacs, vi, and Bash are unusable // in the Terminal view. - - IBindingService bindingService = (IBindingService) PlatformUI - .getWorkbench().getAdapter(IBindingService.class); - bindingService.setKeyFilterEnabled(false); - - // The above code fails to cause Eclipse to disable menu-activation - // accelerators (e.g., Alt-F for the File menu), so we set the command - // context to be the Terminal view's command context. This enables us to - // override menu-activation accelerators with no-op commands in our - // plugin.xml file, which enables the Terminal view to see absolutly _all_ - // key-presses. + if (getState() == TerminalState.CONNECTED) + captureKeyEvents(true); IContextService contextService = (IContextService) PlatformUI .getWorkbench().getAdapter(IContextService.class); - contextActivation = contextService - .activateContext("org.eclipse.tm.terminal.TerminalContext"); //$NON-NLS-1$ - contextActivation1 = contextService + editContextActivation = contextService .activateContext("org.eclipse.tm.terminal.EditContext"); //$NON-NLS-1$ - } public void focusLost(FocusEvent event) { // Enable all keybindings. - - IBindingService bindingService = (IBindingService) PlatformUI - .getWorkbench().getAdapter(IBindingService.class); - bindingService.setKeyFilterEnabled(true); + captureKeyEvents(false); // Restore the command context to its previous value. IContextService contextService = (IContextService) PlatformUI .getWorkbench().getAdapter(IContextService.class); - contextService.deactivateContext(contextActivation); - contextService.deactivateContext(contextActivation1); + contextService.deactivateContext(editContextActivation); + } + + protected void captureKeyEvents(boolean capture) { + IBindingService bindingService = (IBindingService) PlatformUI + .getWorkbench().getAdapter(IBindingService.class); + IContextService contextService = (IContextService) PlatformUI + .getWorkbench().getAdapter(IContextService.class); + + boolean enableKeyFilter = !capture; + if (bindingService.isKeyFilterEnabled() != enableKeyFilter) + bindingService.setKeyFilterEnabled(enableKeyFilter); + + if (capture && terminalContextActivation == null) { + // The above code fails to cause Eclipse to disable menu-activation + // accelerators (e.g., Alt-F for the File menu), so we set the command + // context to be the Terminal view's command context. This enables us to + // override menu-activation accelerators with no-op commands in our + // plugin.xml file, which enables the Terminal view to see absolutely _all_ + // key-presses. + terminalContextActivation = contextService + .activateContext("org.eclipse.tm.terminal.TerminalContext"); //$NON-NLS-1$ + + } else if (!capture && terminalContextActivation != null) { + contextService.deactivateContext(terminalContextActivation); + terminalContextActivation = null; + } } } @@ -1179,9 +1193,17 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC // enable the (blinking) cursor if the terminal is connected runAsyncInDisplayThread(new Runnable() { public void run() { - if(fCtlText!=null && !fCtlText.isDisposed()) - fCtlText.setCursorEnabled(isConnected()); - }}); + if(fCtlText!=null && !fCtlText.isDisposed()) { + if (isConnected()) { + fCtlText.setCursorEnabled(true); + } else { + fCtlText.setCursorEnabled(false); + // Stop capturing all key events + fFocusListener.captureKeyEvents(false); + } + } + } + }); } /** * @param runnable run in display thread @@ -1266,5 +1288,4 @@ public class VT100TerminalControl implements ITerminalControlForText, ITerminalC return getTerminalText().isVT100LineWrapping(); } - }