0

Summary:Adding a command line flag to open URLs in active tab

The user can now add a flag "--same-tab" to open URLs in active tabs
now. The desired command would look something like this:

./usr/bin/google-chrome --same-tab "https://google.com"
OR
./out/Default/chrome --same-tab "https://google.com"

In case multiple URLs are entered as inputs then the first one from the
inputs replaces the active tab while all the others are opened in new
tabs as expected.

Bug: 41283963
Change-Id: Ifbbaacfd7a1c635ab048e79dcb7b89661971f62e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6109882
Commit-Queue: Yann Dago <ydago@chromium.org>
Reviewed-by: Tommy Martino <tmartino@chromium.org>
Reviewed-by: Yann Dago <ydago@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1429265}
This commit is contained in:
Saiv-kodes
2025-03-06 17:18:45 -08:00
committed by Chromium LUCI CQ
parent c0c5614aa6
commit 92d92e0090
7 changed files with 104 additions and 8 deletions

@ -1284,6 +1284,7 @@ Saravanan KR <sramajay@cisco.com>
Sathish Kuppuswamy <sathish.kuppuswamy@intel.com>
Satoshi Matsuzaki <satoshi.matsuzaki@gmail.com>
Satyajit Sahu <satyajit.sahu@amd.com>
Satvic Dhawan <satvicdhawan14@gmail.com>
Sayan Nayak <sayan.nayak@samsung.com>
Sayan Sivakumaran <sivakusayan@gmail.com>
Scott D Phillips <scott.d.phillips@intel.com>

