1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-01 05:15:43 +02:00

Bug 458625 - Terminals view leaks SWT controls when closing a tab

This commit is contained in:
Anton Leherbauer 2015-02-23 14:07:47 +01:00
parent 66a467ab1b
commit 4e2c2046d2
4 changed files with 43 additions and 13 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2011 - 2015 Wind River Systems, Inc. and others. All rights reserved.
* Copyright (c) 2011, 2015 Wind River Systems, Inc. and others. All rights reserved.
* This program and the accompanying materials are made available under the terms
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
@ -13,6 +13,7 @@ import org.eclipse.core.runtime.Assert;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Control;
import org.eclipse.tcf.te.core.terminals.TerminalServiceFactory;
import org.eclipse.tcf.te.core.terminals.interfaces.ITerminalService;
import org.eclipse.tcf.te.ui.terminals.services.TerminalService;
@ -56,6 +57,9 @@ public class TabDisposeListener implements DisposeListener {
if (candidate instanceof ITerminalViewControl) ((ITerminalViewControl)candidate).disposeTerminal();
// Dispose the command input field handler
parentTabFolderManager.disposeTabCommandFieldHandler((CTabItem)e.getSource());
// Dispose the tab item control
Control control = ((CTabItem) e.getSource()).getControl();
if (control != null) control.dispose();
// If all items got removed, we have to switch back to the empty page control
if (parentTabFolderManager.getTabFolder() != null && parentTabFolderManager.getTabFolder().getItemCount() == 0) {

View file

@ -47,7 +47,6 @@ import org.eclipse.tcf.te.ui.terminals.nls.Messages;
import org.eclipse.tm.internal.terminal.control.ITerminalListener;
import org.eclipse.tm.internal.terminal.control.ITerminalViewControl;
import org.eclipse.tm.internal.terminal.control.TerminalViewControlFactory;
import org.eclipse.tm.internal.terminal.emulator.VT100TerminalControl;
import org.eclipse.tm.internal.terminal.provisional.api.ITerminalConnector;
import org.eclipse.tm.internal.terminal.provisional.api.ITerminalControl;
import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
@ -364,6 +363,8 @@ public class TabFolderManager extends PlatformObject implements ISelectionProvid
// Setup the tab item listeners
setupTerminalTabListeners(item);
// Move the terminal listener to the new item
TabTerminalListener.move(oldItem, item);
// Create the composite to create the terminal control within
Composite composite = new Composite(tabFolder, SWT.NONE);
@ -374,12 +375,12 @@ public class TabFolderManager extends PlatformObject implements ISelectionProvid
// Refresh the layout
tabFolder.getParent().layout(true);
// Remember terminal state
TerminalState oldState = terminal.getState();
// change the "parent".
//
// Note: We have to cast to VT100TerminalControl here until setupTerminal is
// re-exposed to clients via the ITerminalControl.
Assert.isTrue(terminal instanceof VT100TerminalControl);
((VT100TerminalControl)terminal).setupTerminal(composite);
Assert.isTrue(terminal instanceof ITerminalControl);
((ITerminalControl)terminal).setupTerminal(composite);
item.setData(terminal);
@ -422,7 +423,7 @@ public class TabFolderManager extends PlatformObject implements ISelectionProvid
// needed to get the focus and cursor
Assert.isTrue(terminal instanceof ITerminalControl);
((ITerminalControl)terminal).setState(TerminalState.CONNECTED);
((ITerminalControl)terminal).setState(oldState);
// Fire selection changed event
fireSelectionChanged();

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2011, 2012 Wind River Systems, Inc. and others. All rights reserved.
* Copyright (c) 2011, 2015 Wind River Systems, Inc. and others. All rights reserved.
* This program and the accompanying materials are made available under the terms
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
@ -23,10 +23,24 @@ import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
*/
@SuppressWarnings("restriction")
public class TabTerminalListener implements ITerminalListener {
private static final String TAB_TERMINAL_LISTENER = "TabTerminalListener"; //$NON-NLS-1$
/* default */ final TabFolderManager tabFolderManager;
private final CTabItem tabItem;
private CTabItem tabItem;
private final String tabItemTitle;
/**
* Move a TabTerminalListener instance to another item (for DnD).
*
* @param fromItem item to detach the listener from
* @param toItem item to attach listener to
*/
static void move(CTabItem fromItem, CTabItem toItem) {
TabTerminalListener listener = (TabTerminalListener) fromItem.getData(TAB_TERMINAL_LISTENER);
if (listener != null) {
listener.attachTo(toItem);
}
}
/**
* Constructor.
*
@ -36,12 +50,18 @@ public class TabTerminalListener implements ITerminalListener {
public TabTerminalListener(TabFolderManager tabFolderManager, CTabItem tabItem) {
super();
Assert.isNotNull(tabFolderManager);
this.tabFolderManager = tabFolderManager;
Assert.isNotNull(tabItem);
this.tabItem = tabItem;
this.tabFolderManager = tabFolderManager;
// Remember the original tab item title
tabItemTitle = tabItem.getText();
attachTo(tabItem);
}
private void attachTo(CTabItem item) {
if (tabItem != null) tabItem.setData(TAB_TERMINAL_LISTENER, null);
item.setData(TAB_TERMINAL_LISTENER, this);
tabItem = item;
}
/**

View file

@ -302,6 +302,11 @@ public class TerminalsView extends ViewPart implements ITerminalsView, IShowInTa
tabFolderManager.bringToTop(item);
switchToTabFolderControl();
// dispose tab item control
final Control control = draggedItem.getControl();
draggedItem.setControl(null);
if (control != null) control.dispose();
// need to remove the dispose listener first
DisposeListener disposeListener = (DisposeListener) draggedItem.getData("disposeListener"); //$NON-NLS-1$
draggedItem.removeDisposeListener(disposeListener);