diff --git a/src/GUI.jl b/src/GUI.jl
index 530ace8157629d13c5764ace3dd602adc72fabab..f216a8f5f5de9c9e9c684bc206f56b1cb4132ac9 100644
--- a/src/GUI.jl
+++ b/src/GUI.jl
@@ -7,9 +7,9 @@ global model = nothing
 global landcovermap = nothing
 global runsimulation = nothing
 global timer = nothing
-global launching = false
 
 const configfile = Observable("guiparams.toml")
+const launching = Observable(false)
 const running = Observable(false)
 const ticks = Observable(0)
 const date = Observable(today())
@@ -30,16 +30,19 @@ global guiproperties =
 
 function newsimulation()
     global model, landcovermap
+    launching[] = true # trigger the launch screen
     running[] = false
     progress[] = 0.0
     model = initialise(configfile[])
     landcovermap = rotr90(load(@param(world.landcovermap)))
     date[] = model.date
+    launching[] = false
     println("Model initialised.")
 end
 
 function loadsimulation(filename)
     global model
+    launching[] = true
     fn = convert(filename, String)
     startswith(fn, "file://") && (fn = fn[8:end])
     model = loadmodelobject(fn)
@@ -48,7 +51,8 @@ function loadsimulation(filename)
     date[] = model.date
     progress[] = (date[]-@param(core.startdate)) /
         (@param(core.enddate)-@param(core.startdate))
-    @emit updateMakie()
+    launching[] = false
+    println("Loaded simulation.")
 end
 
 function savesimulation(filename)
@@ -56,6 +60,7 @@ function savesimulation(filename)
     fn = convert(filename, String)
     startswith(fn, "file://") && (fn = fn[8:end])
     savemodelobject(model, fn)
+    println("Saved simulation.")
 end
 
 function Base.convert(s::QString, ::Type{<:AbstractString})
@@ -130,21 +135,22 @@ function togglerunning()
         runbuttontip[] = "Run"
     else
         running[] = true
-        QML.start(timer)
         runbuttontext[] = "||"
         runbuttontip[] = "Pause"
         runsimulation = createrunfunction()
+        QML.start(timer)
     end
 end
  
 function render_map(screen)
-    global model, mapimage, landcovermap, launching
-    launching && display(screen, Figure().scene) # blank screen at launch
+    global model, mapimage, landcovermap
+    launching[] && return display(screen, Figure().scene) # blank screen at launch
     println("Updating map")
     #FIXME I'm not sure date-1 is the real fix
     #FIXME repeatedly calling `visualisemap` causes the memory leak
     # (regardless of whether individuals are plotted or just the map)
     #mapimage[] = visualisemap(model, date[]-Day(1), landcovermap)
+    empty!(mapimage[])
     mapimage[] = vismap(model, date[]-Day(1), landcovermap)
     display(screen, mapimage[])
 end
@@ -178,8 +184,8 @@ end
 
 function render_plot(screen)
     #FIXME causes segfault when called during a simulation?
-    global model, launching
-    launching && display(screen, Figure().scene) # blank screen at launch
+    global model
+    launching[] && return display(screen, Figure().scene) # blank screen at launch
     println("Updating plot")
     figure = populationtrends(model)
     display(screen, figure.scene)
@@ -195,9 +201,19 @@ on(running) do r
 end
 
 on(ticks) do t
+    #launching[] && #FIXME
     running[] && runsimulation()
 end
 
+on(launching) do l
+    if l
+        @emit showSplash()
+    else
+        @emit closeSplash()
+        @emit updateMakie()
+    end
+end
+
 datestring = () -> Dates.format(date[], "dd U yyyy")
 
 function activateqmlfunctions()     
@@ -218,8 +234,7 @@ end
 The main function that creates the application.
 """
 function launch()
-    global model, timer, launching
-    launching = true
+    global model, timer
 
     activateqmlfunctions()
     timer = QTimer()
@@ -234,12 +249,12 @@ function launch()
             vars = JuliaPropertyMap(guiproperties...,configproperties...),
             render_map_callback = @safe_cfunction(render_map, Cvoid, (Any,)),
             render_plot_callback = @safe_cfunction(render_plot, Cvoid, (Any,)))
-    
-    @emit showSplash()
-    isnothing(model) && newsimulation()
-    @emit closeSplash()
-    launching = false
-    @emit updateMakie()
+    launching[] = true
+    if isnothing(model)
+        #QML.start(timer)
+        #newsimulation()
+        #QML.stop(timer)
+    end
     println("Launched Persefone Desktop.")
-    exec()
+    exec() #TODO how do I make this async? -> change to Threads.@spawn?
 end
diff --git a/src/main.qml b/src/main.qml
index b622cdffa4ceccdcda1c097cb880d7c395cd933f..f06c1898ead9c393b55b4f0307d005df3566d8eb 100644
--- a/src/main.qml
+++ b/src/main.qml
@@ -41,10 +41,6 @@ ApplicationWindow {
 				}
 			}
 			MenuSeparator { }
-			Action {
-				text: "&Show splash screen"
-				onTriggered: { splashPopup.show() }
-			}
 			Action {
 				text: "&Quit"
 				onTriggered: { mainWindow.close() }
@@ -184,20 +180,18 @@ Distributed under the MIT license."
 	Popup {
 		id: splashPopup
 		parent: Overlay.overlay
-		//closePolicy: Popup.NoAutoClose
+		closePolicy: Popup.NoAutoClose
 		modal: true
+		padding: 0
 
 		width: 600
 		height: 250
 		x: Math.round((parent.width - width) / 2)
 		y: Math.round((parent.height - height) / 2)
-
-		Rectangle {
+		
+		Image {
 			anchors.fill: parent
-			
-			Image {
-				source: "persefonejl_logo_v3_splash.png"
-			}
+			source: "persefonejl_logo_v3_splash.png"
 		}
 	}