Page MenuHomePhorge

D364.1790598078.diff
No OneTemporary

Size
6 KB
Referenced Files
None
Subscribers
None

D364.1790598078.diff

diff --git a/src/contents/ui/RoomPage.qml b/src/contents/ui/RoomPage.qml
--- a/src/contents/ui/RoomPage.qml
+++ b/src/contents/ui/RoomPage.qml
@@ -4,14 +4,14 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
-import QtQuick 2.2
-import QtQuick.Layouts 1.15
-import QtQuick.Controls 2.15
-import QtQuick.Window 2.15
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls
+import QtQuick.Window
import Qt.labs.platform as Platform
-import org.kde.kirigami 2.13 as Kirigami
-import moe.kazv.mxc.kazv 0.0 as MK
+import org.kde.kirigami as Kirigami
+import moe.kazv.mxc.kazv as MK
import '.' as Kazv
import 'matrix-helpers.js' as Helpers
@@ -186,36 +186,51 @@
uploadList.model = kazvIOManager.getUploadJobs(roomId)
}
- footer: Item {
- height: childrenRect.height
+ footer: Control {
width: parent.width
+ topPadding: 0
+ // SafeArea covers systemBars|displayCutout only; corner radius
+ // comes from KazvUtil (0 on desktop / pre-API-31).
+ property real roundedInset: MK.KazvUtil.androidRoundedCornerInset
+ // (1-cos45°)R clears the corner; full R overpads ~3.4x.
+ property real cornerPad: roundedInset * 0.293
+ leftPadding: Math.max(parent.SafeArea.margins.left,
+ Kirigami.Units.largeSpacing, cornerPad)
+ rightPadding: Math.max(parent.SafeArea.margins.right,
+ Kirigami.Units.largeSpacing, cornerPad)
+ bottomPadding: Math.max(parent.SafeArea.margins.bottom,
+ cornerPad) + Kirigami.Units.largeSpacing
+ background: Rectangle {
+ color: Kirigami.Theme.backgroundColor
+ }
- ListView {
- id: uploadList
- width: parent.width
- height: contentHeight
- model: kazvIOManager.getUploadJobs(roomId)
- delegate: Kazv.KazvIOMenu {
- width: parent.width
- jobId: roomId
- isUpload: true
+ contentItem: ColumnLayout {
+ spacing: 0
+ ListView {
+ id: uploadList
+ Layout.fillWidth: true
+ Layout.preferredHeight: contentHeight
+ model: kazvIOManager.getUploadJobs(roomId)
+ delegate: Kazv.KazvIOMenu {
+ width: parent.width
+ jobId: roomId
+ isUpload: true
+ }
}
- }
- Kazv.TypingIndicator {
- id: typingIndicator
- typingUsers: roomPage.room.typingUsers()
- width: parent.width
- anchors.top: uploadList.bottom
- }
+ Kazv.TypingIndicator {
+ id: typingIndicator
+ typingUsers: roomPage.room.typingUsers()
+ Layout.fillWidth: true
+ }
- Kazv.SendMessageBox {
- id: sendMessageBox
- objectName: 'sendMessageBox'
- width: parent.width
- room: roomPage.room
- anchors.top: typingIndicator.bottom
- enabled: isJoin
+ Kazv.SendMessageBox {
+ id: sendMessageBox
+ objectName: 'sendMessageBox'
+ Layout.fillWidth: true
+ room: roomPage.room
+ enabled: isJoin
+ }
}
}
diff --git a/src/kazv-util.hpp b/src/kazv-util.hpp
--- a/src/kazv-util.hpp
+++ b/src/kazv-util.hpp
@@ -20,11 +20,19 @@
QML_SINGLETON
Q_PROPERTY(int kfQtMajorVersion CONSTANT MEMBER m_kfQtMajorVersion)
+ Q_PROPERTY(qreal androidRoundedCornerInset READ androidRoundedCornerInset
+ NOTIFY androidRoundedCornerInsetChanged)
public:
KazvUtil(QObject *parent = 0);
~KazvUtil() override;
+ /// Max Android physical rounded-corner radius in dp (logical px).
+ /// 0 on non-Android, pre-API-31, or when unavailable.
+ /// Query WindowInsets.getRoundedCorner() on the Android UI thread.
+ qreal androidRoundedCornerInset() const;
+ Q_SIGNAL void androidRoundedCornerInsetChanged();
+
public Q_SLOTS:
QString escapeHtml(const QString &orig) const;
QString mimeTypeForUrl(const QUrl &url) const;
diff --git a/src/kazv-util.cpp b/src/kazv-util.cpp
--- a/src/kazv-util.cpp
+++ b/src/kazv-util.cpp
@@ -12,6 +12,12 @@
#include "matrix-link.hpp"
#include "kazv-util.hpp"
+#ifdef Q_OS_ANDROID
+#include <QFuture>
+#include <QJniObject>
+#include <QVariant>
+#endif
+
KazvUtil::KazvUtil(QObject *parent)
: QObject(parent)
, m_kfQtMajorVersion(KAZV_KF_QT_MAJOR_VERSION)
@@ -42,3 +48,82 @@
{
return new MatrixLink(QUrl(url));
}
+
+qreal KazvUtil::androidRoundedCornerInset() const
+{
+#ifdef Q_OS_ANDROID
+ // RoundedCorner API needs API 31+. QAndroidApplication::sdkVersion()
+ // wraps Build.VERSION.SDK_INT.
+ if (QNativeInterface::QAndroidApplication::sdkVersion() < 31) {
+ return 0.0;
+ }
+
+ // Must query View/WindowInsets on the Android UI thread.
+ auto fetchInset = []() -> QVariant {
+ const QJniObject activity =
+ QNativeInterface::QAndroidApplication::context();
+ if (!activity.isValid()) {
+ return QVariant(0.0);
+ }
+ const QJniObject window = activity.callObjectMethod(
+ "getWindow", "()Landroid/view/Window;");
+ if (!window.isValid()) {
+ return QVariant(0.0);
+ }
+ const QJniObject decorView = window.callObjectMethod(
+ "getDecorView", "()Landroid/view/View;");
+ if (!decorView.isValid()) {
+ return QVariant(0.0);
+ }
+ const QJniObject insets = decorView.callObjectMethod(
+ "getRootWindowInsets", "()Landroid/view/WindowInsets;");
+ if (!insets.isValid()) {
+ return QVariant(0.0);
+ }
+
+ int maxRadiusPx = 0;
+ // RoundedCorner positions: TOP_LEFT=0, TOP_RIGHT=1,
+ // BOTTOM_RIGHT=2, BOTTOM_LEFT=3
+ for (int pos = 0; pos < 4; ++pos) {
+ const QJniObject corner = insets.callObjectMethod(
+ "getRoundedCorner", "(I)Landroid/view/RoundedCorner;", pos);
+ if (!corner.isValid()) {
+ continue;
+ }
+ const int radius = corner.callMethod<jint>("getRadius", "()I");
+ if (radius > maxRadiusPx) {
+ maxRadiusPx = radius;
+ }
+ }
+ if (maxRadiusPx <= 0) {
+ return QVariant(0.0);
+ }
+
+ // getRadius() is in physical px; QML uses dp. Convert via density.
+ float density = 1.0f;
+ const QJniObject resources = activity.callObjectMethod(
+ "getResources", "()Landroid/content/res/Resources;");
+ if (!resources.isValid()) {
+ return QVariant(static_cast<double>(maxRadiusPx) / density);
+ }
+ const QJniObject metrics = resources.callObjectMethod(
+ "getDisplayMetrics", "()Landroid/util/DisplayMetrics;");
+ if (!metrics.isValid()) {
+ return QVariant(static_cast<double>(maxRadiusPx) / density);
+ }
+ const float d = metrics.getField<float>("density");
+ if (d > 0) {
+ density = d;
+ }
+ return QVariant(static_cast<double>(maxRadiusPx) / density);
+ };
+ QFuture<QVariant> future =
+ QNativeInterface::QAndroidApplication::runOnAndroidMainThread(
+ fetchInset);
+
+ future.waitForFinished();
+ return future.result().toReal();
+#else
+ return 0.0;
+#endif
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Sep 28, 5:21 AM (22 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1778651
Default Alt Text
D364.1790598078.diff (6 KB)

Event Timeline