I will be very happy if you find a solution on your own, I can't handle it.
Here is what I did to make the cursor behavior the same for all three OS.
There is just something here that I don't understand.
Why is the "enter" event fired when the mouse leaves the window and the "leave" event when the mouse is inside?
Code: Select all
EnableExplicit
UsePNGImageDecoder()
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
ImportC ""
gtk_widget_get_window(*Widget.GtkWidget)
EndImport
CompilerEndIf
Procedure ChangeCursorToPNGImage(WindowID.I, ImageID.I)
Protected CustomCursor.I
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
CustomCursor = gdk_cursor_new_from_pixbuf_(gdk_display_get_default_(),
ImageID(ImageID), 0, 0)
gdk_window_set_cursor_(gtk_widget_get_window(WindowID(WindowID)),
CustomCursor)
CompilerCase #PB_OS_MacOS
Protected Hotspot.NSPoint
Hotspot\x = 1
Hotspot\y = 1
CustomCursor = CocoaMessage(0, 0, "NSCursor alloc")
CocoaMessage(0, CustomCursor,
"initWithImage:", ImageID(ImageID),
"hotSpot:@", @Hotspot)
CocoaMessage(0, CustomCursor, "set")
SetWindowData(0, CustomCursor)
CompilerCase #PB_OS_Windows
Protected Cursor.ICONINFO
Cursor\fIcon = #False
Cursor\xHotspot = 1
Cursor\yHotspot = 1
Cursor\hbmColor = ImageID(ImageID)
Cursor\hbmMask = ImageID(ImageID)
CustomCursor = CreateIconIndirect_(Cursor)
SetClassLongPtr_(WindowID(WindowID), #GCL_HCURSOR, CustomCursor)
CompilerEndSelect
ProcedureReturn CustomCursor
EndProcedure
If LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/world.png") = 0
MessageRequester("Error",
"Loading of image World.png failed!",
#PB_MessageRequester_Error)
End
EndIf
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
; #NSLeftMouseDown = 1
; #NSLeftMouseUp = 2
; #NSRightMouseDown = 3
; #NSRightMouseUp = 4
; #NSMouseMoved = 5
; #NSLeftMouseDragged = 6
; #NSRightMouseDragged = 7
; #NSMouseEntered = 8
; #NSMouseExited = 9
; #NSKeyDown = 10
; #NSKeyUp = 11
; #NSFlagsChanged = 12
; #NSAppKitDefined = 13
; #NSSystemDefined = 14
; #NSApplicationDefined = 15
; #NSPeriodic = 16
; #NSCursorUpdate = 17
; #NSScrollWheel = 22
; #NSTabletPoint = 23
; #NSTabletProximity = 24
; #NSOtherMouseDown = 25
; #NSOtherMouseUp = 26
; #NSOtherMouseDragged = 27
; #NSEventTypeGesture = 29
; #NSEventTypeMagnify = 30
; #NSEventTypeSwipe = 31
; #NSEventTypeRotate = 18
; #NSEventTypeBeginGesture = 19
; #NSEventTypeEndGesture = 20
; #NSEventTypeSmartMagnify = 32
; #NSEventTypeQuickLook = 33
;
#MaskLeftMouseDown = 1<<1
#MaskLeftMouseUp = 1<<2
#MaskRightMouseDown = 1<<3
#MaskRightMouseUp = 1<<4
#MaskMouseMoved = 1<<5
#MaskLeftMouseDragged = 1<<6
#MaskRightMouseDragged = 1<<7
#MaskMouseEntered = 1<<9
#MaskMouseExited = 1<<8
#MaskKeyDown = 1<<10
#MaskKeyUp = 1<<11
#MaskFlagsChanged = 1<<12
#MaskAppKitDefined = 1<<13
#MaskSystemDefined = 1<<14
#MaskApplicationDefined = 1<<15
#MaskPeriodic = 1<<16
#MaskCursorUpdate = 1<<17
#MaskScrollWheel = 1<<22
#MaskTabletPoint = 1<<23
#MaskTabletProximity = 1<<24
#MaskOtherMouseDown = 1<<25
#MaskOtherMouseUp = 1<<26
#MaskOtherMouseDragged = 1<<27
#MaskEventTypeGesture = 1<<29
#MaskEventTypeMagnify = 1<<30
#MaskEventTypeSwipe = 1<<31
#MaskEventTypeRotate = 1<<18
#MaskEventTypeBeginGesture = 1<<19
#MaskEventTypeEndGesture = 1<<20
#MaskEventTypeSmartMagnify = 1<<32
#MaskEventTypeQuickLook = 1<<33
Global eventTap, mask = #MaskMouseEntered | #MaskMouseExited | #MaskMouseMoved | #MaskCursorUpdate
ProcedureC eventTapFunction(proxy, type, event, refcon)
Protected NSEvent = CocoaMessage(0, 0, "NSEvent eventWithCGEvent:", event)
If NSEvent
Protected NSWindow = CocoaMessage(0, NSEvent, "window")
If type = #NSMouseEntered
If CocoaMessage(0, 0, "NSCursor currentCursor") <> CocoaMessage(0, 0, "NSCursor arrowCursor")
Debug "enter - "+GetWindowData(0) +" "+ CocoaMessage(0, 0, "NSCursor currentCursor")
CocoaMessage(0, CocoaMessage(0, 0, "NSCursor arrowCursor"), "set")
EndIf
ElseIf type = #NSMouseExited
If GetWindowData(0) And GetWindowData(0) <> CocoaMessage(0, 0, "NSCursor currentCursor")
Debug "leave - "+GetWindowData(0) +" "+ CocoaMessage(0, 0, "NSCursor currentCursor")
CocoaMessage(0, GetWindowData(0), "set")
EndIf
ElseIf type = #NSMouseMoved
ElseIf type = #NSCursorUpdate
EndIf
EndIf
EndProcedure
#cghidEventTap = 0 ; Указывает, что отвод события размещается в точке, где системные события HID поступают на оконный сервер.
#cgSessionEventTap = 1 ; Указывает, что отвод события размещается в точке, где события системы HID и удаленного управления входят в сеанс входа в систему.
#cgAnnotatedSessionEventTap = 2 ; Указывает, что отвод события размещается в точке, где события сеанса были аннотированы для передачи в приложение.
#headInsertEventTap = 0 ; Указывает, что новое касание события должно быть вставлено перед любым ранее существовавшим касанием события в том же месте.
#tailAppendEventTap = 1 ; Указывает, что новое касание события должно быть вставлено после любого ранее существовавшего касания события в том же месте
eventTap = CGEventTapCreate_(#cgAnnotatedSessionEventTap, #headInsertEventTap, 1, mask, @eventTapFunction(), 0)
If eventTap
CocoaMessage(0, CocoaMessage(0, 0, "NSRunLoop currentRunLoop"), "addPort:", eventTap, "forMode:$", @"kCFRunLoopCommonModes")
EndIf
CompilerEndIf
OpenWindow(0, 200, 100, 290, 120, "Display custom cursor")
ButtonGadget(0, WindowWidth(0) / 2 - 120, 40, 240, 25, "Change cursor to PNG image")
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick
ChangeCursorToPNGImage(0, 0)
; SetWindowTitle(0, Str(Random(255)))
DisableGadget(0, #True)
EndIf
EndSelect
ForEver