2
0
Эх сурвалжийг харах

Material Canvas: Fixing graph canvas crashes on shut down

The first issue was improper widget cleanup and some recently added code for adding the color picker button to the graph canvas vector property display class.

The second issue was caused by trying to access clipboard mime data before the application exits. In this case, I just clear the clipboard when the application is being destroyed.

Set up other widget parents to make sure they were cleaned up correctly while debugging the previously mentioned problems.

Signed-off-by: gadams3 <[email protected]>
gadams3 2 жил өмнө
parent
commit
f1e5586ca8

+ 4 - 0
Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp

@@ -39,6 +39,7 @@
 #include "AtomToolsFramework_Traits_Platform.h"
 
 AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT
+#include <QClipboard>
 #include <QMessageBox>
 #include <QObject>
 AZ_POP_DISABLE_WARNING
@@ -237,6 +238,9 @@ namespace AtomToolsFramework
 
     void AtomToolsApplication::Destroy()
     {
+        // Clearing graph canvas clipboard mime data for copied nodes before exiting the application to prevent a crash in qt_call_post_routines
+        QApplication::clipboard()->clear();
+
         m_assetBrowserInteractions.reset();
         m_styleManager.reset();
 

+ 5 - 5
Gems/Atom/Tools/AtomToolsFramework/Code/Source/GraphView/GraphView.cpp

@@ -56,10 +56,11 @@ namespace AtomToolsFramework
         setLayout(new QVBoxLayout());
 
         m_editorToolbar = aznew GraphCanvas::AssetEditorToolbar(m_toolId);
+        m_editorToolbar->setParent(this);
         layout()->addWidget(m_editorToolbar);
 
         // Screenshot
-        m_takeScreenshot = new QToolButton();
+        m_takeScreenshot = new QToolButton(m_editorToolbar);
         m_takeScreenshot->setToolTip("Captures a full resolution screenshot of the entire graph or selected nodes into the clipboard");
         m_takeScreenshot->setIcon(QIcon(":/Icons/screenshot.png"));
         m_takeScreenshot->setEnabled(false);
@@ -74,10 +75,10 @@ namespace AtomToolsFramework
         m_graphicsView->SetEditorId(m_toolId);
         layout()->addWidget(m_graphicsView);
 
-        m_presetEditor = aznew GraphCanvas::ConstructPresetDialog(nullptr);
+        m_presetEditor = aznew GraphCanvas::ConstructPresetDialog(this);
         m_presetEditor->SetEditorId(m_toolId);
 
-        m_presetWrapper = new AzQtComponents::WindowDecorationWrapper(AzQtComponents::WindowDecorationWrapper::OptionAutoTitleBarButtons);
+        m_presetWrapper = new AzQtComponents::WindowDecorationWrapper(AzQtComponents::WindowDecorationWrapper::OptionAutoTitleBarButtons, this);
         m_presetWrapper->setGuest(m_presetEditor);
         m_presetWrapper->hide();
 
@@ -610,8 +611,7 @@ namespace AtomToolsFramework
 
                     for (GraphCanvas::Endpoint proposedEndpoint : endpoints)
                     {
-                        QAction* action = aznew GraphCanvas::EndpointSelectionAction(proposedEndpoint);
-                        menu.addAction(action);
+                        menu.addAction(aznew GraphCanvas::EndpointSelectionAction(proposedEndpoint));
                     }
 
                     QAction* result = menu.exec(screenPoint);

+ 1 - 1
Gems/Atom/Tools/MaterialCanvas/Code/Source/MaterialCanvasApplication.cpp

@@ -175,7 +175,7 @@ namespace MaterialCanvas
         // Overriding documentview factory function to create graph view
         documentTypeInfo.m_documentViewFactoryCallback = [this, graphViewConfig](const AZ::Crc32& toolId, const AZ::Uuid& documentId)
         {
-            return m_window->AddDocumentTab(documentId, aznew MaterialCanvasGraphView(toolId, documentId, graphViewConfig));
+            return m_window->AddDocumentTab(documentId, aznew MaterialCanvasGraphView(toolId, documentId, graphViewConfig, m_window.get()));
         };
 
         AtomToolsFramework::AtomToolsDocumentSystemRequestBus::Event(

+ 11 - 14
Gems/GraphCanvas/Code/Source/Components/NodePropertyDisplays/VectorNodePropertyDisplay.cpp

@@ -355,14 +355,14 @@ namespace GraphCanvas
         {
             m_proxyWidget = new QGraphicsProxyWidget();
 
-            QWidget* widgetContainer  = new QWidget(nullptr);
-            QHBoxLayout* layout = new QHBoxLayout(widgetContainer);
-            widgetContainer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
-            
+            m_widgetContainer = new QWidget();
+            QHBoxLayout* layout = new QHBoxLayout(m_widgetContainer);
+            m_widgetContainer->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
+
             layout->setAlignment(Qt::AlignLeft);
             layout->setContentsMargins(0, 0, 0, 0);
 
-            m_button = new QToolButton();
+            m_button = new QToolButton(m_widgetContainer);
             m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
             m_button->setVisible(false);
             QObject::connect(m_button, &QToolButton::clicked, [this] () {
@@ -378,7 +378,7 @@ namespace GraphCanvas
             m_proxyWidget->setAcceptDrops(false);
 
             const int elementCount = m_dataInterface->GetElementCount();
-            m_propertyVectorCtrl = new AzQtComponents::VectorInput(nullptr, elementCount);
+            m_propertyVectorCtrl = new AzQtComponents::VectorInput(m_widgetContainer, elementCount);
 
             for (int i = 0; i < elementCount; ++i)
             {
@@ -394,8 +394,8 @@ namespace GraphCanvas
             QObject::connect(m_propertyVectorCtrl, &AzQtComponents::VectorInput::editingFinished, [this]() { SubmitValue(); });
 
             layout->addWidget(m_propertyVectorCtrl);
-            widgetContainer->setProperty("HasNoWindowDecorations", true);
-            m_proxyWidget->setWidget(widgetContainer);
+            m_widgetContainer->setProperty("HasNoWindowDecorations", true);
+            m_proxyWidget->setWidget(m_widgetContainer);
             
             UpdateDisplay();
             RefreshStyle();
@@ -408,15 +408,12 @@ namespace GraphCanvas
         if (m_propertyVectorCtrl)
         {
             UnregisterShortcutDispatcher(m_propertyVectorCtrl);
-            delete m_propertyVectorCtrl; // NB: this implicitly deletes m_proxy widget
+            delete m_widgetContainer; // NB: this implicitly deletes m_proxy widget
+            m_widgetContainer = nullptr;
             m_propertyVectorCtrl = nullptr;
+            m_button= nullptr;
             m_proxyWidget = nullptr;
         }
-        if (m_button) 
-        {
-            delete m_button;
-            m_button = nullptr;
-        }
     }
 
 #include <Source/Components/NodePropertyDisplays/moc_VectorNodePropertyDisplay.cpp>

+ 14 - 12
Gems/GraphCanvas/Code/Source/Components/NodePropertyDisplays/VectorNodePropertyDisplay.h

@@ -120,17 +120,19 @@ namespace GraphCanvas
         void SubmitValue();
     
         Styling::StyleHelper m_styleHelper;
-        VectorDataInterface*  m_dataInterface;
-        
-        GraphCanvasLabel*                           m_disabledLabel;
-        AzQtComponents::VectorInput*                m_propertyVectorCtrl;
-        QToolButton*                                m_button;
-        QGraphicsProxyWidget*                       m_proxyWidget;
-        
-        QGraphicsWidget*                            m_displayWidget;
-        IconLayoutItem*                             m_iconDisplay;
-        AZStd::vector< ReadOnlyVectorControl* >     m_vectorDisplays;
+        VectorDataInterface* m_dataInterface{};
+
+        QWidget* m_widgetContainer{};
+
+        GraphCanvasLabel* m_disabledLabel{};
+        AzQtComponents::VectorInput* m_propertyVectorCtrl{};
+        QToolButton* m_button{};
+        QGraphicsProxyWidget* m_proxyWidget{};
+
+        QGraphicsWidget* m_displayWidget{};
+        IconLayoutItem* m_iconDisplay{};
+        AZStd::vector<ReadOnlyVectorControl*> m_vectorDisplays{};
 
-        bool                                        m_releaseLayout;
+        bool m_releaseLayout{};
     };
-}
+} // namespace GraphCanvas

+ 2 - 2
Gems/GraphCanvas/Code/StaticLib/GraphCanvas/Widgets/AssetEditorToolbar/AssetEditorToolbar.cpp

@@ -39,7 +39,7 @@ namespace GraphCanvas
         QObject::connect(m_ui->groupNodes, &QToolButton::clicked, this, &AssetEditorToolbar::GroupSelection);
         QObject::connect(m_ui->ungroupNodes, &QToolButton::clicked, this, &AssetEditorToolbar::UngroupSelection);
 
-        m_commentPresetsMenu = aznew EditorContextMenu(editorId);
+        m_commentPresetsMenu = aznew EditorContextMenu(editorId, this);
         m_commentPresetsMenu->SetIsToolBarMenu(true);
 
         QObject::connect(m_commentPresetsMenu, &QMenu::aboutToShow, this, &AssetEditorToolbar::OnCommentMenuAboutToShow);
@@ -49,7 +49,7 @@ namespace GraphCanvas
         m_ui->addComment->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
         QObject::connect(m_ui->addComment, &QWidget::customContextMenuRequested, this, &AssetEditorToolbar::OnCommentPresetsContextMenu);
 
-        m_nodeGroupPresetsMenu = aznew EditorContextMenu(editorId);
+        m_nodeGroupPresetsMenu = aznew EditorContextMenu(editorId, this);
         m_nodeGroupPresetsMenu->SetIsToolBarMenu(true);
 
         QObject::connect(m_nodeGroupPresetsMenu, &QMenu::aboutToShow, this, &AssetEditorToolbar::OnNodeGroupMenuAboutToShow);