From 47c18fef7fbdf21e3c785d9586bec02c68b55962 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 17 Nov 2014 17:19:41 +0800 Subject: [PATCH] win: Add app.addUserTasks API --- atom/browser/api/atom_api_app.cc | 23 +++++++++++++++++ atom/browser/browser.h | 12 +++++++++ atom/browser/browser_win.cc | 43 ++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 8305b6a320ed..12668dbf344c 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -33,6 +33,25 @@ using atom::Browser; +namespace mate { + +template<> +struct Converter { + static bool FromV8(v8::Isolate* isolate, v8::Handle val, + Browser::UserTask* out) { + mate::Dictionary dict; + if (!ConvertFromV8(isolate, val, &dict)) + return false; + return dict.Get("program", &(out->program)) && + dict.Get("arguments", &(out->arguments)) && + dict.Get("title", &(out->title)) && + dict.Get("description", &(out->description)); + } +}; + +} // namespace mate + + namespace atom { namespace api { @@ -162,6 +181,10 @@ mate::ObjectTemplateBuilder App::GetObjectTemplateBuilder( base::Bind(&Browser::AddRecentDocument, browser)) .SetMethod("clearRecentDocuments", base::Bind(&Browser::ClearRecentDocuments, browser)) +#if defined(OS_WIN) + .SetMethod("addUserTasks", + base::Bind(&Browser::AddUserTasks, browser)) +#endif .SetMethod("getDataPath", &App::GetDataPath) .SetMethod("resolveProxy", &App::ResolveProxy) .SetMethod("setDesktopName", &App::SetDesktopName); diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 6fed3eec0c65..69f61da84f2c 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -6,6 +6,7 @@ #define ATOM_BROWSER_BROWSER_H_ #include +#include #include "base/basictypes.h" #include "base/compiler_specific.h" @@ -14,6 +15,7 @@ #include "atom/browser/window_list_observer.h" #if defined(OS_WIN) +#include "base/files/file_path.h" #include "base/strings/string16.h" #endif @@ -84,6 +86,16 @@ class Browser : public WindowListObserver { #endif // defined(OS_MACOSX) #if defined(OS_WIN) + struct UserTask { + base::FilePath program; + base::string16 arguments; + base::string16 title; + base::string16 description; + }; + + // Add a custom task to jump list. + void AddUserTasks(const std::vector& tasks); + // Set the application user model ID, called when "SetName" is called. void SetAppUserModelID(const std::string& name); #endif diff --git a/atom/browser/browser_win.cc b/atom/browser/browser_win.cc index c5e3aadc8be3..9e4db535b232 100644 --- a/atom/browser/browser_win.cc +++ b/atom/browser/browser_win.cc @@ -5,6 +5,7 @@ #include "atom/browser/browser.h" #include +#include #include #include #include @@ -16,6 +17,7 @@ #include "base/path_service.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/win/win_util.h" #include "base/win/windows_version.h" #include "atom/common/atom_version.h" @@ -69,6 +71,47 @@ void Browser::ClearRecentDocuments() { destinations->RemoveAllDestinations(); } +void Browser::AddUserTasks(const std::vector& tasks) { + CComPtr destinations; + if (FAILED(destinations.CoCreateInstance(CLSID_DestinationList))) + return; + if (FAILED(destinations->SetAppID(app_user_model_id_.c_str()))) + return; + + // Start a transaction that updates the JumpList of this application. + UINT max_slots; + CComPtr removed; + if (FAILED(destinations->BeginList(&max_slots, IID_PPV_ARGS(&removed)))) + return; + + CComPtr collection; + if (FAILED(collection.CoCreateInstance(CLSID_EnumerableObjectCollection))) + return; + + for (auto& task : tasks) { + CComPtr link; + if (FAILED(link.CoCreateInstance(CLSID_ShellLink)) || + FAILED(link->SetPath(task.program.value().c_str())) || + FAILED(link->SetArguments(task.arguments.c_str())) || + FAILED(link->SetDescription(task.description.c_str()))) + return; + + CComQIPtr property_store = link; + if (!base::win::SetStringValueForPropertyStore(property_store, PKEY_Title, + task.title.c_str())) + return; + + if (FAILED(collection->AddObject(link))) + return; + } + + // When the list is empty "AddUserTasks" could fail, so we don't check return + // value for it. + CComQIPtr task_array = collection; + destinations->AddUserTasks(task_array); + destinations->CommitList(); +} + void Browser::SetAppUserModelID(const std::string& name) { app_user_model_id_ = base::UTF8ToUTF16( base::StringPrintf("atom-shell.app.%s", name));