From a312503ed21282c82c8ce457502f2558623b623c Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 7 May 2019 18:17:59 -0600 Subject: [PATCH] libs/libnx/nxtk/nxtk_events: Fix an error in handling mouse events for framed windows. When drawing, NX may report mouse positions outside of the Window. The is only for NX windows, but the outside-the-side positions were being discarded by nxtk_events(). --- graphics/nxmu/nxmu_mouse.c | 12 ++++++---- libs/libnx/nxmu/nx_mousein.c | 2 +- libs/libnx/nxtk/nxtk_events.c | 43 +++++++++++++++++++++++++++++++---- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/graphics/nxmu/nxmu_mouse.c b/graphics/nxmu/nxmu_mouse.c index 641fec7bcb..58e642b6d8 100644 --- a/graphics/nxmu/nxmu_mouse.c +++ b/graphics/nxmu/nxmu_mouse.c @@ -54,6 +54,10 @@ * Private Data ****************************************************************************/ +/* REVISIT: These globals will prevent this code from being used in an + * environment with more than one display. FIX ME! + */ + static struct nxgl_point_s g_mpos; static struct nxgl_point_s g_mrange; static uint8_t g_mbutton; @@ -198,7 +202,7 @@ int nxmu_mousein(FAR struct nxmu_state_s *nxmu, y = g_mrange.y - 1; } - /* Look any change in values */ + /* Look for any change in values */ if (x != g_mpos.x || y != g_mpos.y || buttons != g_mbutton) { @@ -211,13 +215,13 @@ int nxmu_mousein(FAR struct nxmu_state_s *nxmu, /* If a button is already down, regard this as part of a mouse drag * event. Pass all the following events to the window where the drag - * started in. + * started in, including the final button release event. */ - if (oldbuttons) + if (oldbuttons != 0) { g_mwnd = nxmu_revalidate_g_mwnd(nxmu->be.topwnd); - if (g_mwnd && g_mwnd->cb->mousein) + if (g_mwnd != NULL && g_mwnd->cb->mousein) { struct nxclimsg_mousein_s outmsg; outmsg.msgid = NX_CLIMSG_MOUSEIN; diff --git a/libs/libnx/nxmu/nx_mousein.c b/libs/libnx/nxmu/nx_mousein.c index 28014564c3..86344b0ca7 100644 --- a/libs/libnx/nxmu/nx_mousein.c +++ b/libs/libnx/nxmu/nx_mousein.c @@ -67,7 +67,7 @@ int nx_mousein(NXHANDLE handle, nxgl_coord_t x, nxgl_coord_t y, uint8_t buttons) FAR struct nxmu_conn_s *conn = (FAR struct nxmu_conn_s *)handle; struct nxsvrmsg_mousein_s outmsg; - /* Inform the server that this client no longer exists */ + /* Inform the server of the new mouse position */ outmsg.msgid = NX_SVRMSG_MOUSEIN; outmsg.pt.x = x; diff --git a/libs/libnx/nxtk/nxtk_events.c b/libs/libnx/nxtk/nxtk_events.c index deaa860f4c..89aaa2ecb3 100644 --- a/libs/libnx/nxtk/nxtk_events.c +++ b/libs/libnx/nxtk/nxtk_events.c @@ -204,7 +204,7 @@ static void nxtk_position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, #ifdef CONFIG_NX_XYINPUT static void nxtk_mousein(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos, - uint8_t buttons, FAR void *arg) + uint8_t buttons, FAR void *arg) { FAR struct nxtk_framedwindow_s *fwnd = (FAR struct nxtk_framedwindow_s *)hwnd; struct nxgl_point_s abspos; @@ -256,15 +256,50 @@ static void nxtk_mousein(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos, /* Is the mouse position inside of the client window region? */ - if (fwnd->fwcb->mousein && nxgl_rectinside(&fwnd->fwrect, &fwnd->mpos)) + if (fwnd->fwcb->mousein != NULL && + nxgl_rectinside(&fwnd->fwrect, &fwnd->mpos)) { nxgl_vectsubtract(&relpos, &abspos, &fwnd->fwrect.pt1); fwnd->fwcb->mousein((NXTKWINDOW)fwnd, &relpos, buttons, fwnd->fwarg); } - /* If the mouse position inside the toobar region? */ + /* If the mouse position inside the toolbar region? */ - else if (fwnd->tbcb->mousein && nxgl_rectinside(&fwnd->tbrect, &fwnd->mpos)) + else if (fwnd->tbcb->mousein != NULL && + nxgl_rectinside(&fwnd->tbrect, &fwnd->mpos)) + { + nxgl_vectsubtract(&relpos, &abspos, &fwnd->tbrect.pt1); + fwnd->tbcb->mousein((NXTKWINDOW)fwnd, &relpos, buttons, fwnd->tbarg); + } + + /* REVISIT: Missing logic to detect border events. + * + * NOTE that the following logic is completely redundant! All of the + * above tests could be eliminated and only the following performed with + * the same result. These tests are separated from the above only to + * guarantee a spot for future border mouse event event detection which + * would go about here. + */ + + /* As a complexity, when dragging mouse events outside of the containing + * raw window will be sent to this function as well. We will need to pass + * these outside-the-window reports as well. + * + * If the mouse report is below the toolbar, then we will report this + * as a main window event. + */ + + else if (fwnd->fwcb->mousein != NULL && + pos->y >= fwnd->tbheight + CONFIG_NXTK_BORDERWIDTH) + { + nxgl_vectsubtract(&relpos, &abspos, &fwnd->fwrect.pt1); + fwnd->fwcb->mousein((NXTKWINDOW)fwnd, &relpos, buttons, fwnd->fwarg); + } + + /* Otherwise, we will report this as a toolbar event. */ + + else if (fwnd->tbcb->mousein != NULL && + pos->y < fwnd->tbheight + CONFIG_NXTK_BORDERWIDTH) { nxgl_vectsubtract(&relpos, &abspos, &fwnd->tbrect.pt1); fwnd->tbcb->mousein((NXTKWINDOW)fwnd, &relpos, buttons, fwnd->tbarg);