winemac: Consolidate mouse button handling into -[WineApplicationController handleMouseButton:].

This commit is contained in:
Ken Thomases 2013-05-07 03:00:42 -05:00 committed by Alexandre Julliard
parent 72e893237c
commit e15b82ad1b
3 changed files with 90 additions and 37 deletions

View file

@ -61,6 +61,7 @@ @interface WineApplicationController : NSObject <NSApplicationDelegate>
WineWindow* lastTargetWindow;
BOOL forceNextMouseMoveAbsolute;
double mouseMoveDeltaX, mouseMoveDeltaY;
NSUInteger unmatchedMouseDowns;
NSMutableArray* orderedWineWindows;

View file

@ -1219,6 +1219,87 @@ - (void) handleMouseMove:(NSEvent*)anEvent
}
}
- (void) handleMouseButton:(NSEvent*)theEvent
{
WineWindow* window = (WineWindow*)[theEvent window];
if ([window isKindOfClass:[WineWindow class]])
{
NSEventType type = [theEvent type];
BOOL pressed = (type == NSLeftMouseDown || type == NSRightMouseDown || type == NSOtherMouseDown);
CGPoint pt = CGEventGetLocation([theEvent CGEvent]);
BOOL process;
if (pressed)
{
// Test if the click was in the window's content area.
NSPoint nspoint = [self flippedMouseLocation:NSPointFromCGPoint(pt)];
NSRect contentRect = [window contentRectForFrameRect:[window frame]];
process = NSPointInRect(nspoint, contentRect);
if (process && [window styleMask] & NSResizableWindowMask)
{
// Ignore clicks in the grow box (resize widget).
HIPoint origin = { 0, 0 };
HIThemeGrowBoxDrawInfo info = { 0 };
HIRect bounds;
OSStatus status;
info.kind = kHIThemeGrowBoxKindNormal;
info.direction = kThemeGrowRight | kThemeGrowDown;
if ([window styleMask] & NSUtilityWindowMask)
info.size = kHIThemeGrowBoxSizeSmall;
else
info.size = kHIThemeGrowBoxSizeNormal;
status = HIThemeGetGrowBoxBounds(&origin, &info, &bounds);
if (status == noErr)
{
NSRect growBox = NSMakeRect(NSMaxX(contentRect) - bounds.size.width,
NSMinY(contentRect),
bounds.size.width,
bounds.size.height);
process = !NSPointInRect(nspoint, growBox);
}
}
if (process)
unmatchedMouseDowns |= NSEventMaskFromType(type);
}
else
{
NSEventType downType = type - 1;
NSUInteger downMask = NSEventMaskFromType(downType);
process = (unmatchedMouseDowns & downMask) != 0;
unmatchedMouseDowns &= ~downMask;
}
if (process)
{
macdrv_event* event;
event = macdrv_create_event(MOUSE_BUTTON, window);
event->mouse_button.button = [theEvent buttonNumber];
event->mouse_button.pressed = pressed;
event->mouse_button.x = pt.x;
event->mouse_button.y = pt.y;
event->mouse_button.time_ms = [self ticksForEventTime:[theEvent timestamp]];
[window.queue postEvent:event];
macdrv_release_event(event);
}
}
// Since mouse button events deliver absolute cursor position, the
// accumulating delta from move events is invalidated. Make sure
// next mouse move event starts over from an absolute baseline.
// Also, it's at least possible that the title bar widgets (e.g. close
// button, etc.) could enter an internal event loop on a mouse down that
// wouldn't exit until a mouse up. In that case, we'd miss any mouse
// dragged events and, after that, any notion of the cursor position
// computed from accumulating deltas would be wrong.
forceNextMouseMoveAbsolute = TRUE;
}
// Returns TRUE if the event was handled and caller should do nothing more
// with it. Returns FALSE if the caller should process it as normal and
// then call -didSendEvent:.
@ -1240,12 +1321,15 @@ - (void) didSendEvent:(NSEvent*)anEvent
}
else if (type == NSLeftMouseDown || type == NSLeftMouseUp ||
type == NSRightMouseDown || type == NSRightMouseUp ||
type == NSOtherMouseDown || type == NSOtherMouseUp ||
type == NSScrollWheel)
type == NSOtherMouseDown || type == NSOtherMouseUp)
{
// Since mouse button and scroll wheel events deliver absolute cursor
// position, the accumulating delta from move events is invalidated.
// Make sure next mouse move event starts over from an absolute baseline.
[self handleMouseButton:anEvent];
}
else if (type == NSScrollWheel)
{
// Since scroll wheel events deliver absolute cursor position, the
// accumulating delta from move events is invalidated. Make sure next
// mouse move event starts over from an absolute baseline.
forceNextMouseMoveAbsolute = TRUE;
}
else if (type == NSKeyDown && ![anEvent isARepeat] && [anEvent keyCode] == kVK_Tab)

View file

@ -250,13 +250,6 @@ - (void) drawRect:(NSRect)rect
}
}
/* By default, NSView will swallow right-clicks in an attempt to support contextual
menus. We need to bypass that and allow the event to make it to the window. */
- (void) rightMouseDown:(NSEvent*)theEvent
{
[[self window] rightMouseDown:theEvent];
}
- (void) addGLContext:(WineOpenGLContext*)context
{
if (!glContexts)
@ -839,23 +832,6 @@ - (void) setShape:(NSBezierPath*)newShape
[self checkTransparency];
}
- (void) postMouseButtonEvent:(NSEvent *)theEvent pressed:(int)pressed
{
CGPoint pt = CGEventGetLocation([theEvent CGEvent]);
macdrv_event* event;
event = macdrv_create_event(MOUSE_BUTTON, self);
event->mouse_button.button = [theEvent buttonNumber];
event->mouse_button.pressed = pressed;
event->mouse_button.x = pt.x;
event->mouse_button.y = pt.y;
event->mouse_button.time_ms = [[WineApplicationController sharedController] ticksForEventTime:[theEvent timestamp]];
[queue postEvent:event];
macdrv_release_event(event);
}
- (void) makeFocused:(BOOL)activate
{
WineApplicationController* controller = [WineApplicationController sharedController];
@ -1061,14 +1037,6 @@ - (void) sendEvent:(NSEvent*)event
/*
* ---------- NSResponder method overrides ----------
*/
- (void) mouseDown:(NSEvent *)theEvent { [self postMouseButtonEvent:theEvent pressed:1]; }
- (void) rightMouseDown:(NSEvent *)theEvent { [self mouseDown:theEvent]; }
- (void) otherMouseDown:(NSEvent *)theEvent { [self mouseDown:theEvent]; }
- (void) mouseUp:(NSEvent *)theEvent { [self postMouseButtonEvent:theEvent pressed:0]; }
- (void) rightMouseUp:(NSEvent *)theEvent { [self mouseUp:theEvent]; }
- (void) otherMouseUp:(NSEvent *)theEvent { [self mouseUp:theEvent]; }
- (void) keyDown:(NSEvent *)theEvent { [self postKeyEvent:theEvent]; }
- (void) keyUp:(NSEvent *)theEvent { [self postKeyEvent:theEvent]; }