Subject: bug#58515: 29.0.50; [PATCH] Fix menu bar height

From: Manuel Giraud <[email-masked]>
Date: Fri, 14 Oct 2022 16:42:36 +0200

Hi,

This patch tries to fix height calculation for menu bar in X when not
using a toolkit.  It is taking into account the fact that the menu bar
face could be boxed.

There are others issues left (i.e. not handled by this patch):

      - a customization of the menu face does not trigger a redisplay,
        so one has to deactivate/re-activate the menu bar in order to
        update (I don't know how this is done for other faces)
        
      - with a boxed menu bar face, the box is not displayed correctly
        on the right side of the bar

>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

Best regards,

In GNU Emacs 29.0.50 (build 1, x86_64-unknown-openbsd7.2, cairo version
 1.17.6) of 2022-10-14 built on elite.giraud
Repository revision: 820e6f399d0af56ebfdc581f68424f4cb9cbe53b
Repository branch: mgi/play
Windowing system distributor 'The X.Org Foundation', version 11.0.12101004
System Description: OpenBSD elite.giraud 7.2 GENERIC.MP#778 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: Change Log

Minor modes in effect:
  global-git-commit-mode: t
  magit-auto-revert-mode: t
  icomplete-mode: t
  display-time-mode: t
  display-battery-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
  line-number-mode: t
  auto-fill-function: do-auto-fill
  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.26/exwm
/home/manuel/.el/exwm/exwm-xim hides /home/manuel/.emacs.d/elpa/exwm-0.26/exwm-xim
/home/manuel/.el/exwm/exwm-workspace hides /home/manuel/.emacs.d/elpa/exwm-0.26/exwm-workspace
/home/manuel/.el/exwm/exwm-randr hides /home/manuel/.emacs.d/elpa/exwm-0.26/exwm-randr
/home/manuel/.el/exwm/exwm-manage hides /home/manuel/.emacs.d/elpa/exwm-0.26/exwm-manage
/home/manuel/.el/exwm/exwm-layout hides /home/manuel/.emacs.d/elpa/exwm-0.26/exwm-layout
/home/manuel/.el/exwm/exwm-input hides /home/manuel/.emacs.d/elpa/exwm-0.26/exwm-input
/home/manuel/.el/exwm/exwm-floating hides /home/manuel/.emacs.d/elpa/exwm-0.26/exwm-floating
/home/manuel/.el/exwm/exwm-core hides /home/manuel/.emacs.d/elpa/exwm-0.26/exwm-core
/home/manuel/.el/exwm/exwm-config hides /home/manuel/.emacs.d/elpa/exwm-0.26/exwm-config
/home/manuel/.el/exwm/exwm-cm hides /home/manuel/.emacs.d/elpa/exwm-0.26/exwm-cm
/home/manuel/.el/exwm/exwm-systemtray hides /home/manuel/.emacs.d/elpa/exwm-0.26/exwm-systemtray
/home/manuel/.emacs.d/elpa/transient-20220918.2101/transient hides /home/manuel/emacs/share/emacs/29.0.50/lisp/transient

Features:
(shadow sort mail-extr emacsbug whitespace gnus-dired magit-patch
sh-script smie hideshow executable find-dired ffap misearch
multi-isearch vc-git vc-dispatcher vc-svn bug-reference tmm cus-start
pulse 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
paredit edmacro icomplete 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 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 mailabbrev eieio-opt 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
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 slime-scratch slime-presentations advice
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 elp slime-parse slime
derived cl-extra help-mode lisp-mnt gud apropos 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
auctex-autoloads tex-site boxquote-autoloads debbugs-autoloads
hyperbole-autoloads magit-autoloads git-commit-autoloads
magit-section-autoloads dash-autoloads paredit-autoloads
rust-mode-autoloads stimmung-themes-autoloads transient-autoloads
with-editor-autoloads info compat-autoloads ytdious-autoloads 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 cconv url-vars
cl-loaddefs cl-lib rmc iso-transl tooltip 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 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 811685 71052)
 (symbols 48 57973 6)
 (strings 32 176669 9548)
 (string-bytes 1 5791024)
 (vectors 16 102826)
 (vector-slots 8 1742825 122739)
 (floats 8 530 454)
 (intervals 56 16815 580)
 (buffers 1000 36))

-- 
Manuel Giraud