Index: uspace/srv/hid/display/display.c
===================================================================
--- uspace/srv/hid/display/display.c	(revision 6e91475d2748dc57c8470404beb69fc18a2c93c5)
+++ uspace/srv/hid/display/display.c	(revision 29a5a9917c778c2ef39d5fcb7843fcf719c4409e)
@@ -665,4 +665,6 @@
 	}
 
+	ds_display_update_max_rect(disp);
+
 	return EOK;
 error:
@@ -739,4 +741,69 @@
 }
 
+/** Update display maximize rectangle.
+ *
+ * Recalculate the maximize rectangle (the rectangle used for maximized
+ * windows).
+ *
+ * @param display Display
+ */
+void ds_display_update_max_rect(ds_display_t *display)
+{
+	ds_window_t *wnd;
+	gfx_rect_t max_rect;
+	gfx_rect_t drect;
+
+	/* Start with the entire display */
+	max_rect = display->rect;
+
+	wnd = ds_display_first_window(display);
+	while (wnd != NULL) {
+		/* Should maximized windows avoid this window? */
+		if ((wnd->flags & wndf_avoid) != 0) {
+			/* Window bounding rectangle on display */
+			gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
+
+			/* Crop maximized rectangle */
+			ds_display_crop_max_rect(&drect, &max_rect);
+		}
+
+		wnd = ds_display_next_window(wnd);
+	}
+
+	/* Update the maximize rectangle */
+	display->max_rect = max_rect;
+}
+
+/** Crop maximize rectangle.
+ *
+ * Use the avoid rectangle @a arect to crop off maximization rectangle
+ * @a mrect. If @a arect covers the top, bottom, left or right part
+ * of @a mrect, it will be cropped off. Otherwise there will be
+ * no effect.
+ *
+ * @param arect Avoid rectangle
+ * @param mrect Maximize rectangle to be modified
+ */
+void ds_display_crop_max_rect(gfx_rect_t *arect, gfx_rect_t *mrect)
+{
+	if (arect->p0.x == mrect->p0.x && arect->p0.y == mrect->p0.y &&
+	    arect->p1.x == mrect->p1.x) {
+		/* Cropp off top part */
+		mrect->p0.y = arect->p1.y;
+	} else if (arect->p0.x == mrect->p0.x && arect->p1.x == mrect->p1.x &&
+	    arect->p1.y == mrect->p1.y) {
+		/* Cropp off bottom part */
+		mrect->p1.y = arect->p0.y;
+	} else if (arect->p0.x == mrect->p0.x && arect->p0.y == mrect->p0.y &&
+	    arect->p1.y == mrect->p1.y) {
+		/* Cropp off left part */
+		mrect->p0.x = arect->p1.x;
+	} else if (arect->p0.y == mrect->p0.y && arect->p1.x == mrect->p1.x &&
+	    arect->p1.y == mrect->p1.y) {
+		/* Cropp off right part */
+		mrect->p1.x = arect->p0.x;
+	}
+}
+
 /** Get unbuffered GC.
  *
Index: uspace/srv/hid/display/display.h
===================================================================
--- uspace/srv/hid/display/display.h	(revision 6e91475d2748dc57c8470404beb69fc18a2c93c5)
+++ uspace/srv/hid/display/display.h	(revision 29a5a9917c778c2ef39d5fcb7843fcf719c4409e)
@@ -88,4 +88,6 @@
 extern void ds_display_add_cursor(ds_display_t *, ds_cursor_t *);
 extern void ds_display_remove_cursor(ds_cursor_t *);
+extern void ds_display_update_max_rect(ds_display_t *);
+extern void ds_display_crop_max_rect(gfx_rect_t *, gfx_rect_t *);
 extern gfx_context_t *ds_display_get_gc(ds_display_t *);
 extern errno_t ds_display_paint_bg(ds_display_t *, gfx_rect_t *);
Index: uspace/srv/hid/display/test/display.c
===================================================================
--- uspace/srv/hid/display/test/display.c	(revision 6e91475d2748dc57c8470404beb69fc18a2c93c5)
+++ uspace/srv/hid/display/test/display.c	(revision 29a5a9917c778c2ef39d5fcb7843fcf719c4409e)
@@ -601,3 +601,169 @@
 }
 
+/** ds_display_update_max_rect() updates maximization rectangle */
+PCUT_TEST(display_update_max_rect)
+{
+	ds_display_t *disp;
+	ds_seat_t *seat;
+	ds_client_t *client;
+	ds_window_t *wnd;
+	display_wnd_params_t params;
+	errno_t rc;
+
+	rc = ds_display_create(NULL, df_none, &disp);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_seat_create(disp, &seat);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_client_create(disp, NULL, NULL, &client);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/*
+	 * We need to set display dimensions Here we do it directly
+	 * instead of adding a display device.
+	 */
+	disp->rect.p0.x = 0;
+	disp->rect.p0.y = 0;
+	disp->rect.p1.x = 500;
+	disp->rect.p1.y = 500;
+
+	/* Set maximize rectangle as well */
+	disp->max_rect = disp->rect;
+
+	/* A panel-like window at the bottom */
+	display_wnd_params_init(&params);
+	params.flags |= wndf_setpos;
+	params.pos.x = 0;
+	params.pos.y = 450;
+	params.rect.p0.x = 0;
+	params.rect.p0.y = 0;
+	params.rect.p1.x = 500;
+	params.rect.p1.y = 50;
+
+	rc = ds_window_create(client, &params, &wnd);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	/*
+	 * At this point the maximize rect should be unaltered because
+	 * the avoid flag has not been set.
+	 */
+	PCUT_ASSERT_INT_EQUALS(0, disp->max_rect.p0.x);
+	PCUT_ASSERT_INT_EQUALS(0, disp->max_rect.p0.y);
+	PCUT_ASSERT_INT_EQUALS(500, disp->max_rect.p1.x);
+	PCUT_ASSERT_INT_EQUALS(500, disp->max_rect.p1.y);
+
+	wnd->flags |= wndf_avoid;
+
+	/* Update maximize rectangle */
+	ds_display_update_max_rect(disp);
+
+	/* Verify maximize rectangle */
+	PCUT_ASSERT_INT_EQUALS(0, disp->max_rect.p0.x);
+	PCUT_ASSERT_INT_EQUALS(0, disp->max_rect.p0.y);
+	PCUT_ASSERT_INT_EQUALS(500, disp->max_rect.p1.x);
+	PCUT_ASSERT_INT_EQUALS(450, disp->max_rect.p1.y);
+
+	ds_window_destroy(wnd);
+	ds_client_destroy(client);
+	ds_seat_destroy(seat);
+	ds_display_destroy(disp);
+}
+
+/** Cropping maximization rectangle from the top */
+PCUT_TEST(display_crop_max_rect_top)
+{
+	gfx_rect_t arect;
+	gfx_rect_t mrect;
+
+	arect.p0.x = 10;
+	arect.p0.y = 20;
+	arect.p1.x = 30;
+	arect.p1.y = 5;
+
+	mrect.p0.x = 10;
+	mrect.p0.y = 20;
+	mrect.p1.x = 30;
+	mrect.p1.y = 40;
+
+	ds_display_crop_max_rect(&arect, &mrect);
+
+	PCUT_ASSERT_INT_EQUALS(10, mrect.p0.x);
+	PCUT_ASSERT_INT_EQUALS(5, mrect.p0.y);
+	PCUT_ASSERT_INT_EQUALS(30, mrect.p1.x);
+	PCUT_ASSERT_INT_EQUALS(40, mrect.p1.y);
+}
+
+/** Cropping maximization rectangle from the bottom */
+PCUT_TEST(display_crop_max_rect_bottom)
+{
+	gfx_rect_t arect;
+	gfx_rect_t mrect;
+
+	arect.p0.x = 10;
+	arect.p0.y = 35;
+	arect.p1.x = 30;
+	arect.p1.y = 40;
+
+	mrect.p0.x = 10;
+	mrect.p0.y = 20;
+	mrect.p1.x = 30;
+	mrect.p1.y = 40;
+
+	ds_display_crop_max_rect(&arect, &mrect);
+
+	PCUT_ASSERT_INT_EQUALS(10, mrect.p0.x);
+	PCUT_ASSERT_INT_EQUALS(20, mrect.p0.y);
+	PCUT_ASSERT_INT_EQUALS(30, mrect.p1.x);
+	PCUT_ASSERT_INT_EQUALS(35, mrect.p1.y);
+}
+
+/** Cropping maximization rectangle from the left */
+PCUT_TEST(display_crop_max_rect_left)
+{
+	gfx_rect_t arect;
+	gfx_rect_t mrect;
+
+	arect.p0.x = 10;
+	arect.p0.y = 20;
+	arect.p1.x = 15;
+	arect.p1.y = 40;
+
+	mrect.p0.x = 10;
+	mrect.p0.y = 20;
+	mrect.p1.x = 30;
+	mrect.p1.y = 40;
+
+	ds_display_crop_max_rect(&arect, &mrect);
+
+	PCUT_ASSERT_INT_EQUALS(15, mrect.p0.x);
+	PCUT_ASSERT_INT_EQUALS(20, mrect.p0.y);
+	PCUT_ASSERT_INT_EQUALS(30, mrect.p1.x);
+	PCUT_ASSERT_INT_EQUALS(40, mrect.p1.y);
+}
+
+/** Cropping maximization rectangle from the right */
+PCUT_TEST(display_crop_max_rect_right)
+{
+	gfx_rect_t arect;
+	gfx_rect_t mrect;
+
+	arect.p0.x = 25;
+	arect.p0.y = 20;
+	arect.p1.x = 30;
+	arect.p1.y = 40;
+
+	mrect.p0.x = 10;
+	mrect.p0.y = 20;
+	mrect.p1.x = 30;
+	mrect.p1.y = 40;
+
+	ds_display_crop_max_rect(&arect, &mrect);
+
+	PCUT_ASSERT_INT_EQUALS(10, mrect.p0.x);
+	PCUT_ASSERT_INT_EQUALS(20, mrect.p0.y);
+	PCUT_ASSERT_INT_EQUALS(25, mrect.p1.x);
+	PCUT_ASSERT_INT_EQUALS(40, mrect.p1.y);
+}
+
 PCUT_EXPORT(display);
