Shardik wrote: Fri Apr 08, 2022 9:38 pm On MacOS the custom cursor is displayed on the whole desktop and doesn't change when leaving the inner window.
It's not quite right. Try with this.Code: Select all
If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick ChangeCursorToPNGImage(0, 0) DisableGadget(0, #True) SetWindowTitle( 0, "change cursor") EndIf
cursor from datasection
Re: cursor from datasection
Re: cursor from datasection
mestnyi, thank you for your reply. I have tested your proposed addition of SetWindowTitle( 0, "change cursor"), but after its insertion the changing of the cursor to the PNG image doesn't work anymore.mestnyi wrote: Sun Apr 10, 2022 8:28 pmIt's not quite right. Try with this.Shardik wrote: Fri Apr 08, 2022 9:38 pm On MacOS the custom cursor is displayed on the whole desktop and doesn't change when leaving the inner window.Code: Select all
If EventGadget() = 0 And EventType() = #PB_EventType_LeftClick ChangeCursorToPNGImage(0, 0) DisableGadget(0, #True) SetWindowTitle( 0, "change cursor") EndIf
I have just tested your modification with MacOS 10.13.6 and PB 6.00 Beta 6 with Asm backend. If your modification works on your MacOS version, please tell me your MacOS and PB version.
Re: cursor from datasection
The thing is, I wanted to say that it stops working and it doesn't have to be SetWindowTitle( ).
It turns out that we must either set the cursor all the time or apply the cursor setting at the end of all events.
I've looked for the event sent by the system after changing the cursor, but haven't found it yet.
This is what I think is what I need, but I can’t apply it in cocoa.
https://spec-zone.ru/RU/OSX/documentati ... 0060i-CH11
It turns out that we must either set the cursor all the time or apply the cursor setting at the end of all events.
I've looked for the event sent by the system after changing the cursor, but haven't found it yet.
This is what I think is what I need, but I can’t apply it in cocoa.
https://spec-zone.ru/RU/OSX/documentati ... 0060i-CH11
Re: cursor from datasection
You are right. I am working on this problem but it may take some time.mestnyi wrote: Thu Apr 14, 2022 8:22 am The thing is, I wanted to say that it stops working and it doesn't have to be SetWindowTitle( ).
It turns out that we must either set the cursor all the time or apply the cursor setting at the end of all events.
Re: cursor from datasection
I will be very happy if you find a solution on your own, I can't handle it.Shardik wrote: Thu Apr 14, 2022 9:34 pmYou are right. I am working on this problem but it may take some time.mestnyi wrote: Thu Apr 14, 2022 8:22 am The thing is, I wanted to say that it stops working and it doesn't have to be SetWindowTitle( ).
It turns out that we must either set the cursor all the time or apply the cursor setting at the end of all events.
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
Re: cursor from datasection
I have found a different approach to change the cursor on MacOS to the default cursor when leaving the window. Like you I use CGEventTapCreate() to establish an event handler procedure for MacOS. This procedure is always activated when the mouse is moved and only checks with WindowMouseX() and WindowMouseY() if x or y is -1 and then switches to the default cursor (cursor has left the window) or switches back to the custom cursor when both x and y are not -1 (cursor is inside of window). Now SetWindowTitle() doesn't interfere anymore with the custom cursor on MacOS.
I have tested this example successfully on these MacOS versions with PB 5.73 x64:
I have tested this example successfully on these MacOS versions with PB 5.73 x64:
- 10.15.7 'Catalina'
- 11.6.4 'Big Sur'
- 12.2.1 + 12.3.1 'Monterey'
Code: Select all
EnableExplicit
UsePNGImageDecoder()
Define CustomCursor.I
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
ImportC ""
gtk_widget_get_window(*Widget.GtkWidget)
EndImport
CompilerCase #PB_OS_MacOS
ImportC ""
CGEventTapCreate(Tap.I, Place.I, Options.I, EventsOfInterest.Q,
Callback.I, *UserData)
EndImport
Define CursorInWindow.I
Define EventTap.I
ProcedureC EventTapHandler(Proxy.I, EventType.I, Event.I, *UserData)
Shared CustomCursor.I
Shared CursorInWindow.I
If CustomCursor
If WindowMouseX(0) = -1 Or WindowMouseY(0) = -1
If CursorInWindow = #True
CocoaMessage(0, CocoaMessage(0, 0, "NSCursor arrowCursor"), "set")
CursorInWindow = #False
EndIf
Else
If CursorInWindow = #False
CocoaMessage(0, CustomCursor, "set")
CursorInWindow = #True
EndIf
EndIf
EndIf
EndProcedure
EventTap = CGEventTapCreate(0, 0, 1, #NSMouseMovedMask, @EventTapHandler(),
0)
If EventTap
CocoaMessage(0, CocoaMessage(0, 0, "NSRunLoop currentRunLoop"),
"addPort:", EventTap, "forMode:$", @"kCFRunLoopDefaultMode")
EndIf
CompilerEndSelect
Procedure ChangeCursorToPNGImage(WindowID.I, ImageID.I)
Shared 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")
CocoaMessage(0, WindowID(WindowID), "disableCursorRects")
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
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
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)
DisableGadget(0, #True)
SetWindowTitle(0, "Cursor changed into PNG image")
EndIf
EndSelect
ForEver
Re: cursor from datasection
This is what I needed. Thank you very much.
Code: Select all
CocoaMessage(0, WindowID(WindowID), "disableCursorRects")