diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index 87d7107..10d4a91 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -40,6 +40,7 @@
 #include "misc.h"
 #include "viewport.h"
 #include "statusbar-skinned.h"
+#include "debug.h"

 #define ICON_PADDING 1

@@ -230,8 +231,10 @@ void list_draw(struct screen *display, struct gui_synclist *list)
             }
         }
 #endif
-        if(i >= list->selected_item && i <  list->selected_item
-                + list->selected_size && list->show_selection_marker)
+        /* draw the selected line */
+        if(!list->hide_selection && i >= list->selected_item
+                && i <  list->selected_item + list->selected_size
+                && list->show_selection_marker)
         {/* The selected item must be displayed scrolling */
             if (global_settings.cursor_style == 1
 #ifdef HAVE_REMOTE_LCD
@@ -308,7 +311,16 @@ void list_draw(struct screen *display, struct gui_synclist *list)

 #if defined(HAVE_TOUCHSCREEN)
 /* This needs to be fixed if we ever get more than 1 touchscreen on a target. */
-static bool scrolling=false;
+static bool scrolling = false;
+static bool released = false;
+
+/* Used for kinetic scrolling as we need to know the last position to
+ * recognize the scroll direction.
+ * This gets reset to 0 at the end of scrolling
+ */
+static int last_position=0;
+static long scroll_cancel;
+

 static int gui_synclist_touchscreen_scrollbar(struct gui_synclist * gui_list,
                                               int y)
@@ -319,7 +331,6 @@ static int gui_synclist_touchscreen_scrollbar(struct gui_synclist * gui_list,
     if (nb_lines <  gui_list->nb_items)
     {
         scrolling = true;
-
         int scrollbar_size = nb_lines*
             font_get(gui_list->parent[screen]->font)->height;
         int actual_y = y - list_text[screen].y;
@@ -334,7 +345,6 @@ static int gui_synclist_touchscreen_scrollbar(struct gui_synclist * gui_list,
             start_item = gui_list->nb_items - nb_lines;

         gui_list->start_item[screen] = start_item;
-        gui_synclist_select_item(gui_list, new_selection);

         return ACTION_REDRAW;
     }
@@ -342,16 +352,47 @@ static int gui_synclist_touchscreen_scrollbar(struct gui_synclist * gui_list,
     return ACTION_NONE;
 }

+#ifdef HAVE_TOUCHSCREEN
+static int gui_synclist_touchscreen_scrolling(struct gui_synclist * gui_list, int position)
+{
+    const int screen = screens[SCREEN_MAIN].screen_type;
+    const int difference = position - last_position;
+    const int nb_lines = viewport_get_nb_lines(&list_text[screen]);
+    if(nb_lines < gui_list->nb_items && difference != 0) // only scroll if needed
+    {
+        int new_start_item;
+        new_start_item = gui_list->start_item[screen] - difference;
+        // check if new_start_item is bigger than list item count
+        if(new_start_item > gui_list->nb_items - nb_lines)
+            new_start_item = gui_list->nb_items - nb_lines;
+        // set new_start_item to 0 if it's negative
+        if(new_start_item < 0)
+            new_start_item = 0;
+        gui_list->start_item[screen] = new_start_item;
+    }
+    return difference;
+}
+#endif
+
 unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list)
 {
     short x, y;
-    const int button = action_get_touchscreen_press(&x, &y);
+    int button = action_get_touchscreen_press(&x, &y);
     int line;
     const int screen = SCREEN_MAIN;
     const int list_start_item = gui_list->start_item[screen];
     const struct viewport *list_text_vp = &list_text[screen];
     int list_width = list_text_vp->width;
+    bool old_released = released;
+
+    if (UNLIKELY(scroll_cancel == 0))
+        scroll_cancel = current_tick;
+
+    released = (button&BUTTON_REL) != 0;
+    gui_list->hide_selection = scrolling;

+
+    
     if (global_settings.scrollbar == SCROLLBAR_RIGHT)
         list_width += SCROLLBAR_WIDTH;

@@ -385,9 +426,17 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list)
     }
     else
     {
-        if (x > list_text_vp->x + list_text_vp->width &&
-           global_settings.scrollbar == SCROLLBAR_RIGHT)
-            return gui_synclist_touchscreen_scrollbar(gui_list, y);
+        int line_height = font_get(gui_list->parent[screen]->font)->height;
+        if (global_settings.scrollbar == SCROLLBAR_RIGHT)
+        {
+            int x_end = list_text_vp->x+list_text_vp->width;
+            if (x > x_end)
+                return gui_synclist_touchscreen_scrollbar(gui_list, y);
+            /* empty margin to prevent accidental selection when using
+             * the scrollbar */
+            else if (x > (x_end - line_height))
+                return ACTION_NONE;
+        }

         /* |--------------------------------------------------------|
          * | Description of the touchscreen list interface:         |
@@ -403,10 +452,9 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list)
          */
         if (y > list_text_vp->y || button & BUTTON_REPEAT)
         {
-            int line_height, actual_y;
-            
+            int actual_y;
+
             actual_y = y - list_text_vp->y;
-            line_height = font_get(gui_list->parent[screen]->font)->height;
             line = actual_y / line_height;

             /* Pressed below the list*/
@@ -416,30 +464,10 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list)
             /* Pressed a border */
             if(UNLIKELY(actual_y % line_height == 0))
                 return ACTION_NONE;
-            
-            if (line != (gui_list->selected_item - list_start_item)
-                && button ^ BUTTON_REL)
-            {
-                if(button & BUTTON_REPEAT)
-                    scrolling = true;
-                
-                gui_synclist_select_item(gui_list, list_start_item + line);
-                
-                return ACTION_REDRAW;
-            }
-            
-            /* This has the same effect as the icons do when the scrollbar
-               is on the left (ie eliminate the chances an user enters/starts
-               an item when he wanted to use the scrollbar, due to touchscreen
-               dead zones)
-             */
-            if(global_settings.scrollbar == SCROLLBAR_RIGHT &&
-               x > list_text_vp->x + list_text_vp->width -
-                   get_icon_width(SCREEN_MAIN))
-                return ACTION_NONE;
-            
+
             if (button == (BUTTON_REPEAT|BUTTON_REL))
             {
+                last_position = 0;
                 if(!scrolling)
                 {
                     /* Pen was hold on the same line as the 
@@ -454,21 +482,55 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list)
                      * this one
                      * => do nothing
                      */
-                    scrolling = false;
                     return ACTION_NONE;
                 }
             }
-            else if(button == BUTTON_REL &&
-                    line == gui_list->selected_item - list_start_item)
+            else if (button & BUTTON_REL)
             {
                 /* Pen was released on either the same line as the previously
                  *  selected one or an other one
                  *  => simulate short press
                  */
-                return ACTION_STD_OK;
+                last_position = 0;
+                if (!scrolling)
+                {
+                    gui_synclist_select_item(gui_list, list_start_item + line);
+                    return ACTION_STD_OK;
+                }
+                else
+                    return ACTION_NONE;
             }
             else
-                return ACTION_NONE;
+            {
+                int result = 0;
+                bool redraw = false;
+
+                /* beginning of list interaction */
+                if (old_released)
+                {
+                    scrolling = false;
+                    scroll_cancel = current_tick;
+                    redraw = true;
+                    gui_list->hide_selection = false;
+                }
+                
+
+                gui_synclist_select_item(gui_list, list_start_item+line);
+                if (last_position == 0)
+                    last_position = line;
+                else
+                    result = gui_synclist_touchscreen_scrolling(gui_list, line);
+
+                if (result)
+                {
+                    redraw = true;
+                    scrolling = true;
+                }
+
+                last_position = line;
+
+                return redraw ? ACTION_REDRAW:ACTION_NONE;
+            }
         }
     }
     return ACTION_NONE;
diff --git a/apps/gui/list.h b/apps/gui/list.h
index 965a46b..57ca912 100644
--- a/apps/gui/list.h
+++ b/apps/gui/list.h
@@ -94,7 +94,10 @@ struct gui_synclist
     /* wether the text of the whole items of the list have to be
      * scrolled or only for the selected item */
     bool scroll_all;
-
+    /*
+     * if true the selection bar will not be drawn
+     */
+    bool hide_selection;
     int nb_items;
     int selected_item;
     int start_item[NB_SCREENS]; /* the item that is displayed at the top of the screen */
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c
index 0d0d1cd..3d8a5a4 100644
--- a/firmware/drivers/button.c
+++ b/firmware/drivers/button.c
@@ -233,6 +233,13 @@ static void button_tick(void)
                         /* initial repeat */
                         count = REPEAT_INTERVAL_START;
                     }
+#ifdef HAVE_TOUCHSCREEN
+                    else if (data != lastdata && btn == lastbtn)
+                    {   /* only coordinates changed, post anyway */
+                        if (touchscreen_get_mode() == TOUCHSCREEN_POINT)
+                            post = true;
+                    }
+#endif
                 }
             }
             if ( post )