Index: src/Application.h =================================================================== --- src/Application.h +++ src/Application.h @@ -69,8 +69,7 @@ private Q_SLOTS: void createWindow(const Profile::Ptr &profile, const QString &directory); - void detachView(Session *session); - void detachTab(ViewSplitter *splitter, QHash sessionsMap); + void detachTerminals(ViewSplitter *splitter, QHash sessionsMap); void toggleBackgroundInstance(); Index: src/Application.cpp =================================================================== --- src/Application.cpp +++ src/Application.cpp @@ -170,8 +170,7 @@ connect(window, &Konsole::MainWindow::newWindowRequest, this, &Konsole::Application::createWindow); - connect(window, &Konsole::MainWindow::viewDetached, this, &Konsole::Application::detachView); - connect(window, &Konsole::MainWindow::tabDetached, this, &Konsole::Application::detachTab); + connect(window, &Konsole::MainWindow::terminalsDetached, this, &Konsole::Application::detachTerminals); return window; } @@ -194,7 +193,7 @@ window->move(QCursor::pos()); } -void Application::detachTab(ViewSplitter *splitter, QHash sessionsMap) +void Application::detachTerminals(ViewSplitter *splitter, QHash sessionsMap) { detach(this, sender(), [=](ViewManager *manager) { foreach(TerminalDisplay* terminal, splitter->getTerminalDisplays()) { @@ -204,14 +203,6 @@ }); } -void Application::detachView(Session *session) -{ - detach(this, sender(), [=](ViewManager *manager) { - auto view = manager->createView(session); - manager->activeContainer()->addView(view); - }); -} - int Application::newInstance() { // handle session management Index: src/MainWindow.h =================================================================== --- src/MainWindow.h +++ src/MainWindow.h @@ -124,8 +124,7 @@ /** * Emitted when a view for one session is detached from this window */ - void viewDetached(Session *session); - void tabDetached(ViewSplitter *splitter, QHash sessionsMap); + void terminalsDetached(ViewSplitter *splitter, QHash sessionsMap); protected: // Reimplemented for internal reasons. Index: src/MainWindow.cpp =================================================================== --- src/MainWindow.cpp +++ src/MainWindow.cpp @@ -114,10 +114,8 @@ this, &Konsole::MainWindow::newFromProfile); connect(_viewManager, &Konsole::ViewManager::newViewRequest, this, &Konsole::MainWindow::newTab); - connect(_viewManager, &Konsole::ViewManager::viewDetached, this, - &Konsole::MainWindow::viewDetached); - connect(_viewManager, &Konsole::ViewManager::tabDetached, this, - &Konsole::MainWindow::tabDetached); + connect(_viewManager, &Konsole::ViewManager::terminalsDetached, this, + &Konsole::MainWindow::terminalsDetached); setCentralWidget(_viewManager->widget()); @@ -232,6 +230,10 @@ if (controller->isValid()) { guiFactory()->removeClient(controller); } + + if (_pluggedController == controller) { + _pluggedController = nullptr; + } } void MainWindow::activeViewChanged(SessionController *controller) @@ -862,20 +864,20 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event) { - if (obj == _pluggedController->view()) { + if (!_pluggedController.isNull() && obj == _pluggedController->view()) { switch(event->type()) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonDblClick: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonDblClick: switch(static_cast(event)->button()) { - case Qt::ForwardButton: - triggerAction(QStringLiteral("next-view")); - break; - case Qt::BackButton: - triggerAction(QStringLiteral("previous-view")); - break; - default: ; + case Qt::ForwardButton: + triggerAction(QStringLiteral("next-view")); + break; + case Qt::BackButton: + triggerAction(QStringLiteral("previous-view")); + break; + default: ; } - default: ; + default: ; } } Index: src/ViewContainer.h =================================================================== --- src/ViewContainer.h +++ src/ViewContainer.h @@ -193,7 +193,9 @@ * @param fromIndex Current index of the widget to move * @param toIndex New index for the widget */ +#if 0 void moveViewWidget(int fromIndex, int toIndex); +#endif // close tabs and unregister void closeTerminalTab(int idx); Index: src/ViewContainer.cpp =================================================================== --- src/ViewContainer.cpp +++ src/ViewContainer.cpp @@ -48,6 +48,8 @@ #include "DetachableTabBar.h" #include "TerminalDisplay.h" #include "ViewSplitter.h" +#include "MainWindow.h" +#include "Session.h" // TODO Perhaps move everything which is Konsole-specific into different files @@ -158,20 +160,21 @@ void TabbedViewContainer::moveTabToWindow(int index, QWidget *window) { - // TODO: Fix Detaching. - /* - const int id = terminalAt(index)->sessionController()->identifier(); - // This one line here will be removed as soon as I finish my new split handling. - // it's hacky but it works. - const auto widgets = window->findChildren(); - const auto currentPos = QCursor::pos(); - for(const auto dropWidget : widgets) { - if (dropWidget->rect().contains(dropWidget->mapFromGlobal(currentPos))) { - emit dropWidget->moveViewRequest(-1, id); - removeView(terminalAt(index)); - } + auto splitter = viewSplitterAt(index); + auto manager = window->findChild(); + + QHash sessionsMap = _connectedViewManager->forgetAll(splitter); + + foreach(TerminalDisplay* terminal, splitter->getTerminalDisplays()) { + manager->attachView(terminal, sessionsMap[terminal]); } - */ + auto container = manager->activeContainer(); + container->addSplitter(splitter); + + auto controller = splitter->activeTerminalDisplay()->sessionController(); + container->currentSessionControllerChanged(controller); + + forgetView(splitter); } void TabbedViewContainer::konsoleConfigChanged() Index: src/ViewManager.h =================================================================== --- src/ViewManager.h +++ src/ViewManager.h @@ -196,13 +196,14 @@ /** Reorder the terminal display history list */ void updateTerminalDisplayHistory(TerminalDisplay *terminalDisplay = nullptr, bool remove = false); + QHash forgetAll(ViewSplitter* splitter); + Session* forgetTerminal(TerminalDisplay* terminal); Q_SIGNALS: /** Emitted when the last view is removed from the view manager */ void empty(); /** Emitted when a session is detached from a view owned by this ViewManager */ - void viewDetached(Session *session); - void tabDetached(ViewSplitter *splitter, QHash sessionsMap); + void terminalsDetached(ViewSplitter *splitter, QHash sessionsMap); /** * Emitted when the active view changes. @@ -388,9 +389,10 @@ // called when a ViewContainer requests a view be // moved + #if 0 void containerMoveViewRequest(int index, int sessionControllerId); - - void detachView(TabbedViewContainer *container, QWidget *view); + #endif +// void detachView(TabbedViewContainer *container, TerminalDisplay *view); /* Detaches the tab at index tabIdx */ void detachTab(int tabIdx); @@ -420,6 +422,7 @@ // actions associated with that view, and exposes basic information // about the session ( such as title and associated icon ) to the display. SessionController *createController(Session *session, TerminalDisplay *view); + void removeController(SessionController* controller); // Activates a different terminal when the TerminalDisplay // closes or is detached and another one should be focused. Index: src/ViewManager.cpp =================================================================== --- src/ViewManager.cpp +++ src/ViewManager.cpp @@ -405,10 +405,18 @@ void ViewManager::detachActiveView() { +#if !defined(ENABLE_DETACHING) + return; +#endif // find the currently active view and remove it from its container - TabbedViewContainer *container = _viewContainer; - if ((container->findChildren()).count() > 1) { - detachView(container, container->activeViewSplitter()->activeTerminalDisplay()); + if ((_viewContainer->findChildren()).count() > 1) { + auto activeSplitter = _viewContainer->activeViewSplitter(); + auto terminal = activeSplitter->activeTerminalDisplay(); + auto newSplitter = new ViewSplitter(); + newSplitter->addTerminalDisplay(terminal, Qt::Horizontal); + QHash detachedSessions = forgetAll(newSplitter); + emit terminalsDetached(newSplitter, detachedSessions); + focusAnotherTerminal(activeSplitter->getToplevelSplitter()); } } @@ -423,59 +431,32 @@ #if !defined(ENABLE_DETACHING) return; #endif + ViewSplitter* splitter = _viewContainer->viewSplitterAt(tabIdx); + QHash detachedSessions = forgetAll(_viewContainer->viewSplitterAt(tabIdx)); + emit terminalsDetached(splitter, detachedSessions); +} - auto splitter = _viewContainer->viewSplitterAt(tabIdx); +QHash ViewManager::forgetAll(ViewSplitter* splitter) { splitter->setParent(nullptr); auto terminals = splitter->getTerminalDisplays(); QHash detachedSessions; foreach(TerminalDisplay* terminal, terminals) { - auto session = _sessionMap.take(terminal); + Session* session = forgetTerminal(terminal); detachedSessions[terminal] = session; - if (session != nullptr) { - disconnect(session, &Konsole::Session::finished, this, &Konsole::ViewManager::sessionFinished); - _viewContainer->disconnectTerminalDisplay(terminal); - } - auto controller = terminal->sessionController(); - controller->deleteLater(); - updateTerminalDisplayHistory(terminal, true); } - emit tabDetached(splitter, detachedSessions); - focusAnotherTerminal(splitter); + return detachedSessions; } -void ViewManager::detachView(TabbedViewContainer *container, QWidget *view) +Session* ViewManager::forgetTerminal(TerminalDisplay* terminal) { -#if !defined(ENABLE_DETACHING) - return; -#endif - - auto *viewToDetach = qobject_cast(view); - - if (viewToDetach == nullptr) { - return; - } - - // BR390736 - some instances are sending invalid session to viewDetached() - Session *sessionToDetach = _sessionMap[viewToDetach]; - if (sessionToDetach == nullptr) { - return; + removeController(terminal->sessionController()); + auto session = _sessionMap.take(terminal); + if (session != nullptr) { + disconnect(session, &Konsole::Session::finished, this, &Konsole::ViewManager::sessionFinished); } - - disconnect(sessionToDetach, &Konsole::Session::finished, this, &Konsole::ViewManager::sessionFinished); - - emit viewDetached(sessionToDetach); - - _sessionMap.remove(viewToDetach); - - // Remove this view from history - updateTerminalDisplayHistory(viewToDetach, true); - - // remove the view from this window - container->removeView(viewToDetach); - viewToDetach->setScreenWindow(nullptr); - viewToDetach->deleteLater(); - - focusAnotherTerminal(container->activeViewSplitter()); + _viewContainer->disconnectTerminalDisplay(terminal); + updateTerminalDisplayHistory(terminal, true); + return session; } void ViewManager::sessionFinished() @@ -610,6 +591,17 @@ return controller; } +// should this be handed by ViewManager::unplugController signal +void ViewManager::removeController(SessionController* controller) +{ + disconnect(controller, &Konsole::SessionController::focused, this, + &Konsole::ViewManager::controllerChanged); + if (_pluggedController == controller) { + _pluggedController = nullptr; + } + controller->deleteLater(); +} + void ViewManager::controllerChanged(SessionController *controller) { if (controller == _pluggedController) { @@ -632,9 +624,10 @@ void ViewManager::attachView(TerminalDisplay *terminal, Session *session) { - createController(session, terminal); - connect(session, &Konsole::Session::finished, this, &Konsole::ViewManager::sessionFinished, Qt::UniqueConnection); + connect(session, &Konsole::Session::finished, this, &Konsole::ViewManager::sessionFinished, + Qt::UniqueConnection); _sessionMap[terminal] = session; + createController(session, terminal); updateDetachViewState(); _terminalDisplayHistory.append(terminal); } @@ -674,7 +667,6 @@ { auto *container = new TabbedViewContainer(this, nullptr); container->setNavigationVisibility(_navigationVisibility); - //TODO: Fix Detaching. connect(container, &TabbedViewContainer::detachTab, this, &ViewManager::detachTab); // connect signals and slots @@ -692,8 +684,10 @@ this, &ViewManager::newViewRequest); connect(container, &Konsole::TabbedViewContainer::newViewWithProfileRequest, this, &Konsole::ViewManager::newViewWithProfileRequest); +#if 0 connect(container, &Konsole::TabbedViewContainer::moveViewRequest, this, &Konsole::ViewManager::containerMoveViewRequest); +#endif connect(container, &Konsole::TabbedViewContainer::viewRemoved, this, &Konsole::ViewManager::viewDestroyed); connect(container, &Konsole::TabbedViewContainer::activeViewChanged, this, @@ -702,6 +696,7 @@ return container; } +#if 0 void ViewManager::containerMoveViewRequest(int index, int id) { Q_UNUSED(index); @@ -715,6 +710,7 @@ controller->session()->refresh(); container->currentWidget()->setFocus(); } +#endif void ViewManager::setNavigationMethod(NavigationMethod method) {