HTML5 problem

Jimmy

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,021
I seem to have a problem with GetChar().
It only appears sporadically in HTML5 when using AUTO_SUSPEND_ENABLED = False

You can see it by compiling to HTML5 and then active and inactive the browser windows, coming back to it should sometimes work,
and sometimes it would fail to see keyinput until you refresh the webpage.

So far I've tried Linux Firefox and Chrome. It seem to affect both browsers the same but when one works the other can stop working again, until I refresh, but there's no distinct pattern that I've seen so far. So first conclusion was it was Linux keyboard input but it never happens in the browsers otherwise. Neither when AUTOSPEND is not used. Nor in Desktop mode.

What can it be?

EDIT I could replicate the problem in macOS Safari and Chrome.

Here's a simple demo

Code:
#MOJO_AUTO_SUSPEND_ENABLED = False
' On HTML5 (at least both Firefox & Chrome on Linux), GetChar() sometimes stops
' after revisiting webpage when using suspend_enabled (and only then)
 
Import mojo2

Function Main()
    New Game
    Return 0
End

Class Game Extends App

    Field canvas:Canvas
    Field str:String = "", screen:String[100]
    Field x:Int = 0, y:Int = 1*12
    Field mode:Int = 1 ' 2 = Overwritemode
    Field letters:=New List<letter>
    Field changeline:Int = 0
      
    Method OnCreate()
        canvas = New Canvas()
          screen[0] = "Ready."
        
       Return 0
    End

    Method OnUpdate()
      
        ' Update jumping letters
        Local g:Float = 9.1*4
         changeline = 0 ; If MouseHit(0) Then x = Int(MouseX()/8)*8 ; y = Int(MouseY()/12)*12 ; changeline = 1 
            Local out:=New List<letter>
        For Local letter:=Eachin letters
            letter.a = Max(letter.a-.01,0.0)
            If letter.a <= 0 Then Continue
            letter.yv += 0.1 ; letter.x += letter.xv ; letter.y += letter.yv
            If letter.y > 280-12 Then letter.yv = -letter.yv * 0.6 ; letter.y = 280-12
            out.AddLast letter
        Next
        letters=out
      
        Local chr:Int = GetChar()
      
        If chr > 31 And chr < 128 ' WRITING
            Local saved:String = Mid(str,x/8+mode,80)
            While Len(str) < (x/8)
                str = str + " "
            Wend
            str = Left(str,x/8) ; x = x + 8
            str = str + Chr(chr) + saved
      
        Endif
      
        If chr = 8 And x > 0 ' BACKSPACE
            Local saved:String = Mid(str,x/8+1,80)
            While Len(str) < (x/8)
                str = str + " "
            Wend
            str = Left(str,x/8) ; x = x - 8
            Local temp:String = Left(str,Len(str)-0)
            chr =  Val(Right(temp,1))
            str = Left(str,Len(str)-1) + saved
            letters.AddLast New letter(x,y,chr)
        Endif
      
        Local oldy:Int = y
        If chr = 65573 Then x = x - 8 ; x = Max(x,0)        ' Left-key
        If chr = 65575 Then x = x + 8 ; x = Min(x,640-8)    ' Right-key
        If chr = 65574 Then y = y - 12 ; y = Max(y,0)        ' Up-key
        If chr = 65576 Then y = y + 12 ; y = Min(y,480-12)    ' Down-key
        If chr = 13 Then y = y + 12 ; y = Min(y,480-12)        ' Enter-key
        If changeline = 1 Then str = screen[Floor(y/12)]
        If oldy <> y Then str = screen[Floor(y/12)]
        screen[Floor(y/12)] = str
    End
 
    Method OnRender()
        canvas.Clear
        canvas.SetBlendMode BlendMode.Alpha

        ' Draw text
        canvas.SetColor 0.4,0.4,0.4,1
        For Local i:Int = 0 To 99
            canvas.DrawText screen[i],0,i * 12
        Next

        ' Draw cursor
        canvas.SetColor 1,1,1,(Millisecs()/1000.0)
        canvas.DrawLine x,y,x,y+12
        ' canvas.DrawText str,0,y

        canvas.SetBlendMode BlendMode.Additive
        For Local letter:=Eachin letters
            If letter.char <> 0
                canvas.SetAlpha 1.0
                canvas.DrawText Chr(letter.char),letter.x,letter.y
            Endif
        Next
      
        canvas.Flush
    End
 
