# Buggy code
def closeEvent(self, event):
    app = get_app()
    # Some window managers handels dragging of the modal messages incorrectly if other windows are open
    # Hide tutorial window first
    self.tutorial_manager.hide_dialog()

    # Prompt user to save (if needed)
    if app.project.needs_save() and self.mode != "unittest":
        log.info("Prompt user to save project")
        # Translate object
        _ = app._tr

        # Handle exception
        ret = QMessageBox.question(
            self,
            _("Unsaved Changes"),
            _("Save changes to project before closing?"),
            QMessageBox.Cancel | QMessageBox.No | QMessageBox.Yes,
        )
        if ret == QMessageBox.Yes:
            # Save project
            self.actionSave_trigger()
            event.accept()
        elif ret == QMessageBox.Cancel:
            # Show tutorial again, if any
            self.tutorial_manager.re_show_dialog()
            # User canceled prompt - don't quit
            event.ignore()
            return

    # Log the exit routine
    log.info("---------------- Shutting down -----------------")

    # Close any tutorial dialogs
    self.tutorial_manager.exit_manager()

    # Save settings
    self.save_settings()

    # Track end of session
    track_metric_session(False)

    # Stop threads
    self.StopSignal.emit()

    # Process any queued events
    QCoreApplication.processEvents()

    # Stop preview thread (and wait for it to end)
    self.preview_thread.player.CloseAudioDevice()
    self.preview_thread.kill()
    self.preview_parent.background.exit()
    self.preview_parent.background.wait(5000)

    # Shut down the webview
    self.timeline.close()

    # Close Timeline
    self.timeline_sync.timeline.Close()
    self.timeline_sync.timeline = None

    # Close & Stop libopenshot logger
    openshot.ZmqLogger.Instance().Close()
    app.logger_libopenshot.kill()
    self.http_server_thread.kill()

    # Destroy lock file
    self.destroy_lock_file()


# Traceback (TypeError)
Loaded modules from: /home/chiller/Desktop/git-extern/openshot-qt/src
app:INFO ------------------------------------------------
app:INFO             Wed Aug 26 17:21:17 2020
app:INFO               Starting new session
app:INFO ------------------------------------------------
app:INFO          OpenShot (version 2.5.1-dev2)
app:INFO ------------------------------------------------
app:INFO openshot-qt version: 2.5.1-dev2
app:INFO libopenshot version: 0.2.5-dev2
app:INFO platform: Linux-4.19.0-10-amd64-x86_64-with-debian-10.5
app:INFO processor:
app:INFO machine: x86_64
app:INFO python version: 3.7.3
app:INFO qt5 version: 5.11.3
app:INFO pyqt5 version: 5.11.3
language:INFO Qt Detected Languages: ['en-US']
language:INFO LANG Environment Variable: en_US.UTF-8
language:INFO LOCALE Environment Variable:
language:INFO OpenShot Preference Language: Default
project_data:INFO Setting default profile to HD 720p 30 fps
app:INFO Setting font to /home/chiller/Desktop/git-extern/openshot-qt/src/images/fonts/Ubuntu-R.ttf
logger_libopenshot:INFO Connecting to libopenshot with debug port: 5556
app:INFO Setting custom dark theme
exceptions:ERROR Unhandled Exception
Traceback (most recent call last):
File "src/launch.py", line 143, in <module>
main()
File "src/launch.py", line 136, in main
app = OpenShotApp(argv)
File "/home/chiller/Desktop/git-extern/openshot-qt/src/classes/app.py", line 242, in __init__
from windows.main_window import MainWindow
File "/home/chiller/Desktop/git-extern/openshot-qt/src/windows/main_window.py", line 45, in <module>
from windows.views.timeline_webview import TimelineWebView
File "/home/chiller/Desktop/git-extern/openshot-qt/src/windows/views/timeline_webview.py", line 154, in <module>
class TimelineWebView(TimelineMixin, updates.UpdateInterface):
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

# Fixed code
def closeEvent(self, event):
    app = get_app()
    # Some window managers handels dragging of the modal messages incorrectly if other windows are open
    # Hide tutorial window first
    self.tutorial_manager.hide_dialog()

    # Prompt user to save (if needed)
    if app.project.needs_save() and self.mode != "unittest":
        log.info("Prompt user to save project")
        # Translate object
        _ = app._tr

        # Handle exception
        ret = QMessageBox.question(
            self,
            _("Unsaved Changes"),
            _("Save changes to project before closing?"),
            QMessageBox.Cancel | QMessageBox.No | QMessageBox.Yes,
        )
        if ret == QMessageBox.Yes:
            # Save project
            self.actionSave_trigger()
            event.accept()
        elif ret == QMessageBox.Cancel:
            # Show tutorial again, if any
            self.tutorial_manager.re_show_dialog()
            # User canceled prompt - don't quit
            event.ignore()
            return

    # Log the exit routine
    log.info("---------------- Shutting down -----------------")

    # Close any tutorial dialogs
    self.tutorial_manager.exit_manager()

    # Save settings
    self.save_settings()

    # Track end of session
    track_metric_session(False)

    # Stop threads
    self.StopSignal.emit()

    # Process any queued events
    QCoreApplication.processEvents()

    # Stop preview thread (and wait for it to end)
    self.preview_thread.player.CloseAudioDevice()
    self.preview_thread.kill()
    self.preview_parent.background.exit()
    self.preview_parent.background.wait(5000)

    # Close Timeline
    self.timeline_sync.timeline.Close()
    self.timeline_sync.timeline = None

    # Destroy lock file
    self.destroy_lock_file()