Index: uspace/app/taskbar/taskbar.c
===================================================================
--- uspace/app/taskbar/taskbar.c	(revision 913add60dd2ff444e319a0f402067877d08cb574)
+++ uspace/app/taskbar/taskbar.c	(revision 1b92d4b53fe9235e85d98684285dfaa75b944c07)
@@ -53,12 +53,4 @@
 };
 
-static void taskbar_wm_window_added(void *, sysarg_t);
-static void taskbar_wm_window_removed(void *, sysarg_t);
-
-static wndmgt_cb_t taskbar_wndmgt_cb = {
-	.window_added = taskbar_wm_window_added,
-	.window_removed = taskbar_wm_window_removed
-};
-
 /** Window close button was clicked.
  *
@@ -96,11 +88,4 @@
 	}
 
-	if (wndmgt_svc != NULL) {
-		rc = wndmgt_open(wndmgt_svc, &taskbar_wndmgt_cb,
-		    (void *)taskbar, &taskbar->wndmgt);
-		if (rc != EOK)
-			goto error;
-	}
-
 	rc = ui_create(display_spec, &taskbar->ui);
 	if (rc != EOK) {
@@ -177,5 +162,5 @@
 	}
 
-	rc = wndlist_create(ui_res, taskbar->fixed, &taskbar->wndlist);
+	rc = wndlist_create(taskbar->window, taskbar->fixed, &taskbar->wndlist);
 	if (rc != EOK) {
 		printf("Error creating window list.\n");
@@ -183,5 +168,5 @@
 	}
 
-	rc = wndlist_attach_wm(taskbar->wndlist, taskbar->wndmgt);
+	rc = wndlist_open_wm(taskbar->wndlist, wndmgt_svc);
 	if (rc != EOK) {
 		printf("Error attaching window management service.\n");
@@ -233,6 +218,4 @@
 	if (taskbar->ui != NULL)
 		ui_destroy(taskbar->ui);
-	if (taskbar->wndmgt != NULL)
-		wndmgt_close(taskbar->wndmgt);
 	return rc;
 
@@ -246,34 +229,6 @@
 	ui_window_destroy(taskbar->window);
 	ui_destroy(taskbar->ui);
-	if (taskbar->wndmgt != NULL)
-		wndmgt_close(taskbar->wndmgt);
 }
 
-/** Handle WM window added event.
- *
- * @param arg Argument (taskbar_t *)
- * @param wnd_id Window ID
- */
-static void taskbar_wm_window_added(void *arg, sysarg_t wnd_id)
-{
-	taskbar_t *taskbar = (taskbar_t *)arg;
-
-	printf("wm_window_added: taskbar=%p wnd_id=%zu\n",
-	    (void *)taskbar, wnd_id);
-}
-
-/** Handle WM window removed event.
- *
- * @param arg Argument (taskbar_t *)
- * @param wnd_id Window ID
- */
-static void taskbar_wm_window_removed(void *arg, sysarg_t wnd_id)
-{
-	taskbar_t *taskbar = (taskbar_t *)arg;
-
-	printf("wm_window_removed: taskbar=%p wnd_id=%zu\n",
-	    (void *)taskbar, wnd_id);
-}
-
 /** @}
  */
Index: uspace/app/taskbar/test/wndlist.c
===================================================================
--- uspace/app/taskbar/test/wndlist.c	(revision 913add60dd2ff444e319a0f402067877d08cb574)
+++ uspace/app/taskbar/test/wndlist.c	(revision 1b92d4b53fe9235e85d98684285dfaa75b944c07)
@@ -46,5 +46,4 @@
 	ui_window_t *window = NULL;
 	ui_fixed_t *fixed = NULL;
-	ui_resource_t *res;
 	wndlist_t *wndlist;
 
@@ -59,11 +58,8 @@
 	PCUT_ASSERT_NOT_NULL(window);
 
-	res = ui_window_get_res(window);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
 	rc = ui_fixed_create(&fixed);
 	ui_window_add(window, ui_fixed_ctl(fixed));
 
-	rc = wndlist_create(res, fixed, &wndlist);
+	rc = wndlist_create(window, fixed, &wndlist);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
Index: uspace/app/taskbar/types/taskbar.h
===================================================================
--- uspace/app/taskbar/types/taskbar.h	(revision 913add60dd2ff444e319a0f402067877d08cb574)
+++ uspace/app/taskbar/types/taskbar.h	(revision 1b92d4b53fe9235e85d98684285dfaa75b944c07)
@@ -57,6 +57,4 @@
 	/** Clock */
 	taskbar_clock_t *clock;
-	/** Window management service */
-	wndmgt_t *wndmgt;
 } taskbar_t;
 
