native.newTextField text-selection on android doesn't work at certain application-height

I’m having an issue where if the height of the application is set (in the config.lua) to above 85% (90% when statusbar is turned off) of the device’s aspect-height, the text selection for native.textField will break.

The selection drop-down bar options (cut,copy,etc) will pop-in for a moment and then dissapear. Along with that, the width of the frame also decreases while this is happening.

I believe it’s breaking because it doesn’t have enough space, and doesn’t know how to pan or move the application or overlay on the application? Those are just my theories.

Here is the stripped code I’m testing with.

main.lua

--the height of the statusbar also affects how high the application can be display.setStatusBar(display.DefaultStatusBar); --just so I can see how big the application size is local bg = display.newRect(display.contentCenterX,display.contentCenterY,display.contentWidth,display.contentHeight); bg.fill = {0.3} local textField = native.newTextField(display.contentCenterX, display.contentHeight\*0.3, display.contentWidth\*0.9, display.contentHeight\*0.1); textField.placeholder = "a textfield";

config.lua

--Rob's (I think) fit-all config code, causes text selection to break --local aspectRatio = (display.pixelHeight - display.statusBarHeight) / display.pixelWidth --application = { -- content = { -- width = aspectRatio \> 1.5 and 800 or math.floor( 1200 / aspectRatio ), -- height = aspectRatio \< 1.5 and 1200 or math.floor( 800 \* aspectRatio ), -- scale = "letterBox", -- fps = 60, -- imageSuffix = { -- ["@2x"] = 1.3, -- }, -- }, --} --this works on my Samsung Galaxy S3 (res:720x1280) application = { content = { width = 720, height = 1130, --any height roughly above that causes text-selection to break scale = "letterbox" }, } 

build.settings

settings = { &nbsp;&nbsp; &nbsp;orientation = &nbsp;&nbsp; &nbsp;{ &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;default = "portrait", &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;supported = { "portrait", "portraitUpsideDown",} &nbsp;&nbsp; &nbsp;}, &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;iphone = &nbsp;&nbsp; &nbsp;{ &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;plist = &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;{ &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;UIStatusBarHidden = false, &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;CoronaWindowMovesWhenKeyboardAppears = true, &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;} &nbsp;&nbsp; &nbsp;}, &nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp;android = &nbsp;&nbsp; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; coronaWindowMovesWhenKeyboardAppears = true, &nbsp;&nbsp; &nbsp;}, }

Notes for a report:

  • It matters if display.statusBar is set on or off, as it affects the native screen height available.

  • It does not matter if I have coronaWindowMovesWhenKeyboardAppears = true or false (panning still works just fine when it’s enabled, no worries there). But, the selection bar will show under the statusBar if false.

  • It does not matter what the total resolution is.

  • The aspect ratio (specifically the height of the application) affects whether text selection works or not.

I have tried the following four setups on my SGS3.

Works (causes blackboxes at top and bottom):

  • 320x480

  • 720x1130 (or 1180 with statusbar off)

Does not work (no black boxes):

-720x1280 (SGS3 resolution)

  • 320x568 (1.778 aspect ratio)

If I build the Corona/SampleCode/Interface/NativeKeyboard to my SGS3, text selection works perfectly. If I modify it’s config.lua to use the device’s screen aspect ratio (such as Rob’s code) it breaks.

I am building on OSX with daily-build CoronaSDK-2015.2795

As far as I know, this is not an issue on iOS devices as they render the selection pop-up right above the text (I’m guessing this is constant across all iOS devices?)

I should probably also mention that my device is a SGS3 i9300 rooted, running a custom 4.1.2 android ROM (Omega v50.1 XXEMRG). Edit: I am now on ROM CM11 20150901 XNG3CAO3G0 (android 4.4.4), the problem still persists.

Can anyone with a spare 5 minutes who has an android, please test my above code using Rob’s auto config.lua code instead of mine (The code that’s been commented out). All you have to do is: uncomment rob’s code > remove mine > build it > install it to your device > run the app and type something into the text field, then attempt to select it by holding down on the text. You should expect to see the selection dialog at the top of your screen with cut, copy, etc.

If someone else replies confirming this on another device, I will make a bug report.

Update: I’ve tried a much simpler config.lua using the adaptive setting. This still unfortunately causes text-selection to break.

application = { content = { scale = "adaptive" }, }

I’ve uploaded a test project for someone to try and build to their android device (please anyone?).

Hi @danielr0,

For another point of testing, can you load and install our “NativeKeyboard” sample project on the same phone? It’s located in your local applications folder here:

CoronaSDK-XXXX > SampleCode > Interface > NativeKeyboard

Please try that sample and see if the behavior is duplicated.

Thanks,

Brent

As stated in the first post. The NativeKeyboard sample app works just fine. But with it comes the problem of not utilising the entire screen-space for backgrounds and object placement. This is because the config is limited to 320x480. So when I try to place an object at (0<x<1) * display.contentHeight, the object only goes from somewhere between the middle top and middle bottom.

If I modify the config.lua and set the height to the android screen’s 1.778 aspect ratio (such as 320x568 or 720x1280), I can accurately place an object where I want, however the text selection breaks.

This leaves me with having to use some other means of placing objects in the scene instead of using display.contentWidth and display.contentHeight.

For now, I have come up with my own hack to fix this issue, where I:

  1. In the config.lua: leave the height aspect ratio at 320x480, and set yAlign = “top”.

    application = { content = { width = 320, height = 480, yAlign = “top”, scale = “letterbox” }, }

  2. In the program, use the following code to calculate aspect ratio and set my own height variable.

Note: It seems that even though the display.contentHeight is limited to 480, objects are still able to be placed past that, up to 568 (in a 320x480 resolution).

local aspectRatio = display.actualContentHeight/display.actualContentWidth local \_w = display.contentWidth local \_h = display.contentWidth \* aspectRatio local \_cx = display.contentCenterX local \_cy = \_h\*0.5

I can now use these variables instead and place my objects to true screen size.

Obviously I’d prefer if I wasn’t doing this since I have to either: make these variables global, calculate them in each scene, or pass them through to each scene with composer.

I’ve downloaded your test app to check it out, but my android tablet is dead so I’ve got to get it restarted before I can test it, but it seems to me that you may not be a bug, but how config.lua works.

Consider first a fixed config.lua.  When you set width and height, you’re telling Corona what values display.contentWidth and display.contentHeight. These are not determined by anything other than what values you put in config.lua. Lets say you said 320 and 480 for the values.

Lets say you’re on a 16:9 device portrait mode. Your screen will generate a 320 x 570 virtual content area for your app. The 320 x 480 defined area is centered on the screen by default. This means the top of the screen is really a .y of -45 and the bottom of the screen is a .y of 480 + 45. However, in your example you set the yAlign to top, which means your top should be .y = 0 and your bottom is .y = 570.

Because of this, we have other API’s that are of use. display.actualContentHeight will give you the actual content height. In this example it will return 570 instead of 480.  Then there is display.screenOriginY (and there are width/X versions of both of these). This API will give you the offset to the top of the screen if your yAlign is center as I talked about above and would return -45. But since you aligned your Y to the top.  The gist of this is that you can’t use % * display.contentHeight with a fixed content area if the device is bigger. You have to use display.actualContentHeight.

The config.lua that calculates the width/height guarantees that 0 will be the top of the screen and display.contentHeight will be the bottom of the screen, at which your percent based math will be closer to what you desire. Android does funky things with its status bars. For instance on the Kindle Fire, there was a 20 pixel difference. Some show and hide. There are bugs with using immersive sticky from Google that are outside of our control.

Percent calculations seem problematic to begin with. Most apps would just use fixed spacing down from the top and have any empty space due to variable heights at the bottom.

Any way, consider what I’ve posted above above about how the various content configurations work and see if that helps you.

Rob

Thanks for the input Rob. Would you say the method I’m using now is okay? Or do you have any recommendations?

If it works for you and you understand what you’re doing, then go for it. If the sample app you gave me is where you want your text fields, it seems a bit unorthadox. If you have just the 3 fields, draw them in the top half of the screen so the keyboard won’t cover them up and have similar padding.

Now for the selecting text issue, I finally got to build your app and I’m seeing it too, but I’ve not had time to see what the cause is.

Rob

Alright thanks.

Nah, that was just me testing the panning and other things to make sure it all continues to work (or not).

I will most likely have all my text input fields on the top half of the screen for my app.

For the issue, since there is a workaround, is it worth making a bug report?

I’m not sure what bug you’re reporting? Where do you feel the bug is?

Rob

I guess that should’ve been my first question.

Is the text selection popping away, due to certain config.lua setups, a bug?

Update: I’ve tried a much simpler config.lua using the adaptive setting. This still unfortunately causes text-selection to break.

application = { content = { scale = "adaptive" }, }

