Skip to content

Commit

Permalink
Added pin to shortcut on macOS
Browse files Browse the repository at this point in the history
fix brave/brave-browser#24055

User can add to dock via first run or settings.
  • Loading branch information
simonhong committed Oct 27, 2022
1 parent f4669ba commit 3acb0aa
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 35 deletions.
13 changes: 10 additions & 3 deletions app/brave_generated_resources.grd
Original file line number Diff line number Diff line change
Expand Up @@ -939,9 +939,16 @@ Or change later at <ph name="SETTINGS_EXTENIONS_LINK">$2<ex>brave://settings/ext
</message>

<if expr="enable_pin_shortcut">
<message name="IDS_FIRSTRUN_DLG_PIN_SHORTCUT_TEXT" desc="Text for pin to taskbar checkbox">
Pin to taskbar
</message>
<if expr="is_win">
<message name="IDS_FIRSTRUN_DLG_PIN_SHORTCUT_TEXT" desc="Text for pin to taskbar checkbox">
Pin to taskbar
</message>
</if>
<if expr="is_macosx">
<message name="IDS_FIRSTRUN_DLG_PIN_SHORTCUT_TEXT" desc="Text for pin to taskbar checkbox">
Keep in Dock
</message>
</if>
</if>

<!-- Importer -->
Expand Down
31 changes: 22 additions & 9 deletions app/brave_settings_strings.grdp
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,28 @@

<!-- Settings / Pin shortcut-->
<if expr="enable_pin_shortcut">
<message name="IDS_SETTINGS_CAN_PIN_SHORTCUT">
Pin to taskbar
</message>
<message name="IDS_SETTINGS_PIN_SHORTCUT">
Pin
</message>
<message name="IDS_SETTINGS_SHORTCUT_PINNED">
Brave is already pinned
</message>
<if expr="is_win">
<message name="IDS_SETTINGS_CAN_PIN_SHORTCUT" desc="The label for pin to taskbar settings">
Pin to taskbar
</message>
<message name="IDS_SETTINGS_PIN_SHORTCUT" desc="The label for pin to taskbar button">
Pin
</message>
<message name="IDS_SETTINGS_SHORTCUT_PINNED" desc="The label for pinned state description">
Brave is already pinned
</message>
</if>
<if expr="is_macosx">
<message name="IDS_SETTINGS_CAN_PIN_SHORTCUT" desc="The label for keep in dock settings">
Keep in Dock
</message>
<message name="IDS_SETTINGS_PIN_SHORTCUT" desc="The label for dock button">
Dock
</message>
<message name="IDS_SETTINGS_SHORTCUT_PINNED" desc="The label for docked state description">
Brave is already in Dock
</message>
</if>
</if>

<!-- Settings / Shields -->
Expand Down
27 changes: 27 additions & 0 deletions browser/brave_shell_integration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,39 @@

#include <utility>

#include "brave/browser/brave_shell_integration_win.h"
#include "brave/browser/default_protocol_handler_utils_win.h"
#include "chrome/installer/util/shell_util.h"
#endif

#if BUILDFLAG(IS_MAC)
#include "brave/browser/brave_shell_integration_mac.h"
#endif

