Subject: Re: bug#31880: 26.1; VC mode line popup when clicked is off screen

From: Robert Pluim <[email-masked]>
Date: Wed, 20 Jun 2018 16:31:32 +0200

martin rudalics <[email-masked]> writes:

>> It should, but it doesnʼt. I see similar problems here, but I donʼt
>> understand why (unless this is another instance of "Mixing X and GTK
>> calls will bite your arse eventually").
>
> What happens when you move a frame to the bottom of your screen and
> open a menu bar entry?  Does it also get hidden?

No, menu bar menus are fine.

>> GTK tooltips seem to appear in the right place, so Iʼll look for
>> inspiration there.
>
> It's up to GTK to decide whether a menu fits on the screen so maybe it
> messes up the height of menu bar text when scaling is in effect.  Does
> scaling affect the height of menus in the first place?  Does it affect
> the height of tooltips?
>

Yes and yes, because it affects the size of the font used to display
them.

> Thanks for looking into this, martin

Yet another instance of a disagreement between how GTK and X calculate
pixels. Who will rid me of this turbulent mix?

Brian, would it be possible for you to try out the following patch? It
fixes things for me here.

diff --git i/src/xmenu.c w/src/xmenu.c
index e7ef31ac56..3a245771e1 100644
--- i/src/xmenu.c
+++ w/src/xmenu.c
@@ -1162,11 +1162,16 @@ menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer
   GtkRequisition req;
   int max_x = -1;
   int max_y = -1;
+  int scale = 1;
 
   Lisp_Object frame, workarea;
 
   XSETFRAME (frame, data->f);
 
+#ifdef HAVE_GTK3
+  scale = xg_get_scale (data->f);
+#endif
+
   /* TODO: Get the monitor workarea directly without calculating other
      items in x-display-monitor-attributes-list. */
   workarea = call3 (Qframe_monitor_workarea,
@@ -1192,11 +1197,18 @@ menu_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer
       max_y = x_display_pixel_height (dpyinfo);
     }
 
+  /* frame-monitor-workarea and {x,y}_display_pixel_width/height all
+     return device pixels, but GTK wants scaled pixels.  The positions
+     passed in via data were already scaled for us.  */
+  max_x /= scale;
+  max_y /= scale;
   *x = data->x;
   *y = data->y;
 
   /* Check if there is room for the menu.  If not, adjust x/y so that
-     the menu is fully visible.  */
+     the menu is fully visible.  gtk_widget_get_preferred_size returns
+     scaled pixels, so there is no need to apply the scaling
+     factor.  */
   gtk_widget_get_preferred_size (GTK_WIDGET (menu), NULL, &req);
   if (data->x + req.width > max_x)
     *x -= data->x + req.width - max_x;