pythonnative 0.25.0__py3-none-any.whl → 0.26.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pythonnative/__init__.py +1 -1
- pythonnative/cli/pn.py +172 -12
- pythonnative/diagnostics.py +27 -0
- pythonnative/native_modules/app_state.py +2 -1
- pythonnative/native_modules/battery.py +3 -2
- pythonnative/native_modules/biometrics.py +2 -1
- pythonnative/native_modules/camera.py +16 -7
- pythonnative/native_modules/clipboard.py +3 -2
- pythonnative/native_modules/file_system.py +3 -2
- pythonnative/native_modules/haptics.py +7 -6
- pythonnative/native_modules/linking.py +62 -6
- pythonnative/native_modules/location.py +11 -8
- pythonnative/native_modules/net_info.py +2 -1
- pythonnative/native_modules/notifications.py +97 -6
- pythonnative/native_modules/permissions.py +3 -2
- pythonnative/native_modules/share.py +2 -1
- pythonnative/native_views/android.py +142 -122
- pythonnative/native_views/desktop.py +50 -49
- pythonnative/native_views/ios.py +228 -160
- pythonnative/project/android.py +15 -3
- pythonnative/project/builder.py +172 -70
- pythonnative/project/config.py +28 -6
- pythonnative/project/devices.py +291 -0
- pythonnative/project/doctor.py +5 -4
- pythonnative/project/ios.py +51 -77
- pythonnative/project/permissions.py +19 -1
- pythonnative/project/runtime_assets.py +78 -166
- pythonnative/templates/android_template/app/build.gradle +5 -0
- pythonnative/templates/android_template/app/src/main/AndroidManifest.xml +1 -0
- pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt +88 -12
- pythonnative/templates/ios_template/ios_template/AppDelegate.swift +41 -17
- pythonnative/templates/ios_template/ios_template/BridgingHeader.h +14 -0
- pythonnative/templates/ios_template/ios_template/Info.plist +0 -2
- pythonnative/templates/ios_template/ios_template/PythonRuntime.swift +397 -0
- pythonnative/templates/ios_template/ios_template/SceneDelegate.swift +31 -20
- pythonnative/templates/ios_template/ios_template/ViewController.swift +77 -198
- pythonnative/templates/ios_template/ios_template.xcodeproj/project.pbxproj +72 -47
- {pythonnative-0.25.0.dist-info → pythonnative-0.26.0.dist-info}/METADATA +1 -1
- {pythonnative-0.25.0.dist-info → pythonnative-0.26.0.dist-info}/RECORD +43 -41
- pythonnative/templates/ios_template/ios_template/Base.lproj/Main.storyboard +0 -24
- {pythonnative-0.25.0.dist-info → pythonnative-0.26.0.dist-info}/WHEEL +0 -0
- {pythonnative-0.25.0.dist-info → pythonnative-0.26.0.dist-info}/entry_points.txt +0 -0
- {pythonnative-0.25.0.dist-info → pythonnative-0.26.0.dist-info}/licenses/LICENSE +0 -0
- {pythonnative-0.25.0.dist-info → pythonnative-0.26.0.dist-info}/top_level.txt +0 -0
|
@@ -40,6 +40,7 @@ from typing import Any, Callable, Dict, Optional, Tuple
|
|
|
40
40
|
|
|
41
41
|
from java import dynamic_proxy, jclass
|
|
42
42
|
|
|
43
|
+
from .. import diagnostics
|
|
43
44
|
from ..events import dispatch_event, event_names
|
|
44
45
|
from ..gestures import make_arbiter
|
|
45
46
|
from ..utils import get_android_context
|
|
@@ -206,7 +207,7 @@ def _apply_side_border(view: Any, props: Dict[str, Any]) -> bool:
|
|
|
206
207
|
try:
|
|
207
208
|
view.invalidate()
|
|
208
209
|
except Exception:
|
|
209
|
-
|
|
210
|
+
diagnostics.swallowed("android._apply_side_border")
|
|
210
211
|
return True
|
|
211
212
|
except Exception:
|
|
212
213
|
return False
|
|
@@ -237,12 +238,12 @@ def _apply_border(view: Any, props: Dict[str, Any]) -> None:
|
|
|
237
238
|
try:
|
|
238
239
|
drawable.setColor(parse_color_int(props["background_color"]))
|
|
239
240
|
except Exception:
|
|
240
|
-
|
|
241
|
+
diagnostics.swallowed("android._apply_border")
|
|
241
242
|
if "border_radius" in props and props["border_radius"] is not None:
|
|
242
243
|
try:
|
|
243
244
|
drawable.setCornerRadius(float(_dp(float(props["border_radius"]))))
|
|
244
245
|
except Exception:
|
|
245
|
-
|
|
246
|
+
diagnostics.swallowed("android._apply_border")
|
|
246
247
|
if ("border_width" in props and props["border_width"] is not None) or (
|
|
247
248
|
"border_color" in props and props["border_color"] is not None
|
|
248
249
|
):
|
|
@@ -254,18 +255,18 @@ def _apply_border(view: Any, props: Dict[str, Any]) -> None:
|
|
|
254
255
|
parse_color_int(color or "#000000"),
|
|
255
256
|
)
|
|
256
257
|
except Exception:
|
|
257
|
-
|
|
258
|
+
diagnostics.swallowed("android._apply_border")
|
|
258
259
|
view.setBackground(drawable)
|
|
259
260
|
try:
|
|
260
261
|
drawable.invalidateSelf()
|
|
261
262
|
except Exception:
|
|
262
|
-
|
|
263
|
+
diagnostics.swallowed("android._apply_border")
|
|
263
264
|
try:
|
|
264
265
|
view.invalidate()
|
|
265
266
|
except Exception:
|
|
266
|
-
|
|
267
|
+
diagnostics.swallowed("android._apply_border")
|
|
267
268
|
except Exception:
|
|
268
|
-
|
|
269
|
+
diagnostics.swallowed("android._apply_border")
|
|
269
270
|
|
|
270
271
|
|
|
271
272
|
def _apply_shadow(view: Any, props: Dict[str, Any]) -> None:
|
|
@@ -291,7 +292,7 @@ def _apply_shadow(view: Any, props: Dict[str, Any]) -> None:
|
|
|
291
292
|
try:
|
|
292
293
|
view.setElevation(float(_dp(float(elevation))))
|
|
293
294
|
except Exception:
|
|
294
|
-
|
|
295
|
+
diagnostics.swallowed("android._apply_shadow")
|
|
295
296
|
color = props.get("shadow_color")
|
|
296
297
|
if color is None:
|
|
297
298
|
return
|
|
@@ -308,7 +309,7 @@ def _apply_shadow(view: Any, props: Dict[str, Any]) -> None:
|
|
|
308
309
|
view.setOutlineAmbientShadowColor(signed)
|
|
309
310
|
view.setOutlineSpotShadowColor(signed)
|
|
310
311
|
except Exception:
|
|
311
|
-
|
|
312
|
+
diagnostics.swallowed("android._apply_shadow")
|
|
312
313
|
|
|
313
314
|
|
|
314
315
|
def _apply_transform(view: Any, props: Dict[str, Any]) -> None:
|
|
@@ -324,7 +325,7 @@ def _apply_transform(view: Any, props: Dict[str, Any]) -> None:
|
|
|
324
325
|
view.setTranslationX(0.0)
|
|
325
326
|
view.setTranslationY(0.0)
|
|
326
327
|
except Exception:
|
|
327
|
-
|
|
328
|
+
diagnostics.swallowed("android._apply_transform")
|
|
328
329
|
return
|
|
329
330
|
entries = spec if isinstance(spec, list) else [spec]
|
|
330
331
|
for entry in entries:
|
|
@@ -353,7 +354,7 @@ def _apply_transform(view: Any, props: Dict[str, Any]) -> None:
|
|
|
353
354
|
if "translate_y" in entry:
|
|
354
355
|
view.setTranslationY(float(_dp(float(entry["translate_y"]))))
|
|
355
356
|
except Exception:
|
|
356
|
-
|
|
357
|
+
diagnostics.swallowed("android._apply_transform")
|
|
357
358
|
|
|
358
359
|
|
|
359
360
|
def _apply_accessibility(view: Any, props: Dict[str, Any]) -> None:
|
|
@@ -365,13 +366,13 @@ def _apply_accessibility(view: Any, props: Dict[str, Any]) -> None:
|
|
|
365
366
|
View.IMPORTANT_FOR_ACCESSIBILITY_YES if props["accessible"] else View.IMPORTANT_FOR_ACCESSIBILITY_NO
|
|
366
367
|
)
|
|
367
368
|
except Exception:
|
|
368
|
-
|
|
369
|
+
diagnostics.swallowed("android._apply_accessibility")
|
|
369
370
|
if "accessibility_label" in props:
|
|
370
371
|
try:
|
|
371
372
|
label = props["accessibility_label"]
|
|
372
373
|
view.setContentDescription(str(label) if label is not None else None)
|
|
373
374
|
except Exception:
|
|
374
|
-
|
|
375
|
+
diagnostics.swallowed("android._apply_accessibility")
|
|
375
376
|
if "accessibility_live_region" in props:
|
|
376
377
|
try:
|
|
377
378
|
mode = {"none": 0, "polite": 1, "assertive": 2}.get(
|
|
@@ -379,14 +380,14 @@ def _apply_accessibility(view: Any, props: Dict[str, Any]) -> None:
|
|
|
379
380
|
)
|
|
380
381
|
view.setAccessibilityLiveRegion(mode)
|
|
381
382
|
except Exception:
|
|
382
|
-
|
|
383
|
+
diagnostics.swallowed("android._apply_accessibility")
|
|
383
384
|
|
|
384
385
|
state = props.get("accessibility_state")
|
|
385
386
|
if isinstance(state, dict) and "selected" in state:
|
|
386
387
|
try:
|
|
387
388
|
view.setSelected(bool(state["selected"]))
|
|
388
389
|
except Exception:
|
|
389
|
-
|
|
390
|
+
diagnostics.swallowed("android._apply_accessibility")
|
|
390
391
|
test_id = props.get("test_id")
|
|
391
392
|
if test_id is None and not isinstance(state, dict):
|
|
392
393
|
return
|
|
@@ -413,7 +414,7 @@ def _apply_accessibility(view: Any, props: Dict[str, Any]) -> None:
|
|
|
413
414
|
delegate.setStateBusy(state.get("busy"))
|
|
414
415
|
delegate.setStateExpanded(state.get("expanded"))
|
|
415
416
|
except Exception:
|
|
416
|
-
|
|
417
|
+
diagnostics.swallowed("android._apply_accessibility")
|
|
417
418
|
|
|
418
419
|
|
|
419
420
|
def _apply_common_visual(view: Any, props: Dict[str, Any]) -> None:
|
|
@@ -433,12 +434,12 @@ def _apply_common_visual(view: Any, props: Dict[str, Any]) -> None:
|
|
|
433
434
|
view.setClipChildren(clip)
|
|
434
435
|
view.setClipToPadding(clip)
|
|
435
436
|
except Exception:
|
|
436
|
-
|
|
437
|
+
diagnostics.swallowed("android._apply_common_visual")
|
|
437
438
|
if "opacity" in props and props["opacity"] is not None:
|
|
438
439
|
try:
|
|
439
440
|
view.setAlpha(float(props["opacity"]))
|
|
440
441
|
except Exception:
|
|
441
|
-
|
|
442
|
+
diagnostics.swallowed("android._apply_common_visual")
|
|
442
443
|
_apply_shadow(view, props)
|
|
443
444
|
_apply_transform(view, props)
|
|
444
445
|
_apply_accessibility(view, props)
|
|
@@ -501,7 +502,7 @@ def _schedule_arbiter_poll(view: Any, state: Dict[str, Any]) -> None:
|
|
|
501
502
|
|
|
502
503
|
handler.postDelayed(_PollRunnable(), delay_ms)
|
|
503
504
|
except Exception:
|
|
504
|
-
|
|
505
|
+
diagnostics.swallowed("android._schedule_arbiter_poll")
|
|
505
506
|
|
|
506
507
|
|
|
507
508
|
def _bind_touch_stream(view: Any, state: Dict[str, Any]) -> None:
|
|
@@ -515,7 +516,7 @@ def _bind_touch_stream(view: Any, state: Dict[str, Any]) -> None:
|
|
|
515
516
|
|
|
516
517
|
view.setOnTouchListener(_GestureTouchProxy())
|
|
517
518
|
except Exception:
|
|
518
|
-
|
|
519
|
+
diagnostics.swallowed("android._bind_touch_stream")
|
|
519
520
|
|
|
520
521
|
|
|
521
522
|
def _feed_motion_event(view: Any, state: Dict[str, Any], event: Any) -> bool:
|
|
@@ -546,7 +547,7 @@ def _feed_motion_event(view: Any, state: Dict[str, Any], event: Any) -> bool:
|
|
|
546
547
|
if parent is not None:
|
|
547
548
|
parent.requestDisallowInterceptTouchEvent(True)
|
|
548
549
|
except Exception:
|
|
549
|
-
|
|
550
|
+
diagnostics.swallowed("android._feed_motion_event")
|
|
550
551
|
elif action in (1, 6): # UP / POINTER_UP
|
|
551
552
|
idx = int(event.getActionIndex())
|
|
552
553
|
pid = int(event.getPointerId(idx))
|
|
@@ -603,7 +604,7 @@ def _read_animated_value(view: Any, prop_name: str) -> Any:
|
|
|
603
604
|
if prop_name == "rotate":
|
|
604
605
|
return float(view.getRotation())
|
|
605
606
|
except Exception:
|
|
606
|
-
|
|
607
|
+
diagnostics.swallowed("android._read_animated_value")
|
|
607
608
|
return None
|
|
608
609
|
|
|
609
610
|
|
|
@@ -639,7 +640,7 @@ def _make_end_listener(anim_id: int) -> Any:
|
|
|
639
640
|
|
|
640
641
|
native_animation_completed(anim_id, not self._cancelled)
|
|
641
642
|
except Exception:
|
|
642
|
-
|
|
643
|
+
diagnostics.swallowed("android._make_end_listener._EndProxy.onAnimationEnd")
|
|
643
644
|
|
|
644
645
|
return _EndProxy()
|
|
645
646
|
|
|
@@ -731,7 +732,7 @@ class AndroidViewHandler(ViewHandler):
|
|
|
731
732
|
if parent is not None:
|
|
732
733
|
parent.removeView(native_view)
|
|
733
734
|
except Exception:
|
|
734
|
-
|
|
735
|
+
diagnostics.swallowed("android.AndroidViewHandler.destroy")
|
|
735
736
|
_forget(native_view)
|
|
736
737
|
|
|
737
738
|
def _build(self, props: Dict[str, Any]) -> Any:
|
|
@@ -760,17 +761,17 @@ class AndroidViewHandler(ViewHandler):
|
|
|
760
761
|
lp.width = px_w
|
|
761
762
|
lp.height = px_h
|
|
762
763
|
except Exception:
|
|
763
|
-
|
|
764
|
+
diagnostics.swallowed("android.AndroidViewHandler.set_frame")
|
|
764
765
|
try:
|
|
765
766
|
lp.leftMargin = px_x
|
|
766
767
|
lp.topMargin = px_y
|
|
767
768
|
lp.rightMargin = 0
|
|
768
769
|
lp.bottomMargin = 0
|
|
769
770
|
except Exception:
|
|
770
|
-
|
|
771
|
+
diagnostics.swallowed("android.AndroidViewHandler.set_frame")
|
|
771
772
|
native_view.setLayoutParams(lp)
|
|
772
773
|
except Exception:
|
|
773
|
-
|
|
774
|
+
diagnostics.swallowed("android.AndroidViewHandler.set_frame")
|
|
774
775
|
|
|
775
776
|
def measure_intrinsic(
|
|
776
777
|
self,
|
|
@@ -823,7 +824,7 @@ class AndroidViewHandler(ViewHandler):
|
|
|
823
824
|
elif prop_name == "background_color":
|
|
824
825
|
native_view.setBackgroundColor(parse_color_int(value))
|
|
825
826
|
except Exception:
|
|
826
|
-
|
|
827
|
+
diagnostics.swallowed("android.AndroidViewHandler.set_animated_property")
|
|
827
828
|
|
|
828
829
|
def start_animation(
|
|
829
830
|
self,
|
|
@@ -851,7 +852,7 @@ class AndroidViewHandler(ViewHandler):
|
|
|
851
852
|
try:
|
|
852
853
|
entry["animator"].cancel()
|
|
853
854
|
except Exception:
|
|
854
|
-
|
|
855
|
+
diagnostics.swallowed("android.AndroidViewHandler.cancel_animation")
|
|
855
856
|
return _read_animated_value(entry.get("view"), str(entry.get("prop", "")))
|
|
856
857
|
|
|
857
858
|
|
|
@@ -879,7 +880,7 @@ class FlexContainerHandler(AndroidViewHandler):
|
|
|
879
880
|
try:
|
|
880
881
|
parent.removeView(child)
|
|
881
882
|
except Exception:
|
|
882
|
-
|
|
883
|
+
diagnostics.swallowed("android.FlexContainerHandler.remove_child")
|
|
883
884
|
|
|
884
885
|
|
|
885
886
|
def _insert_view(parent: Any, child: Any, index: int) -> None:
|
|
@@ -905,7 +906,7 @@ def _insert_view(parent: Any, child: Any, index: int) -> None:
|
|
|
905
906
|
try:
|
|
906
907
|
parent.addView(child)
|
|
907
908
|
except Exception:
|
|
908
|
-
|
|
909
|
+
diagnostics.swallowed("android._insert_view")
|
|
909
910
|
|
|
910
911
|
|
|
911
912
|
# ======================================================================
|
|
@@ -993,7 +994,7 @@ def _build_spannable(spans: Any) -> Any:
|
|
|
993
994
|
StrikethroughSpan = jclass("android.text.style.StrikethroughSpan")
|
|
994
995
|
_set(StrikethroughSpan())
|
|
995
996
|
except Exception:
|
|
996
|
-
|
|
997
|
+
diagnostics.swallowed("android._build_spannable")
|
|
997
998
|
return builder
|
|
998
999
|
|
|
999
1000
|
|
|
@@ -1035,7 +1036,7 @@ class TextHandler(AndroidViewHandler):
|
|
|
1035
1036
|
else:
|
|
1036
1037
|
tv.setTypeface(tv.getTypeface(), style)
|
|
1037
1038
|
except Exception:
|
|
1038
|
-
|
|
1039
|
+
diagnostics.swallowed("android.TextHandler._apply")
|
|
1039
1040
|
if "max_lines" in props and props["max_lines"] is not None:
|
|
1040
1041
|
tv.setMaxLines(int(props["max_lines"]))
|
|
1041
1042
|
if "text_align" in props:
|
|
@@ -1050,14 +1051,14 @@ class TextHandler(AndroidViewHandler):
|
|
|
1050
1051
|
size = float(merged.get("font_size") or 16.0)
|
|
1051
1052
|
tv.setLetterSpacing(float(props["letter_spacing"]) / max(size, 1.0))
|
|
1052
1053
|
except Exception:
|
|
1053
|
-
|
|
1054
|
+
diagnostics.swallowed("android.TextHandler._apply")
|
|
1054
1055
|
if "line_height" in props and props["line_height"] is not None:
|
|
1055
1056
|
try:
|
|
1056
1057
|
merged = _state_of(tv).get("props") or props
|
|
1057
1058
|
size = float(merged.get("font_size") or 16.0)
|
|
1058
1059
|
tv.setLineSpacing(0.0, float(props["line_height"]) / max(size, 1.0))
|
|
1059
1060
|
except Exception:
|
|
1060
|
-
|
|
1061
|
+
diagnostics.swallowed("android.TextHandler._apply")
|
|
1061
1062
|
if "text_decoration" in props:
|
|
1062
1063
|
try:
|
|
1063
1064
|
Paint = jclass("android.graphics.Paint")
|
|
@@ -1068,7 +1069,7 @@ class TextHandler(AndroidViewHandler):
|
|
|
1068
1069
|
flags |= Paint.STRIKE_THRU_TEXT_FLAG
|
|
1069
1070
|
tv.setPaintFlags(flags)
|
|
1070
1071
|
except Exception:
|
|
1071
|
-
|
|
1072
|
+
diagnostics.swallowed("android.TextHandler._apply")
|
|
1072
1073
|
_apply_common_visual(tv, props)
|
|
1073
1074
|
|
|
1074
1075
|
|
|
@@ -1147,7 +1148,7 @@ class ScrollViewHandler(AndroidViewHandler):
|
|
|
1147
1148
|
try:
|
|
1148
1149
|
outer.setEnabled(False)
|
|
1149
1150
|
except Exception:
|
|
1150
|
-
|
|
1151
|
+
diagnostics.swallowed("android.ScrollViewHandler.create")
|
|
1151
1152
|
self._bind_scroll_listener(outer, sv)
|
|
1152
1153
|
self._apply(outer, props, initial=True)
|
|
1153
1154
|
if props.get("gestures"):
|
|
@@ -1165,7 +1166,7 @@ class ScrollViewHandler(AndroidViewHandler):
|
|
|
1165
1166
|
sv.setVerticalScrollBarEnabled(show)
|
|
1166
1167
|
sv.setHorizontalScrollBarEnabled(show)
|
|
1167
1168
|
except Exception:
|
|
1168
|
-
|
|
1169
|
+
diagnostics.swallowed("android.ScrollViewHandler._apply")
|
|
1169
1170
|
if "bounces" in props:
|
|
1170
1171
|
# ``bounces`` is only present when ``False``; map it to the
|
|
1171
1172
|
# closest analogue, the over-scroll (glow) mode.
|
|
@@ -1174,7 +1175,7 @@ class ScrollViewHandler(AndroidViewHandler):
|
|
|
1174
1175
|
mode = View.OVER_SCROLL_NEVER if props["bounces"] is False else View.OVER_SCROLL_IF_CONTENT_SCROLLS
|
|
1175
1176
|
sv.setOverScrollMode(mode)
|
|
1176
1177
|
except Exception:
|
|
1177
|
-
|
|
1178
|
+
diagnostics.swallowed("android.ScrollViewHandler._apply")
|
|
1178
1179
|
if "refresh_control" in props and state.get("refresh") is not None:
|
|
1179
1180
|
self._apply_refresh(outer, props)
|
|
1180
1181
|
# ``paging_enabled`` and ``keyboard_dismiss_mode`` have no clean
|
|
@@ -1190,7 +1191,7 @@ class ScrollViewHandler(AndroidViewHandler):
|
|
|
1190
1191
|
try:
|
|
1191
1192
|
sv.removeView(child)
|
|
1192
1193
|
except Exception:
|
|
1193
|
-
|
|
1194
|
+
diagnostics.swallowed("android.ScrollViewHandler.remove_child")
|
|
1194
1195
|
|
|
1195
1196
|
def command(self, native_view: Any, name: str, args: Dict[str, Any]) -> Any:
|
|
1196
1197
|
state = _state_of(native_view)
|
|
@@ -1206,7 +1207,7 @@ class ScrollViewHandler(AndroidViewHandler):
|
|
|
1206
1207
|
else:
|
|
1207
1208
|
sv.scrollTo(x_px, y_px)
|
|
1208
1209
|
except Exception:
|
|
1209
|
-
|
|
1210
|
+
diagnostics.swallowed("android.ScrollViewHandler.command")
|
|
1210
1211
|
return None
|
|
1211
1212
|
if name == "scroll_to_end":
|
|
1212
1213
|
try:
|
|
@@ -1220,7 +1221,7 @@ class ScrollViewHandler(AndroidViewHandler):
|
|
|
1220
1221
|
target_y = max(0, int(child.getHeight()) - int(sv.getHeight()))
|
|
1221
1222
|
sv.smoothScrollTo(0, target_y)
|
|
1222
1223
|
except Exception:
|
|
1223
|
-
|
|
1224
|
+
diagnostics.swallowed("android.ScrollViewHandler.command")
|
|
1224
1225
|
return None
|
|
1225
1226
|
if name == "get_scroll_offset":
|
|
1226
1227
|
try:
|
|
@@ -1250,11 +1251,13 @@ class ScrollViewHandler(AndroidViewHandler):
|
|
|
1250
1251
|
density = _density() or 1.0
|
|
1251
1252
|
_fire(outer, "on_scroll", {"x": scroll_x / density, "y": scroll_y / density})
|
|
1252
1253
|
except Exception:
|
|
1253
|
-
|
|
1254
|
+
diagnostics.swallowed(
|
|
1255
|
+
"android.ScrollViewHandler._bind_scroll_listener._ScrollChangeProxy.onScrollChange"
|
|
1256
|
+
)
|
|
1254
1257
|
|
|
1255
1258
|
sv.setOnScrollChangeListener(_ScrollChangeProxy())
|
|
1256
1259
|
except Exception:
|
|
1257
|
-
|
|
1260
|
+
diagnostics.swallowed("android.ScrollViewHandler._bind_scroll_listener")
|
|
1258
1261
|
|
|
1259
1262
|
def _wrap_in_refresh(self, sv: Any) -> Any:
|
|
1260
1263
|
try:
|
|
@@ -1278,7 +1281,7 @@ class ScrollViewHandler(AndroidViewHandler):
|
|
|
1278
1281
|
|
|
1279
1282
|
srl.setOnRefreshListener(_RefreshProxy())
|
|
1280
1283
|
except Exception:
|
|
1281
|
-
|
|
1284
|
+
diagnostics.swallowed("android.ScrollViewHandler._bind_refresh_listener")
|
|
1282
1285
|
|
|
1283
1286
|
def _apply_refresh(self, outer: Any, props: Dict[str, Any]) -> None:
|
|
1284
1287
|
srl = _state_of(outer).get("refresh")
|
|
@@ -1289,21 +1292,21 @@ class ScrollViewHandler(AndroidViewHandler):
|
|
|
1289
1292
|
try:
|
|
1290
1293
|
srl.setEnabled(False)
|
|
1291
1294
|
except Exception:
|
|
1292
|
-
|
|
1295
|
+
diagnostics.swallowed("android.ScrollViewHandler._apply_refresh")
|
|
1293
1296
|
return
|
|
1294
1297
|
try:
|
|
1295
1298
|
srl.setEnabled(True)
|
|
1296
1299
|
except Exception:
|
|
1297
|
-
|
|
1300
|
+
diagnostics.swallowed("android.ScrollViewHandler._apply_refresh")
|
|
1298
1301
|
if spec.get("tint_color"):
|
|
1299
1302
|
try:
|
|
1300
1303
|
srl.setColorSchemeColors([parse_color_int(spec["tint_color"])])
|
|
1301
1304
|
except Exception:
|
|
1302
|
-
|
|
1305
|
+
diagnostics.swallowed("android.ScrollViewHandler._apply_refresh")
|
|
1303
1306
|
try:
|
|
1304
1307
|
srl.setRefreshing(bool(spec.get("refreshing")))
|
|
1305
1308
|
except Exception:
|
|
1306
|
-
|
|
1309
|
+
diagnostics.swallowed("android.ScrollViewHandler._apply_refresh")
|
|
1307
1310
|
|
|
1308
1311
|
|
|
1309
1312
|
class TextInputHandler(AndroidViewHandler):
|
|
@@ -1316,7 +1319,7 @@ class TextInputHandler(AndroidViewHandler):
|
|
|
1316
1319
|
if not props.get("multiline"):
|
|
1317
1320
|
et.setSingleLine(True)
|
|
1318
1321
|
except Exception:
|
|
1319
|
-
|
|
1322
|
+
diagnostics.swallowed("android.TextInputHandler._build")
|
|
1320
1323
|
self._bind_listeners(et, props)
|
|
1321
1324
|
return et
|
|
1322
1325
|
|
|
@@ -1342,7 +1345,7 @@ class TextInputHandler(AndroidViewHandler):
|
|
|
1342
1345
|
|
|
1343
1346
|
et.addTextChangedListener(ChangeProxy())
|
|
1344
1347
|
except Exception:
|
|
1345
|
-
|
|
1348
|
+
diagnostics.swallowed("android.TextInputHandler._bind_listeners")
|
|
1346
1349
|
try:
|
|
1347
1350
|
|
|
1348
1351
|
class _FocusProxy(dynamic_proxy(jclass("android.view.View").OnFocusChangeListener)):
|
|
@@ -1351,7 +1354,7 @@ class TextInputHandler(AndroidViewHandler):
|
|
|
1351
1354
|
|
|
1352
1355
|
et.setOnFocusChangeListener(_FocusProxy())
|
|
1353
1356
|
except Exception:
|
|
1354
|
-
|
|
1357
|
+
diagnostics.swallowed("android.TextInputHandler._bind_listeners")
|
|
1355
1358
|
|
|
1356
1359
|
def _apply(self, et: Any, props: Dict[str, Any], initial: bool) -> None:
|
|
1357
1360
|
state = _state_of(et)
|
|
@@ -1368,7 +1371,7 @@ class TextInputHandler(AndroidViewHandler):
|
|
|
1368
1371
|
selection_start = et.getSelectionStart()
|
|
1369
1372
|
selection_end = et.getSelectionEnd()
|
|
1370
1373
|
except Exception:
|
|
1371
|
-
|
|
1374
|
+
diagnostics.swallowed("android.TextInputHandler._apply")
|
|
1372
1375
|
state["suppress"] = True
|
|
1373
1376
|
try:
|
|
1374
1377
|
et.setText(incoming)
|
|
@@ -1381,7 +1384,7 @@ class TextInputHandler(AndroidViewHandler):
|
|
|
1381
1384
|
else:
|
|
1382
1385
|
et.setSelection(start, end)
|
|
1383
1386
|
except Exception:
|
|
1384
|
-
|
|
1387
|
+
diagnostics.swallowed("android.TextInputHandler._apply")
|
|
1385
1388
|
finally:
|
|
1386
1389
|
state["suppress"] = False
|
|
1387
1390
|
if "placeholder" in props:
|
|
@@ -1390,7 +1393,7 @@ class TextInputHandler(AndroidViewHandler):
|
|
|
1390
1393
|
try:
|
|
1391
1394
|
et.setHintTextColor(parse_color_int(props["placeholder_color"]))
|
|
1392
1395
|
except Exception:
|
|
1393
|
-
|
|
1396
|
+
diagnostics.swallowed("android.TextInputHandler._apply")
|
|
1394
1397
|
if "font_size" in props and props["font_size"] is not None:
|
|
1395
1398
|
et.setTextSize(float(props["font_size"]))
|
|
1396
1399
|
if "color" in props and props["color"] is not None:
|
|
@@ -1428,18 +1431,18 @@ class TextInputHandler(AndroidViewHandler):
|
|
|
1428
1431
|
et.setSingleLine(True)
|
|
1429
1432
|
et.setInputType(base)
|
|
1430
1433
|
except Exception:
|
|
1431
|
-
|
|
1434
|
+
diagnostics.swallowed("android.TextInputHandler._apply")
|
|
1432
1435
|
if "max_length" in props and props["max_length"] is not None:
|
|
1433
1436
|
try:
|
|
1434
1437
|
InputFilter = jclass("android.text.InputFilter$LengthFilter")
|
|
1435
1438
|
et.setFilters([InputFilter(int(props["max_length"]))])
|
|
1436
1439
|
except Exception:
|
|
1437
|
-
|
|
1440
|
+
diagnostics.swallowed("android.TextInputHandler._apply")
|
|
1438
1441
|
if "auto_focus" in props and props["auto_focus"]:
|
|
1439
1442
|
try:
|
|
1440
1443
|
et.requestFocus()
|
|
1441
1444
|
except Exception:
|
|
1442
|
-
|
|
1445
|
+
diagnostics.swallowed("android.TextInputHandler._apply")
|
|
1443
1446
|
if "editable" in props:
|
|
1444
1447
|
# ``editable`` is only present when ``False`` (read-only); a
|
|
1445
1448
|
# removal (``None``) restores editing. We keep the field
|
|
@@ -1452,12 +1455,12 @@ class TextInputHandler(AndroidViewHandler):
|
|
|
1452
1455
|
et.setCursorVisible(editable)
|
|
1453
1456
|
et.setLongClickable(editable)
|
|
1454
1457
|
except Exception:
|
|
1455
|
-
|
|
1458
|
+
diagnostics.swallowed("android.TextInputHandler._apply")
|
|
1456
1459
|
if "selection_color" in props and props["selection_color"] is not None:
|
|
1457
1460
|
try:
|
|
1458
1461
|
et.setHighlightColor(parse_color_int(props["selection_color"]))
|
|
1459
1462
|
except Exception:
|
|
1460
|
-
|
|
1463
|
+
diagnostics.swallowed("android.TextInputHandler._apply")
|
|
1461
1464
|
if "text_content_type" in props and props["text_content_type"] is not None:
|
|
1462
1465
|
self._apply_autofill(et, str(props["text_content_type"]))
|
|
1463
1466
|
if "clear_button" in props:
|
|
@@ -1485,7 +1488,7 @@ class TextInputHandler(AndroidViewHandler):
|
|
|
1485
1488
|
action = rkt_mapping.get(props["return_key_type"], EditorInfo.IME_ACTION_DONE)
|
|
1486
1489
|
et.setImeOptions(action)
|
|
1487
1490
|
except Exception:
|
|
1488
|
-
|
|
1491
|
+
diagnostics.swallowed("android.TextInputHandler._apply")
|
|
1489
1492
|
if initial or "multiline" in props:
|
|
1490
1493
|
self._apply_editor_action(et)
|
|
1491
1494
|
_apply_common_visual(et, props)
|
|
@@ -1514,7 +1517,9 @@ class TextInputHandler(AndroidViewHandler):
|
|
|
1514
1517
|
try:
|
|
1515
1518
|
_fire(view, "on_submit", str(view.getText()))
|
|
1516
1519
|
except Exception:
|
|
1517
|
-
|
|
1520
|
+
diagnostics.swallowed(
|
|
1521
|
+
"android.TextInputHandler._apply_editor_action.SubmitProxy.onEditorAction"
|
|
1522
|
+
)
|
|
1518
1523
|
if not multiline:
|
|
1519
1524
|
try:
|
|
1520
1525
|
view.clearFocus()
|
|
@@ -1522,12 +1527,14 @@ class TextInputHandler(AndroidViewHandler):
|
|
|
1522
1527
|
imm = ctx.getSystemService(Context.INPUT_METHOD_SERVICE)
|
|
1523
1528
|
imm.hideSoftInputFromWindow(view.getWindowToken(), 0)
|
|
1524
1529
|
except Exception:
|
|
1525
|
-
|
|
1530
|
+
diagnostics.swallowed(
|
|
1531
|
+
"android.TextInputHandler._apply_editor_action.SubmitProxy.onEditorAction"
|
|
1532
|
+
)
|
|
1526
1533
|
return True
|
|
1527
1534
|
|
|
1528
1535
|
et.setOnEditorActionListener(SubmitProxy())
|
|
1529
1536
|
except Exception:
|
|
1530
|
-
|
|
1537
|
+
diagnostics.swallowed("android.TextInputHandler._apply_editor_action")
|
|
1531
1538
|
|
|
1532
1539
|
@staticmethod
|
|
1533
1540
|
def _autofill_hint(content_type: str) -> Optional[str]:
|
|
@@ -1559,7 +1566,7 @@ class TextInputHandler(AndroidViewHandler):
|
|
|
1559
1566
|
if hint:
|
|
1560
1567
|
et.setAutofillHints([hint])
|
|
1561
1568
|
except Exception:
|
|
1562
|
-
|
|
1569
|
+
diagnostics.swallowed("android.TextInputHandler._apply_autofill")
|
|
1563
1570
|
|
|
1564
1571
|
def _apply_clear_button(self, et: Any, enabled: bool) -> None:
|
|
1565
1572
|
# Best-effort drawableEnd "X": shows a system clear icon and wires
|
|
@@ -1588,12 +1595,12 @@ class TextInputHandler(AndroidViewHandler):
|
|
|
1588
1595
|
view.setText("")
|
|
1589
1596
|
return True
|
|
1590
1597
|
except Exception:
|
|
1591
|
-
|
|
1598
|
+
diagnostics.swallowed("android.TextInputHandler._apply_clear_button._ClearTouchProxy.onTouch")
|
|
1592
1599
|
return False
|
|
1593
1600
|
|
|
1594
1601
|
et.setOnTouchListener(_ClearTouchProxy())
|
|
1595
1602
|
except Exception:
|
|
1596
|
-
|
|
1603
|
+
diagnostics.swallowed("android.TextInputHandler._apply_clear_button")
|
|
1597
1604
|
|
|
1598
1605
|
|
|
1599
1606
|
class ImageHandler(AndroidViewHandler):
|
|
@@ -1606,12 +1613,12 @@ class ImageHandler(AndroidViewHandler):
|
|
|
1606
1613
|
ColorStateList = jclass("android.content.res.ColorStateList")
|
|
1607
1614
|
iv.setImageTintList(ColorStateList.valueOf(parse_color_int(props["tint_color"])))
|
|
1608
1615
|
except Exception:
|
|
1609
|
-
|
|
1616
|
+
diagnostics.swallowed("android.ImageHandler._apply")
|
|
1610
1617
|
if "placeholder_color" in props and props["placeholder_color"] is not None:
|
|
1611
1618
|
try:
|
|
1612
1619
|
iv.setBackgroundColor(parse_color_int(props["placeholder_color"]))
|
|
1613
1620
|
except Exception:
|
|
1614
|
-
|
|
1621
|
+
diagnostics.swallowed("android.ImageHandler._apply")
|
|
1615
1622
|
if "source" in props and props["source"]:
|
|
1616
1623
|
self._load_source(iv, str(props["source"]))
|
|
1617
1624
|
if "scale_type" in props and props["scale_type"]:
|
|
@@ -1648,7 +1655,7 @@ class ImageHandler(AndroidViewHandler):
|
|
|
1648
1655
|
iv.setImageBitmap(bitmap)
|
|
1649
1656
|
_fire(iv, "on_load")
|
|
1650
1657
|
except Exception:
|
|
1651
|
-
|
|
1658
|
+
diagnostics.swallowed("android.ImageHandler._load_source._on_ready")
|
|
1652
1659
|
|
|
1653
1660
|
def _on_error(message: str) -> None:
|
|
1654
1661
|
if _state_of(iv).get("pending_uri") == source:
|
|
@@ -1674,7 +1681,7 @@ class ImageHandler(AndroidViewHandler):
|
|
|
1674
1681
|
else:
|
|
1675
1682
|
_fire(iv, "on_error", f"drawable {res_name!r} not found")
|
|
1676
1683
|
except Exception:
|
|
1677
|
-
|
|
1684
|
+
diagnostics.swallowed("android.ImageHandler._load_source")
|
|
1678
1685
|
|
|
1679
1686
|
def _load_data_uri(self, iv: Any, source: str) -> None:
|
|
1680
1687
|
"""Decode an inline ``data:`` URI (base64 payload) into the view."""
|
|
@@ -1719,7 +1726,7 @@ class ImageHandler(AndroidViewHandler):
|
|
|
1719
1726
|
target_w = int(iv.getWidth())
|
|
1720
1727
|
target_h = int(iv.getHeight())
|
|
1721
1728
|
except Exception:
|
|
1722
|
-
|
|
1729
|
+
diagnostics.swallowed("android.ImageHandler._decode_downsampled")
|
|
1723
1730
|
if target_w <= 0:
|
|
1724
1731
|
try:
|
|
1725
1732
|
metrics = _ctx().getResources().getDisplayMetrics()
|
|
@@ -1780,7 +1787,7 @@ class ProgressBarHandler(AndroidViewHandler):
|
|
|
1780
1787
|
ColorStateList = jclass("android.content.res.ColorStateList")
|
|
1781
1788
|
pb.setProgressTintList(ColorStateList.valueOf(parse_color_int(props["color"])))
|
|
1782
1789
|
except Exception:
|
|
1783
|
-
|
|
1790
|
+
diagnostics.swallowed("android.ProgressBarHandler._apply")
|
|
1784
1791
|
if "track_color" in props and props["track_color"] is not None:
|
|
1785
1792
|
try:
|
|
1786
1793
|
ColorStateList = jclass("android.content.res.ColorStateList")
|
|
@@ -1788,12 +1795,12 @@ class ProgressBarHandler(AndroidViewHandler):
|
|
|
1788
1795
|
pb.setProgressBackgroundTintList(track)
|
|
1789
1796
|
pb.setSecondaryProgressTintList(track)
|
|
1790
1797
|
except Exception:
|
|
1791
|
-
|
|
1798
|
+
diagnostics.swallowed("android.ProgressBarHandler._apply")
|
|
1792
1799
|
if "indeterminate" in props:
|
|
1793
1800
|
try:
|
|
1794
1801
|
pb.setIndeterminate(bool(props["indeterminate"]))
|
|
1795
1802
|
except Exception:
|
|
1796
|
-
|
|
1803
|
+
diagnostics.swallowed("android.ProgressBarHandler._apply")
|
|
1797
1804
|
|
|
1798
1805
|
|
|
1799
1806
|
class ActivityIndicatorHandler(AndroidViewHandler):
|
|
@@ -1809,7 +1816,7 @@ class ActivityIndicatorHandler(AndroidViewHandler):
|
|
|
1809
1816
|
ColorStateList = jclass("android.content.res.ColorStateList")
|
|
1810
1817
|
pb.setIndeterminateTintList(ColorStateList.valueOf(parse_color_int(props["color"])))
|
|
1811
1818
|
except Exception:
|
|
1812
|
-
|
|
1819
|
+
diagnostics.swallowed("android.ActivityIndicatorHandler._apply")
|
|
1813
1820
|
if "size" in props and props["size"] is not None:
|
|
1814
1821
|
# The framework ProgressBar has no runtime size switch, so
|
|
1815
1822
|
# approximate "large" by scaling the indeterminate drawable.
|
|
@@ -1818,7 +1825,7 @@ class ActivityIndicatorHandler(AndroidViewHandler):
|
|
|
1818
1825
|
pb.setScaleX(scale)
|
|
1819
1826
|
pb.setScaleY(scale)
|
|
1820
1827
|
except Exception:
|
|
1821
|
-
|
|
1828
|
+
diagnostics.swallowed("android.ActivityIndicatorHandler._apply")
|
|
1822
1829
|
|
|
1823
1830
|
|
|
1824
1831
|
def _make_web_client(wv: Any) -> Any:
|
|
@@ -1854,13 +1861,13 @@ def _make_web_client(wv: Any) -> Any:
|
|
|
1854
1861
|
)
|
|
1855
1862
|
view.evaluateJavascript(shim, None)
|
|
1856
1863
|
except Exception:
|
|
1857
|
-
|
|
1864
|
+
diagnostics.swallowed("android._make_web_client._WebClientProxy.onPageFinished")
|
|
1858
1865
|
inject_js = (_state_of(wv).get("props") or {}).get("inject_javascript")
|
|
1859
1866
|
if inject_js:
|
|
1860
1867
|
try:
|
|
1861
1868
|
view.evaluateJavascript(str(inject_js), None)
|
|
1862
1869
|
except Exception:
|
|
1863
|
-
|
|
1870
|
+
diagnostics.swallowed("android._make_web_client._WebClientProxy.onPageFinished")
|
|
1864
1871
|
|
|
1865
1872
|
def shouldOverrideUrlLoading(self, view: Any, request: Any) -> bool:
|
|
1866
1873
|
try:
|
|
@@ -1873,7 +1880,7 @@ def _make_web_client(wv: Any) -> Any:
|
|
|
1873
1880
|
|
|
1874
1881
|
_fire(wv, "on_message", unquote(url[len(scheme) :]))
|
|
1875
1882
|
except Exception:
|
|
1876
|
-
|
|
1883
|
+
diagnostics.swallowed("android._make_web_client._WebClientProxy.shouldOverrideUrlLoading")
|
|
1877
1884
|
return True
|
|
1878
1885
|
return False
|
|
1879
1886
|
|
|
@@ -1893,7 +1900,7 @@ class WebViewHandler(AndroidViewHandler):
|
|
|
1893
1900
|
try:
|
|
1894
1901
|
wv.getSettings().setJavaScriptEnabled(True)
|
|
1895
1902
|
except Exception:
|
|
1896
|
-
|
|
1903
|
+
diagnostics.swallowed("android.WebViewHandler._apply")
|
|
1897
1904
|
|
|
1898
1905
|
if initial:
|
|
1899
1906
|
client = _make_web_client(wv)
|
|
@@ -1901,19 +1908,19 @@ class WebViewHandler(AndroidViewHandler):
|
|
|
1901
1908
|
try:
|
|
1902
1909
|
wv.setWebViewClient(client)
|
|
1903
1910
|
except Exception:
|
|
1904
|
-
|
|
1911
|
+
diagnostics.swallowed("android.WebViewHandler._apply")
|
|
1905
1912
|
|
|
1906
1913
|
# ``html`` takes precedence over ``url`` when both are present.
|
|
1907
1914
|
if "html" in props and props["html"]:
|
|
1908
1915
|
try:
|
|
1909
1916
|
wv.loadDataWithBaseURL(None, str(props["html"]), "text/html", "utf-8", None)
|
|
1910
1917
|
except Exception:
|
|
1911
|
-
|
|
1918
|
+
diagnostics.swallowed("android.WebViewHandler._apply")
|
|
1912
1919
|
elif "url" in props and props["url"]:
|
|
1913
1920
|
try:
|
|
1914
1921
|
wv.loadUrl(str(props["url"]))
|
|
1915
1922
|
except Exception:
|
|
1916
|
-
|
|
1923
|
+
diagnostics.swallowed("android.WebViewHandler._apply")
|
|
1917
1924
|
|
|
1918
1925
|
if "scroll_enabled" in props:
|
|
1919
1926
|
self._apply_scroll_enabled(wv, props["scroll_enabled"])
|
|
@@ -1930,7 +1937,7 @@ class WebViewHandler(AndroidViewHandler):
|
|
|
1930
1937
|
else:
|
|
1931
1938
|
wv.setOnTouchListener(None)
|
|
1932
1939
|
except Exception:
|
|
1933
|
-
|
|
1940
|
+
diagnostics.swallowed("android.WebViewHandler._apply_scroll_enabled")
|
|
1934
1941
|
|
|
1935
1942
|
|
|
1936
1943
|
class SpacerHandler(AndroidViewHandler):
|
|
@@ -1995,7 +2002,7 @@ class ModalHandler(AndroidViewHandler):
|
|
|
1995
2002
|
try:
|
|
1996
2003
|
dialog.setCanceledOnTouchOutside(props["dismiss_on_backdrop"] is not False)
|
|
1997
2004
|
except Exception:
|
|
1998
|
-
|
|
2005
|
+
diagnostics.swallowed("android.ModalHandler._apply")
|
|
1999
2006
|
|
|
2000
2007
|
def insert_child(self, parent: Any, child: Any, index: int) -> None:
|
|
2001
2008
|
state = _state_of(parent)
|
|
@@ -2012,7 +2019,7 @@ class ModalHandler(AndroidViewHandler):
|
|
|
2012
2019
|
try:
|
|
2013
2020
|
content.removeView(child)
|
|
2014
2021
|
except Exception:
|
|
2015
|
-
|
|
2022
|
+
diagnostics.swallowed("android.ModalHandler.remove_child")
|
|
2016
2023
|
else:
|
|
2017
2024
|
buf = state.get("pending")
|
|
2018
2025
|
if buf and child in buf:
|
|
@@ -2057,18 +2064,18 @@ class ModalHandler(AndroidViewHandler):
|
|
|
2057
2064
|
WMLP = jclass("android.view.WindowManager$LayoutParams")
|
|
2058
2065
|
window.setLayout(WMLP.MATCH_PARENT, WMLP.MATCH_PARENT)
|
|
2059
2066
|
except Exception:
|
|
2060
|
-
|
|
2067
|
+
diagnostics.swallowed("android.ModalHandler._present")
|
|
2061
2068
|
try:
|
|
2062
2069
|
dialog.setCanceledOnTouchOutside(props.get("dismiss_on_backdrop") is not False)
|
|
2063
2070
|
except Exception:
|
|
2064
|
-
|
|
2071
|
+
diagnostics.swallowed("android.ModalHandler._present")
|
|
2065
2072
|
state["dialog"] = dialog
|
|
2066
2073
|
state["content_view"] = content
|
|
2067
2074
|
for child in state.pop("pending", []):
|
|
2068
2075
|
try:
|
|
2069
2076
|
content.addView(child)
|
|
2070
2077
|
except Exception:
|
|
2071
|
-
|
|
2078
|
+
diagnostics.swallowed("android.ModalHandler._present")
|
|
2072
2079
|
|
|
2073
2080
|
OnShowListener = jclass("android.content.DialogInterface$OnShowListener")
|
|
2074
2081
|
|
|
@@ -2087,7 +2094,7 @@ class ModalHandler(AndroidViewHandler):
|
|
|
2087
2094
|
dialog.setOnDismissListener(_DismissProxy())
|
|
2088
2095
|
dialog.show()
|
|
2089
2096
|
except Exception:
|
|
2090
|
-
|
|
2097
|
+
diagnostics.swallowed("android.ModalHandler._present")
|
|
2091
2098
|
|
|
2092
2099
|
def _dismiss(self, placeholder: Any, state: Dict[str, Any]) -> None:
|
|
2093
2100
|
dialog = state.pop("dialog", None)
|
|
@@ -2096,7 +2103,7 @@ class ModalHandler(AndroidViewHandler):
|
|
|
2096
2103
|
try:
|
|
2097
2104
|
dialog.dismiss()
|
|
2098
2105
|
except Exception:
|
|
2099
|
-
|
|
2106
|
+
diagnostics.swallowed("android.ModalHandler._dismiss")
|
|
2100
2107
|
|
|
2101
2108
|
|
|
2102
2109
|
# ======================================================================
|
|
@@ -2148,7 +2155,7 @@ class PortalHandler(AndroidViewHandler):
|
|
|
2148
2155
|
lp = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
|
2149
2156
|
container.addView(overlay, lp)
|
|
2150
2157
|
except Exception:
|
|
2151
|
-
|
|
2158
|
+
diagnostics.swallowed("android.PortalHandler._ensure_attached")
|
|
2152
2159
|
|
|
2153
2160
|
def insert_child(self, parent: Any, child: Any, index: int) -> None:
|
|
2154
2161
|
self._ensure_attached(parent)
|
|
@@ -2158,7 +2165,7 @@ class PortalHandler(AndroidViewHandler):
|
|
|
2158
2165
|
try:
|
|
2159
2166
|
parent.removeView(child)
|
|
2160
2167
|
except Exception:
|
|
2161
|
-
|
|
2168
|
+
diagnostics.swallowed("android.PortalHandler.remove_child")
|
|
2162
2169
|
|
|
2163
2170
|
def set_frame(self, native_view: Any, x: float, y: float, width: float, height: float) -> None:
|
|
2164
2171
|
# The overlay fills its container via MATCH_PARENT layout params;
|
|
@@ -2171,7 +2178,7 @@ class PortalHandler(AndroidViewHandler):
|
|
|
2171
2178
|
if parent is not None:
|
|
2172
2179
|
parent.removeView(overlay)
|
|
2173
2180
|
except Exception:
|
|
2174
|
-
|
|
2181
|
+
diagnostics.swallowed("android.PortalHandler._teardown")
|
|
2175
2182
|
|
|
2176
2183
|
|
|
2177
2184
|
class SliderHandler(AndroidViewHandler):
|
|
@@ -2225,7 +2232,7 @@ class TabBarHandler(AndroidViewHandler):
|
|
|
2225
2232
|
try:
|
|
2226
2233
|
bnv.setLabelVisibilityMode(self._LABEL_VISIBILITY_LABELED)
|
|
2227
2234
|
except Exception:
|
|
2228
|
-
|
|
2235
|
+
diagnostics.swallowed("android.TabBarHandler._build")
|
|
2229
2236
|
return bnv
|
|
2230
2237
|
except Exception:
|
|
2231
2238
|
LinearLayout = jclass("android.widget.LinearLayout")
|
|
@@ -2275,7 +2282,7 @@ class TabBarHandler(AndroidViewHandler):
|
|
|
2275
2282
|
|
|
2276
2283
|
bnv.setOnItemSelectedListener(_TabSelectProxy())
|
|
2277
2284
|
except Exception:
|
|
2278
|
-
|
|
2285
|
+
diagnostics.swallowed("android.TabBarHandler._bind_material_listener")
|
|
2279
2286
|
|
|
2280
2287
|
def _set_menu(self, bnv: Any, items: list) -> None:
|
|
2281
2288
|
try:
|
|
@@ -2289,9 +2296,9 @@ class TabBarHandler(AndroidViewHandler):
|
|
|
2289
2296
|
try:
|
|
2290
2297
|
menu_item.setIcon(res_id)
|
|
2291
2298
|
except Exception:
|
|
2292
|
-
|
|
2299
|
+
diagnostics.swallowed("android.TabBarHandler._set_menu")
|
|
2293
2300
|
except Exception:
|
|
2294
|
-
|
|
2301
|
+
diagnostics.swallowed("android.TabBarHandler._set_menu")
|
|
2295
2302
|
|
|
2296
2303
|
def _resolve_icon(self, icon: Any) -> int:
|
|
2297
2304
|
"""Resolve a tab icon spec to an `android.R.drawable.*` res id.
|
|
@@ -2325,7 +2332,7 @@ class TabBarHandler(AndroidViewHandler):
|
|
|
2325
2332
|
try:
|
|
2326
2333
|
bnv.setSelectedItemId(i)
|
|
2327
2334
|
except Exception:
|
|
2328
|
-
|
|
2335
|
+
diagnostics.swallowed("android.TabBarHandler._set_active")
|
|
2329
2336
|
break
|
|
2330
2337
|
|
|
2331
2338
|
def _apply_fallback(self, ll: Any, props: Dict[str, Any]) -> None:
|
|
@@ -2425,7 +2432,9 @@ class PressableHandler(FlexContainerHandler):
|
|
|
2425
2432
|
try:
|
|
2426
2433
|
view.animate().alpha(opacity).setDuration(50).start()
|
|
2427
2434
|
except Exception:
|
|
2428
|
-
|
|
2435
|
+
diagnostics.swallowed(
|
|
2436
|
+
"android.PressableHandler._bind_press_stream._PressTouchProxy.onTouch"
|
|
2437
|
+
)
|
|
2429
2438
|
if _has_event(view, "on_long_press"):
|
|
2430
2439
|
seq = press["seq"]
|
|
2431
2440
|
|
|
@@ -2456,7 +2465,9 @@ class PressableHandler(FlexContainerHandler):
|
|
|
2456
2465
|
try:
|
|
2457
2466
|
view.animate().alpha(1.0).setDuration(100).start()
|
|
2458
2467
|
except Exception:
|
|
2459
|
-
|
|
2468
|
+
diagnostics.swallowed(
|
|
2469
|
+
"android.PressableHandler._bind_press_stream._PressTouchProxy.onTouch"
|
|
2470
|
+
)
|
|
2460
2471
|
if action == 1 and not press["moved"] and not press["long_fired"]:
|
|
2461
2472
|
_fire(view, "on_press")
|
|
2462
2473
|
return True
|
|
@@ -2464,7 +2475,7 @@ class PressableHandler(FlexContainerHandler):
|
|
|
2464
2475
|
|
|
2465
2476
|
fl.setOnTouchListener(_PressTouchProxy())
|
|
2466
2477
|
except Exception:
|
|
2467
|
-
|
|
2478
|
+
diagnostics.swallowed("android.PressableHandler._bind_press_stream")
|
|
2468
2479
|
|
|
2469
2480
|
|
|
2470
2481
|
# ======================================================================
|
|
@@ -2491,20 +2502,29 @@ class StatusBarHandler(AndroidViewHandler):
|
|
|
2491
2502
|
return
|
|
2492
2503
|
if "background_color" in props and props["background_color"] is not None:
|
|
2493
2504
|
window.setStatusBarColor(parse_color_int(props["background_color"]))
|
|
2505
|
+
View = jclass("android.view.View")
|
|
2506
|
+
decor = window.getDecorView()
|
|
2494
2507
|
if "bar_style" in props and props["bar_style"] is not None:
|
|
2495
2508
|
# API 23+: setSystemUiVisibility with SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
|
2496
2509
|
# for dark-content (light backgrounds), 0 for light-content.
|
|
2497
|
-
View = jclass("android.view.View")
|
|
2498
2510
|
bar_style = props["bar_style"]
|
|
2499
|
-
decor = window.getDecorView()
|
|
2500
2511
|
flags = decor.getSystemUiVisibility()
|
|
2501
2512
|
if bar_style in ("dark", "default"):
|
|
2502
2513
|
flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
|
2503
2514
|
else:
|
|
2504
2515
|
flags &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
|
2505
2516
|
decor.setSystemUiVisibility(flags)
|
|
2506
|
-
|
|
2507
|
-
|
|
2517
|
+
if "hidden" in props and props["hidden"] is not None:
|
|
2518
|
+
flags = decor.getSystemUiVisibility()
|
|
2519
|
+
if props["hidden"]:
|
|
2520
|
+
flags |= View.SYSTEM_UI_FLAG_FULLSCREEN
|
|
2521
|
+
else:
|
|
2522
|
+
flags &= ~View.SYSTEM_UI_FLAG_FULLSCREEN
|
|
2523
|
+
decor.setSystemUiVisibility(flags)
|
|
2524
|
+
except Exception as exc:
|
|
2525
|
+
from .. import diagnostics
|
|
2526
|
+
|
|
2527
|
+
diagnostics.warn_once(f"StatusBar: could not apply props on Android: {exc!r}")
|
|
2508
2528
|
|
|
2509
2529
|
|
|
2510
2530
|
class KeyboardAvoidingViewHandler(FlexContainerHandler):
|
|
@@ -2552,7 +2572,7 @@ def _present_alert(
|
|
|
2552
2572
|
try:
|
|
2553
2573
|
on_result(index)
|
|
2554
2574
|
except Exception:
|
|
2555
|
-
|
|
2575
|
+
diagnostics.swallowed("android._present_alert._deliver")
|
|
2556
2576
|
|
|
2557
2577
|
def _present_on_main() -> None:
|
|
2558
2578
|
try:
|
|
@@ -2738,7 +2758,7 @@ class CheckboxHandler(AndroidViewHandler):
|
|
|
2738
2758
|
ColorStateList = jclass("android.content.res.ColorStateList")
|
|
2739
2759
|
cb.setButtonTintList(ColorStateList.valueOf(parse_color_int(props["color"])))
|
|
2740
2760
|
except Exception:
|
|
2741
|
-
|
|
2761
|
+
diagnostics.swallowed("android.CheckboxHandler._apply")
|
|
2742
2762
|
_apply_accessibility(cb, props)
|
|
2743
2763
|
|
|
2744
2764
|
|
|
@@ -2798,7 +2818,7 @@ class SegmentedControlHandler(AndroidViewHandler):
|
|
|
2798
2818
|
try:
|
|
2799
2819
|
ll.removeAllViews()
|
|
2800
2820
|
except Exception:
|
|
2801
|
-
|
|
2821
|
+
diagnostics.swallowed("android.SegmentedControlHandler._rebuild")
|
|
2802
2822
|
state["buttons"] = []
|
|
2803
2823
|
LL_LP = jclass("android.widget.LinearLayout$LayoutParams")
|
|
2804
2824
|
restyle = self._restyle
|
|
@@ -2808,7 +2828,7 @@ class SegmentedControlHandler(AndroidViewHandler):
|
|
|
2808
2828
|
try:
|
|
2809
2829
|
btn.setAllCaps(False)
|
|
2810
2830
|
except Exception:
|
|
2811
|
-
|
|
2831
|
+
diagnostics.swallowed("android.SegmentedControlHandler._rebuild")
|
|
2812
2832
|
# Equal-width segments: zero base width + weight 1, full height.
|
|
2813
2833
|
btn.setLayoutParams(LL_LP(0, LL_LP.MATCH_PARENT, 1.0))
|
|
2814
2834
|
enabled = (state.get("props") or {}).get("enabled") is not False
|
|
@@ -2856,7 +2876,7 @@ class SegmentedControlHandler(AndroidViewHandler):
|
|
|
2856
2876
|
btn.setBackground(drawable)
|
|
2857
2877
|
btn.setEnabled(enabled)
|
|
2858
2878
|
except Exception:
|
|
2859
|
-
|
|
2879
|
+
diagnostics.swallowed("android.SegmentedControlHandler._style_segment")
|
|
2860
2880
|
|
|
2861
2881
|
def measure_intrinsic(
|
|
2862
2882
|
self,
|
|
@@ -2911,7 +2931,7 @@ class DatePickerHandler(AndroidViewHandler):
|
|
|
2911
2931
|
try:
|
|
2912
2932
|
btn.setAllCaps(False)
|
|
2913
2933
|
except Exception:
|
|
2914
|
-
|
|
2934
|
+
diagnostics.swallowed("android.DatePickerHandler._build")
|
|
2915
2935
|
open_dialog = self._open_dialog
|
|
2916
2936
|
|
|
2917
2937
|
class _DateTriggerProxy(dynamic_proxy(jclass("android.view.View").OnClickListener)):
|
|
@@ -3021,7 +3041,7 @@ class DatePickerHandler(AndroidViewHandler):
|
|
|
3021
3041
|
if maximum:
|
|
3022
3042
|
picker.setMaxDate(self._parse_to_calendar(maximum, mode).getTimeInMillis())
|
|
3023
3043
|
except Exception:
|
|
3024
|
-
|
|
3044
|
+
diagnostics.swallowed("android.DatePickerHandler._apply_min_max")
|
|
3025
3045
|
|
|
3026
3046
|
def _parse_to_calendar(self, value: Any, mode: str) -> Any:
|
|
3027
3047
|
Calendar = jclass("java.util.Calendar")
|
|
@@ -3033,7 +3053,7 @@ class DatePickerHandler(AndroidViewHandler):
|
|
|
3033
3053
|
fmt = SimpleDateFormat(self._PATTERNS.get(mode, self._PATTERNS["date"]), Locale.US)
|
|
3034
3054
|
cal.setTime(fmt.parse(str(value)))
|
|
3035
3055
|
except Exception:
|
|
3036
|
-
|
|
3056
|
+
diagnostics.swallowed("android.DatePickerHandler._parse_to_calendar")
|
|
3037
3057
|
return cal
|
|
3038
3058
|
|
|
3039
3059
|
def _format_calendar(self, cal: Any, mode: str) -> str:
|
|
@@ -3053,7 +3073,7 @@ class DatePickerHandler(AndroidViewHandler):
|
|
|
3053
3073
|
try:
|
|
3054
3074
|
btn.setText(iso)
|
|
3055
3075
|
except Exception:
|
|
3056
|
-
|
|
3076
|
+
diagnostics.swallowed("android.DatePickerHandler._commit")
|
|
3057
3077
|
_fire(btn, "on_change", iso)
|
|
3058
3078
|
|
|
3059
3079
|
|
|
@@ -3153,7 +3173,7 @@ class VirtualListHandler(AndroidViewHandler):
|
|
|
3153
3173
|
try:
|
|
3154
3174
|
info["pool"].release(_java_id(container))
|
|
3155
3175
|
except Exception:
|
|
3156
|
-
|
|
3176
|
+
diagnostics.swallowed("android.VirtualListHandler._build._Delegate.onRowRecycled")
|
|
3157
3177
|
|
|
3158
3178
|
def onScrolled(self, offset_dp: float, extent_dp: float, range_dp: float) -> None:
|
|
3159
3179
|
view = info.get("view")
|
|
@@ -3202,12 +3222,12 @@ class VirtualListHandler(AndroidViewHandler):
|
|
|
3202
3222
|
try:
|
|
3203
3223
|
view.setVerticalScrollBarEnabled(show)
|
|
3204
3224
|
except Exception:
|
|
3205
|
-
|
|
3225
|
+
diagnostics.swallowed("android.VirtualListHandler._apply")
|
|
3206
3226
|
if data_changed and not initial:
|
|
3207
3227
|
try:
|
|
3208
3228
|
view.notifyDataChanged()
|
|
3209
3229
|
except Exception:
|
|
3210
|
-
|
|
3230
|
+
diagnostics.swallowed("android.VirtualListHandler._apply")
|
|
3211
3231
|
|
|
3212
3232
|
def _teardown(self, native_view: Any) -> None:
|
|
3213
3233
|
info = _pn_vlist_info.pop(_java_id(native_view), None)
|
|
@@ -3238,7 +3258,7 @@ class VirtualListHandler(AndroidViewHandler):
|
|
|
3238
3258
|
args.get("animated", True) is not False,
|
|
3239
3259
|
)
|
|
3240
3260
|
except Exception:
|
|
3241
|
-
|
|
3261
|
+
diagnostics.swallowed("android.VirtualListHandler.command")
|
|
3242
3262
|
return None
|
|
3243
3263
|
if name == "scroll_to_index":
|
|
3244
3264
|
try:
|
|
@@ -3247,7 +3267,7 @@ class VirtualListHandler(AndroidViewHandler):
|
|
|
3247
3267
|
args.get("animated", True) is not False,
|
|
3248
3268
|
)
|
|
3249
3269
|
except Exception:
|
|
3250
|
-
|
|
3270
|
+
diagnostics.swallowed("android.VirtualListHandler.command")
|
|
3251
3271
|
return None
|
|
3252
3272
|
if name == "scroll_to_end":
|
|
3253
3273
|
info = _pn_vlist_info.get(_java_id(native_view))
|
|
@@ -3255,7 +3275,7 @@ class VirtualListHandler(AndroidViewHandler):
|
|
|
3255
3275
|
try:
|
|
3256
3276
|
native_view.scrollToIndex(max(0, count - 1), args.get("animated", True) is not False)
|
|
3257
3277
|
except Exception:
|
|
3258
|
-
|
|
3278
|
+
diagnostics.swallowed("android.VirtualListHandler.command")
|
|
3259
3279
|
return None
|
|
3260
3280
|
if name == "get_scroll_offset":
|
|
3261
3281
|
try:
|