Index: uspace/app/taskbar/test/wndlist.c
===================================================================
--- uspace/app/taskbar/test/wndlist.c	(revision 6e91475d2748dc57c8470404beb69fc18a2c93c5)
+++ uspace/app/taskbar/test/wndlist.c	(revision 68d68e9763bdb1e3051435500a9dc659c164070d)
@@ -407,4 +407,52 @@
 }
 
+/** Test wndlist_count() */
+PCUT_TEST(count)
+{
+	errno_t rc;
+	ui_t *ui = NULL;
+	ui_wnd_params_t params;
+	ui_window_t *window = NULL;
+	ui_fixed_t *fixed = NULL;
+	wndlist_t *wndlist;
+	size_t count;
+
+	rc = ui_create_disp(NULL, &ui);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	ui_wnd_params_init(&params);
+	params.caption = "Hello";
+
+	rc = ui_window_create(ui, &params, &window);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_NOT_NULL(window);
+
+	rc = ui_fixed_create(&fixed);
+	ui_window_add(window, ui_fixed_ctl(fixed));
+
+	rc = wndlist_create(window, fixed, &wndlist);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	count = wndlist_count(wndlist);
+	PCUT_ASSERT_INT_EQUALS(0, count);
+
+	rc = wndlist_append(wndlist, 1, "Foo", true);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	count = wndlist_count(wndlist);
+	PCUT_ASSERT_INT_EQUALS(1, count);
+
+	rc = wndlist_append(wndlist, 2, "Bar", true);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	count = wndlist_count(wndlist);
+	PCUT_ASSERT_INT_EQUALS(2, count);
+
+	wndlist_destroy(wndlist);
+
+	ui_window_destroy(window);
+	ui_destroy(ui);
+}
+
 /** Test repainting window list */
 PCUT_TEST(repaint)
