diff --git a/apps/filetree.c b/apps/filetree.c
index 945b9ac..6b56c80 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -528,13 +528,9 @@ int ft_enter(struct tree_context* c)
                 splash(0, ID2P(LANG_WAIT));
                 if (!settings_load_config(buf,true))
                     break;
-                /* do both steps seperately so that the redrawing after theme
-                 * changing is independant of whether the theme has a custom ui
-                 * vp or not */
-                send_event(GUI_EVENT_REFRESH, NULL);
-                /* for the statusbar */
-                send_event(GUI_EVENT_ACTIONUPDATE, (void*)true);
-                tree_drawlists();
+
+                /* redraw the UI in case the user setting changed apparence */
+                send_event(GUI_EVENT_REFRESH, tree_drawlists);
                 splash(HZ, ID2P(LANG_SETTINGS_LOADED));
                 break;

diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index 460101a..4f33910 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -58,26 +58,6 @@

 static bool skin_redraw(struct gui_wps *gwps, unsigned refresh_mode);

-
-/* TODO: maybe move this whole function into wps.c instead ? */
-bool gui_wps_display(struct gui_wps *gwps)
-{
-    struct screen *display = gwps->display;
-
-    /* Update the values in the first (default) viewport - in case the user
-       has modified the statusbar or colour settings */
-#if LCD_DEPTH > 1
-    if (display->depth > 1)
-    {
-        struct viewport *vp = &find_viewport(VP_DEFAULT_LABEL, gwps->data)->vp;
-        vp->fg_pattern = display->get_foreground();
-        vp->bg_pattern = display->get_background();
-    }
-#endif
-    display->backdrop_show(BACKDROP_SKIN_WPS);
-    return skin_redraw(gwps, WPS_REFRESH_ALL);
-}
-
 /* update a skinned screen, update_type is WPS_REFRESH_* values.
  * Usually it should only be WPS_REFRESH_NON_STATIC
  * A full update will be done if required (state.do_full_update == true)
diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c
index 0a2630c..9a7cfbd 100644
--- a/apps/gui/viewport.c
+++ b/apps/gui/viewport.c
@@ -70,6 +70,7 @@ static struct viewport custom_vp[NB_SCREENS];

 /* callbacks for GUI_EVENT_* events */
 static void viewportmanager_ui_vp_changed(void *param);
+static void viewportmanager_call_draw_func(void *param);
 static void statusbar_toggled(void* param);
 static unsigned viewport_init_ui_vp(void);
 #endif
@@ -215,29 +216,47 @@ void viewportmanager_theme_changed(const int which)
         event_add |= (statusbar_position(i) == STATUSBAR_CUSTOM);
     }

+    /* add one of those to ensure the draw function is called always */
     if (event_add)
+    {
         add_event(GUI_EVENT_REFRESH, false, viewportmanager_ui_vp_changed);
+        remove_event(GUI_EVENT_REFRESH, viewportmanager_call_draw_func);
+    }
     else
+    {
+        add_event(GUI_EVENT_REFRESH, false, viewportmanager_call_draw_func);
         remove_event(GUI_EVENT_REFRESH, viewportmanager_ui_vp_changed);
+    }

     send_event(GUI_EVENT_THEME_CHANGED, NULL);
 }

+/*
+ * simply calls a function that draws stuff, this exists to ensure the
+ * drawing function call in the GUI_EVENT_REFRESH event
+ *
+ * param should be 'void func(void)' */
+static void viewportmanager_call_draw_func(void *param)
+{
+    /* cast param to a function */
+    void (*draw_func)(void) = ((void(*)(void))param);
+    /* call the passed function which will redraw the content of
+     * the current screen */
+    if (draw_func != NULL)
+        draw_func();
+}
+
 static void viewportmanager_ui_vp_changed(void *param)
 {
     /* if the user changed the theme, we need to initiate a full redraw */
     int i;
-    /* cast param to a function */
-    void (*draw_func)(void) = ((void(*)(void))param);
     /* start with clearing the screen */
     FOR_NB_SCREENS(i)
         screens[i].clear_display();
     /* redraw the statusbar if it was enabled */
     send_event(GUI_EVENT_ACTIONUPDATE, (void*)true);
-    /* call the passed function which will redraw the content of
-     * the current screen */
-    if (draw_func != NULL)
-        draw_func();
+    /* call redraw function */
+    viewportmanager_call_draw_func(param);
     FOR_NB_SCREENS(i)
         screens[i].update();
 }
