diff --git a/src/ViewContainer.cpp b/src/ViewContainer.cpp index 79c24d5c9..d425e0e54 100644 --- a/src/ViewContainer.cpp +++ b/src/ViewContainer.cpp @@ -153,39 +153,27 @@ void ViewContainer::addView(QWidget* view , ViewProperties* item, int index) void ViewContainer::viewDestroyed(QObject* object) { QWidget* widget = static_cast(object); - - _views.removeAll(widget); - _navigation.remove(widget); - - // FIXME This can result in ViewContainerSubClass::removeViewWidget() being - // called after the widget's parent has been deleted or partially deleted - // in the ViewContainerSubClass instance's destructor. - // - // Currently deleteLater() is used to remove child widgets in the subclass - // constructors to get around the problem, but this is a hack and needs - // to be fixed. - removeViewWidget(widget); - - emit viewRemoved(widget); - - if (_views.count() == 0) - emit empty(this); + forgetView(widget); } -void ViewContainer::removeView(QWidget* view) + +void ViewContainer::forgetView(QWidget* view) { _views.removeAll(view); _navigation.remove(view); - disconnect(view, &QWidget::destroyed, this, &Konsole::ViewContainer::viewDestroyed); - - removeViewWidget(view); - emit viewRemoved(view); if (_views.count() == 0) emit empty(this); } +void ViewContainer::removeView(QWidget* view) +{ + disconnect(view, &QWidget::destroyed, this, &Konsole::ViewContainer::viewDestroyed); + removeViewWidget(view); + forgetView(view); +} + const QList ViewContainer::views() const { return _views; @@ -264,6 +252,7 @@ TabbedViewContainer::TabbedViewContainer(NavigationPosition position, ViewManage { _containerWidget = new QWidget; _stackWidget = new QStackedWidget(); + connect(_stackWidget.data(), &QStackedWidget::widgetRemoved, this, &TabbedViewContainer::widgetRemoved); // The tab bar _tabBar = new ViewContainerTabBar(_containerWidget, this); @@ -649,15 +638,18 @@ void TabbedViewContainer::addViewWidget(QWidget* view , int index) if (navigationVisibility() == ShowNavigationAsNeeded) dynamicTabBarVisibility(); } + void TabbedViewContainer::removeViewWidget(QWidget* view) { if (!_stackWidget) return; - const int index = _stackWidget->indexOf(view); + _stackWidget->removeWidget(view); +} +void TabbedViewContainer::widgetRemoved(int index) +{ Q_ASSERT(index != -1); - _stackWidget->removeWidget(view); _tabBar->removeTab(index); if (navigationVisibility() == ShowNavigationAsNeeded) @@ -754,11 +746,5 @@ void StackedViewContainer::removeViewWidget(QWidget* view) { if (!_stackWidget) return; - const int index = _stackWidget->indexOf(view); - - Q_ASSERT(index != -1); - Q_UNUSED(index); - _stackWidget->removeWidget(view); } - diff --git a/src/ViewContainer.h b/src/ViewContainer.h index 60d2bd9ef..bd6b5cc5f 100644 --- a/src/ViewContainer.h +++ b/src/ViewContainer.h @@ -342,6 +342,8 @@ private slots: void searchBarDestroyed(); private: + void forgetView(QWidget* view); + NavigationVisibility _navigationVisibility; NavigationPosition _navigationPosition; QList _views; @@ -417,6 +419,7 @@ private: void setTabActivity(int index, bool activity); void renameTab(int index); void updateVisibilityOfQuickButtons(); + void widgetRemoved(int index); ViewContainerTabBar* _tabBar; QPointer _stackWidget; diff --git a/src/ViewManager.cpp b/src/ViewManager.cpp index 75473e9c2..359aa0651 100644 --- a/src/ViewManager.cpp +++ b/src/ViewManager.cpp @@ -386,23 +386,6 @@ void ViewManager::sessionFinished() emit unplugController(_pluggedController); } -void ViewManager::focusActiveView() -{ - // give the active view in a container the focus. this ensures - // that controller associated with that view is activated and the session-specific - // menu items are replaced with the ones for the newly focused view - - // see the viewFocused() method - - ViewContainer* container = _viewSplitter->activeContainer(); - if (container) { - QWidget* activeView = container->activeView(); - if (activeView) { - activeView->setFocus(Qt::MouseFocusReason); - } - } -} - void ViewManager::viewActivated(QWidget* view) { Q_ASSERT(view != 0); @@ -761,14 +744,11 @@ void ViewManager::viewDestroyed(QWidget* view) Session* session = _sessionMap[ display ]; _sessionMap.remove(display); if (session) { - display->deleteLater(); - if (session->views().count() == 0) session->close(); } //we only update the focus if the splitter is still alive if (_viewSplitter) { - focusActiveView(); updateDetachViewState(); } // The below causes the menus to be messed up diff --git a/src/ViewManager.h b/src/ViewManager.h index 047b7ee6a..ee8647181 100644 --- a/src/ViewManager.h +++ b/src/ViewManager.h @@ -346,7 +346,6 @@ private: static const ColorScheme* colorSchemeForProfile(const Profile::Ptr profile); void setupActions(); - void focusActiveView(); // takes a view from a view container owned by a different manager and places it in // newContainer owned by this manager diff --git a/src/ViewSplitter.cpp b/src/ViewSplitter.cpp index bfc727e5f..d558ca3f0 100644 --- a/src/ViewSplitter.cpp +++ b/src/ViewSplitter.cpp @@ -85,8 +85,13 @@ ViewSplitter* ViewSplitter::activeSplitter() void ViewSplitter::registerContainer(ViewContainer* container) { _containers << container; - connect(container , static_cast(&Konsole::ViewContainer::destroyed) , this , &Konsole::ViewSplitter::containerDestroyed); - connect(container , &Konsole::ViewContainer::empty , this , &Konsole::ViewSplitter::containerEmpty); + // Connecting to container::destroyed() using the new-style connection + // syntax causes a crash at exit. I don't know why. Using the old-style + // syntax works. + //connect(container , static_cast(&Konsole::ViewContainer::destroyed) , this , &Konsole::ViewSplitter::containerDestroyed); + //connect(container , &Konsole::ViewContainer::empty , this , &Konsole::ViewSplitter::containerEmpty); + connect(container , SIGNAL(destroyed(ViewContainer*)) , this , SLOT(containerDestroyed(ViewContainer*))); + connect(container , SIGNAL(empty(ViewContainer*)) , this , SLOT(containerEmpty(ViewContainer*))); } void ViewSplitter::unregisterContainer(ViewContainer* container)