Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions Ports/iOSPort/nativeSources/CodenameOne_GLViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -4582,13 +4582,55 @@ CGRect setOriginY(CGFloat y, CGRect frame) {
int keyboardSlideOffset;
int keyboardHeight;

// Set while a system sheet that owns its own keyboard is presented over the
// application -- today the SMS composer (IOSNative sendSMS). The keyboard
// notifications are process wide, so the composer's keyboard reaches the two
// handlers below exactly as one of our own text fields' would: they record a
// keyboard height, call into Java (which can pad and revalidate the current
// form, and fires the virtual keyboard listeners of the application) and
// repaint underneath the sheet. None of that is about our UI, and issue #6211
// reports the composer intermittently coming up with its entry field behind
// the keyboard, so while the flag is set a "will show" is ignored.
//
// A "will hide" is never ignored on the flag alone. The one that pairs with an
// ignored show is dropped (cn1KeyboardShowIgnored), so the listeners never see
// a "hidden" for a keyboard they were not told about -- but only while we have
// no keyboard of our own on record (keyboardIsShown). When one of OUR editors
// had the keyboard up as the sheet opened, UIKit may hand that keyboard to the
// sheet without a hide in between; the next hide is then the only one our own
// keyboard will ever get, and it is what puts the view and the form back.
BOOL cn1KeyboardTrackingSuspended = NO;
static BOOL cn1KeyboardShowIgnored = NO;

// A flag that stayed set would silently break every text field in the
// application, so it is not trusted by itself: with nothing presented there is
// no sheet whose keyboard this could be, and the flag is dropped.
static BOOL cn1IsKeyboardTrackingSuspended(UIViewController* controller) {
if (!cn1KeyboardTrackingSuspended) {
return NO;
}
if (controller.presentedViewController == nil) {
cn1KeyboardTrackingSuspended = NO;
return NO;
}
return YES;
}


- (void)keyboardWillHide:(NSNotification *)n
{
// UIKit-only helper. AppKit's equivalent is a different API rather than a
// renamed one, so this is inert on the native macOS port until it is ported.
#if TARGET_OS_OSX
#else
if (cn1KeyboardShowIgnored) {
cn1KeyboardShowIgnored = NO;
if (!keyboardIsShown) {
// The keyboard of a system sheet going away, and none of ours to
// put away; see cn1KeyboardTrackingSuspended.
return;
}
}
@synchronized([CodenameOne_GLViewController instance]) {
[currentTarget removeAllObjects];
}
Expand Down Expand Up @@ -4653,6 +4695,11 @@ - (void)keyboardWillShow:(NSNotification *)n
// renamed one, so this is inert on the native macOS port until it is ported.
#if TARGET_OS_OSX
#else
if (cn1IsKeyboardTrackingSuspended(self)) {
cn1KeyboardShowIgnored = YES;
return;
}
cn1KeyboardShowIgnored = NO;
// Hide the datepicker if it is currently showing.
[self datePickerCancel];

Expand Down Expand Up @@ -6152,6 +6199,9 @@ -(void) mailComposeController:(MFMailComposeViewController*)controller didFinish
// only the body would leave a signature naming an unknown type.
#if !TARGET_OS_OSX
-(void) messageComposeViewController:(MFMessageComposeViewController*)controller didFinishWithResult:(MessageComposeResult)result {
// Our own keyboard handling resumes here; the hide of the composer's keyboard
// that follows is still dropped, by cn1KeyboardShowIgnored.
cn1KeyboardTrackingSuspended = NO;
// Through the composer, for the reason given on the mail delegate above.
[controller dismissViewControllerAnimated:YES completion:nil];
}
Expand Down
10 changes: 10 additions & 0 deletions Ports/iOSPort/nativeSources/IOSNative.m
Original file line number Diff line number Diff line change
Expand Up @@ -12341,6 +12341,8 @@ void com_codename1_impl_ios_IOSNative_requestAppStoreReview__(CN1_THREAD_STATE_M
#endif // CN1_USE_APPREVIEW
}

extern BOOL cn1KeyboardTrackingSuspended;

void com_codename1_impl_ios_IOSNative_sendSMS___java_lang_String_java_lang_String(CN1_THREAD_STATE_MULTI_ARG JAVA_OBJECT instanceObject,
JAVA_OBJECT number, JAVA_OBJECT text) {
// Not implemented on the native macOS port: the body below is UIKit -- a
Expand Down Expand Up @@ -12376,6 +12378,14 @@ void com_codename1_impl_ios_IOSNative_sendSMS___java_lang_String_java_lang_Strin

[picker setBody:smsBody];

// The composer brings its own keyboard; keep our keyboard handlers out
// of it until the delegate dismisses the sheet (issue #6211). Not when
// something is already presented: UIKit then refuses this presentation,
// the delegate that clears the flag never runs, and the keyboard of
// whatever is up would go unhandled until that is dismissed.
if (cn1PresentingController().presentedViewController == nil) {
cn1KeyboardTrackingSuspended = YES;
}
[cn1PresentingController() presentModalViewController:picker animated:YES];

#ifndef CN1_USE_ARC
Expand Down
Loading