Function: touch-screen-hold
touch-screen-hold is an autoloaded, interactive and byte-compiled
function defined in touch-screen.el.gz.
Signature
(touch-screen-hold EVENT)
Documentation
Handle a long press EVENT.
Ding and select the window at EVENT, then activate the mark. If
touch-screen-word-select is enabled, try to select the whole
word around EVENT; otherwise, set point to the location of EVENT.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/touch-screen.el.gz
;;; Drag-to-select gesture.
;;;###autoload
(defun touch-screen-hold (event)
"Handle a long press EVENT.
Ding and select the window at EVENT, then activate the mark. If
`touch-screen-word-select' is enabled, try to select the whole
word around EVENT; otherwise, set point to the location of EVENT."
(interactive "e")
(let* ((posn (cadr event))
(point (posn-point posn))
(window (posn-window posn)))
(when (and point
;; Make sure WINDOW is not an inactive minibuffer
;; window.
(or (not (eq window
(minibuffer-window
(window-frame window))))
(minibuffer-window-active-p window)))
(beep)
(select-window window)
(if (or (not touch-screen-word-select)
(when-let* ((char (char-after point))
(class (char-syntax char)))
;; Don't select words if point isn't inside a word
;; constituent or similar.
(not (or (eq class ?w) (eq class ?_)))))
(progn
;; Set the mark and activate it.
(setq touch-screen-word-select-initial-word nil
touch-screen-word-select-bounds nil)
(push-mark point)
(goto-char point)
(activate-mark)
(setq deactivate-mark nil))
;; Start word selection by trying to obtain the position
;; around point.
(let ((word-start nil)
(word-end nil))
(unless (posn-object posn)
;; If there's an object under POSN avoid trying to
;; ascertain the bounds of the word surrounding it.
(save-excursion
(goto-char point)
(forward-word-strictly)
;; Set word-end to ZV if there is no word after this
;; one.
(setq word-end (point))
;; Now try to move backwards. Set word-start to BEGV if
;; this word is there.
(backward-word-strictly)
(setq word-start (point))))
;; Check if word-start and word-end are identical, if there
;; is an object under POSN, or if point is looking at or
;; outside a word.
(if (or (eq word-start word-end)
(>= word-start point))
(progn
;; If so, clear the bounds and set and activate the
;; mark.
(setq touch-screen-word-select-bounds nil
touch-screen-word-select-initial-word nil)
(push-mark point)
(goto-char point)
(activate-mark)
(setq deactivate-mark nil))
;; Otherwise, select the word. Move point to either the
;; end or the start of the word, depending on which is
;; closer to EVENT.
(let ((diff-beg (- point word-start))
(diff-end (- word-end point))
use-end)
(if (> diff-beg diff-end)
;; Set the point to the end of the word.
(setq use-end t)
(if (< diff-end diff-beg)
(setq use-end nil)
;; POINT is in the middle of the word. Use its
;; window coordinates to establish whether or not it
;; is closer to the start of the word or to the end
;; of the word.
(let ((posn-beg (posn-at-point word-start))
(posn-end (posn-at-point word-end)))
;; Give up if there's an object at either of those
;; positions, or they're not on the same row.
;; If one of the positions isn't visible, use the
;; window end.
(if (and posn-beg posn-end
(not (posn-object posn-beg))
(not (posn-object posn-end))
(eq (cdr (posn-col-row posn-beg))
(cdr (posn-col-row posn-end))))
(setq use-end nil)
;; Compare the pixel positions.
(setq point (car (posn-x-y posn))
diff-beg (- point (car (posn-x-y posn-beg)))
diff-end (- (car (posn-x-y posn-end)) point))
;; Now determine whether or not point should be
;; moved to the end.
(setq use-end (>= diff-beg diff-end))))))
(if use-end
(progn
(push-mark word-start)
(activate-mark)
(setq deactivate-mark nil)
(goto-char word-end))
(progn
(push-mark word-end)
(activate-mark)
(setq deactivate-mark nil)
(goto-char word-start)))
;; Record the bounds of the selected word.
(setq touch-screen-word-select-bounds
(cons word-start word-end)
;; Save this for the benefit of touch-screen-drag.
touch-screen-word-select-initial-word
(cons word-start word-end)))))))))