Subject: bug#64440: 30.0.50; [PATCH] Highlight on non toolkit menu bar items

From: Manuel Giraud <[email-masked]>
Date: Fri, 06 Oct 2023 17:59:27 +0200

So here is the new version of the first patch.  The second still applies
onto it.
-- 
Manuel Giraud
>From e4481544b4ce87af2bbc42980d96d35fa8d4a7b8 Mon Sep 17 00:00:00 2001
From: Manuel Giraud <[email-masked]>
Date: Fri, 6 Oct 2023 17:54:15 +0200
Subject: [PATCH] Possibility to get enter event from menu_bar window

---
 src/androidterm.c | 10 +++++-----
 src/haikuterm.c   |  8 ++++----
 src/keyboard.c    |  2 +-
 src/msdos.c       |  2 +-
 src/nsterm.m      |  4 ++--
 src/pgtkterm.c    |  4 ++--
 src/w32inevt.c    |  2 +-
 src/w32term.c     |  8 ++++----
 src/window.c      | 20 ++++++++++++++++++--
 src/window.h      |  2 +-
 src/xdisp.c       |  4 ++--
 src/xterm.c       | 17 +++++++++--------
 12 files changed, 50 insertions(+), 33 deletions(-)

diff --git a/src/androidterm.c b/src/androidterm.c
index 9b00ad85642..d6db1359d97 100644
--- a/src/androidterm.c
+++ b/src/androidterm.c
@@ -1142,7 +1142,7 @@ handle_one_android_event (struct android_display_info *dpyinfo,
 	      Lisp_Object window
 		= window_from_coordinates (f, event->xmotion.x,
 					   event->xmotion.y, 0,
-					   false, false);
+					   false, false, false);
 
 	      /* A window will be autoselected only when it is not
 		 selected now and the last mouse movement event was
@@ -1291,7 +1291,7 @@ handle_one_android_event (struct android_display_info *dpyinfo,
 	      int x = event->xbutton.x;
 	      int y = event->xbutton.y;
 
-	      window = window_from_coordinates (f, x, y, 0, true, true);
+	      window = window_from_coordinates (f, x, y, 0, true, true, true);
 	      tab_bar_p = EQ (window, f->tab_bar_window);
 
 	      if (tab_bar_p)
@@ -1313,7 +1313,7 @@ handle_one_android_event (struct android_display_info *dpyinfo,
 	      int x = event->xbutton.x;
 	      int y = event->xbutton.y;
 
-	      window = window_from_coordinates (f, x, y, 0, true, true);
+	      window = window_from_coordinates (f, x, y, 0, true, true, true);
 	      tool_bar_p = (EQ (window, f->tool_bar_window)
 			    && ((event->xbutton.type
 				 != ANDROID_BUTTON_RELEASE)
@@ -1409,7 +1409,7 @@ handle_one_android_event (struct android_display_info *dpyinfo,
 	  int y = event->touch.y;
 
 	  window = window_from_coordinates (any, x, y, 0, true,
-					    true);
+					    true, true);
 
 	  /* If this touch has started in the tool bar, do not
 	     send it to Lisp.  Instead, simulate a tool bar
@@ -1606,7 +1606,7 @@ handle_one_android_event (struct android_display_info *dpyinfo,
 	  /* Figure out how much to scale the deltas by.  */
 	  window = window_from_coordinates (any, event->wheel.x,
 					    event->wheel.y, NULL,
-					    false, false);
+					    false, false, false);
 
 	  if (WINDOWP (window))
 	    scroll_height = XWINDOW (window)->pixel_height;
