emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 479f51a: Make tooltip code handle scenarios from Bu


From: Martin Rudalics
Subject: [Emacs-diffs] master 479f51a: Make tooltip code handle scenarios from Bug#30182 and Bug#30399
Date: Sat, 10 Feb 2018 04:20:21 -0500 (EST)

branch: master
commit 479f51a63bb0de72453881d72a1b3ff5f30b4658
Author: Martin Rudalics <address@hidden>
Commit: Martin Rudalics <address@hidden>

    Make tooltip code handle scenarios from Bug#30182 and Bug#30399
    
    Move calculation of the mode line default help echo from
    note_mode_line_or_margin_highlight to display_mode_lines
    (Bug#30182).  Fix cursor type for dragging the mode line.
    Normalize FRAME argument of Fx_show_tip before assigning it to
    tip_last_frame and handle the transition from GTK+ to Emacs
    tooltips and vice-versa in x_hide_tip (Bug#30399).
    
    * src/window.h (struct window): New Lisp member
    mode_line_help_echo.
    (wset_mode_line_help_echo): New function.
    * src/w32fns.c (Fx_show_tip): Normalize the FRAME argument
    bevore storing it in tip_last_frame (Bug#30399).
    * src/xdisp.c (display_mode_lines): Calculate mode line
    default help echo string here and store it in the window's
    mode_line_help_echo slot (Bug#30182).
    (note_mode_line_or_margin_highlight): Use value in window's
    mode_line_help_echo slot as mode line default help echo.  When
    the window is resizable show a vertical drag cursor instead of
    the vertical scroll bar cursor.
    * src/xfns.c (x_hide_tip): Rewrite the GTK+ part to correctly
    handle the transition from GTK+ system to Emacs tooltips and
    vice-versa (Bug#30399).
    (Fx_show_tip): Normalize the FRAME argument bevore storing it
    in tip_last_frame (Bug#30399).
---
 src/w32fns.c |  8 +++++--
 src/window.h |  9 ++++++++
 src/xdisp.c  | 60 ++++++++++++++++++++++++++++----------------------
 src/xfns.c   | 72 ++++++++++++++++++++++++++++++++++--------------------------
 4 files changed, 90 insertions(+), 59 deletions(-)

diff --git a/src/w32fns.c b/src/w32fns.c
index 27c765e..2b8c34a 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -6930,7 +6930,7 @@ Lisp_Object tip_timer;
 /* STRING argument of last `x-show-tip' call.  */
 Lisp_Object tip_last_string;
 
-/* FRAME argument of last `x-show-tip' call.  */
+/* Normalized FRAME argument of last `x-show-tip' call.  */
 Lisp_Object tip_last_frame;
 
 /* PARMS argument of last `x-show-tip' call.  */
@@ -7373,7 +7373,11 @@ Text larger than the specified size is clipped.  */)
   specbind (Qinhibit_redisplay, Qt);
 
   CHECK_STRING (string);
+
+  if (NILP (frame))
+    frame = selected_frame;
   decode_window_system_frame (frame);
+
   if (NILP (timeout))
     timeout = make_number (5);
   else
@@ -7508,7 +7512,7 @@ Text larger than the specified size is clipped.  */)
        parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
                       parms);
 
-      /* Create a frame for the tooltip, and record it in the global
+      /* Create a frame for the tooltip and record it in the global
         variable tip_frame.  */
       struct frame *f;         /* The value is unused.  */
       if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), 
parms)))
diff --git a/src/window.h b/src/window.h
index 629283a..91ef7d9 100644
--- a/src/window.h
+++ b/src/window.h
@@ -178,6 +178,9 @@ struct window
     /* An alist with parameters.  */
     Lisp_Object window_parameters;
 
+    /* The help echo text for this window.  Qnil if there's none.  */
+    Lisp_Object mode_line_help_echo;
+
     /* No Lisp data may follow below this point without changing
        mark_object in alloc.c.  The member current_matrix must be the
        first non-Lisp member.  */
@@ -445,6 +448,12 @@ wset_redisplay_end_trigger (struct window *w, Lisp_Object 
val)
 }
 
 INLINE void
