@@ -756,41 +756,6 @@ def _check_and_kill_bluestacks_worker(self) -> None:
756756 logger .exception (error_message )
757757 raise Exception (error_message ) from e
758758
759- def _toggle_single_instance_root (self , unique_id : str ) -> None :
760- """Toggles root for a single, uniquely identified instance."""
761- if not self .worker :
762- raise Exception ("Worker not available." )
763-
764- instance = self .instance_data .get (unique_id )
765- if not instance :
766- raise Exception (f"Instance data missing for { unique_id } ." )
767-
768- config_path = instance ["config_path" ]
769- original_name = instance ["original_name" ]
770- if not os .path .isfile (config_path ):
771- raise FileNotFoundError (f"Config file not found: { config_path } " )
772-
773- current_state = instance .get ("root_enabled" , False )
774- new_state_val = "0" if current_state else "1"
775- new_state_bool = not current_state
776- on_off_text = (
777- self .translation_manager .get_translation ("On" )
778- if new_state_bool
779- else self .translation_manager .get_translation ("Off" )
780- )
781-
782- try :
783- setting_key = f"{ constants .INSTANCE_PREFIX } { original_name } { constants .ENABLE_ROOT_KEY } "
784- config_handler .modify_config_file (config_path , setting_key , new_state_val )
785- config_handler .modify_config_file (config_path , constants .FEATURE_ROOTING_KEY , new_state_val )
786-
787- self .instance_data [unique_id ]["root_enabled" ] = new_state_bool
788- self .worker .instance_status_updated .emit (unique_id , "root" , on_off_text )
789- logger .info (f"Root toggled for instance: { unique_id } to { on_off_text } " )
790- except Exception as e :
791- logger .exception (f"Failed to toggle root for instance { unique_id } " )
792- raise Exception (f"Failed to modify config for { unique_id } : { e } " ) from e
793-
794759 def _toggle_single_instance_rw (self , unique_id : str ) -> None :
795760 """Toggles R/W for a single, uniquely identified instance."""
796761 if not self .worker :
@@ -836,41 +801,85 @@ def _toggle_single_instance_rw(self, unique_id: str) -> None:
836801 raise Exception (f"Failed to modify instance files for { unique_id } : { e } " ) from e
837802
838803 def _perform_root_toggle_operation (self ) -> None :
804+ """
805+ FIXED: This operation toggles root for selected instances and then sets the
806+ global root flag based on the final state of ALL instances per config file.
807+ This prevents toggling one instance from breaking others.
808+ """
839809 if not self .worker :
840810 return
841811 try :
842812 self ._check_and_kill_bluestacks_worker ()
843813 except Exception as e :
844814 self .worker .error .emit (str (e ))
845815 return
846-
847- selected_ids = [
848- uid for uid , w in self .instance_checkboxes .items () if w ["checkbox" ].isChecked ()
849- ]
850-
816+
817+ selected_ids = {uid for uid , w in self .instance_checkboxes .items () if w ["checkbox" ].isChecked ()}
818+ if not selected_ids :
819+ return
820+
821+ # Show reminder if the user is turning root ON for any instance
851822 show_reminder = any (
852823 not self .instance_data .get (uid , {}).get ("root_enabled" , False )
853824 for uid in selected_ids
854825 )
855826 if show_reminder :
856827 self .worker .operation_message .emit ("reminder" , "show_magisk_reminder" )
857-
858- for unique_id in selected_ids :
859- self .worker .operation_message .emit (
860- "info" ,
861- self .translation_manager .get_translation (
862- "Toggling Root for {}..."
863- ).format (unique_id ),
864- )
828+
829+ # Group all instances by their config file path to process them in batches
830+ configs_map : Dict [str , List [Dict [str , Any ]]] = {}
831+ for instance in self .instance_data .values ():
832+ path = instance ["config_path" ]
833+ if path not in configs_map :
834+ configs_map [path ] = []
835+ configs_map [path ].append (instance )
836+
837+ # --- Main Logic ---
838+ for config_path , instances_in_config in configs_map .items ():
839+ # Check if this config file is affected by the user's selection
840+ if not any (inst ["unique_id" ] in selected_ids for inst in instances_in_config ):
841+ continue # Skip this config file if no instances in it were selected
842+
865843 try :
866- self ._toggle_single_instance_root (unique_id )
844+ # 1. Toggle the individual root flags for selected instances
845+ for instance in instances_in_config :
846+ unique_id = instance ["unique_id" ]
847+ if unique_id not in selected_ids :
848+ continue # Only toggle selected instances
849+
850+ self .worker .operation_message .emit (
851+ "info" ,
852+ self .translation_manager .get_translation ("Toggling Root for {}..." ).format (unique_id )
853+ )
854+
855+ original_name = instance ["original_name" ]
856+ current_state = instance .get ("root_enabled" , False )
857+ new_state_bool = not current_state
858+ new_state_val = "1" if new_state_bool else "0"
859+
860+ setting_key = f"{ constants .INSTANCE_PREFIX } { original_name } { constants .ENABLE_ROOT_KEY } "
861+ config_handler .modify_config_file (config_path , setting_key , new_state_val )
862+
863+ # Update internal state so the next step is accurate
864+ instance ["root_enabled" ] = new_state_bool
865+
866+ # Emit UI update signal
867+ on_off_text = self .translation_manager .get_translation ("On" ) if new_state_bool else self .translation_manager .get_translation ("Off" )
868+ self .worker .instance_status_updated .emit (unique_id , "root" , on_off_text )
869+
870+ # 2. Determine the new state for the global root flag
871+ is_any_root_on = any (inst .get ("root_enabled" , False ) for inst in instances_in_config )
872+ new_global_value = "1" if is_any_root_on else "0"
873+
874+ logger .info (f"Setting global '{ constants .FEATURE_ROOTING_KEY } ' to '{ new_global_value } ' in { config_path } " )
875+ config_handler .modify_config_file (config_path , constants .FEATURE_ROOTING_KEY , new_global_value )
876+
867877 except Exception as e :
868- error_msg = self .translation_manager .get_translation (
869- "Error toggling root for {}: {}"
870- ).format (unique_id , e )
878+ # Report a general error for this config file
879+ error_msg = f"Error processing { os .path .basename (config_path )} : { e } "
871880 self .worker .operation_message .emit ("error" , error_msg )
872881 self .operation_had_errors = True
873-
882+
874883 def _perform_rw_toggle_operation (self ) -> None :
875884 if not self .worker :
876885 return
0 commit comments