Changeset - r24771:8e2ad2807649
[Not reviewed]
master
0 3 0
Michael Lutz - 3 years ago 2021-02-03 21:43:06
michi@icosahedron.de
Codechange: [OSX] Use newer mouse tracking API.
3 files changed with 40 insertions and 79 deletions:
0 comments (0 inline, 0 general)
src/video/cocoa/cocoa_v.mm
Show inline comments
 
@@ -495,7 +495,7 @@ bool VideoDriver_Cocoa::MakeWindow(int w
 

	
 
	/* Create wrapper view for text input. */
 
	NSRect view_frame = [ this->window contentRectForFrameRect:[ this->window frame ] ];
 
	this->cocoaview = [ [ OTTD_CocoaView alloc ] initWithFrame:view_frame andDriver:this ];
 
	this->cocoaview = [ [ OTTD_CocoaView alloc ] initWithFrame:view_frame ];
 
	if (this->cocoaview == nil) {
 
		DEBUG(driver, 0, "Could not create the text wrapper view.");
 
		this->setup = false;
src/video/cocoa/cocoa_wnd.h
Show inline comments
 
@@ -32,20 +32,8 @@ extern NSString *OTTDMainLaunchGameEngin
 
- (void)appDidUnhide:(NSNotification*)note;
 
@end
 

	
 
/** Subclass of NSView to fix Quartz rendering and mouse awareness */
 
@interface OTTD_CocoaView : NSView <NSTextInputClient> {
 
	VideoDriver_Cocoa *driver;
 
}
 
- (instancetype)initWithFrame:(NSRect)frameRect andDriver:(VideoDriver_Cocoa *)drv;
 

	
 
- (BOOL)acceptsFirstResponder;
 
- (void)setTrackingRect;
 
- (void)clearTrackingRect;
 
- (void)resetCursorRects;
 
- (void)viewWillMoveToWindow:(NSWindow *)win;
 
- (void)viewDidMoveToWindow;
 
- (void)mouseEntered:(NSEvent *)theEvent;
 
- (void)mouseExited:(NSEvent *)theEvent;
 
/** Subclass of NSView to support mouse awareness and text input. */
 
@interface OTTD_CocoaView : NSView <NSTextInputClient>
 
@end
 

	
 
/** Delegate for our NSWindow to send ask for quit on close */
src/video/cocoa/cocoa_wnd.mm
Show inline comments
 
@@ -112,7 +112,9 @@ static const char *Utf8AdvanceByUtf16Uni
 
	auto *drv = static_cast<VideoDriver_Cocoa *>(VideoDriver::GetInstance());
 

	
 
	/* Setup cursor for the current _game_mode. */
 
	[ drv->window invalidateCursorRectsForView:[ drv->window contentView ] ];
 
	NSEvent *e = [ [ NSEvent alloc ] init ];
 
	[ drv->cocoaview cursorUpdate:e ];
 
	[ e release ];
 

	
 
	/* Hand off to main application code. */
 
	drv->GameLoop();
 
@@ -330,6 +332,25 @@ void CocoaDialog(const char *title, cons
 
}
 

	
 
/**
 
 * Initialize event system for the application rectangle
 
 */
 
- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag driver:(VideoDriver_Cocoa *)drv
 
{
 
	if (self = [ super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag ]) {
 
		/* Make our window subclass receive these application notifications */
 
		[ [ NSNotificationCenter defaultCenter ] addObserver:self
 
			selector:@selector(appDidHide:) name:NSApplicationDidHideNotification object:NSApp ];
 

	
 
		[ [ NSNotificationCenter defaultCenter ] addObserver:self
 
			selector:@selector(appDidUnhide:) name:NSApplicationDidUnhideNotification object:NSApp ];
 

	
 
		self->driver = drv;
 
	}
 

	
 
	return self;
 
}
 

	
 
/**
 
 * Minimize the window
 
 */
 
- (void)miniaturize:(id)sender
 
@@ -383,38 +404,10 @@ void CocoaDialog(const char *title, cons
 
{
 
	driver->active = true;
 
}
 
/**
 
 * Initialize event system for the application rectangle
 
 */
 
- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag driver:(VideoDriver_Cocoa *)drv
 
{
 
	if (self = [ super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag ]) {
 
		/* Make our window subclass receive these application notifications */
 
		[ [ NSNotificationCenter defaultCenter ] addObserver:self
 
			selector:@selector(appDidHide:) name:NSApplicationDidHideNotification object:NSApp ];
 

	
 
		[ [ NSNotificationCenter defaultCenter ] addObserver:self
 
			selector:@selector(appDidUnhide:) name:NSApplicationDidUnhideNotification object:NSApp ];
 

	
 
		self->driver = drv;
 
	}
 

	
 
	return self;
 
}
 

	
 
@end
 

	
 
@implementation OTTD_CocoaView {
 
	NSTrackingRectTag trackingtag;
 
}
 

	
 
- (instancetype)initWithFrame:(NSRect)frameRect andDriver:(VideoDriver_Cocoa *)drv
 
{
 
	if (self = [ super initWithFrame:frameRect ]) {
 
		self->driver = drv;
 
	}
 
	return self;
 
}
 
@implementation OTTD_CocoaView
 

	
 
/**
 
 * Allow to handle events
 
@@ -432,46 +425,26 @@ void CocoaDialog(const char *title, cons
 
	}
 
}
 

	
 
/**
 
 * Define the rectangle where we draw our application window
 
 */
 
- (void)setTrackingRect
 
{
 
	NSPoint loc = [ self convertPoint:[ [ self window ] mouseLocationOutsideOfEventStream ] fromView:nil ];
 
	BOOL inside = ([ self hitTest:loc ]==self);
 
	if (inside) [ [ self window ] makeFirstResponder:self ];
 
	trackingtag = [ self addTrackingRect:[ self visibleRect ] owner:self userData:nil assumeInside:inside ];
 
}
 
/**
 
 * Return responsibility for the application window to system
 
 */
 
- (void)clearTrackingRect
 
/** Update mouse cursor to use for this view. */
 
- (void)cursorUpdate:(NSEvent *)event
 
{
 
	[ self removeTrackingRect:trackingtag ];
 
	[ (_game_mode == GM_BOOTSTRAP ? [ NSCursor arrowCursor ] : [ NSCursor clearCocoaCursor ]) set ];
 
}
 
/**
 
 * Declare responsibility for the cursor within our application rect
 
 */
 
- (void)resetCursorRects
 
{
 
	[ super resetCursorRects ];
 
	[ self clearTrackingRect ];
 
	[ self setTrackingRect ];
 
	[ self addCursorRect:[ self bounds ] cursor:(_game_mode == GM_BOOTSTRAP ? [ NSCursor arrowCursor ] : [ NSCursor clearCocoaCursor ]) ];
 
}
 
/**
 
 * Prepare for moving the application window
 
 */
 

	
 
- (void)viewWillMoveToWindow:(NSWindow *)win
 
{
 
	if (!win && [ self window ]) [ self clearTrackingRect ];
 
	for (NSTrackingArea *a in [ self trackingAreas ]) {
 
		[ self removeTrackingArea:a ];
 
	}
 
}
 
/**
 
 * Restore our responsibility for our application window after moving
 
 */
 

	
 
- (void)viewDidMoveToWindow
 
{
 
	if ([ self window ]) [ self setTrackingRect ];
 
	/* Install mouse tracking area. */
 
	NSTrackingAreaOptions track_opt = NSTrackingInVisibleRect | NSTrackingActiveInActiveApp | NSTrackingMouseEnteredAndExited | NSTrackingCursorUpdate;
 
	NSTrackingArea *track = [ [ NSTrackingArea alloc ] initWithRect:[ self bounds ] options:track_opt owner:self userInfo:nil ];
 
	[ self addTrackingArea:track ];
 
	[ track release ];
 
}
 
/**
 
 * Make OpenTTD aware that it has control over the mouse
 
@@ -485,7 +458,7 @@ void CocoaDialog(const char *title, cons
 
 */
 
- (void)mouseExited:(NSEvent *)theEvent
 
{
 
	if (driver->window != nil) UndrawMouseCursor();
 
	if ([ self window ] != nil) UndrawMouseCursor();
 
	_cursor.in_window = false;
 
}
 

	
0 comments (0 inline, 0 general)