@@ -39,6 +39,7 @@ async function refreshAppList() {
3939 if ( import . meta. env . DEV ) { // vite debug
4040 allApps = [
4141 { appLabel : 'Chrome' , packageName : 'com.android.chrome' , isSystem : false , uid : 10001 } ,
42+ { appLabel : 'Chrome' , packageName : 'com.android.chrome' , isSystem : false , uid : 1010001 } ,
4243 { appLabel : 'Google' , packageName : 'com.google.android.googlequicksearchbox' , isSystem : true , uid : 1010002 } ,
4344 { appLabel : 'Settings' , packageName : 'com.android.settings' , isSystem : true , uid : 10003 } ,
4445 { appLabel : 'WhatsApp' , packageName : 'com.whatsapp' , isSystem : false , uid : 10123 } ,
@@ -60,7 +61,16 @@ const appItemMap = new Map();
6061
6162async function saveExcludedList ( excludedApps ) {
6263 const header = 'pkg,exclude,allow,uid' ;
63- const lines = excludedApps . map ( app => `${ app . packageName } ,1,0,${ app . uid % 100000 } ` ) ;
64+ const seen = new Set ( ) ;
65+ const uniqueList = [ ] ;
66+ excludedApps . forEach ( app => {
67+ const key = `${ app . packageName } :${ app . uid % 100000 } ` ;
68+ if ( ! seen . has ( key ) ) {
69+ seen . add ( key ) ;
70+ uniqueList . push ( app ) ;
71+ }
72+ } ) ;
73+ const lines = uniqueList . map ( app => `${ app . packageName } ,1,0,${ app . uid % 100000 } ` ) ;
6474 const csvContent = [ header , ...lines ] . join ( '\n' ) ;
6575 if ( import . meta. env . DEV ) {
6676 localStorage . setItem ( 'kp-next_excluded_mock' , csvContent ) ;
@@ -105,18 +115,26 @@ async function renderAppList() {
105115
106116 // Consistency check
107117 if ( allApps . length > 0 ) {
108- const currentAppsMap = new Map ( allApps . map ( app => [ ( app . packageName || '' ) . trim ( ) , app ] ) ) ;
118+ const appByRealUid = new Map ( ) ;
119+ allApps . forEach ( app => {
120+ const rUid = app . uid % 100000 ;
121+ const key = `${ ( app . packageName || '' ) . trim ( ) } :${ rUid } ` ;
122+ if ( ! appByRealUid . has ( key ) ) appByRealUid . set ( key , [ ] ) ;
123+ appByRealUid . get ( key ) . push ( app ) ;
124+ } ) ;
109125
126+ excludedApps = [ ] ;
110127 let changed = false ;
111- excludedApps = list . map ( item => {
112- const app = currentAppsMap . get ( item . packageName ) ;
113- if ( ! app ) return item ;
114- const realUid = app . uid % 100000 ;
115- if ( realUid !== item . uid ) {
116- changed = true ;
117- return { packageName : item . packageName , uid : realUid } ;
128+ list . forEach ( item => {
129+ const key = `${ item . packageName } :${ item . uid } ` ;
130+ const matches = appByRealUid . get ( key ) ;
131+ if ( matches ) {
132+ matches . forEach ( app => {
133+ excludedApps . push ( { packageName : app . packageName , uid : app . uid } ) ;
134+ } ) ;
135+ } else {
136+ excludedApps . push ( { packageName : item . packageName , uid : item . uid } ) ;
118137 }
119- return item ;
120138 } ) ;
121139
122140 if ( changed ) {
@@ -127,19 +145,20 @@ async function renderAppList() {
127145 }
128146 }
129147
130- const excludedPkgNames = new Set ( excludedApps . map ( app => app . packageName ) ) ;
148+ const excludedAppKeys = new Set ( excludedApps . map ( app => ` ${ app . packageName } : ${ app . uid } ` ) ) ;
131149
132150 const sortedApps = [ ...allApps ] . sort ( ( a , b ) => {
133- const aExcluded = excludedPkgNames . has ( a . packageName ) ;
134- const bExcluded = excludedPkgNames . has ( b . packageName ) ;
151+ const aExcluded = excludedAppKeys . has ( ` ${ a . packageName } : ${ a . uid } ` ) ;
152+ const bExcluded = excludedAppKeys . has ( ` ${ b . packageName } : ${ b . uid } ` ) ;
135153 if ( aExcluded !== bExcluded ) return aExcluded ? - 1 : 1 ;
136154 return ( a . appLabel || '' ) . localeCompare ( b . appLabel || '' ) ;
137155 } ) ;
138156
139157 emptyMsg . classList . add ( 'hidden' ) ;
140158
141159 sortedApps . forEach ( app => {
142- let item = appItemMap . get ( app . packageName ) ;
160+ const appKey = `${ app . packageName } :${ app . uid } ` ;
161+ let item = appItemMap . get ( appKey ) ;
143162 if ( ! item ) {
144163 item = document . createElement ( 'label' ) ;
145164 item . className = 'app-item' ;
@@ -171,27 +190,43 @@ async function renderAppList() {
171190 let saveTimeout = null ;
172191 toggle . addEventListener ( 'change' , ( ) => {
173192 const realUid = app . uid % 100000 ;
174- if ( toggle . selected ) {
175- if ( ! excludedApps . some ( e => e . packageName === app . packageName ) ) {
176- excludedApps . push ( { packageName : app . packageName , uid : realUid } ) ;
193+ const isSelected = toggle . selected ;
194+
195+ // Sync state across all instances of the same app
196+ allApps . forEach ( a => {
197+ if ( a . packageName === app . packageName && ( a . uid % 100000 ) === realUid ) {
198+ if ( isSelected ) {
199+ if ( ! excludedApps . some ( e => e . packageName === a . packageName && e . uid === a . uid ) ) {
200+ excludedApps . push ( { packageName : a . packageName , uid : a . uid } ) ;
201+ }
202+ } else {
203+ excludedApps = excludedApps . filter ( e => ! ( e . packageName === a . packageName && e . uid === a . uid ) ) ;
204+ }
205+
206+ const otherItem = appItemMap . get ( `${ a . packageName } :${ a . uid } ` ) ;
207+ if ( otherItem ) {
208+ const otherToggle = otherItem . querySelector ( 'md-switch' ) ;
209+ if ( otherToggle && otherToggle !== toggle ) {
210+ otherToggle . selected = isSelected ;
211+ }
212+ }
177213 }
178- } else {
179- excludedApps = excludedApps . filter ( e => e . packageName !== app . packageName ) ;
180- }
214+ } ) ;
215+
181216 if ( saveTimeout ) clearTimeout ( saveTimeout ) ;
182217 saveTimeout = setTimeout ( ( ) => {
183218 saveExcludedList ( excludedApps ) ;
184219 } , 500 ) ;
185- exec ( `kpatch ${ superkey } exclude_set ${ realUid } ${ toggle . selected ? 1 : 0 } ` , { env : { PATH : `${ modDir } /bin` } } ) ;
220+ exec ( `kpatch ${ superkey } exclude_set ${ realUid } ${ isSelected ? 1 : 0 } ` , { env : { PATH : `${ modDir } /bin` } } ) ;
186221 } ) ;
187222
188- appItemMap . set ( app . packageName , item ) ;
223+ appItemMap . set ( appKey , item ) ;
189224 iconObserver . observe ( item ) ;
190225 }
191226
192227 // Update state
193228 const toggle = item . querySelector ( 'md-switch' ) ;
194- toggle . selected = excludedPkgNames . has ( app . packageName ) ;
229+ toggle . selected = excludedAppKeys . has ( ` ${ app . packageName } : ${ app . uid } ` ) ;
195230
196231 appList . appendChild ( item ) ;
197232 } ) ;
@@ -208,7 +243,7 @@ function applyFilters() {
208243 let visibleCount = 0 ;
209244
210245 allApps . forEach ( app => {
211- const item = appItemMap . get ( app . packageName ) ;
246+ const item = appItemMap . get ( ` ${ app . packageName } : ${ app . uid } ` ) ;
212247 if ( ! item ) return ;
213248
214249 const matchesSearch = ( app . appLabel || '' ) . toLowerCase ( ) . includes ( query ) ||
0 commit comments