Files
brave-core/browser/ui/brave_browser_command_controller.h
T
Simon HongandSangwoo Ko 5a93904f1c Enabled immersive fullscreen mode on macOS (#34663)
Resolves brave/brave-browser#53601

Enables macOS immersive fullscreen (auto-hiding toolbar on hover) for the browser
when horizontal tabs are in use. When vertical tabs are active, immersive fullscreen
is disabled and the browser falls back to standard fullscreen behavior. Additionally,
switching to vertical tab mode is blocked while the browser is in fullscreen.

Immersive fullscreen and vertical tab mode both use their own separate widgets for
hosting the tab strip, which means both refer to the same tab strip simultaneously.
This conflict requires more work to resolve properly, so immersive fullscreen is
disabled when vertical tabs are active for now.

IDC_TOGGLE_VERTICAL_TABS command enabled state is used as the single source of truth
for whether the vertical tabs toggle is available. BraveBrowserCommandController
overrides UpdateCommandsForFullscreenMode() to disable this command on macOS when
entering fullscreen. All surfaces — ToggleVerticalTabStrip(), the tab strip context
menu, the system menu, IsVerticalTabToggleEnabled(), and the settings page — derive
their state from this command rather than querying fullscreen state independently.
BraveAppearanceHandler implements CommandObserver to watch IDC_TOGGLE_VERTICAL_TABS
and push state changes to the settings UI via a WebUI event.

TEST=BraveBrowserCommandControllerTest.VerticalTabToggleEnabledState

Co-authored-by: Sangwoo Ko <sangwoo108@gmail.com>
2026-03-17 15:08:48 +09:00

120 lines
4.1 KiB
C++

/* Copyright (c) 2019 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/. */
#ifndef BRAVE_BROWSER_UI_BRAVE_BROWSER_COMMAND_CONTROLLER_H_
#define BRAVE_BROWSER_UI_BRAVE_BROWSER_COMMAND_CONTROLLER_H_
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "base/memory/raw_ref.h"
#include "base/scoped_observation.h"
#include "brave/components/brave_vpn/common/buildflags/buildflags.h"
#include "brave/components/tor/buildflags/buildflags.h"
#include "chrome/browser/ui/browser_command_controller.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "components/prefs/pref_change_registrar.h"
#if BUILDFLAG(ENABLE_BRAVE_VPN)
#include "brave/components/brave_vpn/browser/brave_vpn_service_observer.h"
#endif
class BraveAppMenuBrowserTest;
class BraveAppMenuModelBrowserTest;
class BraveBrowserCommandControllerTest;
enum class TabChangeType;
namespace content {
class WebContents;
}
// This namespace is needed for a chromium_src override
namespace chrome {
class BraveBrowserCommandController : public chrome::BrowserCommandController
#if BUILDFLAG(ENABLE_BRAVE_VPN)
,
public brave_vpn::BraveVPNServiceObserver
#endif
{
public:
explicit BraveBrowserCommandController(BrowserWindowInterface* bwi);
BraveBrowserCommandController(const BraveBrowserCommandController&) = delete;
BraveBrowserCommandController& operator=(
const BraveBrowserCommandController&) = delete;
~BraveBrowserCommandController() override;
#if BUILDFLAG(ENABLE_TOR)
void UpdateCommandForTor();
#endif
protected:
void OnTabChangedAt(tabs::TabInterface* tab,
int index,
TabChangeType change_type) override;
void OnTabPinnedStateChanged(tabs::TabInterface* tab, int index) override;
void OnTabStripModelChanged(
TabStripModel* tab_strip_model,
const TabStripModelChange& change,
const TabStripSelectionChange& selection) override;
void OnTabGroupChanged(const TabGroupChange& change) override;
void OnSplitTabChanged(const SplitTabChange& change) override;
void UpdateCommandsForFullscreenMode() override;
private:
friend class ::BraveAppMenuBrowserTest;
friend class ::BraveAppMenuModelBrowserTest;
friend class ::BraveBrowserCommandControllerTest;
// Overriden from CommandUpdater:
bool SupportsCommand(int id) const override;
bool IsCommandEnabled(int id) const override;
bool ExecuteCommandWithDisposition(
int id,
WindowOpenDisposition disposition,
base::TimeTicks time_stamp = base::TimeTicks::Now()) override;
void AddCommandObserver(int id, CommandObserver* observer) override;
void RemoveCommandObserver(int id, CommandObserver* observer) override;
void RemoveCommandObserver(CommandObserver* observer) override;
bool UpdateCommandEnabled(int id, bool state) override;
#if BUILDFLAG(ENABLE_BRAVE_VPN)
// brave_vpn::BraveVPNServiceObserver overrides:
void OnPurchasedStateChanged(
brave_vpn::mojom::PurchasedState state,
const std::optional<std::string>& description) override;
#endif
void InitBraveCommandState();
void UpdateCommandForBraveRewards();
void UpdateCommandForWebcompatReporter();
void UpdateCommandForBraveSync();
void UpdateCommandForBraveWallet();
void UpdateCommandForSidebar();
void UpdateCommandForAIChat();
void UpdateCommandForBraveVPN();
void UpdateCommandForPlaylist();
void UpdateCommandForWaybackMachine();
void UpdateCommandsForTabs();
void UpdateCommandsForSend();
void UpdateCommandsForPin();
void UpdateCommandForSplitView();
bool ExecuteBraveCommandWithDisposition(int id,
WindowOpenDisposition disposition,
base::TimeTicks time_stamp);
PrefChangeRegistrar pref_change_registrar_;
const raw_ref<Browser> browser_;
CommandUpdaterImpl brave_command_updater_;
};
} // namespace chrome
#endif // BRAVE_BROWSER_UI_BRAVE_BROWSER_COMMAND_CONTROLLER_H_