diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index 7ad59b9..fd95b3a 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -103,13 +103,15 @@ static bool draw_title(struct screen *display, struct gui_synclist *list)
     if (!list_display_title(list, screen))
         return false;
     *title_text_vp = *(list->parent[screen]);
-    title_text_vp->height = font_get(title_text_vp->font)->height;
+    title_text_vp->height = viewport_get_line_height(title_text_vp);
 
     if (list->title_icon != Icon_NOICON && global_settings.show_icons)
     {
         struct viewport title_icon = *title_text_vp;
 
         title_icon.width = get_icon_width(screen) + ICON_PADDING * 2;
+        title_icon.y += (title_icon.height - get_icon_height(screen)) / 2;
+        title_icon.height = get_icon_height(screen);
         if (VP_IS_RTL(&title_icon))
         {
             title_icon.x += title_text_vp->width - title_icon.width;
@@ -121,7 +123,7 @@ static bool draw_title(struct screen *display, struct gui_synclist *list)
         title_text_vp->width -= title_icon.width;
 
         display->set_viewport(&title_icon);
-        screen_put_icon(display, 0, 0, list->title_icon);
+        screen_put_iconxy(display, 0, 0, list->title_icon);
     }
 #ifdef HAVE_LCD_COLOR
     if (list->title_color >= 0)
@@ -137,7 +139,7 @@ static bool draw_title(struct screen *display, struct gui_synclist *list)
 void list_draw(struct screen *display, struct gui_synclist *list)
 {
     struct viewport list_icons;
-    int start, end, line_height, style, i;
+    int start, end, line_height, icon_yoffset, style, i;
     const int screen = display->screen_type;
     const int list_start_item = list->start_item[screen];
     const int icon_width = get_icon_width(screen) + ICON_PADDING;
@@ -152,15 +154,16 @@ void list_draw(struct screen *display, struct gui_synclist *list)
     bool show_title;
     struct viewport *list_text_vp = &list_text[screen];
 
-    line_height = font_get(parent->font)->height;
+    line_height = viewport_get_line_height(parent);
     display->set_viewport(parent);
     display->clear_viewport();
     display->scroll_stop(list_text_vp);
     *list_text_vp = *parent;
     if ((show_title = draw_title(display, list)))
     {
-        list_text_vp->y += line_height;
-        list_text_vp->height -= line_height;
+        int title_height = title_text[screen].height;
+        list_text_vp->y += title_height;
+        list_text_vp->height -= title_height;
     }
 
     const int nb_lines = viewport_get_nb_lines(list_text_vp);
@@ -233,6 +236,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
             list_icons.x += list_text_vp->width + ICON_PADDING;
         else
             list_text_vp->x += list_icons.width + ICON_PADDING;
+        icon_yoffset = (line_height - get_icon_height(screen)) / 2;
     }
 
     for (i=start; i<end && i<list->nb_items; i++)
@@ -330,18 +334,33 @@ void list_draw(struct screen *display, struct gui_synclist *list)
                 display->puts_style_xyoffset(0, line, entry_name,
                         style, item_offset, draw_offset);
         }
+#ifdef HAVE_TOUCHSCREEN
+        /* do the line separator */
+        int oldcolor = display->get_foreground();
+        display->set_foreground(LCD_RGBPACK_LCD(RGB_UNPACK_RED_LCD(oldcolor)/2,
+                                                RGB_UNPACK_GREEN_LCD(oldcolor)/2,
+                                                RGB_UNPACK_BLUE_LCD(oldcolor)/2));
+        //~ if (!i)
+            display->hline(0+3, list_text_vp->width-3, line*line_height+draw_offset);
+        display->hline(0+3, list_text_vp->width-3, (line+1)*line_height+draw_offset);
+        display->set_foreground(oldcolor);
+#endif
         /* do the icon */
         display->set_viewport(&list_icons);
         if (list->callback_get_item_icon != NULL)
         {
-            screen_put_icon_with_offset(display, show_cursor?1:0,
-                                    (line),show_cursor?ICON_PADDING:0,draw_offset,
-                                    list->callback_get_item_icon(i, list->data));
+            int xoff = show_cursor ? get_icon_width(screen) + ICON_PADDING : 0;
+            screen_put_iconxy(display, xoff,
+                            line*line_height + draw_offset + icon_yoffset,
+                            list->callback_get_item_icon(i, list->data));
         }
