bmx-ng / sdl.mod

SDL backend for BlitzMax
7 stars 6 forks source link

Next MouseHit ignored after graphics change #27

Open GWRon opened 4 years ago

GWRon commented 4 years ago

Source: https://www.syntaxbomb.com/index.php/topic,8057.new.html#new

Ashmoor wrote:

If MouseHit() is used before changing graphics, the following MouseHit() is ignored. It is as if the window loses focus and a click must be made to regain mouse input. If a key triggers graphics change, mouse works fine.

BRL graphics works fine so it's not a general MacOS issue, just a SDL issue. It happens on Windows as well but not as often as on Mac. On Mac every other click is registered, on windows about 7 out of 10 are registered.

Check code below. Am I doing something wrong or is it a problem with the module?

SuperStrict

Framework SDL.gl2sdlmax2d
Import brl.jpgloader
Import BRL.PNGLoader
Import brl.Random
Import Brl.RandomDefault

Global fullscreen%=0
Global width:Int=1110
Global height:Int=619

Graphics width,height,fullscreen
Global mouse_hit_nbr:Int
Repeat

        Cls
        SetColor (150,50,20)
        DrawRect (0,0,width,height)
        SetColor(255,255,255)
        DrawMouseCoords()
        Flip

        If KeyHit (KEY_ESCAPE) Or AppTerminate() Then End
        If KeyHit (KEY_3) Then
                fullscreen=Not(fullscreen)
                EndGraphics()
                ReInitGraphics()
        EndIf

        If MouseHit(1) Then
                fullscreen=Not(fullscreen)
                EndGraphics()
                Local w:Int= 500+Rnd(500)
                Local h:Int= 300+Rnd(300)
                Graphics (h,w)
                mouse_hit_nbr:+1
                Print "mouse hits : "+mouse_hit_nbr
        EndIf  

Forever

Function ReInitGraphics()
        If fullscreen=1 Then
                Graphics 1920,1080,32
        Else
                Graphics width,height,0
        EndIf

EndFunction

Function DrawMouseCoords()
        Local x%, y%, vx%, vy%
        Local yOffset:Int=200

        x=MouseX()
        y=MouseY()
        vx=VirtualMouseX()
        vy=VirtualMouseY()

        SetScale(2.0,2.0)
        DrawText("rm:"+x+","+y,10,10+yOffset)
        DrawText("vm:"+vx+","+vy,10,40+yOffset)
        SetScale(1,1)

EndFunction
GWRon commented 4 years ago

I can confirm that it is flawed on Linux too. Hit the Mouse and it switches graphics. Next mouse hit is not registered (else it would switch graphics again).

GWRon commented 4 years ago

In brl.polledinput there is Function Hook:Object( id,data:Object,context:Object ) - it is NOT called for the first (and ignored) mouse hit after a switch.

bmx_SDL_EmitSDLEvent in sdlsystem.mod/glue.c is also not reached by the mouse hit (added an fprintf(stdout, "mouse event\n"); to case SDL_MOUSEBUTTONUP

woollybah commented 4 years ago

Seems to work here, on Windows 10.

GWRon commented 4 years ago

It works here "randomly" too ... most of the time when clicking "very right" of the window ... and once it "works", it works in 75%+ of the cases.

when not moving the mouse much and staying in the center, doing "calm" mouse clicks (while checking the output pane for text output ) ... and it fails everytime.

tried it on Linux.

Edit: using "brl.glmax2d" instead and it works 100% of the time.

woollybah commented 4 years ago

One could try adding context.window.Raise() after the window creation line (224) in sdlgraphics.bmx.

GWRon commented 4 years ago

You mean that way:

        context.window = TSDLWindow.Create(AppTitle, x, y, width, height, windowFlags)
        context.window.Raise()
        If glFlags Then
            context.context = context.window.GLCreateContext()
            SDL_GL_SetSwapInterval(-1)
            context.sync = -1
        End If

If so then no, does not work ;-/

BTW I already tried with "alt + tab" to bring back and forward, minimize + restore ... did not repair the issue.

Edit: Were you able to verify it on your linux box?

GWRon commented 4 years ago

Ok ... another uhm ... maybe it helps narrowing it down:

I replaced the if Mousehit(1) Then to also check for button 2 ...

        If MouseHit(1) Or MouseHit(2) Then
                fullscreen=Not(fullscreen)
                EndGraphics()
                Local w:Int= 500+Rnd(500)
                Local h:Int= 300+Rnd(300)
                Graphics (h,w)
                mouse_hit_nbr:+1
                Print "mouse hits : "+mouse_hit_nbr
        EndIf 
  1. I click left mouse button ... reacts and switches.
  2. I click right mouse button ... reacts and switches (and shows context menu ... of the underlying MaxIDE output pane!) 3.a I click left - nothing happens, I click again - and it works (for one time) 3.b I click right - nothing happens, I click again - and it works (for one time)

So when opening the app and doing LMB and followed by RMB you see two switches - as you would expect. The RMB seems to not be properly "eaten" as the underlying Window receives an RMB event. Following to LMB + RMB you need to click each button once to make this button to work for one time again.

GWRon commented 4 years ago

Single right click: Peek 2020-08-26 15-38

multiple right clicks (with every second being "not registered"): Peek 2020-08-26 15-39

As you see in the second - it does not always lead to Maxide (underlaying window) display the context menu of its textarea.

woollybah commented 4 years ago

The issue is that the "mouse up" event can get lost during the moment that no window exists - since the "mouse down" event is driving the cycle of closing one then opening another window. i.e. The mouse button is released while there is no window. If you delay the cycle or hold the mouse down for longer, the problem goes away.

GWRon commented 4 years ago

But shouldn't and "app minimize/resume" (or "alt tab") refresh all this mouse stuff anyways? Yet it did not change behaviour and is still "borked".

If you delay the cycle or hold the mouse down for longer, the problem goes away.

What "cycle" ? Think I do not understand you properly Adding a delay somewhere ?

GWRon commented 4 years ago
Global switch:Int = -1
Repeat

        Cls
        SetColor (150,50,20)
        DrawRect (0,0,width,height)
        SetColor(255,255,255)
        DrawMouseCoords()
        Flip

        If KeyHit (KEY_ESCAPE) Or AppTerminate() Then End
        If KeyHit (KEY_3) Then
                fullscreen=Not(fullscreen)
                EndGraphics()
                ReInitGraphics()
        EndIf

        If MouseHit(1) Then
            switch = 100
            mouse_hit_nbr:+1
            Print "mouse hits : "+mouse_hit_nbr
        EndIf

        If switch > -1
            switch :- 1
        EndIf

        If switch = 0
            switch = -1
            fullscreen=Not(fullscreen)
            EndGraphics()
            Local w:Int= 500+Rnd(500)
            Local h:Int= 300+Rnd(300)
            Graphics (h,w)
        EndIf
Forever

(excuse this ugly "delayed graphics switch"-approach). As Brucey stated, this would make it "work".

Not sure if we still should fix it (like "resetting" events or so ?).