Index: uspace/lib/ui/include/types/ui/popup.h
===================================================================
--- uspace/lib/ui/include/types/ui/popup.h	(revision 3be53668a72d42907f6124a3b95374fde7f15a53)
+++ uspace/lib/ui/include/types/ui/popup.h	(revision 5d380b63867e347a3212398238dbe95d3b227d35)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2021 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -40,4 +40,5 @@
 #include <io/kbd_event.h>
 #include <io/pos_event.h>
+#include <types/common.h>
 
 struct ui_popup;
@@ -50,4 +51,6 @@
 	/** Placement rectangle close to which popup should be placed */
 	gfx_rect_t place;
+	/** Input device ID associated with the popup's seat */
+	sysarg_t idev_id;
 } ui_popup_params_t;
 
Index: uspace/lib/ui/include/types/ui/window.h
===================================================================
--- uspace/lib/ui/include/types/ui/window.h	(revision 3be53668a72d42907f6124a3b95374fde7f15a53)
+++ uspace/lib/ui/include/types/ui/window.h	(revision 5d380b63867e347a3212398238dbe95d3b227d35)
@@ -89,4 +89,6 @@
 	/** Parent rectangle for popup windows */
 	gfx_rect_t prect;
+	/** Input device associated with the window's seat */
+	sysarg_t idev_id;
 } ui_wnd_params_t;
 
Index: uspace/lib/ui/include/ui/menu.h
===================================================================
--- uspace/lib/ui/include/ui/menu.h	(revision 3be53668a72d42907f6124a3b95374fde7f15a53)
+++ uspace/lib/ui/include/ui/menu.h	(revision 5d380b63867e347a3212398238dbe95d3b227d35)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -42,4 +42,5 @@
 #include <io/pos_event.h>
 #include <stdbool.h>
+#include <types/common.h>
 #include <types/ui/menu.h>
 #include <types/ui/menubar.h>
@@ -56,5 +57,5 @@
 extern void ui_menu_get_rect(ui_menu_t *, gfx_coord2_t *, gfx_rect_t *);
 extern char32_t ui_menu_get_accel(ui_menu_t *);
-extern errno_t ui_menu_open(ui_menu_t *, gfx_rect_t *);
+extern errno_t ui_menu_open(ui_menu_t *, gfx_rect_t *, sysarg_t);
 extern void ui_menu_close(ui_menu_t *);
 extern bool ui_menu_is_open(ui_menu_t *);
Index: uspace/lib/ui/include/ui/menubar.h
===================================================================
--- uspace/lib/ui/include/ui/menubar.h	(revision 3be53668a72d42907f6124a3b95374fde7f15a53)
+++ uspace/lib/ui/include/ui/menubar.h	(revision 5d380b63867e347a3212398238dbe95d3b227d35)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -40,4 +40,5 @@
 #include <gfx/coord.h>
 #include <io/pos_event.h>
+#include <types/common.h>
 #include <types/ui/menubar.h>
 #include <types/ui/control.h>
@@ -56,5 +57,5 @@
 extern ui_evclaim_t ui_menu_bar_kbd_event(ui_menu_bar_t *, kbd_event_t *);
 extern ui_evclaim_t ui_menu_bar_pos_event(ui_menu_bar_t *, pos_event_t *);
-extern void ui_menu_bar_press_accel(ui_menu_bar_t *, char32_t);
+extern void ui_menu_bar_press_accel(ui_menu_bar_t *, char32_t, sysarg_t);
 extern void ui_menu_bar_unfocus(ui_menu_bar_t *);
 extern void ui_menu_bar_activate(ui_menu_bar_t *);
Index: uspace/lib/ui/private/menubar.h
===================================================================
--- uspace/lib/ui/private/menubar.h	(revision 3be53668a72d42907f6124a3b95374fde7f15a53)
+++ uspace/lib/ui/private/menubar.h	(revision 5d380b63867e347a3212398238dbe95d3b227d35)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -41,4 +41,5 @@
 #include <gfx/coord.h>
 #include <stdbool.h>
+#include <types/common.h>
 #include <types/ui/menu.h>
 #include <types/ui/menubar.h>
@@ -65,7 +66,7 @@
 };
 
