I can confirm, both on an Android phone and an iPhone. When you first load the app while in landscape orientation, it displays the portrait page. This seems to be because the OrientationChanged event doesn't fire at session startup. It only fires when the device is rotated after the page is loaded. Rotating back and forth works as expected from then on (except upside-down portrait doesn't work at all - another issue).

But if you refresh the page while in landscape orientation, then the constant reloading occurs. If you then rotate to portrait then back to landscape, then the reloading stops and it works correctly.

Seems like the upside-down portrait issue seems to be because smartphones don't support/allow that mode. Probably to prevent confusion when actually using it as a phone (speaker and mic in proper position).

I couldn't find anything in Feedback about the constant reloading issue - I'll work on adding a case.

1. If the iPhone is turned upside-down (i.e. Angle=180) then OrientationChanged does not fire. Feedback Case #32169 Greg responded that it is expected behaviour as the iPhone does not report the upside-down orientation.

2. If the user connects to the App with the iPhone in landscape orientation then OrientationChanged does fire but Angle is initially reported as 0, and not 90 or -90. Turning the device to portrait and back again causes the correct angle to be reported. There should be a JavaScript workaround for this but I didn't find one yet.

Hello MichelI think you would need to get the device width and height using JavaScript and send it back to the server. Page width and height would be the size of the page you are sending to the browser so they would not give you the initial device orientation. Hopefully someone with a better knowledge of JavaScript than mine might be able to offer a solution.

@Richard C Hello MichelI think you would need to get the device width and height using JavaScript and send it back to the server. Page width and height would be the size of the page you are sending to the browser so they would not give you the initial device orientation. Hopefully someone with a better knowledge of JavaScript than mine might be able to offer a solution.

I checked on my Mac and reported width and height are actually the size of the browser window. Hence my suggestion. Did not have time to upload a test app, but seems worth a try.

I have been doing some more testing using Paul Lefebvre's MobileWebApp example project.

1. Launching the app with the iPhone in portrait orientation, StartUpPage width=320 and height=460. Launching with the device in landscape orientation gives width=320 and height=548, and the iPhonePortaitPage is displayed on its side.

2. When OrientationChanged fires, it calls a method Session.ShowPage which calls the Show method of iPhoneLandscapePage which in turn causes OrientationChanged to fire again, hence the continuous reloading. This is the problem reported by Wittawat in his original post. It should be easy enough to set a flag to stop the looping.

@Richard C 2. When OrientationChanged fires, it calls a method Session.ShowPage which calls the Show method of iPhoneLandscapePage which in turn causes OrientationChanged to fire again, hence the continuous reloading. This is the problem reported by Wittawat in his original post. It should be easy enough to set a flag to stop the looping.

No, showing a page does not fire the OrientationChanged event - it is (supposed to be) fired by the session in reaction to the physical device orientation changing.

@Richard C 2. If the user connects to the App with the iPhone in landscape orientation then OrientationChanged does fire but Angle is initially reported as 0, and not 90 or -90.

No, then angle is correctly reported at startup. Other factors just made it seem like it wasn't. See the new example project (below).

The problem appears to be that for a new session, OrientationChanged fires before Session.Open and therefore before the session is ready (or something along those lines), and trying to show a page at this point (session first started) causes a new session to be started. And that cycle will continually repeat. Or it may be something else - only the Xojo engineers can tell us for sure. But I do know that trying to show a page from OrientationChanged during it's first execution in a new session is where the problem lies.

The reason it was only happening when in landscape mode is the first line in the OrientationChanged event was skipping the rest of the instructions if the angle didn't appear to have changed. But for a new session, the last saved angle is always going to be zero, so the rest of the instructions do not execute when starting off in portrait. You can make the same bug occur in portrait by removing that first line so that the entire OrientationChanged event runs every time.

The solution (or workaround) is along the lines of what Richard suggested - a flag. I used a flag to prevent the showing of any page from the OrientationChanged event until the session Open event had fired. I also fixed the problem of displaying the correct page no matter which orientation you started in. See the feedback case (Feedback Case #32374) for an updated version of the project that now works (along with logging code that shows the order of the events).

Paul had included this code in his original example project, but each time OrientationChanged fired, a new session had been launched and so the previous LastAngle property was no longer available. Jay's workaround fixes this.

I also found that instantiating all the WebPages explicitly avoided this issue of multiple sessions launching repeatedly.

But I am still seeing the initial value of Angle reported as 0 and the page on its side when the app is launched from a landscape orientation. This is with 2013r4.1.

1. Launching the app with the iPhone in portrait orientation, StartUpPage width=320 and height=460. Launching with the device in landscape orientation gives width=320 and height=548, and the iPhonePortaitPage is displayed on its side.

If a web page is being displayed on its side, then even the browser hasn't recognized the orientation change. There's not much we can do about that.

FWIW, I've been experimenting with this and have not been able to reproduce this on a tablet (iPad or Android). I'm beginning to wonder if, since you a phone is typically in portrait mode when the browser is launched, if this is the expected behavior, and not a bug after all.

Unbelievable. An obvious bug that anyone trying to write a mobile-friendly web app is going to encounter. Closed as "not a bug", and the attachment with workarounds posted to Feedback by @Jay M has been removed. How is endlessly refreshing while in landscape mode not a bug?

OK. Long time no see. I tried to implement simple code in Session.OrientationChange to show different pages depending on the value of Angle. I implemented Greg's idea of having a PreviousAngle property so I do

If PreviousAngle <> Angle then

It does not work. A new session seems to be created each time a landscape webpage is displayed.

OK. Here is the workaround I used . I post it here to help the poor souls who stumble on the same issue in the future.

I had already added the PreviousAngle as Integer to the session, which is set in the OrientationChanged Event.

I added a multiple 1000 ms WebTimer to each page (WebPageAndroidPortrait and WebPageAndroidLandscape) with this in the Action event (on WebPageAndroidPortrait) :

Sub Action() Handles Action
Dim ref As WeakRef
ref = New WeakRef(session)
If ref.Value <> Nil Then
if Session(ref.Value).PreviousAngle = 90 or Session(ref.Value).PreviousAngle = 90 then
WebPageAndroidLandscape.show
self.close
End If
end if
End Sub

Of course, the code needs to be modified to PreviousAngle 0 and 180, as well as show WebPageAndroidPortrait for the WebTimer on WebPageAndroidLandscape

I don't know if this could be implemented, but it would make more sense to have OrientationChanged on webPages, instead of session. Or if "by design", the OrientationChanged event fired only once, and did not create undue new sessions.