Commit f9da90b4 authored by spqchan's avatar spqchan Committed by Commit Bot

[MacViews] Hook Web Content Textfield Touch Bar Support

Remove Cocoa dependency from WebTextfieldTouchBar by moving
it from TabContentsController to BrowserWindowTouchBarController.

Hook up BrowserWindowTouchBarController to
AutofillPopupControllerImplMac on MacViews so that the
credit card touch bar can be updated.

Move the the logic that listens to WebContent changes to the
BrowserWindowTouchBarController. When the WebContents has
changed, BrowserWindowTouchBarController will update the
WebContents in BrowserWindowDefaultTouchBar and
WebTextfieldTouchBarController.

Modified SuggestedTextTouchBarController so that when its
WebContents has changed, it'll observe the new WebContents.

Bug: 856391
Change-Id: I9c29a371a0b38eb608bf8e32521abe22d5c664e0
Reviewed-on: https://chromium-review.googlesource.com/1135829Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Commit-Queue: Sarah Chan <spqchan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577940}
parent 4b8a8629
......@@ -5,8 +5,6 @@
#include "chrome/browser/ui/autofill/autofill_popup_controller_impl_mac.h"
#include "base/mac/availability.h"
#import "chrome/browser/ui/cocoa/browser_window_controller.h"
#import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h"
#import "chrome/browser/ui/cocoa/touchbar/web_textfield_touch_bar_controller.h"
#include "components/autofill/core/browser/autofill_popup_delegate.h"
#include "components/autofill/core/browser/popup_item_ids.h"
......@@ -64,13 +62,8 @@ void AutofillPopupControllerImplMac::Show(
return;
if (@available(macOS 10.12.2, *)) {
BrowserWindowController* bwc = [BrowserWindowController
browserWindowControllerForWindow:[container_view() window]];
TabContentsController* tabContentsController =
[[bwc tabStripController] activeTabContentsController];
touch_bar_controller_ =
[tabContentsController webTextfieldTouchBarController];
touch_bar_controller_ = [WebTextfieldTouchBarController
controllerForWindow:[container_view() window]];
[touch_bar_controller_ showCreditCardAutofillWithController:this];
}
}
......@@ -79,9 +72,8 @@ void AutofillPopupControllerImplMac::UpdateDataListValues(
const std::vector<base::string16>& values,
const std::vector<base::string16>& labels) {
AutofillPopupControllerImpl::UpdateDataListValues(values, labels);
if (touch_bar_controller_) {
if (touch_bar_controller_)
[touch_bar_controller_ invalidateTouchBar];
}
}
void AutofillPopupControllerImplMac::Hide() {
......
......@@ -12,7 +12,6 @@
#include "base/mac/scoped_nsobject.h"
class FullscreenObserver;
@class WebTextfieldTouchBarController;
namespace content {
class WebContents;
......@@ -53,8 +52,6 @@ class WebContents;
// Reference to the fullscreen window created to display the WebContents
// view separately.
NSWindow* separateFullscreenWindow_;
base::scoped_nsobject<WebTextfieldTouchBarController> touchBarController_;
}
@property(readonly, nonatomic) content::WebContents* webContents;
......@@ -100,8 +97,6 @@ class WebContents;
// widget or back to WebContentsView's widget.
- (void)toggleFullscreenWidget:(BOOL)enterFullscreen;
- (WebTextfieldTouchBarController*)webTextfieldTouchBarController;
@end
#endif // CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_TAB_CONTENTS_CONTROLLER_H_
......@@ -18,7 +18,6 @@
#include "chrome/browser/ui/cocoa/fullscreen_placeholder_view.h"
#include "chrome/browser/ui/cocoa/separate_fullscreen_window.h"
#import "chrome/browser/ui/cocoa/themed_window.h"
#import "chrome/browser/ui/cocoa/touchbar/web_textfield_touch_bar_controller.h"
#include "chrome/browser/ui/exclusive_access/fullscreen_within_tab_helper.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/common/chrome_features.h"
......@@ -220,8 +219,6 @@ class FullscreenObserver : public WebContentsObserver {
fullscreenObserver_.reset(new FullscreenObserver(self));
[self changeWebContents:contents];
isPopup_ = popup;
touchBarController_.reset([[WebTextfieldTouchBarController alloc]
initWithTabContentsController:self]);
}
return self;
}
......@@ -241,10 +238,6 @@ class FullscreenObserver : public WebContentsObserver {
[self setView:view];
}
- (NSTouchBar*)makeTouchBar API_AVAILABLE(macos(10.12.2)) {
return [touchBarController_ makeTouchBar];
}
- (void)ensureContentsVisibleInSuperview:(NSView*)superview {
if (!contents_)
return;
......@@ -424,10 +417,6 @@ class FullscreenObserver : public WebContentsObserver {
return isPopup_;
}
- (WebTextfieldTouchBarController*)webTextfieldTouchBarController {
return touchBarController_.get();
}
@end
@implementation TabContentsController (SeparateFullscreenWindowDelegate)
......
......@@ -21,6 +21,7 @@
@class CustomWindowControlsView;
@class NewTabButtonCocoa;
@class TabContentsController;
@class TabControllerCocoa;
@class TabViewCocoa;
@class TabStripDragController;
@class TabStripView;
......
......@@ -23,8 +23,6 @@
#import "chrome/browser/ui/cocoa/touchbar/browser_window_touch_bar_controller.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/browser/ui/tabs/tab_strip_model_observer.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "components/omnibox/browser/vector_icons.h"
......@@ -132,7 +130,6 @@ ui::TouchBarAction TouchBarActionFromCommand(int command) {
// the profile preferences and the back/forward commands.
class TouchBarNotificationBridge : public CommandObserver,
public BookmarkTabHelperObserver,
public TabStripModelObserver,
public content::WebContentsObserver {
public:
TouchBarNotificationBridge(BrowserWindowDefaultTouchBar* owner,
......@@ -140,7 +137,6 @@ class TouchBarNotificationBridge : public CommandObserver,
: owner_(owner), browser_(browser), contents_(nullptr) {
TabStripModel* model = browser_->tab_strip_model();
DCHECK(model);
model->AddObserver(this);
UpdateWebContents(model->GetActiveWebContents());
}
......@@ -148,10 +144,6 @@ class TouchBarNotificationBridge : public CommandObserver,
~TouchBarNotificationBridge() override {
if (contents_)
BookmarkTabHelper::FromWebContents(contents_)->RemoveObserver(this);
TabStripModel* model = browser_->tab_strip_model();
if (model)
model->RemoveObserver(this);
}
void UpdateTouchBar() { [[owner_ controller] invalidateTouchBar]; }
......@@ -182,16 +174,6 @@ class TouchBarNotificationBridge : public CommandObserver,
[owner_ setIsStarred:starred];
}
// TabStripModelObserver:
void ActiveTabChanged(content::WebContents* old_contents,
content::WebContents* new_contents,
int index,
int reason) override {
UpdateWebContents(new_contents);
contents_ = new_contents;
UpdateTouchBar();
}
protected:
// CommandObserver:
void EnabledStateChangedForCommand(int command, bool enabled) override {
......@@ -215,11 +197,6 @@ class TouchBarNotificationBridge : public CommandObserver,
[owner_ setIsPageLoading:NO];
}
void WebContentsDestroyed() override {
// Clean up if the web contents is being destroyed.
UpdateWebContents(nullptr);
}
private:
BrowserWindowDefaultTouchBar* owner_; // Weak.
Browser* browser_; // Weak.
......@@ -269,6 +246,7 @@ class TouchBarNotificationBridge : public CommandObserver,
// Creates and returns the search button.
- (NSView*)searchTouchBarView API_AVAILABLE(macos(10.12));
@end
@implementation BrowserWindowDefaultTouchBar
......
......@@ -12,6 +12,11 @@
class Browser;
@class BrowserWindowDefaultTouchBar;
@class WebTextfieldTouchBarController;
namespace content {
class WebContents;
}
// Provides a touch bar for the browser window. This class implements the
// NSTouchBarDelegate and handles the items in the touch bar.
......@@ -26,12 +31,16 @@ class Browser;
// nil.
- (void)invalidateTouchBar;
- (void)updateWebContents:(content::WebContents*)contents;
- (content::WebContents*)webContents;
@end
@interface BrowserWindowTouchBarController (ExposedForTesting)
- (BrowserWindowDefaultTouchBar*)defaultTouchBar;
- (WebTextfieldTouchBarController*)webTextfieldTouchBar;
@end
#endif // CHROME_BROWSER_UI_COCOA_TOUCHBAR_BROWSER_WINDOW_TOUCH_BAR_CONTROLLER_H_
......@@ -12,17 +12,72 @@
#import "base/mac/sdk_forward_declarations.h"
#include "chrome/browser/ui/browser.h"
#import "chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.h"
#import "chrome/browser/ui/cocoa/touchbar/web_textfield_touch_bar_controller.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#import "ui/base/cocoa/touch_bar_util.h"
@interface BrowserWindowTouchBarController () {
// The browser associated with the touch bar.
class WebContentsNotificationBridge : public TabStripModelObserver,
public content::WebContentsObserver {
public:
WebContentsNotificationBridge(BrowserWindowTouchBarController* owner,
Browser* browser)
: owner_(owner), browser_(browser), contents_(nullptr) {
TabStripModel* model = browser_->tab_strip_model();
DCHECK(model);
model->AddObserver(this);
UpdateWebContents(model->GetActiveWebContents());
}
~WebContentsNotificationBridge() override {
TabStripModel* model = browser_->tab_strip_model();
if (model)
model->RemoveObserver(this);
}
void UpdateWebContents(content::WebContents* new_contents) {
contents_ = new_contents;
Observe(contents_);
[owner_ updateWebContents:contents_];
}
// TabStripModelObserver:
void ActiveTabChanged(content::WebContents* old_contents,
content::WebContents* new_contents,
int index,
int reason) override {
UpdateWebContents(new_contents);
contents_ = new_contents;
}
content::WebContents* contents() const { return contents_; }
protected:
// WebContentsObserver:
void WebContentsDestroyed() override {
// Clean up if the web contents is being destroyed.
UpdateWebContents(nullptr);
}
private:
BrowserWindowTouchBarController* owner_; // Weak.
Browser* browser_; // Weak.
content::WebContents* contents_; // Weak.
};
@interface BrowserWindowTouchBarController () {
NSWindow* window_; // Weak.
// Used to receive and handle notifications.
std::unique_ptr<WebContentsNotificationBridge> notificationBridge_;
base::scoped_nsobject<BrowserWindowDefaultTouchBar> defaultTouchBar_;
base::scoped_nsobject<WebTextfieldTouchBarController> webTextfieldTouchBar_;
}
@end
......@@ -30,10 +85,17 @@
- (instancetype)initWithBrowser:(Browser*)browser window:(NSWindow*)window {
if ((self = [super init])) {
DCHECK(browser);
window_ = window;
notificationBridge_ =
std::make_unique<WebContentsNotificationBridge>(self, browser);
defaultTouchBar_.reset([[BrowserWindowDefaultTouchBar alloc]
initWithBrowser:browser
controller:self]);
window_ = window;
webTextfieldTouchBar_.reset(
[[WebTextfieldTouchBarController alloc] initWithController:self]);
}
return self;
......@@ -45,9 +107,23 @@
}
- (NSTouchBar*)makeTouchBar {
NSTouchBar* touchBar = [webTextfieldTouchBar_ makeTouchBar];
if (touchBar)
return touchBar;
return [defaultTouchBar_ makeTouchBar];
}
- (void)updateWebContents:(content::WebContents*)contents {
[defaultTouchBar_ updateWebContents:contents];
[webTextfieldTouchBar_ updateWebContents:contents];
[self invalidateTouchBar];
}
- (content::WebContents*)webContents {
return notificationBridge_->web_contents();
}
@end
@implementation BrowserWindowTouchBarController (ExposedForTesting)
......@@ -56,4 +132,8 @@
return defaultTouchBar_.get();
}
- (WebTextfieldTouchBarController*)webTextfieldTouchBar {
return webTextfieldTouchBar_.get();
}
@end
......@@ -25,8 +25,6 @@ class WebContents;
- (instancetype)initWithWebContents:(content::WebContents*)webContents
controller:(WebTextfieldTouchBarController*)controller;
- (void)initObserver;
- (NSTouchBar*)makeTouchBar API_AVAILABLE(macos(10.12.2));
- (NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar
......
......@@ -26,6 +26,10 @@ class WebContentsTextObserver : public content::WebContentsObserver {
SuggestedTextTouchBarController* owner)
: WebContentsObserver(web_contents), owner_(owner) {}
void UpdateWebContents(content::WebContents* web_contents) {
Observe(web_contents);
}
void DidChangeTextSelection(const base::string16& text,
const gfx::Range& range) override {
if (@available(macOS 10.12.2, *)) {
......@@ -82,18 +86,15 @@ class WebContentsTextObserver : public content::WebContentsObserver {
if ((self = [super init])) {
webContents_ = webContents;
controller_ = controller;
observer_.reset(
new text_observer::WebContentsTextObserver(webContents_, self));
}
return self;
}
- (void)initObserver {
observer_.reset(
new text_observer::WebContentsTextObserver(webContents_, self));
}
- (NSTouchBar*)makeTouchBar {
if (!webContents_->IsFocusedElementEditable())
if (!webContents_ || !webContents_->IsFocusedElementEditable())
return nil;
base::scoped_nsobject<NSTouchBar> touchBar([[ui::NSTouchBar() alloc] init]);
......@@ -253,7 +254,9 @@ class WebContentsTextObserver : public content::WebContentsObserver {
}
- (void)setWebContents:(content::WebContents*)webContents {
// TODO(tnijssen): Update the text suggestions when we change web contents.
webContents_ = webContents;
observer_->UpdateWebContents(webContents);
}
- (content::WebContents*)webContents {
......
......@@ -12,6 +12,7 @@
#import "base/mac/scoped_nsobject.h"
#import "ui/base/cocoa/touch_bar_forward_declarations.h"
@class BrowserWindowTouchBarController;
@class CreditCardAutofillTouchBarController;
@class SuggestedTextTouchBarController;
@class TabContentsController;
......@@ -20,24 +21,32 @@ namespace autofill {
class AutofillPopupController;
}
namespace content {
class WebContents;
}
// Provides a touch bar for the textfields in the WebContents. This class
// implements the NSTouchBarDelegate and handles the items in the touch bar.
@interface WebTextfieldTouchBarController : NSObject<NSTouchBarDelegate> {
TabContentsController* owner_; // weak.
BrowserWindowTouchBarController* controller_; // weak.
base::scoped_nsobject<CreditCardAutofillTouchBarController>
autofillTouchBarController_;
base::scoped_nsobject<SuggestedTextTouchBarController>
suggestedTextTouchBarController_;
}
+ (WebTextfieldTouchBarController*)controllerForWindow:(NSWindow*)window;
// Designated initializer.
- (instancetype)initWithTabContentsController:(TabContentsController*)owner;
- (instancetype)initWithController:(BrowserWindowTouchBarController*)controller;
- (void)showCreditCardAutofillWithController:
(autofill::AutofillPopupController*)controller;
- (void)hideCreditCardAutofillTouchBar;
- (void)updateWebContents:(content::WebContents*)contents;
- (void)invalidateTouchBar;
// Creates and returns a touch bar.
......
......@@ -8,25 +8,47 @@
#include "base/mac/scoped_nsobject.h"
#include "base/mac/sdk_forward_declarations.h"
#include "chrome/browser/ui/autofill/autofill_popup_controller.h"
#import "chrome/browser/ui/cocoa/browser_window_controller.h"
#import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h"
#import "chrome/browser/ui/cocoa/touchbar/browser_window_touch_bar_controller.h"
#import "chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller.h"
#import "chrome/browser/ui/cocoa/touchbar/suggested_text_touch_bar_controller.h"
#include "chrome/browser/ui/views/frame/browser_frame_mac.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/common/chrome_features.h"
#include "content/public/browser/web_contents.h"
#import "ui/base/cocoa/touch_bar_util.h"
#include "ui/base/ui_base_features.h"
@implementation WebTextfieldTouchBarController
- (instancetype)initWithTabContentsController:(TabContentsController*)owner {
+ (WebTextfieldTouchBarController*)controllerForWindow:(NSWindow*)window {
if (features::IsViewsBrowserCocoa()) {
BrowserWindowController* bwc =
[BrowserWindowController browserWindowControllerForWindow:window];
return [[bwc browserWindowTouchBarController] webTextfieldTouchBar];
}
BrowserView* browser_view =
BrowserView::GetBrowserViewForNativeWindow(window);
if (!browser_view)
return nil;
BrowserFrameMac* browser_frame = static_cast<BrowserFrameMac*>(
browser_view->frame()->native_browser_frame());
return [browser_frame->GetTouchBarController() webTextfieldTouchBar];
}
- (instancetype)initWithController:
(BrowserWindowTouchBarController*)controller {
if ((self = [super init])) {
owner_ = owner;
controller_ = controller;
if (IsSuggestedTextTouchBarEnabled()) {
if (base::FeatureList::IsEnabled(features::kSuggestedTextTouchBar)) {
suggestedTextTouchBarController_.reset(
[[SuggestedTextTouchBarController alloc]
initWithWebContents:[owner_ webContents]
initWithWebContents:[controller_ webContents]
controller:self]);
[suggestedTextTouchBarController_ initObserver];
}
}
......@@ -51,13 +73,12 @@
[self invalidateTouchBar];
}
bool IsSuggestedTextTouchBarEnabled() {
return base::FeatureList::IsEnabled(features::kSuggestedTextTouchBar);
- (void)updateWebContents:(content::WebContents*)contents {
[suggestedTextTouchBarController_ setWebContents:contents];
}
- (void)invalidateTouchBar {
if ([owner_ respondsToSelector:@selector(setTouchBar:)])
[owner_ performSelector:@selector(setTouchBar:) withObject:nil];
[controller_ invalidateTouchBar];
}
- (NSTouchBar*)makeTouchBar {
......
......@@ -120,6 +120,10 @@ class BrowserFrame
// Note that in multi user mode this will upon each call create a new model.
ui::MenuModel* GetSystemMenuModel();
NativeBrowserFrame* native_browser_frame() const {
return native_browser_frame_;
}
private:
// Callback for MenuRunner.
void OnMenuClosed();
......
......@@ -13,7 +13,8 @@
class BrowserFrame;
class BrowserView;
@protocol WindowTouchBarDelegate;
@class BrowserWindowTouchBarController;
@class BrowserWindowTouchBarViewsDelegate;
@class ChromeCommandDispatcherDelegate;
////////////////////////////////////////////////////////////////////////////////
......@@ -25,6 +26,8 @@ class BrowserFrameMac : public views::NativeWidgetMac,
public:
BrowserFrameMac(BrowserFrame* browser_frame, BrowserView* browser_view);
BrowserWindowTouchBarController* GetTouchBarController() const;
// Overridden from views::NativeWidgetMac:
int SheetPositionY() override;
void OnWindowFullscreenStateChange() override;
......@@ -57,7 +60,7 @@ class BrowserFrameMac : public views::NativeWidgetMac,
BrowserView* browser_view_; // Weak. Our ClientView.
base::scoped_nsobject<ChromeCommandDispatcherDelegate>
command_dispatcher_delegate_;
base::scoped_nsprotocol<id<WindowTouchBarDelegate>> touch_bar_delegate_;
base::scoped_nsobject<BrowserWindowTouchBarViewsDelegate> touch_bar_delegate_;
DISALLOW_COPY_AND_ASSIGN(BrowserFrameMac);
};
......
......@@ -42,16 +42,18 @@ bool ShouldHandleKeyboardEvent(const content::NativeWebKeyboardEvent& event) {
// Bridge Obj-C class for WindowTouchBarDelegate and
// BrowserWindowTouchBarController.
@interface BrowserWindowTouchBarControllerViewsDelegate
@interface BrowserWindowTouchBarViewsDelegate
: NSObject<WindowTouchBarDelegate> {
Browser* browser_; // Weak.
NSWindow* window_; // Weak.
base::scoped_nsobject<BrowserWindowTouchBarController> touchBarController_;
}
- (BrowserWindowTouchBarController*)touchBarController;
@end
@implementation BrowserWindowTouchBarControllerViewsDelegate
@implementation BrowserWindowTouchBarViewsDelegate
- (instancetype)initWithBrowser:(Browser*)browser window:(NSWindow*)window {
if ((self = [super init])) {
......@@ -62,6 +64,10 @@ bool ShouldHandleKeyboardEvent(const content::NativeWebKeyboardEvent& event) {
return self;
}
- (BrowserWindowTouchBarController*)touchBarController {
return touchBarController_.get();
}
- (NSTouchBar*)makeTouchBar API_AVAILABLE(macos(10.12.2)) {
if (!touchBarController_) {
touchBarController_.reset([[BrowserWindowTouchBarController alloc]
......@@ -83,6 +89,11 @@ BrowserFrameMac::BrowserFrameMac(BrowserFrame* browser_frame,
BrowserFrameMac::~BrowserFrameMac() {
}
BrowserWindowTouchBarController* BrowserFrameMac::GetTouchBarController()
const {
return [touch_bar_delegate_ touchBarController];
}
////////////////////////////////////////////////////////////////////////////////
// BrowserFrameMac, views::NativeWidgetMac implementation:
......@@ -137,8 +148,7 @@ NativeWidgetMacNSWindow* BrowserFrameMac::CreateNSWindow(
[ns_window setCommandHandler:[[[BrowserWindowCommandHandler alloc] init]
autorelease]];
touch_bar_delegate_.reset(
[[BrowserWindowTouchBarControllerViewsDelegate alloc]
touch_bar_delegate_.reset([[BrowserWindowTouchBarViewsDelegate alloc]
initWithBrowser:browser_view_->browser()
window:ns_window]);
[ns_window setWindowTouchBarDelegate:touch_bar_delegate_.get()];
......
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