]> git.eshelyaron.com Git - emacs.git/commitdiff
Set WM_TRANSIENT_FOR on tooltip frames
authorPo Lu <luangruo@yahoo.com>
Sat, 5 Feb 2022 02:51:39 +0000 (10:51 +0800)
committerPo Lu <luangruo@yahoo.com>
Sat, 5 Feb 2022 02:51:39 +0000 (10:51 +0800)
Otherwise the decorations get all messed up on GNOME and some
other composited desktops.

* src/xfns.c (Fx_show_tip): Set WM_TRANSIENT_FOR to the window
underneath the tooltip.

src/xfns.c

index 9bbefd79a0280243a8988fe31826d62ecbae1e41..4719c5dac7d96f9194a697bb64c47b468ae5ddd9 100644 (file)
@@ -7734,6 +7734,8 @@ Text larger than the specified size is clipped.  */)
   ptrdiff_t count = SPECPDL_INDEX ();
   ptrdiff_t count_1;
   Lisp_Object window, size, tip_buf;
+  Window child;
+  int dest_x_return, dest_y_return;
   AUTO_STRING (tip, " *tip*");
 
   specbind (Qinhibit_redisplay, Qt);
@@ -7958,6 +7960,27 @@ Text larger than the specified size is clipped.  */)
 
   /* Show tooltip frame.  */
   block_input ();
+  /* If the display is composited, then WM_TRANSIENT_FOR must be set
+     as well, or else the compositing manager won't display
+     decorations correctly, even though the tooltip window is override
+     redirect. See
+     https://specifications.freedesktop.org/wm-spec/1.4/ar01s08.html
+
+     Perhaps WM_TRANSIENT_FOR should be used in place of
+     override-redirect anyway.  The ICCCM only recommends
+     override-redirect if the pointer will be grabbed.  */
+
+  if (XTranslateCoordinates (FRAME_X_DISPLAY (f),
+                            FRAME_DISPLAY_INFO (f)->root_window,
+                            FRAME_DISPLAY_INFO (f)->root_window,
+                            root_x, root_y, &dest_x_return,
+                            &dest_y_return, &child))
+    XSetTransientForHint (FRAME_X_DISPLAY (tip_f),
+                         FRAME_X_WINDOW (tip_f), child);
+  else
+    XSetTransientForHint (FRAME_X_DISPLAY (tip_f),
+                         FRAME_X_WINDOW (tip_f), None);
+
 #ifndef USE_XCB
   XMoveResizeWindow (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f),
                     root_x, root_y, width, height);