-extern void ui_menu_bar_select(ui_menu_bar_t *, ui_menu_t *, bool);
-extern void ui_menu_bar_left(ui_menu_bar_t *);
-extern void ui_menu_bar_right(ui_menu_bar_t *);
+extern void ui_menu_bar_select(ui_menu_bar_t *, ui_menu_t *, bool, sysarg_t);
+extern void ui_menu_bar_left(ui_menu_bar_t *, sysarg_t);
+extern void ui_menu_bar_right(ui_menu_bar_t *, sysarg_t);
 extern ui_evclaim_t ui_menu_bar_key_press_unmod(ui_menu_bar_t *, kbd_event_t *);
 extern void ui_menu_bar_entry_rect(ui_menu_bar_t *, ui_menu_t *, gfx_rect_t *);
Index: uspace/lib/ui/src/menu.c
===================================================================
--- uspace/lib/ui/src/menu.c	(revision 3be53668a72d42907f6124a3b95374fde7f15a53)
+++ uspace/lib/ui/src/menu.c	(revision 5d380b63867e347a3212398238dbe95d3b227d35)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -280,6 +280,7 @@
  * @param menu Menu
  * @param prect Parent rectangle around which the menu should be placed
- */
-errno_t ui_menu_open(ui_menu_t *menu, gfx_rect_t *prect)
+ * @param idev_id Input device associated with the menu's seat
+ */
+errno_t ui_menu_open(ui_menu_t *menu, gfx_rect_t *prect, sysarg_t idev_id)
 {
 	ui_popup_t *popup = NULL;
@@ -301,4 +302,5 @@
 	params.rect = geom.outer_rect;
 	params.place = *prect;
+	params.idev_id = idev_id;
 
 	rc = ui_popup_create(menu->mbar->ui, menu->mbar->window, &params,
@@ -522,5 +524,5 @@
 	if (event->type == KEY_PRESS && (event->mods & KM_ALT) != 0 &&
 	    (event->mods & (KM_CTRL | KM_SHIFT)) == 0 && event->c != '\0')
-		ui_menu_bar_press_accel(menu->mbar, event->c);
+		ui_menu_bar_press_accel(menu->mbar, event->c, event->kbd_id);
 
 	return ui_claimed;
@@ -616,8 +618,8 @@
 		break;
 	case KC_LEFT:
-		ui_menu_bar_left(menu->mbar);
+		ui_menu_bar_left(menu->mbar, event->kbd_id);
 		break;
 	case KC_RIGHT:
-		ui_menu_bar_right(menu->mbar);
+		ui_menu_bar_right(menu->mbar, event->kbd_id);
 		break;
 	case KC_UP:
Index: uspace/lib/ui/src/menubar.c
===================================================================
--- uspace/lib/ui/src/menubar.c	(revision 3be53668a72d42907f6124a3b95374fde7f15a53)
+++ uspace/lib/ui/src/menubar.c	(revision 5d380b63867e347a3212398238dbe95d3b227d35)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -243,6 +243,8 @@
  * @param menu Menu to select (or deselect if selected) or @c NULL
  * @param openup Open menu even if not currently open
- */
-void ui_menu_bar_select(ui_menu_bar_t *mbar, ui_menu_t *menu, bool openup)
+ * @param idev_id Input device ID associated with the selecting seat
+ */
+void ui_menu_bar_select(ui_menu_bar_t *mbar, ui_menu_t *menu, bool openup,
+    sysarg_t idev_id)
 {
 	ui_menu_t *old_menu;
@@ -272,5 +274,5 @@
 			 * specified.
 			 */
-			(void) ui_menu_open(mbar->selected, &rect);
+			(void) ui_menu_open(mbar->selected, &rect, idev_id);
 		}
 	}
@@ -283,6 +285,7 @@
  *
  * @param mbar Menu bar
- */
-void ui_menu_bar_left(ui_menu_bar_t *mbar)
+ * @param idev_id Input device ID
+ */
+void ui_menu_bar_left(ui_menu_bar_t *mbar, sysarg_t idev_id)
 {
 	ui_menu_t *nmenu;
@@ -296,5 +299,5 @@
 
 	if (nmenu != mbar->selected)
-		ui_menu_bar_select(mbar, nmenu, false);
+		ui_menu_bar_select(mbar, nmenu, false, idev_id);
 }
 
@@ -305,6 +308,7 @@
  *
  * @param mbar Menu bar
- */
-void ui_menu_bar_right(ui_menu_bar_t *mbar)
+ * @param idev_id Input device ID
+ */
+void ui_menu_bar_right(ui_menu_bar_t *mbar, sysarg_t idev_id)
 {
 	ui_menu_t *nmenu;
@@ -318,5 +322,5 @@
 
 	if (nmenu != mbar->selected)
-		ui_menu_bar_select(mbar, nmenu, false);
+		ui_menu_bar_select(mbar, nmenu, false, idev_id);
 }
 
@@ -345,8 +349,8 @@
 
 	if (event->key == KC_LEFT)
-		ui_menu_bar_left(mbar);
+		ui_menu_bar_left(mbar, event->kbd_id);
 
 	if (event->key == KC_RIGHT)
-		ui_menu_bar_right(mbar);
+		ui_menu_bar_right(mbar, event->kbd_id);
 
 	if (event->key == KC_ENTER || event->key == KC_DOWN) {
@@ -354,5 +358,5 @@
 			ui_menu_bar_entry_rect(mbar, mbar->selected,
 			    &rect);
-			ui_menu_open(mbar->selected, &rect);
+			ui_menu_open(mbar->selected, &rect, event->kbd_id);
 		}
 
@@ -362,5 +366,5 @@
 	if (event->c != '\0' && !ui_menu_is_open(mbar->selected)) {
 		/* Check if it is an accelerator. */
-		ui_menu_bar_press_accel(mbar, event->c);
+		ui_menu_bar_press_accel(mbar, event->c, event->kbd_id);
 	}
 
@@ -379,5 +383,5 @@
 	    (event->mods & (KM_CTRL | KM_SHIFT)) == 0 && event->c != '\0') {
 		/* Check if it is an accelerator. */
-		ui_menu_bar_press_accel(mbar, event->c);
+		ui_menu_bar_press_accel(mbar, event->c, event->kbd_id);
 	}
 
