diff --git a/src/module/module_sdl2.c b/src/module/module_sdl2.c
index 7fa151f13d53d8d9cc581b0fd71679a21060b302..2c12527420e27992f413c99a0077282a3041d47d 100644
--- a/src/module/module_sdl2.c
+++ b/src/module/module_sdl2.c
@@ -29,13 +29,6 @@ struct module_sdl2_window {
 
 static Uint32 wakeup_on_mpv_render_update, wakeup_on_mpv_events;
 
-static void
-die(const char *msg)
-{
-    fprintf(stderr, "%s\n", msg);
-    exit(1);
-}
-
 static inline void *
 get_proc_address_mpv(void *fn_ctx, const char *name)
 {
@@ -59,181 +52,6 @@ on_mpv_render_update(void *ctx)
     SDL_PushEvent(&event);
 }
 
-int
-main(int argc, char *argv[])
-{
-    if (argc != 2)
-        die("pass a single media file as argument");
-
-    mpv_handle *mpv = mpv_create();
-    if (!mpv)
-        die("context init failed");
-
-    // Some minor options can only be set before mpv_initialize().
-    if (mpv_initialize(mpv) < 0)
-        die("mpv init failed");
-
-    // Jesus Christ SDL, you suck!
-    SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS, "no");
-
-    if (SDL_Init(SDL_INIT_VIDEO) < 0)
-        die("SDL init failed");
-
-    SDL_Window *window =
-        SDL_CreateWindow("hi", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
-                         1000, 500, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN |
-                         SDL_WINDOW_RESIZABLE);
-    if (!window)
-        die("failed to create SDL window");
-
-    SDL_GLContext glcontext = SDL_GL_CreateContext(window);
-    if (!glcontext)
-        die("failed to create SDL GL context");
-
-    mpv_render_param params[] = {
-        {MPV_RENDER_PARAM_API_TYPE, MPV_RENDER_API_TYPE_OPENGL},
-        {
-            MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, &(mpv_opengl_init_params)
-            {
-                .get_proc_address = get_proc_address_mpv,
-            }
-        },
-        // Tell libmpv that you will call mpv_render_context_update() on render
-        // context update callbacks, and that you will _not_ block on the core
-        // ever (see <libmpv/render.h> "Threading" section for what libmpv
-        // functions you can call at all when this is active).
-        // In particular, this means you must call e.g. mpv_command_async()
-        // instead of mpv_command().
-        // If you want to use synchronous calls, either make them on a separate
-        // thread, or remove the option below (this will disable features like
-        // DR and is not recommended anyway).
-        {
-            MPV_RENDER_PARAM_ADVANCED_CONTROL, &(int)
-            {
-                1
-            }
-        },
-        {0}
-    };
-
-    // This makes mpv use the currently set GL context. It will use the callback
-    // (passed via params) to resolve GL builtin functions, as well as extensions.
-    mpv_render_context *mpv_gl;
-    if (mpv_render_context_create(&mpv_gl, mpv, params) < 0)
-        die("failed to initialize mpv GL context");
-
-    // We use events for thread-safe notification of the SDL main loop.
-    // Generally, the wakeup callbacks (set further below) should do as least
-    // work as possible, and merely wake up another thread to do actual work.
-    // On SDL, waking up the mainloop is the ideal course of action. SDL's
-    // SDL_PushEvent() is thread-safe, so we use that.
-    wakeup_on_mpv_render_update = SDL_RegisterEvents(1);
-    wakeup_on_mpv_events = SDL_RegisterEvents(1);
-    if (wakeup_on_mpv_render_update == (Uint32) - 1 ||
-        wakeup_on_mpv_events == (Uint32) - 1)
-        die("could not register events");
-
-    // When normal mpv events are available.
-    mpv_set_wakeup_callback(mpv, on_mpv_events, NULL);
-
-    // When there is a need to call mpv_render_context_update(), which can
-    // request a new frame to be rendered.
-    // (Separate from the normal event handling mechanism for the sake of
-    //  users which run OpenGL on a different thread.)
-    mpv_render_context_set_update_callback(mpv_gl, on_mpv_render_update, NULL);
-
-    // Play this file.
-    const char *cmd[] = {"loadfile", argv[1], NULL};
-    mpv_command_async(mpv, 0, cmd);
-
-    while (1) {
-        SDL_Event event;
-        if (SDL_WaitEvent(&event) != 1)
-            die("event loop error");
-        int redraw = 0;
-        switch (event.type) {
-        case SDL_QUIT:
-            goto done;
-        case SDL_WINDOWEVENT:
-            if (event.window.event == SDL_WINDOWEVENT_EXPOSED)
-                redraw = 1;
-            break;
-        case SDL_KEYDOWN:
-            if (event.key.keysym.sym == SDLK_SPACE) {
-                const char *cmd_pause[] = {"cycle", "pause", NULL};
-                mpv_command_async(mpv, 0, cmd_pause);
-            }
-            if (event.key.keysym.sym == SDLK_s) {
-                // Also requires MPV_RENDER_PARAM_ADVANCED_CONTROL if you want
-                // screenshots to be rendered on GPU (like --vo=gpu would do).
-                const char *cmd_scr[] = {"screenshot-to-file",
-                                         "screenshot.png",
-                                         "window",
-                                         NULL
-                                        };
-                printf("attempting to save screenshot to %s\n", cmd_scr[1]);
-                mpv_command_async(mpv, 0, cmd_scr);
-            }
-            break;
-        default:
-            // Happens when there is new work for the render thread (such as
-            // rendering a new video frame or redrawing it).
-            if (event.type == wakeup_on_mpv_render_update) {
-                uint64_t flags = mpv_render_context_update(mpv_gl);
-                if (flags & MPV_RENDER_UPDATE_FRAME)
-                    redraw = 1;
-            }
-            // Happens when at least 1 new event is in the mpv event queue.
-            if (event.type == wakeup_on_mpv_events) {
-                // Handle all remaining mpv events.
-                while (1) {
-                    mpv_event *mp_event = mpv_wait_event(mpv, 0);
-                    if (mp_event->event_id == MPV_EVENT_NONE)
-                        break;
-                    printf("event: %s\n", mpv_event_name(mp_event->event_id));
-                }
-            }
-        }
-        if (redraw) {
-            int w, h;
-            SDL_GetWindowSize(window, &w, &h);
-            mpv_render_param params[] = {
-                // Specify the default framebuffer (0) as target. This will
-                // render onto the entire screen. If you want to show the video
-                // in a smaller rectangle or apply fancy transformations, you'll
-                // need to render into a separate FBO and draw it manually.
-                {
-                    MPV_RENDER_PARAM_OPENGL_FBO, &(mpv_opengl_fbo)
-                    {
-                        .fbo = 0,
-                        .w = w,
-                        .h = h,
-                    }
-                },
-                {
-                    MPV_RENDER_PARAM_FLIP_Y, &(int)
-                    {
-                        1
-                    }
-                },
-                {0}
-            };
-            mpv_render_context_render(mpv_gl, params);
-            SDL_GL_SwapWindow(window);
-        }
-    }
-done:
-
-    // Destroy the GL renderer and all of the GL objects it allocated. If video
-    // is still running, the video track will be deselected.
-    mpv_render_context_free(mpv_gl);
-
-    mpv_detach_destroy(mpv);
-
-    printf("properly terminated\n");
-    return 0;
-}
-
 /* Exported functions */
 
 extern int
