Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS mobile: keyboard up/down and scrolling behaviour not working #914

Open
giancarloerra opened this issue Feb 5, 2024 · 23 comments
Open

Comments

@giancarloerra
Copy link

Issue summary

Exploring all the possible examples, even the last one https://terminal.jcubic.pl/android.php, the behaviour on iOS mobile is not working: virtual keyboard going on and off doesn't get the last line (the prompt) scrolling up and down so that's never covered when keyboard is up.

Expected behavior

The bottom of the terminal, where terminal is, should always be automatically attached to the bottom of the visible view, without or without keyboard.

Actual behavior

Keyboard going up (once the screen is full of lines and after has been up and down once), covers the terminal. The terminal should always automatically scroll to the bottom, be attached to the keyboard popping up/down, and keep like that while typing a command (or prompt in focus) or when executing a command.

Steps to reproduce

Simply loading the latest demo https://terminal.jcubic.pl/android.php on iOS, making the screen full of commands so it scrolls down, keyboard up and down and then up again, it covers the bottom of the terminal/view.

Browser and OS

Latest iOS, Safari or Firefox (both using WebKit anyway).

Additional notes

@giancarloerra
Copy link
Author

giancarloerra commented Feb 5, 2024

For now my nearest solution is:

const scrollToCmd = () => {
	let element = document.querySelector(".cmd");
	element.scrollIntoView();
}

and this listener

$(document).ready(function () {
	visualViewport.addEventListener("resize", () => {
		scrollToCmd();
	});
});

And in theory it seems to work. Problem is that when typing a command it scrolls up automatically as there seems to be something else bringing up the scroll to a point where is not aware of the virtual keyboard.

I tried this to mitigate:

		onCommandChange : function () {
			scrollToCmd();
		},

And it shows clearly that is fighting something else that brings the scroll up to to where it would be without the virtual keyboard: typing letters slowly, the focus/scroll goes briefly up and is then dragged down again to the correct position by the scrollToCmd().

If we could get rid of whatever is fighting this scrollToCmd(), this solution I believe could work.

@giancarloerra
Copy link
Author

There's an additional bug happening once you have a long terminal and keyboard up/down a few times and scrolling etc.

A part of the body background colour is showing "behind" (or at the bottom) of the terminal.

Images of keyboard covering the content:
IMG_4502
IMG_4503

And the black terminal showing the body behind (white):
Screenshot 2024-02-05 at 18 04 53

@jcubic
Copy link
Owner

jcubic commented Feb 5, 2024

Yes, this is a known issue see #707.

The problem is that on iOS the keyboard doesn't affect the layout size inside CSS. In the recent version of Chrome, they duplicated the "broken" behavior of Safari. So now for every mobile browser you need to use JavaScript to detect the virtual keyboard and it's not easy. See #859.

There is also a long-standing bug in mobile Safari with white space below the HTML, and I don't see a way to fix this. I think that the new Chrome added that bug to their implementation.

See this question on StackOverflow: White space outside HTML on mobile Safari when the keyboard is open

So the problem are bugs in the browsers that now become the standard.

I will try to attempt to fix this issue again. I need to find the code I was using to hack the new Chrome behavior, maybe it will work for iOS.

On Chrome you only need to add a special viewport meta tag. But on Safari I'm afraid this is default behavior and I don't think they will ever fix this.

If you know how to fix broken mobile browsers I'm all ears.

@jcubic jcubic added the mobile label Feb 5, 2024
@jcubic
Copy link
Owner

jcubic commented Feb 5, 2024

I will check how your Scrolling into view behaves.

@giancarloerra
Copy link
Author

Thank you. I confirm that the white space (in my case the background colour of body in place of background image) happens only in Safari, not Chrome (or it's hidden more quickly).

Thanks for checking those code snippets...they solve the problem of the keyboard up/down and bottom of the terminal (cmd) following it, so the keyboard does not cover anymore. It works on Chrome and Safari.

But the up/down remains, so there's something somewhere else that tries to scroll: if you can find where that is and try to disable it and see it that fixes it, maybe that could be a solution if it doesn't break anything else.

Thanks, much appreciated.

@jcubic
Copy link
Owner

jcubic commented Feb 5, 2024

The problem with scrolling up the content is that the page height is the full height of the phone and if you open the keyboard, the thing that makes the keyboard open is at the bottom of the page. Even if the height is 100% the page is bigger than the size of the available area. This is a broken behavior of Safari that is now duplicated by Chrome, which is really bad.

I've reported this two times to the Chrome team they said this is how it should work. Because they do the same what Safari is doing. This is really stupid but I nothing I can do.

I can only do hacks in JavaScript to fix broken behavior.

The reason why they think it's okay is because no one needs a full-height mobile app like the one I need for jQuery Terminal. They only care about normal websites where this works fine.

@giancarloerra
Copy link
Author

It sounds like it's not going to be fixed (by them) anytime soon, not surprised, but if Chrome is following then maybe JS hacks is the way?

The one I did is a hack but it 'works' solving half of the problem, I wonder if you have a way to make it work also when typing letters in the terminal, because that's the only problem left.

With my hacks when you get focus on the terminal and the keyboard slides up, the terminal is nicely pushed up, and down, it all works nicely...but when typing, the up/down happens.

Just wondering if worth going down the hack route if it works most of the times.

@jcubic
Copy link
Owner

jcubic commented Feb 6, 2024

It seems that my old demo works for Chrome on iOS (that it's Safari with different branding), but not for Real Safari. iOS is a real mess. And there no dev tools of any kind on BrowserStack to debug Safari on iOS.

@jcubic
Copy link
Owner

jcubic commented Feb 6, 2024

Ok, I was able to run the Dev Tools on the browser Stack. And I think I have a working PoC of the code:

https://terminal.jcubic.pl/android.php

Can anyone check (on a physical iPhone) if it works? The code is not yet in the repository.

@bsidhom
Copy link

bsidhom commented Feb 23, 2024

I can confirm that this works as expected on a physical iPhone.

@bsidhom
Copy link

bsidhom commented Feb 23, 2024

Do you have link to the code so we can experiment with it? Did this require internal changes to the terminal itself or did you just use the public API/CSS? I can read the source on the page, but it's not clear what the significant changes are to get this working.

@jcubic
Copy link
Owner

jcubic commented Feb 24, 2024

The code is on top of the library inside the HTML file. I don't remember if I changed something in the source files but I don't see any uncommitted code and there is nothing in the git stash. So everything has to be inside the HTML.

This is everything:

body.full-screen-terminal {
    height: 100%;
    height: 100dvh;
    height: calc(var(--terminal-force-height) * 1px);
}
 function on_height_change(callback) {
     let { height } = window.visualViewport;
     callback(height);
     window.visualViewport.addEventListener('resize', function(event) {
         const { height: newHeight } = window.visualViewport;
         if (height !== newHeight) {
             height = newHeight;
             callback(height);
         }
     });
 }
 if ('visualViewport' in window) {
     on_height_change(function(height) {
         document.documentElement.style.setProperty('--terminal-force-height', height);
     });
 }

I don't see any other code besides this resize/force height. I need to incorporate this code into the library. And do more tests.

@bsidhom
Copy link

bsidhom commented Feb 24, 2024

I may have spoken too soon. It works at first, but seems to get into a weird state if I click away the keyboard and then refocus it. And randomly on some page loads, I can’t focus the text area at all to bring up the virtual keyboard.

The blur-refocus issue also isn’t deterministic, so I’m not sure what’s causing it. It actually seems to work most of the time for me.

@jcubic
Copy link
Owner

jcubic commented Feb 24, 2024

That's what I was afraid of, that it doesn't work all the time. Will keep iterating over this idea and try to fix the issue. It may take time and may never get fixed. iOS is difficult to work with.

@oxygen79
Copy link

A fix to this bug would be very welcome here too :)

@jcubic
Copy link
Owner

jcubic commented Mar 13, 2024

So for me the code works fine (in BrowserStack), the only problem is when you blur and focus again the cursor line is not visible.

I'm going to push this code, after adding the fix to the focus. And close this issue. Any bugs in iOS would have to be added separately with clear reproduction.

@jcubic
Copy link
Owner

jcubic commented Mar 13, 2024

I was too fast, my solution doesn't work 100% correctly.

jcubic added a commit that referenced this issue Mar 13, 2024
@jcubic
Copy link
Owner

jcubic commented Mar 13, 2024

Can anybody check on a real iOS?

Same link https://terminal.jcubic.pl/android.php

I've made few changes, I hope it will work now.

@jcubic
Copy link
Owner

jcubic commented Mar 13, 2024

The fix solve the problem with jumping, but you can't scroll anymore.

jcubic added a commit that referenced this issue Mar 13, 2024
@jcubic
Copy link
Owner

jcubic commented Mar 13, 2024

Ok, I think I got this. You should be able to test now:

Same link https://terminal.jcubic.pl/android.php

@Shev3k
Copy link

Shev3k commented Mar 19, 2024

I tested on an iPhone 13, the initial first command works perfectly and then I cannot enter any more because the keyboard will glitch out whenever I try to target the command line.
It has also caused the Desktop browser version to have the bottom white part for me, and so far I haven't figured out how to target it to keep it in line with the terminal background again (in my case, the usual black).

Edit: Got it to work by <body class="full-screen-terminal" style="height: 100%;">.
This also alleviated the keyboard issue for more than the first command on mobile.

@jcubic
Copy link
Owner

jcubic commented Mar 19, 2024

@Shev3k thanks for testing, I need to revisit this. I also merged the changed, and they got released with 2.29.1 by accident. I should create a separated branch with the changes to mobile.

@jcubic
Copy link
Owner

jcubic commented Mar 20, 2024

Just fixed the height issue, I didn't realize that missing CSS variable don't cancel the CSS property. Now it should work again on Desktop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants