Commit b6d37d2e authored by spqchan's avatar spqchan Committed by Commit bot

[Mac] Fullscreen Touch Bar Support

When in tab fullscreen, replace the ESC button with "Exit Fullscreen"
and display the origin URL of the tab content in the Touch Bar.

A test for this is added in BrowserTouchBarUnitTest

BUG=690611

Review-Url: https://codereview.chromium.org/2816743006
Cr-Commit-Position: refs/heads/master@{#468099}
parent 20c0b305
......@@ -247,6 +247,11 @@ BASE_EXPORT extern NSString* const CIDetectorTypeText;
action:(SEL)action;
@end
@interface NSTextField (SierraPointOneSDK)
+ (instancetype)labelWithAttributedString:
(NSAttributedString*)attributedStringValue;
@end
@interface NSApplication (SierraPointOneSDK)
@property BOOL automaticCustomizeTouchBarMenuItemEnabled;
@end
......
......@@ -1960,6 +1960,9 @@ From <ph name="DOWNLOAD_DOMAIN">$3<ex>example.com</ex></ph>
desc="Customization label for the new tab button in the touch bar.">
New Tab
</message>
<message name="IDS_TOUCH_BAR_EXIT_FULLSCREEN" desc="Text for the exit fullscreen button in the touch bar.">
Exit Full Screen
</message>
</if>
<!-- Remove in-progress downloads confirmation dialog -->
......
......@@ -669,6 +669,8 @@ willPositionSheet:(NSWindow*)sheet
[[tabStripController_ activeTabContentsController]
updateFullscreenWidgetFrame];
[self invalidateTouchBar];
[self showFullscreenExitBubbleIfNecessary];
browser_->WindowFullscreenStateChanged();
......@@ -727,6 +729,8 @@ willPositionSheet:(NSWindow*)sheet
[self resetCustomAppKitFullscreenVariables];
[self invalidateTouchBar];
// Ensures that the permission bubble shows up properly at the front.
PermissionRequestManager* manager = [self permissionRequestManager];
if (manager && manager->IsBubbleVisible()) {
......
......@@ -22,6 +22,9 @@ class Browser;
// True if the current page is starred. Used by star touch bar button.
@property(nonatomic, assign) BOOL isStarred;
// Returns a touch bar item identifier for the given |id|.
+ (NSString*)touchBarIdForItemId:(NSString*)id;
// Designated initializer.
- (instancetype)initWithBrowser:(Browser*)browser
browserWindowController:(BrowserWindowController*)bwc;
......
......@@ -20,6 +20,10 @@
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_command_controller.h"
#import "chrome/browser/ui/cocoa/browser_window_controller.h"
#import "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h"
#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
......@@ -28,6 +32,7 @@
#include "components/search_engines/util.h"
#include "components/strings/grit/components_strings.h"
#include "components/toolbar/vector_icons.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_mac.h"
#include "ui/gfx/color_palette.h"
......@@ -63,6 +68,8 @@ NSString* const kHomeTouchId = @"HOME";
NSString* const kSearchTouchId = @"SEARCH";
NSString* const kStarTouchId = @"BOOKMARK";
NSString* const kNewTabTouchId = @"NEW-TAB";
NSString* const kExitFullscreenTouchId = @"EXIT-FULLSCREEN";
NSString* const kFullscreenOriginLabelTouchId = @"FULLSCREEN-ORIGIN-LABEL";
// The button indexes in the back and forward segment control.
const int kBackSegmentIndex = 0;
......@@ -101,16 +108,11 @@ NSButton* CreateTouchBarButton(const gfx::VectorIcon& icon,
return button;
}
NSString* GetTouchBarId(NSString* const touch_bar_id) {
NSString* GetTouchBarId() {
NSString* chrome_bundle_id =
base::SysUTF8ToNSString(base::mac::BaseBundleID());
return [NSString stringWithFormat:@"%@.%@", chrome_bundle_id, touch_bar_id];
}
NSString* GetTouchBarItemId(NSString* const touch_bar_id,
NSString* const item_id) {
return [NSString
stringWithFormat:@"%@-%@", GetTouchBarId(touch_bar_id), item_id];
stringWithFormat:@"%@.%@", chrome_bundle_id, kBrowserWindowTouchBarId];
}
TouchBarAction TouchBarActionFromCommand(int command) {
......@@ -191,6 +193,10 @@ class HomePrefNotificationBridge {
@synthesize isPageLoading = isPageLoading_;
@synthesize isStarred = isStarred_;
+ (NSString*)touchBarIdForItemId:(NSString*)id {
return [NSString stringWithFormat:@"%@-%@", GetTouchBarId(), id];
}
- (instancetype)initWithBrowser:(Browser*)browser
browserWindowController:(BrowserWindowController*)bwc {
if ((self = [self init])) {
......@@ -216,6 +222,25 @@ class HomePrefNotificationBridge {
base::scoped_nsobject<NSTouchBar> touchBar(
[[NSClassFromString(@"NSTouchBar") alloc] init]);
[touchBar setCustomizationIdentifier:GetTouchBarId()];
[touchBar setDelegate:self];
// When in tab fullscreen, only the option to exit fullscreen should show up
// on the touch bar since the toolbar is hidden in that state.
if ([bwc_ isFullscreenForTabContentOrExtension]) {
if ([touchBar respondsToSelector:
@selector(setEscapeKeyReplacementItemIdentifier:)]) {
[touchBar setEscapeKeyReplacementItemIdentifier:
[BrowserWindowTouchBar
touchBarIdForItemId:kExitFullscreenTouchId]];
[touchBar setDefaultItemIdentifiers:@[
[BrowserWindowTouchBar
touchBarIdForItemId:kFullscreenOriginLabelTouchId]
]];
}
return touchBar.autorelease();
}
NSMutableArray* customIdentifiers = [NSMutableArray arrayWithCapacity:7];
NSMutableArray* defaultIdentifiers = [NSMutableArray arrayWithCapacity:6];
......@@ -225,8 +250,7 @@ class HomePrefNotificationBridge {
];
for (NSString* item in touchBarItems) {
NSString* itemIdentifier =
GetTouchBarItemId(kBrowserWindowTouchBarId, item);
NSString* itemIdentifier = [BrowserWindowTouchBar touchBarIdForItemId:item];
[customIdentifiers addObject:itemIdentifier];
// Don't add the home button if it's not shown in the toolbar.
......@@ -236,10 +260,8 @@ class HomePrefNotificationBridge {
[customIdentifiers addObject:NSTouchBarItemIdentifierFlexibleSpace];
[touchBar setCustomizationIdentifier:GetTouchBarId(kBrowserWindowTouchBarId)];
[touchBar setDefaultItemIdentifiers:defaultIdentifiers];
[touchBar setCustomizationAllowedItemIdentifiers:customIdentifiers];
[touchBar setDelegate:self];
return touchBar.autorelease();
}
......@@ -294,6 +316,29 @@ class HomePrefNotificationBridge {
[touchBarItem setView:[self searchTouchBarView]];
[touchBarItem setCustomizationLabel:l10n_util::GetNSString(
IDS_TOUCH_BAR_GOOGLE_SEARCH)];
} else if ([identifier hasSuffix:kExitFullscreenTouchId]) {
NSButton* button = [NSButton
buttonWithTitle:l10n_util::GetNSString(IDS_TOUCH_BAR_EXIT_FULLSCREEN)
target:self
action:@selector(exitFullscreenForTab:)];
[touchBarItem setView:button];
} else if ([identifier hasSuffix:kFullscreenOriginLabelTouchId]) {
content::WebContents* contents =
browser_->tab_strip_model()->GetActiveWebContents();
GURL originUrl = contents->GetLastCommittedURL();
base::string16 displayText = base::ASCIIToUTF16(originUrl.GetContent());
size_t hostLength = originUrl.host().length();
base::scoped_nsobject<NSMutableAttributedString> attributedString(
[[NSMutableAttributedString alloc]
initWithString:base::SysUTF16ToNSString(displayText)]);
[attributedString
addAttribute:NSForegroundColorAttributeName
value:OmniboxViewMac::BaseTextColor(true)
range:NSMakeRange(hostLength,
[attributedString length] - hostLength)];
[touchBarItem
setView:[NSTextField labelWithAttributedString:attributedString.get()]];
}
return touchBarItem.autorelease();
......@@ -381,6 +426,12 @@ class HomePrefNotificationBridge {
commandUpdater_->ExecuteCommand(command);
}
- (void)exitFullscreenForTab:(id)sender {
browser_->exclusive_access_manager()
->fullscreen_controller()
->ExitExclusiveAccessIfNecessary();
}
- (void)executeCommand:(id)sender {
int command = [sender tag];
LogTouchBarUMA(command);
......
......@@ -4,72 +4,131 @@
#import <Cocoa/Cocoa.h>
#include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/app/chrome_command_ids.h"
#import "chrome/browser/ui/cocoa/browser_window_controller.h"
#import "chrome/browser/ui/cocoa/browser_window_touch_bar.h"
#include "chrome/browser/ui/cocoa/test/cocoa_profile_test.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "testing/gtest/include/gtest/gtest.h"
#import "third_party/ocmock/OCMock/OCMock.h"
class BrowserWindowTouchBarUnitTest : public CocoaProfileTest {
public:
void SetUp() override {
CocoaProfileTest::SetUp();
ASSERT_TRUE(browser());
browserWindowTouchBar_.reset([[BrowserWindowTouchBar alloc]
initWithBrowser:browser()
browserWindowController:nil]);
feature_list.InitAndEnableFeature(features::kBrowserTouchBar);
BOOL yes = YES;
bwc_ = [OCMockObject mockForClass:[BrowserWindowController class]];
[[[bwc_ stub] andReturnValue:OCMOCK_VALUE(yes)]
isKindOfClass:[BrowserWindowController class]];
[[bwc_ stub] invalidateTouchBar];
touch_bar_.reset([[BrowserWindowTouchBar alloc] initWithBrowser:browser()
browserWindowController:bwc_]);
}
id bwc() const { return bwc_; }
void TearDown() override { CocoaProfileTest::TearDown(); }
base::scoped_nsobject<BrowserWindowTouchBar> browserWindowTouchBar_;
// A mock BrowserWindowController object.
id bwc_;
// Used to enable the the browser window touch bar.
base::test::ScopedFeatureList feature_list;
base::scoped_nsobject<BrowserWindowTouchBar> touch_bar_;
};
// Tests to check if the touch bar contains the correct items.
TEST_F(BrowserWindowTouchBarUnitTest, TouchBarItems) {
if (!base::mac::IsAtLeastOS10_12())
return;
BOOL yes = YES;
[[[bwc() expect] andReturnValue:OCMOCK_VALUE(yes)]
isFullscreenForTabContentOrExtension];
PrefService* prefs = profile()->GetPrefs();
DCHECK(prefs);
prefs->SetBoolean(prefs::kShowHomeButton, true);
NSArray* touchBarItemIds =
[[browserWindowTouchBar_ makeTouchBar] itemIdentifiers];
EXPECT_TRUE([touchBarItemIds containsObject:@"BackForwardTouchId"]);
EXPECT_TRUE([touchBarItemIds containsObject:@"ReloadOrStopTouchId"]);
EXPECT_TRUE([touchBarItemIds containsObject:@"HomeTouchId"]);
EXPECT_TRUE([touchBarItemIds containsObject:@"SearchTouchId"]);
EXPECT_TRUE([touchBarItemIds containsObject:@"NewTabTouchId"]);
EXPECT_TRUE([touchBarItemIds containsObject:@"StarTouchId"]);
// The touch bar should be empty since the toolbar is hidden when the browser
// is in tab fullscreen.
NSTouchBar* touch_bar = [touch_bar_ makeTouchBar];
NSArray* touch_bar_items = [touch_bar itemIdentifiers];
EXPECT_TRUE([touch_bar_items
containsObject:[BrowserWindowTouchBar
touchBarIdForItemId:@"FULLSCREEN-ORIGIN-LABEL"]]);
EXPECT_TRUE([[touch_bar escapeKeyReplacementItemIdentifier]
isEqualToString:[BrowserWindowTouchBar
touchBarIdForItemId:@"EXIT-FULLSCREEN"]]);
BOOL no = NO;
[[[bwc() stub] andReturnValue:OCMOCK_VALUE(no)]
isFullscreenForTabContentOrExtension];
touch_bar_items = [[touch_bar_ makeTouchBar] itemIdentifiers];
EXPECT_TRUE([touch_bar_items
containsObject:[BrowserWindowTouchBar touchBarIdForItemId:@"BACK-FWD"]]);
EXPECT_TRUE(
[touch_bar_items containsObject:[BrowserWindowTouchBar
touchBarIdForItemId:@"RELOAD-STOP"]]);
EXPECT_TRUE([touch_bar_items
containsObject:[BrowserWindowTouchBar touchBarIdForItemId:@"HOME"]]);
EXPECT_TRUE([touch_bar_items
containsObject:[BrowserWindowTouchBar touchBarIdForItemId:@"SEARCH"]]);
EXPECT_TRUE([touch_bar_items
containsObject:[BrowserWindowTouchBar touchBarIdForItemId:@"BOOKMARK"]]);
EXPECT_TRUE([touch_bar_items
containsObject:[BrowserWindowTouchBar touchBarIdForItemId:@"NEW-TAB"]]);
prefs->SetBoolean(prefs::kShowHomeButton, false);
touchBarItemIds = [[browserWindowTouchBar_ makeTouchBar] itemIdentifiers];
EXPECT_TRUE([touchBarItemIds containsObject:@"BackForwardTouchId"]);
EXPECT_TRUE([touchBarItemIds containsObject:@"ReloadOrStopTouchId"]);
EXPECT_FALSE([touchBarItemIds containsObject:@"HomeTouchId"]);
EXPECT_TRUE([touchBarItemIds containsObject:@"SearchTouchId"]);
EXPECT_TRUE([touchBarItemIds containsObject:@"NewTabTouchId"]);
EXPECT_TRUE([touchBarItemIds containsObject:@"StarTouchId"]);
touch_bar_items = [[touch_bar_ makeTouchBar] itemIdentifiers];
EXPECT_TRUE([touch_bar_items
containsObject:[BrowserWindowTouchBar touchBarIdForItemId:@"BACK-FWD"]]);
EXPECT_TRUE(
[touch_bar_items containsObject:[BrowserWindowTouchBar
touchBarIdForItemId:@"RELOAD-STOP"]]);
EXPECT_TRUE([touch_bar_items
containsObject:[BrowserWindowTouchBar touchBarIdForItemId:@"SEARCH"]]);
EXPECT_TRUE([touch_bar_items
containsObject:[BrowserWindowTouchBar touchBarIdForItemId:@"BOOKMARK"]]);
EXPECT_TRUE([touch_bar_items
containsObject:[BrowserWindowTouchBar touchBarIdForItemId:@"NEW-TAB"]]);
}
// Tests the reload or stop touch bar item.
TEST_F(BrowserWindowTouchBarUnitTest, ReloadOrStopTouchBarItem) {
if (!base::mac::IsAtLeastOS10_12())
return;
NSTouchBar* touchBar = [browserWindowTouchBar_ makeTouchBar];
[browserWindowTouchBar_ setIsPageLoading:NO];
NSTouchBarItem* item =
[browserWindowTouchBar_ touchBar:touchBar
makeItemForIdentifier:@"ReloadOrStopTouchId"];
BOOL no = NO;
[[[bwc() stub] andReturnValue:OCMOCK_VALUE(no)]
isFullscreenForTabContentOrExtension];
EXPECT_EQ(IDC_RELOAD, [[item view] tag]);
NSTouchBar* touch_bar = [touch_bar_ makeTouchBar];
[touch_bar_ setIsPageLoading:NO];
[browserWindowTouchBar_ setIsPageLoading:YES];
item = [browserWindowTouchBar_ touchBar:touchBar
makeItemForIdentifier:@"ReloadOrStopTouchId"];
NSTouchBarItem* item =
[touch_bar_ touchBar:touch_bar
makeItemForIdentifier:[BrowserWindowTouchBar
touchBarIdForItemId:@"RELOAD-STOP"]];
EXPECT_EQ(IDC_RELOAD, [[item view] tag]);
[touch_bar_ setIsPageLoading:YES];
item = [touch_bar_ touchBar:touch_bar
makeItemForIdentifier:[BrowserWindowTouchBar
touchBarIdForItemId:@"RELOAD-STOP"]];
EXPECT_EQ(IDC_STOP, [[item view] tag]);
}
......@@ -118,6 +118,16 @@ UI_BASE_EXPORT extern NSString* const NSTouchBarItemIdentifierFlexibleSpace;
#endif // MAC_OS_X_VERSION_10_12_1
} // extern "C"
#if !defined(MAC_OS_X_VERSION_10_12_2) || \
MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12_2
@interface NSTouchBar (SierraPointTwoSDK)
@property(copy, nullable)
NSTouchBarItemIdentifier escapeKeyReplacementItemIdentifier;
@end
#endif // MAC_OS_X_VERSION_10_12_2
#pragma clang assume_nonnull end
#endif // UI_BASE_COCOA_TOUCH_BAR_FORWARD_DECLARATIONS_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment