I'm trying to re-write an application I have for Windows in Objective-C for my Mac, and I want to be able to do something like Mac's hot corners. If I move my mouse to the left side of the screen it will make a window visible, if I move it outside of the window location the window will hide again. (window would be pushed up to the left side of screen).
Does anyone know where I can find some demo code (or reference) on how to do this, or at least how to tell where the mouse is at, even if the current application is not on top. (not sure how to word this, too used to Windows world).
Thank you
-Brad
Hold down the Shift key, then right-click on the appropriate application icon in the Windows taskbar. On the resulting pop-up, select the Move option. Begin pressing the arrow keys on your keyboard to move the invisible window from off-screen to on-screen.
Right-click the program on the taskbar, and then click Move. Move the mouse pointer to the middle of the screen. Use the ARROW keys on the keyboard to move the program window to a viewable area on the screen. Press ENTER.
This usually happens after you change screen resolution, or if you closed the application with the window in that position. In some cases, the window will open up completely off the screen; the only evidence that the application has launched will be its entry on the Taskbar.
You must place the cursor anywhere on the active window frame and press Enter. ISPF acknowledges the window move request by displaying WINDOW MOVE pending message. Then place the cursor where you want the upper left corner of the pop-up placed. press Enter a second time, and the pop-up is moved to the new location.
You're going to want to implement an invisible window on the edge of the screen with the window order set so it's always on top. Then, you can listen for mouse-moved events in this window.
To set the window to be invisible and on top, make a window subclass use calls like:
[self setBackgroundColor:[NSColor clearColor]];
[self setExcludedFromWindowsMenu:YES];
[self setCanHide:NO];
[self setLevel:NSScreenSaverWindowLevel];
[self setAlphaValue:0.0f];
[self setOpaque:NO];
[self orderFrontRegardless];
then, to turn on mouse moved events,
[self setAcceptsMouseMovedEvents:YES];
will cause the window to get calls to:
- (void)mouseMoved:(NSEvent *)theEvent
{
NSLog(@"mouse moved into invisible window.");
}
So hopefully that's enough to give you a start.
-Ken
Here's AutoHidingWindow - a subclass of SlidingWindow which pops up when the mouse hits the edge of the screen. Feedback welcome.
@interface ActivationWindow : NSWindow
{
AutoHidingWindow *_activationDelegate;
NSTrackingArea *_trackingArea;
}
- (ActivationWindow*)initWithDelegate:(AutoHidingWindow*)activationDelegate;
@property (assign) AutoHidingWindow *activationDelegate;
@property (retain) NSTrackingArea *trackingArea;
- (void)adjustWindowFrame;
- (void)adjustTrackingArea;
@end
@interface AutoHidingWindow ()
- (void)autoShow;
- (void)autoHide;
@end
@implementation AutoHidingWindow
- (id)initWithContentRect:(NSRect) contentRect
styleMask:(unsigned int) styleMask
backing:(NSBackingStoreType) backingType
defer:(BOOL) flag
{
if ((self = [super initWithContentRect:contentRect
styleMask:NSBorderlessWindowMask
backing:backingType
defer:flag])) {
_activationWindow = [[ActivationWindow alloc] initWithDelegate:self];
}
return self;
}
@synthesize activationWindow = _activationWindow;
- (void)dealloc
{
[_activationWindow release], _activationWindow = nil;
[super dealloc];
}
- (void)makeKeyAndOrderFront:(id)sender
{
[super makeKeyAndOrderFront:sender];
}
- (void)autoShow
{
[self makeKeyAndOrderFront:self];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(autoHide) object:nil];
[self performSelector:@selector(autoHide) withObject:nil afterDelay:2];
}
- (void)autoHide
{
NSPoint mouseLocation = [NSEvent mouseLocation];
NSRect windowFrame = [self frame];
if (NSPointInRect(mouseLocation, windowFrame)) {
[self performSelector:@selector(autoHide) withObject:nil afterDelay:2];
}
else {
[self orderOut:self];
}
}
@end
@implementation ActivationWindow
- (ActivationWindow*)initWithDelegate:(AutoHidingWindow*)activationDelegate
{
if ((self = [super initWithContentRect:[[NSScreen mainScreen] frame]
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO]) != nil) {
_activationDelegate = activationDelegate;
[self setBackgroundColor:[NSColor clearColor]];
[self setExcludedFromWindowsMenu:YES];
[self setCanHide:NO];
[self setHasShadow:NO];
[self setLevel:NSScreenSaverWindowLevel];
[self setAlphaValue:0.0];
[self setIgnoresMouseEvents:YES];
[self setOpaque:NO];
[self orderFrontRegardless];
[self adjustWindowFrame];
[self.activationDelegate addObserver:self
forKeyPath:@"slidingEdge"
options:0
context:@"slidingEdge"];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(screenParametersChanged:)
name:NSApplicationDidChangeScreenParametersNotification
object:nil];
}
return self;
}
@synthesize activationDelegate = _activationDelegate;
@synthesize trackingArea = _trackingArea;
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([@"slidingEdge" isEqual:context]) {
[self adjustTrackingArea];
}
else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self.activationDelegate removeObserver:self forKeyPath:@"slidingEdge"];
_activationDelegate = nil;
[_trackingArea release], _trackingArea = nil;
[super dealloc];
}
- (void)screenParametersChanged:(NSNotification *)notification
{
[self adjustWindowFrame];
}
- (void)adjustWindowFrame
{
NSScreen *mainScreen = [NSScreen mainScreen];
CGFloat menuBarHeight = [NSMenuView menuBarHeight];
NSRect windowFrame = [mainScreen frame];
windowFrame.size.height -= menuBarHeight;
[self setFrame:windowFrame display:NO];
[self adjustTrackingArea];
}
- (void)adjustTrackingArea
{
NSView *contentView = [self contentView];
NSRect trackingRect = contentView.bounds;
CGRectEdge slidingEdge = self.activationDelegate.slidingEdge;
CGFloat trackingRectSize = 2.0;
switch (slidingEdge) {
case CGRectMaxXEdge:
trackingRect.origin.x = trackingRect.origin.x + trackingRect.size.width - trackingRectSize;
trackingRect.size.width = trackingRectSize;
break;
case CGRectMaxYEdge:
trackingRect.origin.y = trackingRect.origin.y + trackingRect.size.height - trackingRectSize;
trackingRect.size.height = trackingRectSize;
break;
case CGRectMinXEdge:
trackingRect.origin.x = 0;
trackingRect.size.width = trackingRectSize;
break;
case CGRectMinYEdge:
default:
trackingRect.origin.y = 0;
trackingRect.size.height = trackingRectSize;
}
NSTrackingAreaOptions options =
NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved |
NSTrackingActiveAlways |
NSTrackingEnabledDuringMouseDrag;
NSTrackingArea *trackingArea = self.trackingArea;
if (trackingArea != nil) {
[contentView removeTrackingArea:trackingArea];
}
trackingArea = [[NSTrackingArea alloc] initWithRect:trackingRect
options:options
owner:self
userInfo:nil];
[contentView addTrackingArea:trackingArea];
self.trackingArea = [trackingArea autorelease];
}
- (void)mouseEntered:(NSEvent *)theEvent
{
[self.activationDelegate autoShow];
}
- (void)mouseMoved:(NSEvent *)theEvent
{
[self.activationDelegate autoShow];
}
- (void)mouseExited:(NSEvent *)theEvent
{
}
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With