diff --git a/src/module/module_qt_window.cc b/src/module/module_qt_window.cc
index e9132fbb8fa41d1a0485e3d2e92efc9877566b57..7eb7f57821ece06292600e7e174cb8901d170405 100644
--- a/src/module/module_qt_window.cc
+++ b/src/module/module_qt_window.cc
@@ -229,7 +229,7 @@ static void
 module_qt_window_close(struct module_qt_window_s *win)
 {
     RETURN_UNLESS(win && win->mpv_widget && win->main_window, "Invalid arguments", NOTHING);
-    win->main_window->closeMpv();
+    win->mpv_widget->stop();
 }
 
 static void
@@ -237,4 +237,5 @@ module_qt_window_free(struct module_qt_window_s *win)
 {
     RETURN_UNLESS(win, "Invalid arguments", NOTHING);
     module_qt_window_close(win);
+    win->main_window->closeMpv();
 }
diff --git a/src/module/qt_window/mpvwidget.cc b/src/module/qt_window/mpvwidget.cc
index 3a850fe15253cdd452ab869bbe75863894f7682f..e81597c39eee93bc4cc7ed0a225ae29790e439aa 100644
--- a/src/module/qt_window/mpvwidget.cc
+++ b/src/module/qt_window/mpvwidget.cc
@@ -145,7 +145,7 @@ MpvWidget::handle_mpv_event(mpv_event *event)
         break;
     case MPV_EVENT_END_FILE:
         LOG_DEBUG("WINDOW", "End of file!");
-        if (!m_inhib)
+        if (!m_inhib && m_state != STOP)
             lkt_queue_send(m_queue, LKT_EVENT_PLAY_NEXT, nullptr);
         break;
 
@@ -166,7 +166,7 @@ MpvWidget::handle_mpv_event(mpv_event *event)
     case MPV_EVENT_IDLE:
         lkt_queue_make_available(m_queue, static_cast<LKT_EVENT_TYPE>(LKT_EVENT_PLAY));
         lkt_queue_make_available(m_queue, static_cast<LKT_EVENT_TYPE>(LKT_EVENT_PROP));
-        titleChanged("[Lektord] Stopped");
+        emit titleChanged("[Lektord] Stopped");
         break;
 
     case MPV_EVENT_LOG_MESSAGE:
@@ -260,6 +260,7 @@ MpvWidget::load_file(const char *filepath)
 
     if (ret) {
         LOG_DEBUG("WINDOW", "Loaded file: %s", filepath);
+        m_state = NONSTOPPED;
         update_window_title();
     } else {
         LOG_ERROR("WINDOW", "Failed to load kara with path: %s", filepath);
@@ -296,6 +297,16 @@ MpvWidget::toggle_pause()
     return true;
 }
 
+bool
+MpvWidget::stop()
+{
+    m_state           = STOP;
+    const char *cmd[] = { "stop", nullptr };
+    mpv_command_async(mpv, 0, cmd);
+    emit titleChanged("[Lektord] Stopped");
+    return true;
+}
+
 #define MPV_SEND_COMMAND_ASYNC(...)          \
     {                                        \
         const char *cmd[] = { __VA_ARGS__ }; \
@@ -305,6 +316,9 @@ MpvWidget::toggle_pause()
 void
 MpvWidget::keyPressEvent(QKeyEvent *event)
 {
+    if (m_state == STOP)
+        return QOpenGLWidget::keyPressEvent(event);
+
     switch (event->modifiers()) {
     /* SHIFTED */
     case Qt::ShiftModifier:
diff --git a/src/module/qt_window/mpvwidget.hh b/src/module/qt_window/mpvwidget.hh
index 9131b61cec4084a9a6b21c5a5041fe584b2e46af..244bcc9c5eb4781f7848368bb06fbd38c3ce7d13 100644
--- a/src/module/qt_window/mpvwidget.hh
+++ b/src/module/qt_window/mpvwidget.hh
@@ -31,6 +31,8 @@ public:
     mpv_render_context *mpv_gl;
 
 private:
+    enum { PLAY, PAUSE, STOP, NONSTOPPED } m_state = STOP;
+
     struct queue *m_queue;
     lkt_db *m_db;
     struct module_reg *m_reg;
@@ -51,6 +53,7 @@ public:
     bool set_position(int);
     bool load_file(const char *);
     bool toggle_pause();
+    bool stop();
 
 private:
     void update_window_title();