From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Ignacio Casso Newsgroups: gmane.emacs.bugs Subject: bug#53894: 27.2; Clipboard copy -> C-y -> M-y -> Same clipboard copy does not push to kill ring Date: Tue, 01 Mar 2022 16:29:36 +0100 Message-ID: References: <877da2yjze.fsf@yahoo.com> <87iltm7upm.fsf@gnus.org> <87leyiw6uu.fsf@yahoo.com> <87wni1tzzl.fsf@yahoo.com> <87pmnttw78.fsf@yahoo.com> <87leyhtv9q.fsf@yahoo.com> <87wni0str6.fsf@yahoo.com> <87h78j6bz0.fsf@yahoo.com> <87czj73xw8.fsf@yahoo.com> <87wnhfoy5h.fsf@hotmail.com> <87sfs233lx.fsf@yahoo.com> <83fso1lsjf.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="34039"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: mu4e 1.6.10; emacs 29.0.50 Cc: luangruo@yahoo.com, larsi@gnus.org, 53894@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Tue Mar 01 17:13:37 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nP583-0008gp-U3 for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 01 Mar 2022 17:13:36 +0100 Original-Received: from localhost ([::1]:39620 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP582-0008Sk-DN for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 01 Mar 2022 11:13:34 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:50900) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP56Y-00075t-8O for bug-gnu-emacs@gnu.org; Tue, 01 Mar 2022 11:12:02 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:44190) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nP56X-0000KK-Vm for bug-gnu-emacs@gnu.org; Tue, 01 Mar 2022 11:12:01 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1nP56X-0000zL-Mx for bug-gnu-emacs@gnu.org; Tue, 01 Mar 2022 11:12:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Ignacio Casso Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 01 Mar 2022 16:12:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 53894 X-GNU-PR-Package: emacs Original-Received: via spool by 53894-submit@debbugs.gnu.org id=B53894.16461511153780 (code B ref 53894); Tue, 01 Mar 2022 16:12:01 +0000 Original-Received: (at 53894) by debbugs.gnu.org; 1 Mar 2022 16:11:55 +0000 Original-Received: from localhost ([127.0.0.1]:38085 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nP56Q-0000ys-9j for submit@debbugs.gnu.org; Tue, 01 Mar 2022 11:11:55 -0500 Original-Received: from mail-oln040092075109.outbound.protection.outlook.com ([40.92.75.109]:60064 helo=EUR04-VI1-obe.outbound.protection.outlook.com) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nP56N-0000ye-JM for 53894@debbugs.gnu.org; Tue, 01 Mar 2022 11:11:52 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=EZaRYZmsbYwzbiAlOYZWFXTuuL9fB8O68AwGGhQctnxPJN5tVUPFWIxIx5IyYmrPayxJU7/tsmSzZ6RtdbGNctsj4yGPjbfOgQlZFbXfVP+Znc64bMsRe2urMVNGAmwwVPSArC4Xgfi1nTJEljahyfQ2SoZln+/Y7EjmYRmZxfMWtptQEaxLcSmyhEEvdfbtUw54ijrh8pW5T5IYF+ENtEEZBqIBxogi61UlhfTLdxx1d65dZJYSiRNlN9cR/qXY/SxaY7oopfeIuYjbDgNjYm0LgpQSHZIC2EfByFEWdqi64qb6Mtw7WvJM3cytaYYTSlJ0DecVBCcH079Ukz6FdQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=91URT9iuktKmA31T7QcxbkPZSMMWQTjcZhq/FWRLvfU=; b=G3Ikh1ZAj0pm8+wKTbn5A7sJucB6fOTtV0/3QoUrml+WMVC7iJu7JLRPUTsIMK3Jq4GRGkbRUweWqEnR9qF+Jy7pqu6YO3d8tOcA2mfK6eqeh0vFMU58y4ltggFO4iloq7L/1yxNyX2eYL3J/8amuy82AJ5IZoRBAusz9Olq1nfOc4DO9FOBOdDYj0DkY1Q3FoTEySZZXiXhrhwWdzeuN2sP62V7VsnfGMvfiCayMefTzYZ16u9AzpQPJ4SZC0JwmfDz09VnUoywg1H+ghSwkhuNgZ4FcC59SPgEEAJJmQWDY36cFQARWyH7zhSLH+J1DSnsQIEpZsfSBn9aJrDjKA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hotmail.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=91URT9iuktKmA31T7QcxbkPZSMMWQTjcZhq/FWRLvfU=; b=TNhLR9luKYDGYA9X0Wfme75a3aL3+jWlXzKRV2HDxyatWu0Furvph+Wo1D3MTtHhDQ5jv3XS92ofS0sGWqX4XLC5tqDPjFzyPF6p6H+zb5ZBpoGUdIFUKvew8Ial/2nKVSuk+Pn+xh2i+l1Al2WLQHdMi8v2BOmvZz55uCaMk4uZ9N4PAPv1YcNy9HXrcPcMo2z0YWNYr/ssjzxsdfOP2RNsoreOxJzRfyGLopTqjSGPsIQovcF1XoLGDDM+DfDLZk200CBZSJ1u6GYYwgmrJHnOD7hlJ7Qv9erZeEWi32cn0bTG1vEi2j043XgJ4v77ETcPzfyDgGg6yLHxRbZ/Og== Original-Received: from PAXPR06MB7760.eurprd06.prod.outlook.com (2603:10a6:102:155::8) by DB8PR06MB6123.eurprd06.prod.outlook.com (2603:10a6:10:107::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5017.21; Tue, 1 Mar 2022 16:11:44 +0000 Original-Received: from PAXPR06MB7760.eurprd06.prod.outlook.com ([fe80::89d5:1159:122b:2b2f]) by PAXPR06MB7760.eurprd06.prod.outlook.com ([fe80::89d5:1159:122b:2b2f%6]) with mapi id 15.20.5017.027; Tue, 1 Mar 2022 16:11:44 +0000 In-reply-to: <83fso1lsjf.fsf@gnu.org> X-TMN: [Q/S6rVVD352iFkZGAeUbqPpzCbo7aRZM] X-ClientProxiedBy: PR2P264CA0037.FRAP264.PROD.OUTLOOK.COM (2603:10a6:101:1::25) To PAXPR06MB7760.eurprd06.prod.outlook.com (2603:10a6:102:155::8) X-Microsoft-Original-Message-ID: <87pmn5hcue.fsf@hotmail.com> X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 1300e459-170f-4f10-0820-08d9fb9e2d59 X-MS-TrafficTypeDiagnostic: DB8PR06MB6123:EE_ X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: c5D8ddNhunolP+UmrIL+sD4dcDgLAYyl8MrQwHulZGEnPEukW0tVY+w1TZFX2Tb2C51rDdFesH4tnMWJAMn+L5TJyA2Ox3DJcQJW5o83wFtQyoVhAXQVRGsUBIrJqmHa3w9asdnr61PpVlyVJz9WXkrQj/u8lQNWdISfUI0i0U34Tn3i0QEpttzkL6leafUfPdPSIyiIIe7JfGx0V7Ouy9NiZ+s9g490FYvm6qjISTxv3dqSgOKjQNkYlJ8TrLLAuRi9V6WI8htYJBfmO5xpPP3g5RGWWVladv0fWT3MTeRo0bIo73zFEyjrDYmYl16N35xg5e2euwTz21OVthaC6yU4GKic0V9LZBj0u8YQwQkX79CZVtv8PN60IaJmvcjx2zQiL+SD2bXC9MNIBdgSoYCKDY1vb9wgBHNiwBxHqGSW3e65/FLlCaJvdkk3guH9Bb0HoQrWZg7kRv3/sVOc9cU3Q1rvxNIIirZdTdcMCQANIbIsQRoHeFnvTFvjD6tFmGDl7LFffmZ1H5r27L0Wxj7WdBBvOxfxLt6fwdo5ykdBgHVVz5GLt++8Q2oEcxFQFl98dPJwQc7CdZmZ3I1/pQ== X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: woXSDLDBnZowQqpYWKmTiO2LftcZQfAlH7ak9zMC5UeQhVJVRu6ETyehyhIPrilcoi2IeiB2Y3VU1ZRUOjOE7aOP2n95fUoacCNcp5JfXqBZppQ5aURg9QzDgpw2AWXwz5og7RVI1u6euOeLQFT7YhmKOyVzMeTWMCgopJOABHHkwVee65UMEpEVeHB8rbpqCBOeF2KkdJPL3B6HCsrBzeNsJH+UWKU2VkndoKf7LJTmnXr4lUURmDvM9k0Sg/U8EZigKfdUdpxB7A97xtGirJL1LBss0FrgI3sFg8BSPuEfordnwtk1jObDcZ2orEWMzB31+If6ZytQ+ustjqAu2qxob3h/LtYsPCIWcr6RkHFOWkTL6bwpIPoRtAbnbGYSxsoCT6vOo9suaq+pufgclXP4El1r2mr8gqaCik7v0+scFCfXLghR0kIuM56fFMKcv83Fv+OWULR1stIzyzl0VG5lz+Rx4GZYd8p8zq+wT+narbdgqBvnbgW/nW3Z6SaUhvcUDYVxXm+R7Jq+hRDqdrSfqjKb7MvVEBDLtJxkOl3LGh3qqnCirpRuscr5jStDnl845B2KSfBr1O5SaJ981AXFWxBlF5bnBaqML8Jyz0IeqFKNAzUzwVvZj5HfBwWO2qk9GPCx2UCX2TlNfHRZtkeuGS9d6awfonaK+bhn5jQaBplydmlHc7cqFYieXIMOvvXAucbb2FLl99SFgh1opBfETtOZw0xCej2fXNmiIvgvqdNleMj0C+mjiy cJ5nQ0aWV6ma/qc8a/RDmI+Lcvrcl+71eZWHzphmbtTSmdn4YqqBrncGmiUg1S+IpIn3YDPZD9eyva/lIIlmwhnuYLPG++Y7hA X-OriginatorOrg: sct-15-20-4755-11-msonline-outlook-6e454.templateTenant X-MS-Exchange-CrossTenant-Network-Message-Id: 1300e459-170f-4f10-0820-08d9fb9e2d59 X-MS-Exchange-CrossTenant-AuthSource: PAXPR06MB7760.eurprd06.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Mar 2022 16:11:44.3236 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB8PR06MB6123 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:227880 Archived-At: --=-=-= Content-Type: text/plain > Not just comment: we should document that every implementation of > gui-get-selection should return either a valid timestamp (and say what > is a valid timestamp) or nil, meaning 'CLIPBOARD 'TIMESTAMP is > unsupported. You are right that it is a dangerous assumption, and it's also hard to test and probably unnecessary. So I have changed the code to check the window-system variable instead and only use timestamps for X and haiku (I don't actually know the list of systems that support it, I have included haiku because it is also in the list of systems that support reliably gui-backend-selection-owner-p, according to the code). I also have defined the functions gui--set-last-clipboard/primary-selection and gui--clipboard/primary-selection-unchanged-p to just change the lines (setq gui--last-selected-text-clipboard/primary text) and (equal text gui--last-selected-text-clipboard/primary) with them. They behave exactly the same for systems other than X and haiku, and are backwards compatible with setting or reading directly the original gui--last-selected-text-clipboard/primary variable in other places. I have assumed this last thing (being backwards compatible) was the reason why Po Lu suggested to use text properties instead of changing the gui--last-selected-text-clipboard/primary variable, so I have taken the liberty of moving away from that idea and using the new variables gui--last-selection-timestamp-clipboard and gui--last-selection-timestamp-primary instead, which simplify the code. So here is the final, hopefully definitive patch, attached to the email and commented below: --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-same-fix-but-with-functions.patch Content-Description: Patch for bug#53894 >From fb91fa4ac94fd57136febec4427e28803afd8c58 Mon Sep 17 00:00:00 2001 From: Ignacio Date: Tue, 1 Mar 2022 11:09:15 +0100 Subject: [PATCH] same fix, but with functions --- lisp/menu-bar.el | 2 +- lisp/select.el | 91 ++++++++++++++++++++++++++++++++++----------- lisp/term/pc-win.el | 8 ++++ 3 files changed, 78 insertions(+), 23 deletions(-) diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index ab64928fe7..7ff5439f7c 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -606,7 +606,7 @@ clipboard-yank "Insert the clipboard contents, or the last stretch of killed text." (interactive "*") (let ((select-enable-clipboard t) - ;; Ensure that we defeat the DWIM login in `gui-selection-value'. + ;; Ensure that we defeat the DWIM logic in `gui-selection-value'. (gui--last-selected-text-clipboard nil)) (yank))) diff --git a/lisp/select.el b/lisp/select.el index 42b50c44e6..708034f6bd 100644 --- a/lisp/select.el +++ b/lisp/select.el @@ -25,9 +25,10 @@ ;; Based partially on earlier release by Lucid. ;; The functionality here is divided in two parts: -;; - Low-level: gui-get-selection, gui-set-selection, gui-selection-owner-p, -;; gui-selection-exists-p are the backend-dependent functions meant to access -;; various kinds of selections (CLIPBOARD, PRIMARY, SECONDARY). +;; - Low-level: gui-backend-get-selection, gui-backend-set-selection, +;; gui-backend-selection-owner-p, gui-backend-selection-exists-p are +;; the backend-dependent functions meant to access various kinds of +;; selections (CLIPBOARD, PRIMARY, SECONDARY). ;; - Higher-level: gui-select-text and gui-selection-value go together to ;; access the general notion of "GUI selection" for interoperation with other ;; applications. This can use either the clipboard or the primary selection, @@ -108,9 +109,10 @@ select-enable-primary :group 'killing :version "25.1") -;; We keep track of the last text selected here, so we can check the -;; current selection against it, and avoid passing back our own text -;; from gui-selection-value. We track both +;; We keep track of the last selection here, so we can check the +;; current selection against it, and avoid passing back with +;; gui-selection-value the same text we previously killed or +;; yanked. We track both ;; separately in case another X application only sets one of them ;; we aren't fooled by the PRIMARY or CLIPBOARD selection staying the same. @@ -119,6 +121,50 @@ gui--last-selected-text-clipboard (defvar gui--last-selected-text-primary nil "The value of the PRIMARY selection last seen.") +(defvar gui--last-selection-timestamp-clipboard nil + "The timestamp of the CLIPBOARD selection last seen.") +(defvar gui--last-selection-timestamp-primary nil + "The timestamp of the PRIMARY selection last seen.") + +(defun gui--set-last-clipboard-selection (text) + "Save last clipboard selection, to be able to check later whether +it has changed. Save the selected text, and for window systems +that support it, the selection timestamp." + (setq gui--last-selected-text-clipboard text) + (when (memq window-system '(x haiku)) + (setq gui--last-selection-timestamp-clipboard + (gui-get-selection 'CLIPBOARD 'TIMESTAMP)))) + +(defun gui--set-last-primary-selection (text) + "Save last primary selection, to be able to check later whether +it has changed. Save the selected text, and for window systems +that support it, the selection timestamp." + (setq gui--last-selected-text-primary text) + (when (memq window-system '(x haiku)) + (setq gui--last-selection-timestamp-primary + (gui-get-selection 'PRIMARY 'TIMESTAMP)))) + +(defun gui--clipboard-selection-unchanged-p (text) + "Check whether the clipboard selection is the same as the last +time it was read, by comparing the selected text, and for window +systems that support it, the selection timestamp." + (and + (equal text gui--last-selected-text-clipboard) + (or (not (memq window-system '(x haiku))) + (eq gui--last-selection-timestamp-clipboard + (gui-get-selection 'CLIPBOARD 'TIMESTAMP))))) + +(defun gui--primary-selection-unchanged-p (text) + "Check whether the primary selection is the same as the last +time it was read, by comparing the selected text, and for window +systems that support it, the selection timestamp." + (and + (equal text gui--last-selected-text-primary) + (or (not (memq window-system '(x haiku))) + (eq gui--last-selection-timestamp-primary + (gui-get-selection 'PRIMARY 'TIMESTAMP))))) + + (defun gui-select-text (text) "Select TEXT, a string, according to the window system. if `select-enable-clipboard' is non-nil, copy TEXT to the system's clipboard. @@ -127,14 +173,14 @@ gui-select-text MS-Windows does not have a \"primary\" selection." (when select-enable-primary (gui-set-selection 'PRIMARY text) - (setq gui--last-selected-text-primary text)) + (gui--set-last-primary-selection text)) (when select-enable-clipboard ;; When cutting, the selection is cleared and PRIMARY ;; set to the empty string. Prevent that, PRIMARY ;; should not be reset by cut (Bug#16382). (setq saved-region-selection text) (gui-set-selection 'CLIPBOARD text) - (setq gui--last-selected-text-clipboard text))) + (gui--set-last-clipboard-selection text))) (define-obsolete-function-alias 'x-select-text 'gui-select-text "25.1") (defcustom x-select-request-type nil @@ -175,6 +221,7 @@ gui--selection-value-internal ;; some other window systems. (memq window-system '(x haiku)) (eq type 'CLIPBOARD) + ;; Should we unify this with the DWIM logic? (gui-backend-selection-owner-p type)) (let ((request-type (if (memq window-system '(x pgtk haiku)) (or x-select-request-type @@ -197,19 +244,18 @@ gui-selection-value (let ((text (gui--selection-value-internal 'CLIPBOARD))) (when (string= text "") (setq text nil)) - ;; When `select-enable-clipboard' is non-nil, - ;; killing/copying text (with, say, `C-w') will push the - ;; text to the clipboard (and store it in - ;; `gui--last-selected-text-clipboard'). We check - ;; whether the text on the clipboard is identical to this - ;; text, and if so, we report that the clipboard is - ;; empty. See (bug#27442) for further discussion about - ;; this DWIM action, and possible ways to make this check - ;; less fragile, if so desired. + ;; Check the CLIPBOARD selection for 'newness', i.e., + ;; whether it is different from the last time we did a + ;; yank operation or whether it was set by Emacs itself + ;; with a kill operation, since in both cases the text + ;; will already be in the kill ring. See (bug#27442) and + ;; (bug#53894) for further discussion about this DWIM + ;; action, and possible ways to make this check less + ;; fragile, if so desired. (prog1 - (unless (equal text gui--last-selected-text-clipboard) + (unless (gui--clipboard-selection-unchanged-p text) text) - (setq gui--last-selected-text-clipboard text))))) + (gui--set-last-clipboard-selection text))))) (primary-text (when select-enable-primary (let ((text (gui--selection-value-internal 'PRIMARY))) @@ -218,9 +264,9 @@ gui-selection-value ;; from what we remembered them to be last time we did a ;; cut/paste operation. (prog1 - (unless (equal text gui--last-selected-text-primary) + (unless (gui--primary-selection-unchanged-p text) text) - (setq gui--last-selected-text-primary text)))))) + (gui--set-last-primary-selection text)))))) ;; As we have done one selection, clear this now. (setq next-selection-coding-system nil) @@ -239,7 +285,8 @@ gui-selection-value ;; timestamps there is no way to know what the 'correct' value to ;; return is. The nice thing to do would be to tell the user we ;; saw multiple possible selections and ask the user which was the - ;; one they wanted. + ;; one they wanted. EDIT: We do have timestamps now (for most + ;; window systems), so we can return the newer. (or clip-text primary-text) )) diff --git a/lisp/term/pc-win.el b/lisp/term/pc-win.el index 327d51f275..289a1414c6 100644 --- a/lisp/term/pc-win.el +++ b/lisp/term/pc-win.el @@ -246,6 +246,14 @@ w16-selection-owner-p ;; if it does not exist, or exists and compares ;; equal with the last text we've put into the ;; Windows clipboard. + ;; EDIT: that variable is actually the last text any program + ;; (not just Emacs) has put into the windows clipboard (up + ;; until the last time Emacs read or set the clipboard), so + ;; it's not suitable for checking actual selection + ;; ownership. This does not result in a bug for any of the + ;; current uses of gui-backend-selection-owner however, since + ;; they don't actually care about selection ownership, but + ;; about the selected text having changed. (cond ((not text) t) ((equal text gui--last-selected-text-clipboard) text) -- 2.25.1 --=-=-= Content-Type: text/plain > --- > lisp/menu-bar.el | 2 +- > lisp/select.el | 91 ++++++++++++++++++++++++++++++++++----------- > lisp/term/pc-win.el | 8 ++++ > 3 files changed, 78 insertions(+), 23 deletions(-) > > diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el > index ab64928fe7..7ff5439f7c 100644 > --- a/lisp/menu-bar.el > +++ b/lisp/menu-bar.el > @@ -606,7 +606,7 @@ clipboard-yank > "Insert the clipboard contents, or the last stretch of killed text." > (interactive "*") > (let ((select-enable-clipboard t) > - ;; Ensure that we defeat the DWIM login in `gui-selection-value'. > + ;; Ensure that we defeat the DWIM logic in `gui-selection-value'. > (gui--last-selected-text-clipboard nil)) > (yank))) - DWIM login -> DWIM logic (typo) - (let ((gui--last-selected-text-clipboard nil))) still achieves the same after the changes > diff --git a/lisp/select.el b/lisp/select.el > index 42b50c44e6..708034f6bd 100644 > --- a/lisp/select.el > +++ b/lisp/select.el > @@ -25,9 +25,10 @@ > ;; Based partially on earlier release by Lucid. > > ;; The functionality here is divided in two parts: > -;; - Low-level: gui-get-selection, gui-set-selection, gui-selection-owner-p, > -;; gui-selection-exists-p are the backend-dependent functions meant to access > -;; various kinds of selections (CLIPBOARD, PRIMARY, SECONDARY). > +;; - Low-level: gui-backend-get-selection, gui-backend-set-selection, > +;; gui-backend-selection-owner-p, gui-backend-selection-exists-p are > +;; the backend-dependent functions meant to access various kinds of > +;; selections (CLIPBOARD, PRIMARY, SECONDARY). > ;; - Higher-level: gui-select-text and gui-selection-value go together to > ;; access the general notion of "GUI selection" for interoperation with other > ;; applications. This can use either the clipboard or the primary selection, - gui-selection-owner-p -> gui-backend-selection-owner-p (the former does not exist) - gui-selection-exists-p -> gui-backend-selection-exists-p (the former does not exist) - gui-get-selection -> gui-backend-get-selection (the former does exist, but the later is lower lever, and I assumed that if the previous needed to be updated this one probably too) - gui-set-selection -> gui-backend-set-selection (same as above) > @@ -108,9 +109,10 @@ select-enable-primary > :group 'killing > :version "25.1") > > -;; We keep track of the last text selected here, so we can check the > -;; current selection against it, and avoid passing back our own text > -;; from gui-selection-value. We track both > +;; We keep track of the last selection here, so we can check the > +;; current selection against it, and avoid passing back with > +;; gui-selection-value the same text we previously killed or > +;; yanked. We track both > ;; separately in case another X application only sets one of them > ;; we aren't fooled by the PRIMARY or CLIPBOARD selection staying the same. > - Updated comment > @@ -119,6 +121,50 @@ gui--last-selected-text-clipboard > (defvar gui--last-selected-text-primary nil > "The value of the PRIMARY selection last seen.") > > +(defvar gui--last-selection-timestamp-clipboard nil > + "The timestamp of the CLIPBOARD selection last seen.") > +(defvar gui--last-selection-timestamp-primary nil > + "The timestamp of the PRIMARY selection last seen.") > + > +(defun gui--set-last-clipboard-selection (text) > + "Save last clipboard selection, to be able to check later whether > +it has changed. Save the selected text, and for window systems > +that support it, the selection timestamp." > + (setq gui--last-selected-text-clipboard text) > + (when (memq window-system '(x haiku)) > + (setq gui--last-selection-timestamp-clipboard > + (gui-get-selection 'CLIPBOARD 'TIMESTAMP)))) > + > +(defun gui--set-last-primary-selection (text) > + "Save last primary selection, to be able to check later whether > +it has changed. Save the selected text, and for window systems > +that support it, the selection timestamp." > + (setq gui--last-selected-text-primary text) > + (when (memq window-system '(x haiku)) > + (setq gui--last-selection-timestamp-primary > + (gui-get-selection 'PRIMARY 'TIMESTAMP)))) > + > +(defun gui--clipboard-selection-unchanged-p (text) > + "Check whether the clipboard selection is the same as the last > +time it was read, by comparing the selected text, and for window > +systems that support it, the selection timestamp." > + (and > + (equal text gui--last-selected-text-clipboard) > + (or (not (memq window-system '(x haiku))) > + (eq gui--last-selection-timestamp-clipboard > + (gui-get-selection 'CLIPBOARD 'TIMESTAMP))))) > + > +(defun gui--primary-selection-unchanged-p (text) > + "Check whether the primary selection is the same as the last > +time it was read, by comparing the selected text, and for window > +systems that support it, the selection timestamp." > + (and > + (equal text gui--last-selected-text-primary) > + (or (not (memq window-system '(x haiku))) > + (eq gui--last-selection-timestamp-primary > + (gui-get-selection 'PRIMARY 'TIMESTAMP))))) > + > + > (defun gui-select-text (text) > "Select TEXT, a string, according to the window system. > if `select-enable-clipboard' is non-nil, copy TEXT to the system's clipboard. - New variables gui--last-selection-timestamp-clipboard and gui--last-selection-timestamp-primary. - New functions gui--set-last-clipboard-selection and gui--set-last-primary-selection. - New functions gui--clipboard-selection-unchanged-p and gui--primary-selection-unchanged-p. > @@ -127,14 +173,14 @@ gui-select-text > MS-Windows does not have a \"primary\" selection." > (when select-enable-primary > (gui-set-selection 'PRIMARY text) > - (setq gui--last-selected-text-primary text)) > + (gui--set-last-primary-selection text)) > (when select-enable-clipboard > ;; When cutting, the selection is cleared and PRIMARY > ;; set to the empty string. Prevent that, PRIMARY > ;; should not be reset by cut (Bug#16382). > (setq saved-region-selection text) > (gui-set-selection 'CLIPBOARD text) > - (setq gui--last-selected-text-clipboard text))) > + (gui--set-last-clipboard-selection text))) > (define-obsolete-function-alias 'x-select-text 'gui-select-text "25.1") > > (defcustom x-select-request-type nil Using new functions instead > @@ -175,6 +221,7 @@ gui--selection-value-internal > ;; some other window systems. > (memq window-system '(x haiku)) > (eq type 'CLIPBOARD) > + ;; Should we unify this with the DWIM logic? > (gui-backend-selection-owner-p type)) > (let ((request-type (if (memq window-system '(x pgtk haiku)) > (or x-select-request-type I consider that check to be conceptually part of the same DWIM logic, and feel that maybe both checks should go together in the code. However I decided to preserve the code structure for now, since I wanted to make as little changes as possible, having the ownership check there can save unnecessary computations, and the check is mostly redundant now otherwise. > @@ -197,19 +244,18 @@ gui-selection-value > (let ((text (gui--selection-value-internal 'CLIPBOARD))) > (when (string= text "") > (setq text nil)) > - ;; When `select-enable-clipboard' is non-nil, > - ;; killing/copying text (with, say, `C-w') will push the > - ;; text to the clipboard (and store it in > - ;; `gui--last-selected-text-clipboard'). We check > - ;; whether the text on the clipboard is identical to this > - ;; text, and if so, we report that the clipboard is > - ;; empty. See (bug#27442) for further discussion about > - ;; this DWIM action, and possible ways to make this check > - ;; less fragile, if so desired. > + ;; Check the CLIPBOARD selection for 'newness', i.e., > + ;; whether it is different from the last time we did a > + ;; yank operation or whether it was set by Emacs itself > + ;; with a kill operation, since in both cases the text > + ;; will already be in the kill ring. See (bug#27442) and > + ;; (bug#53894) for further discussion about this DWIM > + ;; action, and possible ways to make this check less > + ;; fragile, if so desired. Updated comment > (prog1 > - (unless (equal text gui--last-selected-text-clipboard) > + (unless (gui--clipboard-selection-unchanged-p text) > text) > - (setq gui--last-selected-text-clipboard text))))) > + (gui--set-last-clipboard-selection text))))) > (primary-text > (when select-enable-primary > (let ((text (gui--selection-value-internal 'PRIMARY))) Using new functions instead > @@ -218,9 +264,9 @@ gui-selection-value > ;; from what we remembered them to be last time we did a > ;; cut/paste operation. > (prog1 > - (unless (equal text gui--last-selected-text-primary) > + (unless (gui--primary-selection-unchanged-p text) > text) > - (setq gui--last-selected-text-primary text)))))) > + (gui--set-last-primary-selection text)))))) > > ;; As we have done one selection, clear this now. > (setq next-selection-coding-system nil) Using new functions instead > @@ -239,7 +285,8 @@ gui-selection-value > ;; timestamps there is no way to know what the 'correct' value to > ;; return is. The nice thing to do would be to tell the user we > ;; saw multiple possible selections and ask the user which was the > - ;; one they wanted. > + ;; one they wanted. EDIT: We do have timestamps now (for most > + ;; window systems), so we can return the newer. > (or clip-text primary-text) > )) > > diff --git a/lisp/term/pc-win.el b/lisp/term/pc-win.el > index 327d51f275..289a1414c6 100644 > --- a/lisp/term/pc-win.el > +++ b/lisp/term/pc-win.el An unrelated issue which could be solved with timestamps, but the comment must be old and says we don't have them. Just updated the comment saying we do have them now. > @@ -246,6 +246,14 @@ w16-selection-owner-p > ;; if it does not exist, or exists and compares > ;; equal with the last text we've put into the > ;; Windows clipboard. > + ;; EDIT: that variable is actually the last text any program > + ;; (not just Emacs) has put into the windows clipboard (up > + ;; until the last time Emacs read or set the clipboard), so > + ;; it's not suitable for checking actual selection > + ;; ownership. This does not result in a bug for any of the > + ;; current uses of gui-backend-selection-owner however, since > + ;; they don't actually care about selection ownership, but > + ;; about the selected text having changed. > (cond > ((not text) t) > ((equal text gui--last-selected-text-clipboard) text) > -- A comment on the only other use of gui--last-selected-text-clipboard I found, since it is and was incorrect. It behaves exactly the same after the new changes though. --=-=-=--