@@ -399,6 +403,7 @@
  * @param mbar Menu bar
  * @param c Character
- */
-void ui_menu_bar_press_accel(ui_menu_bar_t *mbar, char32_t c)
+ * @param kbd_id Keyboard ID
+ */
+void ui_menu_bar_press_accel(ui_menu_bar_t *mbar, char32_t c, sysarg_t kbd_id)
 {
 	ui_menu_t *menu;
@@ -409,5 +414,5 @@
 		maccel = ui_menu_get_accel(menu);
 		if (c == maccel) {
-			ui_menu_bar_select(mbar, menu, true);
+			ui_menu_bar_select(mbar, menu, true, kbd_id);
 			return;
 		}
@@ -433,4 +438,5 @@
 	gfx_coord_t hpad;
 	gfx_coord2_t ppos;
+	sysarg_t pos_id;
 
 	res = ui_window_get_res(mbar->window);
@@ -446,4 +452,5 @@
 
 	pos = mbar->rect.p0;
+	pos_id = event->pos_id;
 
 	menu = ui_menu_first(mbar);
@@ -463,7 +470,7 @@
 			/* Open the menu, close if already open. */
 			if (menu == mbar->selected)
-				ui_menu_bar_select(mbar, NULL, false);
+				ui_menu_bar_select(mbar, NULL, false, pos_id);
 			else
-				ui_menu_bar_select(mbar, menu, true);
+				ui_menu_bar_select(mbar, menu, true, pos_id);
 
 			return ui_claimed;
@@ -544,5 +551,5 @@
 void ui_menu_bar_deactivate(ui_menu_bar_t *mbar)
 {
-	ui_menu_bar_select(mbar, NULL, false);
+	ui_menu_bar_select(mbar, NULL, false, 0);
 	mbar->active = false;
 }
Index: uspace/lib/ui/src/popup.c
===================================================================
--- uspace/lib/ui/src/popup.c	(revision 3be53668a72d42907f6124a3b95374fde7f15a53)
+++ uspace/lib/ui/src/popup.c	(revision 5d380b63867e347a3212398238dbe95d3b227d35)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -99,4 +99,5 @@
 	wparams.placement = ui_wnd_place_popup;
 	wparams.flags |= ui_wndf_popup;
+	wparams.idev_id = params->idev_id;
 
 	/* Compute position of parent rectangle relative to the screen */
Index: uspace/lib/ui/src/window.c
===================================================================
--- uspace/lib/ui/src/window.c	(revision 3be53668a72d42907f6124a3b95374fde7f15a53)
+++ uspace/lib/ui/src/window.c	(revision 5d380b63867e347a3212398238dbe95d3b227d35)
@@ -227,4 +227,5 @@
 	/* Only allow making the window larger */
 	gfx_rect_dims(&params->rect, &dparams.min_size);
+	dparams.idev_id = params->idev_id;
 
 	if ((params->flags & ui_wndf_popup) != 0)
Index: uspace/lib/ui/test/menu.c
===================================================================
--- uspace/lib/ui/test/menu.c	(revision 3be53668a72d42907f6124a3b95374fde7f15a53)
+++ uspace/lib/ui/test/menu.c	(revision 5d380b63867e347a3212398238dbe95d3b227d35)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2021 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -293,5 +293,5 @@
 
 	/* Open and close */
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -341,5 +341,5 @@
 	PCUT_ASSERT_FALSE(open);
 
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -393,5 +393,5 @@
 
 	/* Menu needs to be open to be able to paint it */
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -442,5 +442,5 @@
 
 	/* Menu needs to be open to be able to paint it */
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -491,5 +491,5 @@
 
 	/* Menu needs to be open to be able to paint it */
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -539,5 +539,5 @@
 
 	/* Menu needs to be open to be able to move around it */
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -599,5 +599,5 @@
 
 	/* Menu needs to be open to be able to move around it */
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -655,5 +655,5 @@
 
 	/* Menu needs to be open to be able to move around it */
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -715,5 +715,5 @@
 
 	/* Menu needs to be open to be able to move around it */
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
Index: uspace/lib/ui/test/menubar.c
===================================================================
--- uspace/lib/ui/test/menubar.c	(revision 3be53668a72d42907f6124a3b95374fde7f15a53)
+++ uspace/lib/ui/test/menubar.c	(revision 5d380b63867e347a3212398238dbe95d3b227d35)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2022 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -235,5 +235,5 @@
 	PCUT_ASSERT_FALSE(ui_menu_is_open(menu));
 
-	ui_menu_bar_press_accel(mbar, 't');
+	ui_menu_bar_press_accel(mbar, 't', 0);
 
 	PCUT_ASSERT_TRUE(ui_menu_is_open(menu));
@@ -329,9 +329,9 @@
 	PCUT_ASSERT_NOT_NULL(menu2);
 
-	ui_menu_bar_select(mbar, menu1, true);
+	ui_menu_bar_select(mbar, menu1, true, 0);
 	PCUT_ASSERT_EQUALS(menu1, mbar->selected);
 
 	/* Selecting different menu should select it */
-	ui_menu_bar_select(mbar, menu2, true);
+	ui_menu_bar_select(mbar, menu2, true, 0);
 	PCUT_ASSERT_EQUALS(menu2, mbar->selected);
 
Index: uspace/lib/ui/test/menuentry.c
===================================================================
--- uspace/lib/ui/test/menuentry.c	(revision 3be53668a72d42907f6124a3b95374fde7f15a53)
+++ uspace/lib/ui/test/menuentry.c	(revision 5d380b63867e347a3212398238dbe95d3b227d35)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2021 Jiri Svoboda
+ * Copyright (c) 2023 Jiri Svoboda
  * All rights reserved.
  *
@@ -381,5 +381,5 @@
 	prect.p1.y = 0;
 
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -492,5 +492,5 @@
 	prect.p1.y = 0;
 
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -555,5 +555,5 @@
 	prect.p1.y = 0;
 
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -623,5 +623,5 @@
 	prect.p1.y = 0;
 
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -695,5 +695,5 @@
 	prect.p1.y = 0;
 
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -750,5 +750,5 @@
 	prect.p1.y = 0;
 
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -810,5 +810,5 @@
 	prect.p1.y = 0;
 
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -870,5 +870,5 @@
 	prect.p1.y = 0;
 
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
@@ -933,5 +933,5 @@
 	prect.p1.y = 0;
 
-	rc = ui_menu_open(menu, &prect);
+	rc = ui_menu_open(menu, &prect, 0);
 	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