@@ -259,6 +77,50 @@ module_set_function(void *arg__, void *handle__)
     return 0;
 }
 
+/* Private init functions */
+
+static inline bool
+init_mpv__(mpv_handle **ctx)
+{
+    *ctx = lmpv_prepare();
+    int status;
+    if ((status = mpv_initialize(*ctx)) < 0) {
+        fprintf(stderr, " ! init_mpv__: failed to initialize mpv: %s\n",
+                mpv_error_string(status));
+        return 1;
+    }
+    if (!lmpv_observe_properties(*ctx)) {
+        fprintf(stderr, " ! init_mpv__: failed to observe properties\n");
+        return 1;
+    }
+    return 0;
+}
+
+static inline bool
+init_mpv_gl__(mpv_handle *mpv, mpv_render_context **mpv_gl, mpv_render_param *params)
+{
+    int status;
+    if ((status = mpv_render_context_create(mpv_gl, mpv, params)) < 0) {
+        fprintf(stderr, " ! init_mpv_gl__: Failed to create render context: %s\n",
+                mpv_error_string(status));
+        return 1;
+    }
+
+    wakeup_on_mpv_render_update = SDL_RegisterEvents(1);
+    wakeup_on_mpv_events = SDL_RegisterEvents(1);
+    if (wakeup_on_mpv_render_update == (Uint32) - 1 ||
+        wakeup_on_mpv_events == (Uint32) - 1) {
+        fprintf(stderr, " . init_mpv_gl__: Failed to register events\n");
+        return 1;
+    }
+
+    mpv_set_wakeup_callback(mpv, on_mpv_events, NULL);
+    mpv_render_context_set_update_callback(*mpv_gl, on_mpv_render_update, NULL);
+    return 0;
+}
+
+/* Exported functions */
+
 bool
 module_sdl2_new(struct lkt_win *const win)
 {
@@ -266,7 +128,22 @@ module_sdl2_new(struct lkt_win *const win)
         return false;
 
     struct module_sdl2_window *sdl2 = win->window;
-    int status;
+    mpv_render_param params[] = {
+        { MPV_RENDER_PARAM_API_TYPE, MPV_RENDER_API_TYPE_OPENGL },
+        {
+            MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, &(mpv_opengl_init_params)
+            {
+                .get_proc_address = get_proc_address_mpv,
+            }
+        },
+        {
+            MPV_RENDER_PARAM_ADVANCED_CONTROL, &(int)
+            {
+                1
+            }
+        },
+        {0}
+    };
 
     if (sdl2 == NULL) {
         sdl2 = calloc(1, sizeof(struct module_sdl2_window));
@@ -292,43 +169,14 @@ module_sdl2_new(struct lkt_win *const win)
             goto error;
 
         /* Init mpv here */
-        sdl2->mpv = lmpv_prepare();
-
-        if ((status = mpv_initialize(sdl2->mpv)) < 0) {
-            fprintf(stderr, " ! lmpv_new: failed to initialize mpv: %s\n",
-                    mpv_error_string(status));
+        if (init_mpv__(&sdl2->mpv))
             goto error;
-        }
-
-        if (!lmpv_observe_properties(sdl2->mpv)) {
-            fprintf(stderr, " * lmpv_new: failed to observe properties\n");
-            goto error;
-        }
 
         /* Init opengl with mpv and sdl2 */
-
-        mpv_render_param params[] = {
-            { MPV_RENDER_PARAM_API_TYPE, MPV_RENDER_API_TYPE_OPENGL },
-            {
-                MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, &(mpv_opengl_init_params)
-                {
-                    .get_proc_address = get_proc_address_mpv,
-                }
-            },
-            {
-                MPV_RENDER_PARAM_ADVANCED_CONTROL, &(int)
-                {
-                    1
-                }
-            },
-            {0}
-        };
-
         if (mpv_render_context_create(&sdl2->mpv_gl, sdl2->mpv, params) < 0)
             goto error;
 
-        fprintf(stderr, " . module_sdl2_new: successfully created the X11 window\n");
-
+        fprintf(stderr, " * Successfully created the SDL2 window\n");
         wakeup_on_mpv_render_update = SDL_RegisterEvents(1);
         wakeup_on_mpv_events = SDL_RegisterEvents(1);
         if (wakeup_on_mpv_render_update == (Uint32) - 1 || wakeup_on_mpv_events == (Uint32) - 1)
@@ -336,28 +184,17 @@ module_sdl2_new(struct lkt_win *const win)
 
         mpv_set_wakeup_callback(sdl2->mpv, on_mpv_events, NULL);
         mpv_render_context_set_update_callback(sdl2->mpv_gl, on_mpv_render_update, NULL);
-    }
-
-    if (sdl2->mpv == NULL) {
-        sdl2->mpv = lmpv_prepare();
 
-        if ((status = mpv_initialize(sdl2->mpv)) < 0) {
-            fprintf(stderr, " ! lmpv_new: failed to initialize mpv: %s\n",
-                    mpv_error_string(status));
+        /* Init mpv_gl here */
+        if (init_mpv_gl__(sdl2->mpv, &sdl2->mpv_gl, params))
             goto error;
-        }
-
-        if (!lmpv_observe_properties(sdl2->mpv)) {
-            fprintf(stderr, " * lmpv_new: failed to observe properties\n");
-            goto error;
-        }
-
-        if (sdl2->mpv == NULL)
-            return false;
     }
 
-    if (sdl2->mpv_gl == NULL) {
-    }
+    if (sdl2->mpv == NULL && init_mpv__(&sdl2->mpv))
+        goto error;
+
+    if (sdl2->mpv_gl == NULL && init_mpv_gl__(sdl2->mpv, &sdl2->mpv_gl, params))
+        goto error;
 
     win->window = sdl2;
     return true;
@@ -370,7 +207,10 @@ module_sdl2_close(struct lkt_win *const win)
 {
     if (win == NULL || win->window == NULL)
         return;
-    lmpv_free(&((struct module_sdl2_window *)win->window)->mpv);
+    struct module_sdl2_window *sdl2 = win->window;
+    mpv_render_context_free(sdl2->mpv_gl);
+    sdl2->mpv_gl = NULL;
+    lmpv_free(&sdl2->mpv);
 }
 
 void
@@ -440,4 +280,71 @@ module_sdl2_get_elapsed(struct lkt_win *const win, int *elapsed_sec)
 bool
 module_sdl2_handle_events(struct lkt_win *const win, sqlite3 *db, enum mpd_idle_flag *mpd_idle_events)
 {
+    struct module_sdl2_window *sdl2 = win->window;
+    if (sdl2 == NULL)
+        return false;
+
+    for (;;) {
+        SDL_Event event;
+        int redraw = 0;
+        if (SDL_WaitEvent(&event) != 1)
+            return false;
+
+        switch (event.type) {
+        case SDL_QUIT:
+            return true;
+        case SDL_WINDOWEVENT:
+            if (event.window.event == SDL_WINDOWEVENT_EXPOSED)
+                redraw = 1;
+            break;
+        case SDL_KEYDOWN:
+            if (event.key.keysym.sym == SDLK_SPACE) {
+                const char *cmd_pause[] = { "cycle", "pause", NULL };
+                mpv_command_async(sdl2->mpv, 0, cmd_pause);
+            }
+            break;
+        default:
+            if (event.type == wakeup_on_mpv_render_update) {
+                uint64_t flags = mpv_render_context_update(sdl2->mpv_gl);
+                if (flags & MPV_RENDER_UPDATE_FRAME)
+                    redraw = 1;
+            }
+            // Happens when at least 1 new event is in the mpv event queue.
+            if (event.type == wakeup_on_mpv_events) {
+                // Handle all remaining mpv events.
+                for (;;) {
+                    mpv_event *mp_event = mpv_wait_event(sdl2->mpv, 0);
+                    if (mp_event->event_id == MPV_EVENT_NONE)
+                        break;
+                    printf("event: %s\n", mpv_event_name(mp_event->event_id));
+                }
+            }
+        }
+
+        if (redraw) {
+            int w, h;
+            SDL_GetWindowSize(sdl2->window, &w, &h);
+            mpv_render_param params[] = {
+                // Specify the default framebuffer (0) as target. This will
+                // render onto the entire screen. If you want to show the video
+                // in a smaller rectangle or apply fancy transformations, you'll
+                // need to render into a separate FBO and draw it manually.
+                {
+                    MPV_RENDER_PARAM_OPENGL_FBO, &(mpv_opengl_fbo)
+                    {
+                        .fbo = 0, .w = w, .h = h,
+                    }
+                },
+                {
+                    MPV_RENDER_PARAM_FLIP_Y, &(int)
+                    {
+                        1
+                    }
+                },
+                {0}
+            };
+            mpv_render_context_render(sdl2->mpv_gl, params);
+            SDL_GL_SwapWindow(sdl2->window);
+        }
+    }
 }