Instead of
Application("Preview").windows[0].bounds = {"x": 1440, "y":25, "width":1440, "height": 2535}
I'd like to move the window but instead of using an index, I'd like to use the window's ID. I got the ID with
Application("Preview").windows[0].id();
But when I replace the index with the ID:
Application("Preview").windows.whose({id: 15596}).bounds = {"x": 1440, "y":25, "width":1440, "height": 2535}
I get
Error -1728: Can't get object.
There's a difference between the window id
given by the Application
object, the window id
tracked by the Application('System Events')
object, and the window id
tracked by the CoreGraphics
framework.
Unless the developer of the application wrote a scripting exposure for manipulating window bounds into their app, you can't use the Application
object to adjust bounds, you have to use Application('System Events')
or use the Objective-C bridge to access the AXUIElement
sub-system directly.
For example, using Application('System Events')
:
const window = Application('System Events')
.applicationProcesses
.whose({name: 'Safari'}).at(0)
.windows.at(0);
window.position.set([0, 0]);
window.size.set([1200, 1000]);
return 0;
Note that there isn't any addressing of the window by its id
, because the System Events process isn't aware of such application-tracked IDs.
If you needed to narrow the scope of your window selection by its title or other characteristic, you can do so using JavaScript's Array.prototype.find()
or Array.prototype.filter()
:
const SafariEvents = Application('System Events')
.applicationProcesses
.whose({name: 'Safari'})
.at(0);
const window = SafariEvents.windows()
.find((window) => !!window.attributes
.byName('AXTitle').value()
.match(/JXA/));
window.position.set([0, 0]);
window.size.set([1200, 1000]);
return 0;
Take care to notice the extremely-verbose syntax of extracting accessibility attributes from the System Events scripting object. While it's lengthy, it does give you the ability to use things like regular expressions to help find what you want — a much better alternative to native AppleScript's hodgepodge of search/find mechanisms.
Saving the best for last, you can use the Objective-C bridge to access the accessibility subsystem directly. This requires dealing with pointers and is a little more complex than the previous examples, but it is significantly faster than using System Events (I can't emphasize that enough — it's nuts how responsive this approach is).
I've made a gist with helper functions to make this easier. It includes an example of adjusting the position of a Visual Studio Code window. You can find it here if you'd like to try it.
Cheers.