I’ve uploaded a test project for someone to try and build to their android device (please anyone?).

Hi @danielr0,

For another point of testing, can you load and install our “NativeKeyboard” sample project on the same phone? It’s located in your local applications folder here:

CoronaSDK-XXXX > SampleCode > Interface > NativeKeyboard

Please try that sample and see if the behavior is duplicated.

Thanks,

Brent

As stated in the first post. The NativeKeyboard sample app works just fine. But with it comes the problem of not utilising the entire screen-space for backgrounds and object placement. This is because the config is limited to 320x480. So when I try to place an object at (0<x<1) * display.contentHeight, the object only goes from somewhere between the middle top and middle bottom.

If I modify the config.lua and set the height to the android screen’s 1.778 aspect ratio (such as 320x568 or 720x1280), I can accurately place an object where I want, however the text selection breaks.

This leaves me with having to use some other means of placing objects in the scene instead of using display.contentWidth and display.contentHeight.

For now, I have come up with my own hack to fix this issue, where I:

  1. In the config.lua: leave the height aspect ratio at 320x480, and set yAlign = “top”.

    application = { content = { width = 320, height = 480, yAlign = “top”, scale = “letterbox” }, }

  2. In the program, use the following code to calculate aspect ratio and set my own height variable.

Note: It seems that even though the display.contentHeight is limited to 480, objects are still able to be placed past that, up to 568 (in a 320x480 resolution).

local aspectRatio = display.actualContentHeight/display.actualContentWidth local \_w = display.contentWidth local \_h = display.contentWidth \* aspectRatio local \_cx = display.contentCenterX local \_cy = \_h\*0.5

I can now use these variables instead and place my objects to true screen size.

Obviously I’d prefer if I wasn’t doing this since I have to either: make these variables global, calculate them in each scene, or pass them through to each scene with composer.

I’ve downloaded your test app to check it out, but my android tablet is dead so I’ve got to get it restarted before I can test it, but it seems to me that you may not be a bug, but how config.lua works.

Consider first a fixed config.lua.  When you set width and height, you’re telling Corona what values display.contentWidth and display.contentHeight. These are not determined by anything other than what values you put in config.lua. Lets say you said 320 and 480 for the values.

Lets say you’re on a 16:9 device portrait mode. Your screen will generate a 320 x 570 virtual content area for your app. The 320 x 480 defined area is centered on the screen by default. This means the top of the screen is really a .y of -45 and the bottom of the screen is a .y of 480 + 45. However, in your example you set the yAlign to top, which means your top should be .y = 0 and your bottom is .y = 570.

Because of this, we have other API’s that are of use. display.actualContentHeight will give you the actual content height. In this example it will return 570 instead of 480.  Then there is display.screenOriginY (and there are width/X versions of both of these). This API will give you the offset to the top of the screen if your yAlign is center as I talked about above and would return -45. But since you aligned your Y to the top.  The gist of this is that you can’t use % * display.contentHeight with a fixed content area if the device is bigger. You have to use display.actualContentHeight.

The config.lua that calculates the width/height guarantees that 0 will be the top of the screen and display.contentHeight will be the bottom of the screen, at which your percent based math will be closer to what you desire. Android does funky things with its status bars. For instance on the Kindle Fire, there was a 20 pixel difference. Some show and hide. There are bugs with using immersive sticky from Google that are outside of our control.

Percent calculations seem problematic to begin with. Most apps would just use fixed spacing down from the top and have any empty space due to variable heights at the bottom.

Any way, consider what I’ve posted above above about how the various content configurations work and see if that helps you.

Rob

Thanks for the input Rob. Would you say the method I’m using now is okay? Or do you have any recommendations?

If it works for you and you understand what you’re doing, then go for it. If the sample app you gave me is where you want your text fields, it seems a bit unorthadox. If you have just the 3 fields, draw them in the top half of the screen so the keyboard won’t cover them up and have similar padding.

Now for the selecting text issue, I finally got to build your app and I’m seeing it too, but I’ve not had time to see what the cause is.

Rob

Alright thanks.

Nah, that was just me testing the panning and other things to make sure it all continues to work (or not).

I will most likely have all my text input fields on the top half of the screen for my app.

For the issue, since there is a workaround, is it worth making a bug report?

I’m not sure what bug you’re reporting? Where do you feel the bug is?

Rob

I guess that should’ve been my first question.

Is the text selection popping away, due to certain config.lua setups, a bug?