diff --git a/src/haikuterm.c b/src/haikuterm.c
index b1a016b49a9..bcb5055ea42 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -3472,7 +3472,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
 		if (!NILP (Vmouse_autoselect_window))
 		  {
 		    static Lisp_Object last_mouse_window;
-		    Lisp_Object window = window_from_coordinates (f, b->x, b->y, 0, 0, 0);
+		    Lisp_Object window = window_from_coordinates (f, b->x, b->y, 0, 0, 0, 0);
 
 		    if (WINDOWP (window)
 			&& !EQ (window, last_mouse_window)
@@ -3555,7 +3555,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
 		int x = b->x;
 		int y = b->y;
 
-		window = window_from_coordinates (f, x, y, 0, true, true);
+		window = window_from_coordinates (f, x, y, 0, true, true, true);
 		tab_bar_p = EQ (window, f->tab_bar_window);
 
 		if (tab_bar_p)
@@ -3573,7 +3573,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
 		int x = b->x;
 		int y = b->y;
 
-		window = window_from_coordinates (f, x, y, 0, true, true);
+		window = window_from_coordinates (f, x, y, 0, true, true, true);
 		tool_bar_p = (EQ (window, f->tool_bar_window)
 			      && (type != BUTTON_UP
 				  || f->last_tool_bar_item != -1));
@@ -3834,7 +3834,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
 
 	    BView_get_mouse (FRAME_HAIKU_VIEW (f), &x, &y);
 
-	    wheel_window = window_from_coordinates (f, x, y, 0, false, false);
+	    wheel_window = window_from_coordinates (f, x, y, 0, false, false, false);
 
 	    if (NILP (wheel_window))
 	      {
diff --git a/src/keyboard.c b/src/keyboard.c
index f756f163e87..fc567488e7c 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5549,7 +5549,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
   int xret = 0, yret = 0;
   /* The window or frame under frame pixel coordinates (x,y)  */
   Lisp_Object window_or_frame = f
-    ? window_from_coordinates (f, mx, my, &part, true, true)
+    ? window_from_coordinates (f, mx, my, &part, true, true, true)
     : Qnil;
 #ifdef HAVE_WINDOW_SYSTEM
   bool tool_bar_p = false;
diff --git a/src/msdos.c b/src/msdos.c
index 1b7f2d4ae21..5dd7c1573c4 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -2662,7 +2662,7 @@ dos_rawgetc (void)
 	      static Lisp_Object last_mouse_window;
 
 	      mouse_window = window_from_coordinates
-		(SELECTED_FRAME (), mouse_last_x, mouse_last_y, 0, 0, 0);
+		(SELECTED_FRAME (), mouse_last_x, mouse_last_y, 0, 0, 0, 0);
 	      /* A window will be selected only when it is not
 		 selected now, and the last mouse movement event was
 		 not in it.  A minibuffer window will be selected iff
diff --git a/src/nsterm.m b/src/nsterm.m
index 4e0dfa58c63..96661b8e227 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -7404,7 +7404,7 @@ - (void)mouseDown: (NSEvent *)theEvent
 	  int x = lrint (p.x);
 	  int y = lrint (p.y);
 
-	  window = window_from_coordinates (emacsframe, x, y, 0, true, true);
+	  window = window_from_coordinates (emacsframe, x, y, 0, true, true, true);
 	  tab_bar_p = EQ (window, emacsframe->tab_bar_window);
 
 	  if (tab_bar_p)
@@ -7510,7 +7510,7 @@ - (void)mouseMoved: (NSEvent *)e
       NSTRACE_MSG ("mouse_autoselect_window");
       static Lisp_Object last_mouse_window;
       Lisp_Object window
-	= window_from_coordinates (emacsframe, pt.x, pt.y, 0, 0, 0);
+	= window_from_coordinates (emacsframe, pt.x, pt.y, 0, 0, 0, 0);
 
       if (WINDOWP (window)
           && !EQ (window, last_mouse_window)
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index a7c687d811d..461c9d6d899 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -5894,7 +5894,7 @@ motion_notify_event (GtkWidget *widget, GdkEvent *event,
 	{
 	  static Lisp_Object last_mouse_window;
 	  Lisp_Object window = window_from_coordinates
-	    (f, event->motion.x, event->motion.y, 0, false, false);
+	    (f, event->motion.x, event->motion.y, 0, false, false, false);
 
 	  /* A window will be autoselected only when it is not
 	     selected now and the last mouse movement event was
@@ -6047,7 +6047,7 @@ button_event (GtkWidget *widget, GdkEvent *event,
 	  int x = event->button.x;
 	  int y = event->button.y;
 
-	  window = window_from_coordinates (f, x, y, 0, true, true);
+	  window = window_from_coordinates (f, x, y, 0, true, true, true);
 	  tab_bar_p = EQ (window, f->tab_bar_window);
 
 	  if (tab_bar_p)
diff --git a/src/w32inevt.c b/src/w32inevt.c
index 29717954cfd..630a9f4e5fb 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -496,7 +496,7 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
 	    if (!NILP (Vmouse_autoselect_window))
 	      {
 		Lisp_Object mouse_window = window_from_coordinates (f, mx, my,
-								    0, 0, 0);
+								    0, 0, 0, 0);
 		/* A window will be selected only when it is not
 		   selected now, and the last mouse movement event was
 		   not in it.  A minibuffer window will be selected iff
diff --git a/src/w32term.c b/src/w32term.c
index a5f17a18213..301d8f4ef12 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -3376,7 +3376,7 @@ w32_construct_mouse_wheel (struct input_event *result, W32Msg *msg,
       if (w32_wheel_scroll_lines == UINT_MAX)
 	{
 	  Lisp_Object window = window_from_coordinates (f, p.x, p.y, NULL,
-							false, false);
+							false, false, false);
 	  if (!WINDOWP (window))
 	    {
 	      result->kind = NO_EVENT;
@@ -5335,7 +5335,7 @@ w32_read_socket (struct terminal *terminal,
 		{
 		  static Lisp_Object last_mouse_window;
 		  Lisp_Object window = window_from_coordinates
-		    (f, LOWORD (msg.msg.lParam), HIWORD (msg.msg.lParam), 0, 0, 0);
+		    (f, LOWORD (msg.msg.lParam), HIWORD (msg.msg.lParam), 0, 0, 0, 0);
 
 		  /* Window will be selected only when it is not
 		     selected now and last mouse movement event was
@@ -5407,7 +5407,7 @@ w32_read_socket (struct terminal *terminal,
 		    int x = XFIXNAT (inev.x);
 		    int y = XFIXNAT (inev.y);
 
-                    window = window_from_coordinates (f, x, y, 0, 1, 1);
+                    window = window_from_coordinates (f, x, y, 0, 1, 1, 1);
 
                     if (EQ (window, f->tab_bar_window))
                       {
@@ -5435,7 +5435,7 @@ w32_read_socket (struct terminal *terminal,
 		    int x = XFIXNAT (inev.x);
 		    int y = XFIXNAT (inev.y);
 
-                    window = window_from_coordinates (f, x, y, 0, 1, 1);
+                    window = window_from_coordinates (f, x, y, 0, 1, 1, 1);
 
                     if (EQ (window, f->tool_bar_window)
 			/* Make sure the tool bar was previously
diff --git a/src/window.c b/src/window.c
index 968b982c135..e802ffb3fe2 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1680,7 +1680,8 @@ check_window_containing (struct window *w, void *user_data)
 
 Lisp_Object
 window_from_coordinates (struct frame *f, int x, int y,
-			 enum window_part *part, bool tab_bar_p, bool tool_bar_p)
+			 enum window_part *part, bool menu_bar_p,
+			 bool tab_bar_p, bool tool_bar_p)
 {
   Lisp_Object window;
   struct check_window_data cw;
@@ -1693,6 +1694,21 @@ window_from_coordinates (struct frame *f, int x, int y,
   cw.window = &window, cw.x = x, cw.y = y; cw.part = part;
   foreach_window (f, check_window_containing, &cw);
 
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_MENU_BAR)
+  /* If not found above, see if it's in the menu bar window, if a menu
+     bar exists.  */
+  if (NILP (window)
+      && menu_bar_p
+      && WINDOWP (f->menu_bar_window)
+      && WINDOW_TOTAL_LINES (XWINDOW (f->menu_bar_window)) > 0
+      && (coordinates_in_window (XWINDOW (f->menu_bar_window), x, y)
+	  != ON_NOTHING))
+    {
+      *part = ON_TEXT;
+      window = f->menu_bar_window;
+    }
+#endif
+
 #if defined (HAVE_WINDOW_SYSTEM)
   /* If not found above, see if it's in the tab bar window, if a tab
      bar exists.  */
@@ -1746,7 +1762,7 @@ DEFUN ("window-at", Fwindow_at, Swindow_at, 2, 3, 0,
 				   + FRAME_INTERNAL_BORDER_WIDTH (f)),
 				  (FRAME_PIXEL_Y_FROM_CANON_Y (f, y)
 				   + FRAME_INTERNAL_BORDER_WIDTH (f)),
-				  0, false, false);
+				  0, false, false, false);
 }
 
 ptrdiff_t
diff --git a/src/window.h b/src/window.h
index 413293420fd..9ef8434af18 100644
--- a/src/window.h
+++ b/src/window.h
@@ -1111,7 +1111,7 @@ #define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X)	\
 
 extern Lisp_Object make_window (void);
 extern Lisp_Object window_from_coordinates (struct frame *, int, int,
-                                            enum window_part *, bool, bool);
+                                            enum window_part *, bool, bool, bool);
 extern void resize_frame_windows (struct frame *, int, bool);
 extern void restore_window_configuration (Lisp_Object);
 extern void delete_all_child_windows (Lisp_Object);
diff --git a/src/xdisp.c b/src/xdisp.c
index 2c53527c25e..7f9e62f05e8 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2778,7 +2778,7 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
       goto virtual_glyph;
     }
   else if (!f->glyphs_initialized_p
-	   || (window = window_from_coordinates (f, gx, gy, &part, false, false),
+	   || (window = window_from_coordinates (f, gx, gy, &part, false, false, false),
 	       NILP (window)))
     {
       width = FRAME_SMALLEST_CHAR_WIDTH (f);
@@ -35438,7 +35438,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
     return;
 
   /* Which window is that in?  */
-  window = window_from_coordinates (f, x, y, &part, true, true);
+  window = window_from_coordinates (f, x, y, &part, true, true, true);
 
   /* If displaying active text in another window, clear that.  */
   if (! EQ (window, hlinfo->mouse_face_window)
diff --git a/src/xterm.c b/src/xterm.c
index 517bdf57aab..d5ca60089d7 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -21161,7 +21161,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 		  }
 
 		Lisp_Object window = window_from_coordinates
-		  (f, xmotion.x, xmotion.y, 0, false, false);
+		  (f, xmotion.x, xmotion.y, 0, false, false, false);
 
 		/* A window will be autoselected only when it is not
 		   selected now and the last mouse movement event was
@@ -21892,7 +21892,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                 int x = event->xbutton.x;
                 int y = event->xbutton.y;
 
-                window = window_from_coordinates (f, x, y, 0, true, true);
+                window = window_from_coordinates (f, x, y, 0, true, true, true);
                 tab_bar_p = EQ (window, f->tab_bar_window);
 
                 if (tab_bar_p)
@@ -21913,7 +21913,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                 int x = event->xbutton.x;
                 int y = event->xbutton.y;
 
-                window = window_from_coordinates (f, x, y, 0, true, true);
+                window = window_from_coordinates (f, x, y, 0, true, true, true);
                 tool_bar_p = (EQ (window, f->tool_bar_window)
 			      && (event->xbutton.type != ButtonRelease
 				  || f->last_tool_bar_item != -1));
@@ -22646,7 +22646,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 			    continue;
 
 			  window = window_from_coordinates (f, real_x, real_y, NULL,
-							    false, false);
+							    false, false, false);
 
 			  if (WINDOWP (window))
 			    scroll_height = XWINDOW (window)->pixel_height;
@@ -23089,7 +23089,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 			  || !NILP (focus_follows_mouse)))
 		    {
 		      static Lisp_Object last_mouse_window;
-		      Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false);
+		      Lisp_Object window = window_from_coordinates (f, ev.x, ev.y, 0, false, false,
+								    false);
 
 		      /* A window will be autoselected only when it is not
 			 selected now and the last mouse movement event was
@@ -23667,7 +23668,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 		      int x = bv.x;
 		      int y = bv.y;
 
-		      window = window_from_coordinates (f, x, y, 0, true, true);
+		      window = window_from_coordinates (f, x, y, 0, true, true, true);
 		      tab_bar_p = EQ (window, f->tab_bar_window);
 
 		      if (tab_bar_p)
@@ -23688,7 +23689,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 		      int x = bv.x;
 		      int y = bv.y;
 
-		      window = window_from_coordinates (f, x, y, 0, true, true);
+		      window = window_from_coordinates (f, x, y, 0, true, true, true);
 		      /* Ignore button release events if the mouse
 			 wasn't previously pressed on the tool bar.
 			 We do this because otherwise selecting some
@@ -24694,7 +24695,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 		  int x = xev->event_x;
 		  int y = xev->event_y;
 
-		  window = window_from_coordinates (f, x, y, 0, true, true);
+		  window = window_from_coordinates (f, x, y, 0, true, true, true);
 		  /* Ignore button release events if the mouse
 		     wasn't previously pressed on the tool bar.
 		     We do this because otherwise selecting some
-- 
2.40.0