diff --git a/apps/action.c b/apps/action.c
index fc10c92..fbf520c 100644
--- a/apps/action.c
+++ b/apps/action.c
@@ -37,6 +37,7 @@
#if defined(HAVE_LCD_BITMAP) && !defined(BOOTLOADER)
#include "language.h"
#endif
+#include "viewport.h"

static int last_button = BUTTON_NONE|BUTTON_REL; /* allow the ipod wheel to
work on startup */
@@ -353,7 +354,7 @@ int get_action_statuscode(int *button)
}

#ifdef HAVE_TOUCHSCREEN
-/* return BUTTON_NONE on error
+/* return ACTION_NONE on error
* BUTTON_REPEAT if repeated press
* BUTTON_REPEAT|BUTTON_REL if release after repeated press
* BUTTON_REL if its a short press = release after press
@@ -386,6 +387,29 @@ int action_get_touchscreen_press(short *x, short *y)
return BUTTON_REPEAT|BUTTON_REL;
return BUTTON_TOUCHSCREEN;
}
+
+/* wrapper to filter the touchscreen coordinates through a viewport
+ * returns the action and x1, y1 relative to the viewport if
+ * the press was within the viewport,
+ * ACTION_UNKNOWN (and x1, y1 untouched) if the press was outside
+ * BUTTON_NONE else */
+int action_get_touchscreen_press_in_vp(short *x1, short *y1, struct viewport *vp)
+{
+ short x, y;
+ int ret;
+
+ ret = action_get_touchscreen_press(&x, &y);
+
+ if (ret != BUTTON_NONE && viewport_point_within_vp(vp, x, y))
+ {
+ *x1 = x - vp->x;
+ *y1 = y - vp->y;
+ return ret;
+ }
+ if (ret & BUTTON_TOUCHSCREEN)
+ return ACTION_UNKNOWN;
+ return BUTTON_NONE;
+}
#endif

/* Don't let get_action*() return any ACTION_* values untill the current buttons
diff --git a/apps/action.h b/apps/action.h
index 24250ef..545994d 100644
--- a/apps/action.h
+++ b/apps/action.h
@@ -22,6 +22,7 @@

#include "stdbool.h"
#include "button.h"
+#include "viewport.h"

#define TIMEOUT_BLOCK -1
#define TIMEOUT_NOBLOCK 0
@@ -327,12 +328,20 @@ int get_action_statuscode(int *button);
intptr_t get_action_data(void);

#ifdef HAVE_TOUCHSCREEN
-/* return BUTTON_NONE on error
- BUTTON_REPEAT if repeated press
- BUTTON_REL if its a short press
- BUTTON_TOUCHSCREEN otherwise
-*/
+/* return ACTION_NONE on error
+ * BUTTON_REPEAT if repeated press
+ * BUTTON_REPEAT|BUTTON_REL if release after repeated press
+ * BUTTON_REL if its a short press = release after press
+ * BUTTON_TOUCHSCREEN if press
+ */
int action_get_touchscreen_press(short *x, short *y);
+
+/* wrapper for action_get_touchscreen_press
+ * to filter the touchscreen coordinates through a viewport,
+ * returns the action and x1, y1 relative to the viewport if
+ * the press was within the viewport,
+ * ACTION_NONE (and x1, y1 untouched) if the press was outside */
+int action_get_touchscreen_press_in_vp(short *x1, short *y1, struct viewport *vp);
#endif

/* Don't let get_action*() return any ACTION_* values untill the current buttons
diff --git a/apps/gui/color_picker.c b/apps/gui/color_picker.c
index d70b98c..75c0612 100644
--- a/apps/gui/color_picker.c
+++ b/apps/gui/color_picker.c
@@ -335,7 +335,7 @@ static int touchscreen_slider(struct screen *display,
{
short x,y;
int text_top, slider_x, slider_width, title_height;
- unsigned button = action_get_touchscreen_press(&x, &y);
+ int button;
bool display_three_rows;
int max_label_width;
int pressed_slider;
@@ -344,16 +344,15 @@ static int touchscreen_slider(struct screen *display,

viewport_set_defaults(&vp, display->screen_type);

- if (button == BUTTON_NONE)
- return ACTION_NONE;
-
max_label_width = label_get_max_width(display);
display->getstringsize(title, NULL, &title_height);
-
+ button = action_get_touchscreen_press_in_vp(&x, &y, &vp);
+ if (button == ACTION_UNKNOWN || button == BUTTON_NONE)
+ return ACTION_NONE;
/* Get slider positions and top starting position
* need vp.y here, because of the statusbar, since touchscreen
* coordinates are absolute */
- text_top = vp.y + MARGIN_TOP + title_height + TITLE_MARGIN_BOTTOM +
+ text_top = MARGIN_TOP + title_height + TITLE_MARGIN_BOTTOM +
SELECTOR_TB_MARGIN;
slider_x = SELECTOR_WIDTH + max_label_width + SLIDER_TEXT_MARGIN;
slider_width = vp.width - slider_x*2 - max_label_width;
@@ -376,12 +375,15 @@ static int touchscreen_slider(struct screen *display,
return ACTION_STD_CANCEL;
}

- pressed_slider = (y - text_top)/line_height;
- if (pressed_slider > (display_three_rows?2:0))
- {
+ vp.y += text_top;
+ vp.height = line_height * (display_three_rows ? 3:1);
+ if (!viewport_point_within_vp(&vp, x, y))
+ { /* touching the color area means accept */
if (button == BUTTON_REL)
return ACTION_STD_OK;
}
+ /* y is relative to the original viewport */
+ pressed_slider = (y - text_top)/line_height;
if (pressed_slider != *selected_slider)
*selected_slider = pressed_slider;
/* add max_label_width to overcome integer division limits,