Skip to content

Commit 92e7281

Browse files
authored
Merge branch 'topjohnwu:master' into meta-quest-zygisk-fix
2 parents ef099a7 + a5bca88 commit 92e7281

83 files changed

Lines changed: 1262 additions & 698 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Guidelines and instructions for AI models and automated agents operating in the
2525

2626
## 4. Guidelines for AI Models
2727

28-
1. **Git / Commit Control:** NEVER commit changes or amend an existing git commit without the user's explicit request or approval. When explicitly requested to commit changes, follow the 50/72 rule for commit messages (subject line <= 50 characters, blank line before body, wrap body lines at 72 characters) and include an `Assisted-by: <ModelVersion>` trailer in the commit message body (using a pretty name, e.g., `Assisted-by: Gemini 3.6 Flash`).
28+
1. **Git / Commit Control:** NEVER commit changes or amend an existing git commit without the user's explicit request or approval. When explicitly requested to commit changes, follow the 50/72 rule for commit messages (subject line <= 50 characters, blank line before body, wrap body lines at 72 characters) and include an `Assisted-by: <Friendly Name of Current Model>` trailer in the commit message body.
2929
2. **Build Invocation:** Execute `./build.py <command>` directly without `scripts/env.py`. Prefix standalone tool executions (like `./gradlew` or raw `cargo`) with `scripts/env.py`.
3030
3. **Pre-build Native Code:** Before modifying code in `native/`, build native binaries at least once with `./build.py native` to generate required bindings and header files.
3131
4. **App Subproject Context:** Refer to [`app/AGENTS.md`](app/AGENTS.md) when working inside the `app/` subproject.

app/AGENTS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# AGENTS.md (app subproject)
22

3-
Guidelines for AI models operating inside the `app/` subproject.
3+
Guidelines for AI models operating inside the `app/` subproject. Always include and follow the top-level [`AGENTS.md`](../AGENTS.md).
44

55
## 1. Environment & Gradle Setup
66

7+
- **General Guidelines:** Always follow the top-level [`AGENTS.md`](../AGENTS.md) for general repository rules, environment execution setup, and commit control policies.
78
- **Working Directory:** Set working directory to `app/` when working on app code.
89
- **Environment Wrapper:** Standalone `./gradlew` commands MUST be prefixed with `../scripts/env.py` (e.g., `../scripts/env.py ./gradlew assembleDebug`), or run `./build.py app` from root.
910

app/apk-ng/src/main/java/com/topjohnwu/magisk/ui/MagiskTheme.kt

Lines changed: 147 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ package com.topjohnwu.magisk.ui
22

33
import android.os.Build
44
import androidx.compose.foundation.isSystemInDarkTheme
5+
import androidx.compose.foundation.shape.RoundedCornerShape
56
import androidx.compose.material3.MaterialTheme
7+
import androidx.compose.material3.Shapes
8+
import androidx.compose.material3.Typography
69
import androidx.compose.material3.darkColorScheme
710
import androidx.compose.material3.dynamicDarkColorScheme
811
import androidx.compose.material3.dynamicLightColorScheme
@@ -11,13 +14,152 @@ import androidx.compose.runtime.Composable
1114
import androidx.compose.runtime.getValue
1215
import androidx.compose.runtime.mutableIntStateOf
1316
import androidx.compose.runtime.setValue
17+
import androidx.compose.ui.graphics.Color
1418
import androidx.compose.ui.platform.LocalContext
19+
import androidx.compose.ui.text.TextStyle
20+
import androidx.compose.ui.text.font.FontWeight
21+
import androidx.compose.ui.unit.dp
22+
import androidx.compose.ui.unit.sp
1523
import com.topjohnwu.magisk.core.Config
1624

