Skip to content

Commit fda015c

Browse files
author
Johan Vos
committed
8242167: ios keyboard handling
Reviewed-by: kcr
1 parent 844460b commit fda015c

File tree

12 files changed

+291
-79
lines changed

12 files changed

+291
-79
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package javafx.scene.control.skin;
27+
28+
import javafx.beans.value.ChangeListener;
29+
import javafx.beans.value.ObservableValue;
30+
import javafx.scene.control.TextArea;
31+
import javafx.scene.control.skin.TextAreaSkin;
32+
33+
public class TextAreaSkinIos extends TextAreaSkin {
34+
35+
public TextAreaSkinIos(final TextArea textArea) {
36+
super(textArea);
37+
38+
textArea.focusedProperty().addListener(new ChangeListener<Boolean>() {
39+
public void changed(ObservableValue<? extends Boolean> observable,
40+
Boolean wasFocused, Boolean isFocused) {
41+
if (textArea.isEditable()) {
42+
if (isFocused) {
43+
showSoftwareKeyboard();
44+
} else {
45+
hideSoftwareKeyboard();
46+
}
47+
}
48+
}
49+
});
50+
}
51+
52+
native void showSoftwareKeyboard();
53+
native void hideSoftwareKeyboard();
54+
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package javafx.scene.control.skin;
27+
28+
import javafx.beans.value.ChangeListener;
29+
import javafx.beans.value.ObservableValue;
30+
import javafx.scene.control.TextField;
31+
32+
import com.sun.javafx.scene.control.behavior.TextFieldBehavior;
33+
import javafx.scene.control.skin.TextFieldSkin;
34+
35+
public class TextFieldSkinIos extends TextFieldSkin {
36+
37+
public TextFieldSkinIos(final TextField textField) {
38+
super(textField);
39+
40+
textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
41+
public void changed(ObservableValue<? extends Boolean> observable,
42+
Boolean wasFocused, Boolean isFocused) {
43+
if (textField.isEditable()) {
44+
if (isFocused) {
45+
showSoftwareKeyboard();
46+
} else {
47+
hideSoftwareKeyboard();
48+
}
49+
}
50+
}
51+
});
52+
}
53+
54+
native void showSoftwareKeyboard();
55+
native void hideSoftwareKeyboard();
56+
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
/*******************************************************************************
27+
* *
28+
* Ios specific css *
29+
* *
30+
******************************************************************************/
31+
32+
33+
/*******************************************************************************
34+
* *
35+
* TextField *
36+
* *
37+
******************************************************************************/
38+
39+
.text-field {
40+
-fx-skin: "javafx.scene.control.skin.TextFieldSkinIos";
41+
}
42+
43+
44+
/*******************************************************************************
45+
* *
46+
* TextArea *
47+
* *
48+
******************************************************************************/
49+
50+
.text-area {
51+
-fx-skin: "javafx.scene.control.skin.TextAreaSkinIos";
52+
}
53+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
/*******************************************************************************
27+
* *
28+
* Ios specific css *
29+
* *
30+
******************************************************************************/
31+
32+
33+
/*******************************************************************************
34+
* *
35+
* TextField *
36+
* *
37+
******************************************************************************/
38+
39+
.text-field {
40+
-fx-skin: "javafx.scene.control.skin.TextFieldSkinIos";
41+
}
42+
43+
44+
/*******************************************************************************
45+
* *
46+
* TextArea *
47+
* *
48+
******************************************************************************/
49+
50+
.text-area {
51+
-fx-skin: "javafx.scene.control.skin.TextAreaSkinIos";
52+
}
53+

modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TextAreaBehavior.java

