Subject: bug#59351: 29.0.50; [PATCH] Fix mouse click position to menu bar entry

From: Manuel Giraud <[email-masked]>
Date: Fri, 18 Nov 2022 09:37:20 +0100

Hi,

So here is a patch that I think fixes the calculation of the menu bar
entry to activate from the mouse click in menu bar with the no toolkit
build.

Issue: Before this patch, if you change the font of the menu face (for
instance with (set-face-font 'menu "SomeOtherFontOfDifferentSize")), a
click in the menu bar won't activate the correct entry.

What is not in this patch: The height of the menu bar is not
recalculated correctly.

>>From 100ed84198cd97664a94e89d1730e97b1fabbbb9 Mon Sep 17 00:00:00 2001
From: Manuel Giraud <[email-masked]>
Date: Fri, 14 Oct 2022 16:24:10 +0200
Subject: [PATCH] Fix menu bar height for --with-x-toolkit=no

* src/xterm.c (x_menu_bar_height): New function to compute menu
bar height with menu face and boxed information.
(x_new_font): Use it.

* src/xfns.c (x_set_menu_bar_lines): Use it.
---
 src/xfns.c  |  2 +-
 src/xterm.c | 25 ++++++++++++++++++++++++-
 src/xterm.h |  1 +
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/xfns.c b/src/xfns.c
index 9112448899..3d93a6a207 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1674,7 +1674,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
     }
 #else /* not USE_X_TOOLKIT && not USE_GTK */
   FRAME_MENU_BAR_LINES (f) = nlines;
-  FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
+  FRAME_MENU_BAR_HEIGHT (f) = nlines * x_menu_bar_height (f);
   if (FRAME_X_WINDOW (f))
     x_clear_under_internal_border (f);
 
diff --git a/src/xterm.c b/src/xterm.c
index 9059ad7136..c3bc494667 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -25464,6 +25464,29 @@ x_io_error_quitter (Display *display)
 
 /* Changing the font of the frame.  */
 
+int
+x_menu_bar_height (struct frame *f)
+{
+  int font_ascent = 0;
+  int font_descent = 0;
+  int height = 0;
+
+  recompute_basic_faces (f);
+  if (FRAME_FACE_CACHE (f))
+    {
+      struct face *face = FACE_FROM_ID_OR_NULL (f, MENU_FACE_ID);
+      if (face && face->font)
+	{
+	  height += (face->box_horizontal_line_width > 0)
+	    ? (face->box_horizontal_line_width * 2)
+	    : 0;
+	  get_font_ascent_descent (face->font, &font_ascent, &font_descent);
+	}
+    }
+
+  return (height + font_ascent + font_descent);
+}
+
 /* Give frame F the font FONT-OBJECT as its default font.  The return
    value is FONT-OBJECT.  FONTSET is an ID of the fontset for the
    frame.  If it is negative, generate a new fontset from
@@ -25490,7 +25513,7 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
   FRAME_LINE_HEIGHT (f) = font_ascent + font_descent;
 
 #ifndef USE_X_TOOLKIT
-  FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
+  FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * x_menu_bar_height (f);
 #endif
   /* We could use a more elaborate calculation here.  */
   FRAME_TAB_BAR_HEIGHT (f) = FRAME_TAB_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
diff --git a/src/xterm.h b/src/xterm.h
index b68a234faa..5b914d48da 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1595,6 +1595,7 @@ #define SELECTION_EVENT_TIME(eventp)	\
 extern void x_ignore_errors_for_next_request (struct x_display_info *);
 extern void x_stop_ignoring_errors (struct x_display_info *);
 extern void x_clear_errors (Display *);
+extern int x_menu_bar_height (struct frame *);
 extern void x_set_window_size (struct frame *, bool, int, int);
 extern void x_set_last_user_time_from_lisp (struct x_display_info *, Time);
 extern void x_make_frame_visible (struct frame *);
-- 
2.38.0

Thanks,

In GNU Emacs 29.0.50 (build 1, x86_64-unknown-openbsd7.2, cairo version
 1.17.6) of 2022-11-18 built on elite.giraud
Repository revision: 61b9f2c3179aa454963493e1923307e875e2322a
Repository branch: mgi/update-menu-bar-height
Windowing system distributor 'The X.Org Foundation', version 11.0.12101004
System Description: OpenBSD elite.giraud 7.2 GENERIC.MP#835 amd64

Configured using:
 'configure --prefix=/home/manuel/emacs --bindir=/home/manuel/bin
 --with-x-toolkit=no --without-sound --without-compress-install
 CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib'

Configured features:
CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON
LCMS2 LIBOTF LIBXML2 MODULES NOTIFY KQUEUE OLDXMENU PDUMPER PNG RSVG
SQLITE3 THREADS TIFF WEBP X11 XDBE XIM XINPUT2 XPM ZLIB

Important settings:
  value of $LC_ALL: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Dired by name

Minor modes in effect:
  gnus-dired-mode: t
  global-git-commit-mode: t
  magit-auto-revert-mode: t
  display-time-mode: t
  display-battery-mode: t
  server-mode: t
  shell-dirtrack-mode: t
  global-so-long-mode: t
  repeat-mode: t
  global-eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  buffer-read-only: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
/home/manuel/.el/exwm/exwm hides /home/manuel/.emacs.d/elpa/exwm-0.27/exwm
/home/manuel/.el/exwm/exwm-xim hides /home/manuel/.emacs.d/elpa/exwm-0.27/exwm-xim
/home/manuel/.el/exwm/exwm-workspace hides /home/manuel/.emacs.d/elpa/exwm-0.27/exwm-workspace
/home/manuel/.el/exwm/exwm-systemtray hides /home/manuel/.emacs.d/elpa/exwm-0.27/exwm-systemtray
/home/manuel/.el/exwm/exwm-randr hides /home/manuel/.emacs.d/elpa/exwm-0.27/exwm-randr
/home/manuel/.el/exwm/exwm-manage hides /home/manuel/.emacs.d/elpa/exwm-0.27/exwm-manage
/home/manuel/.el/exwm/exwm-layout hides /home/manuel/.emacs.d/elpa/exwm-0.27/exwm-layout
/home/manuel/.el/exwm/exwm-input hides /home/manuel/.emacs.d/elpa/exwm-0.27/exwm-input
/home/manuel/.el/exwm/exwm-floating hides /home/manuel/.emacs.d/elpa/exwm-0.27/exwm-floating
/home/manuel/.el/exwm/exwm-core hides /home/manuel/.emacs.d/elpa/exwm-0.27/exwm-core
/home/manuel/.el/exwm/exwm-config hides /home/manuel/.emacs.d/elpa/exwm-0.27/exwm-config
/home/manuel/.el/exwm/exwm-cm hides /home/manuel/.emacs.d/elpa/exwm-0.27/exwm-cm
/home/manuel/.emacs.d/elpa/transient-20221028.1430/transient hides /home/manuel/emacs/share/emacs/29.0.50/lisp/transient

Features:
(shadow sort mail-extr emacsbug whitespace gnus-dired magit-patch
dabbrev executable vc-git vc-dispatcher vc-svn bug-reference
magit-extras face-remap magit-bookmark magit-submodule magit-obsolete
magit-blame magit-stash magit-reflog magit-bisect magit-push magit-pull
magit-fetch magit-clone magit-remote magit-commit magit-sequence
magit-notes magit-worktree magit-tag magit-merge magit-branch
magit-reset magit-files magit-refs magit-status magit magit-repos
magit-apply magit-wip magit-log which-func imenu magit-diff smerge-mode
diff diff-mode git-commit log-edit pcvs-util add-log magit-core
magit-autorevert autorevert filenotify magit-margin magit-transient
magit-process with-editor magit-mode transient magit-git magit-base
magit-section dash compat-27 compat-26 compat compat-macs tmm cus-start
pulse tutorial paredit edmacro time battery exwm-randr xcb-randr
exwm-config exwm exwm-input xcb-keysyms xcb-xkb exwm-manage
exwm-floating xcb-cursor xcb-render exwm-layout exwm-workspace exwm-core
xcb-ewmh xcb-icccm xcb xcb-xproto xcb-types xcb-debug kmacro server
stimmung-themes modus-operandi-theme modus-themes ytdious osm mingus
libmpdee reporter edebug debug backtrace transmission diary-lib
diary-loaddefs color calc-bin calc-ext calc calc-loaddefs rect calc-macs
w3m-load mu4e mu4e-org mu4e-main mu4e-view mu4e-headers mu4e-compose
mu4e-draft mu4e-actions smtpmail mu4e-search mu4e-lists mu4e-bookmarks
mu4e-mark mu4e-message flow-fill mule-util hl-line mu4e-contacts
mu4e-update mu4e-folders mu4e-server mu4e-context mu4e-vars mu4e-helpers
mu4e-config bookmark ido supercite regi ebdb-message ebdb-gnus nnselect
gnus-msg gnus-art mm-uu mml2015 mm-view mml-smime smime gnutls dig
gnus-sum shr pixel-fill kinsoku url-file svg dom gnus-group gnus-undo
gnus-start gnus-dbus gnus-cloud nnimap nnmail mail-source utf7 nnoo
gnus-spec gnus-int gnus-range message sendmail yank-media puny rfc822
mml mml-sec epa epg rfc6068 epg-config mm-decode mm-bodies mm-encode
mail-parse rfc2231 rfc2047 rfc2045 ietf-drums gmm-utils mailheader
gnus-win gnus nnheader gnus-util mail-utils range mm-util mail-prsvr
ebdb-mua ebdb-com crm ebdb-format ebdb inline mailabbrev eieio-opt
cl-extra help-mode speedbar ezimage dframe eieio-base pcase timezone org
ob ob-tangle ob-ref ob-lob ob-table ob-exp org-macro org-footnote
org-src ob-comint org-pcomplete org-list org-faces org-entities
org-version ob-emacs-lisp ob-core ob-eval org-table oc-basic bibtex ol
org-keys oc org-compat org-macs org-loaddefs find-func cal-menu calendar
cal-loaddefs visual-basic-mode cl web-mode derived disp-table
erlang-start smart-tabs-mode skeleton cc-mode cc-fonts cc-guess cc-menus
cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs slime-asdf grep
slime-tramp tramp tramp-loaddefs trampver tramp-integration cus-edit
cus-load wid-edit files-x tramp-compat rx shell pcomplete parse-time
iso8601 time-date ls-lisp format-spec slime-fancy slime-indentation
slime-cl-indent cl-indent slime-trace-dialog slime-fontifying-fu
slime-package-fu slime-references slime-compiler-notes-tree advice
slime-scratch slime-presentations bridge slime-macrostep macrostep
slime-mdot-fu slime-enclosing-context slime-fuzzy slime-fancy-trace
slime-fancy-inspector slime-c-p-c slime-editing-commands slime-autodoc
slime-repl slime-parse slime compile text-property-search etags fileloop
generator xref project arc-mode archive-mode noutline outline icons pp
comint ansi-osc ansi-color ring hyperspec thingatpt slime-autoloads
dired-aux dired-x dired dired-loaddefs so-long notifications dbus xml
repeat easy-mmode rust-mode-autoloads stimmung-themes-autoloads
debbugs-autoloads paredit-autoloads ebdb-autoloads ef-themes-autoloads
ytdious-autoloads auctex-autoloads tex-site exwm-autoloads
hyperbole-autoloads magit-autoloads magit-section-autoloads
git-commit-autoloads with-editor-autoloads transient-autoloads
dash-autoloads compat-autoloads info package browse-url url url-proxy
url-privacy url-expand url-methods url-history url-cookie
generate-lisp-file url-domsuf url-util mailcap url-handlers url-parse
auth-source cl-seq eieio eieio-core cl-macs password-cache json subr-x
map byte-opt gv bytecomp byte-compile url-vars cl-loaddefs cl-lib rmc
iso-transl tooltip cconv eldoc paren electric uniquify ediff-hook
vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win
term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode lisp-mode prog-mode register
page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads dbusbind kqueue lcms2 dynamic-setting system-font-setting
font-render-setting cairo xinput2 x multi-tty make-network-process
emacs)

Memory information:
((conses 16 756398 76643)
 (symbols 48 57143 2)
 (strings 32 169527 9002)
 (string-bytes 1 5556598)
 (vectors 16 101653)
 (vector-slots 8 1331942 88236)
 (floats 8 528 478)
 (intervals 56 10690 906)
 (buffers 984 26))

-- 
Manuel Giraud