diff --git a/Engine/system/api/macosapi.mm b/Engine/system/api/macosapi.mm index 62daeb1b..28985b66 100644 --- a/Engine/system/api/macosapi.mm +++ b/Engine/system/api/macosapi.mm @@ -106,6 +106,28 @@ static NSPoint mousePos(NSPoint px, NSWindow* wnd, bool& inWindow) { return mousePos(e,dummy); } +static Tempest::Point mousePos(NSWindow* wnd, bool& inWindow) { + NSPoint p = [wnd mouseLocationOutsideOfEventStream]; + NSPoint px = mousePos(p, wnd, inWindow); + return Tempest::Point{int(px.x), int(px.y)}; + } + +static void implShowCursor(SystemApi::Window *w, CursorShape show) { + static CursorShape current = CursorShape::Arrow; + if(current==show) { + // show/hie mechanism is ref couter based on Mac + // https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/QuartzDisplayServicesConceptual/Articles/MouseCursor.html + return; + } + + current = show; + if(show==CursorShape::Hidden) { + CGDisplayHideCursor(kCGNullDirectDisplay); + return; + } + CGDisplayShowCursor(kCGNullDirectDisplay); + } + void Detail::ImplMacOSApi::onDisplayLink(void* hwnd) { @autoreleasepool { auto cb = reinterpret_cast(hwnd); @@ -128,6 +150,20 @@ static NSPoint mousePos(NSPoint px, NSWindow* wnd, bool& inWindow) { auto cb = reinterpret_cast(hwnd); NSWindow* wnd = reinterpret_cast(w); + bool inWindow = true; + auto mpos = mousePos(wnd, inWindow); + if(inWindow) { + MouseEvent e( mpos.x, + mpos.y, + Event::ButtonNone, + Event::M_NoModifier, + 0, + 0, + Event::MouseMove ); + MacOSApi::dispatchMouseMove(*cb, e); + } + implShowCursor(reinterpret_cast(w), MacOSApi::cursorShape(*cb)); + FocusEvent e(true, Event::UnknownReason); MacOSApi::dispatchFocus(*cb, e); } @@ -367,11 +403,7 @@ - (void)dispatchRenderer{ } void MacOSApi::implShowCursor(SystemApi::Window *w, CursorShape show) { - if(show==CursorShape::Hidden) { - CGDisplayHideCursor(kCGNullDirectDisplay); - return; - } - CGDisplayShowCursor(kCGNullDirectDisplay); + ::implShowCursor(w, show); } void MacOSApi::implSetWindowTitle(Window* w, const char* utf8) { @@ -601,7 +633,7 @@ MouseEvent e(p.x,p.y, break; } default: break; - } + } auto isDown = evt.modifierFlags & flag; auto eType = (isDown ? Event::KeyDown : Event::KeyUp); @@ -613,8 +645,8 @@ MouseEvent e(p.x,p.y, return; } case NSEventTypeAppKitDefined: - break; case NSEventTypeMouseEntered: + break; case NSEventTypeMouseExited: break; diff --git a/Engine/system/api/windowsapi.cpp b/Engine/system/api/windowsapi.cpp index 6c889424..642e4a5f 100644 --- a/Engine/system/api/windowsapi.cpp +++ b/Engine/system/api/windowsapi.cpp @@ -394,7 +394,21 @@ long long WindowsApi::windowProc(void *_hWnd, uint32_t msg, const unsigned long } case WM_ACTIVATE:{ - SetCursor(cb->cursorShape()); + POINT mpos = {}; + if(wParam==WA_ACTIVE && GetCursorPos(&mpos)) { + mpos.x -= cb->x(); + mpos.y -= cb->y(); + MouseEvent e( mpos.x, + mpos.y, + Event::ButtonNone, + Event::M_NoModifier, + 0, + 0, + Event::MouseMove ); + SystemApi::dispatchMouseMove(*cb, e); + } + + SetCursor(SystemApi::cursorShape(*cb)); if(wParam==WA_INACTIVE) { FocusEvent e(false, Event::UnknownReason); SystemApi::dispatchFocus(*cb, e); diff --git a/Engine/system/api/x11api.cpp b/Engine/system/api/x11api.cpp index a7abcc78..c1bbdcd0 100644 --- a/Engine/system/api/x11api.cpp +++ b/Engine/system/api/x11api.cpp @@ -279,7 +279,7 @@ SystemApi::Window *X11Api::implCreateWindow(Tempest::Window *owner, uint32_t w, XSetWindowAttributes swa={}; swa.colormap = cmap; - swa.event_mask = PointerMotionMask | ExposureMask | + swa.event_mask = PointerMotionMask | EnterWindowMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | FocusChangeMask | StructureNotifyMask | @@ -598,6 +598,28 @@ void X11Api::implProcessEvents(SystemApi::AppCallBack &cb) { } break; } + case EnterNotify: { + MouseEvent e( xev.xcrossing.x, + xev.xcrossing.y, + Event::ButtonNone, + Event::M_NoModifier, + 0, + 0, + Event::MouseMove ); + SystemApi::dispatchMouseMove(cb,e); + implShowCursor(hWnd.ptr(),SystemApi::cursorShape(cb)); + break; + } + case FocusIn: { + FocusEvent e(true, Event::UnknownReason); + SystemApi::dispatchFocus(cb, e); + break; + } + case FocusOut: { + FocusEvent e(false, Event::UnknownReason); + SystemApi::dispatchFocus(cb, e); + break; + } case MotionNotify: { if(activeCursorChange == 1) { // FIXME: mouse behave crazy in OpenGothic @@ -643,16 +665,6 @@ void X11Api::implProcessEvents(SystemApi::AppCallBack &cb) { SystemApi::dispatchKeyUp (cb,e,scan); break; } - case FocusIn: { - FocusEvent e(true, Event::UnknownReason); - SystemApi::dispatchFocus(cb, e); - break; - } - case FocusOut: { - FocusEvent e(false, Event::UnknownReason); - SystemApi::dispatchFocus(cb, e); - break; - } } std::this_thread::yield(); diff --git a/Engine/system/systemapi.cpp b/Engine/system/systemapi.cpp index f942ba89..9e61bd75 100644 --- a/Engine/system/systemapi.cpp +++ b/Engine/system/systemapi.cpp @@ -205,6 +205,10 @@ void SystemApi::showCursor(SystemApi::Window *w, CursorShape show) { return inst().implShowCursor(w,show); } +CursorShape SystemApi::cursorShape(Tempest::Window& cb) { + return cb.resolvedCursor; + } + float SystemApi::uiScale(Window* w) { return inst().implUiScale(w); } diff --git a/Engine/system/systemapi.h b/Engine/system/systemapi.h index 3e5704e1..31482d0f 100644 --- a/Engine/system/systemapi.h +++ b/Engine/system/systemapi.h @@ -89,6 +89,7 @@ class SystemApi { static void setCursorPosition(SystemApi::Window *w, int x, int y); static void showCursor(SystemApi::Window *w, CursorShape c); + static CursorShape cursorShape(Tempest::Window& cb); static void dispatchOverlayRender(Tempest::Window &w, Tempest::PaintEvent& e); static void dispatchRender (Tempest::Window& cb); diff --git a/Engine/ui/window.cpp b/Engine/ui/window.cpp index 69f8977e..de00eb2c 100644 --- a/Engine/ui/window.cpp +++ b/Engine/ui/window.cpp @@ -57,5 +57,6 @@ void Window::setCursorPosition(const Point& p) { } void Window::implShowCursor(CursorShape s) { + resolvedCursor = s; SystemApi::showCursor(hwnd(),s); } diff --git a/Engine/ui/window.h b/Engine/ui/window.h index 846822a6..9217073e 100644 --- a/Engine/ui/window.h +++ b/Engine/ui/window.h @@ -37,11 +37,13 @@ class Window : public Widget { private: void implShowCursor(CursorShape s); - SystemApi::Window* id=nullptr; + SystemApi::Window* id = nullptr; + CursorShape resolvedCursor = CursorShape::Arrow; friend class Widget; friend class UiOverlay; friend class EventDispatcher; + friend class SystemApi; }; }