+        /* do the cursor */
         if (show_cursor && i >= list->selected_item &&
                 i <  list->selected_item + list->selected_size)
         {
-            screen_put_icon_with_offset(display, 0, line, 0, draw_offset, Icon_Cursor);
+            screen_put_iconxy(display, 0,
+                            line*line_height + draw_offset + icon_yoffset,
+                            Icon_Cursor);
         }
     }
     display->set_viewport(parent);
@@ -371,7 +390,7 @@ static int scrollbar_scroll(struct gui_synclist * gui_list,
         /* scrollbar scrolling is still line based */
         y_offset = 0;
         int scrollbar_size = nb_lines*
-            font_get(gui_list->parent[screen]->font)->height;
+            viewport_get_line_height(gui_list->parent[screen]);
         int actual_y = y - list_text[screen].y;
 
         int new_selection = (actual_y * gui_list->nb_items)
@@ -559,7 +578,7 @@ static int kinetic_callback(struct timeout *tmo)
         return 0;
 
     struct cb_data *data = (struct cb_data*)tmo->data;
-    int line_height = font_get(data->list->parent[0]->font)->height;
+    int line_height = viewport_get_line_height(data->list->parent[0]);
     /* ds = v*dt */
     int pixel_diff = data->velocity * RELOAD_INTERVAL / HZ;
     /* remember signedness to detect stopping */
@@ -628,7 +647,7 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list)
     struct viewport *info_vp = sb_skin_get_info_vp(screen);
     const int button = action_get_touchscreen_press_in_vp(&x, &y, info_vp);
     const int list_start_item = gui_list->start_item[screen];
-    const int line_height = font_get(gui_list->parent[screen]->font)->height;
+    const int line_height = viewport_get_line_height(gui_list->parent[screen]);
     const struct viewport *list_text_vp = &list_text[screen];
     const bool old_released = released;
     const bool show_title = list_display_title(gui_list, screen);
diff --git a/apps/gui/icon.c b/apps/gui/icon.c
index 628196a..87ea071 100644
--- a/apps/gui/icon.c
+++ b/apps/gui/icon.c
@@ -277,3 +277,8 @@ int get_icon_width(enum screen_type screen_type)
 {
     return ICON_WIDTH(screen_type);
 }
+
+int get_icon_height(enum screen_type screen_type)
+{
+    return ICON_HEIGHT(screen_type);
+}
diff --git a/apps/gui/icon.h b/apps/gui/icon.h
index e79defe..ca7f048 100644
--- a/apps/gui/icon.h
+++ b/apps/gui/icon.h
@@ -109,8 +109,11 @@ void icons_init(void);
 #ifdef HAVE_LCD_CHARCELLS
 # define CURSOR_CHAR 0xe10c
 # define get_icon_width(a) 6
+# define get_icon_height(a) 1 /* needs to be verified */
 #else
 int get_icon_width(enum screen_type screen_type);
+int get_icon_height(enum screen_type screen_type);
 #endif
 
+
 #endif /*_GUI_ICON_H_*/
diff --git a/apps/gui/list.c b/apps/gui/list.c
index fbcdcb2..18ec5a1 100644
--- a/apps/gui/list.c
+++ b/apps/gui/list.c
@@ -72,6 +72,26 @@ void list_init(void)
     add_event(GUI_EVENT_THEME_CHANGED, false, list_force_reinit);
 }
 
+#ifdef HAVE_TOUCHSCREEN
+static int line_height_from_lcd_dpi(const struct viewport *vp)
+{
+    /* the 4/11 factor is designed so that 8 lines fit perfectly on a
+     * 160 dpi screen, may not be perfect for other sizes */
+    return MAX(lcd_get_dpi()*4/13, (int)font_get(vp->font)->height);
+}
+
+static int line_height_from_settings(const struct viewport *vp)
+{ 
+    return font_get(vp->font)->height + global_settings.list_item_padding;
+}
+
+void on_list_padding_setting_changed(int value)
+{
+    (void)value;
+    list_need_reinit = true;
+}
+#endif
+
 static void list_init_viewports(struct gui_synclist *list)
 {
     int i, parent_used;
@@ -91,6 +111,23 @@ static void list_init_viewports(struct gui_synclist *list)
             if (screens[i].has_buttonbar)
                 list->parent[i]->height -= BUTTONBAR_HEIGHT;
 #endif
+#ifdef HAVE_TOUCHSCREEN
+            switch (global_settings.list_item_padding)
+            {
+                case -1: /* from screen density */
+                    list->parent[i]->get_line_height =
+                                            line_height_from_lcd_dpi;
+                    break;
+                case  0: /* none / from font */
+                    list->parent[i]->get_line_height =
+                                            viewport_get_line_height_from_font;
+                    break;
+                default: /* from settings */
+                    list->parent[i]->get_line_height =
+                                            line_height_from_settings;
+                    break;
+            }
+#endif
         }
     }
     list_need_reinit = false;