End

Function Len:Int(s:String)
    Return s.Length
End

Function Mid:String(s:String,p:Int,n:Int)
    p=p-1 ; Return s[(p)..(p+n)]
End

Function Left:String(s:String,n:Int)
    Return s[0..n]
End

Function Right:String(s:String,n:Int)
    Return s[(s.Length()-n)..(s.Length())]
End

Function Chr:String(n:Int)
    Local result:String ; result = result.FromChar(n) ; Return result
End
 
Function Val:Int(s:String)
    Local chrs:Int[] = s.ToChars() ; Return chrs[0]
End

Function Alphabet:Int(s:String,n:Int=0)
    Local chrs:Int[] = s.ToChars() ; Return chrs[n] & 31
End

Class rectangle

    Field x:Int
    Field y:Int
    Field w:Int
    Field h:Int
  
End

Class letter

    Field x#,y#,xv#,yv#,a#,char:Int
  
    Method New(x#,y#,char:Int)
        Local an# = Rnd(360),v# = 0.8
        Self.x = x
        Self.y = y
        Self.xv = Cos(an) * v
        Self.yv = Sin(an) * v
        Self.a = 1
        Self.char = char
    End
  
End
 
Last edited:

MikeHart

Administrator
Joined
Jun 19, 2017
Messages
3,210
You can see it by compiling to HTML5 and then active and inactive the browser windows, coming back to it should sometimes work,
Please describe your exact workflow. Means, did you just active the window or did you click on the canvas as well? Was the canvas click on before you put it in the background? What app did you activate when you deactivated the window (cause I can imagine that it would have some effect) or did you just minimize it? Are other tabs/websites n the browser open as well? etc etc.

Also I see you didn't use Strict Mode, so the error could be in your code as well.

Please also post the details about your OS including patch level, the versions of the browsers and so on. I am not sure if we can do anything about it but at least if someone tries to find the error in CX, they know exactly what you did, what your system looked like and see if they can replicate the error.
 

Jimmy

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,021
Try the democode I provided it should be repeatable within 2m n clicking around on off any browser any OS. Nothing special with this demo btw. Normal use of the command any example anywhere should give the same result. I have tried to locate the bug around EventEat (the Mouse and everything else works though). This is all I can say right now. I change the OS all the time and it is everywhere .
 

Jimmy

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,021
I just realized that KeyDown does the same. Keyboard events might have a general problem in HTML5. Regardless of browser and underlying system.
 

Jimmy

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,021
I tried to replicate the problem, this time it didn't wanna show itself. So it's not a easy one.
It's impossible to replicate and describe yet.

It happens only in HTML5 and only when the flag tells the browser to run the game in the background. Never otherwise. I can only tell that it does so regardless of what OS and browser you use. Sometimes it rare to happen and sometimes it goes on a streak and it happens almost 50/50.

What happens is that the keyboard stops working when you unfocus the windows and comes back.. This time I couldn't get it to do it. for instance for a whole 5 minutes. The only valuable input I can give right is that it seem to also affect KeyDown and that the Mouse still works perfectly as the demo shohws.

I looked into the html template and see that all keys 0-255 are emptied. So I thought the quque might gotten full. But it's probably not that easy.

I don't see a way in Cerberus to differentiate between no-key and empty-queue so I was thinking to try emptying the event-queue on the OnResume Method or something like that to try to go around it but I don't that much about Cerberus so I stay put for awhile.
 

magic

Active member
3rd Party Module Dev
3rd Party Tool Dev
Joined
Mar 5, 2018
Messages
167
I run the code on Window10 but nothing wierd happen. After several suspend/resume I can key in char as expected.
 
Top Bottom