Index: uspace/app/uidemo/uidemo.c
===================================================================
--- uspace/app/uidemo/uidemo.c	(revision 4ed00d3638fbbf6827906cc823e1d277fbad9277)
+++ uspace/app/uidemo/uidemo.c	(revision faca61b865ace1f8e56cfe959875ce75b8aaad0d)
@@ -81,49 +81,7 @@
 {
 	ui_demo_t *demo = (ui_demo_t *) arg;
-	gfx_rect_t rect1;
-	gfx_rect_t rect2;
-	gfx_coord2_t pos;
-
-	rect1.p0.x = 20;
-	rect1.p0.y = 50;
-	rect1.p1.x = 100;
-	rect1.p1.y = 80;
-
-	rect2.p0.x = 120;
-	rect2.p0.y = 50;
-	rect2.p1.x = 200;
-	rect2.p1.y = 80;
-
-	pos.x = event->hpos;
-	pos.y = event->vpos;
-
-	if (event->type == POS_PRESS) {
-		printf("Button press\n");
-
-		if (gfx_pix_inside_rect(&pos, &rect1)) {
-			printf("Press button 1\n");
-			ui_pbutton_press(demo->pb1);
-			(void) ui_pbutton_paint(demo->pb1);
-		}
-		if (gfx_pix_inside_rect(&pos, &rect2)) {
-			printf("Press button 2\n");
-			ui_pbutton_press(demo->pb2);
-			(void) ui_pbutton_paint(demo->pb2);
-		}
-	}
-
-	if (event->type == POS_RELEASE) {
-		printf("Button release\n");
-		if (gfx_pix_inside_rect(&pos, &rect1)) {
-			printf("Release button 1\n");
-			ui_pbutton_release(demo->pb1);
-			(void) ui_pbutton_paint(demo->pb1);
-		}
-		if (gfx_pix_inside_rect(&pos, &rect2)) {
-			printf("Release button 2\n");
-			ui_pbutton_release(demo->pb2);
-			(void) ui_pbutton_paint(demo->pb2);
-		}
-	}
+
+	ui_pbutton_pos_event(demo->pb1, event);
+	ui_pbutton_pos_event(demo->pb2, event);
 }
 
Index: uspace/lib/ui/include/ui/pbutton.h
===================================================================
--- uspace/lib/ui/include/ui/pbutton.h	(revision 4ed00d3638fbbf6827906cc823e1d277fbad9277)
+++ uspace/lib/ui/include/ui/pbutton.h	(revision faca61b865ace1f8e56cfe959875ce75b8aaad0d)
@@ -39,4 +39,5 @@
 #include <errno.h>
 #include <gfx/coord.h>
+#include <io/pos_event.h>
 #include <types/ui/pbutton.h>
 #include <types/ui/resource.h>
@@ -51,4 +52,5 @@
 extern void ui_pbutton_press(ui_pbutton_t *);
 extern void ui_pbutton_release(ui_pbutton_t *);
+extern void ui_pbutton_pos_event(ui_pbutton_t *, pos_event_t *);
 
 #endif
Index: uspace/lib/ui/src/pbutton.c
===================================================================
--- uspace/lib/ui/src/pbutton.c	(revision 4ed00d3638fbbf6827906cc823e1d277fbad9277)
+++ uspace/lib/ui/src/pbutton.c	(revision faca61b865ace1f8e56cfe959875ce75b8aaad0d)
@@ -39,4 +39,5 @@
 #include <gfx/render.h>
 #include <gfx/text.h>
+#include <io/pos_event.h>
 #include <stdlib.h>
 #include <str.h>
@@ -408,4 +409,29 @@
 }
 
