Index: uspace/srv/hid/display/display.c
===================================================================
--- uspace/srv/hid/display/display.c	(revision dbef30fb1faefbb940d9c7275e085e71216fe08b)
+++ uspace/srv/hid/display/display.c	(revision 978c9bc58ddd532fb1e7d27a9d069c678c4b31f5)
@@ -553,4 +553,5 @@
 	errno_t rc;
 	ds_window_t *wnd;
+	ds_seat_t *seat;
 
 	/* Paint background */
@@ -569,4 +570,13 @@
 	}
 
+	seat = ds_display_first_seat(disp);
+	while (seat != NULL) {
+		rc = ds_seat_paint_pointer(seat, rect);
+		if (rc != EOK)
+			return rc;
+
+		seat = ds_display_next_seat(seat);
+	}
+
 	return EOK;
 }
Index: uspace/srv/hid/display/seat.c
===================================================================
--- uspace/srv/hid/display/seat.c	(revision dbef30fb1faefbb940d9c7275e085e71216fe08b)
+++ uspace/srv/hid/display/seat.c	(revision 978c9bc58ddd532fb1e7d27a9d069c678c4b31f5)
@@ -45,6 +45,6 @@
 #include "window.h"
 
-static errno_t ds_seat_clear_pointer(ds_seat_t *);
-static errno_t ds_seat_draw_pointer(ds_seat_t *);
+static void ds_seat_get_pointer_rect(ds_seat_t *, gfx_rect_t *);
+static errno_t ds_seat_repaint_pointer(ds_seat_t *, gfx_rect_t *);
 
 /** Create seat.
@@ -185,15 +185,16 @@
 	ds_cursor_t *old_cursor;
 	ds_cursor_t *new_cursor;
+	gfx_rect_t old_rect;
 
 	old_cursor = ds_seat_get_cursor(seat);
 	new_cursor = ds_seat_compute_cursor(seat->wm_cursor, cursor);
 
-	if (new_cursor != old_cursor)
-		ds_seat_clear_pointer(seat);
-
-	seat->client_cursor = cursor;
-
-	if (new_cursor != old_cursor)
-		ds_seat_draw_pointer(seat);
+	if (new_cursor != old_cursor) {
+		ds_seat_get_pointer_rect(seat, &old_rect);
+		seat->client_cursor = cursor;
+		ds_seat_repaint_pointer(seat, &old_rect);
+	} else {
+		seat->client_cursor = cursor;
+	}
 }
 
@@ -209,49 +210,74 @@
 	ds_cursor_t *old_cursor;
 	ds_cursor_t *new_cursor;
+	gfx_rect_t old_rect;
 
 	old_cursor = ds_seat_get_cursor(seat);
 	new_cursor = ds_seat_compute_cursor(cursor, seat->client_cursor);
 
-	if (new_cursor != old_cursor)
-		ds_seat_clear_pointer(seat);
-
-	seat->wm_cursor = cursor;
-
-	if (new_cursor != old_cursor)
-		ds_seat_draw_pointer(seat);
-}
-
-/** Draw seat pointer
- *
- * @param seat Seat
+	if (new_cursor != old_cursor) {
+		ds_seat_get_pointer_rect(seat, &old_rect);
+		seat->wm_cursor = cursor;
+		ds_seat_repaint_pointer(seat, &old_rect);
+	} else {
+		seat->wm_cursor = cursor;
+	}
+}
+
+/** Get rectangle covered by pointer.
+ *
+ * @param seat Seat
+ * @param rect Place to store rectangle
+ */
+void ds_seat_get_pointer_rect(ds_seat_t *seat, gfx_rect_t *rect)
+{
+	ds_cursor_t *cursor;
+
+	cursor = ds_seat_get_cursor(seat);
+	ds_cursor_get_rect(cursor, &seat->pntpos, rect);
+}
+
+/** Repaint seat pointer
+ *
+ * Repaint the pointer after it has moved or changed. This is done by
+ * repainting the are of the display previously (@a old_rect) and currently
+ * covered by the pointer.
+ *
+ * @param seat Seat
+ * @param old_rect Rectangle previously covered by pointer
  *
  * @return EOK on success or an error code
  */