@ -258,6 +258,8 @@ class StartupBrowserCreator {
CommandLineWindowByAppId);
FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
LastUsedProfilesWithWebApp);
FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
KSameTabSwitchReplacesActiveTab);
bool ProcessCmdLineImpl(const base::CommandLine& command_line,
const base::FilePath& cur_dir,

@ -465,6 +465,55 @@ IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, OpenAppUrlShortcut) {
web_contents->GetLastCommittedURL().ExtractFileName());
}
IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest,
KSameTabSwitchReplacesActiveTab) {
// Use a couple of arbitrary URLs.
std::vector<GURL> urls;
urls.push_back(ui_test_utils::GetTestUrl(
base::FilePath(base::FilePath::kCurrentDirectory),
base::FilePath(FILE_PATH_LITERAL("title1.html"))));
urls.push_back(ui_test_utils::GetTestUrl(
base::FilePath(base::FilePath::kCurrentDirectory),
base::FilePath(FILE_PATH_LITERAL("title2.html"))));
urls.push_back(ui_test_utils::GetTestUrl(
base::FilePath(base::FilePath::kCurrentDirectory),
base::FilePath(FILE_PATH_LITERAL("title3.html"))));
DisableWhatsNewPage();
// Open a browser window with some preloaded tabs.
ui_test_utils::NavigateToURLWithDisposition(
browser(), GURL("http://localhost"), WindowOpenDisposition::CURRENT_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
TabStripModel* tab_strip = browser()->tab_strip_model();
EXPECT_EQ(1, tab_strip->count()); // Verify one tab is open.
// Set the first tab as the active tab.
tab_strip->ActivateTabAt(0);
EXPECT_EQ(0, tab_strip->active_index());
// Add the --kSameTab switch and URLs to the command line.
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
command_line.AppendSwitch(switches::kSameTab); // Add the switch.
command_line.AppendArg(urls[0].spec()); // First URL.
command_line.AppendArg(urls[1].spec()); // Second URL.
command_line.AppendArg(urls[2].spec()); // Third URL.
// Process the command line to simulate the launch.
ASSERT_TRUE(StartupBrowserCreator().ProcessCmdLineImpl(
command_line, base::FilePath(), chrome::startup::IsProcessStartup::kNo,
{browser()->profile(), StartupProfileMode::kBrowserWindow}, {}));
// Verify the behavior:
// - The active tab's URL should be replaced by the first URL.
EXPECT_EQ(urls[0], tab_strip->GetWebContentsAt(0)->GetVisibleURL());
// - The remaining URLs should open in new tabs.
EXPECT_EQ(3, tab_strip->count()); // Verify total tabs.
EXPECT_EQ(urls[1], tab_strip->GetWebContentsAt(1)->GetVisibleURL());
EXPECT_EQ(urls[2], tab_strip->GetWebContentsAt(2)->GetVisibleURL());
}
IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, OpenAppUrlIncognitoShortcut) {
// Add --app=<url> and --incognito to the command line. Tests launching
// legacy apps which may have been created by "Add to Desktop" in old versions

@ -174,13 +174,14 @@ Browser* StartupBrowserCreatorImpl::OpenURLsInBrowser(
const std::vector<GURL>& urls) {
StartupTabs tabs;
UrlsToTabs(urls, &tabs);
return OpenTabsInBrowser(browser, process_startup, tabs);
return OpenTabsInBrowser(browser, process_startup, tabs, TabOverWrite::kNo);
}
Browser* StartupBrowserCreatorImpl::OpenTabsInBrowser(
Browser* browser,
chrome::startup::IsProcessStartup process_startup,
const StartupTabs& tabs) {
const StartupTabs& tabs,
TabOverWrite is_active_tab_overwrite) {
DCHECK(!tabs.empty());
// If we don't yet have a profile, try to use the one we're given from
@ -276,6 +277,18 @@ Browser* StartupBrowserCreatorImpl::OpenTabsInBrowser(
browser->AsWeakPtr(), std::move(profile_keepalive)));
continue;
}
// Active tab overwrites apply only to one tab per launch, and can only
// happen if there is already a tab open to replace
if (first_tab && browser->tab_strip_model()->count() &&
(is_active_tab_overwrite == TabOverWrite::kYes)) {
NavigateParams params(browser, tab.url,
ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
params.disposition = WindowOpenDisposition::CURRENT_TAB;
params.tabstrip_add_types = ADD_NONE;
first_tab = false;
Navigate(&params);
continue;
}
int add_types = first_tab ? AddTabTypes::ADD_ACTIVE : AddTabTypes::ADD_NONE;
add_types |= AddTabTypes::ADD_FORCE_INDEX;
@ -397,6 +410,9 @@ void StartupBrowserCreatorImpl::DetermineURLsAndLaunch(
if (command_line_->HasSwitch(switches::kOpenInNewWindow)) {
behavior_options |= HAS_NEW_WINDOW_SWITCH;
}
if (command_line_->HasSwitch(switches::kSameTab)) {
behavior_options |= HAS_SAME_TAB_SWITCH;
}
if (result.launch_result == LaunchResult::kWithGivenUrls) {
behavior_options |= HAS_CMD_LINE_TABS;
}
@ -597,7 +613,9 @@ Browser* StartupBrowserCreatorImpl::RestoreOrCreateBrowser(
if (browser) {
return browser;
}
} else if (behavior == BrowserOpenBehavior::USE_EXISTING) {
} else if (behavior == BrowserOpenBehavior::USE_EXISTING ||
behavior ==
BrowserOpenBehavior::USE_EXISTING_AND_OVERWRITE_ACTIVE_TAB) {
browser = chrome::FindTabbedBrowser(
profile_, process_startup == chrome::startup::IsProcessStartup::kYes);
}
@ -612,7 +630,10 @@ Browser* StartupBrowserCreatorImpl::RestoreOrCreateBrowser(
browser, process_startup,
(tabs.empty()
? StartupTabs({StartupTab(GURL(chrome::kChromeUINewTabURL))})
: tabs));
: tabs),
(behavior == BrowserOpenBehavior::USE_EXISTING_AND_OVERWRITE_ACTIVE_TAB
? (TabOverWrite::kYes)
: (TabOverWrite::kNo)));
// Now that a restore is no longer possible, it is safe to clear session
// cookie/storage, unless this is a crash recovery.
@ -633,9 +654,17 @@ StartupBrowserCreatorImpl::DetermineBrowserOpenBehavior(
// function. If Chrome was launched with passed URLs, assume these should
// be appended to an existing window if possible, unless overridden by a
// switch.
return ((options & HAS_CMD_LINE_TABS) && !(options & HAS_NEW_WINDOW_SWITCH))
? BrowserOpenBehavior::USE_EXISTING
: BrowserOpenBehavior::NEW;
if (options & HAS_CMD_LINE_TABS && !(options & HAS_NEW_WINDOW_SWITCH)) {
// If not a new window and the kSameTab switch is included then the
// active tab will be overwritten (if one exists).
if (options & HAS_SAME_TAB_SWITCH) {
return BrowserOpenBehavior::USE_EXISTING_AND_OVERWRITE_ACTIVE_TAB;
}
return BrowserOpenBehavior::USE_EXISTING;
}
return BrowserOpenBehavior::NEW;
}
if (pref.ShouldRestoreLastSession()) {

@ -129,6 +129,8 @@ class StartupBrowserCreatorImpl {
NEW, // Open in a new browser.
SYNCHRONOUS_RESTORE, // Attempt a synchronous session restore.
USE_EXISTING, // Attempt to add to an existing tabbed browser.
USE_EXISTING_AND_OVERWRITE_ACTIVE_TAB, // Attempt to replace the contents
// of the active tab
};
// Boolean flags used to indicate state for DetermineBrowserOpenBehavior.
@ -137,6 +139,12 @@ class StartupBrowserCreatorImpl {
IS_POST_CRASH_LAUNCH = (1 << 1),
HAS_NEW_WINDOW_SWITCH = (1 << 2),
HAS_CMD_LINE_TABS = (1 << 3),
HAS_SAME_TAB_SWITCH = (1 << 4)
};
enum class TabOverWrite {
kYes, // If the tab needs to be overwritten
kNo, // Default behavior
};
using BrowserOpenBehaviorOptions = uint32_t;
@ -148,7 +156,8 @@ class StartupBrowserCreatorImpl {
// browser, or nullptr if browser could not be created.
Browser* OpenTabsInBrowser(Browser* browser,
chrome::startup::IsProcessStartup process_startup,
const StartupTabs& tabs);
const StartupTabs& tabs,
TabOverWrite is_active_tab_overwrite);
// Determines the URLs to be shown at startup by way of various policies
// (welcome, pinned tabs, etc.), determines whether a session restore

@ -542,6 +542,11 @@ const char kRestart[] = "restart";
// on OS X and Windows.
const char kRestoreLastSession[] = "restore-last-session";
// Indicates that the URL in the command line should open in the active tab
// instead of a new tab. In case of multiple URLS given as arguments, the
// first one will replace the active tab.
const char kSameTab[] = "same-tab";
// This flag sets the checkboxes for sharing audio during screen capture to off
// by default. It is primarily intended to be used for tests.
const char kScreenCaptureAudioDefaultUnchecked[] =

@ -162,6 +162,7 @@ extern const char kProxyServer[];
extern const char kRemoteDebuggingTargets[];
extern const char kRestart[];
extern const char kRestoreLastSession[];
extern const char kSameTab[];
extern const char kScreenCaptureAudioDefaultUnchecked[];
extern const char kSilentDebuggerExtensionAPI[];
extern const char kSilentLaunch[];