From d699ddce6b80956b5b8c95bb74bbb077a8d39250 Mon Sep 17 00:00:00 2001 From: MarcaDian <152095496+MarcaDian@users.noreply.github.com> Date: Fri, 11 Jul 2025 23:40:47 +0300 Subject: [PATCH 1/7] fix(YouTube - Settings): Back button/gesture closes search instead of exiting --- .../youtube/settings/LicenseActivityHook.java | 7 ++- .../settings/SearchViewController.java | 21 ++++++-- .../youtube/misc/settings/SettingsPatch.kt | 50 +++++++++++-------- 3 files changed, 51 insertions(+), 27 deletions(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java index 65c68b525b..5e8e78b1c2 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java @@ -24,12 +24,15 @@ * This class is responsible for injecting our own fragment by replacing the LicenseActivity. */ @SuppressWarnings("unused") -public class LicenseActivityHook { +public class LicenseActivityHook extends Activity { private static int currentThemeValueOrdinal = -1; // Must initially be a non-valid enum ordinal value. private static ViewGroup.LayoutParams toolbarLayoutParams; + @SuppressLint("StaticFieldLeak") + public static SearchViewController searchViewController; + public static void setToolbarLayoutParams(Toolbar toolbar) { if (toolbarLayoutParams != null) { toolbar.setLayoutParams(toolbarLayoutParams); @@ -131,7 +134,7 @@ private static void createToolbar(Activity activity, PreferenceFragment fragment // Add Search Icon and EditText for ReVancedPreferenceFragment only. if (fragment instanceof ReVancedPreferenceFragment) { - SearchViewController.addSearchViewComponents(activity, toolbar, (ReVancedPreferenceFragment) fragment); + searchViewController = SearchViewController.addSearchViewComponents(activity, toolbar, (ReVancedPreferenceFragment) fragment); } toolBarParent.addView(toolbar, 0); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/SearchViewController.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/SearchViewController.java index c194108a83..2922ffdab0 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/SearchViewController.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/SearchViewController.java @@ -83,8 +83,8 @@ public static int getSearchViewBackground() { /** * Adds search view components to the activity. */ - public static void addSearchViewComponents(Activity activity, Toolbar toolbar, ReVancedPreferenceFragment fragment) { - new SearchViewController(activity, toolbar, fragment); + public static SearchViewController addSearchViewComponents(Activity activity, Toolbar toolbar, ReVancedPreferenceFragment fragment) { + return new SearchViewController(activity, toolbar, fragment); } private SearchViewController(Activity activity, Toolbar toolbar, ReVancedPreferenceFragment fragment) { @@ -197,7 +197,7 @@ public boolean onQueryTextChange(String newText) { if (isSearchActive) { closeSearch(); } else { - activity.onBackPressed(); + activity.finish(); } } catch (Exception ex) { Logger.printException(() -> "navigation click failure", ex); @@ -313,7 +313,7 @@ private void openSearch() { /** * Closes the search view and hides the keyboard. */ - private void closeSearch() { + public void closeSearch() { isSearchActive = false; toolbar.getMenu().findItem(getResourceIdentifier( "action_search", "id")).setVisible(true); @@ -326,6 +326,19 @@ private void closeSearch() { imm.hideSoftInputFromWindow(searchView.getWindowToken(), 0); } + public static boolean handleBackPress() { + if (LicenseActivityHook.searchViewController != null + && LicenseActivityHook.searchViewController.isSearchExpanded()) { + LicenseActivityHook.searchViewController.closeSearch(); + return true; + } + return false; + } + + public boolean isSearchExpanded() { + return isSearchActive; + } + /** * Custom ArrayAdapter for search history. */ diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt index fce41f3275..75fc2f1013 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt @@ -12,31 +12,15 @@ import app.revanced.patches.shared.misc.mapping.get import app.revanced.patches.shared.misc.mapping.resourceMappingPatch import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.shared.misc.settings.overrideThemeColors -import app.revanced.patches.shared.misc.settings.preference.BasePreference -import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen -import app.revanced.patches.shared.misc.settings.preference.InputType -import app.revanced.patches.shared.misc.settings.preference.IntentPreference -import app.revanced.patches.shared.misc.settings.preference.ListPreference -import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference -import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory -import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference +import app.revanced.patches.shared.misc.settings.preference.* import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting -import app.revanced.patches.shared.misc.settings.preference.SwitchPreference -import app.revanced.patches.shared.misc.settings.preference.TextPreference import app.revanced.patches.shared.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.check.checkEnvironmentPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.fix.playbackspeed.fixPlaybackSpeedWhilePlayingPatch import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch -import app.revanced.util.ResourceGroup -import app.revanced.util.addInstructionsAtControlFlowLabel -import app.revanced.util.copyResources -import app.revanced.util.copyXmlNode -import app.revanced.util.findElementByAttributeValueOrThrow -import app.revanced.util.findInstructionIndicesReversedOrThrow -import app.revanced.util.inputStreamFromBundledResource -import app.revanced.util.insertLiteralOverride +import app.revanced.util.* import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation @@ -267,6 +251,32 @@ val settingsPatch = bytecodePatch( methods.add(attachBaseContext) } + licenseActivityOnCreateFingerprint.classDef.apply { + val onBackPressed = ImmutableMethod( + type, + "onBackPressed", + emptyList(), + "V", + AccessFlags.PUBLIC.value, + null, + null, + MutableMethodImplementation(3) + ).toMutable().apply { + addInstructions( + """ + invoke-static {}, Lapp/revanced/extension/youtube/settings/SearchViewController;->handleBackPress()Z + move-result v0 + if-nez v0, :search_handled + invoke-virtual { p0 }, Landroid/app/Activity;->finish()V + :search_handled + return-void + """ + ) + + }; + methods.add(onBackPressed); + }; + // Update shared dark mode status based on YT theme. // This is needed because YT allows forcing light/dark mode // which then differs from the system dark mode status. @@ -338,20 +348,18 @@ object PreferenceScreen : BasePreferenceScreen() { icon = "@drawable/revanced_settings_screen_05_player", layout = "@layout/preference_with_icon", ) - val SHORTS = Screen( key = "revanced_settings_screen_06_shorts", summaryKey = null, icon = "@drawable/revanced_settings_screen_06_shorts", layout = "@layout/preference_with_icon", ) - val SEEKBAR = Screen( key = "revanced_settings_screen_07_seekbar", summaryKey = null, icon = "@drawable/revanced_settings_screen_07_seekbar", layout = "@layout/preference_with_icon", - ) + ) val SWIPE_CONTROLS = Screen( key = "revanced_settings_screen_08_swipe_controls", summaryKey = null, From 0a08eca630c26872d56d0e199524b50c5453c2af Mon Sep 17 00:00:00 2001 From: MarcaDian <152095496+MarcaDian@users.noreply.github.com> Date: Sat, 12 Jul 2025 00:11:34 +0300 Subject: [PATCH 2/7] close search bar when going to submenu --- .../settings/preference/ReVancedPreferenceFragment.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java index ed2608e5af..423cc10bb2 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -269,6 +269,11 @@ private void setPreferenceScreenToolbar(PreferenceScreen parentScreen) { LicenseActivityHook.setToolbarLayoutParams(toolbar); + if (LicenseActivityHook.searchViewController != null + && LicenseActivityHook.searchViewController.isSearchExpanded()) { + toolbar.post(() -> LicenseActivityHook.searchViewController.closeSearch()); + } + rootView.addView(toolbar, 0); return false; } From 57fb231159bba95093d1f3e3a641fa7751460197 Mon Sep 17 00:00:00 2001 From: MarcaDian <152095496+MarcaDian@users.noreply.github.com> Date: Sat, 12 Jul 2025 09:57:53 +0300 Subject: [PATCH 3/7] do not recreate activity when screen rotates --- .../youtube/misc/settings/SettingsPatch.kt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt index 75fc2f1013..1e6732446e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt @@ -136,15 +136,24 @@ private val settingsResourcePatch = resourcePatch { } } - // Modify the manifest and add a data intent filter to the LicenseActivity. - // Some devices freak out if undeclared data is passed to an intent, - // and this change appears to fix the issue. + // Modify the manifest to enhance LicenseActivity behavior: + // 1. Add a data intent filter with MIME type "text/plain". + // Some devices crash if undeclared data is passed to an intent, + // and this change appears to fix the issue. + // 2. Add android:configChanges="orientation|screenSize|keyboardHidden". + // This prevents the activity from being recreated on configuration changes + // (e.g., screen rotation), preserving its current state and fragment. document("AndroidManifest.xml").use { document -> val licenseElement = document.childNodes.findElementByAttributeValueOrThrow( "android:name", "com.google.android.libraries.social.licenses.LicenseActivity", ) + licenseElement.setAttribute( + "android:configChanges", + "orientation|screenSize|keyboardHidden" + ) + val mimeType = document.createElement("data") mimeType.setAttribute("android:mimeType", "text/plain") From 1235e42dc00ad64ad6dda8bd38fd0bdeb3f09f0d Mon Sep 17 00:00:00 2001 From: MarcaDian <152095496+MarcaDian@users.noreply.github.com> Date: Sat, 12 Jul 2025 11:05:07 +0300 Subject: [PATCH 4/7] disable fullscreen keyboard mode when search is active --- .../extension/youtube/settings/SearchViewController.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/SearchViewController.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/SearchViewController.java index 2922ffdab0..c7cfbcedc9 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/SearchViewController.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/SearchViewController.java @@ -10,6 +10,7 @@ import android.util.Pair; import android.view.MenuItem; import android.view.View; +import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; @@ -115,6 +116,9 @@ private SearchViewController(Activity activity, Toolbar toolbar, ReVancedPrefere searchView.getContext().getResources().getIdentifier( "android:id/search_src_text", null, null)); + // Disable fullscreen keyboard mode. + autoCompleteTextView.setImeOptions(autoCompleteTextView.getImeOptions() | EditorInfo.IME_FLAG_NO_EXTRACT_UI); + // Set background and query hint. searchView.setBackground(createBackgroundDrawable(toolbar.getContext())); searchView.setQueryHint(str("revanced_settings_search_hint")); From b3e6f17469e05f56033d35963c0d57244b5b7a27 Mon Sep 17 00:00:00 2001 From: MarcaDian <152095496+MarcaDian@users.noreply.github.com> Date: Sat, 12 Jul 2025 11:33:56 +0300 Subject: [PATCH 5/7] apply padding for display cutout in landscape --- .../preference/ReVancedPreferenceFragment.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java index 423cc10bb2..405880baad 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -248,7 +248,15 @@ private void setPreferenceScreenToolbar(PreferenceScreen parentScreen) { rootView.setOnApplyWindowInsetsListener((v, insets) -> { Insets statusInsets = insets.getInsets(WindowInsets.Type.statusBars()); Insets navInsets = insets.getInsets(WindowInsets.Type.navigationBars()); - v.setPadding(0, statusInsets.top, 0, navInsets.bottom); + Insets cutoutInsets = insets.getInsets(WindowInsets.Type.displayCutout()); + + // Apply padding for display cutout in landscape. + int leftPadding = cutoutInsets.left; + int rightPadding = cutoutInsets.right; + int topPadding = statusInsets.top; + int bottomPadding = navInsets.bottom; + + v.setPadding(leftPadding, topPadding, rightPadding, bottomPadding); return insets; }); } From ed56e0f72eadf31c4469cab89e008b8ce5064283 Mon Sep 17 00:00:00 2001 From: MarcaDian <152095496+MarcaDian@users.noreply.github.com> Date: Sat, 12 Jul 2025 11:46:56 +0300 Subject: [PATCH 6/7] toolbar title sometimes resizes when changing orientation --- .../extension/youtube/settings/LicenseActivityHook.java | 2 ++ .../youtube/settings/preference/ReVancedPreferenceFragment.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java index 5e8e78b1c2..fd371d1cf6 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java @@ -6,6 +6,7 @@ import android.app.Activity; import android.content.Context; import android.preference.PreferenceFragment; +import android.util.TypedValue; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toolbar; @@ -129,6 +130,7 @@ private static void createToolbar(Activity activity, PreferenceFragment fragment view -> view instanceof TextView); if (toolbarTextView != null) { toolbarTextView.setTextColor(Utils.getAppForegroundColor()); + toolbarTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); } setToolbarLayoutParams(toolbar); diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java index 405880baad..e764514170 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -17,6 +17,7 @@ import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.style.BackgroundColorSpan; +import android.util.TypedValue; import android.view.ViewGroup; import android.view.Window; import android.view.WindowInsets; @@ -273,6 +274,7 @@ private void setPreferenceScreenToolbar(PreferenceScreen parentScreen) { true, TextView.class::isInstance); if (toolbarTextView != null) { toolbarTextView.setTextColor(Utils.getAppForegroundColor()); + toolbarTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); } LicenseActivityHook.setToolbarLayoutParams(toolbar); From e607def7fe97b14337167fb760e1690d39f61f95 Mon Sep 17 00:00:00 2001 From: MarcaDian <152095496+MarcaDian@users.noreply.github.com> Date: Sat, 12 Jul 2025 13:37:06 +0300 Subject: [PATCH 7/7] close search history when changing orientation --- .../youtube/settings/LicenseActivityHook.java | 2 +- .../youtube/settings/SearchViewController.java | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java index fd371d1cf6..4ba25c4c56 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/LicenseActivityHook.java @@ -134,7 +134,7 @@ private static void createToolbar(Activity activity, PreferenceFragment fragment } setToolbarLayoutParams(toolbar); - // Add Search Icon and EditText for ReVancedPreferenceFragment only. + // Add Search bar only for ReVancedPreferenceFragment. if (fragment instanceof ReVancedPreferenceFragment) { searchViewController = SearchViewController.addSearchViewComponents(activity, toolbar, (ReVancedPreferenceFragment) fragment); } diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/SearchViewController.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/SearchViewController.java index c7cfbcedc9..b99c885cf7 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/SearchViewController.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/SearchViewController.java @@ -52,6 +52,7 @@ public class SearchViewController { private final Deque searchHistory; private final AutoCompleteTextView autoCompleteTextView; private final boolean showSettingsSearchHistory; + private int currentOrientation; /** * Creates a background drawable for the SearchView with rounded corners. @@ -207,6 +208,8 @@ public boolean onQueryTextChange(String newText) { Logger.printException(() -> "navigation click failure", ex); } }); + + monitorOrientationChanges(); } /** @@ -289,6 +292,21 @@ private void updateSearchHistoryAdapter() { } } + private void monitorOrientationChanges() { + currentOrientation = activity.getResources().getConfiguration().orientation; + + searchView.getViewTreeObserver().addOnGlobalLayoutListener(() -> { + int newOrientation = activity.getResources().getConfiguration().orientation; + if (newOrientation != currentOrientation) { + currentOrientation = newOrientation; + if (autoCompleteTextView != null) { + autoCompleteTextView.dismissDropDown(); + Logger.printDebug(() -> "Orientation changed, search history dismissed"); + } + } + }); + } + /** * Opens the search view and shows the keyboard. */