all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Arthur Miller <arthur.miller@live.com>
To: emacs-devel@gnu.org
Subject: Sticky tooltips
Date: Mon, 28 Sep 2020 22:04:50 +0200	[thread overview]
Message-ID: <VI1PR06MB45267EE061A679C6B2FEA35096350@VI1PR06MB4526.eurprd06.prod.outlook.com> (raw)

[-- Attachment #1: test --]
[-- Type: text/plain, Size: 4296 bytes --]

;;; poor-man-tooltip.el ---                                 -*- lexical-binding: t; -*-

(require 'widget)

(defvar pm-tooltip-duration)
(setq pm-tooltip-duration 4)

(defun pm-test ()
  (interactive)
  (pm-tooltip "Here is some tootip text."))

(define-minor-mode pm-minor-mode
  ""
  :keymap (let ((map (make-sparse-keymap)))
            (define-key map (kbd "C-g")   'pm-quit-tooltip)
            map))

(defun pm-tooltip (tooltip-text)
  
  (let ((cur-line 0)
        (lng-line 0)
        (tooltip-timer nil)
        (tooltip-frame nil))
    
    (with-current-buffer (get-buffer-create "tooltip-buffer")
      (kill-all-local-variables)
      (let ((inhibit-read-only t))
        (erase-buffer))
      (remove-overlays)
      
      (insert " ")
      (insert tooltip-text)
      (goto-char (point-min))

      (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-char ?- (- lng-line 6))
      (widget-insert " Sticky ")
      (widget-create 'checkbox 
                 :notify (lambda (s &rest ignore)
                           (if (widget-value s)
                                 (progn
                                   (when tooltip-timer
                                     (cancel-timer tooltip-timer)
                                     (setq tooltip-timer nil))
                                   (message "Sticky tooltip enabled!"))
                             ;; else
                             (progn
                               (when tooltip-frame
                                 (setq tooltip-timer (pm-start-timer
                                                      tooltip-frame)))
                               (message "Sticky tooltip disabled!")))))
      (use-local-map widget-keymap)
      (widget-setup))
      
    (setq tooltip-frame (pm-show-at-cursor "tooltip-buffer"))
    (setq tooltip-timer (pm-start-timer tooltip-frame))))

(defun pm-quit-tooltip (tooltip-frame)
  (with-current-buffer (get-buffer "tooltip-buffer")
    (kill-buffer))
  (delete-frame tooltip-frame))

(defun pm-start-timer (tooltip-frame)
  (let ((tooltip-timer
        (run-with-timer pm-tooltip-duration nil
                        (apply-partially #'pm-quit-tooltip tooltip-frame))))
    tooltip-timer))

(defun pm-show-at-point (menuname)
  (let ((position (pos-visible-in-window-p nil nil t)))
      (pm-create-tooltip menuname (nth 0 position) (nth 1 position))))

(defun pm-show-at-cursor (menuname)
  (let ((cursor-pos (mouse-pixel-position)))
        (pm-create-tooltip menuname (cadr cursor-pos) (cddr cursor-pos))))
    
(defun pm-create-tooltip (menuname x y)
  
  (with-current-buffer (get-buffer menuname)
    (pm-minor-mode)

    (setq tab-line-format nil)
    (setq mode-line-format nil)
    (setq cursor-type nil)
    (setq buffer-read-only t)
    
    (let ((parent (selected-frame))
          (child-frame (make-frame   '((visible . 0)
                                       (border-width . 2)
                                       (internal-border-width . 2)
                                       (undecorated . 0)
                                       (keep-ratio . t)
                                       (menu-bar-lines . 0)
                                       (tool-bar-lines . 0)
                                       (left-fringe . 0)
                                       (right-fringe . 0)
                                       (line-spacing . 0)
                                       (unsplittable . t)
                                       (minibuffer . nil)
                                       (no-other-frame . t)
                                       (drag-internal-border . t)
                                       (inhibit-double-buffering . t)
                                       (desktop-dont-save . t)))))
      
      (set-frame-parameter child-frame 'parent-frame parent)
      (fit-frame-to-buffer child-frame)
      ;; seems that afte fit-frame-to-buff there is few pixels missing
      (set-frame-width child-frame (+ 1 (frame-width child-frame)))
      (set-frame-position child-frame x y)
      child-frame)))

(provide 'poor-man-tooltip)

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


Somebody suggested for sticky tooltips the other day; Mr. Eli Z.
explained about tooltips, when compiled in Gtk are controlled by Gtk.

So I wonder - do they need to be?

A tooltip is just a small pop-up window showing some text (usually).
Emacs is already very good at showing text in all kind of windows so
question is, is Gtk really needed to render tooltips? Even if Emacs
is compiled with Gtk? Is there any special advantage over an "Emacs
frame"?

I tested idea with a sticky tooltip based on just ordinary buffer
displayed in a child frame. I haven't done any text
styling/propertizing, faces, colors etc. The frame is displayed at mouse
cursor (just for test) and it starts a timer which deletes frame after
an (customizable) interval. There is a small checkbox to make it
"sticky" (it just removed the expiration timer); toggling it on will
start timer again.

It is just a sketch of the idea; i just wonder if such similar tooltip
implementatation (all Emacs) would be interesting. It seems to be quite
trivial and if it is done all in Elisp then I guess it would be same on
all gui platforms? 


             reply	other threads:[~2020-09-28 20:04 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-28 20:04 Arthur Miller [this message]
2020-09-28 22:11 ` Sticky tooltips 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
2020-10-01  2:28           ` Sv: " arthur miller
2020-10-01 12:58             ` Eli Zaretskii
2020-10-02 10:47               ` Sv: " arthur miller
2020-10-05  9:27               ` Arthur Miller
2020-10-05  9:48                 ` Eli Zaretskii
2020-10-05 10:18                   ` Arthur Miller
2020-10-05 10:52                     ` Eli Zaretskii
2020-10-05 11:04                       ` Arthur Miller
  -- strict thread matches above, loose matches on Subject: below --
2020-10-05  0:55 Arthur Miller
2020-10-22 16: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

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

  git send-email \
    --in-reply-to=VI1PR06MB45267EE061A679C6B2FEA35096350@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 external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.