@@ -120,13 +157,15 @@ bool list_display_title(struct gui_synclist *list, enum screen_type screen)
 
 static int list_get_nb_lines(struct gui_synclist *list, enum screen_type screen)
 {
-    struct viewport vp = *list->parent[screen];
-    int skin_count = skinlist_get_line_count(screen, list);
-    if (skin_count >= 0)
-        return skin_count;
-    if (list_display_title(list, screen))
-        vp.height -= font_get(list->parent[screen]->font)->height;
-    return viewport_get_nb_lines(&vp);
+    struct viewport *vp = list->parent[screen];
+    int lines = skinlist_get_line_count(screen, list);
+    if (lines < 0)
+    {
+        lines = viewport_get_nb_lines(vp);
+        if (list_display_title(list, screen))
+            lines -= 1;
+    }
+    return lines;
 }
 #else
 #define list_display_title(l, i) false
diff --git a/apps/gui/list.h b/apps/gui/list.h
index d40cfe9..c1c4d4a 100644
--- a/apps/gui/list.h
+++ b/apps/gui/list.h
@@ -202,6 +202,8 @@ int skinlist_get_line_count(enum screen_type screen, struct gui_synclist *list);
 extern unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list);
 /* only for private use in gui/list.c */
 extern void _gui_synclist_stop_kinetic_scrolling(void);
+/* notifier when the item padding seting changed */
+extern void on_list_padding_setting_changed(int value);
 #endif
 
 /* If the list has a pending postponed scheduled announcement, that
diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c
index df8093d..9622376 100644
--- a/apps/gui/viewport.c
+++ b/apps/gui/viewport.c
@@ -224,7 +224,7 @@ static bool is_theme_enabled(enum screen_type screen)
 int viewport_get_nb_lines(const struct viewport *vp)
 {
 #ifdef HAVE_LCD_BITMAP
-    return vp->height/font_get(vp->font)->height;
+    return vp->height/vp->get_line_height(vp);
 #else
     (void)vp;
     return 2;
@@ -322,6 +322,7 @@ void viewport_set_fullscreen(struct viewport *vp,
     set_default_align_flags(vp);
 #endif
     vp->font = global_status.font_id[screen];
+    vp->get_line_height = viewport_get_line_height_from_font;
     vp->drawmode = DRMODE_SOLID;
 #if LCD_DEPTH > 1
 #ifdef HAVE_REMOTE_LCD
diff --git a/apps/gui/viewport.h b/apps/gui/viewport.h
index 51ab35e..723f1e7 100644
--- a/apps/gui/viewport.h
+++ b/apps/gui/viewport.h
@@ -27,6 +27,7 @@
 #include "lcd.h"
 #include "system.h"
 #include "screen_access.h"
+#include "font.h"
 
 /* return the number of text lines in the vp viewport */
 int viewport_get_nb_lines(const struct viewport *vp);
@@ -48,6 +49,19 @@ void viewport_set_defaults(struct viewport *vp,
                             const enum screen_type screen);
 void viewport_set_fullscreen(struct viewport *vp,
                               const enum screen_type screen);
+
+static inline
+int viewport_get_line_height(struct viewport *vp)
+{
+    return vp->get_line_height(vp);
+}
+
+static inline
+int viewport_get_line_height_from_font(const struct viewport *vp)
+{
+    return font_get(vp->font)->height;
+}
+
 int get_viewport_default_colour(enum screen_type screen, bool fgcolour);
 
 #ifdef HAVE_LCD_BITMAP
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 5ee087e..9e9a63d 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -12830,3 +12830,34 @@
     multidrive_usb: "USB Hide Internal Drive"
   </voice>
 </phrase>
