Hello macscripter community (my first post here!)
I’m trying to make a script that can execute a task as soon as I connect or disconnect a screen to my Mac.
I already have two working scripts but I’m not yet happy with them.
The difficult part is to count the displays that are connected.
One method was to use “Extra Suites” and ES screen count.
I wouldn’t mind to pay 10$ for Extra Suite but if there is an other way i’ll take it.
Second method comes from this link: http://stackoverflow.com/questions/559009/applescript-multiple-monitors-and-maximum-window-sizes
As suggested by the author a created an empty AppleScript application in Xcode and called it ASSAccess.
Here is my code:
tell application "ASSAccess"
-- The first item in this list will be your main monitor
set screensArray to call method "screens" of class "NSScreen"
set startnumDisplay to screensArray count
repeat
set screensArray to call method "screens" of class "NSScreen"
set numDisplay to screensArray count
tell application "System Events"
if startnumDisplay is not equal to numDisplay then
set startnumDisplay to numDisplay
-- return "newDisplay"
-- DO SOMTHING HERE
end if
delay 10
end tell
end repeat
end tell
This also works but I have to open two applications (ASSAccess and my Code).
Isn’t there a way to combine the two?
Or maybe an even more simple way to detect the dis-/ connection of a screen?
cheers,
broenni
Hi,
you can gather the number of connected displays with Image Events
tell application "Image Events"
launch
set countDisplays to count displays
quit
end tell
An automatic detection is possible only in ObjC respectively with the CoreGraphics function CGDisplayRegisterReconfigurationCallback
http://developer.apple.com/documentation/GraphicsImaging/Conceptual/QuartzDisplayServicesConceptual/Articles/Notification.html#//apple_ref/doc/uid/TP40004235-SW1
PS: this is a sophisticated solution for a AppleScript Studio application
to pass the ObjC notification about the display connection changing to AppleScript via a hidden ComboBox
- Xcode
¢ create a new Objective-C class (Menu File > New File > Objective-C class), name it DisplayCallback
¢ Replace the contents of DisplayCallback.h with
[code]#import <Cocoa/Cocoa.h>
@interface DisplayCallback : NSObject {
IBOutlet NSComboBox *combo;
}
- (void)setCombo:(NSString *)str;
@end[/code]
¢ Replace the contents of DisplayCallback.m with
[code]#import “DisplayCallback.h”
@implementation DisplayCallback
static void displayReconfigurationCallBack (
CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
void *userInfo)
{
if (flags & kCGDisplayAddFlag) {
[(DisplayCallback *)userInfo setCombo:[NSString stringWithFormat:@“%u added”, display]];
}
else if (flags & kCGDisplayRemoveFlag) {
[(DisplayCallback *)userInfo setCombo:[NSString stringWithFormat:@“%u removed”, display]];
}
}
-
(void)awakeFromNib
{
NSLog(@“awakeFromNib”);
CGDisplayRegisterReconfigurationCallback (displayReconfigurationCallBack, self);
}
-
(void)dealloc
{
CGDisplayRemoveReconfigurationCallback (displayReconfigurationCallBack, self);
[super dealloc];
}
-
(void)setCombo:(NSString *)str
{
[combo removeAllItems];
[combo insertItemWithObjectValue:str atIndex:0];
[combo selectItemAtIndex:0];
}
@end[/code]
- Interface Builder
¢ drag an NSObject from the Library into the MainMenu window
¢ in Inspector > Identity > Class type DisplayCallback
¢ drag a NSComboBox item from the Library into your application window
¢ in Inspector > Attributes check Hidden (at the bottom), this item will be invisible
¢ in Inspector > AppleScript select your AppleScript in the Script popup menu, name it combo and connect (check) the Event handler Combo Box > selection changed
¢ highlight the NSObject, control-drag to the Combo Box, in the appearing menu select combo
Save and Quit Interface Builder
- Xcode
¢ in your AppleScript, add this code to the on selection changed handler
on selection changed theObject
set {displayID, displayAction} to words of (get string value of theObject)
if displayAction is "added" then
-- do "added" action
else if displayAction is "removed" then
-- do "removed" action
end if
end selection changed
When you run your application check the log.
If the “awake from nib” message won’t be displayed, open Interface Builder, control-drag from File’s Owner to the new NSObject and choose delegate.
Afterwards you can comment out the NSLog line with
// NSLog(@"awakeFromNib");