-static errno_t ds_seat_draw_pointer(ds_seat_t *seat)
-{
-	ds_cursor_t *cursor;
-
-	cursor = ds_seat_get_cursor(seat);
-	return ds_cursor_paint(cursor, &seat->pntpos);
-}
-
-/** Clear seat pointer
- *
- * @param seat Seat
- *
- * @return EOK on success or an error code
- */
-static errno_t ds_seat_clear_pointer(ds_seat_t *seat)
-{
-	gfx_rect_t rect;
-	ds_cursor_t *cursor;
-
-	cursor = ds_seat_get_cursor(seat);
-
-	/* Get rectangle covered by cursor */
-	ds_cursor_get_rect(cursor, &seat->pntpos, &rect);
-
-	/* Repaint it */
-	return ds_display_paint(seat->display, &rect);
+static errno_t ds_seat_repaint_pointer(ds_seat_t *seat, gfx_rect_t *old_rect)
+{
+	gfx_rect_t new_rect;
+	gfx_rect_t isect;
+	gfx_rect_t envelope;
+	errno_t rc;
+
+	ds_seat_get_pointer_rect(seat, &new_rect);
+
+	gfx_rect_clip(old_rect, &new_rect, &isect);
+	if (gfx_rect_is_empty(&isect)) {
+		/* Rectangles do not intersect. Repaint them separately. */
+		rc = ds_display_paint(seat->display, &new_rect);
+		if (rc != EOK)
+			return rc;
+
+		rc = ds_display_paint(seat->display, old_rect);
+		if (rc != EOK)
+			return rc;
+	} else {
+		/*
+		 * Rectangles intersect. As an optimization, repaint them
+		 * in a single operation.
+		 */
+		gfx_rect_envelope(old_rect, &new_rect, &envelope);
+
+		rc = ds_display_paint(seat->display, &envelope);
+		if (rc != EOK)
+			return rc;
+	}
+
+	return EOK;
 }
 
@@ -269,4 +295,5 @@
 	ds_display_t *disp = seat->display;
 	gfx_coord2_t npos;
+	gfx_rect_t old_rect;
 	ds_window_t *wnd;
 	pos_event_t pevent;
@@ -299,5 +326,5 @@
 		gfx_coord2_clip(&npos, &disp->rect, &npos);
 
-		(void) ds_seat_clear_pointer(seat);
+		ds_seat_get_pointer_rect(seat, &old_rect);
 		seat->pntpos = npos;
 
@@ -312,5 +339,5 @@
 			return rc;
 
-		(void) ds_seat_draw_pointer(seat);
+		ds_seat_repaint_pointer(seat, &old_rect);
 	}
 
@@ -327,5 +354,5 @@
 		gfx_coord2_clip(&npos, &disp->rect, &npos);
 
-		(void) ds_seat_clear_pointer(seat);
+		ds_seat_get_pointer_rect(seat, &old_rect);
 		seat->pntpos = npos;
 
@@ -340,5 +367,5 @@
 			return rc;
 
-		(void) ds_seat_draw_pointer(seat);
+		ds_seat_repaint_pointer(seat, &old_rect);
 	}
 
@@ -380,4 +407,18 @@
 }
 
+/** Paint seat pointer.
+ *
+ * @param seat Seat whose pointer to paint
+ * @param rect Clipping rectangle
+ */
+errno_t ds_seat_paint_pointer(ds_seat_t *seat, gfx_rect_t *rect)
+{
+	ds_cursor_t *cursor;
+
+	cursor = ds_seat_get_cursor(seat);
+	(void) rect; // XXX ds_cursor_paint should accept a clipping rectangle
+	return ds_cursor_paint(cursor, &seat->pntpos);
+}
+
 /** @}
  */
Index: uspace/srv/hid/display/seat.h
===================================================================
--- uspace/srv/hid/display/seat.h	(revision dbef30fb1faefbb940d9c7275e085e71216fe08b)
+++ uspace/srv/hid/display/seat.h	(revision 978c9bc58ddd532fb1e7d27a9d069c678c4b31f5)
@@ -38,4 +38,5 @@
 
 #include <errno.h>
+#include <gfx/coord.h>
 #include <io/kbd_event.h>
 #include <io/pos_event.h>
@@ -53,4 +54,5 @@
 extern errno_t ds_seat_post_pos_event(ds_seat_t *, pos_event_t *);
 extern void ds_seat_set_wm_cursor(ds_seat_t *, ds_cursor_t *);
+extern errno_t ds_seat_paint_pointer(ds_seat_t *, gfx_rect_t *);
 
 #endif
