Possible to identify screen/monitor of current cursor position?

Hello!

How can I identify the screen/monitor where the cursor is positioned, on multiheaded settings? Is this possible with AS at all?

A web search found stuff that might be useful for a kludge workaround, i.e.,
All screen resolutions (can be refined into lists ( {width,height} )

 get (do shell script "system_profiler SPDisplaysDataType | grep Resolution") 

Desktop size (problematic when external displays are in changing arrangement re main display)

 tell application "Finder" to get bounds of window of desktop 

Bounds of currenly active window

 set currFrame to (current application's NSScreen's mainScreen()'s visibleFrame()) as list 

But to get even the cursor position within a single screen, I’m at a loss.

Grateful for help,
lg

PS: Something outside AS that I’d lack the knowledge to code:
“[NSScreen screens] and iterate through the result, using NSPointInRect to test”
Is there something similar possible with AS?

Hi,

this is the Something outside AS but still in AS solution

The result displays if the mouse position is on the main screen

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

property |⌘| : a reference to current application

set mousePosition to |⌘|'s NSEvent's mouseLocation()
set allScreens to |⌘|'s NSScreen's screens()
repeat with aScreen in allScreens
	if |⌘|'s NSPointInRect(mousePosition, aScreen's frame()) then
		set foundScreen to contents of aScreen
		exit repeat
	end if
end repeat

display dialog "Screen is main screen: " & (foundScreen's isEqual:(|⌘|'s NSScreen's mainScreen()))

Hello Stefan

If I use :

display dialog "Screen is main screen: " & (foundScreen's isEqual:(|⌘|'s NSScreen's mainScreen())) & ", " & mousePosition
to display the mouse position I get :
error "Impossible de convertir {x:276.08203125, y:804.125} en type Unicode text." number -1700 from {x:276.08203125, y:804.125} to Unicode text


display dialog "Screen is main screen: " & (foundScreen’s isEqual:(|⌘|'s NSScreen’s mainScreen())) & “, {x:” & mousePosition’s x & “, y:” & mousePosition’s y & “}”


does' the job but seems awful. Is there a better syntax ?

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mercredi 16 janvier 2019 16:18:37

mousePosition is an NSPoint object, a C struct. It’s not AppleScript compatible.

You could coerce the object to an AppleScript list and join it with text item delimiters

set {TID, text item delimiters} to {text item delimiters, ", "}
display dialog "Screen is main screen: " & (foundScreen's isEqual:(|⌘|'s NSScreen's mainScreen())) & "; " & (mousePosition as list) as text
set text item delimiters to TID

Or get x and y as AppleScript reals in one line

set {xPosition, yPosition} to mousePosition as list

@StefanK

Thanks

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mercredi 16 janvier 2019 18:36:28

Thank you, StefanK! That helped very much - I realized from your code that I could skip the step of explicitly dealing with a screen ID and directly get the frame that I was after. :slight_smile:

For what it’s worth (as a didactic example? :slight_smile: ):

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "AppKit" -- for NSScreen
use scripting additions

property |⌘| : a reference to current application

set mousePosition to |⌘|'s NSEvent's mouseLocation()
set allScreens to |⌘|'s NSScreen's screens()
repeat with aScreen in allScreens
	if |⌘|'s NSPointInRect(mousePosition, aScreen's frame()) then
		set MouseScreenBounds to (aScreen's frame()) as list
		set activeWindowScreenBounds to (|⌘|'s NSScreen's mainScreen()'s frame()) as list
		exit repeat
	end if
end repeat

set {X_Mouse, Y_Mouse} to mousePosition as list
set X_Mouse to round X_Mouse
set Y_Mouse to round Y_Mouse
set X_MouseScreen to (round (item 1 of item 1 of MouseScreenBounds))
set Y_MouseScreen to (round (item 2 of item 1 of MouseScreenBounds))
set W_MouseScreen to (round (item 1 of item 2 of MouseScreenBounds))
set H_MouseScreen to (round (item 2 of item 2 of MouseScreenBounds))
set X_ActiveWindow to (round (item 1 of item 1 of activeWindowScreenBounds))
set Y_ActiveWindow to (round (item 2 of item 1 of activeWindowScreenBounds))
set W_ActiveWindow to (round (item 1 of item 2 of activeWindowScreenBounds))
set H_ActiveWindow to (round (item 2 of item 2 of activeWindowScreenBounds))

display dialog "Mouse position: " & X_Mouse & " " & Y_Mouse & return & ¬
	"Mouse positions's screen offset: " & X_MouseScreen & " " & Y_MouseScreen & ¬
	", size: " & W_MouseScreen & " " & H_MouseScreen & return & ¬
	"Active window's screen offset: " & X_ActiveWindow & " " & Y_ActiveWindow & ¬
	", size: " & W_ActiveWindow & " " & H_ActiveWindow:)

Again, BIG thanks!
lg

P.S.: " |⌘| " is a cool name!

You don’t need to round the screen bounds. They are even values

Not always, it seems. In Script Editor my Log History gives one decimal, except for mousePosition Y.

tell current application
tell current application
	round 979.0
		--> 979
	round 215.00390625
		--> 215
	round 0.0
		--> 0
	round 0.0
		--> 0
	round 1920.0
		--> 1920
	round 1080.0
		--> 1080
	round 0.0
		--> 0
	round 0.0
		--> 0
	round 1920.0
		--> 1920
	round 1080.0
		--> 1080
end tell

Most times (not always) I get 8 decimals in mousePositions Y, e.g. “338.00390625”, in Script Debugger seldom also for X. --?? Bug?

The rounding just made for a clean dialog.

I was talking only about the screen bounds. The mouse position has to be rounded.

That happens when I don’t read carfully… My apology.

Except the scripting bridge automatically converts it to an AppleScript record…