diff --git a/apps/gui/wps.c b/apps/gui/wps.c
index 9236f9f..85639f7 100644
--- a/apps/gui/wps.c
+++ b/apps/gui/wps.c
@@ -582,6 +582,31 @@ static void gwps_leave_wps(void)
     send_event(GUI_EVENT_REFRESH, NULL);
 }

+/*
+ * display the wps on entering or restoring */
+static void gwps_enter_wps(void)
+{
+    int i;
+    FOR_NB_SCREENS(i)
+    {
+        struct gui_wps *gwps = &gui_wps[i];
+        struct screen *display = gwps->display;
+
+        display->stop_scroll();
+        /* Update the values in the first (default) viewport - in case the user
+           has modified the statusbar or colour settings */
+#if LCD_DEPTH > 1
+        if (display->depth > 1)
+        {
+            struct viewport *vp = &find_viewport(VP_DEFAULT_LABEL, gwps->data)->vp;
+            vp->fg_pattern = display->get_foreground();
+            vp->bg_pattern = display->get_background();
+        }
+#endif
+        skin_update(gwps, WPS_REFRESH_ALL);
+    }
+}
+
 #ifdef HAVE_TOUCHSCREEN
 int wps_get_touchaction(struct wps_data *data)
 {
@@ -696,6 +721,7 @@ long gui_wps_show(void)
     bool vol_changed = false;
     int i;
     long last_left = 0, last_right = 0;
+    long curr_tick = current_tick;

 #ifdef HAVE_LCD_CHARCELLS
     status_set_audio(true);
@@ -1136,7 +1162,27 @@ long gui_wps_show(void)
             }
         }

-        if (wps_sync_data.do_full_update || update)
+
+        if (restore && wps_state.id3 &&
+            ((restoretimer == RESTORE_WPS_INSTANTLY) ||
+             TIME_AFTER(current_tick, restoretimer)))
+        {
+            restore = false;
+            restoretimer = RESTORE_WPS_INSTANTLY;
+#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
+            add_event(LCD_EVENT_ACTIVATION, false, wps_lcd_activation_hook);
+#endif
+        /* we remove the update delay since it's not very usable in the wps,
+         * e.g. during volume changing or ffwd/rewind */
+            sb_skin_set_update_delay(0);
+            FOR_NB_SCREENS(i)
+                gui_wps[i].display->backdrop_show(BACKDROP_SKIN_WPS);
+            send_event(GUI_EVENT_REFRESH, gwps_enter_wps);
+            long difftime = current_tick - curr_tick;
+            splashf(HZ, "done, needed %ld:%ld", difftime/HZ, difftime%HZ);
+            wps_sync_data.do_full_update = update = false;
+        }
+        else if (wps_sync_data.do_full_update || update)
         {
 #if defined(HAVE_BACKLIGHT) || defined(HAVE_REMOTE_LCD)
             gwps_caption_backlight(&wps_state);
@@ -1156,25 +1202,6 @@ long gui_wps_show(void)
             update = false;
         }
 
-        if (restore && wps_state.id3 &&
-            ((restoretimer == RESTORE_WPS_INSTANTLY) ||
-             TIME_AFTER(current_tick, restoretimer)))
-        {
-            restore = false;
-            restoretimer = RESTORE_WPS_INSTANTLY;
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
-            add_event(LCD_EVENT_ACTIVATION, false, wps_lcd_activation_hook);
-#endif
-        /* we remove the update delay since it's not very usable in the wps,
-         * e.g. during volume changing or ffwd/rewind */
-            sb_skin_set_update_delay(0);
-            FOR_NB_SCREENS(i)
-            {
-                screens[i].stop_scroll();
-                gui_wps_display(&gui_wps[i]);
-            }
-        }
-
         if (exit) {
 #ifdef HAVE_LCD_CHARCELLS
             status_set_record(false);