Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision 743f2cdd361af5078f5d096158a45c0e7c4ad059)
+++ uspace/app/edit/edit.c	(revision ec50d65ee29a48534ce00b21e79ef5e2e5b04274)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2023 Jiri Svoboda
+ * Copyright (c) 2024 Jiri Svoboda
  * Copyright (c) 2012 Martin Sucha
  * All rights reserved.
@@ -238,9 +238,21 @@
 
 static void edit_wnd_close(ui_window_t *, void *);
+static void edit_wnd_focus(ui_window_t *, void *, unsigned);
 static void edit_wnd_kbd_event(ui_window_t *, void *, kbd_event_t *);
+static void edit_wnd_unfocus(ui_window_t *, void *, unsigned);
 
 static ui_window_cb_t edit_window_cb = {
 	.close = edit_wnd_close,
-	.kbd = edit_wnd_kbd_event
+	.focus = edit_wnd_focus,
+	.kbd = edit_wnd_kbd_event,
+	.unfocus = edit_wnd_unfocus
+};
+
+static void edit_menubar_activate(ui_menu_bar_t *, void *);
+static void edit_menubar_deactivate(ui_menu_bar_t *, void *);
+
+static ui_menu_bar_cb_t edit_menubar_cb = {
+	.activate = edit_menubar_activate,
+	.deactivate = edit_menubar_deactivate
 };
 
@@ -431,4 +443,6 @@
 	}
 
+	ui_menu_bar_set_cb(edit->menubar, &edit_menubar_cb, (void *) edit);
+
 	rc = ui_menu_dd_create(edit->menubar, "~F~ile", NULL, &mfile);
 	if (rc != EOK) {
@@ -2221,4 +2235,19 @@
 }
 
