mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-05-08 14:33:23 +00:00
fix: black screen resume / pause (#2400)
This commit is contained in:
@@ -343,12 +343,22 @@ class AmneziaActivity : QtActivity() {
|
|||||||
resumeHandler.removeCallbacksAndMessages(null)
|
resumeHandler.removeCallbacksAndMessages(null)
|
||||||
openFileDeliveryScheduled = false
|
openFileDeliveryScheduled = false
|
||||||
Log.d(TAG, "Pause Amnezia activity")
|
Log.d(TAG, "Pause Amnezia activity")
|
||||||
|
// Notify Qt to stop rendering before the EGL surface is disconnected
|
||||||
|
mainScope.launch {
|
||||||
|
qtInitialized.await()
|
||||||
|
QtAndroidController.onActivityPaused()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
isActivityResumed = true
|
isActivityResumed = true
|
||||||
Log.d(TAG, "Resume Amnezia activity")
|
Log.d(TAG, "Resume Amnezia activity")
|
||||||
|
// Notify Qt to resume rendering after surface reconnects
|
||||||
|
mainScope.launch {
|
||||||
|
qtInitialized.await()
|
||||||
|
QtAndroidController.onActivityResumed()
|
||||||
|
}
|
||||||
|
|
||||||
if (pendingOpenFileUri != null && !openFileDeliveryScheduled) {
|
if (pendingOpenFileUri != null && !openFileDeliveryScheduled) {
|
||||||
val uri = pendingOpenFileUri!!
|
val uri = pendingOpenFileUri!!
|
||||||
|
|||||||
@@ -31,4 +31,7 @@ object QtAndroidController {
|
|||||||
|
|
||||||
external fun onImeInsetsChanged(heightDp: Int)
|
external fun onImeInsetsChanged(heightDp: Int)
|
||||||
external fun onSystemBarsInsetsChanged(navBarHeightDp: Int, statusBarHeightDp: Int)
|
external fun onSystemBarsInsetsChanged(navBarHeightDp: Int, statusBarHeightDp: Int)
|
||||||
|
|
||||||
|
external fun onActivityPaused()
|
||||||
|
external fun onActivityResumed()
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,9 @@ bool AndroidController::initialize()
|
|||||||
{"onAuthResult", "(Z)V", reinterpret_cast<void *>(onAuthResult)},
|
{"onAuthResult", "(Z)V", reinterpret_cast<void *>(onAuthResult)},
|
||||||
{"decodeQrCode", "(Ljava/lang/String;)Z", reinterpret_cast<bool *>(decodeQrCode)},
|
{"decodeQrCode", "(Ljava/lang/String;)Z", reinterpret_cast<bool *>(decodeQrCode)},
|
||||||
{"onImeInsetsChanged", "(I)V", reinterpret_cast<void *>(onImeInsetsChanged)},
|
{"onImeInsetsChanged", "(I)V", reinterpret_cast<void *>(onImeInsetsChanged)},
|
||||||
{"onSystemBarsInsetsChanged", "(II)V", reinterpret_cast<void *>(onSystemBarsInsetsChanged)}
|
{"onSystemBarsInsetsChanged", "(II)V", reinterpret_cast<void *>(onSystemBarsInsetsChanged)},
|
||||||
|
{"onActivityPaused", "()V", reinterpret_cast<void *>(onActivityPaused)},
|
||||||
|
{"onActivityResumed", "()V", reinterpret_cast<void *>(onActivityResumed)}
|
||||||
};
|
};
|
||||||
|
|
||||||
QJniEnvironment env;
|
QJniEnvironment env;
|
||||||
@@ -558,3 +560,22 @@ void AndroidController::onSystemBarsInsetsChanged(JNIEnv *env, jobject thiz, jin
|
|||||||
emit AndroidController::instance()->systemBarsInsetsChanged(navBarHeightDp, statusBarHeightDp);
|
emit AndroidController::instance()->systemBarsInsetsChanged(navBarHeightDp, statusBarHeightDp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void AndroidController::onActivityPaused(JNIEnv *env, jobject thiz)
|
||||||
|
{
|
||||||
|
Q_UNUSED(env);
|
||||||
|
Q_UNUSED(thiz);
|
||||||
|
|
||||||
|
emit AndroidController::instance()->activityPaused();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void AndroidController::onActivityResumed(JNIEnv *env, jobject thiz)
|
||||||
|
{
|
||||||
|
Q_UNUSED(env);
|
||||||
|
Q_UNUSED(thiz);
|
||||||
|
|
||||||
|
emit AndroidController::instance()->activityResumed();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ signals:
|
|||||||
void authenticationResult(bool result);
|
void authenticationResult(bool result);
|
||||||
void imeInsetsChanged(int heightDp);
|
void imeInsetsChanged(int heightDp);
|
||||||
void systemBarsInsetsChanged(int navBarHeightDp, int statusBarHeightDp);
|
void systemBarsInsetsChanged(int navBarHeightDp, int statusBarHeightDp);
|
||||||
|
void activityPaused();
|
||||||
|
void activityResumed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isWaitingStatus = true;
|
bool isWaitingStatus = true;
|
||||||
@@ -105,6 +107,8 @@ private:
|
|||||||
static bool decodeQrCode(JNIEnv *env, jobject thiz, jstring data);
|
static bool decodeQrCode(JNIEnv *env, jobject thiz, jstring data);
|
||||||
static void onImeInsetsChanged(JNIEnv *env, jobject thiz, jint heightDp);
|
static void onImeInsetsChanged(JNIEnv *env, jobject thiz, jint heightDp);
|
||||||
static void onSystemBarsInsetsChanged(JNIEnv *env, jobject thiz, jint navBarHeightDp, jint statusBarHeightDp);
|
static void onSystemBarsInsetsChanged(JNIEnv *env, jobject thiz, jint navBarHeightDp, jint statusBarHeightDp);
|
||||||
|
static void onActivityPaused(JNIEnv *env, jobject thiz);
|
||||||
|
static void onActivityResumed(JNIEnv *env, jobject thiz);
|
||||||
|
|
||||||
template <typename Ret, typename ...Args>
|
template <typename Ret, typename ...Args>
|
||||||
static auto callActivityMethod(const char *methodName, const char *signature, Args &&...args);
|
static auto callActivityMethod(const char *methodName, const char *signature, Args &&...args);
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ SettingsController::SettingsController(const QSharedPointer<ServersModel> &serve
|
|||||||
emit safeAreaBottomMarginChanged();
|
emit safeAreaBottomMarginChanged();
|
||||||
emit safeAreaTopMarginChanged();
|
emit safeAreaTopMarginChanged();
|
||||||
});
|
});
|
||||||
|
connect(AndroidController::instance(), &AndroidController::activityPaused, this, &SettingsController::activityPaused);
|
||||||
|
connect(AndroidController::instance(), &AndroidController::activityResumed, this, &SettingsController::activityResumed);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_isDevModeEnabled = m_settings->isDevGatewayEnv();
|
m_isDevModeEnabled = m_settings->isDevGatewayEnv();
|
||||||
|
|||||||
@@ -141,6 +141,9 @@ signals:
|
|||||||
void safeAreaTopMarginChanged();
|
void safeAreaTopMarginChanged();
|
||||||
void safeAreaBottomMarginChanged();
|
void safeAreaBottomMarginChanged();
|
||||||
|
|
||||||
|
void activityPaused();
|
||||||
|
void activityResumed();
|
||||||
|
|
||||||
void isHomeAdLabelVisibleChanged(bool visible);
|
void isHomeAdLabelVisibleChanged(bool visible);
|
||||||
void startMinimizedChanged();
|
void startMinimizedChanged();
|
||||||
|
|
||||||
|
|||||||
@@ -23,17 +23,25 @@ Window {
|
|||||||
if (Qt.application.state === Qt.ApplicationActive) {
|
if (Qt.application.state === Qt.ApplicationActive) {
|
||||||
root.visible = true
|
root.visible = true
|
||||||
refreshTimer.restart()
|
refreshTimer.restart()
|
||||||
} else if (Qt.application.state === Qt.ApplicationSuspended) {
|
|
||||||
// Hide window to stop the Qt render loop and prevent
|
|
||||||
// eglSwapBuffers from being called on a lost EGL context.
|
|
||||||
// NOTE: Do NOT hide on ApplicationInactive — that fires on any
|
|
||||||
// focus change (IME, notifications) and would blank the screen.
|
|
||||||
root.visible = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hide the window immediately when Android Activity.onPause() fires so that
|
||||||
|
// Qt's render loop stops before the EGL surface is disconnected. This
|
||||||
|
// prevents "QRhiGles2: Failed to make context current" and the resulting
|
||||||
|
// black screen that appears after swiping home and returning.
|
||||||
|
Connections {
|
||||||
|
target: SettingsController
|
||||||
|
function onActivityPaused() {
|
||||||
|
if (Qt.platform.os === "android") root.visible = false
|
||||||
|
}
|
||||||
|
function onActivityResumed() {
|
||||||
|
if (Qt.platform.os === "android") root.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: refreshTimer
|
id: refreshTimer
|
||||||
interval: 150
|
interval: 150
|
||||||
|
|||||||
Reference in New Issue
Block a user