25+
private val MagiskLightColorScheme = lightColorScheme(
26+
primary = Color(0xFF006A5E),
27+
onPrimary = Color(0xFFFFFFFF),
28+
primaryContainer = Color(0xFF70F7E2),
29+
onPrimaryContainer = Color(0xFF00201C),
30+
secondary = Color(0xFF4A635E),
31+
onSecondary = Color(0xFFFFFFFF),
32+
secondaryContainer = Color(0xFFCCE8E1),
33+
onSecondaryContainer = Color(0xFF05201B),
34+
tertiary = Color(0xFF456179),
35+
onTertiary = Color(0xFFFFFFFF),
36+
tertiaryContainer = Color(0xFFCCE5FF),
37+
onTertiaryContainer = Color(0xFF001E31),
38+
error = Color(0xFFBA1A1A),
39+
onError = Color(0xFFFFFFFF),
40+
errorContainer = Color(0xFFFFDAD6),
41+
onErrorContainer = Color(0xFF410002),
42+
background = Color(0xFFFAFDFB),
43+
onBackground = Color(0xFF191C1B),
44+
surface = Color(0xFFFAFDFB),
45+
onSurface = Color(0xFF191C1B),
46+
surfaceVariant = Color(0xFFDAE5E1),
47+
onSurfaceVariant = Color(0xFF3F4946),
48+
outline = Color(0xFF6F7976),
49+
outlineVariant = Color(0xFFBFC9C5),
50+
)
51+
52+
private val MagiskDarkColorScheme = darkColorScheme(
53+
primary = Color(0xFF51DBC6),
54+
onPrimary = Color(0xFF003730),
55+
primaryContainer = Color(0xFF005047),
56+
onPrimaryContainer = Color(0xFF70F7E2),
57+
secondary = Color(0xFFB1CCC6),
58+
onSecondary = Color(0xFF1C3530),
59+
secondaryContainer = Color(0xFF334B46),
60+
onSecondaryContainer = Color(0xFFCCE8E1),
61+
tertiary = Color(0xFFAEC9E6),
62+
onTertiary = Color(0xFF143349),
63+
tertiaryContainer = Color(0xFF2D4960),
64+
onTertiaryContainer = Color(0xFFCCE5FF),
65+
error = Color(0xFFFFB4AB),
66+
onError = Color(0xFF690005),
67+
errorContainer = Color(0xFF93000A),
68+
onErrorContainer = Color(0xFFFFDAD6),
69+
background = Color(0xFF191C1B),
70+
onBackground = Color(0xFFE0E3E1),
71+
surface = Color(0xFF191C1B),
72+
onSurface = Color(0xFFE0E3E1),
73+
surfaceVariant = Color(0xFF3F4946),
74+
onSurfaceVariant = Color(0xFFBFC9C5),
75+
outline = Color(0xFF899390),
76+
outlineVariant = Color(0xFF3F4946),
77+
)
78+
1779
object ThemeState {
1880
var colorMode by mutableIntStateOf(Config.colorMode)
1981
}
2082

83+
val MagiskShapes = Shapes(
84+
extraSmall = RoundedCornerShape(6.dp),
85+
small = RoundedCornerShape(10.dp),
86+
medium = RoundedCornerShape(16.dp),
87+
large = RoundedCornerShape(24.dp),
88+
extraLarge = RoundedCornerShape(32.dp),
89+
)
90+
91+
val MagiskTypography = Typography(
92+
headlineLarge = TextStyle(
93+
fontWeight = FontWeight.SemiBold,
94+
fontSize = 32.sp,
95+
lineHeight = 40.sp,
96+
letterSpacing = (-0.25).sp,
97+
),
98+
headlineMedium = TextStyle(
99+
fontWeight = FontWeight.SemiBold,
100+
fontSize = 28.sp,
101+
lineHeight = 36.sp,
102+
),
103+
headlineSmall = TextStyle(
104+
fontWeight = FontWeight.SemiBold,
105+
fontSize = 24.sp,
106+
lineHeight = 32.sp,
107+
),
108+
titleLarge = TextStyle(
109+
fontWeight = FontWeight.SemiBold,
110+
fontSize = 20.sp,
111+
lineHeight = 26.sp,
112+
),
113+
titleMedium = TextStyle(
114+
fontWeight = FontWeight.SemiBold,
115+
fontSize = 16.sp,
116+
lineHeight = 24.sp,
117+
letterSpacing = 0.15.sp,
118+
),
119+
titleSmall = TextStyle(
120+
fontWeight = FontWeight.Medium,
121+
fontSize = 14.sp,
122+
lineHeight = 20.sp,
123+
letterSpacing = 0.1.sp,
124+
),
125+
bodyLarge = TextStyle(
126+
fontWeight = FontWeight.Normal,
127+
fontSize = 16.sp,
128+
lineHeight = 24.sp,
129+
letterSpacing = 0.5.sp,
130+
),
131+
bodyMedium = TextStyle(
132+
fontWeight = FontWeight.Normal,
133+
fontSize = 14.sp,
134+
lineHeight = 20.sp,
135+
letterSpacing = 0.25.sp,
136+
),
137+
bodySmall = TextStyle(
138+
fontWeight = FontWeight.Normal,
139+
fontSize = 12.sp,
140+
lineHeight = 16.sp,
141+
letterSpacing = 0.4.sp,
142+
),
143+
labelLarge = TextStyle(
144+
fontWeight = FontWeight.SemiBold,
145+
fontSize = 14.sp,
146+
lineHeight = 20.sp,
147+
letterSpacing = 0.1.sp,
148+
),
149+
labelMedium = TextStyle(
150+
fontWeight = FontWeight.Medium,
151+
fontSize = 12.sp,
152+
lineHeight = 16.sp,
153+
letterSpacing = 0.5.sp,
154+
),
155+
labelSmall = TextStyle(
156+
fontWeight = FontWeight.Medium,
157+
fontSize = 11.sp,
158+
lineHeight = 16.sp,
159+
letterSpacing = 0.5.sp,
160+
),
161+
)
162+
21163
@Composable
22164
fun MagiskTheme(
23165
content: @Composable () -> Unit
@@ -40,12 +182,14 @@ fun MagiskTheme(
40182
val colorScheme = when {
41183
useDynamicColor && isDarkTheme -> dynamicDarkColorScheme(context)
42184
useDynamicColor && !isDarkTheme -> dynamicLightColorScheme(context)
43-
isDarkTheme -> darkColorScheme()
44-
else -> lightColorScheme()
185+
isDarkTheme -> MagiskDarkColorScheme
186+
else -> MagiskLightColorScheme
45187
}
46188

47189
MaterialTheme(
48190
colorScheme = colorScheme,
191+
shapes = MagiskShapes,
192+
typography = MagiskTypography,
49193
content = content
50194
)
51-
}
195+
}

