From patchwork Fri Oct 10 03:42:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 577 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1760067836; bh=GAcG8wRqF3Ozd9a1q0r5OJaIBsfAZtgKUr1a3zM0Fqk=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=A9k6wveWK/FJjNbI9SW3tou8RfHIeSA5UUYwHwjlHJ9j11pQAazI5JBmCxIgDPa4d 4SI2kuAMwErt9kWCEfh54FIHAKgTHE43rbaZRtSg3lxb/22Zmsey51GgYDbPbDQoLM bAGw2tIE4J14B3azwJOqzPPJSG8irwVDploBSxG5osqCeKjkWBr0Uau7X72wRxuKor hoVeVPTGtAZYTNPiAa/7tDOAoktZGTVMVrudKegtXrLyqTNw2eqnayGXVVPh3XofpY LTcXv05qYRnSQSm44tRTy9hvPUC55dWfzHGx0FwvxxO1NbBicmSP+T8PV+SQHZJ12f Vn2z8DhVloHDQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 3283A67FE9 for ; Thu, 9 Oct 2025 21:43:56 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id w0SRZvWKg0LA for ; Thu, 9 Oct 2025 21:43:56 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1760067836; bh=GAcG8wRqF3Ozd9a1q0r5OJaIBsfAZtgKUr1a3zM0Fqk=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=A9k6wveWK/FJjNbI9SW3tou8RfHIeSA5UUYwHwjlHJ9j11pQAazI5JBmCxIgDPa4d 4SI2kuAMwErt9kWCEfh54FIHAKgTHE43rbaZRtSg3lxb/22Zmsey51GgYDbPbDQoLM bAGw2tIE4J14B3azwJOqzPPJSG8irwVDploBSxG5osqCeKjkWBr0Uau7X72wRxuKor hoVeVPTGtAZYTNPiAa/7tDOAoktZGTVMVrudKegtXrLyqTNw2eqnayGXVVPh3XofpY LTcXv05qYRnSQSm44tRTy9hvPUC55dWfzHGx0FwvxxO1NbBicmSP+T8PV+SQHZJ12f Vn2z8DhVloHDQ== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 2041468044 for ; Thu, 9 Oct 2025 21:43:56 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1760067834; bh=PJm7JRS6HUIrlPmLyKUmwHv/Hf4vXdr95PiiqpnCy+8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rNcWvyQw7PXxZ31+uxsEk6axKhn1zoIXH9SGCZGD3DAmizoz/GPzo/ob4R3inUHPs TkfHD/0vJy1j3X5GDzGAkzv2Y1XVOHEcyJzuPpJJigSCs1qk8RB/O89mhhFLt+jaVa tgGH6hZc1YYxXR9HSchSeckQE8TgXanaBd1LJVmJ5DLIDgbnvdjoblaukDm+DgVg/0 FF5TVh8NoknzfZqFj98wjyUmoJaIjOPflSkc7aKWxJ3ZhyGAeGpdPy68qYw1U34W+6 J61G+CQ2cF7RBYP0WQBk7dn9229TPpOCWq8+jMKrx6SWS0WIeTMEEEeeiZopRSFJuh DyvsSywf+Xoqw== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id A016F67F7F; Thu, 9 Oct 2025 21:43:54 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id e0SoQivEPwdy; Thu, 9 Oct 2025 21:43:54 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1760067830; bh=NqYqQ5Svg9IuGabqCKWo/r4URNdzC3yXTcWbYHbeaj8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FK8bITYlHIM4domsqE7O7+rZbkfunzG6AS6W5r+JiqMFRURKKJm+tpNnlL1v7ldbo cB8S5rzbbvHnIKmWc5g1QTEivi+TkFozjGI6qlmOs291qSnfcX0CRuZRC1v6+lyLRr gUpgGRhV4NK3pSKQt7l9KUEnnfRL0jF3ePUoshgaB2bAggH6uR+56LhSR3G4pbDIRW CB7SGmp7MAYFePERhIq9mNuoMGLlGTbxBTYCN1tuUTkSOx3fhM0N6gqyb3O0KFD+hu 9CMI8JSFkN8oXfobozhwVfaloWKQS6CYADgyF7Nu4iGmFrRsnXL0za0e/XBgPV9MLS KkV9v3zBpVyZQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 88FFC67FE9; Thu, 9 Oct 2025 21:43:50 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Thu, 9 Oct 2025 21:42:39 -0600 Message-ID: <20251010034255.1099728-12-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251010034255.1099728-1-sjg@u-boot.org> References: <20251010034255.1099728-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: WBWMABJJHIMJLRQRCWKIBNJWR5ILQL54 X-Message-ID-Hash: WBWMABJJHIMJLRQRCWKIBNJWR5ILQL54 X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass , Claude X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 11/18] expo: Allow searching for any object type by position List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass At present only highlightable objects can be clicked on, i.e. menus and textlines. Update scene_find_obj_within() so that it can find any type of object, if requested. Update all the callers to false, so things work the same. Since the scene is drawn by iterating through the list of objects, when the user clicks somewhere we should look at the top-most object under the mouse first. So reverse the direction of the object search. Update the tests to cover this new feature. Co-developed-by: Claude Signed-off-by: Simon Glass --- boot/scene.c | 15 ++++++------- boot/scene_internal.h | 3 ++- test/boot/expo.c | 49 +++++++++++++++++++++++++++++++++++++------ 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/boot/scene.c b/boot/scene.c index 05a683dd1da..4cf1b6d5852 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -1194,18 +1194,19 @@ bool scene_obj_within(const struct scene *scn, struct scene_obj *obj, int x, } struct scene_obj *scene_find_obj_within(const struct scene *scn, int x, int y, - bool reverse) + bool reverse, bool allow_any) { struct scene_obj *obj; - log_debug("within: x %d y %d reverse %d\n", x, y, reverse); + log_debug("within: x %d y %d reverse %d allow_any %d\n", x, y, reverse, + allow_any); if (reverse) { list_for_each_entry_reverse(obj, &scn->obj_head, sibling) { log_debug(" - obj %d '%s' can_highlight %d within %d\n", obj->id, obj->name, scene_obj_can_highlight(obj), scene_obj_within(scn, obj, x, y)); - if (scene_obj_can_highlight(obj) && + if ((allow_any || scene_obj_can_highlight(obj)) && scene_obj_within(scn, obj, x, y)) { log_debug("- returning obj %d '%s'\n", obj->id, obj->name); @@ -1218,7 +1219,7 @@ struct scene_obj *scene_find_obj_within(const struct scene *scn, int x, int y, obj->id, obj->name, scene_obj_can_highlight(obj), scene_obj_within(scn, obj, x, y)); - if (scene_obj_can_highlight(obj) && + if ((allow_any || scene_obj_can_highlight(obj)) && scene_obj_within(scn, obj, x, y)) { log_debug("- returning obj %d '%s'\n", obj->id, obj->name); @@ -1255,7 +1256,7 @@ static void send_click_obj(struct scene *scn, struct scene_obj *obj, int x, } log_debug("no object; finding...\n"); - obj = scene_find_obj_within(scn, x, y, false); + obj = scene_find_obj_within(scn, x, y, false, false); if (obj) { event->type = EXPOACT_POINT_OPEN; event->select.id = obj->id; @@ -1281,7 +1282,7 @@ static int scene_click_popup(struct scene *scn, int x, int y, } /* check that the click is within our object */ - chk = scene_find_obj_within(scn, x, y, false); + chk = scene_find_obj_within(scn, x, y, false, false); log_debug("chk %d '%s' (obj %d '%s')\n", chk ? chk->id : -1, chk ? chk->name : "(none)", obj->id, obj->name); if (!chk) { @@ -1340,7 +1341,7 @@ int scene_send_click(struct scene *scn, int x, int y, struct expo_action *event) return 0; } - obj = scene_find_obj_within(scn, x, y, false); + obj = scene_find_obj_within(scn, x, y, false, false); log_debug("non-popup obj %d '%s'\n", obj ? obj->id : -1, obj ? obj->name : "(none)"); if (!obj) diff --git a/boot/scene_internal.h b/boot/scene_internal.h index e2f4cc066d0..2bfbb5dcf50 100644 --- a/boot/scene_internal.h +++ b/boot/scene_internal.h @@ -564,9 +564,10 @@ const char *scene_obj_type_name(enum scene_obj_t type); * @y: Y coordinate of the click * @reverse: true to search from top to bottom (reverse order), false for * bottom to top + * @allow_any: true to allow searching non-highlight objects * Return: object that is being clicked on, NULL if none */ struct scene_obj *scene_find_obj_within(const struct scene *scn, int x, int y, - bool reverse); + bool reverse, bool allow_any); #endif /* __SCENE_INTERNAL_H */ diff --git a/test/boot/expo.c b/test/boot/expo.c index e32550a6685..66fd5a2873f 100644 --- a/test/boot/expo.c +++ b/test/boot/expo.c @@ -1289,19 +1289,56 @@ static int expo_find_obj_within(struct unit_test_state *uts) * Check finding a menu by 'clicking' on a menu item label - menu items * are at (50,436) for ITEM1 and (50,454) for ITEM2 */ - obj = scene_find_obj_within(scn, 60, 440, false); + obj = scene_find_obj_within(scn, 60, 440, false, false); ut_assertnonnull(obj); ut_asserteq(OBJ_MENU, obj->id); - /* logo and text are not highlightable, so they should not be found */ - ut_assertnull(scene_find_obj_within(scn, 60, 30, false)); - ut_assertnull(scene_find_obj_within(scn, 410, 110, false)); + /* + * Check with allow_any=false for non-highlightable objects - logo and + * text are not highlightable, so they should not be found + */ + ut_assertnull(scene_find_obj_within(scn, 60, 30, false, false)); + ut_assertnull(scene_find_obj_within(scn, 410, 110, false, false)); + + /* Test with allow_any=true for non-highlightable objects */ + obj = scene_find_obj_within(scn, 60, 30, false, true); + ut_assertnonnull(obj); + ut_asserteq(OBJ_LOGO, obj->id); + + /* + * Check reversing search order with allow_any=true at the overlapping + * position. OBJ_TEXT was created first at (400, 100), and the + * "overlap" text object was created second at (405, 105). They + * overlap at position (410, 110). + * + * With reverse=false, we search from start of list (bottom to top) and + * find OBJ_TEXT first. + */ + obj = scene_find_obj_within(scn, 410, 110, false, true); + ut_assertnonnull(obj); + ut_asserteq(OBJ_TEXT, obj->id); + + /* + * With reverse=true, we search from end of list (top to bottom) and + * find the OBJ_OVERLAP_TEST object first. + */ + obj = scene_find_obj_within(scn, 410, 110, true, true); + ut_assertnonnull(obj); + ut_asserteq(OBJ_OVERLAP, obj->id); + + /* + * Test reverse=true with a non-overlapping object - should get same + * result as reverse=false + */ + obj = scene_find_obj_within(scn, 60, 30, true, true); + ut_assertnonnull(obj); + ut_asserteq(OBJ_LOGO, obj->id); /* empty space */ - ut_assertnull(scene_find_obj_within(scn, 10, 10, false)); + ut_assertnull(scene_find_obj_within(scn, 10, 10, false, false)); /* way outside bounds */ - ut_assertnull(scene_find_obj_within(scn, 9999, 9999, false)); + ut_assertnull(scene_find_obj_within(scn, 9999, 9999, false, false)); abuf_uninit(&buf); abuf_uninit(&logo_copy);