Page 1 of 1

Canvas mouse position (enter & leave)

Posted: Fri Sep 27, 2024 5:11 pm
by mestnyi
In windows I observe a strange behavior the position of the canvas mouse when the window has no borders.
Hover over the first window then go to the second window we get the following events.

Code: Select all

enter 1
enter 2
leave 1
The following events were supposed to happen.

Code: Select all

enter 1
leave 1
enter 2

Code: Select all

Procedure   Canvas(gadget)
   Protected color = RGB( Random(255), Random(255), Random(255) )
   CanvasGadget(gadget, 0, 0, 200, 200)    
   StartDrawing(CanvasOutput(gadget))
   DrawingMode(#PB_2DDrawing_Default)
   Box(0,0,OutputWidth(), OutputHeight(), color)
   DrawText(10,10, Str(gadget))
   StopDrawing()
EndProcedure

OpenWindow(1, 110, 110, 200, 200, "", #PB_Window_BorderLess)
Canvas(1)    

OpenWindow(2, 210, 210, 200, 200, "", #PB_Window_BorderLess)
Canvas(2)    

Repeat 
   event = WaitWindowEvent()
   If event = #PB_Event_Gadget
      If EventType() = #PB_EventType_MouseEnter
         Debug "enter "+EventGadget()
      EndIf
      If EventType() = #PB_EventType_MouseLeave
         Debug "leave "+EventGadget()
      EndIf
   EndIf
Until event = #PB_Event_CloseWindow

Re: Canvas mouse position (enter & leave)

Posted: Fri Sep 27, 2024 6:58 pm
by mestnyi
it works correctly through winapi.

Code: Select all

Procedure CallbackHandler(hWnd, uMsg, wParam, lParam) 
   Static enter.b
   Protected text.s, sysProc = GetProp_(hWnd, "sysProc")
   
   Select uMsg
      Case #WM_MOUSEFIRST
         Protected TRACK.TRACKMOUSEEVENT
         TRACK\cbSize = SizeOf(TRACK)
         TRACK\dwFlags = #TME_HOVER|#TME_LEAVE
         TRACK\hwndTrack = hWnd
         TRACK\dwHoverTime = 1
         TrackMouseEvent_(@TRACK)
         
      Case #WM_MOUSELEAVE
         enter = 0
         text = "leave gadget #" + Str(GetDlgCtrlID_(hWnd))
         
      Case #WM_MOUSEHOVER
         If enter = 0
            enter = 1
            text = "enter gadget #" + Str(GetDlgCtrlID_(hWnd))
         EndIf
         
      Case #WM_LBUTTONDOWN
         text = "Left button down on gadget #" + Str(GetDlgCtrlID_(hWnd))
      Case #WM_LBUTTONUP
         text = "Left button up on gadget #" + Str(GetDlgCtrlID_(hWnd))
      Case #WM_LBUTTONDBLCLK
         text = "Left button click on gadget #" + Str(GetDlgCtrlID_(hWnd))
      Case #WM_RBUTTONDOWN
         text = "Right button down on gadget #" + Str(GetDlgCtrlID_(hWnd))
      Case #WM_RBUTTONUP
         text = "Right button up on gadget #" + Str(GetDlgCtrlID_(hWnd))
      Case #WM_RBUTTONDBLCLK
         text = "Right button click on gadget #" + Str(GetDlgCtrlID_(hWnd))
   EndSelect
   
   If text
      Debug text
   EndIf
         
   ProcedureReturn CallWindowProc_(sysProc, hWnd, uMsg, wParam, lParam)
EndProcedure 

Procedure BindCallBack(hWnd)
   Protected sysProc = SetWindowLongPtr_(hWnd, #GWL_WNDPROC, @CallbackHandler())
   SetProp_(hWnd, "sysProc", sysProc)
EndProcedure

Procedure   Canvas(gadget)
   Protected color = RGB( Random(255), Random(255), Random(255) )
   CanvasGadget(gadget, 0, 0, 200, 200)    
   StartDrawing(CanvasOutput(gadget))
   DrawingMode(#PB_2DDrawing_Default)
   Box(0,0,OutputWidth(), OutputHeight(), color)
   DrawText(10,10, Str(gadget))
   StopDrawing()
   BindCallBack(GadgetID(gadget))
EndProcedure

OpenWindow(1, 110, 110, 200, 200, "", #PB_Window_BorderLess)
Canvas(1)    

OpenWindow(2, 210, 210, 200, 200, "", #PB_Window_BorderLess)
Canvas(2)    

Repeat 
   event = WaitWindowEvent()
   If event = #PB_Event_Gadget
      If EventType() = #PB_EventType_MouseEnter
         Debug "enter "+EventGadget()
      EndIf
      If EventType() = #PB_EventType_MouseLeave
         Debug "leave "+EventGadget()
      EndIf
   EndIf
Until event = #PB_Event_CloseWindow

Re: Canvas mouse position (enter & leave)

Posted: Mon Sep 30, 2024 3:46 am
by renmsa
In your case, it seems that the #PB_EventType_MouseLeave event is delayed for the first window until the second window's #PB_EventType_MouseEnter event is triggered. This may be due to the way Windows handles z-ordering or window focus changes between borderless windows.

Enforcing Window Focus on Hover: You can manually handle the window focus changes by using SetFocus_() or BringWindowToTop_() to force focus when hovering over a window, ensuring that leave events are properly triggered in sequence. If the event sequencesnow rider 3d is critical, consider using a global mouse hook to track the mouse position and manually trigger enter and leave events as needed. This could bypass the default Windows event system, but it's a more advanced and manual approach.

Code: Select all

Procedure Canvas(gadget)
   Protected color = RGB( Random(255), Random(255), Random(255) )
   CanvasGadget(gadget, 0, 0, 200, 200)    
   StartDrawing(CanvasOutput(gadget))
   DrawingMode(#PB_2DDrawing_Default)
   Box(0,0,OutputWidth(), OutputHeight(), color)
   DrawText(10,10, Str(gadget))
   StopDrawing()
EndProcedure

OpenWindow(1, 110, 110, 200, 200, "", #PB_Window_BorderLess)
Canvas(1)    

OpenWindow(2, 210, 210, 200, 200, "", #PB_Window_BorderLess)
Canvas(2)    

Repeat 
   event = WaitWindowEvent()
   If event = #PB_Event_Gadget
      If EventType() = #PB_EventType_MouseEnter
         SetActiveWindow(EventWindow()) ; Enforce focus on mouse hover
         Debug "enter "+Str(EventGadget())
      EndIf
      If EventType() = #PB_EventType_MouseLeave
         Debug "leave "+Str(EventGadget())
      EndIf
   EndIf
Until event = #PB_Event_CloseWindow

Re: Canvas mouse position (enter & leave)

Posted: Mon Sep 30, 2024 4:45 pm
by mestnyi
Have you watched my second example using winapi? So everything works there as expected. So I think this is a bug.
What you suggested is not suitable for me, because on the contrary, I need the second window to never get focus. But I don't know how to do it yet.

Re: Canvas mouse position (enter & leave)

Posted: Thu Oct 03, 2024 12:27 pm
by mestnyi
Who can confirm that this is a bug?