B4J Question B4XPage events: Appear/Disappear - Foregroud/Background

udg

Expert
Licensed User
Longtime User
Hi all,

I was in the process to update a simple game of mine where the elapsed time is showed.
When the user minimizes the game or switches to a different program (browser, file manager,..) I'd like to stop the timer, record the elapsed time so far in order to continue the game on resume exactly where it was "suspended".

As far as B4XPage_IconifiedChanged is involved, everything seems to work as expected.
But Disappear/Appear and Backgrounf/Foreground are not called when switching to other software on my PC. Disappear/Background are correctly raised at program close (after CloseRequest)
Enabling B4XPages.GetManager.LogEvents shows just the Foreground and Appear events called at app start, but nothing when switching away.

Tried both in Debug and Release.

So the first question is: are events Disappear/Backgound meaningless in Windows or intented for another kind of user action but what I tried so far?
Second question: how would you design the app (B4J side) to account for a "suspended" period of time?

TIA
 

teddybear

Well-Known Member
Licensed User
But Disappear/Appear and Backgrounf/Foreground are not called when switching to other software on my PC.
Try MainForm_FocusChanged event, it works when switching to other software on your PC
 
  • Like
Reactions: udg
Upvote 0

udg

Expert
Licensed User
Longtime User
Indeed it works from Main module, but in B4XMainPage module, altough there's a Delegate from Main, it doesn't fire.

I expected it to work like CloseRequest or even IconifiedChanged which are delegated as well and work in MainForm.

Anyway, it's strange that Disappear and Backgroud are called only on program exit.

Edit: not so strange for Background since Erel's note specifies: Note that in B4J it is raised when the last page is closed.
 
Last edited:
Upvote 0

teddybear

Well-Known Member
Licensed User
Indeed it works from Main module, but in B4XMainPage module, altough there's a Delegate from Main, it doesn't fire.

I expected it to work like CloseRequest or even IconifiedChanged which are delegated as well and work in MainForm.

Anyway, it's strange that Disappear and Backgroud are called only on program exit.

Edit: not so strange for Background since Erel's note specifies: Note that in B4J it is raised when the last page is closed.
The delegate of Mainform_FocusChanged is not like CloseRequest and IconifiedChanged, it has no raiseevent method to call b4xpage sub. but you also use callsub method in Mainform_FocusChanged to call b4xpage sub which you specified. such as enable or disable the timer
 
Upvote 0

udg

Expert
Licensed User
Longtime User
I temporarly solved modifying the FocusChanged in Main like below:
B4X:
Sub MainForm_FocusChanged (HasFocus As Boolean)
    B4XPages.Delegate.MainForm_FocusChanged(HasFocus)
    B4XPages.GetManager.RaiseEvent(B4XPages.GetManager.GetTopPage, "DG_FocusChanged", Array(HasFocus))
End Sub
 '.... in MainForm
Private Sub DG_FocusChanged(HasFocus As Boolean)
    Log("DGFocusChanged: " & HasFocus)
End Sub

This way FocusChanged is called when I switch from/to other apps on the PC.
Switching between pages of my game raises it only on the HasFous=True (appear). No event when the MainForm disappear (in order to show a secondary page).

I'm still curious about a couple of points:

- are all the B4XPages events supposed to work on all the platforms? Eventually what are the expected limitations?
- why do I need to add the RaiseEvent to Main sub FocusChanged if it already delegates to the B4XPages framework? And how can I understand whether a delegated sub needs or not the adding of RaiseEvent looking at the code (i.e. CloseRequest or IconifiedChanged don't need it, while FocusChanged do).

Maybe @Erel could add some comments in the B4XPages thread to better explain eventual limitations and expected usage.

udg
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
are all the B4XPages events supposed to work on all the platforms?
They do work on all platforms but the exact behavior is not as you need it in this case. Focus changed <> visibility changed. Desktops are not small mobile devices.

why do I need to add the RaiseEvent to Main sub FocusChanged if it already delegates to the B4XPages framework?
The events are listed here: https://www.b4x.com/android/forum/t...or-managing-multiple-pages.118901/post-744867
You can also see them in the IDE.

B4J uses the FocusChanged event to manage the stack of pages.
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Erel, thank you for your reply.
Desktops are not small mobile devices. This one is difficult to disagree with :)

When we open a secondary page in a B4J/Windows app, both the MainForm and the secondary page coexist on the desktop, so expecting a Disappear event of MainForm like in Android is probably wrong. When we close the secondary page, its own Disapear event is raised (correct, it vanished from the desktop) and when finally close the app/MainForm even its Disappear is raised. Again correct, respective to what we can see on the desktop.

What I think is missing is a simple note in the post you linked above, similar to the one about Backgroud.

As you say, what's different on the paltforms is the bahaviour of the events, not their existence.

B4J uses the FocusChanged event to manage the stack of pages.
OK. I used it for my initial goal and everything works as planned.

What I don't understand is why I need to raise myself the FocusChanged event and not CloseRequest or IconifiedChanged which seems to be identically written in Main.
Obviously there's somenthing going on behind the scenes, but how can I differentiate events which need to be raised by me and events that are raised by the B4Xpages architecture?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
What I don't understand is why I need to raise myself the FocusChanged event and not CloseRequest or IconifiedChanged which seems to be identically written in Main.
Obviously there's somenthing going on behind the scenes, but how can I differentiate events which need to be raised by me and events that are raised by the B4Xpages architecture?
You can see that there is no FocusChanged event, either in the list I linked or in the IDE in the list of events. I will add a clarification about the Appear / Disappear events.
 
Upvote 0

udg

Expert
Licensed User
Longtime User
or in the IDE
Creating a new B4XPages project, in Main there's a region (#Region Delegates) from Template version: B4J-1.0
The first sub in this region is
B4X:
Sub MainForm_FocusChanged (HasFocus As Boolean)
    B4XPages.Delegate.MainForm_FocusChanged(HasFocus)
End Sub
This is the reason I expected the event to be raised automatically as the others mentioned above which are part of the same region.

BTW, MainForm_CloseRequest from Main is delegated as B4XPages.Delegate.MainForm_CloseRequest(EventData), but in MainForm we have to use the signature B4XPage_CloseRequest As ResumableSub. Which makes me think that the B4XPages framework simplifies things for us, but at the same time I can't find any post or documentation which explains it in more detail.

In other words, my concern is that we have five subs in the mentioned template in Main, but there isn't a place which explains the details of each, behaviour, use case,etc.
Mainly for completeness rather than specific needs.

Thank you
 
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Longtime User
Indeed it works from Main module, but in B4XMainPage module, altough there's a Delegate from Main, it doesn't fire.
When updating and testing a menu program I discovered that B4XMainPage behaves differently than the other added B4XPages of which I could rewrite the screen, but that routine did not work on the B4XMainPage of which it seems to just stay active in the background. The solution was simple, B4XMainPage only for the initialization and common variables and program routines in the other B4XPages.
 
Upvote 0
Top