Reposition an Apple Intelligence window

My macOS is Sequoia 15.2 and I’ve enabled Apple Intelligence and ChatGPT. This works fine, but the AI window is in the upper right-hand corner of my screen. I can manually move it with the mouse to a better location, but all my attempts to do this with a script or shortcut have failed. Any idea on how to identify the AI process (siriactionsd didn’t work) or to move the AI window? I’ve included below one AppleScript that I tried and the resulting error message. Thanks!

tell application "System Events"
	set activeApp to name of first process whose frontmost is true
	tell process activeApp to tell window 1
		set position to {100, 100}
	end tell
end tell

In the past I’ve used an ancient Python script to get a list of open windows with their locations on screen and the owning processes, and looked for one with the most likely screen coordinates. But it’s written for Python 2, requiring a complicated (by my standards) pyenv setup to get it working, and something is broken now. I’m no Python expert, so I have no clue how to fix it.

(The script just uses CGWindowListCopyWindowInfo() to get the list, so maybe it can be done with ASObjC?)

I originally found the python script in this Super User post. Another suggestion in that thread is to use the Accessibility Inspector, which is telling me that the owner of the Type to Siri window is Notification Center.

1 Like

ASObjC can’t use CGWindowListCopyWindowInfo, but JSObjC can.
CJK11 has posted a sample code in this topic: Get window ID

You can run JSObjC code in AppleScript like this:

use framework "Foundation"
use scripting additions

property parent : a reference to current application
property NSJSONWritingPrettyPrinted : a reference to 1

set windowsInfo to fromJSON(do shell script "osascript -l JavaScript <<EOF
	ObjC.import('CoreGraphics');
	ObjC.import('Quartz');
	(function () {
		$.unwrap = ObjC.deepUnwrap.bind(ObjC),
		$.bind = ObjC.bindFunction.bind($);
		$.bind('CFMakeCollectable', [ 'id', [ 'void *' ] ]);

		Ref.prototype._nsObject = function () {
			return $.unwrap($.CFMakeCollectable(this));
		}

		const kCGWindows = $.CGWindowListCopyWindowInfo($.kCGWindowListOptionAll, $.kCGWindowNull)._nsObject();

		const Windows = {
			visible: kCGWindows.filter( w => w.kCGWindowIsOnscreen ),
			applications: kCGWindows.filter( w => !w.kCGWindowLayer)
		};
		
		return JSON.stringify(Windows)
	})()
EOF")

--> {applications:{…}, visible:{…}}

-- helper functions
on toJSON(theData)
	set theJSONData to parent's NSJSONSerialization's dataWithJSONObject:theData options:NSJSONWritingPrettyPrinted |error|:(missing value)
	set theString to (parent's NSString's alloc()'s initWithData:theJSONData encoding:(parent's NSUTF8StringEncoding)) as text
	return theString
end toJSON

on fromJSON(strJSON)
	set {x, e} to parent's NSJSONSerialization's JSONObjectWithData:((parent's NSString's stringWithString:strJSON)'s dataUsingEncoding:(parent's NSUTF8StringEncoding)) options:0 |error|:(reference)
	if x is missing value then
		error e's localizedDescription() as text
	else
		return item 1 of ((parent's NSArray's arrayWithObject:x) as list)
	end if
end fromJSON
1 Like

Thanks fuzzywan and Dirk for the suggestions.

I tested Dirk’s script and it does return the AI Siri window. Now to see if I can use that to move ths Siri window.

Perhaps with the PID?

repeat with visibleWindow in windowsInfo's |visible|
	if visibleWindow's kCGWindowOwnerName is "Siri" then
		set unixId to visibleWindow's kCGWindowOwnerPID
		tell application "System Events"
			set theProcess to first item of (every process where unix id is unixId)
			tell theProcess
				return windows
			end tell
		end tell
	end if
end repeat

I don’t have Apple Intelligence. So I can’t test it.

1 Like

Dirk. Thanks for the suggestion, which returned:

{window 1 of application process "Siri"}

This caused me to test the following, which moved the Siri window just as I wanted. However, apparently you first have to select/move the AI window with the mouse to create the Siri window, which sort of defeats the purpose of the script. Anyways, I think I can get this to work with the JSObjC code and the System Events position command.

tell application "System Events" to tell process "Siri"
	set position of window 1 to {333, 333}
end tell

Why didn’t you address the window directly?

repeat with visibleWindow in windowsInfo's |visible|
	if visibleWindow's kCGWindowOwnerName is "Siri" then
		set unixId to visibleWindow's kCGWindowOwnerPID
		tell application "System Events"
			set theProcess to first item of (every process where unix id is unixId)
			tell theProcess
				set position of window 1 to {333, 333}
			end tell
		end tell
	end if
end repeat

As I said, I don’t have Apple Intelligence and therefore can’t test it. It works for me with the other apps that appear in the list of visible windows.

1 Like