-22
Original file line numberDiff line numberDiff line change
@@ -149,33 +149,11 @@ public void changed(ObservableValue<? extends Boolean> observable, Boolean oldVa
149149
// TextArea doesn't lose selection on focus lost, whereas the TextField does.
150150
final TextArea textArea = getNode();
151151
if (textArea.isFocused()) {
152-
if (PlatformUtil.isIOS()) {
153-
// Special handling of focus on iOS is required to allow to
154-
// control native keyboard, because native keyboard is popped-up only when native
155-
// text component gets focus. When we have JFX keyboard we can remove this code
156-
final Bounds bounds = textArea.getBoundsInParent();
157-
double w = bounds.getWidth();
158-
double h = bounds.getHeight();
159-
Affine3D trans = TextFieldBehavior.calculateNodeToSceneTransform(textArea);
160-
String text = textArea.textProperty().getValueSafe();
161-
162-
// we need to display native text input component on the place where JFX component is drawn
163-
// all parameters needed to do that are passed to native impl. here
164-
WindowHelper.getPeer(textArea.getScene().getWindow()).requestInput(
165-
text, TextFieldBehavior.TextInputTypes.TEXT_AREA.ordinal(), w, h,
166-
trans.getMxx(), trans.getMxy(), trans.getMxz(), trans.getMxt(),
167-
trans.getMyx(), trans.getMyy(), trans.getMyz(), trans.getMyt(),
168-
trans.getMzx(), trans.getMzy(), trans.getMzz(), trans.getMzt());
169-
}
170152
if (!focusGainedByMouseClick) {
171153
setCaretAnimating(true);
172154
}
173155
} else {
174156
// skin.hideCaret();
175-
if (PlatformUtil.isIOS() && textArea.getScene() != null) {
176-
// releasing the focus => we need to hide the native component and also native keyboard
177-
WindowHelper.getPeer(textArea.getScene().getWindow()).releaseInput();
178-
}
179157
focusGainedByMouseClick = false;
180158
setCaretAnimating(false);
181159
}

modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TextFieldBehavior.java

-31
Original file line numberDiff line numberDiff line change
@@ -120,41 +120,10 @@ private void handleFocusChange() {
120120
TextField textField = getNode();
121121

122122
if (textField.isFocused()) {
123-
if (PlatformUtil.isIOS()) {
124-
// special handling of focus on iOS is required to allow to
125-
// control native keyboard, because nat. keyboard is poped-up only when native
126-
// text component gets focus. When we have JFX keyboard we can remove this code
127-
TextInputTypes type = TextInputTypes.TEXT_FIELD;
128-
if (textField.getClass().equals(javafx.scene.control.PasswordField.class)) {
129-
type = TextInputTypes.PASSWORD_FIELD;
130-
} else if (textField.getParent().getClass().equals(javafx.scene.control.ComboBox.class)) {
131-
type = TextInputTypes.EDITABLE_COMBO;
132-
}
133-
final Bounds bounds = textField.getBoundsInParent();
134-
double w = bounds.getWidth();
135-
double h = bounds.getHeight();
136-
Affine3D trans = calculateNodeToSceneTransform(textField);
137-
// Insets insets = skin.getInsets();
138-
// w -= insets.getLeft() + insets.getRight();
139-
// h -= insets.getTop() + insets.getBottom();
140-
String text = textField.getText();
141-
142-
// we need to display native text input component on the place where JFX component is drawn
143-
// all parameters needed to do that are passed to native impl. here
144-
WindowHelper.getPeer(textField.getScene().getWindow()).requestInput(
145-
text, type.ordinal(), w, h,
146-
trans.getMxx(), trans.getMxy(), trans.getMxz(), trans.getMxt(),// + insets.getLeft(),
147-
trans.getMyx(), trans.getMyy(), trans.getMyz(), trans.getMyt(),// + insets.getTop(),
148-
trans.getMzx(), trans.getMzy(), trans.getMzz(), trans.getMzt());
149-
}
150123
if (!focusGainedByMouseClick) {
151124
setCaretAnimating(true);
152125
}
153126
} else {
154-
if (PlatformUtil.isIOS() && textField.getScene() != null) {
155-
// releasing the focus => we need to hide the native component and also native keyboard
156-
WindowHelper.getPeer(textField.getScene().getWindow()).releaseInput();
157-
}
158127
focusGainedByMouseClick = false;
159128
setCaretAnimating(false);
160129
}

modules/javafx.controls/src/main/java/javafx/scene/control/skin/TextInputControlSkin.java

-6
Original file line numberDiff line numberDiff line change
@@ -687,12 +687,6 @@ protected void handleInputMethodEvent(InputMethodEvent event) {
687687
final TextInputControl textInput = getSkinnable();
688688
if (textInput.isEditable() && !textInput.textProperty().isBound() && !textInput.isDisabled()) {
689689

690-
// just replace the text on iOS
691-
if (PlatformUtil.isIOS()) {
692-
textInput.setText(event.getCommitted());
693-
return;
694-
}
695-
696690
// remove previous input method text (if any) or selected text
697691
if (imlength != 0) {
698692
removeHighlight(imattrs);

modules/javafx.graphics/src/main/java/com/sun/javafx/application/PlatformImpl.java

+6
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,9 @@ private static void _setPlatformUserAgentStylesheet(String stylesheetUrl) {
787787
if (PlatformUtil.isAndroid()) {
788788
uaStylesheets.add("com/sun/javafx/scene/control/skin/caspian/android.css");
789789
}
790+
if (PlatformUtil.isIOS()) {
791+
uaStylesheets.add("com/sun/javafx/scene/control/skin/caspian/ios.css");
792+
}
790793
}
791794

792795
if (isSupported(ConditionalFeature.TWO_LEVEL_FOCUS)) {
@@ -816,6 +819,9 @@ private static void _setPlatformUserAgentStylesheet(String stylesheetUrl) {
816819
if (PlatformUtil.isAndroid()) {
817820
uaStylesheets.add("com/sun/javafx/scene/control/skin/modena/android.css");
818821
}
822+
if (PlatformUtil.isIOS()) {
823+
uaStylesheets.add("com/sun/javafx/scene/control/skin/modena/ios.css");
824+
}
819825

820826
if (isSupported(ConditionalFeature.TWO_LEVEL_FOCUS)) {
821827
uaStylesheets.add("com/sun/javafx/scene/control/skin/modena/two-level-focus.css");

modules/javafx.graphics/src/main/native-glass/ios/GlassViewGL.h

+2
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,7 @@
5252
UIView *inputAccessoryView;
5353
UIView *nativeView; // view used for user input
5454
}
55+
-(void) doInsertText:(NSString*)myText;
56+
-(void) doDeleteBackward;
5557

5658
@end

modules/javafx.graphics/src/main/native-glass/ios/GlassViewGL.m

+13
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,19 @@ - (void)dealloc {
124124

125125
@implementation GlassViewGL : GLView
126126

127+
-(void) doInsertText:(NSString*)myText {
128+
int asciiCode = [myText characterAtIndex:0];
129+
[self->delegate sendJavaKeyEventWithType:111 keyCode:asciiCode chars:(char)asciiCode modifiers:0];
130+
[self->delegate sendJavaKeyEventWithType:113 keyCode:asciiCode chars:(char)asciiCode modifiers:0];
131+
[self->delegate sendJavaKeyEventWithType:112 keyCode:asciiCode chars:(char)asciiCode modifiers:0];
132+
}
133+
134+
-(void) doDeleteBackward {
135+
int asciiCode = 8;
136+
[self->delegate sendJavaKeyEventWithType:111 keyCode:asciiCode chars:(char)asciiCode modifiers:0];
137+
[self->delegate sendJavaKeyEventWithType:113 keyCode:asciiCode chars:(char)asciiCode modifiers:0];
138+
[self->delegate sendJavaKeyEventWithType:112 keyCode:asciiCode chars:(char)asciiCode modifiers:0];
139+
}
127140

128141
-(BOOL) touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
129142
{

modules/javafx.graphics/src/main/native-glass/ios/GlassWindow.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040

4141
@end
4242

43-
@interface GlassWindow : UIView
43+
@interface GlassWindow : UIView<UIKeyInput>
4444
{
4545
jobject jWindow; // Glass java Window object
4646

0 commit comments

Comments
 (0)