+/** Window focus event
+ *
+ * @param window Window
+ * @param arg Argument (edit_t *)
+ * @param focus Focus number
+ */
+static void edit_wnd_focus(ui_window_t *window, void *arg, unsigned focus)
+{
+	edit_t *edit = (edit_t *)arg;
+
+	(void)edit;
+	pane_caret_display(&pane);
+	cursor_setvis(true);
+}
+
 /** Window keyboard event
  *
@@ -2242,4 +2271,45 @@
 }
 
+/** Window unfocus event
+ *
+ * @param window Window
+ * @param arg Argument (edit_t *)
+ * @param focus Focus number
+ */
+static void edit_wnd_unfocus(ui_window_t *window, void *arg, unsigned focus)
+{
+	edit_t *edit = (edit_t *) arg;
+
+	(void)edit;
+	cursor_setvis(false);
+}
+
+/** Menu bar activate event
+ *
+ * @param mbar Menu bar
+ * @param arg Argument (edit_t *)
+ */
+static void edit_menubar_activate(ui_menu_bar_t *mbar, void *arg)
+{
+	edit_t *edit = (edit_t *)arg;
+
+	(void)edit;
+	cursor_setvis(false);
+}
+
+/** Menu bar deactivate event
+ *
+ * @param mbar Menu bar
+ * @param arg Argument (edit_t *)
+ */
+static void edit_menubar_deactivate(ui_menu_bar_t *mbar, void *arg)
+{
+	edit_t *edit = (edit_t *)arg;
+
+	(void)edit;
+	pane_caret_display(&pane);
+	cursor_setvis(true);
+}
+
 /** File / Save menu entry selected.
  *
@@ -2407,13 +2477,9 @@
 {
 	edit_t *edit = (edit_t *)arg;
-	gfx_context_t *gc = ui_window_get_gc(edit->window);
 	char *cname;
 	errno_t rc;
 
+	(void)edit;
 	ui_file_dialog_destroy(dialog);
-	// TODO Smarter cursor management
-	pane.rflags |= REDRAW_CARET;
-	(void) pane_update(&pane);
-	gfx_cursor_set_visible(gc, true);
 
 	cname = str_dup(fname);
@@ -2441,11 +2507,7 @@
 {
 	edit_t *edit = (edit_t *)arg;
-	gfx_context_t *gc = ui_window_get_gc(edit->window);
-
+
+	(void)edit;
 	ui_file_dialog_destroy(dialog);
-	// TODO Smarter cursor management
-	pane.rflags |= REDRAW_CARET;
-	(void) pane_update(&pane);
-	gfx_cursor_set_visible(gc, true);
 }
 
@@ -2458,11 +2520,7 @@
 {
 	edit_t *edit = (edit_t *)arg;
-	gfx_context_t *gc = ui_window_get_gc(edit->window);
-
+
+	(void)edit;
 	ui_file_dialog_destroy(dialog);
-	// TODO Smarter cursor management
-	pane.rflags |= REDRAW_CARET;
-	(void) pane_update(&pane);
-	gfx_cursor_set_visible(gc, true);
 }
 
@@ -2477,5 +2535,4 @@
 {
 	edit_t *edit = (edit_t *) arg;
-	gfx_context_t *gc = ui_window_get_gc(edit->window);
 	char *endptr;
 	int line;
@@ -2489,8 +2546,6 @@
 
 	caret_move_absolute(line, pane.ideal_column, dir_before, false);
-	// TODO Smarter cursor management
+	(void)edit;
 	(void) pane_update(&pane);
-	gfx_cursor_set_visible(gc, true);
-	(void) gfx_update(gc);
 }
 
@@ -2503,11 +2558,7 @@
 {
 	edit_t *edit = (edit_t *) arg;
-	gfx_context_t *gc = ui_window_get_gc(edit->window);
-
+
+	(void)edit;
 	ui_prompt_dialog_destroy(dialog);
-	// TODO Smarter cursor management
-	pane.rflags |= REDRAW_CARET;
-	(void) pane_update(&pane);
-	gfx_cursor_set_visible(gc, true);
 }
 
@@ -2520,11 +2571,7 @@
 {
 	edit_t *edit = (edit_t *) arg;
-	gfx_context_t *gc = ui_window_get_gc(edit->window);
-
+
+	(void)edit;
 	ui_prompt_dialog_destroy(dialog);
-	// TODO Smarter cursor management
-	pane.rflags |= REDRAW_CARET;
-	(void) pane_update(&pane);
-	gfx_cursor_set_visible(gc, true);
 }
 
@@ -2539,8 +2586,8 @@
 {
 	edit_t *edit = (edit_t *) arg;
-	gfx_context_t *gc = ui_window_get_gc(edit->window);
 	char *pattern;
 	bool reverse;
 
+	(void)edit;
 	ui_prompt_dialog_destroy(dialog);
 
@@ -2559,8 +2606,5 @@
 	search(pattern, reverse);
 
-	// TODO Smarter cursor management
 	(void) pane_update(&pane);
-	gfx_cursor_set_visible(gc, true);
-	(void) gfx_update(gc);
 }
 
@@ -2573,11 +2617,7 @@
 {
 	edit_t *edit = (edit_t *) arg;
-	gfx_context_t *gc = ui_window_get_gc(edit->window);
-
+
+	(void)edit;
 	ui_prompt_dialog_destroy(dialog);
-	// TODO Smarter cursor management
-	pane.rflags |= REDRAW_CARET;
-	(void) pane_update(&pane);
-	gfx_cursor_set_visible(gc, true);
 }
 
@@ -2590,11 +2630,7 @@
 {
 	edit_t *edit = (edit_t *) arg;
-	gfx_context_t *gc = ui_window_get_gc(edit->window);
-
+
+	(void)edit;
 	ui_prompt_dialog_destroy(dialog);
-	// TODO Smarter cursor management
-	pane.rflags |= REDRAW_CARET;
-	(void) pane_update(&pane);
-	gfx_cursor_set_visible(gc, true);
 }
 
Index: uspace/lib/ui/include/types/ui/menubar.h
===================================================================
--- uspace/lib/ui/include/types/ui/menubar.h	(revision 743f2cdd361af5078f5d096158a45c0e7c4ad059)
+++ uspace/lib/ui/include/types/ui/menubar.h	(revision ec50d65ee29a48534ce00b21e79ef5e2e5b04274)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2021 Jiri Svoboda
+ * Copyright (c) 2024 Jiri Svoboda
  * All rights reserved.
  *
@@ -40,4 +40,12 @@
 typedef struct ui_menu_bar ui_menu_bar_t;
 
+/** Menu bar callbacks */
+typedef struct ui_menu_bar_cb {
+	/** Activated */
+	void (*activate)(ui_menu_bar_t *, void *);
+	/** Deactivated */
+	void (*deactivate)(ui_menu_bar_t *, void *);
+} ui_menu_bar_cb_t;
+
 #endif
 
Index: uspace/lib/ui/include/ui/menubar.h
===================================================================
--- uspace/lib/ui/include/ui/menubar.h	(revision 743f2cdd361af5078f5d096158a45c0e7c4ad059)
+++ uspace/lib/ui/include/ui/menubar.h	(revision ec50d65ee29a48534ce00b21e79ef5e2e5b04274)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2023 Jiri Svoboda
+ * Copyright (c) 2024 Jiri Svoboda
  * All rights reserved.
  *
@@ -52,4 +52,5 @@
     ui_menu_bar_t **);
 extern void ui_menu_bar_destroy(ui_menu_bar_t *);
+extern void ui_menu_bar_set_cb(ui_menu_bar_t *, ui_menu_bar_cb_t *, void *);
 extern ui_control_t *ui_menu_bar_ctl(ui_menu_bar_t *);
 extern void ui_menu_bar_set_rect(ui_menu_bar_t *, gfx_rect_t *);