+wset_mode_line_help_echo (struct window *w, Lisp_Object val)
+{
+  w->mode_line_help_echo = val;
+}
+
+INLINE void
 wset_new_pixel (struct window *w, Lisp_Object val)
 {
   w->new_pixel = val;
diff --git a/src/xdisp.c b/src/xdisp.c
index 55f3151..9a5bd2e 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -23209,6 +23209,23 @@ display_mode_lines (struct window *w)
   Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
   int n = 0;
 
+  if (window_wants_mode_line (w))
+    {
+      Lisp_Object window;
+      Lisp_Object default_help
+       = buffer_local_value (Qmode_line_default_help_echo, w->contents);
+
+      /* Set up mode line help echo.  Do this before selecting w so it
+        can reasonably tell whether a mouse click will select w.  */
+      XSETWINDOW (window, w);
+      if (FUNCTIONP (default_help))
+       wset_mode_line_help_echo (w, safe_call1 (default_help, window));
+      else if (STRINGP (default_help))
+       wset_mode_line_help_echo (w, default_help);
+      else
+       wset_mode_line_help_echo (w, Qnil);
+    }
+
   selected_frame = new_frame;
   /* FIXME: If we were to allow the mode-line's computation changing the buffer
      or window's point, then we'd need select_window_1 here as well.  */
@@ -23223,7 +23240,6 @@ display_mode_lines (struct window *w)
     {
       Lisp_Object window_mode_line_format
        = window_parameter (w, Qmode_line_format);
-
       struct window *sel_w = XWINDOW (old_selected_window);
 
       /* Select mode line face based on the real selected window.  */
@@ -30733,9 +30749,6 @@ note_mode_line_or_margin_highlight (Lisp_Object window, 
int x, int y,
   struct window *w = XWINDOW (window);
   struct frame *f = XFRAME (w->frame);
   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
-#ifdef HAVE_WINDOW_SYSTEM
-  Display_Info *dpyinfo;
-#endif
   Cursor cursor = No_Cursor;
   Lisp_Object pointer = Qnil;
   int dx, dy, width, height;
@@ -30829,7 +30842,8 @@ note_mode_line_or_margin_highlight (Lisp_Object window, 
int x, int y,
 
   /* Set the help text and mouse pointer.  If the mouse is on a part
      of the mode line without any text (e.g. past the right edge of
-     the mode line text), use the default help text and pointer.  */
+     the mode line text), use that windows's mode line help echo if it
+     has been set.  */
   if (STRINGP (string) || area == ON_MODE_LINE)
     {
       /* Arrange to display the help by setting the global variables
@@ -30846,21 +30860,13 @@ note_mode_line_or_margin_highlight (Lisp_Object 
window, int x, int y,
              help_echo_object = string;
              help_echo_pos = charpos;
            }
-         else if (area == ON_MODE_LINE)
+         else if (area == ON_MODE_LINE
+                  && !NILP (w->mode_line_help_echo))
            {
-             Lisp_Object default_help
-               = buffer_local_value (Qmode_line_default_help_echo,
-                                     w->contents);
-
-             if (FUNCTIONP (default_help) || STRINGP (default_help))
-               {
-                 help_echo_string = (FUNCTIONP (default_help)
-                                     ? safe_call1 (default_help, window)
-                                     : default_help);
-                 XSETWINDOW (help_echo_window, w);
-                 help_echo_object = Qnil;
-                 help_echo_pos = -1;
-               }
+             help_echo_string =  w->mode_line_help_echo;
+             XSETWINDOW (help_echo_window, w);
+             help_echo_object = Qnil;
+             help_echo_pos = -1;
            }
        }
 
@@ -30872,7 +30878,6 @@ note_mode_line_or_margin_highlight (Lisp_Object window, 
int x, int y,
                            || minibuf_level
                            || NILP (Vresize_mini_windows));
 
-         dpyinfo = FRAME_DISPLAY_INFO (f);
          if (STRINGP (string))
            {
              cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
@@ -30882,25 +30887,28 @@ note_mode_line_or_margin_highlight (Lisp_Object 
window, int x, int y,
 
              /* Change the mouse pointer according to what is under X/Y.  */
              if (NILP (pointer)
-                 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
+                 && (area == ON_MODE_LINE || area == ON_HEADER_LINE))
                {
                  Lisp_Object map;
+
                  map = Fget_text_property (pos, Qlocal_map, string);
                  if (!KEYMAPP (map))
                    map = Fget_text_property (pos, Qkeymap, string);
-                 if (!KEYMAPP (map) && draggable)
-                   cursor = dpyinfo->vertical_scroll_bar_cursor;
+                 if (!KEYMAPP (map) && draggable && area == ON_MODE_LINE)
+                   cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
                }
            }
-         else if (draggable)
-           /* Default mode-line pointer.  */
-           cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
+         else if (draggable && area == ON_MODE_LINE)
+           cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
+         else
+           cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
        }
 #endif
     }
 
   /* Change the mouse face according to what is under X/Y.  */
   bool mouse_face_shown = false;
+
   if (STRINGP (string))
     {
       mouse_face = Fget_text_property (pos, Qmouse_face, string);
diff --git a/src/xfns.c b/src/xfns.c
index db1ce31..9f0d946 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -6077,7 +6077,7 @@ static Lisp_Object tip_timer;
 /* STRING argument of last `x-show-tip' call.  */
 static Lisp_Object tip_last_string;
 
-/* FRAME argument of last `x-show-tip' call.  */
+/* Normalized FRAME argument of last `x-show-tip' call.  */
 static Lisp_Object tip_last_frame;
 
 /* PARMS argument of last `x-show-tip' call.  */
@@ -6542,16 +6542,20 @@ x_hide_tip (bool delete)
     }
 
 #ifdef USE_GTK
-  /* The GTK+ system tooltip window can be found via the x_output
-     structure of tip_last_frame, if it still exists.  */
-  if (x_gtk_use_system_tooltips && NILP (tip_last_frame))
-    return Qnil;
-  else if (!x_gtk_use_system_tooltips
-          && (NILP (tip_frame)
-              || (!delete
-                  && FRAMEP (tip_frame)
-                  && FRAME_LIVE_P (XFRAME (tip_frame))
-                  && !FRAME_VISIBLE_P (XFRAME (tip_frame)))))
+  /* Any GTK+ system tooltip can be found via the x_output structure of
+     tip_last_frame, provided that frame is still live.  Any Emacs
+     tooltip is found via the tip_frame variable.  Note that the current
+     value of x_gtk_use_system_tooltips might not be the same as used
+     for the tooltip we have to hide, see Bug#30399.  */
+  if ((NILP (tip_last_frame) && NILP (tip_frame))
+      || (!x_gtk_use_system_tooltips
+         && !delete
+         && FRAMEP (tip_frame)
+         && FRAME_LIVE_P (XFRAME (tip_frame))
+         && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
+    /* Either there's no tooltip to hide or it's an already invisible
+       Emacs tooltip and we don't want to change its type.  Return
+       quickly.  */
     return Qnil;
   else
     {
@@ -6562,10 +6566,9 @@ x_hide_tip (bool delete)
       specbind (Qinhibit_redisplay, Qt);
       specbind (Qinhibit_quit, Qt);
 
-      if (x_gtk_use_system_tooltips)
+      /* Try to hide the GTK+ system tip first.  */
+      if (FRAMEP (tip_last_frame))
        {
-         /* The GTK+ system tooltip window is stored in the x_output
-            structure of tip_last_frame.  */
          struct frame *f = XFRAME (tip_last_frame);
 
          if (FRAME_LIVE_P (f))
@@ -6573,33 +6576,37 @@ x_hide_tip (bool delete)
              if (xg_hide_tooltip (f))
                was_open = Qt;
            }
-         else
-           tip_last_frame = Qnil;
        }
-      else
+
+      /* Reset tip_last_frame, it will be reassigned when showing the
+        next GTK+ system tooltip.  */
+      tip_last_frame = Qnil;
+
+      /* Now look whether there's an Emacs tip around.  */
+      if (FRAMEP (tip_frame))
        {
-         if (FRAMEP (tip_frame))
-           {
-             struct frame *f = XFRAME (tip_frame);
+         struct frame *f = XFRAME (tip_frame);
 
-             if (FRAME_LIVE_P (f))
+         if (FRAME_LIVE_P (f))
+           {
+             if (delete || x_gtk_use_system_tooltips)
                {
-                 if (delete)
-                   {
-                     delete_frame (tip_frame, Qnil);
-                     tip_frame = Qnil;
-                   }
-                 else
-                   x_make_frame_invisible (f);
-
-                 was_open = Qt;
+                 /* Delete the Emacs tooltip frame when DELETE is true
+                    or we change the tooltip type from an Emacs one to
+                    a GTK+ system one.  */
+                 delete_frame (tip_frame, Qnil);
+                 tip_frame = Qnil;
                }
              else
-               tip_frame = Qnil;
+               x_make_frame_invisible (f);
+
+             was_open = Qt;
            }
          else
            tip_frame = Qnil;
        }
+      else
+       tip_frame = Qnil;
 
       return unbind_to (count, was_open);
     }
@@ -6721,7 +6728,10 @@ Text larger than the specified size is clipped.  */)
   if (SCHARS (string) == 0)
     string = make_unibyte_string (" ", 1);
 
+  if (NILP (frame))
+    frame = selected_frame;
   f = decode_window_system_frame (frame);
+
   if (NILP (timeout))
     timeout = make_number (5);
   else



reply via email to

[Prev in Thread] Current Thread [Next in Thread]