Index: uspace/lib/c/include/io/window.h
===================================================================
--- uspace/lib/c/include/io/window.h	(revision c4ebe025c2fab360da14b4704075168c94a51a2c)
+++ uspace/lib/c/include/io/window.h	(revision 290a0f0bca64b949d48d6b8a5d58988fc13ad577)
@@ -71,4 +71,6 @@
 	ET_POSITION_EVENT,
 	ET_SIGNAL_EVENT,
+	ET_WINDOW_FOCUS,
+	ET_WINDOW_UNFOCUS,
 	ET_WINDOW_RESIZE,
 	ET_WINDOW_REFRESH,
Index: uspace/lib/gui/window.c
===================================================================
--- uspace/lib/gui/window.c	(revision c4ebe025c2fab360da14b4704075168c94a51a2c)
+++ uspace/lib/gui/window.c	(revision 290a0f0bca64b949d48d6b8a5d58988fc13ad577)
@@ -66,6 +66,8 @@
 
 static pixel_t border_color = PIXEL(255, 0, 0, 0);
-static pixel_t header_bgcolor = PIXEL(255, 25, 25, 112);
-static pixel_t header_fgcolor = PIXEL(255, 255, 255, 255);
+static pixel_t header_bg_focus_color = PIXEL(255, 25, 25, 112);
+static pixel_t header_fg_focus_color = PIXEL(255, 255, 255, 255);
+static pixel_t header_bg_unfocus_color = PIXEL(255, 70, 130, 180);
+static pixel_t header_fg_unfocus_color = PIXEL(255, 255, 255, 255);
 
 static void paint_internal(widget_t *w)
@@ -94,5 +96,6 @@
 	    w->vpos + w->height - border_thickness, w->width, border_thickness);
 
-	source_set_color(&source, header_bgcolor);
+	source_set_color(&source, 
+	    w->window->is_focused ? header_bg_focus_color : header_bg_unfocus_color);
 	drawctx_transfer(&drawctx,
 	    w->hpos + border_thickness, w->vpos + border_thickness,
@@ -106,5 +109,6 @@
 	char cls_pict[] = "x";
 	font_get_box(&font, cls_pict, &cls_width, &cls_height);
-	source_set_color(&source, header_fgcolor);
+	source_set_color(&source, 
+	    w->window->is_focused ? header_fg_focus_color : header_fg_unfocus_color);
 	sysarg_t cls_x = ((close_width - cls_width) / 2) + w->hpos + w->width -
 	    border_thickness - close_width;
@@ -447,4 +451,8 @@
 			break;
 		case ET_POSITION_EVENT:
+			if (!win->is_focused) {
+				win->is_focused = true;
+				handle_refresh(win);
+			}
 			deliver_position_event(win, event->data.pos);
 			break;
@@ -454,4 +462,16 @@
 		case ET_WINDOW_RESIZE:
 			handle_resize(win, event->data.rsz.width, event->data.rsz.height);
+			break;
+		case ET_WINDOW_FOCUS:
+			if (!win->is_focused) {
+				win->is_focused = true;
+				handle_refresh(win);
+			}
+			break;
+		case ET_WINDOW_UNFOCUS:
+			if (win->is_focused) {
+				win->is_focused = false;
+				handle_refresh(win);
+			}
 			break;
 		case ET_WINDOW_REFRESH:
@@ -525,4 +545,5 @@
 	win->is_main = is_main;
 	win->is_decorated = is_decorated;
+	win->is_focused = true;
 	prodcons_initialize(&win->events);
 	fibril_mutex_initialize(&win->guard);
Index: uspace/lib/gui/window.h
===================================================================
--- uspace/lib/gui/window.h	(revision c4ebe025c2fab360da14b4704075168c94a51a2c)
+++ uspace/lib/gui/window.h	(revision 290a0f0bca64b949d48d6b8a5d58988fc13ad577)
@@ -50,4 +50,5 @@
 	bool is_main; /**< True for the main window of the application. */
 	bool is_decorated; /**< True if the window decorations should be rendered. */
+	bool is_focused; /**< True for the top level window of the desktop. */
 	char *caption; /**< Text title of the window header. */
 	async_sess_t *isess; /**< Input events from compositor. */
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision c4ebe025c2fab360da14b4704075168c94a51a2c)
+++ uspace/srv/hid/compositor/compositor.c	(revision 290a0f0bca64b949d48d6b8a5d58988fc13ad577)
@@ -573,5 +573,5 @@
 		pointer_t *pointer = list_get_instance(link, pointer_t, link);
 		if (pointer->id == pos_id) {
-			pointer->grab_flags = grab_flags;
+			pointer->grab_flags = pointer->pressed ? grab_flags : GF_EMPTY;
 			// TODO change pointer->state according to grab_flags
 			break;
@@ -646,4 +646,32 @@
 }
 
+static void comp_post_event_win(window_event_t *event, window_t *target)
+{
+	fibril_mutex_lock(&window_list_mtx);
+	window_t *window = NULL;
+	list_foreach(window_list, link) {
+		window = list_get_instance(link, window_t, link);
+		if (window == target) {
+			prodcons_produce(&window->queue, &event->link);
+		}
+	}
+	if (!window) {
+		free(event);
+	}
+	fibril_mutex_unlock(&window_list_mtx);
+}
+
+static void comp_post_event_top(window_event_t *event)
+{
+	fibril_mutex_lock(&window_list_mtx);
+	window_t *win = (window_t *) list_first(&window_list);
+	if (win) {
+		prodcons_produce(&win->queue, &event->link);
+	} else {
+		free(event);
+	}
+	fibril_mutex_unlock(&window_list_mtx);
+}
+
 static void comp_window_close(window_t *win, ipc_callid_t iid, ipc_call_t *icall)
 {
@@ -651,5 +679,15 @@
 	fibril_mutex_lock(&window_list_mtx);
 	list_remove(&win->link);
+	window_t *win_focus = (window_t *) list_first(&window_list);
+	window_event_t *event_focus = (window_event_t *) malloc(sizeof(window_event_t));
+	if (event_focus) {
+		link_initialize(&event_focus->link);
+		event_focus->type = ET_WINDOW_FOCUS;
+	}
 	fibril_mutex_unlock(&window_list_mtx);
+
+	if (event_focus && win_focus) {
+		comp_post_event_win(event_focus, win_focus);
+	}
 
 	/* Calculate damage. */
@@ -735,8 +773,20 @@
 			}
 
+			window_t *win_unfocus = (window_t *) list_first(&window_list);
 			list_prepend(&win->link, &window_list);
+
+			window_event_t *event_unfocus = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event_unfocus) {
+				link_initialize(&event_unfocus->link);
+				event_unfocus->type = ET_WINDOW_UNFOCUS;
+			}
 			
 			async_answer_2(callid, EOK, win->in_dsid, win->out_dsid);
 			fibril_mutex_unlock(&window_list_mtx);
+			
+			if (event_unfocus && win_unfocus) {
+				comp_post_event_win(event_unfocus, win_unfocus);
+			}
+
 			return;
 		} else {
@@ -1058,16 +1108,4 @@
 }
 
-static void comp_post_event(window_event_t *event)
-{
-	fibril_mutex_lock(&window_list_mtx);
-	window_t *win = (window_t *) list_first(&window_list);
-	if (win) {
-		prodcons_produce(&win->queue, &event->link);
-	} else {
-		free(event);
-	}
-	fibril_mutex_unlock(&window_list_mtx);
-}
-
 static void comp_recalc_transform(window_t *win)
 {
@@ -1102,4 +1140,5 @@
 {
 	/* window_list_mtx locked by caller */
+	/* pointer_list_mtx locked by caller */
 
 	int dx = pointer->accum.x;
@@ -1181,4 +1220,7 @@
     desktop_rect_t *rect1, desktop_rect_t *rect2, desktop_rect_t *rect3, desktop_rect_t *rect4)
 {
+	/* window_list_mtx locked by caller */
+	/* pointer_list_mtx locked by caller */
+
 	int dx = pointer->accum_ghost.x;
 	int dy = pointer->accum_ghost.y;
@@ -1336,4 +1378,5 @@
 
 	fibril_mutex_lock(&window_list_mtx);
+	fibril_mutex_lock(&pointer_list_mtx);
 	window_t *top = (window_t *) list_first(&window_list);
 	if (top && top->surface) {
@@ -1347,8 +1390,8 @@
 			within_client = comp_coord_to_client(pointer->pos.x, pointer->pos.y,
 			    top->transform, width, height, &point_x, &point_y);
-			fibril_mutex_unlock(&window_list_mtx);
-
+
+			window_event_t *event = NULL;
 			if (within_client) {
-				window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
+				event = (window_event_t *) malloc(sizeof(window_event_t));
 				if (event) {
 					link_initialize(&event->link);
@@ -1359,7 +1402,14 @@
 					event->data.pos.hpos = point_x;
 					event->data.pos.vpos = point_y;
-					comp_post_event(event);
 				}
 			}
+
+			fibril_mutex_unlock(&pointer_list_mtx);
+			fibril_mutex_unlock(&window_list_mtx);
+
+			if (event) {
+				comp_post_event_top(event);
+			}
+
 		} else {
 			/* Pointer is grabbed by top-level window action. */
@@ -1385,4 +1435,5 @@
 			comp_window_animate(pointer, top, &x, &y, &width, &height);
 #endif
+			fibril_mutex_unlock(&pointer_list_mtx);
 			fibril_mutex_unlock(&window_list_mtx);
 #if ANIMATE_WINDOW_TRANSFORMS == 0
@@ -1397,4 +1448,5 @@
 		}
 	} else {
+		fibril_mutex_unlock(&pointer_list_mtx);
 		fibril_mutex_unlock(&window_list_mtx);
 	}
@@ -1408,4 +1460,5 @@
 
 	fibril_mutex_lock(&window_list_mtx);
+	fibril_mutex_lock(&pointer_list_mtx);
 	window_t *win = NULL;
 	sysarg_t point_x = 0;
@@ -1430,9 +1483,12 @@
 	window_t *top = (window_t *) list_first(&window_list);
 	if (!win || !top) {
+		fibril_mutex_unlock(&pointer_list_mtx);
 		fibril_mutex_unlock(&window_list_mtx);
 		return EOK;
 	}
 
-	window_event_t *event = NULL;
+	window_event_t *event_top = NULL;
+	window_event_t *event_unfocus = NULL;
+	window_t *win_unfocus = NULL;
 	sysarg_t dmg_x, dmg_y;
 	sysarg_t dmg_width = 0;
@@ -1450,6 +1506,12 @@
 		/* Bring the window to the foreground. */
 		if ((win != top) && within_client) {
+			win_unfocus = (window_t *) list_first(&window_list);
 			list_remove(&win->link);
 			list_prepend(&win->link, &window_list);
+			event_unfocus = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event_unfocus) {
+				link_initialize(&event_unfocus->link);
+				event_unfocus->type = ET_WINDOW_UNFOCUS;
+			}
 			comp_coord_bounding_rect(0, 0, width, height, win->transform,
 			    &dmg_x, &dmg_y, &dmg_width, &dmg_height);
@@ -1458,13 +1520,13 @@
 		/* Notify top-level window about mouse press. */
 		if (within_client) {
-			event = (window_event_t *) malloc(sizeof(window_event_t));
-			if (event) {
-				link_initialize(&event->link);
-				event->type = ET_POSITION_EVENT;
-				event->data.pos.pos_id = pointer->id;
-				event->data.pos.type = POS_PRESS;
-				event->data.pos.btn_num = bnum;
-				event->data.pos.hpos = point_x;
-				event->data.pos.vpos = point_y;
+			event_top = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event_top) {
+				link_initialize(&event_top->link);
+				event_top->type = ET_POSITION_EVENT;
+				event_top->data.pos.pos_id = pointer->id;
+				event_top->data.pos.type = POS_PRESS;
+				event_top->data.pos.btn_num = bnum;
+				event_top->data.pos.hpos = point_x;
+				event_top->data.pos.vpos = point_y;
 			}
 			pointer->grab_flags = GF_EMPTY;
@@ -1501,8 +1563,8 @@
 
 			/* Commit proper resize action. */
-			event = (window_event_t *) malloc(sizeof(window_event_t));
-			if (event) {
-				link_initialize(&event->link);
-				event->type = ET_WINDOW_RESIZE;
+			event_top = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event_top) {
+				link_initialize(&event_top->link);
+				event_top->type = ET_WINDOW_RESIZE;
 
 				int dx = (int) (((double) width) * (scale_back_x - 1.0));
@@ -1510,15 +1572,15 @@
 
 				if (pointer->grab_flags & GF_RESIZE_X) {
-					event->data.rsz.width =
+					event_top->data.rsz.width =
 						((((int) width) + dx) >= 0) ? (width + dx) : 0;
 				} else {
-					event->data.rsz.width = width;
+					event_top->data.rsz.width = width;
 				}
 
 				if (pointer->grab_flags & GF_RESIZE_Y) {
-					event->data.rsz.height =
+					event_top->data.rsz.height =
 						((((int) height) + dy) >= 0) ? (height + dy) : 0;
 				} else {
-					event->data.rsz.height = height;
+					event_top->data.rsz.height = height;
 				}
 			}
@@ -1529,13 +1591,13 @@
 			
 			/* Notify top-level window about mouse release. */
-			event = (window_event_t *) malloc(sizeof(window_event_t));
-			if (event) {
-				link_initialize(&event->link);
-				event->type = ET_POSITION_EVENT;
-				event->data.pos.pos_id = pointer->id;
-				event->data.pos.type = POS_RELEASE;
-				event->data.pos.btn_num = bnum;
-				event->data.pos.hpos = point_x;
-				event->data.pos.vpos = point_y;
+			event_top = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event_top) {
+				link_initialize(&event_top->link);
+				event_top->type = ET_POSITION_EVENT;
+				event_top->data.pos.pos_id = pointer->id;
+				event_top->data.pos.type = POS_RELEASE;
+				event_top->data.pos.btn_num = bnum;
+				event_top->data.pos.hpos = point_x;
+				event_top->data.pos.vpos = point_y;
 			}
 			pointer->grab_flags = GF_EMPTY;
@@ -1547,4 +1609,5 @@
 	}
 
+	fibril_mutex_unlock(&pointer_list_mtx);
 	fibril_mutex_unlock(&window_list_mtx);
 
@@ -1560,6 +1623,10 @@
 	}
 
-	if (event) {
-		comp_post_event(event);
+	if (event_unfocus && win_unfocus) {
+		comp_post_event_win(event_unfocus, win_unfocus);
+	}
+
+	if (event_top) {
+		comp_post_event_top(event_top);
 	}
 
@@ -1685,5 +1752,5 @@
 
 			fibril_mutex_unlock(&window_list_mtx);
-			comp_post_event(event);
+			comp_post_event_top(event);
 		} else {
 			fibril_mutex_unlock(&window_list_mtx);
@@ -1727,5 +1794,5 @@
 		event->type = ET_WINDOW_CLOSE;
 
-		comp_post_event(event);
+		comp_post_event_top(event);
 	} else if (win_switch) {
 		fibril_mutex_lock(&window_list_mtx);
@@ -1735,4 +1802,16 @@
 			list_append(&win1->link, &window_list);
 			window_t *win2 = (window_t *) list_first(&window_list);
+
+			window_event_t *event1 = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event1) {
+				link_initialize(&event1->link);
+				event1->type = ET_WINDOW_UNFOCUS;
+			}
+
+			window_event_t *event2 = (window_event_t *) malloc(sizeof(window_event_t));
+			if (event2) {
+				link_initialize(&event2->link);
+				event2->type = ET_WINDOW_FOCUS;
+			}
 
 			sysarg_t x1 = 0;
@@ -1763,4 +1842,13 @@
 
 			fibril_mutex_unlock(&window_list_mtx);
+
+			if (event1 && win1) {
+				comp_post_event_win(event1, win1);
+			}
+
+			if (event2 && win2) {
+				comp_post_event_win(event2, win2);
+			}
+
 			comp_damage(x, y, width, height);
 		} else {
@@ -1875,5 +1963,5 @@
 		event->data.kbd.c = c;
 
-		comp_post_event(event);
+		comp_post_event_top(event);
 	}
 
@@ -1926,5 +2014,5 @@
 static void input_disconnect(void)
 {
-    	pointer_t *pointer = input->user;
+	pointer_t *pointer = input->user;
 	input_close(input);
 	pointer_destroy(pointer);