Index: uspace/lib/ui/private/menubar.h
===================================================================
--- uspace/lib/ui/private/menubar.h	(revision 743f2cdd361af5078f5d096158a45c0e7c4ad059)
+++ uspace/lib/ui/private/menubar.h	(revision ec50d65ee29a48534ce00b21e79ef5e2e5b04274)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2023 Jiri Svoboda
+ * Copyright (c) 2024 Jiri Svoboda
  * All rights reserved.
  *
@@ -64,4 +64,8 @@
 	/** List of menu drop-downs (ui_menu_dd_t) */
 	list_t menudds;
+	/** Callbacks */
+	struct ui_menu_bar_cb *cb;
+	/** Callback argument */
+	void *arg;
 };
 
Index: uspace/lib/ui/src/menubar.c
===================================================================
--- uspace/lib/ui/src/menubar.c	(revision 743f2cdd361af5078f5d096158a45c0e7c4ad059)
+++ uspace/lib/ui/src/menubar.c	(revision ec50d65ee29a48534ce00b21e79ef5e2e5b04274)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2023 Jiri Svoboda
+ * Copyright (c) 2024 Jiri Svoboda
  * All rights reserved.
  *
@@ -66,4 +66,6 @@
 static ui_evclaim_t ui_menu_bar_ctl_kbd_event(void *, kbd_event_t *);
 static ui_evclaim_t ui_menu_bar_ctl_pos_event(void *, pos_event_t *);
+static void ui_menu_bar_activate_ev(ui_menu_bar_t *);
+static void ui_menu_bar_deactivate_ev(ui_menu_bar_t *);
 
 /** Menu bar control ops */
@@ -131,4 +133,16 @@
 	ui_control_delete(mbar->control);
 	free(mbar);
+}
+
+/** Set menu bar callbacks.
+ *
+ * @param mbar Menu bar
+ * @param cb Callbacks
+ * @param arg Callback argument
+ */
+void ui_menu_bar_set_cb(ui_menu_bar_t *mbar, ui_menu_bar_cb_t *cb, void *arg)
+{
+	mbar->cb = cb;
+	mbar->arg = arg;
 }
 
@@ -288,6 +302,10 @@
 		}
 
+		if (!mbar->active)
+			ui_menu_bar_activate_ev(mbar);
 		mbar->active = true;
 	} else {
+		if (mbar->active)
+			ui_menu_bar_deactivate_ev(mbar);
 		mbar->active = false;
 	}
@@ -640,4 +658,5 @@
 
 	(void) ui_menu_bar_paint(mbar);
+	ui_menu_bar_activate_ev(mbar);
 }
 
@@ -649,4 +668,5 @@
 {
 	ui_menu_bar_select(mbar, NULL, false, 0);
+	ui_menu_bar_deactivate_ev(mbar);
 }
 
@@ -700,4 +720,24 @@
 }
 
+/** Send menu bar activate event.
+ *
+ * @param mbar Menu bar
+ */
+static void ui_menu_bar_activate_ev(ui_menu_bar_t *mbar)
+{
+	if (mbar->cb != NULL && mbar->cb->activate != NULL)
+		mbar->cb->activate(mbar, mbar->arg);
+}
+
+/** Send menu bar deactivate event.
+ *
+ * @param mbar Menu bar
+ */
+static void ui_menu_bar_deactivate_ev(ui_menu_bar_t *mbar)
+{
+	if (mbar->cb != NULL && mbar->cb->deactivate != NULL)
+		mbar->cb->deactivate(mbar, mbar->arg);
+}
+
 /** @}
  */
Index: uspace/lib/ui/src/window.c
===================================================================
--- uspace/lib/ui/src/window.c	(revision 743f2cdd361af5078f5d096158a45c0e7c4ad059)
+++ uspace/lib/ui/src/window.c	(revision ec50d65ee29a48534ce00b21e79ef5e2e5b04274)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2023 Jiri Svoboda
+ * Copyright (c) 2024 Jiri Svoboda
  * All rights reserved.
  *
@@ -318,4 +318,5 @@
 {
 	ui_window_t *window;
+	ui_window_t *pwindow = NULL;
 	display_info_t info;
 	gfx_coord2_t scr_dims;
@@ -505,5 +506,15 @@
 	*rwindow = window;
 
+	if (ui_is_fullscreen(ui))
+		pwindow = ui_window_get_active(ui);
+
 	list_append(&window->lwindows, &ui->windows);
+
+	if (ui_is_fullscreen(ui)) {
+		/* Send unfocus event to previously active window */
+		if (pwindow != NULL)
+			ui_window_send_unfocus(pwindow, 0);
+	}
+
 	return EOK;
 error:
@@ -531,4 +542,5 @@
 {
 	ui_t *ui;
+	ui_window_t *nwindow;
 
 	if (window == NULL)
@@ -558,4 +570,8 @@
 	if (ui_is_fullscreen(ui)) {
 		ui_paint(ui);
+		/* Send focus event to newly active window */
+		nwindow = ui_window_get_active(ui);
+		if (nwindow != NULL)
+			ui_window_send_focus(nwindow, 0);
 	}
 