Index: uspace/srv/hid/display/types/display/display.h
===================================================================
--- uspace/srv/hid/display/types/display/display.h	(revision 6e91475d2748dc57c8470404beb69fc18a2c93c5)
+++ uspace/srv/hid/display/types/display/display.h	(revision 29a5a9917c778c2ef39d5fcb7843fcf719c4409e)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2019 Jiri Svoboda
+ * Copyright (c) 2022 Jiri Svoboda
  * All rights reserved.
  *
@@ -97,4 +97,7 @@
 	gfx_rect_t rect;
 
+	/** Maximize rectangle */
+	gfx_rect_t max_rect;
+
 	/** Backbuffer bitmap or @c NULL if not double-buffering */
 	gfx_bitmap_t *backbuf;
Index: uspace/srv/hid/display/window.c
===================================================================
--- uspace/srv/hid/display/window.c	(revision 6e91475d2748dc57c8470404beb69fc18a2c93c5)
+++ uspace/srv/hid/display/window.c	(revision 29a5a9917c778c2ef39d5fcb7843fcf719c4409e)
@@ -150,4 +150,7 @@
 		ds_seat_set_focus(seat, wnd);
 
+	if ((params->flags & wndf_avoid) != 0)
+		ds_display_update_max_rect(wnd->display);
+
 	(void) ds_display_paint(wnd->display, NULL);
 
@@ -183,4 +186,7 @@
 	ds_display_remove_window(wnd);
 
+	if ((wnd->flags & wndf_avoid) != 0)
+		ds_display_update_max_rect(disp);
+
 	mem_gc_delete(wnd->mgc);
 
@@ -718,5 +724,5 @@
 void ds_window_get_max_rect(ds_window_t *wnd, gfx_rect_t *rect)
 {
-	*rect = wnd->display->rect;
+	*rect = wnd->display->max_rect;
 }
 
@@ -795,4 +801,7 @@
 	wnd->rect = *nrect;
 
+	if ((wnd->flags & wndf_avoid) != 0)
+		ds_display_update_max_rect(wnd->display);
+
 	(void) ds_display_paint(wnd->display, NULL);
 	return EOK;