app/apk-ng/src/main/java/com/topjohnwu/magisk/ui/MainScreen.kt

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package com.topjohnwu.magisk.ui
22

33
import androidx.compose.animation.animateColorAsState
4+
import androidx.compose.animation.core.Spring
5+
import androidx.compose.animation.core.animateDpAsState
6+
import androidx.compose.animation.core.animateFloatAsState
7+
import androidx.compose.animation.core.spring
48
import androidx.compose.animation.core.tween
59
import androidx.compose.foundation.background
610
import androidx.compose.foundation.clickable
7-
import androidx.compose.foundation.interaction.MutableInteractionSource
811
import androidx.compose.foundation.layout.Arrangement
912
import androidx.compose.foundation.layout.Box
1013
import androidx.compose.foundation.layout.Column
@@ -18,9 +21,11 @@ import androidx.compose.foundation.layout.height
1821
import androidx.compose.foundation.layout.navigationBars
1922
import androidx.compose.foundation.layout.padding
2023
import androidx.compose.foundation.layout.size
24+
import androidx.compose.foundation.layout.width
2125
import androidx.compose.foundation.pager.HorizontalPager
2226
import androidx.compose.foundation.pager.PagerState
2327
import androidx.compose.foundation.pager.rememberPagerState
28+
import androidx.compose.foundation.shape.CircleShape
2429
import androidx.compose.foundation.shape.RoundedCornerShape
2530
import androidx.compose.material3.Icon
2631
import androidx.compose.material3.MaterialTheme
@@ -33,14 +38,16 @@ import androidx.compose.runtime.rememberCoroutineScope
3338
import androidx.compose.ui.Alignment
3439
import androidx.compose.ui.Modifier
3540
import androidx.compose.ui.draw.clip
41+
import androidx.compose.ui.draw.scale
3642
import androidx.compose.ui.draw.shadow
43+
import androidx.compose.ui.graphics.Color
3744
import androidx.compose.ui.graphics.vector.ImageVector
3845
import androidx.activity.compose.LocalActivity
3946
import androidx.compose.ui.res.stringResource
4047
import androidx.compose.ui.res.vectorResource
4148
import androidx.compose.ui.semantics.Role
49+
import androidx.compose.ui.text.font.FontWeight
4250
import androidx.compose.ui.unit.dp
43-
import androidx.compose.ui.unit.sp
4451
import androidx.lifecycle.viewmodel.compose.viewModel
4552
import com.topjohnwu.magisk.R
4653
import com.topjohnwu.magisk.arch.VMFactory
@@ -152,18 +159,18 @@ private fun FloatingNavigationBar(
152159
modifier: Modifier = Modifier
153160
) {
154161
val scope = rememberCoroutineScope()
155-
val shape = RoundedCornerShape(28.dp)
162+
val shape = RoundedCornerShape(32.dp)
156163
val navBarInset = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()
157164

158165
Row(
159166
modifier = modifier
160-
.padding(bottom = navBarInset + 12.dp, start = 24.dp, end = 24.dp)
161-
.shadow(elevation = 6.dp, shape = shape)
167+
.padding(bottom = navBarInset + 12.dp, start = 20.dp, end = 20.dp)
168+
.shadow(elevation = 8.dp, shape = shape)
162169
.clip(shape)
163170
.background(MaterialTheme.colorScheme.surfaceContainer)
164171
.fillMaxWidth()
165-
.height(64.dp)
166-
.padding(horizontal = 4.dp),
172+
.height(68.dp)
173+
.padding(horizontal = 6.dp, vertical = 6.dp),
167174
horizontalArrangement = Arrangement.SpaceEvenly,
168175
verticalAlignment = Alignment.CenterVertically
169176
) {
@@ -189,39 +196,80 @@ private fun FloatingNavItem(
189196
onClick: () -> Unit,
190197
modifier: Modifier = Modifier
191198
) {
192-
val contentColor by animateColorAsState(
199+
val indicatorColor by animateColorAsState(
200+
targetValue = if (selected) MaterialTheme.colorScheme.secondaryContainer else Color.Transparent,
201+
animationSpec = spring(dampingRatio = Spring.DampingRatioNoBouncy, stiffness = Spring.StiffnessMedium),
202+
label = "navIndicatorColor"
203+
)
204+
205+
val iconTint by animateColorAsState(
206+
targetValue = when {
207+
!enabled -> MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)
208+
selected -> MaterialTheme.colorScheme.onSecondaryContainer
209+
else -> MaterialTheme.colorScheme.onSurfaceVariant
210+
},
211+
animationSpec = tween(150),
212+
label = "navIconTint"
213+
)
214+
215+
val labelColor by animateColorAsState(
193216
targetValue = when {
194217
!enabled -> MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)
195-
selected -> MaterialTheme.colorScheme.primary
218+
selected -> MaterialTheme.colorScheme.onSurface
196219
else -> MaterialTheme.colorScheme.onSurfaceVariant
197220
},
198-
animationSpec = tween(200),
199-
label = "navItemColor"
221+
animationSpec = tween(150),
222+
label = "navLabelColor"
223+
)
224+
225+
val iconScale by animateFloatAsState(
226+
targetValue = if (selected) 1.08f else 1.0f,
227+
animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy, stiffness = Spring.StiffnessMedium),
228+
label = "navIconScale"
229+
)
230+
231+
val indicatorWidth by animateDpAsState(
232+
targetValue = if (selected) 48.dp else 24.dp,
233+
animationSpec = spring(dampingRatio = Spring.DampingRatioLowBouncy, stiffness = Spring.StiffnessMedium),
234+
label = "navIndicatorWidth"
200235
)
201236

202237
Column(
203238
modifier = modifier
239+
.clip(CircleShape)
204240
.clickable(
205241
enabled = enabled,
206-
indication = null,
207-
interactionSource = remember { MutableInteractionSource() },
208242
role = Role.Tab,
209243
onClick = onClick,
210-
),
244+
)
245+
.padding(vertical = 2.dp),
211246
horizontalAlignment = Alignment.CenterHorizontally,
212247
verticalArrangement = Arrangement.Center,
213248
) {
214-
Icon(
215-
imageVector = icon,
216-
contentDescription = label,
217-
modifier = Modifier.size(24.dp),
218-
tint = contentColor,
219-
)
249+
Box(
250+
modifier = Modifier
251+
.width(indicatorWidth)
252+
.height(28.dp)
253+
.clip(CircleShape)
254+
.background(indicatorColor),
255+
contentAlignment = Alignment.Center
256+
) {
257+
Icon(
258+
imageVector = icon,
259+
contentDescription = label,
260+
modifier = Modifier
261+
.size(22.dp)
262+
.scale(iconScale),
263+
tint = iconTint,
264+
)
265+
}
220266
Spacer(Modifier.height(2.dp))
221267
Text(
222268
text = label,
223-
fontSize = 11.sp,
224-
color = contentColor,
269+
style = MaterialTheme.typography.labelSmall,
270+
fontWeight = if (selected) FontWeight.SemiBold else FontWeight.Medium,
271+
color = labelColor,
272+
maxLines = 1,
225273
)
226274
}
227275
}

0 commit comments

Comments
 (0)