1 ;;; vm-mouse.el --- Mouse related functions and commands
3 ;; Copyright (C) 1995-1997 Kyle E. Jones
4 ;; Copyright (C) 2003-2006 Robert Widhopf-Fenk
6 ;; This program is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 2 of the License, or
9 ;; (at your option) any later version.
11 ;; This program is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;; GNU General Public License for more details.
16 ;; You should have received a copy of the GNU General Public License along
17 ;; with this program; if not, write to the Free Software Foundation, Inc.,
18 ;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 (defun vm-mouse-set-mouse-track-highlight (start end &optional overlay)
24 (let ((o (make-overlay start end)))
25 (overlay-put o 'mouse-face 'highlight)
28 (let ((o (make-extent start end)))
29 (set-extent-property o 'start-open t)
30 (set-extent-property o 'priority 10)
31 (set-extent-property o 'highlight t)
34 (move-overlay overlay start end))
36 (set-extent-endpoints overlay start end)))))
39 (defun vm-mouse-button-2 (event)
41 ;; go to where the event occurred
42 (cond ((vm-mouse-xemacs-mouse-p)
43 (set-buffer (window-buffer (event-window event)))
44 (and (event-point event) (goto-char (event-point event))))
45 ((vm-mouse-fsfemacs-mouse-p)
46 (set-buffer (window-buffer (posn-window (event-start event))))
47 (goto-char (posn-point (event-start event)))))
48 ;; now dispatch depending on where we are
49 (cond ((eq major-mode 'vm-summary-mode)
50 (mouse-set-point event)
52 (if (let ((vm-follow-summary-cursor t))
53 (vm-follow-summary-cursor))
55 (setq this-command 'vm-scroll-forward)
56 (call-interactively 'vm-scroll-forward)))
57 ((eq major-mode 'vm-folders-summary-mode)
58 (mouse-set-point event)
60 (vm-follow-folders-summary-cursor))
61 ((memq major-mode '(vm-mode vm-virtual-mode vm-presentation-mode))
62 (vm-mouse-popup-or-select event))))
65 (defun vm-mouse-button-3 (event)
69 ;; go to where the event occurred
70 (cond ((vm-mouse-xemacs-mouse-p)
71 (set-buffer (window-buffer (event-window event)))
72 (and (event-point event) (goto-char (event-point event))))
73 ((vm-mouse-fsfemacs-mouse-p)
74 (set-buffer (window-buffer (posn-window (event-start event))))
75 (goto-char (posn-point (event-start event)))))
76 ;; now dispatch depending on where we are
77 (cond ((eq major-mode 'vm-summary-mode)
78 (vm-menu-popup-mode-menu event))
79 ((eq major-mode 'vm-mode)
80 (vm-menu-popup-context-menu event))
81 ((eq major-mode 'vm-presentation-mode)
82 (vm-menu-popup-context-menu event))
83 ((eq major-mode 'vm-virtual-mode)
84 (vm-menu-popup-context-menu event))
85 ((eq major-mode 'mail-mode)
86 (vm-menu-popup-context-menu event))))))
88 (defun vm-mouse-3-help (object)
90 "Use mouse button 3 to see a menu of options.")
92 (defun vm-mouse-get-mouse-track-string (event)
94 ;; go to where the event occurred
95 (cond ((vm-mouse-xemacs-mouse-p)
96 (set-buffer (window-buffer (event-window event)))
97 (and (event-point event) (goto-char (event-point event))))
98 ((vm-mouse-fsfemacs-mouse-p)
99 (set-buffer (window-buffer (posn-window (event-start event))))
100 (goto-char (posn-point (event-start event)))))
102 (let ((o-list (overlays-at (point)))
105 (if (overlay-get (car o-list) 'mouse-face)
106 (setq string (vm-buffer-substring-no-properties
107 (overlay-start (car o-list))
108 (overlay-end (car o-list)))
110 (setq o-list (cdr o-list))))
113 (let ((e (extent-at (point) nil 'highlight)))
115 (buffer-substring (extent-start-position e)
116 (extent-end-position e))
121 (defun vm-mouse-popup-or-select (event)
123 (cond ((vm-mouse-fsfemacs-mouse-p)
124 (set-buffer (window-buffer (posn-window (event-start event))))
125 (goto-char (posn-point (event-start event)))
126 (let (o-list (found nil))
127 (setq o-list (overlays-at (point)))
128 (while (and o-list (not found))
129 (cond ((overlay-get (car o-list) 'vm-url)
131 (vm-mouse-send-url-at-event event))
132 ((overlay-get (car o-list) 'vm-mime-function)
134 (funcall (overlay-get (car o-list) 'vm-mime-function)
136 (setq o-list (cdr o-list)))
137 (and (not found) (vm-menu-popup-context-menu event))))
138 ;; The XEmacs code is not actually used now, since all
139 ;; selectable objects are handled by an extent keymap
140 ;; binding that points to a more specific function. But
141 ;; this might come in handy later if I want selectable
142 ;; objects that don't have an extent keymap attached.
143 ((vm-mouse-xemacs-mouse-p)
144 (set-buffer (window-buffer (event-window event)))
145 (and (event-point event) (goto-char (event-point event)))
147 (cond ((extent-at (point) (current-buffer) 'vm-url)
148 (vm-mouse-send-url-at-event event))
149 ((setq e (extent-at (point) nil 'vm-mime-function))
150 (funcall (extent-property e 'vm-mime-function) e))
151 (t (vm-menu-popup-context-menu event)))))))
154 (defun vm-mouse-send-url-at-event (event)
156 (cond ((vm-mouse-xemacs-mouse-p)
157 (set-buffer (window-buffer (event-window event)))
158 (and (event-point event) (goto-char (event-point event)))
159 (vm-mouse-send-url-at-position (event-point event)))
160 ((vm-mouse-fsfemacs-mouse-p)
161 (set-buffer (window-buffer (posn-window (event-start event))))
162 (goto-char (posn-point (event-start event)))
163 (vm-mouse-send-url-at-position (posn-point (event-start event))))))
165 (defun vm-mouse-send-url-at-position (pos &optional browser)
168 (cond ((vm-mouse-xemacs-mouse-p)
169 (let ((e (extent-at pos (current-buffer) 'vm-url))
173 (setq url (buffer-substring (extent-start-position e)
174 (extent-end-position e)))
175 (vm-mouse-send-url url browser))))
176 ((vm-mouse-fsfemacs-mouse-p)
178 (setq o-list (overlays-at pos))
179 (while (and o-list (null (overlay-get (car o-list) 'vm-url)))
180 (setq o-list (cdr o-list)))
183 (setq o (car o-list))
184 (setq url (vm-buffer-substring-no-properties
187 (vm-mouse-send-url url browser)))))))
189 (defun vm-mouse-send-url (url &optional browser switches)
190 (if (string-match "^[A-Za-z0-9._-]+@[A-Za-z0-9._-]+$" url)
191 (setq url (concat "mailto:" url)))
192 (if (string-match "^mailto:" url)
193 (vm-mail-to-mailto-url url)
194 (let ((browser (or browser vm-url-browser))
195 (switches (or switches vm-url-browser-switches)))
196 (cond ((symbolp browser)
197 (funcall browser url))
199 (message "Sending URL to %s..." browser)
200 (apply 'vm-run-background-command browser
201 (append switches (list url)))
202 (message "Sending URL to %s... done" browser))))))
204 (defun vm-mouse-send-url-to-netscape (url &optional new-netscape new-window)
205 ;; Change commas to %2C to avoid confusing Netscape -remote.
206 (while (string-match "," url)
207 (setq url (replace-match "%2C" nil t url)))
208 (message "Sending URL to Netscape...")
210 (apply 'vm-run-background-command vm-netscape-program
211 (append vm-netscape-program-switches (list url)))
212 (or (equal 0 (apply 'vm-run-command vm-netscape-program
213 (append vm-netscape-program-switches
215 (concat "openURL(" url
216 (if new-window ",new-window" "")
218 (vm-mouse-send-url-to-netscape url t new-window)))
219 (message "Sending URL to Netscape... done"))
221 (defun vm-mouse-send-url-to-opera (url &optional new-opera new-window)
222 ;; Change commas to %2C to avoid confusing Netscape -remote.
223 (while (string-match "," url)
224 (setq url (replace-match "%2C" nil t url)))
225 (message "Sending URL to Opera...")
227 (apply 'vm-run-background-command vm-opera-program
228 (append vm-opera-program-switches (list url)))
229 (or (equal 0 (apply 'vm-run-command vm-opera-program
230 (append vm-opera-program-switches
232 (concat "openURL(" url
234 (vm-mouse-send-url-to-opera url t new-window)))
235 (message "Sending URL to Opera... done"))
238 (defun vm-mouse-send-url-to-mozilla (url &optional new-mozilla new-window)
239 ;; Change commas to %2C to avoid confusing Netscape -remote.
240 (while (string-match "," url)
241 (setq url (replace-match "%2C" nil t url)))
242 (message "Sending URL to Mozilla...")
244 (apply 'vm-run-background-command vm-mozilla-program
245 (append vm-mozilla-program-switches (list url)))
246 (or (equal 0 (apply 'vm-run-command vm-mozilla-program
247 (append vm-mozilla-program-switches
249 (concat "openURL(" url
250 (if new-window ",new-window" "")
252 (vm-mouse-send-url-to-mozilla url t new-window)))
253 (message "Sending URL to Mozilla... done"))
255 (defun vm-mouse-send-url-to-netscape-new-window (url)
256 (vm-mouse-send-url-to-netscape url nil t))
258 (defun vm-mouse-send-url-to-opera-new-window (url)
259 (vm-mouse-send-url-to-opera url nil t))
261 (defun vm-mouse-send-url-to-mozilla-new-window (url)
262 (vm-mouse-send-url-to-mozilla url nil t))
264 (defvar buffer-file-type)
266 (defun vm-mouse-send-url-to-mosaic (url &optional new-mosaic new-window)
267 (vm-mouse-send-url-to-xxxx-mosaic 'mosaic url new-mosaic new-window))
269 (defun vm-mouse-send-url-to-mmosaic (url &optional new-mosaic new-window)
270 (vm-mouse-send-url-to-xxxx-mosaic 'mmosaic url new-mosaic new-window))
272 (defun vm-mouse-send-url-to-xxxx-mosaic (m-type url &optional
273 new-mosaic new-window)
274 (let ((what (cond ((eq m-type 'mmosaic) "mMosaic")
276 (message "Sending URL to %s..." what)
277 (if (null new-mosaic)
278 (let ((pid-file (cond ((eq m-type 'mmosaic)
279 "~/.mMosaic/.mosaicpid")
281 (work-buffer " *mosaic work*")
282 (coding-system-for-read (vm-line-ending-coding-system))
283 (coding-system-for-write (vm-line-ending-coding-system))
285 (cond ((file-exists-p pid-file)
286 (set-buffer (get-buffer-create work-buffer))
287 (setq selective-display nil)
289 (insert-file-contents pid-file)
290 (setq pid (int-to-string (string-to-number (buffer-string))))
292 (insert (if new-window "newwin" "goto") ?\n)
294 ;; newline convention used should be the local
295 ;; one, whatever that is.
296 (setq buffer-file-type nil)
297 (if (fboundp 'set-buffer-file-coding-system)
298 (set-buffer-file-coding-system
299 (vm-line-ending-coding-system) nil))
300 (write-region (point-min) (point-max)
301 (concat "/tmp/Mosaic." pid)
303 (set-buffer-modified-p nil)
304 (kill-buffer work-buffer)))
305 (cond ((or (null pid)
306 (not (equal 0 (vm-run-command "kill" "-USR1" pid))))
307 (setq new-mosaic t)))))
309 (apply 'vm-run-background-command
310 (cond ((eq m-type 'mmosaic) vm-mmosaic-program)
311 (t vm-mosaic-program))
312 (append (cond ((eq m-type 'mmosaic) vm-mmosaic-program-switches)
313 (t vm-mosaic-program-switches))
315 (message "Sending URL to %s... done" what)))
317 (defun vm-mouse-send-url-to-mosaic-new-window (url)
318 (vm-mouse-send-url-to-mosaic url nil t))
320 (defun vm-mouse-send-url-to-konqueror (url &optional new-konqueror)
321 (message "Sending URL to Konqueror...")
323 (apply 'vm-run-background-command vm-konqueror-program
324 (append vm-konqueror-program-switches (list url)))
325 (or (equal 0 (apply 'vm-run-command vm-konqueror-client-program
326 (append vm-konqueror-client-program-switches
327 (list "openURL" url))))
328 (vm-mouse-send-url-to-konqueror url t)))
329 (message "Sending URL to Konqueror... done"))
331 (defun vm-mouse-send-url-to-firefox (url &optional new-window)
332 (message "Sending URL to Mozilla Firebird...")
334 (apply 'vm-run-background-command vm-firefox-program
335 (append vm-firefox-program-switches (list url)))
336 (or (equal 0 (apply 'vm-run-command vm-firefox-client-program
337 (append vm-firefox-client-program-switches
338 (list (format "openURL(%s)" url)))))
339 (vm-mouse-send-url-to-firefox url t)))
340 (message "Sending URL to Mozilla Firefox... done"))
342 (defun vm-mouse-send-url-to-konqueror-new-browser (url)
343 (vm-mouse-send-url-to-konqueror url t))
345 (defun vm-mouse-send-url-to-clipboard (url)
346 (message "Sending URL to X Clipboard...")
347 (cond ((fboundp 'own-selection)
348 (own-selection url 'CLIPBOARD))
349 ((fboundp 'x-own-clipboard)
350 (x-own-clipboard url))
351 ((fboundp 'x-own-selection-internal)
352 (x-own-selection-internal 'CLIPBOARD url)))
353 (message "Sending URL to X Clipboard... done"))
356 (defun vm-mouse-install-mouse ()
357 (cond ((vm-mouse-xemacs-mouse-p)
358 (if (null (lookup-key vm-mode-map 'button2))
359 (define-key vm-mode-map 'button2 'vm-mouse-button-2)))
360 ((vm-mouse-fsfemacs-mouse-p)
361 (if (null (lookup-key vm-mode-map [mouse-2]))
362 (define-key vm-mode-map [mouse-2] 'vm-mouse-button-2))
363 (if vm-popup-menu-on-mouse-3
365 (define-key vm-mode-map [mouse-3] 'ignore)
366 (define-key vm-mode-map [down-mouse-3] 'vm-mouse-button-3))))))
368 (defun vm-run-background-command (command &rest arg-list)
369 (message "vm-run-background-command: %S %S" command arg-list)
370 (apply (function call-process) command
375 (defun vm-run-command (command &rest arg-list)
376 (message "vm-run-command: %S %S" command arg-list)
377 (apply (function call-process) command
379 (get-buffer-create (concat " *" command "*"))
382 ;; return t on zero exit status
383 ;; return (exit-status . stderr-string) on nonzero exit status
384 (defun vm-run-command-on-region (start end output-buffer command
387 ;; use binary coding system in FSF Emacs/MULE
388 (coding-system-for-read (vm-binary-coding-system))
389 (coding-system-for-write (vm-binary-coding-system))
390 (buffer-file-format nil)
391 ;; for DOS/Windows command to tell it that its input is
393 (binary-process-input t)
394 ;; call-process-region calls write-region.
395 ;; don't let it do CR -> LF translation.
396 (selective-display nil)
400 (setq tempfile (vm-make-tempfile-name))
402 (apply 'call-process-region
403 start end command nil
404 (list output-buffer tempfile)
406 (cond ((equal status 0) t)
407 ;; even if exit status non-zero, if there was no
408 ;; diagnostic output the command probably
409 ;; succeeded. I have tried to just use exit status
410 ;; as the failure criterion and users complained.
411 ((equal (nth 7 (file-attributes tempfile)) 0)
412 (message "%s exited non-zero (code %s)" command status)
415 (message "%s exited non-zero (code %s)" command status)
416 (set-buffer (find-file-noselect tempfile))
417 (setq errstring (buffer-string))
419 (cons status errstring)))))
420 (vm-error-free-call 'delete-file tempfile))))
422 ;; stupid yammering compiler
423 (defvar vm-mouse-read-file-name-prompt)
424 (defvar vm-mouse-read-file-name-dir)
425 (defvar vm-mouse-read-file-name-default)
426 (defvar vm-mouse-read-file-name-must-match)
427 (defvar vm-mouse-read-file-name-initial)
428 (defvar vm-mouse-read-file-name-history)
429 (defvar vm-mouse-read-file-name-return-value)
430 (defvar vm-mouse-read-file-name-should-delete-frame)
432 (defun vm-mouse-read-file-name (prompt &optional dir default
433 must-match initial history)
434 "Like read-file-name, except uses a mouse driven interface.
435 HISTORY argument is ignored."
437 (or dir (setq dir default-directory))
438 (set-buffer (vm-make-work-buffer " *Files*"))
439 (use-local-map (make-sparse-keymap))
440 (setq buffer-read-only t
441 default-directory dir)
442 (make-local-variable 'vm-mouse-read-file-name-prompt)
443 (make-local-variable 'vm-mouse-read-file-name-dir)
444 (make-local-variable 'vm-mouse-read-file-name-default)
445 (make-local-variable 'vm-mouse-read-file-name-must-match)
446 (make-local-variable 'vm-mouse-read-file-name-initial)
447 (make-local-variable 'vm-mouse-read-file-name-history)
448 (make-local-variable 'vm-mouse-read-file-name-return-value)
449 (make-local-variable 'vm-mouse-read-file-name-should-delete-frame)
450 (setq vm-mouse-read-file-name-prompt prompt)
451 (setq vm-mouse-read-file-name-dir dir)
452 (setq vm-mouse-read-file-name-default default)
453 (setq vm-mouse-read-file-name-must-match must-match)
454 (setq vm-mouse-read-file-name-initial initial)
455 (setq vm-mouse-read-file-name-history history)
456 (setq vm-mouse-read-file-name-prompt prompt)
457 (setq vm-mouse-read-file-name-return-value nil)
458 (setq vm-mouse-read-file-name-should-delete-frame nil)
459 (if (and vm-mutable-frames vm-frame-per-completion
460 (vm-multiple-frames-possible-p))
462 (setq vm-mouse-read-file-name-should-delete-frame t)
463 (vm-goto-new-frame 'completion)))
464 (switch-to-buffer (current-buffer))
465 (vm-mouse-read-file-name-event-handler)
467 (local-set-key "\C-g" 'vm-mouse-read-file-name-quit-handler)
469 ;; buffer could have been killed
470 (and (boundp 'vm-mouse-read-file-name-return-value)
472 vm-mouse-read-file-name-return-value
473 (kill-buffer (current-buffer))))))
475 (defun vm-mouse-read-file-name-event-handler (&optional string)
476 (let ((key-doc "Click here for keyboard interface.")
479 (cond ((equal string key-doc)
482 (setq vm-mouse-read-file-name-return-value
484 (vm-keyboard-read-file-name
485 vm-mouse-read-file-name-prompt
486 vm-mouse-read-file-name-dir
487 vm-mouse-read-file-name-default
488 vm-mouse-read-file-name-must-match
489 vm-mouse-read-file-name-initial
490 vm-mouse-read-file-name-history)))
491 (vm-mouse-read-file-name-quit-handler t))
492 (quit (vm-mouse-read-file-name-quit-handler))))
493 ((file-directory-p string)
494 (setq default-directory (expand-file-name string)))
495 (t (setq vm-mouse-read-file-name-return-value
496 (expand-file-name string))
497 (vm-mouse-read-file-name-quit-handler t))))
498 (setq buffer-read-only nil)
501 (insert vm-mouse-read-file-name-prompt)
502 (vm-set-region-face start (point) 'bold)
503 (cond ((and (not string) vm-mouse-read-file-name-default)
505 (insert vm-mouse-read-file-name-default)
506 (vm-mouse-set-mouse-track-highlight start (point)))
508 (t (insert default-directory)))
512 (vm-mouse-set-mouse-track-highlight start (point))
513 (vm-set-region-face start (point) 'italic)
515 (setq list (vm-delete-backup-file-names
516 (vm-delete-auto-save-file-names
517 (vm-delete-index-file-names
518 (directory-files default-directory)))))
521 (setq list (vm-delete (lambda (file)
522 (string-match "^\\.\\([^.].*\\)?$" file))
524 ;; append a "/" to directories
525 (setq list (mapcar (lambda (file)
526 (if (file-directory-p file)
531 (vm-show-list list 'vm-mouse-read-file-name-event-handler)
532 (setq buffer-read-only t)))
535 (defun vm-mouse-read-file-name-quit-handler (&optional normal-exit)
537 (if vm-mouse-read-file-name-should-delete-frame
538 (vm-maybe-delete-windows-or-frames-on (current-buffer)))
543 (defvar vm-mouse-read-string-prompt)
544 (defvar vm-mouse-read-string-completion-list)
545 (defvar vm-mouse-read-string-multi-word)
546 (defvar vm-mouse-read-string-return-value)
547 (defvar vm-mouse-read-string-should-delete-frame)
549 (defun vm-mouse-read-string (prompt completion-list &optional multi-word)
551 (set-buffer (vm-make-work-buffer " *Choices*"))
552 (use-local-map (make-sparse-keymap))
553 (setq buffer-read-only t)
554 (make-local-variable 'vm-mouse-read-string-prompt)
555 (make-local-variable 'vm-mouse-read-string-completion-list)
556 (make-local-variable 'vm-mouse-read-string-multi-word)
557 (make-local-variable 'vm-mouse-read-string-return-value)
558 (make-local-variable 'vm-mouse-read-string-should-delete-frame)
559 (setq vm-mouse-read-string-prompt prompt)
560 (setq vm-mouse-read-string-completion-list completion-list)
561 (setq vm-mouse-read-string-multi-word multi-word)
562 (setq vm-mouse-read-string-return-value nil)
563 (setq vm-mouse-read-string-should-delete-frame nil)
564 (if (and vm-mutable-frames vm-frame-per-completion
565 (vm-multiple-frames-possible-p))
567 (setq vm-mouse-read-string-should-delete-frame t)
568 (vm-goto-new-frame 'completion)))
569 (switch-to-buffer (current-buffer))
570 (vm-mouse-read-string-event-handler)
572 (local-set-key "\C-g" 'vm-mouse-read-string-quit-handler)
574 ;; buffer could have been killed
575 (and (boundp 'vm-mouse-read-string-return-value)
577 (if (listp vm-mouse-read-string-return-value)
578 (mapconcat 'identity vm-mouse-read-string-return-value " ")
579 vm-mouse-read-string-return-value)
580 (kill-buffer (current-buffer))))))
582 (defun vm-mouse-read-string-event-handler (&optional string)
583 (let ((key-doc "Click here for keyboard interface.")
584 (bs-doc " .... to go back one word.")
585 (done-doc " .... when you're done.")
588 (cond ((equal string key-doc)
591 (setq vm-mouse-read-string-return-value
592 (vm-keyboard-read-string
593 vm-mouse-read-string-prompt
594 vm-mouse-read-string-completion-list
595 vm-mouse-read-string-multi-word))
596 (vm-mouse-read-string-quit-handler t))
597 (quit (vm-mouse-read-string-quit-handler))))
598 ((equal string bs-doc)
599 (setq vm-mouse-read-string-return-value
602 (nreverse vm-mouse-read-string-return-value)))))
603 ((equal string done-doc)
604 (vm-mouse-read-string-quit-handler t))
605 (t (setq vm-mouse-read-string-return-value
606 (nconc vm-mouse-read-string-return-value
608 (if (null vm-mouse-read-string-multi-word)
609 (vm-mouse-read-string-quit-handler t)))))
610 (setq buffer-read-only nil)
613 (insert vm-mouse-read-string-prompt)
614 (vm-set-region-face start (point) 'bold)
615 (insert (mapconcat 'identity vm-mouse-read-string-return-value " "))
619 (vm-mouse-set-mouse-track-highlight start (point))
620 (vm-set-region-face start (point) 'italic)
622 (if vm-mouse-read-string-multi-word
626 (vm-mouse-set-mouse-track-highlight start (point))
627 (vm-set-region-face start (point) 'italic)
631 (vm-mouse-set-mouse-track-highlight start (point))
632 (vm-set-region-face start (point) 'italic)
635 (vm-show-list vm-mouse-read-string-completion-list
636 'vm-mouse-read-string-event-handler)
637 (setq buffer-read-only t)))
640 (defun vm-mouse-read-string-quit-handler (&optional normal-exit)
642 (if vm-mouse-read-string-should-delete-frame
643 (vm-maybe-delete-windows-or-frames-on (current-buffer)))
650 ;;; vm-mouse.el ends here