Index: uspace/app/taskbar/types/wndlist.h
===================================================================
--- uspace/app/taskbar/types/wndlist.h	(revision 913add60dd2ff444e319a0f402067877d08cb574)
+++ uspace/app/taskbar/types/wndlist.h	(revision 1b92d4b53fe9235e85d98684285dfaa75b944c07)
@@ -41,5 +41,5 @@
 #include <ui/pbutton.h>
 #include <ui/fixed.h>
-#include <ui/resource.h>
+#include <ui/window.h>
 #include <wndmgt.h>
 
@@ -50,4 +50,6 @@
 	/** Link to wndlist->entries */
 	link_t lentries;
+	/** Window ID */
+	sysarg_t wnd_id;
 	/** Window button */
 	ui_pbutton_t *button;
@@ -59,6 +61,6 @@
 	struct ui_control *control;
 
-	/** UI resource */
-	ui_resource_t *res;
+	/** Containing window */
+	ui_window_t *window;
 
 	/** Layout to which we add window buttoons */
Index: uspace/app/taskbar/wndlist.c
===================================================================
--- uspace/app/taskbar/wndlist.c	(revision 913add60dd2ff444e319a0f402067877d08cb574)
+++ uspace/app/taskbar/wndlist.c	(revision 1b92d4b53fe9235e85d98684285dfaa75b944c07)
@@ -34,4 +34,5 @@
 
 #include <gfx/coord.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -45,7 +46,15 @@
 #include "wndlist.h"
 
+static void wndlist_wm_window_added(void *, sysarg_t);
+static void wndlist_wm_window_removed(void *, sysarg_t);
+
+static wndmgt_cb_t wndlist_wndmgt_cb = {
+	.window_added = wndlist_wm_window_added,
+	.window_removed = wndlist_wm_window_removed
+};
+
 /** Create task bar window list.
  *
- * @param res UI resource
+ * @param window Containing window
  * @param fixed Fixed layout to which buttons will be added
  * @param wndmgt Window management service
@@ -53,5 +62,5 @@
  * @return @c EOK on success or an error code
  */