namespace shell_integration {

void PinShortcut(Profile* profile,
base::OnceCallback<void(bool)> result_callback) {
#if BUILDFLAG(IS_WIN)
win::PinToTaskbar(profile, std::move(result_callback));
#elif BUILDFLAG(IS_MAC)
// Mac doesn't support profile specific icon in dock.
mac::AddIconToDock(std::move(result_callback));
#elif BUILDFLAG(IS_LINUX)
NOTREACHED() << "Not supported on linux yet.";
#endif
}

void IsShortcutPinned(base::OnceCallback<void(bool)> result_callback) {
#if BUILDFLAG(IS_WIN)
win::IsShortcutPinned(std::move(result_callback));
#elif BUILDFLAG(IS_MAC)
mac::IsIconAddedToDock(std::move(result_callback));
#elif BUILDFLAG(IS_LINUX)
NOTREACHED() << "Not supported on linux yet.";
#endif
}

BraveDefaultBrowserWorker::BraveDefaultBrowserWorker() = default;
BraveDefaultBrowserWorker::~BraveDefaultBrowserWorker() = default;

Expand Down
10 changes: 10 additions & 0 deletions browser/brave_shell_integration.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,20 @@
#ifndef BRAVE_BROWSER_BRAVE_SHELL_INTEGRATION_H_
#define BRAVE_BROWSER_BRAVE_SHELL_INTEGRATION_H_

#include "base/callback.h"
#include "base/callback_helpers.h"
#include "chrome/browser/shell_integration.h"

class Profile;

namespace shell_integration {

void PinShortcut(
Profile* profile = nullptr,
base::OnceCallback<void(bool)> result_callback = base::DoNothing());
void IsShortcutPinned(
base::OnceCallback<void(bool)> result_callback = base::DoNothing());

class BraveDefaultBrowserWorker : public DefaultBrowserWorker {
public:
BraveDefaultBrowserWorker();
Expand Down
20 changes: 20 additions & 0 deletions browser/brave_shell_integration_mac.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* Copyright (c) 2022 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 http://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_BROWSER_BRAVE_SHELL_INTEGRATION_MAC_H_
#define BRAVE_BROWSER_BRAVE_SHELL_INTEGRATION_MAC_H_

#include "base/callback.h"
#include "base/callback_helpers.h"

namespace shell_integration::mac {

// No-op if already added.
void AddIconToDock(
base::OnceCallback<void(bool)> result_callback = base::DoNothing());
void IsIconAddedToDock(base::OnceCallback<void(bool)> result_callback);
} // namespace shell_integration::mac

#endif // BRAVE_BROWSER_BRAVE_SHELL_INTEGRATION_MAC_H_
25 changes: 25 additions & 0 deletions browser/brave_shell_integration_mac.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* Copyright (c) 2022 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 http://mozilla.org/MPL/2.0/. */

#include "brave/browser/brave_shell_integration_mac.h"

#include "base/mac/bundle_locations.h"
#include "chrome/browser/mac/dock.h"

namespace shell_integration::mac {

void AddIconToDock(base::OnceCallback<void(bool)> result_callback) {
dock::AddIcon([base::mac::MainBundle() bundlePath], nullptr);

std::move(result_callback)
.Run(dock::ChromeIsInTheDock() == dock::ChromeInDockTrue);
}

void IsIconAddedToDock(base::OnceCallback<void(bool)> result_callback) {
std::move(result_callback)
.Run(dock::ChromeIsInTheDock() == dock::ChromeInDockTrue);
}

} // namespace shell_integration::mac
2 changes: 1 addition & 1 deletion browser/shell_integrations/buildflags/buildflags.gni
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.

enable_pin_shortcut = is_win
enable_pin_shortcut = is_win || is_mac
2 changes: 2 additions & 0 deletions browser/sources.gni
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ if (is_mac) {
brave_chrome_browser_sources += [
"//brave/browser/brave_browser_main_parts_mac.h",
"//brave/browser/brave_browser_main_parts_mac.mm",
"//brave/browser/brave_shell_integration_mac.h",
"//brave/browser/brave_shell_integration_mac.mm",
]
}

Expand Down
7 changes: 1 addition & 6 deletions browser/ui/views/brave_first_run_dialog.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@
#include "ui/views/window/dialog_delegate.h"

#if BUILDFLAG(ENABLE_PIN_SHORTCUT)
#if BUILDFLAG(IS_WIN)
#include "brave/browser/brave_shell_integration.h"
#include "brave/browser/brave_shell_integration_win.h"
#endif
#else // BUILDFLAG(ENABLE_PIN_SHORTCUT)
#include "chrome/browser/shell_integration.h"
#endif
Expand Down Expand Up @@ -166,19 +163,17 @@ bool BraveFirstRunDialog::Accept() {
GetWidget()->Hide();

#if BUILDFLAG(ENABLE_PIN_SHORTCUT)
#if BUILDFLAG(IS_WIN)
base::MakeRefCounted<shell_integration::BraveDefaultBrowserWorker>()
->StartSetAsDefault(base::BindOnce(
[](bool pin_to_shortcut,
shell_integration::DefaultWebClientState state) {
if (pin_to_shortcut &&
state == shell_integration::DefaultWebClientState::IS_DEFAULT) {
// Try to pin to taskbar when Brave is set as a default browser.
shell_integration::win::PinToTaskbar();
shell_integration::PinShortcut();
}
},
pin_shortcut_checkbox_->GetChecked()));
#endif
#else
shell_integration::SetAsDefaultBrowser();
#endif
Expand Down
16 changes: 3 additions & 13 deletions browser/ui/webui/settings/pin_shortcut_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,11 @@
#include "brave/browser/ui/webui/settings/pin_shortcut_handler.h"

#include "base/bind.h"
#include "build/build_config.h"
#include "brave/browser/brave_shell_integration.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_ui.h"

#if BUILDFLAG(IS_WIN)
#include "brave/browser/brave_shell_integration_win.h"
#endif

PinShortcutHandler::PinShortcutHandler() = default;

PinShortcutHandler::~PinShortcutHandler() = default;
Expand All @@ -32,26 +28,21 @@ void PinShortcutHandler::RegisterMessages() {
void PinShortcutHandler::HandlePinShortcut(const base::Value::List& args) {
AllowJavascript();

#if BUILDFLAG(IS_WIN)
shell_integration::win::PinToTaskbar(
shell_integration::PinShortcut(
Profile::FromWebUI(web_ui()),
base::BindOnce(&PinShortcutHandler::OnPinShortcut,
weak_factory_.GetWeakPtr()));
#endif
}

void PinShortcutHandler::HandleCheckShortcutPinState(
const base::Value::List& args) {
AllowJavascript();

#if BUILDFLAG(IS_WIN)
shell_integration::win::IsShortcutPinned(
shell_integration::IsShortcutPinned(
base::BindOnce(&PinShortcutHandler::OnCheckShortcutPinState,
weak_factory_.GetWeakPtr()));
#endif
}

#if BUILDFLAG(IS_WIN)
void PinShortcutHandler::OnPinShortcut(bool pinned) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

Expand All @@ -63,7 +54,6 @@ void PinShortcutHandler::OnCheckShortcutPinState(bool pinned) {

NotifyShortcutPinStateChangeToPage(pinned);
}
#endif // BUILDFLAG(IS_WIN)

void PinShortcutHandler::NotifyShortcutPinStateChangeToPage(bool pinned) {
if (IsJavascriptAllowed()) {
Expand Down
2 changes: 0 additions & 2 deletions browser/ui/webui/settings/pin_shortcut_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@ class PinShortcutHandler : public settings::SettingsPageUIHandler {
void HandlePinShortcut(const base::Value::List& args);
void NotifyShortcutPinStateChangeToPage(bool pinned);

#if BUILDFLAG(IS_WIN)
void OnPinShortcut(bool pinned);
void OnCheckShortcutPinState(bool pinned);

base::WeakPtrFactory<PinShortcutHandler> weak_factory_{this};
#endif
};

#endif // BRAVE_BROWSER_UI_WEBUI_SETTINGS_PIN_SHORTCUT_HANDLER_H_
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "base/i18n/rtl.h"
#include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "brave/browser/brave_shell_integration.h"
#include "brave/browser/metrics/metrics_reporting_util.h"
#include "brave/components/l10n/common/localization_util.h"
#include "brave/grit/brave_generated_resources.h"
Expand All @@ -21,11 +22,13 @@

@implementation FirstRunDialogViewController {
BOOL _setAsDefaultBrowser;
NSButton* _dockCheckbox;
}

- (instancetype)initWithStatsCheckboxInitiallyChecked:(BOOL)checked {
if ((self = [super init])) {
_setAsDefaultBrowser = NO;
_dockCheckbox = nil;
}
return self;
}
Expand All @@ -35,6 +38,7 @@ - (void)loadView {
constexpr int kPadding = 24;
constexpr int kLabelSpacing = 16;
constexpr int kTopPadding = 20;
constexpr int kCheckboxTopMargin = 20;
constexpr int kButtonTopMargin = 40;
constexpr int kButtonBottomMargin = 20;
constexpr int kButtonHorizontalMargin = 20;
Expand Down Expand Up @@ -91,10 +95,22 @@ - (void)loadView {
[contentsLabel
setFrame:NSMakeRect(0, 0, preferredSize.width, preferredSize.height)];

std::u16string dockCheckboxString =
brave_l10n::GetLocalizedResourceUTF16String(
IDS_FIRSTRUN_DLG_PIN_SHORTCUT_TEXT);
base::i18n::AdjustStringForLocaleDirection(&dockCheckboxString);
_dockCheckbox = [[NSButton alloc] init];
[_dockCheckbox setButtonType:NSSwitchButton];
[_dockCheckbox setTitle:base::SysUTF16ToNSString(dockCheckboxString)];
[_dockCheckbox setFont:[NSFont systemFontOfSize:14.0
weight:NSFontWeightRegular]];
[_dockCheckbox sizeToFit];

// It's time to calculate window's height as we can get all controls' final
// heights.
const int windowHeight = kTopPadding + NSHeight(headerLabel.frame) +
kLabelSpacing + NSHeight(contentsLabel.frame) +
kCheckboxTopMargin + NSHeight(_dockCheckbox.frame) +
kButtonTopMargin + NSHeight(maybeLaterButton.frame) +
kButtonBottomMargin;

Expand All @@ -119,6 +135,7 @@ - (void)loadView {
[self.view setValue:backgroundColor forKey:@"backgroundColor"];
[self.view addSubview:headerLabel];
[self.view addSubview:contentsLabel];
[self.view addSubview:_dockCheckbox];
[self.view addSubview:maybeLaterButton];
[self.view addSubview:makeDefaultButton];

Expand All @@ -133,13 +150,19 @@ - (void)loadView {
frame.origin.y = NSMinY(headerLabel.frame) - kLabelSpacing - NSHeight(frame);
[contentsLabel setFrame:frame];

frame = _dockCheckbox.frame;
frame.origin.x = kPadding;
frame.origin.y =
NSMinY(contentsLabel.frame) - kCheckboxTopMargin - NSHeight(frame);
[_dockCheckbox setFrame:frame];

frame = makeDefaultButton.frame;
frame.origin.x = dialogWidth - kButtonHorizontalMargin - NSWidth(frame);
if (base::i18n::IsRTL()) {
frame.origin.x = kButtonHorizontalMargin;
}
frame.origin.y =
NSMinY(contentsLabel.frame) - kButtonTopMargin - NSHeight(frame);
NSMinY(_dockCheckbox.frame) - kButtonTopMargin - NSHeight(frame);
[makeDefaultButton setFrame:frame];

frame = maybeLaterButton.frame;
Expand Down Expand Up @@ -167,6 +190,10 @@ - (BOOL)isMakeDefaultBrowserEnabled {

- (void)ok:(id)sender {
_setAsDefaultBrowser = YES;
if ([_dockCheckbox state] == NSControlStateValueOn) {
shell_integration::PinShortcut();
}

[[[self view] window] close];
[NSApp stopModal];
}
Expand Down

0 comments on commit 3acb0aa

Please sign in to comment.