forked from qt-creator/qt-creator
Fix crash at shutdown if multiple windows are open
The issue is that the window actions were explicitly made children of
the ActionManager, but ActionManager is deleted earlier than the windows
closed at shutdown.
Change WindowList from a bunch of static data to an object with a
lifetime and make it own the actions itself.
Fix-up of 1b0d6e3c26
which started
deleting the actions in the first place.
Fixes: QTCREATORBUG-21221
Change-Id: I2e335887fa4b85b29bdaa2c908ec643b6abf3231
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
@@ -44,11 +44,7 @@
|
|||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC(WindowList, m_windowList)
|
||||||
QMenu *WindowList::m_dockMenu = nullptr;
|
|
||||||
QList<QWidget *> WindowList::m_windows;
|
|
||||||
QList<QAction *> WindowList::m_windowActions;
|
|
||||||
QList<Id> WindowList::m_windowActionIds;
|
|
||||||
|
|
||||||
WindowSupport::WindowSupport(QWidget *window, const Context &context)
|
WindowSupport::WindowSupport(QWidget *window, const Context &context)
|
||||||
: QObject(window),
|
: QObject(window),
|
||||||
@@ -80,7 +76,7 @@ WindowSupport::WindowSupport(QWidget *window, const Context &context)
|
|||||||
ActionManager::registerAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN, context);
|
ActionManager::registerAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN, context);
|
||||||
connect(m_toggleFullScreenAction, &QAction::triggered, this, &WindowSupport::toggleFullScreen);
|
connect(m_toggleFullScreenAction, &QAction::triggered, this, &WindowSupport::toggleFullScreen);
|
||||||
|
|
||||||
WindowList::addWindow(window);
|
m_windowList->addWindow(window);
|
||||||
|
|
||||||
connect(ICore::instance(), &ICore::coreAboutToClose, this, [this]() { m_shutdown = true; });
|
connect(ICore::instance(), &ICore::coreAboutToClose, this, [this]() { m_shutdown = true; });
|
||||||
}
|
}
|
||||||
@@ -95,7 +91,7 @@ WindowSupport::~WindowSupport()
|
|||||||
}
|
}
|
||||||
ActionManager::unregisterAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN);
|
ActionManager::unregisterAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN);
|
||||||
ICore::removeContextObject(m_contextObject);
|
ICore::removeContextObject(m_contextObject);
|
||||||
WindowList::removeWindow(m_window);
|
m_windowList->removeWindow(m_window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,12 +113,12 @@ bool WindowSupport::eventFilter(QObject *obj, QEvent *event)
|
|||||||
}
|
}
|
||||||
updateFullScreenAction();
|
updateFullScreenAction();
|
||||||
} else if (event->type() == QEvent::WindowActivate) {
|
} else if (event->type() == QEvent::WindowActivate) {
|
||||||
WindowList::setActiveWindow(m_window);
|
m_windowList->setActiveWindow(m_window);
|
||||||
} else if (event->type() == QEvent::Hide) {
|
} else if (event->type() == QEvent::Hide) {
|
||||||
// minimized windows are hidden, but we still want to show them
|
// minimized windows are hidden, but we still want to show them
|
||||||
WindowList::setWindowVisible(m_window, m_window->isMinimized());
|
m_windowList->setWindowVisible(m_window, m_window->isMinimized());
|
||||||
} else if (event->type() == QEvent::Show) {
|
} else if (event->type() == QEvent::Show) {
|
||||||
WindowList::setWindowVisible(m_window, true);
|
m_windowList->setWindowVisible(m_window, true);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -151,6 +147,11 @@ void WindowSupport::updateFullScreenAction()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowList::~WindowList()
|
||||||
|
{
|
||||||
|
qDeleteAll(m_windowActions);
|
||||||
|
}
|
||||||
|
|
||||||
void WindowList::addWindow(QWidget *window)
|
void WindowList::addWindow(QWidget *window)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_OSX
|
#ifdef Q_OS_OSX
|
||||||
@@ -163,16 +164,16 @@ void WindowList::addWindow(QWidget *window)
|
|||||||
m_windows.append(window);
|
m_windows.append(window);
|
||||||
Id id = Id("QtCreator.Window.").withSuffix(m_windows.size());
|
Id id = Id("QtCreator.Window.").withSuffix(m_windows.size());
|
||||||
m_windowActionIds.append(id);
|
m_windowActionIds.append(id);
|
||||||
auto action = new QAction(window->windowTitle(), ActionManager::instance());
|
auto action = new QAction(window->windowTitle());
|
||||||
m_windowActions.append(action);
|
m_windowActions.append(action);
|
||||||
QObject::connect(action, &QAction::triggered, [action]() { WindowList::activateWindow(action); });
|
QObject::connect(action, &QAction::triggered, [action, this]() { activateWindow(action); });
|
||||||
action->setCheckable(true);
|
action->setCheckable(true);
|
||||||
action->setChecked(false);
|
action->setChecked(false);
|
||||||
Command *cmd = ActionManager::registerAction(action, id);
|
Command *cmd = ActionManager::registerAction(action, id);
|
||||||
cmd->setAttribute(Command::CA_UpdateText);
|
cmd->setAttribute(Command::CA_UpdateText);
|
||||||
ActionManager::actionContainer(Constants::M_WINDOW)->addAction(cmd, Constants::G_WINDOW_LIST);
|
ActionManager::actionContainer(Constants::M_WINDOW)->addAction(cmd, Constants::G_WINDOW_LIST);
|
||||||
action->setVisible(window->isVisible() || window->isMinimized()); // minimized windows are hidden but should be shown
|
action->setVisible(window->isVisible() || window->isMinimized()); // minimized windows are hidden but should be shown
|
||||||
QObject::connect(window, &QWidget::windowTitleChanged, [window]() { WindowList::updateTitle(window); });
|
QObject::connect(window, &QWidget::windowTitleChanged, [window, this]() { updateTitle(window); });
|
||||||
if (m_dockMenu)
|
if (m_dockMenu)
|
||||||
m_dockMenu->addAction(action);
|
m_dockMenu->addAction(action);
|
||||||
if (window->isActiveWindow())
|
if (window->isActiveWindow())
|
||||||
|
@@ -41,19 +41,21 @@ namespace Internal {
|
|||||||
class WindowList
|
class WindowList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void addWindow(QWidget *window);
|
~WindowList();
|
||||||
static void removeWindow(QWidget *window);
|
|
||||||
static void setActiveWindow(QWidget *window);
|
void addWindow(QWidget *window);
|
||||||
static void setWindowVisible(QWidget *window, bool visible);
|
void removeWindow(QWidget *window);
|
||||||
|
void setActiveWindow(QWidget *window);
|
||||||
|
void setWindowVisible(QWidget *window, bool visible);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void activateWindow(QAction *action);
|
void activateWindow(QAction *action);
|
||||||
static void updateTitle(QWidget *window);
|
void updateTitle(QWidget *window);
|
||||||
|
|
||||||
static QMenu *m_dockMenu;
|
QMenu *m_dockMenu = nullptr;
|
||||||
static QList<QWidget *> m_windows;
|
QList<QWidget *> m_windows;
|
||||||
static QList<QAction *> m_windowActions;
|
QList<QAction *> m_windowActions;
|
||||||
static QList<Id> m_windowActionIds;
|
QList<Id> m_windowActionIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WindowSupport : public QObject
|
class WindowSupport : public QObject
|
||||||
|
Reference in New Issue
Block a user