commit
74120493fd
147 changed files with 2605 additions and 1221 deletions
|
@ -463,10 +463,11 @@ void App::DisableHardwareAcceleration(mate::Arguments* args) {
|
|||
void App::ImportCertificate(
|
||||
const base::DictionaryValue& options,
|
||||
const net::CompletionCallback& callback) {
|
||||
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
|
||||
auto browser_context = brightray::BrowserContext::From("", false);
|
||||
if (!certificate_manager_model_) {
|
||||
std::unique_ptr<base::DictionaryValue> copy = options.CreateDeepCopy();
|
||||
CertificateManagerModel::Create(browser_context,
|
||||
CertificateManagerModel::Create(
|
||||
browser_context.get(),
|
||||
base::Bind(&App::OnCertificateManagerModelCreated,
|
||||
base::Unretained(this),
|
||||
base::Passed(©),
|
||||
|
@ -519,6 +520,8 @@ void App::BuildPrototype(
|
|||
base::Bind(&Browser::SetAsDefaultProtocolClient, browser))
|
||||
.SetMethod("removeAsDefaultProtocolClient",
|
||||
base::Bind(&Browser::RemoveAsDefaultProtocolClient, browser))
|
||||
.SetMethod("setBadgeCount", base::Bind(&Browser::SetBadgeCount, browser))
|
||||
.SetMethod("getBadgeCount", base::Bind(&Browser::GetBadgeCount, browser))
|
||||
#if defined(OS_MACOSX)
|
||||
.SetMethod("hide", base::Bind(&Browser::Hide, browser))
|
||||
.SetMethod("show", base::Bind(&Browser::Show, browser))
|
||||
|
@ -528,8 +531,11 @@ void App::BuildPrototype(
|
|||
base::Bind(&Browser::GetCurrentActivityType, browser))
|
||||
#endif
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("setUserTasks",
|
||||
base::Bind(&Browser::SetUserTasks, browser))
|
||||
.SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser))
|
||||
#endif
|
||||
#if defined(OS_LINUX)
|
||||
.SetMethod("isUnityRunning",
|
||||
base::Bind(&Browser::IsUnityRunning, browser))
|
||||
#endif
|
||||
.SetMethod("setPath", &App::SetPath)
|
||||
.SetMethod("getPath", &App::GetPath)
|
||||
|
|
|
@ -30,7 +30,7 @@ struct Converter<atom::api::Cookies::Error> {
|
|||
if (val == atom::api::Cookies::SUCCESS)
|
||||
return v8::Null(isolate);
|
||||
else
|
||||
return v8::Exception::Error(StringToV8(isolate, "failed"));
|
||||
return v8::Exception::Error(StringToV8(isolate, "Setting cookie failed"));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -61,8 +61,10 @@ bool Menu::GetAcceleratorForCommandId(int command_id,
|
|||
return mate::ConvertFromV8(isolate(), val, accelerator);
|
||||
}
|
||||
|
||||
void Menu::ExecuteCommand(int command_id, int event_flags) {
|
||||
execute_command_.Run(command_id);
|
||||
void Menu::ExecuteCommand(int command_id, int flags) {
|
||||
execute_command_.Run(
|
||||
mate::internal::CreateEventFromFlags(isolate(), flags),
|
||||
command_id);
|
||||
}
|
||||
|
||||
void Menu::MenuWillShow(ui::SimpleMenuModel* source) {
|
||||
|
|
|
@ -90,7 +90,7 @@ class Menu : public mate::TrackableObject<Menu>,
|
|||
base::Callback<bool(int)> is_enabled_;
|
||||
base::Callback<bool(int)> is_visible_;
|
||||
base::Callback<v8::Local<v8::Value>(int)> get_accelerator_;
|
||||
base::Callback<void(int)> execute_command_;
|
||||
base::Callback<void(v8::Local<v8::Value>, int)> execute_command_;
|
||||
base::Callback<void()> menu_will_show_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Menu);
|
||||
|
|
|
@ -41,8 +41,10 @@
|
|||
#include "net/http/http_auth_preferences.h"
|
||||
#include "net/proxy/proxy_service.h"
|
||||
#include "net/proxy/proxy_config_service_fixed.h"
|
||||
#include "net/url_request/static_http_user_agent_settings.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
using content::StoragePartition;
|
||||
|
@ -93,6 +95,15 @@ uint32_t GetQuotaMask(const std::vector<std::string>& quota_types) {
|
|||
return quota_mask;
|
||||
}
|
||||
|
||||
void SetUserAgentInIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
const std::string& accept_lang,
|
||||
const std::string& user_agent) {
|
||||
getter->GetURLRequestContext()->set_http_user_agent_settings(
|
||||
new net::StaticHttpUserAgentSettings(
|
||||
net::HttpUtil::GenerateAcceptLanguageHeader(accept_lang),
|
||||
user_agent));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
@ -455,6 +466,23 @@ void Session::AllowNTLMCredentialsForDomains(const std::string& domains) {
|
|||
domains));
|
||||
}
|
||||
|
||||
void Session::SetUserAgent(const std::string& user_agent,
|
||||
mate::Arguments* args) {
|
||||
browser_context_->SetUserAgent(user_agent);
|
||||
|
||||
std::string accept_lang = l10n_util::GetApplicationLocale("");
|
||||
args->GetNext(&accept_lang);
|
||||
|
||||
auto getter = browser_context_->GetRequestContext();
|
||||
getter->GetNetworkTaskRunner()->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&SetUserAgentInIO, getter, accept_lang, user_agent));
|
||||
}
|
||||
|
||||
std::string Session::GetUserAgent() {
|
||||
return browser_context_->GetUserAgent();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
|
||||
if (cookies_.IsEmpty()) {
|
||||
auto handle = atom::api::Cookies::Create(isolate, browser_context());
|
||||
|
@ -520,6 +548,8 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
|||
.SetMethod("clearHostResolverCache", &Session::ClearHostResolverCache)
|
||||
.SetMethod("allowNTLMCredentialsForDomains",
|
||||
&Session::AllowNTLMCredentialsForDomains)
|
||||
.SetMethod("setUserAgent", &Session::SetUserAgent)
|
||||
.SetMethod("getUserAgent", &Session::GetUserAgent)
|
||||
.SetProperty("cookies", &Session::Cookies)
|
||||
.SetProperty("protocol", &Session::Protocol)
|
||||
.SetProperty("webRequest", &Session::WebRequest);
|
||||
|
|
|
@ -57,15 +57,7 @@ class Session: public mate::TrackableObject<Session>,
|
|||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
protected:
|
||||
Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~Session();
|
||||
|
||||
// content::DownloadManager::Observer:
|
||||
void OnDownloadCreated(content::DownloadManager* manager,
|
||||
content::DownloadItem* item) override;
|
||||
|
||||
private:
|
||||
// Methods.
|
||||
void ResolveProxy(const GURL& url, ResolveProxyCallback callback);
|
||||
template<CacheAction action>
|
||||
void DoCacheAction(const net::CompletionCallback& callback);
|
||||
|
@ -80,10 +72,21 @@ class Session: public mate::TrackableObject<Session>,
|
|||
mate::Arguments* args);
|
||||
void ClearHostResolverCache(mate::Arguments* args);
|
||||
void AllowNTLMCredentialsForDomains(const std::string& domains);
|
||||
void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
|
||||
std::string GetUserAgent();
|
||||
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> Protocol(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
Session(v8::Isolate* isolate, AtomBrowserContext* browser_context);
|
||||
~Session();
|
||||
|
||||
// content::DownloadManager::Observer:
|
||||
void OnDownloadCreated(content::DownloadManager* manager,
|
||||
content::DownloadItem* item) override;
|
||||
|
||||
private:
|
||||
// Cached object.
|
||||
v8::Global<v8::Value> cookies_;
|
||||
v8::Global<v8::Value> protocol_;
|
||||
|
|
|
@ -53,6 +53,10 @@ void SystemPreferences::BuildPrototype(
|
|||
&SystemPreferences::SubscribeNotification)
|
||||
.SetMethod("unsubscribeNotification",
|
||||
&SystemPreferences::UnsubscribeNotification)
|
||||
.SetMethod("subscribeLocalNotification",
|
||||
&SystemPreferences::SubscribeLocalNotification)
|
||||
.SetMethod("unsubscribeLocalNotification",
|
||||
&SystemPreferences::UnsubscribeLocalNotification)
|
||||
.SetMethod("getUserDefault", &SystemPreferences::GetUserDefault)
|
||||
#endif
|
||||
.SetMethod("isDarkMode", &SystemPreferences::IsDarkMode);
|
||||
|
|
|
@ -26,17 +26,18 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences> {
|
|||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> prototype);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
using NotificationCallback = base::Callback<
|
||||
void(const std::string&, const base::DictionaryValue&)>;
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool IsAeroGlassEnabled();
|
||||
#elif defined(OS_MACOSX)
|
||||
using NotificationCallback = base::Callback<
|
||||
void(const std::string&, const base::DictionaryValue&)>;
|
||||
|
||||
int SubscribeNotification(const std::string& name,
|
||||
const NotificationCallback& callback);
|
||||
void UnsubscribeNotification(int id);
|
||||
int SubscribeLocalNotification(const std::string& name,
|
||||
const NotificationCallback& callback);
|
||||
void UnsubscribeLocalNotification(int request_id);
|
||||
v8::Local<v8::Value> GetUserDefault(const std::string& name,
|
||||
const std::string& type);
|
||||
#endif
|
||||
|
@ -46,6 +47,13 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences> {
|
|||
explicit SystemPreferences(v8::Isolate* isolate);
|
||||
~SystemPreferences() override;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
int DoSubscribeNotification(const std::string& name,
|
||||
const NotificationCallback& callback,
|
||||
bool is_local);
|
||||
void DoUnsubscribeNotification(int request_id, bool is_local);
|
||||
#endif
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(SystemPreferences);
|
||||
};
|
||||
|
|
|
@ -30,34 +30,59 @@ std::map<int, id> g_id_map;
|
|||
|
||||
int SystemPreferences::SubscribeNotification(
|
||||
const std::string& name, const NotificationCallback& callback) {
|
||||
return DoSubscribeNotification(name, callback, false);
|
||||
}
|
||||
|
||||
void SystemPreferences::UnsubscribeNotification(int request_id) {
|
||||
DoUnsubscribeNotification(request_id, false);
|
||||
}
|
||||
|
||||
int SystemPreferences::SubscribeLocalNotification(
|
||||
const std::string& name, const NotificationCallback& callback) {
|
||||
return DoSubscribeNotification(name, callback, true);
|
||||
}
|
||||
|
||||
void SystemPreferences::UnsubscribeLocalNotification(int request_id) {
|
||||
DoUnsubscribeNotification(request_id, true);
|
||||
}
|
||||
|
||||
int SystemPreferences::DoSubscribeNotification(const std::string& name,
|
||||
const NotificationCallback& callback, bool is_local) {
|
||||
int request_id = g_next_id++;
|
||||
__block NotificationCallback copied_callback = callback;
|
||||
g_id_map[request_id] = [[NSDistributedNotificationCenter defaultCenter]
|
||||
addObserverForName:base::SysUTF8ToNSString(name)
|
||||
object:nil
|
||||
queue:nil
|
||||
usingBlock:^(NSNotification* notification) {
|
||||
std::unique_ptr<base::DictionaryValue> user_info =
|
||||
NSDictionaryToDictionaryValue(notification.userInfo);
|
||||
if (user_info) {
|
||||
copied_callback.Run(
|
||||
base::SysNSStringToUTF8(notification.name),
|
||||
*user_info);
|
||||
} else {
|
||||
copied_callback.Run(
|
||||
base::SysNSStringToUTF8(notification.name),
|
||||
base::DictionaryValue());
|
||||
}
|
||||
NSNotificationCenter* center = is_local ?
|
||||
[NSNotificationCenter defaultCenter] :
|
||||
[NSDistributedNotificationCenter defaultCenter];
|
||||
|
||||
g_id_map[request_id] = [center
|
||||
addObserverForName:base::SysUTF8ToNSString(name)
|
||||
object:nil
|
||||
queue:nil
|
||||
usingBlock:^(NSNotification* notification) {
|
||||
std::unique_ptr<base::DictionaryValue> user_info =
|
||||
NSDictionaryToDictionaryValue(notification.userInfo);
|
||||
if (user_info) {
|
||||
copied_callback.Run(
|
||||
base::SysNSStringToUTF8(notification.name),
|
||||
*user_info);
|
||||
} else {
|
||||
copied_callback.Run(
|
||||
base::SysNSStringToUTF8(notification.name),
|
||||
base::DictionaryValue());
|
||||
}
|
||||
}
|
||||
];
|
||||
return request_id;
|
||||
}
|
||||
|
||||
void SystemPreferences::UnsubscribeNotification(int request_id) {
|
||||
void SystemPreferences::DoUnsubscribeNotification(int request_id, bool is_local) {
|
||||
auto iter = g_id_map.find(request_id);
|
||||
if (iter != g_id_map.end()) {
|
||||
id observer = iter->second;
|
||||
[[NSDistributedNotificationCenter defaultCenter] removeObserver:observer];
|
||||
NSNotificationCenter* center = is_local ?
|
||||
[NSNotificationCenter defaultCenter] :
|
||||
[NSDistributedNotificationCenter defaultCenter];
|
||||
[center removeObserver:observer];
|
||||
g_id_map.erase(iter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/events/event_constants.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
namespace atom {
|
||||
|
@ -44,24 +43,15 @@ mate::WrappableBase* Tray::New(v8::Isolate* isolate,
|
|||
}
|
||||
|
||||
void Tray::OnClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
EmitCustomEvent("click",
|
||||
ModifiersToObject(isolate(), modifiers), bounds);
|
||||
EmitWithFlags("click", modifiers, bounds);
|
||||
}
|
||||
|
||||
void Tray::OnDoubleClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
EmitCustomEvent("double-click",
|
||||
ModifiersToObject(isolate(), modifiers), bounds);
|
||||
EmitWithFlags("double-click", modifiers, bounds);
|
||||
}
|
||||
|
||||
void Tray::OnRightClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
EmitCustomEvent("right-click",
|
||||
ModifiersToObject(isolate(), modifiers), bounds);
|
||||
EmitWithFlags("right-click", modifiers, bounds);
|
||||
}
|
||||
|
||||
void Tray::OnBalloonShow() {
|
||||
|
@ -159,14 +149,8 @@ void Tray::SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu) {
|
|||
tray_icon_->SetContextMenu(menu->model());
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> Tray::ModifiersToObject(v8::Isolate* isolate,
|
||||
int modifiers) {
|
||||
mate::Dictionary obj(isolate, v8::Object::New(isolate));
|
||||
obj.Set("shiftKey", static_cast<bool>(modifiers & ui::EF_SHIFT_DOWN));
|
||||
obj.Set("ctrlKey", static_cast<bool>(modifiers & ui::EF_CONTROL_DOWN));
|
||||
obj.Set("altKey", static_cast<bool>(modifiers & ui::EF_ALT_DOWN));
|
||||
obj.Set("metaKey", static_cast<bool>(modifiers & ui::EF_COMMAND_DOWN));
|
||||
return obj.GetHandle();
|
||||
gfx::Rect Tray::GetBounds() {
|
||||
return tray_icon_->GetBounds();
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -181,7 +165,8 @@ void Tray::BuildPrototype(v8::Isolate* isolate,
|
|||
.SetMethod("setHighlightMode", &Tray::SetHighlightMode)
|
||||
.SetMethod("displayBalloon", &Tray::DisplayBalloon)
|
||||
.SetMethod("popUpContextMenu", &Tray::PopUpContextMenu)
|
||||
.SetMethod("setContextMenu", &Tray::SetContextMenu);
|
||||
.SetMethod("setContextMenu", &Tray::SetContextMenu)
|
||||
.SetMethod("getBounds", &Tray::GetBounds);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
|
|
@ -65,10 +65,9 @@ class Tray : public mate::TrackableObject<Tray>,
|
|||
void DisplayBalloon(mate::Arguments* args, const mate::Dictionary& options);
|
||||
void PopUpContextMenu(mate::Arguments* args);
|
||||
void SetContextMenu(v8::Isolate* isolate, mate::Handle<Menu> menu);
|
||||
gfx::Rect GetBounds();
|
||||
|
||||
private:
|
||||
v8::Local<v8::Object> ModifiersToObject(v8::Isolate* isolate, int modifiers);
|
||||
|
||||
v8::Global<v8::Object> menu_;
|
||||
std::unique_ptr<TrayIcon> tray_icon_;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "atom/browser/lib/bluetooth_chooser.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/net/atom_network_delegate.h"
|
||||
#include "atom/browser/ui/drag_util.h"
|
||||
#include "atom/browser/web_contents_permission_helper.h"
|
||||
#include "atom/browser/web_contents_preferences.h"
|
||||
#include "atom/browser/web_view_guest_delegate.h"
|
||||
|
@ -61,11 +62,9 @@
|
|||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/http/http_response_headers.h"
|
||||
#include "net/url_request/static_http_user_agent_settings.h"
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "third_party/WebKit/public/web/WebInputEvent.h"
|
||||
#include "third_party/WebKit/public/web/WebFindOptions.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
|
@ -76,15 +75,6 @@ struct PrintSettings {
|
|||
bool print_background;
|
||||
};
|
||||
|
||||
void SetUserAgentInIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
std::string accept_lang,
|
||||
std::string user_agent) {
|
||||
getter->GetURLRequestContext()->set_http_user_agent_settings(
|
||||
new net::StaticHttpUserAgentSettings(
|
||||
net::HttpUtil::GenerateAcceptLanguageHeader(accept_lang),
|
||||
user_agent));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
@ -618,7 +608,10 @@ void WebContents::DidFailProvisionalLoad(
|
|||
bool was_ignored_by_handler) {
|
||||
bool is_main_frame = !render_frame_host->GetParent();
|
||||
Emit("did-fail-provisional-load", code, description, url, is_main_frame);
|
||||
Emit("did-fail-load", code, description, url, is_main_frame);
|
||||
|
||||
// Do not emit "did-fail-load" for canceled requests.
|
||||
if (code != net::ERR_ABORTED)
|
||||
Emit("did-fail-load", code, description, url, is_main_frame);
|
||||
}
|
||||
|
||||
void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
|
||||
|
@ -811,7 +804,7 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
|
|||
|
||||
std::string user_agent;
|
||||
if (options.Get("userAgent", &user_agent))
|
||||
SetUserAgent(user_agent);
|
||||
web_contents()->SetUserAgentOverride(user_agent);
|
||||
|
||||
std::string extra_headers;
|
||||
if (options.Get("extraHeaders", &extra_headers))
|
||||
|
@ -898,14 +891,9 @@ bool WebContents::IsCrashed() const {
|
|||
return web_contents()->IsCrashed();
|
||||
}
|
||||
|
||||
void WebContents::SetUserAgent(const std::string& user_agent) {
|
||||
void WebContents::SetUserAgent(const std::string& user_agent,
|
||||
mate::Arguments* args) {
|
||||
web_contents()->SetUserAgentOverride(user_agent);
|
||||
scoped_refptr<net::URLRequestContextGetter> getter =
|
||||
web_contents()->GetBrowserContext()->GetRequestContext();
|
||||
|
||||
auto accept_lang = l10n_util::GetApplicationLocale("");
|
||||
getter->GetNetworkTaskRunner()->PostTask(FROM_HERE,
|
||||
base::Bind(&SetUserAgentInIO, getter, accept_lang, user_agent));
|
||||
}
|
||||
|
||||
std::string WebContents::GetUserAgent() {
|
||||
|
@ -1194,15 +1182,14 @@ void WebContents::SendInputEvent(v8::Isolate* isolate,
|
|||
isolate, "Invalid event object")));
|
||||
}
|
||||
|
||||
void WebContents::BeginFrameSubscription(
|
||||
mate::Arguments* args) {
|
||||
FrameSubscriber::FrameCaptureCallback callback;
|
||||
void WebContents::BeginFrameSubscription(mate::Arguments* args) {
|
||||
bool only_dirty = false;
|
||||
FrameSubscriber::FrameCaptureCallback callback;
|
||||
|
||||
args->GetNext(&only_dirty);
|
||||
if (!args->GetNext(&callback)) {
|
||||
args->GetNext(&only_dirty);
|
||||
if (!args->GetNext(&callback))
|
||||
args->ThrowTypeError("'callback' must be defined");
|
||||
args->ThrowError();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto view = web_contents()->GetRenderWidgetHostView();
|
||||
|
@ -1219,6 +1206,35 @@ void WebContents::EndFrameSubscription() {
|
|||
view->EndFrameSubscription();
|
||||
}
|
||||
|
||||
void WebContents::StartDrag(const mate::Dictionary& item,
|
||||
mate::Arguments* args) {
|
||||
base::FilePath file;
|
||||
std::vector<base::FilePath> files;
|
||||
if (!item.Get("files", &files) && item.Get("file", &file)) {
|
||||
files.push_back(file);
|
||||
}
|
||||
|
||||
mate::Handle<NativeImage> icon;
|
||||
if (!item.Get("icon", &icon) && !file.empty()) {
|
||||
// TODO(zcbenz): Set default icon from file.
|
||||
}
|
||||
|
||||
// Error checking.
|
||||
if (icon.IsEmpty()) {
|
||||
args->ThrowError("icon must be set");
|
||||
return;
|
||||
}
|
||||
|
||||
// Start dragging.
|
||||
if (!files.empty()) {
|
||||
base::MessageLoop::ScopedNestableTaskAllower allow(
|
||||
base::MessageLoop::current());
|
||||
DragFileItems(files, icon->image(), web_contents()->GetNativeView());
|
||||
} else {
|
||||
args->ThrowError("There is nothing to drag");
|
||||
}
|
||||
}
|
||||
|
||||
void WebContents::OnCursorChange(const content::WebCursor& cursor) {
|
||||
content::WebCursor::CursorInfo info;
|
||||
cursor.GetCursorInfo(&info);
|
||||
|
@ -1338,6 +1354,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
|||
.SetMethod("beginFrameSubscription",
|
||||
&WebContents::BeginFrameSubscription)
|
||||
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
|
||||
.SetMethod("startDrag", &WebContents::StartDrag)
|
||||
.SetMethod("setSize", &WebContents::SetSize)
|
||||
.SetMethod("isGuest", &WebContents::IsGuest)
|
||||
.SetMethod("getType", &WebContents::GetType)
|
||||
|
|
|
@ -81,7 +81,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
|||
void GoForward();
|
||||
void GoToOffset(int offset);
|
||||
bool IsCrashed() const;
|
||||
void SetUserAgent(const std::string& user_agent);
|
||||
void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
|
||||
std::string GetUserAgent();
|
||||
void InsertCSS(const std::string& css);
|
||||
bool SavePage(const base::FilePath& full_file_path,
|
||||
|
@ -142,6 +142,9 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
|||
void BeginFrameSubscription(mate::Arguments* args);
|
||||
void EndFrameSubscription();
|
||||
|
||||
// Dragging native items.
|
||||
void StartDrag(const mate::Dictionary& item, mate::Arguments* args);
|
||||
|
||||
// Methods for creating <webview>.
|
||||
void SetSize(const SetSizeParams& params);
|
||||
bool IsGuest() const;
|
||||
|
|
|
@ -106,9 +106,6 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
|
|||
options,
|
||||
parent.IsEmpty() ? nullptr : parent->window_.get()));
|
||||
web_contents->SetOwnerWindow(window_.get());
|
||||
window_->InitFromOptions(options);
|
||||
window_->AddObserver(this);
|
||||
AttachAsUserData(window_.get());
|
||||
|
||||
#if defined(TOOLKIT_VIEWS)
|
||||
// Sets the window icon.
|
||||
|
@ -116,6 +113,10 @@ Window::Window(v8::Isolate* isolate, const mate::Dictionary& options) {
|
|||
if (options.Get(options::kIcon, &icon))
|
||||
SetIcon(icon);
|
||||
#endif
|
||||
|
||||
window_->InitFromOptions(options);
|
||||
window_->AddObserver(this);
|
||||
AttachAsUserData(window_.get());
|
||||
}
|
||||
|
||||
Window::~Window() {
|
||||
|
@ -572,6 +573,10 @@ void Window::SetIgnoreMouseEvents(bool ignore) {
|
|||
return window_->SetIgnoreMouseEvents(ignore);
|
||||
}
|
||||
|
||||
void Window::SetContentProtection(bool enable) {
|
||||
return window_->SetContentProtection(enable);
|
||||
}
|
||||
|
||||
void Window::SetFocusable(bool focusable) {
|
||||
return window_->SetFocusable(focusable);
|
||||
}
|
||||
|
@ -833,6 +838,7 @@ void Window::BuildPrototype(v8::Isolate* isolate,
|
|||
.SetMethod("setDocumentEdited", &Window::SetDocumentEdited)
|
||||
.SetMethod("isDocumentEdited", &Window::IsDocumentEdited)
|
||||
.SetMethod("setIgnoreMouseEvents", &Window::SetIgnoreMouseEvents)
|
||||
.SetMethod("setContentProtection", &Window::SetContentProtection)
|
||||
.SetMethod("setFocusable", &Window::SetFocusable)
|
||||
.SetMethod("focusOnWebView", &Window::FocusOnWebView)
|
||||
.SetMethod("blurWebView", &Window::BlurWebView)
|
||||
|
|
|
@ -153,6 +153,7 @@ class Window : public mate::TrackableObject<Window>,
|
|||
void SetDocumentEdited(bool edited);
|
||||
bool IsDocumentEdited();
|
||||
void SetIgnoreMouseEvents(bool ignore);
|
||||
void SetContentProtection(bool enable);
|
||||
void SetFocusable(bool focusable);
|
||||
void CapturePage(mate::Arguments* args);
|
||||
void SetProgressBar(double progress);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "native_mate/arguments.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "ui/events/event_constants.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
|
@ -65,6 +66,15 @@ v8::Local<v8::Object> CreateCustomEvent(
|
|||
return event;
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags) {
|
||||
mate::Dictionary obj = mate::Dictionary::CreateEmpty(isolate);
|
||||
obj.Set("shiftKey", static_cast<bool>(flags & ui::EF_SHIFT_DOWN));
|
||||
obj.Set("ctrlKey", static_cast<bool>(flags & ui::EF_CONTROL_DOWN));
|
||||
obj.Set("altKey", static_cast<bool>(flags & ui::EF_ALT_DOWN));
|
||||
obj.Set("metaKey", static_cast<bool>(flags & ui::EF_COMMAND_DOWN));
|
||||
return obj.GetHandle();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace mate
|
||||
|
|
|
@ -30,6 +30,7 @@ v8::Local<v8::Object> CreateCustomEvent(
|
|||
v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> object,
|
||||
v8::Local<v8::Object> event);
|
||||
v8::Local<v8::Object> CreateEventFromFlags(v8::Isolate* isolate, int flags);
|
||||
|
||||
} // namespace internal
|
||||
|
||||
|
@ -54,6 +55,16 @@ class EventEmitter : public Wrappable<T> {
|
|||
internal::CreateCustomEvent(isolate(), GetWrapper(), event), args...);
|
||||
}
|
||||
|
||||
// this.emit(name, new Event(flags), args...);
|
||||
template<typename... Args>
|
||||
bool EmitWithFlags(const base::StringPiece& name,
|
||||
int flags,
|
||||
const Args&... args) {
|
||||
return EmitCustomEvent(
|
||||
name,
|
||||
internal::CreateEventFromFlags(isolate(), flags), args...);
|
||||
}
|
||||
|
||||
// this.emit(name, new Event(), args...);
|
||||
template<typename... Args>
|
||||
bool Emit(const base::StringPiece& name, const Args&... args) {
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#include "atom/browser/api/frame_subscriber.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
|
||||
#include <iostream>
|
||||
|
@ -31,8 +31,11 @@ FrameSubscriber::FrameSubscriber(v8::Isolate* isolate,
|
|||
content::RenderWidgetHostView* view,
|
||||
const FrameCaptureCallback& callback,
|
||||
bool only_dirty)
|
||||
: isolate_(isolate), view_(view), callback_(callback),
|
||||
only_dirty_(only_dirty), weak_factory_(this) {
|
||||
: isolate_(isolate),
|
||||
view_(view),
|
||||
callback_(callback),
|
||||
only_dirty_(only_dirty),
|
||||
weak_factory_(this) {
|
||||
}
|
||||
|
||||
bool FrameSubscriber::ShouldCaptureFrame(
|
||||
|
@ -87,8 +90,9 @@ void FrameSubscriber::ReadbackResultAsBitmap(
|
|||
}
|
||||
|
||||
void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback,
|
||||
const gfx::Rect& damage_rect, const SkBitmap& bitmap,
|
||||
content::ReadbackResponse response) {
|
||||
const gfx::Rect& damage_rect,
|
||||
const SkBitmap& bitmap,
|
||||
content::ReadbackResponse response) {
|
||||
if (response != content::ReadbackResponse::READBACK_SUCCESS)
|
||||
return;
|
||||
|
||||
|
@ -106,7 +110,7 @@ void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback,
|
|||
rgb_arr_size);
|
||||
|
||||
v8::Local<v8::Value> damage =
|
||||
mate::Converter<gfx::Rect>::ToV8(isolate_, damage_rect);
|
||||
mate::Converter<gfx::Rect>::ToV8(isolate_, damage_rect);
|
||||
|
||||
callback_.Run(buffer.ToLocalChecked(), damage);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class FrameSubscriberRenderWidgetHostView
|
|||
class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber {
|
||||
public:
|
||||
using FrameCaptureCallback =
|
||||
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
|
||||
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
|
||||
|
||||
FrameSubscriber(v8::Isolate* isolate,
|
||||
content::RenderWidgetHostView* view,
|
||||
|
@ -52,8 +52,9 @@ class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber {
|
|||
std::unique_ptr<cc::CopyOutputResult> result);
|
||||
|
||||
void OnFrameDelivered(const FrameCaptureCallback& callback,
|
||||
const gfx::Rect& damage_rect, const SkBitmap& bitmap,
|
||||
content::ReadbackResponse response);
|
||||
const gfx::Rect& damage_rect,
|
||||
const SkBitmap& bitmap,
|
||||
content::ReadbackResponse response);
|
||||
|
||||
v8::Isolate* isolate_;
|
||||
content::RenderWidgetHostView* view_;
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
#include <utility>
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/common/google_api_key.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/geolocation_provider.h"
|
||||
|
||||
namespace atom {
|
||||
|
@ -25,6 +25,7 @@ const char* kGeolocationProviderURL =
|
|||
} // namespace
|
||||
|
||||
AtomAccessTokenStore::AtomAccessTokenStore() {
|
||||
LOG(ERROR) << "AtomAccessTokenStore";
|
||||
content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices();
|
||||
}
|
||||
|
||||
|
@ -33,21 +34,35 @@ AtomAccessTokenStore::~AtomAccessTokenStore() {
|
|||
|
||||
void AtomAccessTokenStore::LoadAccessTokens(
|
||||
const LoadAccessTokensCallback& callback) {
|
||||
AccessTokenMap access_token_map;
|
||||
|
||||
// Equivelent to access_token_map[kGeolocationProviderURL].
|
||||
// Somehow base::string16 is causing compilation errors when used in a pair
|
||||
// of std::map on Linux, this can work around it.
|
||||
std::pair<GURL, base::string16> token_pair;
|
||||
token_pair.first = GURL(kGeolocationProviderURL);
|
||||
access_token_map.insert(token_pair);
|
||||
|
||||
auto browser_context = AtomBrowserMainParts::Get()->browser_context();
|
||||
callback.Run(access_token_map, browser_context->url_request_context_getter());
|
||||
content::BrowserThread::PostTaskAndReply(
|
||||
content::BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(&AtomAccessTokenStore::GetRequestContextOnUIThread, this),
|
||||
base::Bind(&AtomAccessTokenStore::RespondOnOriginatingThread,
|
||||
this, callback));
|
||||
}
|
||||
|
||||
void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,
|
||||
const base::string16& access_token) {
|
||||
}
|
||||
|
||||
void AtomAccessTokenStore::GetRequestContextOnUIThread() {
|
||||
auto browser_context = brightray::BrowserContext::From("", false);
|
||||
request_context_getter_ = browser_context->GetRequestContext();
|
||||
}
|
||||
|
||||
void AtomAccessTokenStore::RespondOnOriginatingThread(
|
||||
const LoadAccessTokensCallback& callback) {
|
||||
// Equivelent to access_token_map[kGeolocationProviderURL].
|
||||
// Somehow base::string16 is causing compilation errors when used in a pair
|
||||
// of std::map on Linux, this can work around it.
|
||||
AccessTokenMap access_token_map;
|
||||
std::pair<GURL, base::string16> token_pair;
|
||||
token_pair.first = GURL(kGeolocationProviderURL);
|
||||
access_token_map.insert(token_pair);
|
||||
|
||||
callback.Run(access_token_map, request_context_getter_.get());
|
||||
request_context_getter_ = nullptr;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -9,12 +9,10 @@
|
|||
|
||||
namespace atom {
|
||||
|
||||
class AtomBrowserContext;
|
||||
|
||||
class AtomAccessTokenStore : public content::AccessTokenStore {
|
||||
public:
|
||||
AtomAccessTokenStore();
|
||||
virtual ~AtomAccessTokenStore();
|
||||
~AtomAccessTokenStore();
|
||||
|
||||
// content::AccessTokenStore:
|
||||
void LoadAccessTokens(
|
||||
|
@ -23,6 +21,11 @@ class AtomAccessTokenStore : public content::AccessTokenStore {
|
|||
const base::string16& access_token) override;
|
||||
|
||||
private:
|
||||
void GetRequestContextOnUIThread();
|
||||
void RespondOnOriginatingThread(const LoadAccessTokensCallback& callback);
|
||||
|
||||
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomAccessTokenStore);
|
||||
};
|
||||
|
||||
|
|
|
@ -287,20 +287,21 @@ brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
|||
|
||||
void AtomBrowserClient::WebNotificationAllowed(
|
||||
int render_process_id,
|
||||
const base::Callback<void(bool)>& callback) {
|
||||
const base::Callback<void(bool, bool)>& callback) {
|
||||
content::WebContents* web_contents =
|
||||
WebContentsPreferences::GetWebContentsFromProcessID(render_process_id);
|
||||
if (!web_contents) {
|
||||
callback.Run(false);
|
||||
callback.Run(false, false);
|
||||
return;
|
||||
}
|
||||
auto permission_helper =
|
||||
WebContentsPermissionHelper::FromWebContents(web_contents);
|
||||
if (!permission_helper) {
|
||||
callback.Run(false);
|
||||
callback.Run(false, false);
|
||||
return;
|
||||
}
|
||||
permission_helper->RequestWebNotificationPermission(callback);
|
||||
permission_helper->RequestWebNotificationPermission(
|
||||
base::Bind(callback, web_contents->IsAudioMuted()));
|
||||
}
|
||||
|
||||
void AtomBrowserClient::RenderProcessHostDestroyed(
|
||||
|
|
|
@ -100,7 +100,7 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
|||
const content::MainFunctionParams&) override;
|
||||
void WebNotificationAllowed(
|
||||
int render_process_id,
|
||||
const base::Callback<void(bool)>& callback) override;
|
||||
const base::Callback<void(bool, bool)>& callback) override;
|
||||
|
||||
// content::RenderProcessHostObserver:
|
||||
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
|
||||
|
|
|
@ -68,16 +68,7 @@ AtomBrowserContext::AtomBrowserContext(const std::string& partition,
|
|||
: brightray::BrowserContext(partition, in_memory),
|
||||
cert_verifier_(new AtomCertVerifier),
|
||||
network_delegate_(new AtomNetworkDelegate) {
|
||||
}
|
||||
|
||||
AtomBrowserContext::~AtomBrowserContext() {
|
||||
}
|
||||
|
||||
net::NetworkDelegate* AtomBrowserContext::CreateNetworkDelegate() {
|
||||
return network_delegate_;
|
||||
}
|
||||
|
||||
std::string AtomBrowserContext::GetUserAgent() {
|
||||
// Construct user agent string.
|
||||
Browser* browser = Browser::Get();
|
||||
std::string name = RemoveWhitespace(browser->GetName());
|
||||
std::string user_agent;
|
||||
|
@ -91,7 +82,22 @@ std::string AtomBrowserContext::GetUserAgent() {
|
|||
browser->GetVersion().c_str(),
|
||||
CHROME_VERSION_STRING);
|
||||
}
|
||||
return content::BuildUserAgentFromProduct(user_agent);
|
||||
user_agent_ = content::BuildUserAgentFromProduct(user_agent);
|
||||
}
|
||||
|
||||
AtomBrowserContext::~AtomBrowserContext() {
|
||||
}
|
||||
|
||||
void AtomBrowserContext::SetUserAgent(const std::string& user_agent) {
|
||||
user_agent_ = user_agent;
|
||||
}
|
||||
|
||||
net::NetworkDelegate* AtomBrowserContext::CreateNetworkDelegate() {
|
||||
return network_delegate_;
|
||||
}
|
||||
|
||||
std::string AtomBrowserContext::GetUserAgent() {
|
||||
return user_agent_;
|
||||
}
|
||||
|
||||
std::unique_ptr<net::URLRequestJobFactory>
|
||||
|
|
|
@ -22,6 +22,8 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
|||
AtomBrowserContext(const std::string& partition, bool in_memory);
|
||||
~AtomBrowserContext() override;
|
||||
|
||||
void SetUserAgent(const std::string& user_agent);
|
||||
|
||||
// brightray::URLRequestContextGetter::Delegate:
|
||||
net::NetworkDelegate* CreateNetworkDelegate() override;
|
||||
std::string GetUserAgent() override;
|
||||
|
@ -47,6 +49,7 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
|||
std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
|
||||
std::unique_ptr<WebViewManager> guest_manager_;
|
||||
std::unique_ptr<AtomPermissionManager> permission_manager_;
|
||||
std::string user_agent_;
|
||||
|
||||
// Managed by brightray::BrowserContext.
|
||||
AtomCertVerifier* cert_verifier_;
|
||||
|
|
|
@ -124,6 +124,8 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
|
|||
}
|
||||
|
||||
void AtomBrowserMainParts::PreMainMessageLoopRun() {
|
||||
js_env_->OnMessageLoopCreated();
|
||||
|
||||
// Run user's main script before most things get initialized, so we can have
|
||||
// a chance to setup everything.
|
||||
node_bindings_->PrepareMessageLoop();
|
||||
|
@ -169,6 +171,8 @@ void AtomBrowserMainParts::PostMainMessageLoopStart() {
|
|||
void AtomBrowserMainParts::PostMainMessageLoopRun() {
|
||||
brightray::BrowserMainParts::PostMainMessageLoopRun();
|
||||
|
||||
js_env_->OnMessageLoopDestroying();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
FreeAppDelegate();
|
||||
#endif
|
||||
|
|
|
@ -118,6 +118,10 @@ void Browser::SetName(const std::string& name) {
|
|||
name_override_ = name;
|
||||
}
|
||||
|
||||
int Browser::GetBadgeCount() {
|
||||
return badge_count_;
|
||||
}
|
||||
|
||||
bool Browser::OpenFile(const std::string& file_path) {
|
||||
bool prevent_default = false;
|
||||
FOR_EACH_OBSERVER(BrowserObserver,
|
||||
|
|
|
@ -87,6 +87,10 @@ class Browser : public WindowListObserver {
|
|||
// Query the current state of default handler for a protocol.
|
||||
bool IsDefaultProtocolClient(const std::string& protocol);
|
||||
|
||||
// Set/Get the badge count.
|
||||
bool SetBadgeCount(int count);
|
||||
int GetBadgeCount();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Hide the application.
|
||||
void Hide();
|
||||
|
@ -149,7 +153,12 @@ class Browser : public WindowListObserver {
|
|||
// one from app's name.
|
||||
// The returned string managed by Browser, and should not be modified.
|
||||
PCWSTR GetAppUserModelID();
|
||||
#endif
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
// Whether Unity launcher is running.
|
||||
bool IsUnityRunning();
|
||||
#endif // defined(OS_LINUX)
|
||||
|
||||
// Tell the application to open a file.
|
||||
bool OpenFile(const std::string& file_path);
|
||||
|
@ -216,6 +225,8 @@ class Browser : public WindowListObserver {
|
|||
std::string version_override_;
|
||||
std::string name_override_;
|
||||
|
||||
int badge_count_ = 0;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
base::string16 app_user_model_id_;
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "atom/browser/window_list.h"
|
||||
#include "atom/common/atom_version.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
#include "chrome/browser/ui/libgtk2ui/unity_service.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
|
@ -46,6 +47,16 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Browser::SetBadgeCount(int count) {
|
||||
if (IsUnityRunning()) {
|
||||
unity::SetDownloadCount(count);
|
||||
badge_count_ = count;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Browser::GetExecutableFileVersion() const {
|
||||
return brightray::GetApplicationVersion();
|
||||
}
|
||||
|
@ -54,4 +65,8 @@ std::string Browser::GetExecutableFileProductName() const {
|
|||
return brightray::GetApplicationName();
|
||||
}
|
||||
|
||||
bool Browser::IsUnityRunning() {
|
||||
return unity::IsRunning();
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "atom/browser/window_list.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/foundation_util.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "brightray/common/application_info.h"
|
||||
#include "net/base/mac/url_conversions.h"
|
||||
|
@ -114,6 +115,12 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
|
|||
void Browser::SetAppUserModelID(const base::string16& name) {
|
||||
}
|
||||
|
||||
bool Browser::SetBadgeCount(int count) {
|
||||
DockSetBadgeText(count != 0 ? base::IntToString(count) : "");
|
||||
badge_count_ = count;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Browser::SetUserActivity(const std::string& type,
|
||||
const base::DictionaryValue& user_info,
|
||||
mate::Arguments* args) {
|
||||
|
|
|
@ -269,6 +269,10 @@ bool Browser::IsDefaultProtocolClient(const std::string& protocol) {
|
|||
}
|
||||
}
|
||||
|
||||
bool Browser::SetBadgeCount(int count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PCWSTR Browser::GetAppUserModelID() {
|
||||
if (app_user_model_id_.empty()) {
|
||||
SetAppUserModelID(base::ReplaceStringPlaceholders(
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <string>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "gin/array_buffer.h"
|
||||
#include "gin/v8_initializer.h"
|
||||
|
@ -23,6 +24,14 @@ JavascriptEnvironment::JavascriptEnvironment()
|
|||
context_scope_(v8::Local<v8::Context>::New(isolate_, context_)) {
|
||||
}
|
||||
|
||||
void JavascriptEnvironment::OnMessageLoopCreated() {
|
||||
isolate_holder_.AddRunMicrotasksObserver();
|
||||
}
|
||||
|
||||
void JavascriptEnvironment::OnMessageLoopDestroying() {
|
||||
isolate_holder_.RemoveRunMicrotasksObserver();
|
||||
}
|
||||
|
||||
bool JavascriptEnvironment::Initialize() {
|
||||
auto cmd = base::CommandLine::ForCurrentProcess();
|
||||
if (cmd->HasSwitch("debug-brk")) {
|
||||
|
|
|
@ -14,6 +14,9 @@ class JavascriptEnvironment {
|
|||
public:
|
||||
JavascriptEnvironment();
|
||||
|
||||
void OnMessageLoopCreated();
|
||||
void OnMessageLoopDestroying();
|
||||
|
||||
v8::Isolate* isolate() const { return isolate_; }
|
||||
v8::Local<v8::Context> context() const {
|
||||
return v8::Local<v8::Context>::New(isolate_, context_);
|
||||
|
|
|
@ -157,6 +157,7 @@ class NativeWindow : public base::SupportsUserData,
|
|||
virtual void SetDocumentEdited(bool edited);
|
||||
virtual bool IsDocumentEdited();
|
||||
virtual void SetIgnoreMouseEvents(bool ignore) = 0;
|
||||
virtual void SetContentProtection(bool enable) = 0;
|
||||
virtual void SetFocusable(bool focusable);
|
||||
virtual void SetMenu(ui::MenuModel* menu);
|
||||
virtual bool HasModalDialog();
|
||||
|
|
|
@ -79,6 +79,7 @@ class NativeWindowMac : public NativeWindow {
|
|||
void SetDocumentEdited(bool edited) override;
|
||||
bool IsDocumentEdited() override;
|
||||
void SetIgnoreMouseEvents(bool ignore) override;
|
||||
void SetContentProtection(bool enable) override;
|
||||
bool HasModalDialog() override;
|
||||
void SetParentWindow(NativeWindow* parent) override;
|
||||
gfx::NativeWindow GetNativeWindow() override;
|
||||
|
|
|
@ -70,6 +70,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
|||
@interface AtomNSWindowDelegate : NSObject<NSWindowDelegate> {
|
||||
@private
|
||||
atom::NativeWindowMac* shell_;
|
||||
bool is_zooming_;
|
||||
}
|
||||
- (id)initWithShell:(atom::NativeWindowMac*)shell;
|
||||
@end
|
||||
|
@ -79,6 +80,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
|||
- (id)initWithShell:(atom::NativeWindowMac*)shell {
|
||||
if ((self = [super init])) {
|
||||
shell_ = shell;
|
||||
is_zooming_ = false;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -172,16 +174,20 @@ bool ScopedDisableResize::disable_resize_ = false;
|
|||
}
|
||||
|
||||
- (BOOL)windowShouldZoom:(NSWindow*)window toFrame:(NSRect)newFrame {
|
||||
// Cocoa doen't have concept of maximize/unmaximize, so wee need to emulate
|
||||
// them by calculating size change when zooming.
|
||||
if (newFrame.size.width < [window frame].size.width ||
|
||||
newFrame.size.height < [window frame].size.height)
|
||||
shell_->NotifyWindowUnmaximize();
|
||||
else
|
||||
shell_->NotifyWindowMaximize();
|
||||
is_zooming_ = true;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)windowDidEndLiveResize:(NSNotification*)notification {
|
||||
if (is_zooming_) {
|
||||
if (shell_->IsMaximized())
|
||||
shell_->NotifyWindowMaximize();
|
||||
else
|
||||
shell_->NotifyWindowUnmaximize();
|
||||
is_zooming_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)windowWillEnterFullScreen:(NSNotification*)notification {
|
||||
// Hide the native toolbar before entering fullscreen, so there is no visual
|
||||
// artifacts.
|
||||
|
@ -199,6 +205,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
|||
// have to set one, because title bar is visible here.
|
||||
NSWindow* window = shell_->GetNativeWindow();
|
||||
if ((shell_->transparent() || !shell_->has_frame()) &&
|
||||
base::mac::IsOSYosemiteOrLater() &&
|
||||
// FIXME(zcbenz): Showing titlebar for hiddenInset window is weird under
|
||||
// fullscreen mode.
|
||||
shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET) {
|
||||
|
@ -223,6 +230,7 @@ bool ScopedDisableResize::disable_resize_ = false;
|
|||
// Restore the titlebar visibility.
|
||||
NSWindow* window = shell_->GetNativeWindow();
|
||||
if ((shell_->transparent() || !shell_->has_frame()) &&
|
||||
base::mac::IsOSYosemiteOrLater() &&
|
||||
shell_->title_bar_style() != atom::NativeWindowMac::HIDDEN_INSET) {
|
||||
[window setTitleVisibility:NSWindowTitleHidden];
|
||||
}
|
||||
|
@ -526,8 +534,10 @@ NativeWindowMac::NativeWindowMac(
|
|||
[window_ setDisableKeyOrMainWindow:YES];
|
||||
|
||||
if (transparent() || !has_frame()) {
|
||||
// Don't show title bar.
|
||||
[window_ setTitleVisibility:NSWindowTitleHidden];
|
||||
if (base::mac::IsOSYosemiteOrLater()) {
|
||||
// Don't show title bar.
|
||||
[window_ setTitleVisibility:NSWindowTitleHidden];
|
||||
}
|
||||
// Remove non-transparent corners, see http://git.io/vfonD.
|
||||
[window_ setOpaque:NO];
|
||||
}
|
||||
|
@ -852,6 +862,11 @@ void NativeWindowMac::Center() {
|
|||
}
|
||||
|
||||
void NativeWindowMac::SetTitle(const std::string& title) {
|
||||
// For macOS <= 10.9, the setTitleVisibility API is not available, we have
|
||||
// to avoid calling setTitle for frameless window.
|
||||
if (!base::mac::IsOSYosemiteOrLater() && (transparent() || !has_frame()))
|
||||
return;
|
||||
|
||||
[window_ setTitle:base::SysUTF8ToNSString(title)];
|
||||
}
|
||||
|
||||
|
@ -935,6 +950,11 @@ void NativeWindowMac::SetIgnoreMouseEvents(bool ignore) {
|
|||
[window_ setIgnoresMouseEvents:ignore];
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetContentProtection(bool enable) {
|
||||
[window_ setSharingType:enable ? NSWindowSharingNone
|
||||
: NSWindowSharingReadOnly];
|
||||
}
|
||||
|
||||
bool NativeWindowMac::HasModalDialog() {
|
||||
return [window_ attachedSheet] != nil;
|
||||
}
|
||||
|
|
|
@ -752,6 +752,13 @@ void NativeWindowViews::SetIgnoreMouseEvents(bool ignore) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetContentProtection(bool enable) {
|
||||
#if defined(OS_WIN)
|
||||
DWORD affinity = enable ? WDA_MONITOR : WDA_NONE;
|
||||
::SetWindowDisplayAffinity(GetAcceleratedWidget(), affinity);
|
||||
#endif
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetFocusable(bool focusable) {
|
||||
#if defined(OS_WIN)
|
||||
LONG ex_style = ::GetWindowLong(GetAcceleratedWidget(), GWL_EXSTYLE);
|
||||
|
|
|
@ -97,6 +97,7 @@ class NativeWindowViews : public NativeWindow,
|
|||
void SetHasShadow(bool has_shadow) override;
|
||||
bool HasShadow() override;
|
||||
void SetIgnoreMouseEvents(bool ignore) override;
|
||||
void SetContentProtection(bool enable) override;
|
||||
void SetFocusable(bool focusable) override;
|
||||
void SetMenu(ui::MenuModel* menu_model) override;
|
||||
void SetParentWindow(NativeWindow* parent) override;
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.2.3</string>
|
||||
<string>1.2.6</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.2.3</string>
|
||||
<string>1.2.6</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
|
|
@ -56,8 +56,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,2,3,0
|
||||
PRODUCTVERSION 1,2,3,0
|
||||
FILEVERSION 1,2,6,0
|
||||
PRODUCTVERSION 1,2,6,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -74,12 +74,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "1.2.3"
|
||||
VALUE "FileVersion", "1.2.6"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "1.2.3"
|
||||
VALUE "ProductVersion", "1.2.6"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
|
|
@ -29,6 +29,10 @@ void SetPlatformAccelerator(ui::Accelerator* accelerator) {
|
|||
modifiers ^= NSShiftKeyMask;
|
||||
}
|
||||
|
||||
if (character == NSDeleteFunctionKey) {
|
||||
character = NSDeleteCharacter;
|
||||
}
|
||||
|
||||
NSString* characters =
|
||||
[[[NSString alloc] initWithCharacters:&character length:1] autorelease];
|
||||
|
||||
|
|
|
@ -17,12 +17,14 @@ AtomMenuModel::~AtomMenuModel() {
|
|||
}
|
||||
|
||||
void AtomMenuModel::SetRole(int index, const base::string16& role) {
|
||||
roles_[index] = role;
|
||||
int command_id = GetCommandIdAt(index);
|
||||
roles_[command_id] = role;
|
||||
}
|
||||
|
||||
base::string16 AtomMenuModel::GetRoleAt(int index) {
|
||||
if (ContainsKey(roles_, index))
|
||||
return roles_[index];
|
||||
int command_id = GetCommandIdAt(index);
|
||||
if (ContainsKey(roles_, command_id))
|
||||
return roles_[command_id];
|
||||
else
|
||||
return base::string16();
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class AtomMenuModel : public ui::SimpleMenuModel {
|
|||
private:
|
||||
Delegate* delegate_; // weak ref.
|
||||
|
||||
std::map<int, base::string16> roles_;
|
||||
std::map<int, base::string16> roles_; // command id -> role
|
||||
base::ObserverList<Observer> observers_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomMenuModel);
|
||||
|
|
|
@ -38,6 +38,8 @@ Role kRolesMap[] = {
|
|||
{ @selector(performMiniaturize:), "minimize" },
|
||||
{ @selector(performClose:), "close" },
|
||||
{ @selector(performZoom:), "zoom" },
|
||||
{ @selector(terminate:), "quit" },
|
||||
{ @selector(toggleFullScreen:), "togglefullscreen" },
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
24
atom/browser/ui/drag_util.h
Normal file
24
atom/browser/ui/drag_util.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_UI_DRAG_UTIL_H_
|
||||
#define ATOM_BROWSER_UI_DRAG_UTIL_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
void DragFileItems(const std::vector<base::FilePath>& files,
|
||||
const gfx::Image& icon,
|
||||
gfx::NativeView view);
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_UI_DRAG_UTIL_H_
|
58
atom/browser/ui/drag_util_mac.mm
Normal file
58
atom/browser/ui/drag_util_mac.mm
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "atom/browser/ui/drag_util.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
// Write information about the file being dragged to the pasteboard.
|
||||
void AddFilesToPasteboard(NSPasteboard* pasteboard,
|
||||
const std::vector<base::FilePath>& files) {
|
||||
NSMutableArray* fileList = [NSMutableArray array];
|
||||
for (const base::FilePath& file : files)
|
||||
[fileList addObject:base::SysUTF8ToNSString(file.value())];
|
||||
[pasteboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType]
|
||||
owner:nil];
|
||||
[pasteboard setPropertyList:fileList forType:NSFilenamesPboardType];
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void DragFileItems(const std::vector<base::FilePath>& files,
|
||||
const gfx::Image& icon,
|
||||
gfx::NativeView view) {
|
||||
NSPasteboard* pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
|
||||
AddFilesToPasteboard(pasteboard, files);
|
||||
|
||||
// Synthesize a drag event, since we don't have access to the actual event
|
||||
// that initiated a drag (possibly consumed by the Web UI, for example).
|
||||
NSPoint position = [[view window] mouseLocationOutsideOfEventStream];
|
||||
NSTimeInterval eventTime = [[NSApp currentEvent] timestamp];
|
||||
NSEvent* dragEvent = [NSEvent mouseEventWithType:NSLeftMouseDragged
|
||||
location:position
|
||||
modifierFlags:NSLeftMouseDraggedMask
|
||||
timestamp:eventTime
|
||||
windowNumber:[[view window] windowNumber]
|
||||
context:nil
|
||||
eventNumber:0
|
||||
clickCount:1
|
||||
pressure:1.0];
|
||||
|
||||
// Run the drag operation.
|
||||
[[view window] dragImage:icon.ToNSImage()
|
||||
at:position
|
||||
offset:NSZeroSize
|
||||
event:dragEvent
|
||||
pasteboard:pasteboard
|
||||
source:view
|
||||
slideBack:YES];
|
||||
}
|
||||
|
||||
} // namespace atom
|
48
atom/browser/ui/drag_util_views.cc
Normal file
48
atom/browser/ui/drag_util_views.cc
Normal file
|
@ -0,0 +1,48 @@
|
|||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/ui/drag_util.h"
|
||||
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/base/dragdrop/drag_drop_types.h"
|
||||
#include "ui/base/dragdrop/drag_utils.h"
|
||||
#include "ui/base/dragdrop/file_info.h"
|
||||
#include "ui/base/dragdrop/os_exchange_data.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
#include "ui/wm/public/drag_drop_client.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
void DragFileItems(const std::vector<base::FilePath>& files,
|
||||
const gfx::Image& icon,
|
||||
gfx::NativeView view) {
|
||||
// Set up our OLE machinery
|
||||
ui::OSExchangeData data;
|
||||
|
||||
drag_utils::CreateDragImageForFile(files[0], icon.AsImageSkia(), &data);
|
||||
|
||||
std::vector<ui::FileInfo> file_infos;
|
||||
for (const base::FilePath& file : files) {
|
||||
file_infos.push_back(ui::FileInfo(file, base::FilePath()));
|
||||
}
|
||||
data.SetFilenames(file_infos);
|
||||
|
||||
aura::Window* root_window = view->GetRootWindow();
|
||||
if (!root_window || !aura::client::GetDragDropClient(root_window))
|
||||
return;
|
||||
|
||||
gfx::Point location = gfx::Screen::GetScreen()->GetCursorScreenPoint();
|
||||
// TODO(varunjain): Properly determine and send DRAG_EVENT_SOURCE below.
|
||||
aura::client::GetDragDropClient(root_window)->StartDragAndDrop(
|
||||
data,
|
||||
root_window,
|
||||
view,
|
||||
location,
|
||||
ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK,
|
||||
ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE);
|
||||
}
|
||||
|
||||
} // namespace atom
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "atom/browser/ui/file_dialog.h"
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
|
@ -40,7 +40,8 @@ class FileChooserDialog {
|
|||
const std::string& button_label,
|
||||
const base::FilePath& default_path,
|
||||
const Filters& filters)
|
||||
: dialog_scope_(parent_window),
|
||||
: parent_(static_cast<atom::NativeWindowViews*>(parent_window)),
|
||||
dialog_scope_(parent_window),
|
||||
filters_(filters) {
|
||||
const char* confirm_text = GTK_STOCK_OK;
|
||||
|
||||
|
@ -58,9 +59,10 @@ class FileChooserDialog {
|
|||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
confirm_text, GTK_RESPONSE_ACCEPT,
|
||||
NULL);
|
||||
if (parent_window) {
|
||||
gfx::NativeWindow window = parent_window->GetNativeWindow();
|
||||
libgtk2ui::SetGtkTransientForAura(dialog_, window);
|
||||
if (parent_) {
|
||||
parent_->SetEnabled(false);
|
||||
libgtk2ui::SetGtkTransientForAura(dialog_, parent_->GetNativeWindow());
|
||||
gtk_window_set_modal(GTK_WINDOW(dialog_), TRUE);
|
||||
}
|
||||
|
||||
if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
|
||||
|
@ -69,8 +71,6 @@ class FileChooserDialog {
|
|||
if (action != GTK_FILE_CHOOSER_ACTION_OPEN)
|
||||
gtk_file_chooser_set_create_folders(GTK_FILE_CHOOSER(dialog_), TRUE);
|
||||
|
||||
gtk_window_set_modal(GTK_WINDOW(dialog_), TRUE);
|
||||
|
||||
if (!default_path.empty()) {
|
||||
if (base::DirectoryExists(default_path)) {
|
||||
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog_),
|
||||
|
@ -89,6 +89,8 @@ class FileChooserDialog {
|
|||
|
||||
virtual ~FileChooserDialog() {
|
||||
gtk_widget_destroy(dialog_);
|
||||
if (parent_)
|
||||
parent_->SetEnabled(true);
|
||||
}
|
||||
|
||||
void RunAsynchronous() {
|
||||
|
@ -143,6 +145,7 @@ class FileChooserDialog {
|
|||
void AddFilters(const Filters& filters);
|
||||
base::FilePath AddExtensionForFilename(const gchar* filename) const;
|
||||
|
||||
atom::NativeWindowViews* parent_;
|
||||
atom::NativeWindow::DialogScope dialog_scope_;
|
||||
|
||||
GtkWidget* dialog_;
|
||||
|
@ -208,7 +211,9 @@ base::FilePath FileChooserDialog::AddExtensionForFilename(
|
|||
|
||||
const auto& extensions = filters_[i].second;
|
||||
for (const auto& extension : extensions) {
|
||||
if (extension == "*" || path.MatchesExtension("." + extension))
|
||||
if (extension == "*" ||
|
||||
base::EndsWith(path.value(), "." + extension,
|
||||
base::CompareCase::INSENSITIVE_ASCII))
|
||||
return path;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "atom/browser/ui/message_box.h"
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/native_window_views.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
|
@ -36,7 +36,8 @@ class GtkMessageBox {
|
|||
const std::string& detail,
|
||||
const gfx::ImageSkia& icon)
|
||||
: dialog_scope_(parent_window),
|
||||
cancel_id_(cancel_id) {
|
||||
cancel_id_(cancel_id),
|
||||
parent_(static_cast<NativeWindowViews*>(parent_window)) {
|
||||
// Create dialog.
|
||||
dialog_ = gtk_message_dialog_new(
|
||||
nullptr, // parent
|
||||
|
@ -75,14 +76,17 @@ class GtkMessageBox {
|
|||
}
|
||||
|
||||
// Parent window.
|
||||
if (parent_window) {
|
||||
gfx::NativeWindow window = parent_window->GetNativeWindow();
|
||||
libgtk2ui::SetGtkTransientForAura(dialog_, window);
|
||||
if (parent_) {
|
||||
parent_->SetEnabled(false);
|
||||
libgtk2ui::SetGtkTransientForAura(dialog_, parent_->GetNativeWindow());
|
||||
gtk_window_set_modal(GTK_WINDOW(dialog_), TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
~GtkMessageBox() {
|
||||
gtk_widget_destroy(dialog_);
|
||||
if (parent_)
|
||||
parent_->SetEnabled(true);
|
||||
}
|
||||
|
||||
GtkMessageType GetMessageType(MessageBoxType type) {
|
||||
|
@ -123,7 +127,6 @@ class GtkMessageBox {
|
|||
}
|
||||
|
||||
int RunSynchronous() {
|
||||
gtk_window_set_modal(GTK_WINDOW(dialog_), TRUE);
|
||||
Show();
|
||||
int response = gtk_dialog_run(GTK_DIALOG(dialog_));
|
||||
if (response < 0)
|
||||
|
@ -149,6 +152,7 @@ class GtkMessageBox {
|
|||
// The id to return when the dialog is closed without pressing buttons.
|
||||
int cancel_id_;
|
||||
|
||||
NativeWindowViews* parent_;
|
||||
GtkWidget* dialog_;
|
||||
MessageBoxCallback callback_;
|
||||
|
||||
|
|
|
@ -30,6 +30,10 @@ void TrayIcon::PopUpContextMenu(const gfx::Point& pos,
|
|||
ui::SimpleMenuModel* menu_model) {
|
||||
}
|
||||
|
||||
gfx::Rect TrayIcon::GetBounds() {
|
||||
return gfx::Rect();
|
||||
}
|
||||
|
||||
void TrayIcon::NotifyClicked(const gfx::Rect& bounds, int modifiers) {
|
||||
FOR_EACH_OBSERVER(TrayIconObserver, observers_, OnClicked(bounds, modifiers));
|
||||
}
|
||||
|
|
|
@ -60,8 +60,12 @@ class TrayIcon {
|
|||
// Set the context menu for this icon.
|
||||
virtual void SetContextMenu(ui::SimpleMenuModel* menu_model) = 0;
|
||||
|
||||
// Returns the bounds of tray icon.
|
||||
virtual gfx::Rect GetBounds();
|
||||
|
||||
void AddObserver(TrayIconObserver* obs) { observers_.AddObserver(obs); }
|
||||
void RemoveObserver(TrayIconObserver* obs) { observers_.RemoveObserver(obs); }
|
||||
|
||||
void NotifyClicked(const gfx::Rect& = gfx::Rect(), int modifiers = 0);
|
||||
void NotifyDoubleClicked(const gfx::Rect& = gfx::Rect(), int modifiers = 0);
|
||||
void NotifyBalloonShow();
|
||||
|
|
|
@ -32,6 +32,7 @@ class TrayIconCocoa : public TrayIcon,
|
|||
void PopUpContextMenu(const gfx::Point& pos,
|
||||
ui::SimpleMenuModel* menu_model) override;
|
||||
void SetContextMenu(ui::SimpleMenuModel* menu_model) override;
|
||||
gfx::Rect GetBounds() override;
|
||||
|
||||
protected:
|
||||
// AtomMenuModel::Observer:
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "ui/events/cocoa/cocoa_event_utils.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "ui/gfx/mac/coordinate_conversion.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
|
||||
namespace {
|
||||
|
@ -236,13 +237,13 @@ const CGFloat kVerticalTitleMargin = 2;
|
|||
// Single click event.
|
||||
if (event.clickCount == 1)
|
||||
trayIcon_->NotifyClicked(
|
||||
[self getBoundsFromEvent:event],
|
||||
gfx::ScreenRectFromNSRect(event.window.frame),
|
||||
ui::EventFlagsFromModifiers([event modifierFlags]));
|
||||
|
||||
// Double click event.
|
||||
if (event.clickCount == 2)
|
||||
trayIcon_->NotifyDoubleClicked(
|
||||
[self getBoundsFromEvent:event],
|
||||
gfx::ScreenRectFromNSRect(event.window.frame),
|
||||
ui::EventFlagsFromModifiers([event modifierFlags]));
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
|
@ -262,7 +263,7 @@ const CGFloat kVerticalTitleMargin = 2;
|
|||
}
|
||||
|
||||
if (menuController_ && ![menuController_ isMenuOpen]) {
|
||||
// Redraw the dray icon to show highlight if it is enabled.
|
||||
// Redraw the tray icon to show highlight if it is enabled.
|
||||
[self setNeedsDisplay:YES];
|
||||
[statusItem_ popUpStatusItemMenu:[menuController_ menu]];
|
||||
// The popUpStatusItemMenu returns only after the showing menu is closed.
|
||||
|
@ -273,7 +274,7 @@ const CGFloat kVerticalTitleMargin = 2;
|
|||
|
||||
- (void)rightMouseUp:(NSEvent*)event {
|
||||
trayIcon_->NotifyRightClicked(
|
||||
[self getBoundsFromEvent:event],
|
||||
gfx::ScreenRectFromNSRect(event.window.frame),
|
||||
ui::EventFlagsFromModifiers([event modifierFlags]));
|
||||
}
|
||||
|
||||
|
@ -324,13 +325,6 @@ const CGFloat kVerticalTitleMargin = 2;
|
|||
return isHighlightEnable_ && (inMouseEventSequence_ || isMenuOpen);
|
||||
}
|
||||
|
||||
- (gfx::Rect)getBoundsFromEvent:(NSEvent*)event {
|
||||
NSRect frame = event.window.frame;
|
||||
gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame));
|
||||
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
|
||||
bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
|
||||
return bounds;
|
||||
}
|
||||
@end
|
||||
|
||||
namespace atom {
|
||||
|
@ -386,6 +380,15 @@ void TrayIconCocoa::SetContextMenu(ui::SimpleMenuModel* menu_model) {
|
|||
[status_item_view_ setMenuController:menu_.get()];
|
||||
}
|
||||
|
||||
gfx::Rect TrayIconCocoa::GetBounds() {
|
||||
auto bounds = gfx::ScreenRectFromNSRect([status_item_view_ window].frame);
|
||||
// Calling [window frame] immediately after the view gets created will have
|
||||
// negative |y| sometimes.
|
||||
if (bounds.y() < 0)
|
||||
bounds.set_y(0);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
void TrayIconCocoa::MenuClosed() {
|
||||
[status_item_view_ setNeedsDisplay:YES];
|
||||
}
|
||||
|
|
|
@ -50,14 +50,7 @@ void GetMenuBarColor(SkColor* enabled, SkColor* disabled, SkColor* highlight,
|
|||
MenuBar::MenuBar()
|
||||
: background_color_(kDefaultColor),
|
||||
menu_model_(NULL) {
|
||||
#if defined(OS_WIN)
|
||||
background_color_ = color_utils::GetSysSkColor(COLOR_MENUBAR);
|
||||
#elif defined(USE_X11)
|
||||
GetMenuBarColor(&enabled_color_, &disabled_color_, &highlight_color_,
|
||||
&hover_color_, &background_color_);
|
||||
#endif
|
||||
|
||||
set_background(views::Background::CreateSolidBackground(background_color_));
|
||||
UpdateMenuBarColor();
|
||||
SetLayoutManager(new views::BoxLayout(
|
||||
views::BoxLayout::kHorizontal, 0, 0, 0));
|
||||
}
|
||||
|
@ -152,11 +145,27 @@ void MenuBar::OnMenuButtonClicked(views::MenuButton* source,
|
|||
|
||||
int id = source->tag();
|
||||
ui::MenuModel::ItemType type = menu_model_->GetTypeAt(id);
|
||||
if (type != ui::MenuModel::TYPE_SUBMENU)
|
||||
if (type != ui::MenuModel::TYPE_SUBMENU) {
|
||||
menu_model_->ActivatedAt(id, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
MenuDelegate menu_delegate(this);
|
||||
menu_delegate.RunMenu(menu_model_->GetSubmenuModelAt(id), source);
|
||||
}
|
||||
|
||||
void MenuBar::OnNativeThemeChanged(const ui::NativeTheme* theme) {
|
||||
UpdateMenuBarColor();
|
||||
}
|
||||
|
||||
void MenuBar::UpdateMenuBarColor() {
|
||||
#if defined(OS_WIN)
|
||||
background_color_ = color_utils::GetSysSkColor(COLOR_MENUBAR);
|
||||
#elif defined(USE_X11)
|
||||
GetMenuBarColor(&enabled_color_, &disabled_color_, &highlight_color_,
|
||||
&hover_color_, &background_color_);
|
||||
#endif
|
||||
set_background(views::Background::CreateSolidBackground(background_color_));
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -60,9 +60,11 @@ class MenuBar : public views::View,
|
|||
void OnMenuButtonClicked(views::MenuButton* source,
|
||||
const gfx::Point& point,
|
||||
const ui::Event* event) override;
|
||||
|
||||
void OnNativeThemeChanged(const ui::NativeTheme* theme) override;
|
||||
|
||||
private:
|
||||
void UpdateMenuBarColor();
|
||||
|
||||
SkColor background_color_;
|
||||
|
||||
#if defined(USE_X11)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "ui/gfx/geometry/point.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
#include "ui/gfx/win/dpi.h"
|
||||
#include "ui/views/controls/menu/menu_runner.h"
|
||||
|
||||
namespace atom {
|
||||
|
@ -48,26 +49,19 @@ NotifyIcon::~NotifyIcon() {
|
|||
void NotifyIcon::HandleClickEvent(int modifiers,
|
||||
bool left_mouse_click,
|
||||
bool double_button_click) {
|
||||
NOTIFYICONIDENTIFIER icon_id;
|
||||
memset(&icon_id, 0, sizeof(NOTIFYICONIDENTIFIER));
|
||||
icon_id.uID = icon_id_;
|
||||
icon_id.hWnd = window_;
|
||||
icon_id.cbSize = sizeof(NOTIFYICONIDENTIFIER);
|
||||
|
||||
RECT rect = { 0 };
|
||||
Shell_NotifyIconGetRect(&icon_id, &rect);
|
||||
gfx::Rect bounds = GetBounds();
|
||||
|
||||
if (left_mouse_click) {
|
||||
if (double_button_click) // double left click
|
||||
NotifyDoubleClicked(gfx::Rect(rect), modifiers);
|
||||
NotifyDoubleClicked(bounds, modifiers);
|
||||
else // single left click
|
||||
NotifyClicked(gfx::Rect(rect), modifiers);
|
||||
NotifyClicked(bounds, modifiers);
|
||||
return;
|
||||
} else if (!double_button_click) { // single right click
|
||||
if (menu_model_)
|
||||
PopUpContextMenu(gfx::Point(), menu_model_);
|
||||
else
|
||||
NotifyRightClicked(gfx::Rect(rect), modifiers);
|
||||
NotifyRightClicked(bounds, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,8 +134,9 @@ void NotifyIcon::DisplayBalloon(HICON icon,
|
|||
void NotifyIcon::PopUpContextMenu(const gfx::Point& pos,
|
||||
ui::SimpleMenuModel* menu_model) {
|
||||
// Returns if context menu isn't set.
|
||||
if (!menu_model)
|
||||
if (menu_model == nullptr && menu_model_ == nullptr)
|
||||
return;
|
||||
|
||||
// Set our window as the foreground window, so the context menu closes when
|
||||
// we click away from it.
|
||||
if (!SetForegroundWindow(window_))
|
||||
|
@ -153,7 +148,7 @@ void NotifyIcon::PopUpContextMenu(const gfx::Point& pos,
|
|||
rect.set_origin(gfx::Screen::GetScreen()->GetCursorScreenPoint());
|
||||
|
||||
views::MenuRunner menu_runner(
|
||||
menu_model,
|
||||
menu_model != nullptr ? menu_model : menu_model_,
|
||||
views::MenuRunner::CONTEXT_MENU | views::MenuRunner::HAS_MNEMONICS);
|
||||
ignore_result(menu_runner.RunMenuAt(
|
||||
NULL, NULL, rect, views::MENU_ANCHOR_TOPLEFT, ui::MENU_SOURCE_MOUSE));
|
||||
|
@ -163,6 +158,18 @@ void NotifyIcon::SetContextMenu(ui::SimpleMenuModel* menu_model) {
|
|||
menu_model_ = menu_model;
|
||||
}
|
||||
|
||||
gfx::Rect NotifyIcon::GetBounds() {
|
||||
NOTIFYICONIDENTIFIER icon_id;
|
||||
memset(&icon_id, 0, sizeof(NOTIFYICONIDENTIFIER));
|
||||
icon_id.uID = icon_id_;
|
||||
icon_id.hWnd = window_;
|
||||
icon_id.cbSize = sizeof(NOTIFYICONIDENTIFIER);
|
||||
|
||||
RECT rect = { 0 };
|
||||
Shell_NotifyIconGetRect(&icon_id, &rect);
|
||||
return gfx::win::ScreenToDIPRect(gfx::Rect(rect));
|
||||
}
|
||||
|
||||
void NotifyIcon::InitIconData(NOTIFYICONDATA* icon_data) {
|
||||
memset(icon_data, 0, sizeof(NOTIFYICONDATA));
|
||||
icon_data->cbSize = sizeof(NOTIFYICONDATA);
|
||||
|
|
|
@ -54,6 +54,7 @@ class NotifyIcon : public TrayIcon {
|
|||
void PopUpContextMenu(const gfx::Point& pos,
|
||||
ui::SimpleMenuModel* menu_model) override;
|
||||
void SetContextMenu(ui::SimpleMenuModel* menu_model) override;
|
||||
gfx::Rect GetBounds() override;
|
||||
|
||||
private:
|
||||
void InitIconData(NOTIFYICONDATA* icon_data);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue