Index: uspace/srv/hid/display/client.c
===================================================================
--- uspace/srv/hid/display/client.c	(revision e1f2079eea6e0ce553d66ced5b7ca0b64e0b4929)
+++ uspace/srv/hid/display/client.c	(revision b0a94854e61e0da77ab38167f0510ca1ae7cd70a)
@@ -203,4 +203,31 @@
 }
 
+/** Post focus event to the client's message queue.
+ *
+ * @param client Client
+ * @param ewindow Window that the message is targetted to
+ *
+ * @return EOK on success or an error code
+ */
+errno_t ds_client_post_focus_event(ds_client_t *client, ds_window_t *ewindow)
+{
+	ds_window_ev_t *wevent;
+
+	wevent = calloc(1, sizeof(ds_window_ev_t));
+	if (wevent == NULL)
+		return ENOMEM;
+
+	wevent->window = ewindow;
+	wevent->event.etype = wev_focus;
+	list_append(&wevent->levents, &client->events);
+
+	/* Notify the client */
+	// TODO Do not send more than once until client drains the queue
+	if (client->cb != NULL && client->cb->ev_pending != NULL)
+		client->cb->ev_pending(client->cb_arg);
+
+	return EOK;
+}
+
 /** Post keyboard event to the client's message queue.
  *
@@ -262,4 +289,31 @@
 }
 
+/** Post unfocus event to the client's message queue.
+ *
+ * @param client Client
+ * @param ewindow Window that the message is targetted to
+ *
+ * @return EOK on success or an error code
+ */
+errno_t ds_client_post_unfocus_event(ds_client_t *client, ds_window_t *ewindow)
+{
+	ds_window_ev_t *wevent;
+
+	wevent = calloc(1, sizeof(ds_window_ev_t));
+	if (wevent == NULL)
+		return ENOMEM;
+
+	wevent->window = ewindow;
+	wevent->event.etype = wev_unfocus;
+	list_append(&wevent->levents, &client->events);
+
+	/* Notify the client */
+	// TODO Do not send more than once until client drains the queue
+	if (client->cb != NULL && client->cb->ev_pending != NULL)
+		client->cb->ev_pending(client->cb_arg);
+
+	return EOK;
+}
+
 /** @}
  */
Index: uspace/srv/hid/display/client.h
===================================================================
--- uspace/srv/hid/display/client.h	(revision e1f2079eea6e0ce553d66ced5b7ca0b64e0b4929)
+++ uspace/srv/hid/display/client.h	(revision b0a94854e61e0da77ab38167f0510ca1ae7cd70a)
@@ -53,8 +53,10 @@
 extern errno_t ds_client_get_event(ds_client_t *, ds_window_t **,
     display_wnd_ev_t *);
+extern errno_t ds_client_post_focus_event(ds_client_t *, ds_window_t *);
 extern errno_t ds_client_post_kbd_event(ds_client_t *, ds_window_t *,
     kbd_event_t *);
 extern errno_t ds_client_post_pos_event(ds_client_t *, ds_window_t *,
     pos_event_t *);
+extern errno_t ds_client_post_unfocus_event(ds_client_t *, ds_window_t *);
 
 #endif
Index: uspace/srv/hid/display/seat.c
===================================================================
--- uspace/srv/hid/display/seat.c	(revision e1f2079eea6e0ce553d66ced5b7ca0b64e0b4929)
+++ uspace/srv/hid/display/seat.c	(revision b0a94854e61e0da77ab38167f0510ca1ae7cd70a)
@@ -83,5 +83,11 @@
 void ds_seat_set_focus(ds_seat_t *seat, ds_window_t *wnd)
 {
+	if (seat->focus != NULL)
+		ds_window_post_unfocus_event(seat->focus);
+
 	seat->focus = wnd;
+
+	if (wnd != NULL)
+		ds_window_post_focus_event(wnd);
 }
 
Index: uspace/srv/hid/display/test/client.c
===================================================================
--- uspace/srv/hid/display/test/client.c	(revision e1f2079eea6e0ce553d66ced5b7ca0b64e0b4929)
+++ uspace/srv/hid/display/test/client.c	(revision b0a94854e61e0da77ab38167f0510ca1ae7cd70a)
@@ -163,4 +163,51 @@
 }
 
+/** Test ds_client_get_event(), ds_client_post_focus_event(). */
+PCUT_TEST(client_get_post_focus_event)
+{
+	ds_display_t *disp;
+	ds_client_t *client;
+	ds_window_t *wnd;
+	display_wnd_params_t params;
+	ds_window_t *rwindow;
+	display_wnd_ev_t revent;
+	bool called_cb = NULL;
+	errno_t rc;
+
+	rc = ds_display_create(NULL, &disp);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	display_wnd_params_init(&params);
+	params.rect.p0.x = params.rect.p0.y = 0;
+	params.rect.p1.x = params.rect.p1.y = 1;
+
+	rc = ds_window_create(client, &params, &wnd);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_FALSE(called_cb);
+
+	rc = ds_client_get_event(client, &rwindow, &revent);
+	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
+
+	rc = ds_client_post_focus_event(client, wnd);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_TRUE(called_cb);
+
+	rc = ds_client_get_event(client, &rwindow, &revent);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_EQUALS(wnd, rwindow);
+	PCUT_ASSERT_EQUALS(wev_focus, revent.etype);
+
+	rc = ds_client_get_event(client, &rwindow, &revent);
+	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
+
+	ds_window_destroy(wnd);
+	ds_client_destroy(client);
+	ds_display_destroy(disp);
+}
+
 /** Test ds_client_get_event(), ds_client_post_kbd_event(). */
 PCUT_TEST(client_get_post_kbd_event)
@@ -275,4 +322,51 @@
 }
 
+/** Test ds_client_get_event(), ds_client_post_unfocus_event(). */
+PCUT_TEST(client_get_post_unfocus_event)
+{
+	ds_display_t *disp;
+	ds_client_t *client;
+	ds_window_t *wnd;
+	display_wnd_params_t params;
+	ds_window_t *rwindow;
+	display_wnd_ev_t revent;
+	bool called_cb = NULL;
+	errno_t rc;
+
+	rc = ds_display_create(NULL, &disp);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	display_wnd_params_init(&params);
+	params.rect.p0.x = params.rect.p0.y = 0;
+	params.rect.p1.x = params.rect.p1.y = 1;
+
+	rc = ds_window_create(client, &params, &wnd);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	PCUT_ASSERT_FALSE(called_cb);
+
+	rc = ds_client_get_event(client, &rwindow, &revent);
+	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
+
+	rc = ds_client_post_unfocus_event(client, wnd);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_TRUE(called_cb);
+
+	rc = ds_client_get_event(client, &rwindow, &revent);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+	PCUT_ASSERT_EQUALS(wnd, rwindow);
+	PCUT_ASSERT_EQUALS(wev_unfocus, revent.etype);
+
+	rc = ds_client_get_event(client, &rwindow, &revent);
+	PCUT_ASSERT_ERRNO_VAL(ENOENT, rc);
+
+	ds_window_destroy(wnd);
+	ds_client_destroy(client);
+	ds_display_destroy(disp);
+}
+
 /** Test client being destroyed while still having a window.
  *
Index: uspace/srv/hid/display/window.c
===================================================================
--- uspace/srv/hid/display/window.c	(revision e1f2079eea6e0ce553d66ced5b7ca0b64e0b4929)
+++ uspace/srv/hid/display/window.c	(revision b0a94854e61e0da77ab38167f0510ca1ae7cd70a)
@@ -518,4 +518,26 @@
 }
 
+/** Post focus event to window.
+ *
+ * @param wnd Window
+ */
+errno_t ds_window_post_focus_event(ds_window_t *wnd)
+{
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_focus_event\n");
+
+	return ds_client_post_focus_event(wnd->client, wnd);
+}
+
+/** Post unfocus event to window.
+ *
+ * @param wnd Window
+ */
+errno_t ds_window_post_unfocus_event(ds_window_t *wnd)
+{
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_unfocus_event\n");
+
+	return ds_client_post_unfocus_event(wnd->client, wnd);
+}
+
 /** @}
  */
Index: uspace/srv/hid/display/window.h
===================================================================
--- uspace/srv/hid/display/window.h	(revision e1f2079eea6e0ce553d66ced5b7ca0b64e0b4929)
+++ uspace/srv/hid/display/window.h	(revision b0a94854e61e0da77ab38167f0510ca1ae7cd70a)
@@ -54,4 +54,6 @@
 extern errno_t ds_window_paint(ds_window_t *, gfx_rect_t *);
 extern errno_t ds_window_post_pos_event(ds_window_t *, pos_event_t *);
+extern errno_t ds_window_post_focus_event(ds_window_t *);
+extern errno_t ds_window_post_unfocus_event(ds_window_t *);
 
 #endif
