From 58a216fde3d2b34ab4ef896dcf7f4a2cefa25c6d Mon Sep 17 00:00:00 2001 From: Nikhil Date: Wed, 11 Mar 2026 14:50:54 -0700 Subject: [PATCH] fix: sparkle crash + notification fix for macos (#425) * fix: sparkle crash * feat: sparkle notification fix * feat: new tab focus fix --- .../browser/browseros/core/browseros_prefs.cc | 11 ++++- .../browser/browseros/core/browseros_prefs.h | 10 +++- .../browser/lifetime/application_lifetime.cc | 39 ++++++++++++++++ .../chrome/browser/mac/sparkle_glue.mm | 22 +++++++-- .../chrome/browser/ui/browser.cc | 46 +++++++++++++++++++ 5 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 packages/browseros/chromium_patches/chrome/browser/lifetime/application_lifetime.cc create mode 100644 packages/browseros/chromium_patches/chrome/browser/ui/browser.cc diff --git a/packages/browseros/chromium_patches/chrome/browser/browseros/core/browseros_prefs.cc b/packages/browseros/chromium_patches/chrome/browser/browseros/core/browseros_prefs.cc index c7391dc95..0e53a0988 100644 --- a/packages/browseros/chromium_patches/chrome/browser/browseros/core/browseros_prefs.cc +++ b/packages/browseros/chromium_patches/chrome/browser/browseros/core/browseros_prefs.cc @@ -1,9 +1,9 @@ diff --git a/chrome/browser/browseros/core/browseros_prefs.cc b/chrome/browser/browseros/core/browseros_prefs.cc new file mode 100644 -index 0000000000000..38f09f1f42dc4 +index 0000000000000..c191fb3963968 --- /dev/null +++ b/chrome/browser/browseros/core/browseros_prefs.cc -@@ -0,0 +1,89 @@ +@@ -0,0 +1,96 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -31,6 +31,9 @@ index 0000000000000..38f09f1f42dc4 + registry->RegisterStringPref(prefs::kProviders, ""); + registry->RegisterStringPref(prefs::kCustomProviders, "[]"); + registry->RegisterStringPref(prefs::kDefaultProviderId, ""); ++ ++ // NTP focus pref ++ registry->RegisterBooleanPref(prefs::kNtpFocusContent, false); +} + +bool ShouldShowLLMChat(PrefService* pref_service) { @@ -73,6 +76,10 @@ index 0000000000000..38f09f1f42dc4 + } +} + ++bool IsNtpFocusContentEnabled(PrefService* pref_service) { ++ return pref_service->GetBoolean(prefs::kNtpFocusContent); ++} ++ +const char* GetVisibilityPrefForAction(actions::ActionId id) { + switch (id) { + case kActionSidePanelShowThirdPartyLlm: diff --git a/packages/browseros/chromium_patches/chrome/browser/browseros/core/browseros_prefs.h b/packages/browseros/chromium_patches/chrome/browser/browseros/core/browseros_prefs.h index ccd95707a..7affe3bc7 100644 --- a/packages/browseros/chromium_patches/chrome/browser/browseros/core/browseros_prefs.h +++ b/packages/browseros/chromium_patches/chrome/browser/browseros/core/browseros_prefs.h @@ -1,9 +1,9 @@ diff --git a/chrome/browser/browseros/core/browseros_prefs.h b/chrome/browser/browseros/core/browseros_prefs.h new file mode 100644 -index 0000000000000..2719852d7d8c6 +index 0000000000000..a94b14e0664ca --- /dev/null +++ b/chrome/browser/browseros/core/browseros_prefs.h -@@ -0,0 +1,80 @@ +@@ -0,0 +1,86 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -45,6 +45,9 @@ index 0000000000000..2719852d7d8c6 +// String containing the default provider ID for BrowserOS +inline constexpr char kDefaultProviderId[] = "browseros.default_provider_id"; + ++// Boolean: Focus NTP content instead of omnibox on new tab (default: true) ++inline constexpr char kNtpFocusContent[] = "browseros.ntp_focus_content"; ++ +} // namespace prefs + +// Registers BrowserOS profile preferences. @@ -78,6 +81,9 @@ index 0000000000000..2719852d7d8c6 +// Returns false if action's visibility pref is false. +bool ShouldShowToolbarAction(actions::ActionId id, PrefService* pref_service); + ++// Check if NTP content should receive focus instead of the omnibox. ++bool IsNtpFocusContentEnabled(PrefService* pref_service); ++ +// Get the visibility pref key for an action, or nullptr if none exists. +const char* GetVisibilityPrefForAction(actions::ActionId id); + diff --git a/packages/browseros/chromium_patches/chrome/browser/lifetime/application_lifetime.cc b/packages/browseros/chromium_patches/chrome/browser/lifetime/application_lifetime.cc new file mode 100644 index 000000000..63b0dba5f --- /dev/null +++ b/packages/browseros/chromium_patches/chrome/browser/lifetime/application_lifetime.cc @@ -0,0 +1,39 @@ +diff --git a/chrome/browser/lifetime/application_lifetime.cc b/chrome/browser/lifetime/application_lifetime.cc +index 120cee0391d43..29ee1da2a6b2c 100644 +--- a/chrome/browser/lifetime/application_lifetime.cc ++++ b/chrome/browser/lifetime/application_lifetime.cc +@@ -13,6 +13,7 @@ + #include "build/build_config.h" + #include "chrome/browser/browser_process.h" + #include "chrome/browser/browser_process_platform_part.h" ++#include "chrome/browser/buildflags.h" + #include "chrome/browser/lifetime/browser_shutdown.h" + #include "chrome/browser/ui/profiles/profile_picker.h" + #include "chrome/common/buildflags.h" +@@ -29,6 +30,13 @@ + #include "chrome/browser/lifetime/application_lifetime_desktop.h" + #endif // !BUILDFLAG(IS_ANDROID) + ++#if BUILDFLAG(ENABLE_SPARKLE) ++namespace sparkle_glue { ++bool IsUpdateReady(); ++void InstallAndRelaunch(); ++} // namespace sparkle_glue ++#endif ++ + namespace chrome { + + namespace { +@@ -65,6 +73,12 @@ void AttemptUserExit() { + } + + void AttemptRelaunch() { ++#if BUILDFLAG(ENABLE_SPARKLE) ++ if (sparkle_glue::IsUpdateReady()) { ++ sparkle_glue::InstallAndRelaunch(); ++ return; ++ } ++#endif + AttemptRestart(); + } + diff --git a/packages/browseros/chromium_patches/chrome/browser/mac/sparkle_glue.mm b/packages/browseros/chromium_patches/chrome/browser/mac/sparkle_glue.mm index 0c6afd99b..b6529a3b7 100644 --- a/packages/browseros/chromium_patches/chrome/browser/mac/sparkle_glue.mm +++ b/packages/browseros/chromium_patches/chrome/browser/mac/sparkle_glue.mm @@ -1,9 +1,9 @@ diff --git a/chrome/browser/mac/sparkle_glue.mm b/chrome/browser/mac/sparkle_glue.mm new file mode 100644 -index 0000000000000..25a2dd2d5a578 +index 0000000000000..bc8c3ec061c3d --- /dev/null +++ b/chrome/browser/mac/sparkle_glue.mm -@@ -0,0 +1,662 @@ +@@ -0,0 +1,674 @@ +// Copyright 2024 BrowserOS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -258,9 +258,10 @@ index 0000000000000..25a2dd2d5a578 + VLOG(1) << "Sparkle: Ready to install and relaunch"; + self.installReplyBlock = reply; + [self.glue setInternalStatus:SparkleStatusReadyToInstall]; -+ if (self.updateVersion) { -+ NotifyUpgradeReady(base::SysNSStringToUTF8(self.updateVersion)); -+ } ++ std::string version = self.updateVersion ++ ? base::SysNSStringToUTF8(self.updateVersion) ++ : std::string(); ++ NotifyUpgradeReady(version); +} + +- (void)showInstallingUpdateWithApplicationTerminated:(BOOL)applicationTerminated @@ -508,6 +509,17 @@ index 0000000000000..25a2dd2d5a578 + if (errorMessage && [errorMessage length] > 0) { + [self notifyError:errorMessage]; + } ++ ++ // Ensure the upgrade system is notified whenever we reach ReadyToInstall, ++ // regardless of which Sparkle callback triggered the transition. This covers ++ // automatic background downloads where showUpdateFoundWithAppcastItem: is ++ // not called and updateVersion may be nil. ++ if (status == SparkleStatusReadyToInstall) { ++ std::string version = _userDriver.updateVersion ++ ? base::SysNSStringToUTF8(_userDriver.updateVersion) ++ : std::string(); ++ NotifyUpgradeReady(version); ++ } +} + +- (void)notifyStatusChange { diff --git a/packages/browseros/chromium_patches/chrome/browser/ui/browser.cc b/packages/browseros/chromium_patches/chrome/browser/ui/browser.cc new file mode 100644 index 000000000..e72f8c10b --- /dev/null +++ b/packages/browseros/chromium_patches/chrome/browser/ui/browser.cc @@ -0,0 +1,46 @@ +diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc +index ca32d6faace3a..459c9597ea6f8 100644 +--- a/chrome/browser/ui/browser.cc ++++ b/chrome/browser/ui/browser.cc +@@ -42,6 +42,7 @@ + #include "chrome/browser/background/background_contents_service_factory.h" + #include "chrome/browser/bookmarks/bookmark_model_factory.h" + #include "chrome/browser/browser_process.h" ++#include "chrome/browser/browseros/core/browseros_prefs.h" + #include "chrome/browser/buildflags.h" + #include "chrome/browser/content_settings/host_content_settings_map_factory.h" + #include "chrome/browser/content_settings/mixed_content_settings_tab_helper.h" +@@ -2298,6 +2299,11 @@ bool Browser::ShouldFocusLocationBarByDefault(WebContents* source) { + source->GetController().GetPendingEntry() + ? source->GetController().GetPendingEntry() + : source->GetController().GetLastCommittedEntry(); ++ ++ // BrowserOS: Check once so the per-URL gates below can use it. ++ const bool ntp_focus_content = ++ browseros::IsNtpFocusContentEnabled(profile_->GetPrefs()); ++ + if (entry) { + const GURL& url = entry->GetURL(); + const GURL& virtual_url = entry->GetVirtualURL(); +@@ -2310,15 +2316,18 @@ bool Browser::ShouldFocusLocationBarByDefault(WebContents* source) { + url.host() == chrome::kChromeUINewTabHost) || + (virtual_url.SchemeIs(content::kChromeUIScheme) && + virtual_url.host() == chrome::kChromeUINewTabHost)) { +- return true; ++ return !ntp_focus_content; + } + + if (url.spec() == chrome::kChromeUISplitViewNewTabPageURL) { +- return true; ++ return !ntp_focus_content; + } + } + +- return search::NavEntryIsInstantNTP(source, entry); ++ if (search::NavEntryIsInstantNTP(source, entry)) { ++ return !ntp_focus_content; ++ } ++ return false; + } + + bool Browser::ShouldFocusPageAfterCrash(WebContents* source) {