+/** Handle push button position event.
+ *
+ * @param pbutton Push button
+ * @param pos_event Position event
+ */
+void ui_pbutton_pos_event(ui_pbutton_t *pbutton, pos_event_t *event)
+{
+	gfx_coord2_t pos;
+
+	pos.x = event->hpos;
+	pos.y = event->vpos;
+
+	if (gfx_pix_inside_rect(&pos, &pbutton->rect)) {
+		if (event->type == POS_PRESS) {
+			ui_pbutton_press(pbutton);
+			(void) ui_pbutton_paint(pbutton);
+		}
+	}
+
+	if (event->type == POS_RELEASE && pbutton->held) {
+		ui_pbutton_release(pbutton);
+		(void) ui_pbutton_paint(pbutton);
+	}
+}
+
 /** @}
  */
Index: uspace/lib/ui/test/pbutton.c
===================================================================
--- uspace/lib/ui/test/pbutton.c	(revision 4ed00d3638fbbf6827906cc823e1d277fbad9277)
+++ uspace/lib/ui/test/pbutton.c	(revision faca61b865ace1f8e56cfe959875ce75b8aaad0d)
@@ -185,4 +185,47 @@
 }
 
+/** ui_pos_event() correctly translates POS_PRESS/POS_RELEASE */
+PCUT_TEST(pos_event_press_release)
+{
+	ui_pbutton_t *pbutton;
+	pos_event_t event;
+	gfx_rect_t rect;
+	errno_t rc;
+
+	rc = ui_pbutton_create(NULL, "Hello", &pbutton);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_FALSE(pbutton->held);
+
+	rect.p0.x = 10;
+	rect.p0.y = 20;
+	rect.p1.x = 30;
+	rect.p1.y = 40;
+	ui_pbutton_set_rect(pbutton, &rect);
+
+	/* Press outside does nothing */
+	event.type = POS_PRESS;
+	event.hpos = 9;
+	event.vpos = 20;
+	ui_pbutton_pos_event(pbutton, &event);
+	PCUT_ASSERT_FALSE(pbutton->held);
+
+	/* Press inside depresses button */
+	event.type = POS_PRESS;
+	event.hpos = 10;
+	event.vpos = 20;
+	ui_pbutton_pos_event(pbutton, &event);
+	PCUT_ASSERT_TRUE(pbutton->held);
+
+	/* Release outside (or anywhere) relases button */
+	event.type = POS_RELEASE;
+	event.hpos = 9;
+	event.vpos = 20;
+	ui_pbutton_pos_event(pbutton, &event);
+	PCUT_ASSERT_FALSE(pbutton->held);
+
+	ui_pbutton_destroy(pbutton);
+}
+
 static errno_t testgc_set_color(void *arg, gfx_color_t *color)
 {
@@ -214,6 +257,6 @@
 		tbm->alloc.off0 = 0;
 		tbm->alloc.pixels = calloc(sizeof(uint32_t),
-			(params->rect.p1.x - params->rect.p0.x) *
-			(params->rect.p1.y - params->rect.p0.y));
+		    (params->rect.p1.x - params->rect.p0.x) *
+		    (params->rect.p1.y - params->rect.p0.y));
 		tbm->myalloc = true;
 		if (tbm->alloc.pixels == NULL) {
Index: uspace/lib/ui/test/resource.c
===================================================================
--- uspace/lib/ui/test/resource.c	(revision 4ed00d3638fbbf6827906cc823e1d277fbad9277)
+++ uspace/lib/ui/test/resource.c	(revision faca61b865ace1f8e56cfe959875ce75b8aaad0d)
@@ -114,6 +114,6 @@
 		tbm->alloc.off0 = 0;
 		tbm->alloc.pixels = calloc(sizeof(uint32_t),
-			(params->rect.p1.x - params->rect.p0.x) *
-			(params->rect.p1.y - params->rect.p0.y));
+		    (params->rect.p1.x - params->rect.p0.x) *
+		    (params->rect.p1.y - params->rect.p0.y));
 		tbm->myalloc = true;
 		if (tbm->alloc.pixels == NULL) {
