From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Manuel Giraud via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#64440: 30.0.50; [PATCH] Highlight on non toolkit menu bar items Date: Mon, 11 Sep 2023 22:51:31 +0200 Message-ID: <87sf7kh1rg.fsf@ledu-giraud.fr> References: <87zg4d56l8.fsf@ledu-giraud.fr> <87ilaz1wol.fsf@ledu-giraud.fr> <87fs3xo13z.fsf@yahoo.com> <83zg259iwz.fsf@gnu.org> <878r9losil.fsf@ledu-giraud.fr> <83tts2scvp.fsf@gnu.org> <87cyyo28m0.fsf@ledu-giraud.fr> <83cyyorfnr.fsf@gnu.org> <87r0n4sqm8.fsf@ledu-giraud.fr> <835y4gr9ao.fsf@gnu.org> <87jzswsfmi.fsf@ledu-giraud.fr> <83v8cgplqo.fsf@gnu.org> Reply-To: Manuel Giraud Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="14203"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: luangruo@yahoo.com, stefankangas@gmail.com, 64440@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Sep 11 22:52:53 2023 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qfnti-000314-As for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 11 Sep 2023 22:52:42 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qfnt2-0007FU-80; Mon, 11 Sep 2023 16:52:00 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qfnsz-0007FJ-Rl for bug-gnu-emacs@gnu.org; Mon, 11 Sep 2023 16:51:57 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qfnsz-0000yY-Jw for bug-gnu-emacs@gnu.org; Mon, 11 Sep 2023 16:51:57 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qfnt3-0004nO-Ml for bug-gnu-emacs@gnu.org; Mon, 11 Sep 2023 16:52:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Manuel Giraud Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 11 Sep 2023 20:52:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 64440 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 64440-submit@debbugs.gnu.org id=B64440.169446550318410 (code B ref 64440); Mon, 11 Sep 2023 20:52:01 +0000 Original-Received: (at 64440) by debbugs.gnu.org; 11 Sep 2023 20:51:43 +0000 Original-Received: from localhost ([127.0.0.1]:54938 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qfnsl-0004mr-20 for submit@debbugs.gnu.org; Mon, 11 Sep 2023 16:51:43 -0400 Original-Received: from ledu-giraud.fr ([51.159.28.247]:43477) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qfnsh-0004mf-72 for 64440@debbugs.gnu.org; Mon, 11 Sep 2023 16:51:41 -0400 DKIM-Signature: v=1; a=ed25519-sha256; c=simple/simple; s=ed25519; bh=jg0b/10i Oa8k9hv2+4yJeNeNXdu2FNdZPlTy+YsjYK4=; h=date:references:in-reply-to: subject:cc:to:from; d=ledu-giraud.fr; b=HeY9t0aDX7m87UT2OHhhXvnDcefYiE +cyV69Dy6CrODYcu0SX1VzCDXsCdEOLo+Hn9cLYT+9LDf/JrZs/NLFDg== DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; s=rsa; bh=jg0b/10iOa8k9hv2 +4yJeNeNXdu2FNdZPlTy+YsjYK4=; h=date:references:in-reply-to:subject: cc:to:from; d=ledu-giraud.fr; b=dPILyXMaUluaBuUx90KfxTjuaoEIZnONBWcUe4 q5rREjWwhYaMgnMWF4tKvYL4/PhHX1lIwZFO72mRXDv/q1B3L00V/HFoCqjfEPZDaGMzVl N04MWQ/tyinu674FbB4jYzQLpB2ISrGUxBNE4VkroKE2+K5ozgMeAtjs27vdEbwOPYR8n4 e2pYRCA2m6oPr4b8MF5b3YTEcGxoBUoZP6wUD/YxPq/H9gcFMiXr8wzZ6nBTSBxe/0NSqG 4ZhWs/ptA9dri6lc1sxPr75S15IFf4L3COwTClt2LhRX1h0Z0hTlZahbi5HfMBsa+0epo4 hr6BuMj+TsfQ1VCRefohL2sQ== Original-Received: from computer ( [10.1.1.1]) by ledu-giraud.fr (OpenSMTPD) with ESMTPSA id 17d7636d (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 11 Sep 2023 22:51:32 +0200 (CEST) In-Reply-To: <83v8cgplqo.fsf@gnu.org> (Eli Zaretskii's message of "Mon, 11 Sep 2023 22:12:47 +0300") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:270083 Archived-At: Eli Zaretskii writes: >> From: Manuel Giraud >> Cc: luangruo@yahoo.com, stefankangas@gmail.com, 64440@debbugs.gnu.org >> Date: Mon, 11 Sep 2023 20:56:37 +0200 >> >> Eli Zaretskii writes: >> >> [...] >> >> > Thanks. That's what I imagined we have there. So I guess considering >> > that a string ends where is SCHARS end is reasonable. >> > >> > But note that the above means you could also detect where each item >> > ends by looking for the glyph whose string position is -1. So maybe >> > add an assertion there that the glyph after the last character has its >> > position as -1, in case we could have some complications there with >> > double-width characters or something. >> >> What do you think of this: >> >> + /* Convert to pixels bounds. */ >> + row = MATRIX_ROW (w->current_matrix, *vpos); >> + *x_start = 0; >> + for (i = 0; i < *h_start; ++i) >> + *x_start += row->glyphs[TEXT_AREA][i].pixel_width; >> + >> + *x_end = *x_start; >> + for (i = *h_start; CHARPOS (row->glyphs[TEXT_AREA][i]) != -1; ++i) >> + *x_end += row->glyphs[TEXT_AREA][i].pixel_width; > > That's OK, but I think we should also make sure 'i' never exceeds the > value row->used[TEXT_AREA] - 1. This is only important for the last > item, but still. > > And I would also add an assertion that row->reversed_p is false. We > don't currently support R2L menu bars, but if we ever do, the above > loops should go backwards in such glyph rows. Ok. Here is the full version of the second patch: >From 4420fde7757a9b02087c4330c6102cb40c9e4038 Mon Sep 17 00:00:00 2001 From: Manuel Giraud Date: Mon, 3 Jul 2023 17:35:06 +0200 Subject: [PATCH 2/2] Highlight on non toolkit menu bar items * src/xdisp.c (get_menu_bar_item, note_menu_bar_highlight): New functions to highlight item in the menu-bar. (note_mouse_highlight): Use it. --- src/xdisp.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/src/xdisp.c b/src/xdisp.c index ca7e3b9743e..b194837e69c 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -13922,6 +13922,131 @@ update_menu_bar (struct frame *f, bool save_match_data, bool hooks_run) return hooks_run; } +#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR + +/* Get information about the menu-bar item at position X/Y on frame F. + Return menu-bar's item char position in H_START/H_END and pixel + position in X_START/X_END. Value is + + -1 if X/Y is not on a menu-bar item + 0 if X/Y is on the same item that was highlighted before. + 1 otherwise. */ + +static int +get_menu_bar_item (struct frame *f, int x, int y, int *h_start, int *h_end, + int *x_start, int *x_end, int *vpos) +{ + Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); + struct window *w = XWINDOW (f->menu_bar_window); + struct glyph_row *row; + int dummy; + Lisp_Object items; + int i; + + /* Find glyph's hpos and vpos under X/Y. */ + if (x_y_to_hpos_vpos (w, x, y, h_start, vpos, NULL, NULL, &dummy) == NULL) + return -1; + + /* We do not support R2L menu bar. */ + row = MATRIX_ROW (w->current_matrix, *vpos); + if (row->reversed_p) + return -1; + + /* Compute h_start and h_end for this menu bar item. */ + items = FRAME_MENU_BAR_ITEMS (f); + for (i = 0; i < ASIZE (items); i += 4) + { + Lisp_Object pos, string; + string = AREF (items, i + 1); + pos = AREF (items, i + 3); + if (NILP (string)) + return -1; + if (*h_start >= XFIXNUM (pos) + && *h_start < XFIXNUM (pos) + SCHARS (string)) + { + *h_start = XFIXNUM (pos); + *h_end = *h_start + SCHARS (string); + break; + } + } + + /* Convert to pixels bounds. */ + *x_start = 0; + for (i = 0; i < *h_start; ++i) + *x_start += row->glyphs[TEXT_AREA][i].pixel_width; + + *x_end = *x_start; + for (i = *h_start; + CHARPOS (row->glyphs[TEXT_AREA][i]) != -1 + && i < row->used[TEXT_AREA]; + ++i) + *x_end += row->glyphs[TEXT_AREA][i].pixel_width; + + /* Is mouse on the highlighted item? */ + if (EQ (f->menu_bar_window, hlinfo->mouse_face_window) + && *vpos >= hlinfo->mouse_face_beg_row + && *vpos <= hlinfo->mouse_face_end_row + && (*vpos > hlinfo->mouse_face_beg_row + || *h_start >= hlinfo->mouse_face_beg_col) + && (*vpos < hlinfo->mouse_face_end_row + || *h_end < hlinfo->mouse_face_end_col + || hlinfo->mouse_face_past_end)) + return 0; + + return 1; +} + +/* Possibly highlight a menu-bar item on frame F when mouse moves to + menu-bar window-relative coordinates X/Y. Called from + note_mouse_highlight. */ + +static void +note_menu_bar_highlight (struct frame *f, int x, int y) +{ + Lisp_Object window = f->menu_bar_window; + Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); + int h_start, h_end, vpos, x_start, x_end; + int rc; + + /* Function note_mouse_highlight is called with negative X/Y + values when mouse moves outside of the frame. */ + if (x <= 0 || y <= 0) + { + clear_mouse_face (hlinfo); + return; + } + + h_start = h_end = 0; + rc = get_menu_bar_item (f, x, y, &h_start, &h_end, &x_start, &x_end, &vpos); + if (rc < 0) + { + /* Not on menu-bar item. */ + clear_mouse_face (hlinfo); + return; + } + else if (rc == 0) + /* On same menu-bar item as before. */ + return; + + if (!NILP (Vmouse_highlight)) + { + /* Record this as the current active region. */ + hlinfo->mouse_face_beg_col = h_start; + hlinfo->mouse_face_beg_row = vpos; + hlinfo->mouse_face_beg_x = x_start; + hlinfo->mouse_face_past_end = false; + + hlinfo->mouse_face_end_col = h_end; + hlinfo->mouse_face_end_row = vpos; + hlinfo->mouse_face_end_x = x_end; + hlinfo->mouse_face_window = window; + hlinfo->mouse_face_face_id = MENU_FACE_ID; + + /* Display it as active. */ + show_mouse_face (hlinfo, DRAW_MOUSE_FACE); + } +} +#endif /*********************************************************************** @@ -35538,6 +35663,16 @@ note_mouse_highlight (struct frame *f, int x, int y) w = XWINDOW (window); frame_to_window_pixel_xy (w, &x, &y); +#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR + /* Handle menu-bar window differently since it doesn't display a + buffer. */ + if (EQ (window, f->menu_bar_window)) + { + note_menu_bar_highlight (f, x, y); + return; + } +#endif + #if defined (HAVE_WINDOW_SYSTEM) /* Handle tab-bar window differently since it doesn't display a buffer. */ -- 2.40.0 -- Manuel Giraud