From 1604140125ce14c18a9d42a655af40dab892e959 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Sat, 31 Jul 2010 17:26:56 -0400 Subject: [PATCH] Adapt mouse-3 behavior to recent selection changes (Bug#6701). * lisp/mouse.el (mouse-save-then-kill): Doc fix. Deactivate mark before killing to preserve the primary selection. * lisp/term/x-win.el (x-select-text): Doc fix. * src/xselect.c (x_own_selection): Use list4. --- lisp/ChangeLog | 7 ++++ lisp/mouse.el | 91 ++++++++++++++++++++++++++-------------------- lisp/term/x-win.el | 18 +++------ src/ChangeLog | 4 ++ src/xselect.c | 12 +++--- 5 files changed, 74 insertions(+), 58 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index cba5e645f56..e282cef0c30 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,10 @@ +2010-07-31 Chong Yidong + + * mouse.el (mouse-save-then-kill): Doc fix. Deactivate mark + before killing to preserve the primary selection (Bug#6701). + + * term/x-win.el (x-select-text): Doc fix. + 2010-07-31 Alan Mackenzie Enhanced Java Mode to handle Java 5.0 (Tiger) and Java 6 (Mustang). Contributed by Nathaniel Flath. The following diff --git a/lisp/mouse.el b/lisp/mouse.el index 7ba7b031e1e..b928f636bd5 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -1336,16 +1336,23 @@ This does not delete the region; it acts like \\[kill-ring-save]." (undo-boundary)) (defun mouse-save-then-kill (click) - "Save text to point in kill ring; the second time, kill the text. -If the text between point and the mouse is the same as what's -at the front of the kill ring, this deletes the text. -Otherwise, it adds the text to the kill ring, like \\[kill-ring-save], -which prepares for a second click to delete the text. - -If you have selected words or lines, this command extends the -selection through the word or line clicked on. If you do this -again in a different position, it extends the selection again. -If you do this twice in the same position, the selection is killed." + "Set the region according to CLICK; the second time, kill the region. +Assuming this command is bound to a mouse button, CLICK is the +corresponding input event. + +If the region is already active, adjust it. Normally, this +happens by moving either point or mark, whichever is closer, to +the position of CLICK. But if you have selected words or lines, +the region is adjusted by moving point or mark to the word or +line boundary closest to CLICK. + +If the region is inactive, activate it temporarily; set mark at +the original point, and move click to the position of CLICK. + +However, if this command is being called a second time (i.e. the +value of `last-command' is `mouse-save-then-kill'), kill the +region instead. If the text in the region is the same as the +text in the front of the kill ring, just delete it." (interactive "e") (let ((before-scroll (with-current-buffer (window-buffer (posn-window (event-start click))) @@ -1357,44 +1364,50 @@ If you do this twice in the same position, the selection is killed." (this-command this-command)) (if (and (with-current-buffer (window-buffer (posn-window (event-start click))) - (and (mark t) (> (mod mouse-selection-click-count 3) 0) + (and (mark t) + (> (mod mouse-selection-click-count 3) 0) ;; Don't be fooled by a recent click in some other buffer. (eq mouse-selection-click-count-buffer (current-buffer))))) - (if (not (and (eq last-command 'mouse-save-then-kill) - (equal click-posn - (car (cdr-safe (cdr-safe mouse-save-then-kill-posn)))))) - ;; Find both ends of the object selected by this click. - (let* ((range - (mouse-start-end click-posn click-posn - mouse-selection-click-count))) - ;; Move whichever end is closer to the click. - ;; That's what xterm does, and it seems reasonable. - (if (< (abs (- click-posn (mark t))) - (abs (- click-posn (point)))) - (set-mark (car range)) - (goto-char (nth 1 range))) - ;; We have already put the old region in the kill ring. - ;; Replace it with the extended region. - ;; (It would be annoying to make a separate entry.) - (kill-new (buffer-substring (point) (mark t)) t) - (mouse-set-region-1) - ;; Arrange for a repeated mouse-3 to kill this region. - (setq mouse-save-then-kill-posn - (list (car kill-ring) (point) click-posn))) - ;; If we click this button again without moving it, - ;; that time kill. - (mouse-save-then-kill-delete-region (mark) (point)) - (setq mouse-selection-click-count 0) - (setq mouse-save-then-kill-posn nil)) + (if (and (eq last-command 'mouse-save-then-kill) + (equal click-posn (nth 2 mouse-save-then-kill-posn))) + ;; If we click this button again without moving it, kill. + (progn + ;; Call `deactivate-mark' to save the primary selection. + (deactivate-mark) + (mouse-save-then-kill-delete-region (mark) (point)) + (setq mouse-selection-click-count 0) + (setq mouse-save-then-kill-posn nil)) + ;; Find both ends of the object selected by this click. + (let* ((range + (mouse-start-end click-posn click-posn + mouse-selection-click-count))) + ;; Move whichever end is closer to the click. + ;; That's what xterm does, and it seems reasonable. + (if (< (abs (- click-posn (mark t))) + (abs (- click-posn (point)))) + (set-mark (car range)) + (goto-char (nth 1 range))) + ;; We have already put the old region in the kill ring. + ;; Replace it with the extended region. + ;; (It would be annoying to make a separate entry.) + (kill-new (buffer-substring (point) (mark t)) t) + (mouse-set-region-1) + ;; Arrange for a repeated mouse-3 to kill this region. + (setq mouse-save-then-kill-posn + (list (car kill-ring) (point) click-posn)))) + (if (and (eq last-command 'mouse-save-then-kill) mouse-save-then-kill-posn (eq (car mouse-save-then-kill-posn) (car kill-ring)) - (equal (cdr mouse-save-then-kill-posn) (list (point) click-posn))) + (equal (cdr mouse-save-then-kill-posn) + (list (point) click-posn))) ;; If this is the second time we've called ;; mouse-save-then-kill, delete the text from the buffer. (progn - (mouse-save-then-kill-delete-region (point) (mark)) + ;; Call `deactivate-mark' to save the primary selection. + (deactivate-mark) + (mouse-save-then-kill-delete-region (point) (mark t)) ;; After we kill, another click counts as "the first time". (setq mouse-save-then-kill-posn nil)) ;; This is not a repetition. diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el index 213f7f5230b..65ba534de42 100644 --- a/lisp/term/x-win.el +++ b/lisp/term/x-win.el @@ -1234,18 +1234,12 @@ This is in addition to, but in preference to, the primary selection." (defun x-select-text (text &optional push) "Select TEXT, a string, according to the window system. - -On X, put TEXT in the primary X selection. For backward -compatibility with older X applications, set the value of X cut -buffer 0 as well, and if the optional argument PUSH is non-nil, -rotate the cut buffers. If `x-select-enable-clipboard' is -non-nil, copy the text to the X clipboard as well. - -On Windows, make TEXT the current selection. If -`x-select-enable-clipboard' is non-nil, copy the text to the -clipboard as well. The argument PUSH is ignored. - -On Nextstep, put TEXT in the pasteboard; PUSH is ignored." +If `x-select-enable-clipboard' is non-nil, copy TEXT to the +clipboard. If `x-select-enable-primary' is non-nil, put TEXT in +the primary selection. For backward compatibility with older X +applications, this function also sets the value of X cut buffer +0, and, if the optional argument PUSH is non-nil, rotates the cut +buffers." ;; With multi-tty, this function may be called from a tty frame. (when (eq (framep (selected-frame)) 'x) ;; Don't send the cut buffer too much text. diff --git a/src/ChangeLog b/src/ChangeLog index e2832c49bde..ee745778951 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2010-07-31 Chong Yidong + + * xselect.c (x_own_selection): Use list4. + 2010-07-30 Dan Nicolaescu * buffer.c (Qwindow): Do not define, already defined in data.c. diff --git a/src/xselect.c b/src/xselect.c index 69d9ca868c4..ceb856b8dae 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -392,7 +392,7 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value) selecting_window = FRAME_X_WINDOW (sf); display = FRAME_X_DISPLAY (sf); dpyinfo = FRAME_X_DISPLAY_INFO (sf); - + CHECK_SYMBOL (selection_name); selection_atom = symbol_to_x_atom (dpyinfo, display, selection_name); @@ -410,10 +410,8 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value) Lisp_Object prev_value; selection_time = long_to_cons ((unsigned long) time); - selection_data = Fcons (selection_name, - Fcons (selection_value, - Fcons (selection_time, - Fcons (selected_frame, Qnil)))); + selection_data = list4 (selection_name, selection_value, + selection_time, selected_frame); prev_value = assq_no_quit (selection_name, Vselection_alist); Vselection_alist = Fcons (selection_data, Vselection_alist); @@ -1015,7 +1013,7 @@ x_handle_selection_clear (struct input_event *event) } } UNBLOCK_INPUT; - + selection_symbol = x_atom_to_symbol (display, selection); local_selection_data = assq_no_quit (selection_symbol, Vselection_alist); @@ -2416,7 +2414,7 @@ Positive N means shift the values forward, negative means backward. */) Atom props[8]; Display *display; struct frame *sf = SELECTED_FRAME (); - + check_x (); if (! FRAME_X_P (sf)) -- 2.39.2