Index: uspace/app/taskbar/wndlist.c
===================================================================
--- uspace/app/taskbar/wndlist.c	(revision 6e91475d2748dc57c8470404beb69fc18a2c93c5)
+++ uspace/app/taskbar/wndlist.c	(revision 68d68e9763bdb1e3051435500a9dc659c164070d)
@@ -35,4 +35,5 @@
 #include <gfx/coord.h>
 #include <stdbool.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -65,8 +66,12 @@
 
 enum {
-	/** X distance between left edges of two consecutive buttons */
-	wndlist_button_pitch = 145,
-	/** X distance between left edges of two consecutive buttons (text) */
-	wndlist_button_pitch_text = 17,
+	/** Min. X distance between left edges of two consecutive buttons */
+	wndlist_button_pitch_min = 85,
+	/** Max. X distance between left edges of two consecutive buttons (text) */
+	wndlist_button_pitch_min_text = 10,
+	/** Min. X distance between left edges of two consecutive buttons */
+	wndlist_button_pitch_max = 165,
+	/** Max. X distance between left edges of two consecutive buttons (text) */
+	wndlist_button_pitch_max_text = 17,
 	/** Padding between buttons */
 	wndlist_button_pad = 5,
@@ -197,4 +202,5 @@
 	wndlist_entry_t *entry = NULL;
 	ui_resource_t *res;
+	wndlist_entry_t *e;
 	errno_t rc;
 
@@ -217,15 +223,19 @@
 	entry->visible = false;
 
-	/* Set the button rectangle and add it to layout, if applicable */
-	wndlist_set_entry_rect(wndlist, entry);
+	/*
+	 * Update rectangles for all entries, including @a entry, adding
+	 * it to the layout, if applicable.
+	 */
+	e = wndlist_first(wndlist);
+	while (e != NULL) {
+		wndlist_set_entry_rect(wndlist, e);
+		e = wndlist_next(e);
+	}
 
 	/* Set button callbacks */
 	ui_pbutton_set_cb(entry->button, &wndlist_button_cb, (void *)entry);
 
-	if (paint && entry->visible) {
-		rc = ui_pbutton_paint(entry->button);
-		if (rc != EOK)
-			goto error;
-	}
+	if (paint)
+		return wndlist_repaint(wndlist);
 
 	return EOK;
@@ -249,18 +259,18 @@
     bool paint)
 {
-	wndlist_entry_t *next;
+	wndlist_entry_t *e;
 	assert(entry->wndlist == wndlist);
 
-	next = wndlist_next(entry);
-
-	ui_fixed_remove(wndlist->fixed, ui_pbutton_ctl(entry->button));
+	if (entry->visible)
+		ui_fixed_remove(wndlist->fixed, ui_pbutton_ctl(entry->button));
 	ui_pbutton_destroy(entry->button);
 	list_remove(&entry->lentries);
 	free(entry);
 
-	/* Update positions of the remaining entries */
-	while (next != NULL) {
-		wndlist_set_entry_rect(wndlist, next);
-		next = wndlist_next(next);
+	/* Update positions of the all entries */
+	e = wndlist_first(wndlist);
+	while (e != NULL) {
+		wndlist_set_entry_rect(wndlist, e);
+		e = wndlist_next(e);
 	}
 
@@ -307,6 +317,9 @@
 	ui_resource_t *res;
 	gfx_coord_t pitch;
+	gfx_coord_t pitch_max;
+	gfx_coord_t pitch_min;
 	gfx_coord_t pad;
 	size_t idx;
+	size_t nbuttons;
 
 	/* Determine entry index */
@@ -322,10 +335,20 @@
 
 	if (ui_resource_is_textmode(res)) {
-		pitch = wndlist_button_pitch_text;
+		pitch_max = wndlist_button_pitch_max_text;
+		pitch_min = wndlist_button_pitch_min_text;
 		pad = wndlist_button_pad_text;
 	} else {
-		pitch = wndlist_button_pitch;
+		pitch_max = wndlist_button_pitch_max;
+		pitch_min = wndlist_button_pitch_min;
 		pad = wndlist_button_pad;
 	}
+
+	/* Compute pitch that fits all buttons perfectly */
+	nbuttons = wndlist_count(wndlist);
+	pitch = (wndlist->rect.p1.x - wndlist->rect.p0.x + pad) / nbuttons;
+	if (pitch < pitch_min)
+		pitch = pitch_min;
+	if (pitch > pitch_max)
+		pitch = pitch_max;
 
 	rect.p0.x = wndlist->rect.p0.x + pitch * idx;
@@ -478,4 +501,14 @@
 }
 
+/** Get number of window list entries.
+ *
+ * @param wndlist Window list
+ * @return Number of entries
+ */
+size_t wndlist_count(wndlist_t *wndlist)
+{
+	return list_count(&wndlist->entries);
+}
+
 /** Repaint window list.
  *
Index: uspace/app/taskbar/wndlist.h
===================================================================
--- uspace/app/taskbar/wndlist.h	(revision 6e91475d2748dc57c8470404beb69fc18a2c93c5)
+++ uspace/app/taskbar/wndlist.h	(revision 68d68e9763bdb1e3051435500a9dc659c164070d)
@@ -40,4 +40,5 @@
 #include <gfx/coord.h>
 #include <stdbool.h>
+#include <stddef.h>
 #include <ui/fixed.h>
 #include <ui/window.h>
@@ -56,4 +57,5 @@
 extern wndlist_entry_t *wndlist_first(wndlist_t *);
 extern wndlist_entry_t *wndlist_next(wndlist_entry_t *);
+extern size_t wndlist_count(wndlist_t *);
 extern errno_t wndlist_repaint(wndlist_t *);
 
Index: uspace/lib/ui/src/pbutton.c
===================================================================
--- uspace/lib/ui/src/pbutton.c	(revision 6e91475d2748dc57c8470404beb69fc18a2c93c5)
+++ uspace/lib/ui/src/pbutton.c	(revision 68d68e9763bdb1e3051435500a9dc659c164070d)
@@ -54,5 +54,7 @@
 enum {
 	ui_pb_press_dx = 1,
-	ui_pb_press_dy = 1
+	ui_pb_press_dy = 1,
+	ui_pb_pad_x = 2,
+	ui_pb_pad_x_text = 1
 };
 
@@ -323,4 +325,5 @@
 	gfx_text_fmt_t fmt;
 	gfx_rect_t rect;
+	gfx_rect_t irect;
 	gfx_coord_t thickness;
 	bool depressed;
@@ -360,4 +363,5 @@
 	} else {
 		/* Text decoration */
+		ui_paint_get_inset_frame_inside(pbutton->res, &rect, &irect);
 		gfx_text_fmt_init(&fmt);
 		fmt.font = pbutton->res->font;
@@ -365,4 +369,6 @@
 		fmt.halign = gfx_halign_center;
 		fmt.valign = gfx_valign_center;
+		fmt.abbreviate = true;
+		fmt.width = irect.p1.x - irect.p0.x - 2 * ui_pb_pad_x;
 
 		rc = gfx_puttext(&pos, &fmt, pbutton->caption);
@@ -442,4 +448,6 @@
 	fmt.halign = gfx_halign_center;
 	fmt.valign = gfx_valign_center;
+	fmt.abbreviate = true;
+	fmt.width = rect.p1.x - rect.p0.x - 2 * ui_pb_pad_x_text;
 
 	rc = gfx_puttext(&pos, &fmt, pbutton->caption);
