Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 25 additions & 46 deletions dev/src/api_macos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ static constexpr const char* kSetContentViewSel = "setContentVie
static constexpr const char* kContentViewSel = "contentView";
static constexpr const char* kBoundsSel = "bounds";
static constexpr const char* kConvertRectToBackingSel = "convertRectToBacking:"; // Thank you - Ben the Ultimate Guru
static constexpr const char* kConvertRectFromBackingSel = "convertRectFromBacking:"; // Thank you - Mr B the Ultimate Teacher!!!
static constexpr const char* kConvertPointToBackingSel = "convertPointToBacking:";
static constexpr const char* kConvertPointFromBackingSel = "convertPointFromBacking:";
static constexpr const char* kConvertPointFromViewSel = "convertPoint:fromView:";
Expand Down Expand Up @@ -330,6 +331,7 @@ namespace ObjectiveCSEL {
static SEL contentViewSel = nullptr;
static SEL boundsSel = nullptr;
static SEL convertRectToBackingSel = nullptr; // Thank you - Ben the Ultimate Guru
static SEL convertRectFromBackingSel = nullptr; // Thank you - Mr B the Ultimate Teacher!!!
static SEL convertPointToBackingSel = nullptr;
static SEL convertPointFromBackingSel = nullptr;
static SEL convertPointFromViewSel = nullptr;
Expand Down Expand Up @@ -479,6 +481,7 @@ namespace ObjectiveCSEL {
contentViewSel = sel_registerName(kContentViewSel);
boundsSel = sel_registerName(kBoundsSel);
convertRectToBackingSel = sel_registerName(kConvertRectToBackingSel); // Thank you - Ben the Ultimate Guru
convertRectFromBackingSel = sel_registerName(kConvertRectFromBackingSel); // Thank you - Mr B the Ultimate Teacher!!!
convertPointToBackingSel = sel_registerName(kConvertPointToBackingSel);
convertPointFromBackingSel = sel_registerName(kConvertPointFromBackingSel);
convertPointFromViewSel = sel_registerName(kConvertPointFromViewSel);
Expand Down Expand Up @@ -1365,8 +1368,8 @@ void view_mouseDown(id self, SEL _cmd, id event) {
CGEventRef cgEvent = ((CGEventRef(*)(id, SEL))objc_msgSend)(event, ObjectiveCSEL::cgEventSel);
uint8_t nPointerEventType = CGEventGetIntegerValueField(cgEvent, kCGMouseEventSubtype);

// Is it a mouse drag event (subtype 0) or a tablet pointer event (subtype 1 or 2)?
if (nPointerEventType == 0) [[likely]] {
// Is it a mouse drag event (subtype 0) or a tablet pointer event (subtype 1 or 2)? Thanks Mr B
if (nPointerEventType != kCGEventMouseSubtypeTabletPoint && nPointerEventType != kCGEventMouseSubtypeTabletProximity) [[likely]] {

if (gptrNSWindowEvents && gptrNSWindowEvents->acceptsInputEvents && gptrNSWindowEvents->mouseDownCallback) [[likely]] {
MouseEventData data = extractMouseEventData(event);
Expand Down Expand Up @@ -1397,8 +1400,8 @@ void view_mouseUp(id self, SEL _cmd, id event) {
CGEventRef cgEvent = ((CGEventRef(*)(id, SEL))objc_msgSend)(event, ObjectiveCSEL::cgEventSel);
uint8_t nPointerEventType = CGEventGetIntegerValueField(cgEvent, kCGMouseEventSubtype);

// Is it a mouse drag event (subtype 0) or a tablet pointer event (subtype 1 or 2)?
if (nPointerEventType == 0) [[likely]] {
// Is it a mouse drag event (subtype 0) or a tablet pointer event (subtype 1 or 2)? Thanks Mr B
if (nPointerEventType != kCGEventMouseSubtypeTabletPoint && nPointerEventType != kCGEventMouseSubtypeTabletProximity) [[likely]] {

MouseEventData data = extractMouseEventData(event);
if (gptrNSWindowEvents && gptrNSWindowEvents->acceptsInputEvents && gptrNSWindowEvents->mouseUpCallback) [[likely]] {
Expand Down Expand Up @@ -1429,8 +1432,8 @@ void view_mouseDragged(id self, SEL _cmd, id event) {
CGEventRef cgEvent = ((CGEventRef(*)(id, SEL))objc_msgSend)(event, ObjectiveCSEL::cgEventSel);
uint8_t nPointerEventType = CGEventGetIntegerValueField(cgEvent, kCGMouseEventSubtype);

// Is it a mouse drag event (subtype 0) or a tablet pointer event (subtype 1 or 2)?
if (nPointerEventType == 0) [[likely]] {
// Is it a mouse drag event (subtype 0) or a tablet pointer event (subtype 1 or 2)? Thanks Mr B
if (nPointerEventType != kCGEventMouseSubtypeTabletPoint && nPointerEventType != kCGEventMouseSubtypeTabletProximity) [[likely]] {

if (gptrNSWindowEvents && gptrNSWindowEvents->acceptsInputEvents && gptrNSWindowEvents->mouseDraggedCallback) [[likely]] {
MouseEventData data = extractMouseEventData(event);
Expand All @@ -1456,12 +1459,7 @@ void view_mouseDragged(id self, SEL _cmd, id event) {
// Handle mouse movement events
void view_mouseMoved(id self, SEL _cmd, id event) {
(void)self;(void)_cmd;

CGEventRef cgEvent = ((CGEventRef(*)(id, SEL))objc_msgSend)(event, ObjectiveCSEL::cgEventSel);
uint8_t nPointerEventType = CGEventGetIntegerValueField(cgEvent, kCGMouseEventSubtype);
// if it is a trackpad event, ignore it.
if (nPointerEventType > 2) return;


// a Mouse move event and Stlus roximity Event have the same properties.
NSPoint location = ((NSPoint(*)(id, SEL))objc_msgSend)(event, ObjectiveCSEL::locationInWindowSel);
NSUInteger modifierFlags = ((NSUInteger(*)(id, SEL))objc_msgSend)(event, ObjectiveCSEL::modifierFlagsSel);
Expand All @@ -1476,12 +1474,7 @@ void view_mouseMoved(id self, SEL _cmd, id event) {
// Handle right mouse down events
void view_rightMouseDown(id self, SEL _cmd, id event) {
(void)self;(void)_cmd;

CGEventRef cgEvent = ((CGEventRef(*)(id, SEL))objc_msgSend)(event, ObjectiveCSEL::cgEventSel);
uint8_t nPointerEventType = CGEventGetIntegerValueField(cgEvent, kCGMouseEventSubtype);
if(nPointerEventType > 2) [[unlikely]]
return; // Ignore mouse events that are not mouse drag or tablet pointer events


MouseEventData data = extractMouseEventData(event);
if (gptrNSWindowEvents && gptrNSWindowEvents->acceptsInputEvents && gptrNSWindowEvents->rightMouseDownCallback) [[likely]] {
gptrNSWindowEvents->rightMouseDownCallback(data.location.x, data.location.y, (int)data.buttonNumber, (unsigned int)data.modifierFlags, gptrNSWindowEvents->eventUserData);
Expand All @@ -1492,11 +1485,6 @@ void view_rightMouseDown(id self, SEL _cmd, id event) {
void view_rightMouseUp(id self, SEL _cmd, id event) {
(void)self;(void)_cmd;

CGEventRef cgEvent = ((CGEventRef(*)(id, SEL))objc_msgSend)(event, ObjectiveCSEL::cgEventSel);
uint8_t nPointerEventType = CGEventGetIntegerValueField(cgEvent, kCGMouseEventSubtype);
if(nPointerEventType > 2) [[unlikely]]
return; // Ignore mouse events that are not mouse drag or tablet pointer events

MouseEventData data = extractMouseEventData(event);
if (gptrNSWindowEvents && gptrNSWindowEvents->acceptsInputEvents && gptrNSWindowEvents->rightMouseUpCallback) [[likely]] {
gptrNSWindowEvents->rightMouseUpCallback(data.location.x, data.location.y, (int)data.buttonNumber, (unsigned int)data.modifierFlags, gptrNSWindowEvents->eventUserData);
Expand All @@ -1506,11 +1494,6 @@ void view_rightMouseUp(id self, SEL _cmd, id event) {
// Handle right mouse drag events
void view_rightMouseDragged(id self, SEL _cmd, id event) {
(void)self;(void)_cmd;

CGEventRef cgEvent = ((CGEventRef(*)(id, SEL))objc_msgSend)(event, ObjectiveCSEL::cgEventSel);
uint8_t nPointerEventType = CGEventGetIntegerValueField(cgEvent, kCGMouseEventSubtype);
if(nPointerEventType > 2) [[unlikely]]
return; // Ignore mouse events that are not mouse drag or tablet pointer events

MouseEventData data = extractMouseEventData(event);
if (gptrNSWindowEvents && gptrNSWindowEvents->acceptsInputEvents && gptrNSWindowEvents->rightMouseDraggedCallback) [[likely]] {
Expand All @@ -1523,11 +1506,6 @@ void view_rightMouseDragged(id self, SEL _cmd, id event) {
void view_otherMouseDown(id self, SEL _cmd, id event) {
(void)self;(void)_cmd;

CGEventRef cgEvent = ((CGEventRef(*)(id, SEL))objc_msgSend)(event, ObjectiveCSEL::cgEventSel);
uint8_t nPointerEventType = CGEventGetIntegerValueField(cgEvent, kCGMouseEventSubtype);
if(nPointerEventType > 2) [[unlikely]]
return; // Ignore mouse events that are not mouse drag or tablet pointer events

MouseEventData data = extractMouseEventData(event);
if (gptrNSWindowEvents && gptrNSWindowEvents->acceptsInputEvents && gptrNSWindowEvents->otherMouseDownCallback) [[likely]] {
gptrNSWindowEvents->otherMouseDownCallback(data.location.x, data.location.y, (int)data.buttonNumber, (unsigned int)data.modifierFlags, gptrNSWindowEvents->eventUserData);
Expand All @@ -1538,11 +1516,6 @@ void view_otherMouseDown(id self, SEL _cmd, id event) {
void view_otherMouseUp(id self, SEL _cmd, id event) {
(void)self;(void)_cmd;

CGEventRef cgEvent = ((CGEventRef(*)(id, SEL))objc_msgSend)(event, ObjectiveCSEL::cgEventSel);
uint8_t nPointerEventType = CGEventGetIntegerValueField(cgEvent, kCGMouseEventSubtype);
if(nPointerEventType > 2) [[unlikely]]
return; // Ignore mouse events that are not mouse drag or tablet pointer events

MouseEventData data = extractMouseEventData(event);
if (gptrNSWindowEvents && gptrNSWindowEvents->acceptsInputEvents && gptrNSWindowEvents->otherMouseUpCallback) {
gptrNSWindowEvents->otherMouseUpCallback(data.location.x, data.location.y, (int)data.buttonNumber, (unsigned int)data.modifierFlags, gptrNSWindowEvents->eventUserData);
Expand All @@ -1551,11 +1524,6 @@ void view_otherMouseUp(id self, SEL _cmd, id event) {

void view_otherMouseDragged(id self, SEL _cmd, id event) {
(void)self;(void)_cmd;

CGEventRef cgEvent = ((CGEventRef(*)(id, SEL))objc_msgSend)(event, ObjectiveCSEL::cgEventSel);
uint8_t nPointerEventType = CGEventGetIntegerValueField(cgEvent, kCGMouseEventSubtype);
if(nPointerEventType > 2) [[unlikely]]
return; // Ignore mouse events that are not mouse drag or tablet pointer events

MouseEventData data = extractMouseEventData(event);
if (gptrNSWindowEvents && gptrNSWindowEvents->acceptsInputEvents && gptrNSWindowEvents->otherMouseDraggedCallback) [[likely]] {
Expand Down Expand Up @@ -2100,7 +2068,17 @@ extern "C" {

// Destroy the window
void window_destroy(Window* self) {
(void)self;

// Thanks Mr B!
if (self) {
self->acceptsInputEvents = NO;
if (gptrNSWindowEvents == self) {
gptrNSWindowEvents = NULL;
}
if (gptrWindowDelegate == self) {
gptrWindowDelegate = NULL;
}
}
// NSWindow will be cleaned up by autorelease pool
}

Expand Down Expand Up @@ -2411,8 +2389,9 @@ extern "C" {
// Make context current
((void(*)(id, SEL))objc_msgSend)(self->glContext, ObjectiveCSEL::makeCurrentContextSel);

// Update the view frame
NSRect newFrame = {0.0, 0.0, width, height};
// Update the view frame Without folks like Mr B the Ultimate Teacher, this would have been tricky
NSRect pixelFrame = {0.0, 0.0, width, height};
NSRect newFrame = ((NSRect(*)(id, SEL, NSRect))objc_msgSend)(self->glView, ObjectiveCSEL::convertRectFromBackingSel, pixelFrame);
((void(*)(id, SEL, NSRect))objc_msgSend)(self->glView, ObjectiveCSEL::setFrameSel, newFrame);

// Force context to reshape
Expand Down
14 changes: 10 additions & 4 deletions dev/src/host_apple_macos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,16 +212,15 @@ namespace olc::host {
bool Host_Apple_MacOS::SetMousePosition(olc::Window* pWindow, const olc::vi2d& vPos)
{
olc_IgnoreUnused(pWindow);
dispatch_sync(dispatch_get_main_queue(), ^{
pMacOSWindow->setCursorPosition(vPos.x, vPos.y);
});
vPositionMouse = vPos;
this->vPendingMainThreadTasks.push_back(SET_MOUSE_POSITION);
return false;
}

bool Host_Apple_MacOS::SetMouseVisible(olc::Window* pWindow, const bool bVisible)
{
olc_IgnoreUnused(pWindow);
dispatch_sync(dispatch_get_main_queue(), ^{
dispatch_async(dispatch_get_main_queue(), ^{
pMacOSWindow->setCursorVisibility(bVisible);
});
return true;
Expand Down Expand Up @@ -555,6 +554,13 @@ namespace olc::host {
pPGEwindow->olc_OnFocus(false);
break;
}
case SET_MOUSE_POSITION:
{
// Set mouse position on main thread
pMacOSWindow->setCursorPosition(vPositionMouse.x, vPositionMouse.y);
res = false; // No need to skip frame
break;
}
case NONE:
default:
{
Expand Down
5 changes: 4 additions & 1 deletion dev/src/host_apple_macos.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ namespace olc
BECOME_ACTIVE,
RESIGN_ACTIVE,
MINIMIZE_WINDOW,
DEMINIMIZE_WINDOW
DEMINIMIZE_WINDOW,
SET_MOUSE_POSITION
};

// Internal Mac OS functions
Expand Down Expand Up @@ -149,6 +150,8 @@ namespace olc
void KeyboardEventHandler(const olc::apis::macos::KeyEvent& event, bool isPressed);
bool bNumLockActive = true; // Num Lock state, we assume it's active at start
uint16_t ConvertPGE2WindowStyle();

olc::vi2d vPositionMouse = {0, 0}; // Stores the desired mouse position for SET_MOUSE_POSITION task


};
Expand Down
Loading
Loading