Compare commits

...

4 Commits

Author SHA1 Message Date
Zongle Wang
d7c16ecd42 Replace shortcut icons (#729) 2026-05-09 16:54:26 +08:00
Zongle Wang
63a68d43f2 Defer shortcut setup to MainActivity (#215) (#728) 2026-05-09 16:13:13 +08:00
wwqgtxx
1d42dfa477 disable futex_time64 again 2026-05-09 00:07:33 +08:00
wwqgtxx
a097966eee remove already applied patch file for go1.26.3 2026-05-08 00:38:34 +08:00
7 changed files with 106 additions and 111 deletions

View File

@@ -1,56 +1,33 @@
Subject: [PATCH] remove 64bits syscall on 32bit linux
From bef1938b64a444911de119db613e60b9078ddd81 Mon Sep 17 00:00:00 2001
From: wwqgtxx <wwqgtxx@gmail.com>
Date: Sat, 9 May 2026 00:05:48 +0800
Subject: [PATCH] Disable futex_time64 again
---
Index: src/runtime/os_linux32.go
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
src/runtime/os_linux32.go | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/runtime/os_linux32.go b/src/runtime/os_linux32.go
--- a/src/runtime/os_linux32.go (revision 030384681641464bf71ed16500075c458363510f)
+++ b/src/runtime/os_linux32.go (date 1771666707318)
@@ -21,14 +21,14 @@
index 1ee1cdcaf90051..4aa42132d73739 100644
--- a/src/runtime/os_linux32.go
+++ b/src/runtime/os_linux32.go
@@ -24,9 +24,6 @@ var use64bitsTimeOn32bits bool
//go:nosplit
func futex(addr unsafe.Pointer, op int32, val uint32, ts *timespec, addr2 unsafe.Pointer, val3 uint32) int32 {
- if !isFutexTime32bitOnly.Load() {
- ret := futex_time64(addr, op, val, ts, addr2, val3)
- // futex_time64 is only supported on Linux 5.0+
- if ret != -_ENOSYS {
- return ret
- }
- isFutexTime32bitOnly.Store(true)
- if use64bitsTimeOn32bits {
- return futex_time64(addr, op, val, ts, addr2, val3)
- }
+ //if !isFutexTime32bitOnly.Load() {
+ // ret := futex_time64(addr, op, val, ts, addr2, val3)
+ // // futex_time64 is only supported on Linux 5.0+
+ // if ret != -_ENOSYS {
+ // return ret
+ // }
+ // isFutexTime32bitOnly.Store(true)
+ //}
// Downgrade ts.
var ts32 timespec32
var pts32 *timespec32
@@ -49,14 +49,14 @@
@@ -45,9 +42,6 @@ func timer_settime64(timerid int32, flags int32, new, old *itimerspec) int32
//go:nosplit
func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32 {
- if !isSetTime32bitOnly.Load() {
- ret := timer_settime64(timerid, flags, new, old)
- // timer_settime64 is only supported on Linux 5.0+
- if ret != -_ENOSYS {
- return ret
- }
- isSetTime32bitOnly.Store(true)
- if use64bitsTimeOn32bits {
- return timer_settime64(timerid, flags, new, old)
- }
+ //if !isSetTime32bitOnly.Load() {
+ // ret := timer_settime64(timerid, flags, new, old)
+ // // timer_settime64 is only supported on Linux 5.0+
+ // if ret != -_ENOSYS {
+ // return ret
+ // }
+ // isSetTime32bitOnly.Store(true)
+ //}
var newts, oldts itimerspec32
var new32, old32 *itimerspec32

View File

@@ -2,7 +2,6 @@ package com.github.kr328.clash
import android.content.ComponentName
import android.content.pm.PackageManager
import androidx.core.content.pm.ShortcutManagerCompat
import com.github.kr328.clash.common.util.componentName
import com.github.kr328.clash.design.AppSettingsDesign
import com.github.kr328.clash.design.model.Behavior
@@ -75,9 +74,5 @@ class AppSettingsActivity : BaseActivity<AppSettingsDesign>(), Behavior {
newState,
PackageManager.DONT_KILL_APP
)
if (hide) {
// Prevent launcher activity not found.
ShortcutManagerCompat.removeAllDynamicShortcuts(this)
}
}
}

View File

@@ -1,5 +1,6 @@
package com.github.kr328.clash
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
@@ -8,6 +9,10 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.drawable.IconCompat
import com.github.kr328.clash.common.constants.Intents
import com.github.kr328.clash.common.util.intent
import com.github.kr328.clash.common.util.ticker
import com.github.kr328.clash.design.MainDesign
@@ -22,7 +27,7 @@ import kotlinx.coroutines.isActive
import kotlinx.coroutines.selects.select
import kotlinx.coroutines.withContext
import java.util.concurrent.TimeUnit
import com.github.kr328.clash.design.R
import com.github.kr328.clash.design.R as DesignR
class MainActivity : BaseActivity<MainDesign>() {
override suspend fun main() {
@@ -111,8 +116,8 @@ class MainActivity : BaseActivity<MainDesign>() {
val active = withProfile { queryActive() }
if (active == null || !active.imported) {
showToast(R.string.no_profile_selected, ToastDuration.Long) {
setAction(R.string.profiles) {
showToast(DesignR.string.no_profile_selected, ToastDuration.Long) {
setAction(DesignR.string.profiles) {
startActivity(ProfilesActivity::class.intent)
}
}
@@ -133,7 +138,7 @@ class MainActivity : BaseActivity<MainDesign>() {
startClashService()
}
} catch (e: Exception) {
design?.showToast(R.string.unable_to_start_vpn, ToastDuration.Long)
design?.showToast(DesignR.string.unable_to_start_vpn, ToastDuration.Long)
}
}
@@ -157,5 +162,53 @@ class MainActivity : BaseActivity<MainDesign>() {
requestPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
}
}
setupShortcuts()
}
private fun setupShortcuts() {
// Skip dynamic shortcut setup when the app icon is hidden.
if (uiStore.hideAppIcon) return
val flags = Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS or
Intent.FLAG_ACTIVITY_NO_ANIMATION
val toggle = ShortcutInfoCompat.Builder(this, "toggle_clash")
.setShortLabel(getString(DesignR.string.shortcut_toggle_short))
.setLongLabel(getString(DesignR.string.shortcut_toggle_long))
.setIcon(IconCompat.createWithResource(this, R.drawable.ic_toggle_all))
.setIntent(
Intent(Intents.ACTION_TOGGLE_CLASH)
.setClassName(this, ExternalControlActivity::class.java.name)
.addFlags(flags)
)
.setRank(0)
.build()
val start = ShortcutInfoCompat.Builder(this, "start_clash")
.setShortLabel(getString(DesignR.string.shortcut_start_short))
.setLongLabel(getString(DesignR.string.shortcut_start_long))
.setIcon(IconCompat.createWithResource(this, R.drawable.ic_toggle_on))
.setIntent(
Intent(Intents.ACTION_START_CLASH)
.setClassName(this, ExternalControlActivity::class.java.name)
.addFlags(flags)
)
.setRank(1)
.build()
val stop = ShortcutInfoCompat.Builder(this, "stop_clash")
.setShortLabel(getString(DesignR.string.shortcut_stop_short))
.setLongLabel(getString(DesignR.string.shortcut_stop_long))
.setIcon(IconCompat.createWithResource(this, R.drawable.ic_toggle_off))
.setIntent(
Intent(Intents.ACTION_STOP_CLASH)
.setClassName(this, ExternalControlActivity::class.java.name)
.addFlags(flags)
)
.setRank(2)
.build()
ShortcutManagerCompat.setDynamicShortcuts(this, listOf(toggle, start, stop))
}
}

View File

@@ -2,26 +2,17 @@ package com.github.kr328.clash
import android.app.Application
import android.content.Context
import android.content.Intent
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.drawable.IconCompat
import com.github.kr328.clash.common.Global
import com.github.kr328.clash.common.compat.currentProcessName
import com.github.kr328.clash.common.constants.Intents
import com.github.kr328.clash.common.log.Log
import com.github.kr328.clash.design.store.UiStore
import com.github.kr328.clash.remote.Remote
import com.github.kr328.clash.service.util.sendServiceRecreated
import com.github.kr328.clash.util.clashDir
import java.io.File
import java.io.FileOutputStream
import com.github.kr328.clash.design.R as DesignR
@Suppress("unused")
class MainApplication : Application() {
private val uiStore by lazy(LazyThreadSafetyMode.NONE) { UiStore(this) }
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
@@ -39,63 +30,11 @@ class MainApplication : Application() {
if (processName == packageName) {
Remote.launch()
setupShortcuts()
} else {
sendServiceRecreated()
}
}
private fun setupShortcuts() {
if (uiStore.hideAppIcon) {
// Prevent launcher activity not found.
ShortcutManagerCompat.removeAllDynamicShortcuts(this)
return
}
val icon = IconCompat.createWithResource(this, R.mipmap.ic_launcher)
val flags = Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS or
Intent.FLAG_ACTIVITY_NO_ANIMATION
val toggle = ShortcutInfoCompat.Builder(this, "toggle_clash")
.setShortLabel(getString(DesignR.string.shortcut_toggle_short))
.setLongLabel(getString(DesignR.string.shortcut_toggle_long))
.setIcon(icon)
.setIntent(
Intent(Intents.ACTION_TOGGLE_CLASH)
.setClassName(this, ExternalControlActivity::class.java.name)
.addFlags(flags)
)
.setRank(0)
.build()
val start = ShortcutInfoCompat.Builder(this, "start_clash")
.setShortLabel(getString(DesignR.string.shortcut_start_short))
.setLongLabel(getString(DesignR.string.shortcut_start_long))
.setIcon(icon)
.setIntent(
Intent(Intents.ACTION_START_CLASH)
.setClassName(this, ExternalControlActivity::class.java.name)
.addFlags(flags)
)
.setRank(1)
.build()
val stop = ShortcutInfoCompat.Builder(this, "stop_clash")
.setShortLabel(getString(DesignR.string.shortcut_stop_short))
.setLongLabel(getString(DesignR.string.shortcut_stop_long))
.setIcon(icon)
.setIntent(
Intent(Intents.ACTION_STOP_CLASH)
.setClassName(this, ExternalControlActivity::class.java.name)
.addFlags(flags)
)
.setRank(2)
.build()
ShortcutManagerCompat.setDynamicShortcuts(this, listOf(toggle, start, stop))
}
private fun extractGeoFiles() {
clashDir.mkdirs()

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#000000"
android:pathData="M277.3,554.7h469.3a192,192 0,1 1,0 384h-469.3a192,192 0,1 1,0 -384zM746.7,85.3a192,192 0,1 1,0 384h-469.3a192,192 0,0 1,0 -384h469.3zM746.7,810.7a64,64 0,1 1,0 -128,64 64,0 0,1 0,128zM277.3,640a106.7,106.7 0,1 0,0 213.3h469.3a106.7,106.7 0,1 0,0 -213.3h-469.3zM746.7,170.7h-469.3a106.7,106.7 0,0 0,0 213.3h469.3a106.7,106.7 0,1 0,0 -213.3zM277.3,341.3a64,64 0,1 1,0 -128,64 64,0 0,1 0,128z" />
</vector>

View File

@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="21.021898dp"
android:viewportWidth="1170"
android:viewportHeight="1024">
<path
android:fillColor="#000000"
android:pathData="M658.3,512q0,-59.4 -23.1,-113.4T572.6,305.1 479.1,242.6 365.7,219.4t-113.4,23.1T158.9,305.1 96.3,398.6 73.1,512t23.1,113.4T158.9,718.9t93.4,62.6T365.7,804.6t113.4,-23.1T572.6,718.9t62.6,-93.4T658.3,512zM1097.1,512q0,-59.4 -23.1,-113.4T1011.4,305.1t-93.4,-62.6T804.6,219.4h-220.6q68,51.4 107.7,128t39.7,164.6 -39.7,164.6 -107.7,128h220.6q59.4,0 113.4,-23.1T1011.4,718.9t62.6,-93.4T1097.1,512zM1170.3,512q0,74.3 -29.1,142t-78,116.6 -116.6,78 -142,29.1L365.7,877.7q-74.3,0 -142,-29.1t-116.6,-78 -78,-116.6T0,512t29.1,-142 78,-116.6 116.6,-78T365.7,146.3h438.9q74.3,0 142,29.1t116.6,78 78,116.6 29.1,142z" />
</vector>

View File

@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="21.021898dp"
android:viewportWidth="1170"
android:viewportHeight="1024">
<path
android:fillColor="#000000"
android:pathData="M0,512q0,-74.3 29.1,-142t78,-116.6 116.6,-78T365.7,146.3h438.9q74.3,0 142,29.1t116.6,78 78,116.6 29.1,142 -29.1,142 -78,116.6 -116.6,78 -142,29.1L365.7,877.7q-74.3,0 -142,-29.1t-116.6,-78 -78,-116.6T0,512zM804.6,804.6q59.4,0 113.4,-23.1T1011.4,718.9t62.6,-93.4T1097.1,512t-23.1,-113.4T1011.4,305.1t-93.4,-62.6T804.6,219.4t-113.4,23.1T597.7,305.1 535.1,398.6 512,512t23.1,113.4T597.7,718.9t93.4,62.6T804.6,804.6z" />
</vector>