Index: uspace/srv/hid/display/clonegc.c
===================================================================
--- uspace/srv/hid/display/clonegc.c	(revision 2ab8ab3c0a1e9771074c6e9d07ec1bf5e87ddafc)
+++ uspace/srv/hid/display/clonegc.c	(revision ec7902df3bea37028cfd215b507c5248f4e054dd)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2020 Jiri Svoboda
+ * Copyright (c) 2021 Jiri Svoboda
  * All rights reserved.
  *
@@ -44,4 +44,5 @@
 #include "clonegc.h"
 
+static errno_t ds_clonegc_set_clip_rect(void *, gfx_rect_t *);
 static errno_t ds_clonegc_set_color(void *, gfx_color_t *);
 static errno_t ds_clonegc_fill_rect(void *, gfx_rect_t *);
@@ -65,4 +66,5 @@
 
 gfx_context_ops_t ds_clonegc_ops = {
+	.set_clip_rect = ds_clonegc_set_clip_rect,
 	.set_color = ds_clonegc_set_color,
 	.fill_rect = ds_clonegc_fill_rect,
@@ -73,4 +75,29 @@
 };
 
+/** Set clipping rectangle on clone GC.
+ *
+ * @param arg Clone GC
+ * @param rect Rectangle
+ *
+ * @return EOK on success or an error code
+ */
+static errno_t ds_clonegc_set_clip_rect(void *arg, gfx_rect_t *rect)
+{
+	ds_clonegc_t *cgc = (ds_clonegc_t *)arg;
+	ds_clonegc_output_t *output;
+	errno_t rc;
+
+	output = ds_clonegc_first_output(cgc);
+	while (output != NULL) {
+		rc = gfx_set_clip_rect(output->gc, rect);
+		if (rc != EOK)
+			return rc;
+
+		output = ds_clonegc_next_output(output);
+	}
+
+	return EOK;
+}
+
 /** Set color on clone GC.
  *
Index: uspace/srv/hid/display/test/clonegc.c
===================================================================
--- uspace/srv/hid/display/test/clonegc.c	(revision 2ab8ab3c0a1e9771074c6e9d07ec1bf5e87ddafc)
+++ uspace/srv/hid/display/test/clonegc.c	(revision ec7902df3bea37028cfd215b507c5248f4e054dd)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2020 Jiri Svoboda
+ * Copyright (c) 2021 Jiri Svoboda
  * All rights reserved.
  *
@@ -39,4 +39,5 @@
 PCUT_TEST_SUITE(clonegc);
 
+static errno_t testgc_set_clip_rect(void *, gfx_rect_t *);
 static errno_t testgc_set_color(void *, gfx_color_t *);
 static errno_t testgc_fill_rect(void *, gfx_rect_t *);
@@ -48,4 +49,5 @@
 
 static gfx_context_ops_t ops = {
+	.set_clip_rect = testgc_set_clip_rect,
 	.set_color = testgc_set_color,
 	.fill_rect = testgc_fill_rect,
@@ -59,4 +61,7 @@
 	/** Error code to return */
 	errno_t rc;
+
+	bool set_clip_rect_called;
+	gfx_rect_t *set_clip_rect_rect;
 
 	bool set_color_called;
@@ -95,4 +100,74 @@
 	rc = ds_clonegc_create(NULL, &cgc);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_clonegc_delete(cgc);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+}
+
+/** Set clipping rectangle with two output GCs */
+PCUT_TEST(set_clip_rect)
+{
+	ds_clonegc_t *cgc;
+	gfx_context_t *gc;
+	test_gc_t tgc1;
+	gfx_context_t *gc1;
+	test_gc_t tgc2;
+	gfx_context_t *gc2;
+	gfx_rect_t rect;
+	errno_t rc;
+
+	/* Create clone GC */
+	rc = ds_clonegc_create(NULL, &cgc);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	gc = ds_clonegc_get_ctx(cgc);
+	PCUT_ASSERT_NOT_NULL(gc);
+
+	/* Add two output GCs */
+
+	rc = gfx_context_new(&ops, &tgc1, &gc1);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_clonegc_add_output(cgc, gc1);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = gfx_context_new(&ops, &tgc2, &gc2);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_clonegc_add_output(cgc, gc2);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rect.p0.x = 1;
+	rect.p0.y = 2;
+	rect.p1.x = 3;
+	rect.p1.y = 4;
+
+	/* Set clipping rectangle returning error */
+
+	tgc1.set_clip_rect_called = false;
+	tgc2.set_clip_rect_called = false;
+	tgc1.rc = EINVAL;
+	tgc2.rc = EINVAL;
+
+	rc = gfx_set_clip_rect(gc, &rect);
+	PCUT_ASSERT_ERRNO_VAL(EINVAL, rc);
+
+	PCUT_ASSERT_TRUE(tgc1.set_clip_rect_called);
+	PCUT_ASSERT_EQUALS(&rect, tgc1.set_clip_rect_rect);
+	PCUT_ASSERT_FALSE(tgc2.set_clip_rect_called);
+
+	/* Set clipping rectangle returning success for all outputs */
+	tgc1.set_clip_rect_called = false;
+	tgc2.set_clip_rect_called = false;
+	tgc1.rc = EOK;
+	tgc2.rc = EOK;
+
+	rc = gfx_set_clip_rect(gc, &rect);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_TRUE(tgc1.set_clip_rect_called);
+	PCUT_ASSERT_EQUALS(&rect, tgc1.set_clip_rect_rect);
+	PCUT_ASSERT_TRUE(tgc2.set_clip_rect_called);
+	PCUT_ASSERT_EQUALS(&rect, tgc2.set_clip_rect_rect);
 
 	rc = ds_clonegc_delete(cgc);
@@ -628,4 +703,14 @@
 }
 
+static errno_t testgc_set_clip_rect(void *arg, gfx_rect_t *rect)
+{
+	test_gc_t *tgc = (test_gc_t *) arg;
+
+	tgc->set_clip_rect_called = true;
+	tgc->set_clip_rect_rect = rect;
+
+	return tgc->rc;
+}
+
 static errno_t testgc_set_color(void *arg, gfx_color_t *color)
 {
