From 3a53ad8130d89b190f7c4982708c2ffe557c08b6 Mon Sep 17 00:00:00 2001 From: iamnbutler Date: Tue, 20 Oct 2026 13:37:38 -0400 Subject: [PATCH 1/5] native2: selecting web text focuses the page, so Edit > Copy copies it (#188) Why: native2/Sources/DesktopMac/WebText.swift | Safari focuses its address field when it opens a page in the background, so Copy after a marker selection copied the URL; focus the web area before selecting, since focusing can move the selection Why: scripts/live-check.mjs | Safari disables Copy and has no in-window keyboard focus while inactive, so the #88 copy runs Edit > Copy after desktop_activate; background Command-C and Edit > Copy are refused --- CHANGELOG.md | 4 ++++ dist/tools.js | 2 +- docs/tools.md | 2 +- native2/Sources/DesktopMac/Text.swift | 2 ++ native2/Sources/DesktopMac/WebText.swift | 9 +++++++++ native2/Sources/DesktopProtocol/ContractText.swift | 2 +- scripts/live-check.mjs | 13 ++++++++----- src/tools.ts | 2 +- 8 files changed, 27 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7be0c771..5b472f55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ Notable changes to Desktop Tools, newest first. Each release's GitHub release no ## [Unreleased] +### Fixed + +- Text selected in a Safari page with `desktop_select` can be copied: selecting focuses the page, as a click would, so Edit > Copy in the activated Safari copies the selection instead of the page's address. Safari copies only while active, so `desktop_activate` it and choose Edit > Copy with `desktop_menu`; the tool description and docs said to press Command-C, which Safari ignores in the background. ([#188](https://github.com/githubnext/desktop-tools/issues/188)) + ## [0.17.0] - 2026-10-20 ### Changed diff --git a/dist/tools.js b/dist/tools.js index 46a1ab0f..00d0e090 100644 --- a/dist/tools.js +++ b/dist/tools.js @@ -775,7 +775,7 @@ export function desktopTools({ place, app, wire = 1 }) { { name: "desktop_select", op: "select", - description: `Select literal text in one element from a fresh desktop_inspect snapshot, or place the caret before or after it (selection). The element is an editable field, web page text such as a paragraph or link, or the text of a PDF page in Preview. Background. Completed when the selection reads back as exactly that text. Missing or ambiguous text is refused; add prefix or suffix, the text immediately around it. To copy, press c with command through desktop_key; Preview copies only while active, so desktop_activate it and use desktop_menu Edit > Copy.`, + description: `Select literal text in one element from a fresh desktop_inspect snapshot, or place the caret before or after it (selection). The element is an editable field, web page text such as a paragraph or link, or the text of a PDF page in Preview. Background. Completed when the selection reads back as exactly that text. Missing or ambiguous text is refused; add prefix or suffix, the text immediately around it. To copy a field's selection, press c with command through desktop_key; Safari and Preview copy only while active, so desktop_activate the app and use desktop_menu Edit > Copy.`, parameters: { type: "object", required: ["snapshot", "element", "text"], diff --git a/docs/tools.md b/docs/tools.md index 0fb24aec..c0c27551 100644 --- a/docs/tools.md +++ b/docs/tools.md @@ -203,7 +203,7 @@ The host replaces the field's contents with key events. The fill is completed wh `desktop_insert` also pastes an image or files into a native text area, such as TextEdit's rich text, Mail or Notes, in place of text; see [the details](#details-by-tool) for how it confirms the paste and when it refuses. -`desktop_select` sets a field's `AXSelectedTextRange` and reads it back. Text in a web page has no such range, so for an element inside a web area, such as a paragraph, heading or link, the host uses WebKit's text markers instead. It finds the requested range from the element's own start, sets the web area's selected marker range, and reads it back: the result is `completed` only when the selection covers exactly the requested text, and `unknown` otherwise. A long element may need the host to walk the text one marker at a time; that walk stops after 2,048 steps or 300 ms, and the selection is refused before anything is selected, with a hint to select within a smaller element. Offsets are UTF-16 units within the element, as for fields. To copy the selection, press `c` with `command` through `desktop_key`, then `desktop_clipboard_read`. Text on a PDF page in Preview is selected the same way, through the page's text element, even though that element reports itself disabled and has no selection until one is set. Preview disables Copy while it is in the background, so `desktop_activate` it first, then choose Edit > Copy with `desktop_menu`. Not yet checked on a live system: other selectable text outside web pages that isn't a field, such as a read-only native text view, which works only if it exposes a settable `AXSelectedTextRange` and is refused otherwise. +`desktop_select` sets a field's `AXSelectedTextRange` and reads it back. Text in a web page has no such range, so for an element inside a web area, such as a paragraph, heading or link, the host uses WebKit's text markers instead. It focuses the web area, as a click in the page would, so that Copy acts on the page rather than on Safari's address field, finds the requested range from the element's own start, sets the web area's selected marker range, and reads it back: the result is `completed` only when the selection covers exactly the requested text, and `unknown` otherwise. A long element may need the host to walk the text one marker at a time; that walk stops after 2,048 steps or 300 ms, and the selection is refused before anything is selected, with a hint to select within a smaller element. Offsets are UTF-16 units within the element, as for fields. To copy a field's selection, press `c` with `command` through `desktop_key`, then `desktop_clipboard_read`. Safari disables Copy while it is in the background, and its keyboard focus isn't in the window then, so `desktop_activate` it first and choose Edit > Copy with `desktop_menu`. Text on a PDF page in Preview is selected the same way, through the page's text element, even though that element reports itself disabled and has no selection until one is set. Preview disables Copy while it is in the background, so `desktop_activate` it first, then choose Edit > Copy with `desktop_menu`. Not yet checked on a live system: other selectable text outside web pages that isn't a field, such as a read-only native text view, which works only if it exposes a settable `AXSelectedTextRange` and is refused otherwise. `desktop_inspect` lists the actions each element offers in `actions`. A pop-up button has no settable value: click it, then pick the item from the next observation, which puts an open menu's items first. A `