unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Arthur Miller <arthur.miller@live.com>
To: emacs-devel@gnu.org
Subject: Sticky tooltips
Date: Thu, 22 Oct 2020 18:17:53 +0200	[thread overview]
Message-ID: <VI1PR06MB452636128AEDDEF9229D9CC3961D0@VI1PR06MB4526.eurprd06.prod.outlook.com> (raw)

[-- Attachment #1: sticky-tips.patch --]
[-- Type: text/x-patch, Size: 6486 bytes --]

diff --git a/lisp/tooltip.el b/lisp/tooltip.el
index ffc3d499e3..8ca56f2100 100644
--- a/lisp/tooltip.el
+++ b/lisp/tooltip.el
@@ -67,6 +67,10 @@ tooltip-mode
 
 \f
 ;;; Customizable settings
+;; keep true while testing, will be default nil
+(defcustom tooltip-enable-sticky-tips t
+  "Seconds to wait before displaying a tooltip the first time."
+  :type 'boolean)
 
 (defcustom tooltip-delay 0.7
   "Seconds to wait before displaying a tooltip the first time."
@@ -175,6 +179,9 @@ tooltip-hide-time
 
 (defvar gud-tooltip-mode) ;; Prevent warning.
 
+(defvar sticky-tooltip-timer nil
+  "Time during which sticky tooltip is not hidden.")
+
 ;;; Event accessors
 
 (defun tooltip-event-buffer (event)
@@ -210,6 +217,10 @@ tooltip-timeout
   (run-hook-with-args-until-success 'tooltip-functions
 				    tooltip-last-mouse-motion-event))
 
+(defun tooltip-start-sticky-timer ()
+  (setq sticky-tooltip-timer
+        (run-with-timer tooltip-hide-delay nil 'tooltip-hide)
+        sticky-is-up t))
 \f
 ;;; Displaying tips
 
@@ -237,6 +248,8 @@ tooltip-show
 
 Optional second arg USE-ECHO-AREA non-nil means to show tooltip
 in echo area."
+  ;; while testing keep gtk tips off
+  (setq x-gtk-use-system-tooltips nil)
   (if use-echo-area
       (tooltip-show-help-non-mode text)
     (condition-case error
@@ -248,12 +261,47 @@ tooltip-show
 	    (setf (alist-get 'border-color params) fg))
 	  (when (stringp bg)
 	    (setf (alist-get 'background-color params) bg))
-	  (x-show-tip (propertize text 'face 'tooltip)
-		      (selected-frame)
+
+          (unless x-gtk-use-system-tooltips
+            (with-current-buffer (get-buffer-create " *tip*")
+              (let ((inhibit-read-only t))
+                (erase-buffer)
+                (remove-overlays)
+                (insert (propertize text 'face 'tooltip))
+
+                (when tooltip-enable-sticky-tips
+                  (goto-char (point-min))
+                  (let ((cur-line 0)
+                        (lng-line 0))
+                    (while (not (eobp))
+                      (setq cur-line (- (line-end-position) (line-beginning-position)))
+                      (when (> cur-line lng-line)
+                        (setq lng-line cur-line))
+                      (forward-line))
+                    (newline)
+                    (insert (make-string (- lng-line 6) ?─))
+                    (widget-insert " Sticky ")
+                    (widget-create 'checkbox
+                                   :notify
+                                   (lambda (s &rest ignore)
+                                     (if (widget-value s)
+                                         (message "START WIDGET")
+                                       (message "EXIT WIDGET"))))
+                    (use-local-map widget-keymap)
+                    (widget-setup))))))
+
+          ;; text properties are now handled, in buffer, and
+          ;; 'text' argument is only needed for gtk-tooltips
+          ;; (not used if we are here)
+          (x-show-tip text
+                      (selected-frame)
 		      params
 		      tooltip-hide-delay
 		      tooltip-x-offset
-		      tooltip-y-offset))
+		      tooltip-y-offset)
+
+          (when tooltip-enable-sticky-tips
+            (tooltip-start-sticky-timer)))
       (error
        (message "Error while displaying tooltip: %s" error)
        (sit-for 1)
@@ -368,7 +416,8 @@ tooltip-show-help
 	(cond ((null msg)
 	       ;; Cancel display.  This also cancels a delayed tip, if
 	       ;; there is one.
-	       (tooltip-hide))
+               (unless sticky-tooltip-timer
+	         (tooltip-hide)))
 	      ((equal-including-properties previous-help msg)
 	       ;; Same help as before (but possibly the mouse has moved).
 	       ;; Keep what we have.
@@ -376,6 +425,8 @@ tooltip-show-help
 	      (t
 	       ;; A different help.  Remove a previous tooltip, and
 	       ;; display a new one, with some delay.
+               (when sticky-tooltip-timer
+                 (cancel-timer sticky-tooltip-timer))
 	       (tooltip-hide)
 	       (tooltip-start-delayed-tip))))
     ;; On text-only displays, try `tooltip-show-help-non-mode'.
diff --git a/src/xfns.c b/src/xfns.c
index 46e4bd73a6..afb26b6b94 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -6909,7 +6909,6 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
     dy = make_fixnum (-10);
   else
     CHECK_FIXNUM (dy);
-
 #ifdef USE_GTK
   if (x_gtk_use_system_tooltips)
     {
@@ -6930,6 +6929,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
       unblock_input ();
       if (ok) goto start_timer;
     }
+
 #endif /* USE_GTK */
 
   if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
@@ -7081,20 +7081,20 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
      buffer.  */
   count_1 = SPECPDL_INDEX ();
   old_buffer = current_buffer;
-  set_buffer_internal_1 (XBUFFER (w->contents));
-  bset_truncate_lines (current_buffer, Qnil);
-  specbind (Qinhibit_read_only, Qt);
-  specbind (Qinhibit_modification_hooks, Qt);
-  specbind (Qinhibit_point_motion_hooks, Qt);
-  Ferase_buffer ();
-  Finsert (1, &string);
-  clear_glyph_matrix (w->desired_matrix);
-  clear_glyph_matrix (w->current_matrix);
-  SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
-  try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
-  /* Calculate size of tooltip window.  */
+  // set_buffer_internal_1 (XBUFFER (w->contents));
+  // bset_truncate_lines (current_buffer, Qnil);
+  // specbind (Qinhibit_read_only, Qt);
+  // specbind (Qinhibit_modification_hooks, Qt);
+  // specbind (Qinhibit_point_motion_hooks, Qt);
+  // Ferase_buffer ();
+  // Finsert (1, &string);
+  // clear_glyph_matrix (w->desired_matrix);
+  // clear_glyph_matrix (w->current_matrix);
+  // SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
+  // try_window (window, pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
+  // /* Calculate size of tooltip window.  */
   size = Fwindow_text_pixel_size (window, Qnil, Qnil, Qnil,
-				  make_fixnum (w->pixel_height), Qnil);
+                                  make_fixnum (w->pixel_height), Qnil);
   /* Add the frame's internal border to calculated size.  */
   width = XFIXNUM (Fcar (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);
   height = XFIXNUM (Fcdr (size)) + 2 * FRAME_INTERNAL_BORDER_WIDTH (tip_f);

[-- Attachment #2: Type: text/plain, Size: 744 bytes --]


I had a bit of time today to play with the idea of sticky tooltips. I am
still testing the interaction between tooltips and frame; so I tried
with a timer to keep a tooltip alive long enough so that user can move
mouse into the frame to enable a frame to be sticky (no functionality
yet).

I am having a little bit of a problem there; and I am not really sure
why. When I move mouse slow enough, it works for the most part; but if
mouse is moved quickly it sometimes work, sometimes not, and sometimes a
bit jerky: the tip frame "jumps" after the mouse. I guess it all depends
on timers and how Emacs delivers events. I am not sure what would be the
best strategy to go about this, so I appreciate if someone can give me a
tip (pun intended).

             reply	other threads:[~2020-10-22 16:17 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-22 16:17 Arthur Miller [this message]
  -- strict thread matches above, loose matches on Subject: below --
2020-10-05  0:55 Sticky tooltips Arthur Miller
2020-09-28 20:04 Arthur Miller
2020-09-28 22:11 ` Jean Louis
2020-09-29  3:39   ` Arthur Miller
2020-09-29  4:20     ` Jean Louis
2020-09-29  2:41 ` Eli Zaretskii
2020-09-29  3:36   ` Arthur Miller
2020-09-29 14:17     ` Eli Zaretskii
2020-09-29 21:30       ` Arthur Miller
2020-09-30 14:50         ` Eli Zaretskii
2020-09-30 15:17           ` Arthur Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=VI1PR06MB452636128AEDDEF9229D9CC3961D0@VI1PR06MB4526.eurprd06.prod.outlook.com \
    --to=arthur.miller@live.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).