-errno_t wndlist_create(ui_resource_t *res, ui_fixed_t *fixed,
+errno_t wndlist_create(ui_window_t *window, ui_fixed_t *fixed,
     wndlist_t **rwndlist)
 {
@@ -65,5 +74,5 @@
 	}
 
-	wndlist->res = res;
+	wndlist->window = window;
 	wndlist->fixed = fixed;
 	list_initialize(&wndlist->entries);
@@ -77,8 +86,8 @@
  *
  * @param wndlist Window list
- * @param rwndlist Place to store pointer to new window list
- * @return @c EOK on success or an error code
- */
-errno_t wndlist_attach_wm(wndlist_t *wndlist, wndmgt_t *wndmgt)
+ * @param wndmgt_svc Window management service name
+ * @return @c EOK on success or an error code
+ */
+errno_t wndlist_open_wm(wndlist_t *wndlist, const char *wndmgt_svc)
 {
 	errno_t rc;
@@ -87,15 +96,21 @@
 	sysarg_t i;
 
-	rc = wndmgt_get_window_list(wndmgt, &wlist);
+	rc = wndmgt_open(wndmgt_svc, &wndlist_wndmgt_cb, (void *)wndlist,
+	    &wndlist->wndmgt);
+	if (rc != EOK)
+		goto error;
+
+	rc = wndmgt_get_window_list(wndlist->wndmgt, &wlist);
 	if (rc != EOK)
 		goto error;
 
 	for (i = 0; i < wlist->nwindows; i++) {
-		rc = wndmgt_get_window_info(wndmgt, wlist->windows[i],
+		rc = wndmgt_get_window_info(wndlist->wndmgt, wlist->windows[i],
 		    &winfo);
 		if (rc != EOK)
 			goto error;
 
-		rc = wndlist_append(wndlist, winfo->caption);
+		rc = wndlist_append(wndlist, wlist->windows[i], winfo->caption,
+		    false);
 		if (rc != EOK) {
 			wndmgt_free_window_info(winfo);
@@ -106,9 +121,12 @@
 	}
 
-	wndlist->wndmgt = wndmgt;
 	return EOK;
 error:
 	if (wlist != NULL)
 		wndmgt_free_window_list(wlist);
+	if (wndlist->wndmgt != NULL) {
+		wndmgt_close(wndlist->wndmgt);
+		wndlist->wndmgt = NULL;
+	}
 	return rc;
 }
@@ -117,4 +135,17 @@
 void wndlist_destroy(wndlist_t *wndlist)
 {
+	wndlist_entry_t *entry;
+
+	/* Close window management service */
+	if (wndlist->wndmgt)
+		wndmgt_close(wndlist->wndmgt);
+
+	/* Destroy entries */
+	entry = wndlist_first(wndlist);
+	while (entry != NULL) {
+		(void)wndlist_remove(wndlist, entry, false);
+		entry = wndlist_first(wndlist);
+	}
+
 	free(wndlist);
 }
@@ -123,16 +154,15 @@
  *
  * @param wndlist Window list
+ * @param wnd_id Window ID
  * @param caption Entry caption
- * @return @c EOK on success or an error code
- */
-errno_t wndlist_append(wndlist_t *wndlist, const char *caption)
+ * @param paint @c true to paint immediately
+ * @return @c EOK on success or an error code
+ */
+errno_t wndlist_append(wndlist_t *wndlist, sysarg_t wnd_id,
+    const char *caption, bool paint)
 {
 	wndlist_entry_t *entry = NULL;
-	gfx_rect_t rect;
-	size_t nentries;
+	ui_resource_t *res;
 	errno_t rc;
-
-	/* Number of existing entries */
-	nentries = list_count(&wndlist->entries);
 
 	entry = calloc(1, sizeof(wndlist_entry_t));
@@ -142,23 +172,8 @@
 	}
 
-	rc = ui_pbutton_create(wndlist->res, caption, &entry->button);
-	if (rc != EOK)
-		goto error;
-
-	if (ui_resource_is_textmode(wndlist->res)) {
-		rect.p0.x = 17 * nentries + 9;
-		rect.p0.y = 0;
-		rect.p1.x = 17 * nentries + 25;
-		rect.p1.y = 1;
-	} else {
-		rect.p0.x = 145 * nentries + 90;
-		rect.p0.y = 3;
-		rect.p1.x = 145 * nentries + 230;
-		rect.p1.y = 29;
-	}
-
-	ui_pbutton_set_rect(entry->button, &rect);
-
-	rc = ui_fixed_add(wndlist->fixed, ui_pbutton_ctl(entry->button));
+	entry->wnd_id = wnd_id;
+	res = ui_window_get_res(wndlist->window);
+
+	rc = ui_pbutton_create(res, caption, &entry->button);
 	if (rc != EOK)
 		goto error;
@@ -166,4 +181,17 @@
 	entry->wndlist = wndlist;
 	list_append(&entry->lentries, &wndlist->entries);
+
+	/* Set the button rectangle */
+	wndlist_set_entry_rect(wndlist, entry);
+
+	rc = ui_fixed_add(wndlist->fixed, ui_pbutton_ctl(entry->button));
+	if (rc != EOK)
+		goto error;
+
+	if (paint) {
+		rc = ui_pbutton_paint(entry->button);
+		if (rc != EOK)
+			goto error;
+	}
 
 	return EOK;
@@ -177,4 +205,187 @@
 }
 
+/** Remove entry from window list.
+ *
+ * @param wndlist Window list
+ * @param entry Window list entry
+ * @param paint @c true to repaint window list
+ * @return @c EOK on success or an error code
+ */
+errno_t wndlist_remove(wndlist_t *wndlist, wndlist_entry_t *entry,
+    bool paint)
+{
+	wndlist_entry_t *next;
+	assert(entry->wndlist == wndlist);
+
+	next = wndlist_next(entry);
+
+	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);
+	}
+
+	if (!paint)
+		return EOK;
+
+	return wndlist_repaint(wndlist);
+}
+
+/** Compute and set window list entry rectangle.
+ *
+ * Compute rectangle for window list entry and set it.
+ *
+ * @param wndlist Window list
+ * @param entry Window list entry
+ */
+void wndlist_set_entry_rect(wndlist_t *wndlist, wndlist_entry_t *entry)
+{
+	wndlist_entry_t *e;
+	gfx_rect_t rect;
+	ui_resource_t *res;
+	size_t idx;
+
+	/* Determine entry index */
+	idx = 0;
+	e = wndlist_first(wndlist);
+	while (e != entry) {
+		assert(e != NULL);
+		e = wndlist_next(e);
+		++idx;
+	}
+
+	res = ui_window_get_res(wndlist->window);
+
+	if (ui_resource_is_textmode(res)) {
+		rect.p0.x = 17 * idx + 9;
+		rect.p0.y = 0;
+		rect.p1.x = 17 * idx + 25;
+		rect.p1.y = 1;
+	} else {
+		rect.p0.x = 145 * idx + 90;
+		rect.p0.y = 3;
+		rect.p1.x = 145 * idx + 230;
+		rect.p1.y = 29;
+	}
+
+	ui_pbutton_set_rect(entry->button, &rect);
+}
+
+/** Handle WM window added event.
+ *
+ * @param arg Argument (wndlist_t *)
+ * @param wnd_id Window ID
+ */
+static void wndlist_wm_window_added(void *arg, sysarg_t wnd_id)
+{
+	wndlist_t *wndlist = (wndlist_t *)arg;
+	wndmgt_window_info_t *winfo = NULL;
+	errno_t rc;
+
+	rc = wndmgt_get_window_info(wndlist->wndmgt, wnd_id, &winfo);
+	if (rc != EOK)
+		goto error;
+
+	rc = wndlist_append(wndlist, wnd_id, winfo->caption, true);
+	if (rc != EOK) {
+		wndmgt_free_window_info(winfo);
+		goto error;
+	}
+
+	wndmgt_free_window_info(winfo);
+	return;
+error:
+	if (winfo != NULL)
+		wndmgt_free_window_info(winfo);
+}
+
+/** Handle WM window removed event.
+ *
+ * @param arg Argument (wndlist_t *)
+ * @param wnd_id Window ID
+ */
+static void wndlist_wm_window_removed(void *arg, sysarg_t wnd_id)
+{
+	wndlist_t *wndlist = (wndlist_t *)arg;
+	wndlist_entry_t *entry;
+
+	printf("wm_window_removed: wndlist=%p wnd_id=%zu\n",
+	    (void *)wndlist, wnd_id);
+
+	entry = wndlist_entry_by_id(wndlist, wnd_id);
+	if (entry == NULL)
+		return;
+
+	(void) wndlist_remove(wndlist, entry, true);
+}
+
+/** Find window list entry by ID.
+ *
+ * @param wndlist Window list
+ * @param wnd_id Window ID
+ * @return Window list entry on success or @c NULL if not found
+ */
+wndlist_entry_t *wndlist_entry_by_id(wndlist_t *wndlist, sysarg_t wnd_id)
+{
+	wndlist_entry_t *entry;
+
+	entry = wndlist_first(wndlist);
+	while (entry != NULL) {
+		if (entry->wnd_id == wnd_id)
+			return entry;
+
+		entry = wndlist_next(entry);
+	}
+
+	return NULL;
+}
+
+/** Get first window list entry.
+ *
+ * @param wndlist Window list
+ * @return First entry or @c NULL if the list is empty
+ */
+wndlist_entry_t *wndlist_first(wndlist_t *wndlist)
+{
+	link_t *link;
+
+	link = list_first(&wndlist->entries);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, wndlist_entry_t, lentries);
+}
+
+/** Get next window list entry.
+ *
+ * @param cur Current entry
+ * @return Next entry or @c NULL if @a cur is the last entry
+ */
+wndlist_entry_t *wndlist_next(wndlist_entry_t *cur)
+{
+	link_t *link;
+
+	link = list_next(&cur->lentries, &cur->wndlist->entries);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, wndlist_entry_t, lentries);
+}
+
+/** Repaint window list.
+ *
+ * @param wndlist Window list
+ * @return @c EOK on success or an error code
+ */
+errno_t wndlist_repaint(wndlist_t *wndlist)
+{
+	return ui_window_paint(wndlist->window);
+}
+
 /** @}
  */