+<phrase>
+  id: LANG_LIST_ITEM_PADDING
+  desc: list padding, in display settings
+  user: core
+  <source>
+    *: none
+    touchscreen: "Item Padding in Lists"
+  </source>
+  <dest>
+    *: none
+    touchscreen: "Item Padding in Lists"
+  </dest>
+  <voice>
+    *: none
+    touchscreen: "Item Padding in Lists"
+  </voice>
+</phrase>
+<phrase>
+  id: LANG_AUTOMATIC
+  desc: generic automatic
+  user: core
+  <source>
+    *: "Automatic"
+  </source>
+  <dest>
+    *: "Automatic"
+  </dest>
+  <voice>
+    *: "Automatic"
+  </voice>
+</phrase>
diff --git a/apps/menus/display_menu.c b/apps/menus/display_menu.c
index 7e7b5a6..548c1b9 100644
--- a/apps/menus/display_menu.c
+++ b/apps/menus/display_menu.c
@@ -506,8 +506,9 @@ MENUITEM_FUNCTION(touchscreen_menu_calibrate, 0, ID2P(LANG_TOUCHSCREEN_CALIBRATE
                     NULL, NULL, Icon_NOICON);
 MENUITEM_FUNCTION(touchscreen_menu_reset_calibration, 0, ID2P(LANG_TOUCHSCREEN_RESET_CALIBRATION), reset_mapping,
                     NULL, NULL, Icon_NOICON);
+MENUITEM_SETTING(list_item_padding, &global_settings.list_item_padding, NULL);
 
-MAKE_MENU(touchscreen_menu, ID2P(LANG_TOUCHSCREEN_SETTINGS), NULL, Icon_NOICON, &touch_mode,
+MAKE_MENU(touchscreen_menu, ID2P(LANG_TOUCHSCREEN_SETTINGS), NULL, Icon_NOICON, &list_item_padding, &touch_mode,
             &touchscreen_menu_calibrate, &touchscreen_menu_reset_calibration);
 #endif
 
diff --git a/apps/settings.h b/apps/settings.h
index 36e403b..a0aff1b 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -562,6 +562,10 @@ struct user_settings
     int scrollbar_width;
 #endif
 
+#ifdef HAVE_TOUCHSCREEN
+    int list_item_padding;
+#endif
+
     /* goto current song when exiting WPS */
     bool browse_current; /* 1=goto current song,
                             0=goto previous location */
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 2f452e6..5043adf 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -286,6 +286,29 @@ static const char graphic_numeric[] = "graphic,numeric";
 
 #endif /* HAVE_RECORDING */
 
+static const char* list_pad_formatter(char *buffer, size_t buffer_size,
+                                    int val, const char *unit)
+{
+    switch (val)
+    {
+        case -1: return str(LANG_AUTOMATIC);
+        case  0: return str(LANG_OFF);
+        default: break;
+    }
+    snprintf(buffer, buffer_size, "%d %s", val, unit);
+    return buffer;
+}
+
+static int32_t list_pad_getlang(int value, int unit)
+{
+    switch (value)
+    {
+        case -1: return LANG_AUTOMATIC;
+        case  0: return LANG_OFF;
+        default: return TALK_ID(value, unit);
+    }
+}
+
 static const char* formatter_unit_0_is_off(char *buffer, size_t buffer_size,
                                     int val, const char *unit)
 {
@@ -744,6 +767,10 @@ const struct settings_list settings[] = {
     INT_SETTING(F_THEMESETTING, scrollbar_width, LANG_SCROLLBAR_WIDTH, 6,
                 "scrollbar width",UNIT_INT, 3, MAX(LCD_WIDTH/10,25), 1,
                 NULL, NULL, NULL),
+    TABLE_SETTING(F_ALLOW_ARBITRARY_VALS, list_item_padding, LANG_LIST_ITEM_PADDING,
+                  -1, "list padding", "off,auto", UNIT_PIXEL, list_pad_formatter,
+                  list_pad_getlang, on_list_padding_setting_changed, 16,
+                  -1,0,2,4,6,8,10,12,16,20,24,28,32,38,44,50),
 #if CONFIG_KEYPAD == RECORDER_PAD
     OFFON_SETTING(F_THEMESETTING,buttonbar, LANG_BUTTON_BAR ,true,"buttonbar", NULL),
 #endif
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
index fc84fdd..b405a91 100644
--- a/firmware/drivers/lcd-bitmap-common.c
+++ b/firmware/drivers/lcd-bitmap-common.c
@@ -254,11 +254,12 @@ void LCDFN(putsxyf)(int x, int y, const unsigned char *fmt, ...)
 
 static void LCDFN(putsxyofs_style)(int xpos, int ypos,
                                    const unsigned char *str, int style,
-                                   int w, int h, int offset)
+                                   int h, int offset)
 {
     int lastmode = current_vp->drawmode;
-    int xrect = xpos + MAX(w - offset, 0);
-    int x = VP_IS_RTL(current_vp) ? xpos : xrect;
+    int text_ypos = ypos;
+    int line_height = font_get(current_vp->font)->height;
+    text_ypos += h/2 - line_height/2; /* center the text in the line */
 #if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR)
     int oldfgcolor = current_vp->fg_pattern;
     int oldbgcolor = current_vp->bg_pattern;
@@ -284,21 +285,21 @@ static void LCDFN(putsxyofs_style)(int xpos, int ypos,
         current_vp->fg_pattern = current_vp->lst_pattern;
     }
     else {
-        lcd_fillrect(x, ypos, current_vp->width - xrect, h);
+        lcd_fillrect(xpos, ypos, current_vp->width - xpos, h);
         current_vp->drawmode = (style & STYLE_INVERT) ?
         (DRMODE_SOLID|DRMODE_INVERSEVID) : DRMODE_SOLID;
     }
     if (str[0])
-        lcd_putsxyofs(xpos, ypos, offset, str);
+        lcd_putsxyofs(xpos, text_ypos, offset, str);
     current_vp->fg_pattern = oldfgcolor;
     current_vp->bg_pattern = oldbgcolor;
 #else
     current_vp->drawmode = DRMODE_SOLID | ((style & STYLE_INVERT) ?
                                            0 : DRMODE_INVERSEVID);
-    LCDFN(fillrect)(x, ypos, current_vp->width - xrect, h);
+    LCDFN(fillrect)(xpos, ypos, current_vp->width - xpos, h);
     current_vp->drawmode ^= DRMODE_INVERSEVID;
     if (str[0])
-        LCDFN(putsxyofs)(xpos, ypos, offset, str);
+        LCDFN(putsxyofs)(xpos, text_ypos, offset, str);
 #endif
     current_vp->drawmode = lastmode;
 }
@@ -309,15 +310,15 @@ static void LCDFN(putsxyofs_style)(int xpos, int ypos,
 void LCDFN(puts_style_xyoffset)(int x, int y, const unsigned char *str,
                               int style, int x_offset, int y_offset)
 {
-    int xpos, ypos, w, h;
+    int xpos, ypos, h;
     LCDFN(scroll_stop_line)(current_vp, y);
     if(!str)
         return;
 
-    LCDFN(getstringsize)(str, &w, &h);
+    h = current_vp->get_line_height(current_vp);
     xpos = x * LCDFN(getstringsize)(" ", NULL, NULL);
     ypos = y * h + y_offset;
-    LCDFN(putsxyofs_style)(xpos, ypos, str, style, w, h, x_offset);
+    LCDFN(putsxyofs_style)(xpos, ypos, str, style, h, x_offset);
 }
 
 void LCDFN(puts_style_offset)(int x, int y, const unsigned char *str,
@@ -436,10 +437,9 @@ void LCDFN(puts_scroll_offset)(int x, int y, const unsigned char *string,
 
 void LCDFN(scroll_fn)(void)
 {
-    struct font* pf;
     struct scrollinfo* s;
     int index;
-    int xpos, ypos;
+    int xpos, ypos, height;
     struct viewport* old_vp = current_vp;
     bool makedelay;
 
@@ -451,15 +451,15 @@ void LCDFN(scroll_fn)(void)
             continue;
 
         LCDFN(set_viewport)(s->vp);
+        height = s->vp->get_line_height(s->vp);
 
         if (s->backward)
             s->offset -= LCDFN(scroll_info).step;
         else
             s->offset += LCDFN(scroll_info).step;
 
-        pf = font_get(current_vp->font);
         xpos = s->startx;
-        ypos = s->y * pf->height + s->y_offset;
+        ypos = s->y * height + s->y_offset;
 
         makedelay = false;
         if (s->bidir) { /* scroll bidirectional */
@@ -488,10 +488,8 @@ void LCDFN(scroll_fn)(void)
             s->start_tick = current_tick + LCDFN(scroll_info).delay +
                     LCDFN(scroll_info).ticks;
 
-        LCDFN(putsxyofs_style)(xpos, ypos, s->line, s->style, s->width,
-                               pf->height, s->offset);
-        LCDFN(update_viewport_rect)(xpos, ypos, current_vp->width - xpos,
-                               pf->height);
+        LCDFN(putsxyofs_style)(xpos, ypos, s->line, s->style, height, s->offset);
+        LCDFN(update_viewport_rect)(xpos, ypos, current_vp->width-xpos, height);
     }
     LCDFN(set_viewport)(old_vp);
 }
diff --git a/firmware/export/lcd.h b/firmware/export/lcd.h
index e6e19b1..3457a9e 100644
--- a/firmware/export/lcd.h
+++ b/firmware/export/lcd.h
@@ -54,6 +54,7 @@ struct viewport {
     unsigned lst_pattern;
 #endif
 #endif
+    int (*get_line_height)(const struct viewport* vp);
 };
 
 /* Frame buffer stride