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; ...@@ -247,6 +247,11 @@ BASE_EXPORT extern NSString* const CIDetectorTypeText;
action:(SEL)action; action:(SEL)action;
@end @end
@interface NSTextField (SierraPointOneSDK)
+ (instancetype)labelWithAttributedString:
(NSAttributedString*)attributedStringValue;
@end
@interface NSApplication (SierraPointOneSDK) @interface NSApplication (SierraPointOneSDK)
@property BOOL automaticCustomizeTouchBarMenuItemEnabled; @property BOOL automaticCustomizeTouchBarMenuItemEnabled;
@end @end
......
...@@ -1960,6 +1960,9 @@ From <ph name="DOWNLOAD_DOMAIN">$3<ex>example.com</ex></ph> ...@@ -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."> desc="Customization label for the new tab button in the touch bar.">
New Tab New Tab
</message> </message>
<message name="IDS_TOUCH_BAR_EXIT_FULLSCREEN" desc="Text for the exit fullscreen button in the touch bar.">
Exit Full Screen
</message>
</if> </if>
<!-- Remove in-progress downloads confirmation dialog --> <!-- Remove in-progress downloads confirmation dialog -->
......
...@@ -669,6 +669,8 @@ willPositionSheet:(NSWindow*)sheet ...@@ -669,6 +669,8 @@ willPositionSheet:(NSWindow*)sheet
[[tabStripController_ activeTabContentsController] [[tabStripController_ activeTabContentsController]
updateFullscreenWidgetFrame]; updateFullscreenWidgetFrame];
[self invalidateTouchBar];
[self showFullscreenExitBubbleIfNecessary]; [self showFullscreenExitBubbleIfNecessary];
browser_->WindowFullscreenStateChanged(); browser_->WindowFullscreenStateChanged();
...@@ -727,6 +729,8 @@ willPositionSheet:(NSWindow*)sheet ...@@ -727,6 +729,8 @@ willPositionSheet:(NSWindow*)sheet
[self resetCustomAppKitFullscreenVariables]; [self resetCustomAppKitFullscreenVariables];
[self invalidateTouchBar];
// Ensures that the permission bubble shows up properly at the front. // Ensures that the permission bubble shows up properly at the front.
PermissionRequestManager* manager = [self permissionRequestManager]; PermissionRequestManager* manager = [self permissionRequestManager];
if (manager && manager->IsBubbleVisible()) { if (manager && manager->IsBubbleVisible()) {
......
...@@ -22,6 +22,9 @@ class Browser; ...@@ -22,6 +22,9 @@ class Browser;
// True if the current page is starred. Used by star touch bar button. // True if the current page is starred. Used by star touch bar button.
@property(nonatomic, assign) BOOL isStarred; @property(nonatomic, assign) BOOL isStarred;
// Returns a touch bar item identifier for the given |id|.
+ (NSString*)touchBarIdForItemId:(NSString*)id;
// Designated initializer. // Designated initializer.
- (instancetype)initWithBrowser:(Browser*)browser - (instancetype)initWithBrowser:(Browser*)browser
browserWindowController:(BrowserWindowController*)bwc; browserWindowController:(BrowserWindowController*)bwc;
......
...@@ -20,6 +20,10 @@ ...@@ -20,6 +20,10 @@
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_command_controller.h" #include "chrome/browser/ui/browser_command_controller.h"
#import "chrome/browser/ui/cocoa/browser_window_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/chrome_features.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
...@@ -28,6 +32,7 @@ ...@@ -28,6 +32,7 @@
#include "components/search_engines/util.h" #include "components/search_engines/util.h"
#include "components/strings/grit/components_strings.h" #include "components/strings/grit/components_strings.h"
#include "components/toolbar/vector_icons.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.h"
#include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/l10n/l10n_util_mac.h"
#include "ui/gfx/color_palette.h" #include "ui/gfx/color_palette.h"
...@@ -63,6 +68,8 @@ NSString* const kHomeTouchId = @"HOME"; ...@@ -63,6 +68,8 @@ NSString* const kHomeTouchId = @"HOME";
NSString* const kSearchTouchId = @"SEARCH"; NSString* const kSearchTouchId = @"SEARCH";
NSString* const kStarTouchId = @"BOOKMARK"; NSString* const kStarTouchId = @"BOOKMARK";
NSString* const kNewTabTouchId = @"NEW-TAB"; 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. // The button indexes in the back and forward segment control.
const int kBackSegmentIndex = 0; const int kBackSegmentIndex = 0;
...@@ -101,16 +108,11 @@ NSButton* CreateTouchBarButton(const gfx::VectorIcon& icon, ...@@ -101,16 +108,11 @@ NSButton* CreateTouchBarButton(const gfx::VectorIcon& icon,
return button; return button;
} }
NSString* GetTouchBarId(NSString* const touch_bar_id) { NSString* GetTouchBarId() {
NSString* chrome_bundle_id = NSString* chrome_bundle_id =
base::SysUTF8ToNSString(base::mac::BaseBundleID()); 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 return [NSString
stringWithFormat:@"%@-%@", GetTouchBarId(touch_bar_id), item_id]; stringWithFormat:@"%@.%@", chrome_bundle_id, kBrowserWindowTouchBarId];
} }
TouchBarAction TouchBarActionFromCommand(int command) { TouchBarAction TouchBarActionFromCommand(int command) {
...@@ -191,6 +193,10 @@ class HomePrefNotificationBridge { ...@@ -191,6 +193,10 @@ class HomePrefNotificationBridge {
@synthesize isPageLoading = isPageLoading_; @synthesize isPageLoading = isPageLoading_;
@synthesize isStarred = isStarred_; @synthesize isStarred = isStarred_;
+ (NSString*)touchBarIdForItemId:(NSString*)id {
return [NSString stringWithFormat:@"%@-%@", GetTouchBarId(), id];
}
- (instancetype)initWithBrowser:(Browser*)browser - (instancetype)initWithBrowser:(Browser*)browser
browserWindowController:(BrowserWindowController*)bwc { browserWindowController:(BrowserWindowController*)bwc {
if ((self = [self init])) { if ((self = [self init])) {
...@@ -216,6 +222,25 @@ class HomePrefNotificationBridge { ...@@ -216,6 +222,25 @@ class HomePrefNotificationBridge {
base::scoped_nsobject<NSTouchBar> touchBar( base::scoped_nsobject<NSTouchBar> touchBar(
[[NSClassFromString(@"NSTouchBar") alloc] init]); [[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* customIdentifiers = [NSMutableArray arrayWithCapacity:7];
NSMutableArray* defaultIdentifiers = [NSMutableArray arrayWithCapacity:6]; NSMutableArray* defaultIdentifiers = [NSMutableArray arrayWithCapacity:6];
...@@ -225,8 +250,7 @@ class HomePrefNotificationBridge { ...@@ -225,8 +250,7 @@ class HomePrefNotificationBridge {
]; ];
for (NSString* item in touchBarItems) { for (NSString* item in touchBarItems) {
NSString* itemIdentifier = NSString* itemIdentifier = [BrowserWindowTouchBar touchBarIdForItemId:item];
GetTouchBarItemId(kBrowserWindowTouchBarId, item);
[customIdentifiers addObject:itemIdentifier]; [customIdentifiers addObject:itemIdentifier];
// Don't add the home button if it's not shown in the toolbar. // Don't add the home button if it's not shown in the toolbar.
...@@ -236,10 +260,8 @@ class HomePrefNotificationBridge { ...@@ -236,10 +260,8 @@ class HomePrefNotificationBridge {
[customIdentifiers addObject:NSTouchBarItemIdentifierFlexibleSpace]; [customIdentifiers addObject:NSTouchBarItemIdentifierFlexibleSpace];
[touchBar setCustomizationIdentifier:GetTouchBarId(kBrowserWindowTouchBarId)];
[touchBar setDefaultItemIdentifiers:defaultIdentifiers]; [touchBar setDefaultItemIdentifiers:defaultIdentifiers];
[touchBar setCustomizationAllowedItemIdentifiers:customIdentifiers]; [touchBar setCustomizationAllowedItemIdentifiers:customIdentifiers];
[touchBar setDelegate:self];
return touchBar.autorelease(); return touchBar.autorelease();
} }
...@@ -294,6 +316,29 @@ class HomePrefNotificationBridge { ...@@ -294,6 +316,29 @@ class HomePrefNotificationBridge {
[touchBarItem setView:[self searchTouchBarView]]; [touchBarItem setView:[self searchTouchBarView]];
[touchBarItem setCustomizationLabel:l10n_util::GetNSString( [touchBarItem setCustomizationLabel:l10n_util::GetNSString(
IDS_TOUCH_BAR_GOOGLE_SEARCH)]; 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(); return touchBarItem.autorelease();
...@@ -381,6 +426,12 @@ class HomePrefNotificationBridge { ...@@ -381,6 +426,12 @@ class HomePrefNotificationBridge {
commandUpdater_->ExecuteCommand(command); commandUpdater_->ExecuteCommand(command);
} }
- (void)exitFullscreenForTab:(id)sender {
browser_->exclusive_access_manager()
->fullscreen_controller()
->ExitExclusiveAccessIfNecessary();
}
- (void)executeCommand:(id)sender { - (void)executeCommand:(id)sender {
int command = [sender tag]; int command = [sender tag];
LogTouchBarUMA(command); LogTouchBarUMA(command);
......
...@@ -4,72 +4,131 @@ ...@@ -4,72 +4,131 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h" #include "base/mac/mac_util.h"
#include "base/mac/scoped_nsobject.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" #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" #import "chrome/browser/ui/cocoa/browser_window_touch_bar.h"
#include "chrome/browser/ui/cocoa/test/cocoa_profile_test.h" #include "chrome/browser/ui/cocoa/test/cocoa_profile_test.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#import "third_party/ocmock/OCMock/OCMock.h"
class BrowserWindowTouchBarUnitTest : public CocoaProfileTest { class BrowserWindowTouchBarUnitTest : public CocoaProfileTest {
public: public:
void SetUp() override { void SetUp() override {
CocoaProfileTest::SetUp(); CocoaProfileTest::SetUp();
ASSERT_TRUE(browser()); ASSERT_TRUE(browser());
browserWindowTouchBar_.reset([[BrowserWindowTouchBar alloc]
initWithBrowser:browser() feature_list.InitAndEnableFeature(features::kBrowserTouchBar);
browserWindowController:nil]);
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(); } 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) { TEST_F(BrowserWindowTouchBarUnitTest, TouchBarItems) {
if (!base::mac::IsAtLeastOS10_12()) if (!base::mac::IsAtLeastOS10_12())
return; return;
BOOL yes = YES;
[[[bwc() expect] andReturnValue:OCMOCK_VALUE(yes)]
isFullscreenForTabContentOrExtension];
PrefService* prefs = profile()->GetPrefs(); PrefService* prefs = profile()->GetPrefs();
DCHECK(prefs); DCHECK(prefs);
prefs->SetBoolean(prefs::kShowHomeButton, true); prefs->SetBoolean(prefs::kShowHomeButton, true);
NSArray* touchBarItemIds = // The touch bar should be empty since the toolbar is hidden when the browser
[[browserWindowTouchBar_ makeTouchBar] itemIdentifiers]; // is in tab fullscreen.
EXPECT_TRUE([touchBarItemIds containsObject:@"BackForwardTouchId"]); NSTouchBar* touch_bar = [touch_bar_ makeTouchBar];
EXPECT_TRUE([touchBarItemIds containsObject:@"ReloadOrStopTouchId"]); NSArray* touch_bar_items = [touch_bar itemIdentifiers];
EXPECT_TRUE([touchBarItemIds containsObject:@"HomeTouchId"]); EXPECT_TRUE([touch_bar_items
EXPECT_TRUE([touchBarItemIds containsObject:@"SearchTouchId"]); containsObject:[BrowserWindowTouchBar
EXPECT_TRUE([touchBarItemIds containsObject:@"NewTabTouchId"]); touchBarIdForItemId:@"FULLSCREEN-ORIGIN-LABEL"]]);
EXPECT_TRUE([touchBarItemIds containsObject:@"StarTouchId"]); 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); prefs->SetBoolean(prefs::kShowHomeButton, false);
touchBarItemIds = [[browserWindowTouchBar_ makeTouchBar] itemIdentifiers]; touch_bar_items = [[touch_bar_ makeTouchBar] itemIdentifiers];
EXPECT_TRUE([touchBarItemIds containsObject:@"BackForwardTouchId"]); EXPECT_TRUE([touch_bar_items
EXPECT_TRUE([touchBarItemIds containsObject:@"ReloadOrStopTouchId"]); containsObject:[BrowserWindowTouchBar touchBarIdForItemId:@"BACK-FWD"]]);
EXPECT_FALSE([touchBarItemIds containsObject:@"HomeTouchId"]); EXPECT_TRUE(
EXPECT_TRUE([touchBarItemIds containsObject:@"SearchTouchId"]); [touch_bar_items containsObject:[BrowserWindowTouchBar
EXPECT_TRUE([touchBarItemIds containsObject:@"NewTabTouchId"]); touchBarIdForItemId:@"RELOAD-STOP"]]);
EXPECT_TRUE([touchBarItemIds containsObject:@"StarTouchId"]); 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) { TEST_F(BrowserWindowTouchBarUnitTest, ReloadOrStopTouchBarItem) {
if (!base::mac::IsAtLeastOS10_12()) if (!base::mac::IsAtLeastOS10_12())
return; return;
NSTouchBar* touchBar = [browserWindowTouchBar_ makeTouchBar]; BOOL no = NO;
[browserWindowTouchBar_ setIsPageLoading:NO]; [[[bwc() stub] andReturnValue:OCMOCK_VALUE(no)]
NSTouchBarItem* item = isFullscreenForTabContentOrExtension];
[browserWindowTouchBar_ touchBar:touchBar
makeItemForIdentifier:@"ReloadOrStopTouchId"];
EXPECT_EQ(IDC_RELOAD, [[item view] tag]); NSTouchBar* touch_bar = [touch_bar_ makeTouchBar];
[touch_bar_ setIsPageLoading:NO];
[browserWindowTouchBar_ setIsPageLoading:YES]; NSTouchBarItem* item =
item = [browserWindowTouchBar_ touchBar:touchBar [touch_bar_ touchBar:touch_bar
makeItemForIdentifier:@"ReloadOrStopTouchId"]; 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]); EXPECT_EQ(IDC_STOP, [[item view] tag]);
} }
...@@ -118,6 +118,16 @@ UI_BASE_EXPORT extern NSString* const NSTouchBarItemIdentifierFlexibleSpace; ...@@ -118,6 +118,16 @@ UI_BASE_EXPORT extern NSString* const NSTouchBarItemIdentifierFlexibleSpace;
#endif // MAC_OS_X_VERSION_10_12_1 #endif // MAC_OS_X_VERSION_10_12_1
} // extern "C" } // 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 #pragma clang assume_nonnull end
#endif // UI_BASE_COCOA_TOUCH_BAR_FORWARD_DECLARATIONS_H_ #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