Index: uspace/app/taskbar/wndlist.h
===================================================================
--- uspace/app/taskbar/wndlist.h	(revision 913add60dd2ff444e319a0f402067877d08cb574)
+++ uspace/app/taskbar/wndlist.h	(revision 1b92d4b53fe9235e85d98684285dfaa75b944c07)
@@ -38,13 +38,20 @@
 
 #include <errno.h>
+#include <stdbool.h>
 #include <ui/fixed.h>
-#include <ui/resource.h>
+#include <ui/window.h>
 #include <wndmgt.h>
 #include "types/wndlist.h"
 
-extern errno_t wndlist_create(ui_resource_t *, ui_fixed_t *, wndlist_t **);
-extern errno_t wndlist_attach_wm(wndlist_t *, wndmgt_t *);
+extern errno_t wndlist_create(ui_window_t *, ui_fixed_t *, wndlist_t **);
+extern errno_t wndlist_open_wm(wndlist_t *, const char *);
 extern void wndlist_destroy(wndlist_t *);
-extern errno_t wndlist_append(wndlist_t *, const char *);
+extern errno_t wndlist_append(wndlist_t *, sysarg_t, const char *, bool);
+extern errno_t wndlist_remove(wndlist_t *, wndlist_entry_t *, bool);
+extern void wndlist_set_entry_rect(wndlist_t *, wndlist_entry_t *);
+extern wndlist_entry_t *wndlist_entry_by_id(wndlist_t *, sysarg_t);
+extern wndlist_entry_t *wndlist_first(wndlist_t *);
+extern wndlist_entry_t *wndlist_next(wndlist_entry_t *);
+extern errno_t wndlist_repaint(wndlist_t *);
 
 #endif
