There is ReleaseMouse().
You could trigger it via a key combination like in DOSBox to capture/release the mouse.
Or you auto-release the mouse if touching the screen edges, then recapture depending on WindowMouseX/Y().
I have some snippets here that regularly break, but the following seems to work with PB 5.62b2 x64, Windows 7
Code: Select all
InitSprite()
InitMouse()
InitKeyboard()
ww=800
wh=600
style | #PB_Window_ScreenCentered
style | #PB_Window_SystemMenu
style | #PB_Window_MinimizeGadget
If 01
win=OpenWindow(#PB_Any, 50,100, ww,wh, "", style) :: AddKeyboardShortcut(win, #PB_Shortcut_Escape, 10)
OpenWindowedScreen(WindowID(win), 0,0, ww,wh, 0,0,0)
Else
OpenScreen(ww,wh,32,"", #PB_Screen_NoSynchronization)
SetFrameRate(9999)
EndIf
mouseCaptured = 1
Repeat
ExamineKeyboard()
ExamineMouse()
mx = MouseX()
my = MouseY()
mw = -MouseWheel()
; acceleration
; mousespeed.f = 1.8
; mx + MouseDeltaX()*mousespeed :: If mx<0 : mx=0 :: ElseIf mx>ww-1 : mx=ww-1 :: EndIf
; my + MouseDeltaY()*mousespeed :: If my<0 : my=0 :: ElseIf my>wh-1 : my=wh-1 :: EndIf
; MouseLocate(mx,my)
If IsWindow(win) ;{
If mouseCaptured
If mx=0 Or mx=(ww-1) Or my=0 Or my=(wh-1)
; Debug "----------------- releasing"
; Debug "s x: " + mx
; Debug "s y: " + my
; Debug "w x: " + WindowMouseX(win)
; Debug "w y: " + WindowMouseY(win)
mouseCaptured=0
ReleaseMouse(1)
EndIf
ElseIf Not mouseCaptured
If WindowMouseX(win)>0 And WindowMouseX(win)<(ww-1) And WindowMouseY(win)>0 And WindowMouseY(win)<(wh-1)
; Debug "----------------- capturing"
; Debug "s x: " + mx
; Debug "s y: " + my
; Debug "w x: " + WindowMouseX(win)
; Debug "w y: " + WindowMouseY(win)
mx=WindowMouseX(win)
my=WindowMouseY(win)
mouseCaptured=1
ReleaseMouse(0)
MouseLocate(mx,my)
EndIf
EndIf
EndIf
If IsWindow(win) ;{
Repeat
event = WindowEvent()
em = EventMenu()
Select event
Case #PB_Event_CloseWindow
quit = #True
Case #PB_Event_Menu
Select em
Case 10
quit = #True
EndSelect
EndSelect
Until Not event
;}
EndIf
StartDrawing(ScreenOutput())
DrawingMode(#PB_2DDrawing_Transparent)
Circle(mx ,my, 1)
StopDrawing()
FlipBuffers()
ClearScreen($333333)
If IsWindow(win)
Delay(10)
EndIf
Until quit Or KeyboardPushed(#PB_Key_Escape)
Might need some tweaking if used with a strechted/scaled screen.
In Linux (PB 5.62 x64, Ubuntu 16.04) the mouse is released to the center of the window, so to avoid immediate recapture you need a 3-stage check, enabling recapture only after the released mouse has leaved and reentered the window:
Code: Select all
InitSprite()
InitMouse()
InitKeyboard()
ww=800
wh=600
win=OpenWindow(#PB_Any, 50,100, ww,wh, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(win), 0,0, ww,wh, 1,0,0)
captured = 1
Repeat
ExamineKeyboard()
ExamineMouse()
; Debug "------"
; Debug MouseX()
; Debug MouseY()
; Debug WindowMouseX(win)
; Debug WindowMouseY(win)
If captured = 1
If MouseX() = 0 Or MouseY() = 0 Or MouseX() = ww-1 Or MouseY() = wh-1
Debug "-> -1"
captured = -1
ReleaseMouse(1)
ExamineMouse()
EndIf
EndIf
If captured = -1
If WindowMouseX(win) < 0 Or WindowMouseY(win) < 0
Debug "-> 0"
captured = 0
EndIf
EndIf
If captured = 0
If WindowMouseX(win) >= 1 And WindowMouseY(win) >= 1
Debug "-> 1"
captured = 1
ReleaseMouse(0)
MouseLocate(WindowMouseX(win), WindowMouseY(win))
Debug MouseX()
Debug MouseY()
ExamineMouse()
Debug MouseX()
Debug MouseY()
EndIf
EndIf
; If KeyboardPushed(#PB_Key_C) And captured = 0
; ReleaseMouse(0)
; captured = 1
; EndIf
; If Not KeyboardPushed(#PB_Key_C) And captured = 1
; ReleaseMouse(1)
; captured = 0
; EndIf
Repeat
event = WindowEvent()
Select event
Case #PB_Event_CloseWindow
quit = #True
EndSelect
Until Not event
If captured
StartDrawing(ScreenOutput())
Box(MouseX(), MouseY(), 3, 3)
StopDrawing()
EndIf
FlipBuffers()
ClearScreen($333333)
Until quit Or KeyboardPushed(#PB_Key_Escape)
Its weird but at least you can leave the window. Maybe some GTK API might be able to correct the window mouse position to the edge of the screen after release.