4package org.qtproject.qt.android;
6import android.annotation.SuppressLint;
7import android.app.ActionBar;
8import android.app.Activity;
9import android.content.Context;
10import android.content.res.TypedArray;
11import android.graphics.Insets;
13import android.view.DisplayCutout;
14import android.view.GestureDetector;
15import android.view.MotionEvent;
16import android.view.Surface;
17import android.view.View;
18import android.view.ViewGroup;
19import android.view.ViewTreeObserver;
20import android.view.Window;
21import android.view.WindowInsets;
22import android.view.WindowInsetsController;
23import android.os.Build;
25import java.util.HashMap;
27@SuppressLint(
"ViewConstructor")
29 private View m_surfaceContainer;
30 private View m_nativeView;
31 private final HashMap<Integer, QtWindow> m_childWindows =
new HashMap<>();
32 private QtWindow m_parentWindow;
33 private GestureDetector m_gestureDetector;
34 private final QtEditText m_editText;
36 private boolean m_firstSafeMarginsDelivered =
false;
37 private int m_actionBarHeight = -1;
39 private static native
void setSurface(
int windowId, Surface surface);
40 private static native
void safeAreaMarginsChanged(Insets insets,
int id);
41 static native
void windowFocusChanged(
boolean hasFocus,
int id);
44 QtWindow(
Context context,
boolean isForeignWindow, QtWindow parentWindow,
45 QtInputConnection.QtInputConnectionListener listener)
48 setId(View.generateViewId());
49 m_inputConnectionListener = listener;
51 setFocusableInTouchMode(
true);
52 setDefaultFocusHighlightEnabled(
false);
53 setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
62 if (!isForeignWindow &&
context instanceof Activity) {
64 m_editText =
new QtEditText(
context, listener);
65 m_editText.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
66 LayoutParams layoutParams =
new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
67 ViewGroup.LayoutParams.WRAP_CONTENT);
68 QtNative.runAction(() -> addView(m_editText, layoutParams));
75 new GestureDetector(
context,
new GestureDetector.SimpleOnGestureListener() {
77 public void onLongPress(MotionEvent event) {
78 QtInputDelegate.longPress(getId(), (int) event.getX(), (int) event.getY());
81 m_gestureDetector.setIsLongpressEnabled(
true);
84 registerSafeAreaMarginsListener();
87 void registerSafeAreaMarginsListener()
92 setOnApplyWindowInsetsListener((
view, insets) -> {
93 WindowInsets windowInsets =
view.onApplyWindowInsets(insets);
94 reportSafeAreaMargins(windowInsets, getId());
100 if (isAttachedToWindow()) {
101 WindowInsets insets = getRootWindowInsets();
102 if (insets !=
null) {
103 getRootView().post(() -> reportSafeAreaMargins(insets, getId()));
104 m_firstSafeMarginsDelivered =
true;
107 addOnAttachStateChangeListener(
new View.OnAttachStateChangeListener() {
109 public void onViewAttachedToWindow(View view) {
110 view.removeOnAttachStateChangeListener(this);
111 view.requestApplyInsets();
115 public void onViewDetachedFromWindow(View
view) {}
120 if (!m_firstSafeMarginsDelivered) {
121 ViewTreeObserver.OnPreDrawListener listener =
new ViewTreeObserver.OnPreDrawListener() {
123 public boolean onPreDraw() {
124 if (isAttachedToWindow()) {
125 WindowInsets insets = getRootWindowInsets();
126 if (insets !=
null) {
127 getViewTreeObserver().removeOnPreDrawListener(
this);
128 getRootView().post(() -> reportSafeAreaMargins(insets, getId()));
129 m_firstSafeMarginsDelivered =
true;
134 requestApplyInsets();
139 getViewTreeObserver().addOnPreDrawListener(listener);
142 addOnLayoutChangeListener((
view, l,
t,
r,
b, oldl, oldt, oldr, oldb) -> {
143 WindowInsets insets = getRootWindowInsets();
145 getRootView().post(() -> reportSafeAreaMargins(insets, getId()));
149 @SuppressWarnings(
"deprecation")
150 Insets getSafeInsets(
View view, WindowInsets insets)
152 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
153 int types = WindowInsets.Type.displayCutout() | WindowInsets.Type.systemBars();
154 return insets.getInsets(types);
158 int left = insets.getSystemWindowInsetLeft();
159 int top = insets.getSystemWindowInsetTop();
160 int right = insets.getSystemWindowInsetRight();
161 int bottom = insets.getSystemWindowInsetBottom();
165 DisplayCutout cutout = insets.getDisplayCutout();
166 if (cutout !=
null) {
167 left = Math.max(
left, cutout.getSafeInsetLeft());
168 top = Math.max(
top, cutout.getSafeInsetTop());
169 right = Math.max(
right, cutout.getSafeInsetRight());
177 ActionBar actionBar = ((Activity) getContext()).getActionBar();
178 if (actionBar ==
null || !actionBar.isShowing()) {
179 int topWithoutActionBar = top - actionBarHeight();
180 if (topWithoutActionBar > 0)
181 top = topWithoutActionBar;
187 private void reportSafeAreaMargins(WindowInsets insets,
int id)
189 View rootView = getRootView();
191 int[] rootLocation =
new int[2];
192 rootView.getLocationOnScreen(rootLocation);
193 int rootX = rootLocation[0];
194 int rootY = rootLocation[1];
196 int[] windowLocation =
new int[2];
197 getLocationOnScreen(windowLocation);
198 int windowX = windowLocation[0];
199 int windowY = windowLocation[1];
203 int topOffset = windowY - rootY;
204 int rightOffset = (rootX + rootView.getWidth()) - (windowX + getWidth());
205 int bottomOffset = (rootY + rootView.getHeight()) - (windowY + getHeight());
208 Insets safeInsets = getSafeInsets(rootView, insets);
209 int left = Math.max(0, Math.min(safeInsets.left, safeInsets.left -
leftOffset));
210 int top = Math.max(0, Math.min(safeInsets.top, safeInsets.top - topOffset));
211 int right = Math.max(0, Math.min(safeInsets.right, safeInsets.right -
rightOffset));
212 int bottom = Math.max(0, Math.min(safeInsets.bottom, safeInsets.bottom - bottomOffset));
217 private int actionBarHeight()
219 if (m_actionBarHeight == -1) {
220 TypedArray ta = getContext().getTheme().obtainStyledAttributes(
221 new int[] { android.R.attr.actionBarSize });
223 m_actionBarHeight = ta.getDimensionPixelSize(0, 0);
228 return m_actionBarHeight;
233 QtNative.runAction(() -> setVisibility(visible ?
View.VISIBLE :
View.INVISIBLE));
237 public void onSurfaceChanged(Surface surface)
239 setSurface(getId(), surface);
243 public boolean onTouchEvent(MotionEvent
event)
245 windowFocusChanged(
true, getId());
246 if (m_editText !=
null && m_inputConnectionListener !=
null)
247 m_inputConnectionListener.onEditTextChanged(m_editText);
249 QtInputDelegate.sendTouchEvent(
event, getId());
250 m_gestureDetector.onTouchEvent(
event);
255 public boolean onTrackballEvent(MotionEvent
event)
257 QtInputDelegate.sendTrackballEvent(
event, getId());
262 public boolean onGenericMotionEvent(MotionEvent
event)
264 return QtInputDelegate.sendGenericMotionEvent(
event, getId());
270 if (m_parentWindow !=
null)
271 m_parentWindow.removeChildWindow(getId());
275 void createSurface(
final boolean onTop,
276 final int imageDepth,
final boolean isOpaque,
277 final int surfaceContainerType)
279 QtNative.runAction(()-> {
280 if (m_surfaceContainer !=
null)
281 removeView(m_surfaceContainer);
283 if (surfaceContainerType == 0) {
284 m_surfaceContainer =
new QtSurface(getContext(), QtWindow.this,
287 m_surfaceContainer =
new QtTextureView(getContext(), QtWindow.this, isOpaque);
289 m_surfaceContainer.setLayoutParams(
new QtLayout.LayoutParams(
290 ViewGroup.LayoutParams.MATCH_PARENT,
291 ViewGroup.LayoutParams.MATCH_PARENT));
294 addView(m_surfaceContainer, 0);
299 void destroySurface()
301 QtNative.runAction(()-> {
302 if (m_surfaceContainer !=
null) {
303 removeView(m_surfaceContainer);
304 m_surfaceContainer =
null;
310 void setGeometry(
final int x,
final int y,
final int w,
final int h)
312 QtNative.runAction(()-> {
313 if (getContext() instanceof QtActivityBase)
314 setLayoutParams(
new QtLayout.LayoutParams(
w,
h,
x,
y));
318 void addChildWindow(QtWindow
window)
320 QtNative.runAction(()-> {
322 addView(
window, getChildCount());
326 void removeChildWindow(
int id)
328 QtNative.runAction(()-> {
329 if (m_childWindows.containsKey(
id))
330 removeView(m_childWindows.remove(
id));
337 QtNative.runAction(()-> {
338 if (m_nativeView !=
null)
339 removeView(m_nativeView);
342 m_nativeView.setLayoutParams(
new QtLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
343 ViewGroup.LayoutParams.MATCH_PARENT));
344 addView(m_nativeView);
349 void bringChildToFront(
int id)
351 QtNative.runAction(()-> {
354 if (getChildCount() > 0)
355 moveChild(
view, getChildCount() - 1);
361 void bringChildToBack(
int id) {
362 QtNative.runAction(()-> {
371 void removeNativeView()
373 QtNative.runAction(()-> {
374 if (m_nativeView !=
null) {
375 removeView(m_nativeView);
383 if (m_parentWindow == parentWindow)
386 if (m_parentWindow !=
null)
387 m_parentWindow.removeChildWindow(getId());
389 m_parentWindow = parentWindow;
390 if (m_parentWindow !=
null)
391 m_parentWindow.addChildWindow(
this);
395 void updateFocusedEditText()
397 if (m_editText !=
null && m_inputConnectionListener !=
null)
398 m_inputConnectionListener.onEditTextChanged(m_editText);
memberSheet setVisible(index, false)
static const QString context()
static const double leftOffset
static const double rightOffset
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
GLfloat GLfloat GLfloat w
[0]
GLdouble GLdouble GLdouble GLdouble top
GLfloat GLfloat GLfloat GLfloat h
static bool onTop(QWaylandQuickShellSurfaceItem *surf)
file setParent(multiPart)
if(foo.startsWith("("+type+") 0x")) ... QString hello("hello")
[0]