Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented APIs for set/get AppUserModelID #5374

Open
wants to merge 3 commits into
base: nw18
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/References/App.md
Expand Up @@ -172,6 +172,21 @@ Unregisters a global keyboard shortcut.

See [Shortcut](Shortcut.md) for more information.

## App.getDefaultAppUserModelID() (Windows)

* Returns `{String}` the default application wide AUMID.

Get the default application wide AUMID (App User Model ID). See also [`app_user_model_id`](Manifest Format.md#app_user_model_id-windows) field in Manifest Format.

## App.setDefaultAppUserModelID(app_id) (Windows)

* `app_id` `{String}` the default application wide AUMID.

Overwrite the default application wide AUMID (App User Model ID) for newly opened windows. See also [`app_user_model_id`](Manifest Format.md#app_user_model_id-windows) field in Manifest Format.

!!! warning "No Change for Previous Opened Windows"
This API will only affect the newly opened windows. It will **NOT** change the AUMID for previous opened windows. To change them, you need to iterate all windows and call [`win.setAppUserModelID(app_id)`](Window.md#winsetappusermodelid-app_id-windows) for each.

## Event: open(args)

* `args` `{String}` the full command line of the program.
Expand Down
16 changes: 16 additions & 0 deletions docs/References/Manifest Format.md
Expand Up @@ -153,6 +153,16 @@ These certificates are used as additional root certificates for validation, to a

* `{Boolean}` whether the default `Edit` menu should be disabled on Mac OS X. The default value is `false`. Only effective on Mac OS X.

### app_user_model_id (Windows)

* `{String}` Default application wide AUMID ([App User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx)). Only effective on Windows.

This property is a fallback when [window specific AUMID](#app_user_model_id-windows_1) is not set.

If this property is not set, NW.js will use a auto generated AUMID.

This property can be overwritten by [`nw.App.setDefaultAppUserModelID(app_id)`](App.md##appsetdefaultappusermodelidapp_id-windows) at runtime.

## Window Subfields

Most of window subfields are inherited by sub windows opened by `window.open()` or links (`<a target="_blank">`) by default. The exception list of non inherited subfields are as following. They will be set to default value for opened window:
Expand Down Expand Up @@ -259,6 +269,12 @@ Control the transparency with rgba background value in CSS. Use command line opt

There is experimental support for "click-through" on the transparent region: add `--disable-gpu` option to the command line.

### app_user_model_id (Windows)

* `{String}` window specific AUMID ([App User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx)). Only effective on Windows.

The AUMID of the window can be changed at runtime by [`win.setAppUserModelID(app_id)`](Window.md#winsetappusermodelidapp_id-windows).

## WebKit Subfields

### double_tap_to_zoom_enabled
Expand Down
11 changes: 11 additions & 0 deletions docs/References/Window.md
Expand Up @@ -61,6 +61,7 @@ nw.Window.open('https://github.com/nwjs/nw.js', {}, function(new_win) {
- `new_instance` `{Boolean}` _Optional_ whether to open a new window in a separate render process.
- `inject_js_start` `{String}` _Optional_ the script to be injected before document loaded. See [Manifest format](Manifest Format.md#inject_js_start)
- `inject_js_end` `{String}` _Optional_ the script to be injected before document unloaded. See [Manifest format](Manifest Format.md#inject_js_end)
- `app_user_model_id` `{String}` _Optional_ the AUMID (App User Model ID) for the window. See [Manifest format](Manifest Format.md#app_user_model_id-windows)
- `id` `{String}` _Optional_ the `id` used to identify the window. This will be used to remember the size and position of the window and restore that geometry when a window with the same id is later opened. [See also the Chrome App documentation](https://developer.chrome.com/apps/app_window#type-CreateWindowOptions)
* `callback(win)` `{Function}` _Optional_ callback when with the opened native `Window` object

Expand Down Expand Up @@ -421,6 +422,16 @@ Execute a piece of JavaScript in the frame.

Load and execute the compiled snapshot in the frame. See [Protect JavaScript Source Code with V8 Snapshot](../For Users/Advanced/Protect JavaScript Source Code.md).

## win.setAppUserModelID(app_id) (Windows)

* `app_id` `{String}` Set AUMID ([App User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx)) for the window. Only effective on Windows 7 or later.

This method will overwrite the AUMID set in [`package.json`](Manifest Format.md#app_user_model_id-windows_1).

## win.getAppUserModelID() (Windows)

* Returns `{String}` of AUMID ([App User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx)) for the window. Only effective on Windows.

## Event: close

The `close` event is a special event that will affect the result of the `Window.close()` function. If developer is listening to the `close` event of a window, the `Window.close()` emit the `close` event without closing the window.
Expand Down
2 changes: 2 additions & 0 deletions src/api/nw_app.idl
Expand Up @@ -26,6 +26,8 @@ namespace nw.App {
static DOMString[] getArgvSync();
static DOMString getDataPath();
static void crashBrowser();
static DOMString getDefaultAppUserModelID();
static void setDefaultAppUserModelID(DOMString app_id);
};
interface Events {
static void onOpen(DOMString cmdline);
Expand Down
38 changes: 38 additions & 0 deletions src/api/nw_app_api.cc
Expand Up @@ -2,12 +2,16 @@

#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
#include "chrome/browser/browsing_data/browsing_data_helper.h"
#include "chrome/browser/browsing_data/browsing_data_remover_factory.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/extensions/devtools_util.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/web_applications/web_app.h"
#include "content/nw/src/common/shell_switches.h"
#include "content/nw/src/nw_base.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
Expand All @@ -24,6 +28,10 @@
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"

#if defined(OS_WIN)
#include "chrome/browser/shell_integration_win.h"
#endif

namespace {
void SetProxyConfigCallback(
base::WaitableEvent* done,
Expand Down Expand Up @@ -182,5 +190,35 @@ bool NwAppCrashBrowserFunction::RunAsync() {
return true;
}

bool NwAppGetDefaultAppUserModelIDFunction::RunNWSync(base::ListValue* response, std::string* error) {
#if defined(OS_WIN)
base::string16 app_id;
nw::Package* package = nw::package();
if (package->root()->GetString(::switches::kmAppUserModelID, &app_id)) {
response->AppendString(app_id);
} else {
std::string app_name =
web_app::GenerateApplicationNameFromExtensionId(extension_id());
base::string16 app_name_wide = base::UTF8ToWide(app_name);
Profile* profile =
Profile::FromBrowserContext(browser_context());
app_id = shell_integration::win::GetAppModelIdForProfile(
app_name_wide, profile->GetPath());
response->AppendString(app_id);
}
#endif
return true;
}

bool NwAppSetDefaultAppUserModelIDFunction::RunNWSync(base::ListValue* response, std::string* error) {
#if defined(OS_WIN)
std::string app_id;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &app_id));

nw::Package* package = nw::package();
package->root()->SetString(::switches::kmAppUserModelID, app_id);
#endif
return true;
}

} // namespace extensions
26 changes: 26 additions & 0 deletions src/api/nw_app_api.h
Expand Up @@ -117,5 +117,31 @@ class NwAppCrashBrowserFunction : public AsyncExtensionFunction {
DECLARE_EXTENSION_FUNCTION("nw.App.crashBrowser", UNKNOWN)
};

class NwAppGetDefaultAppUserModelIDFunction : public NWSyncExtensionFunction {
public:
NwAppGetDefaultAppUserModelIDFunction(){}
bool RunNWSync(base::ListValue* response, std::string* error) override;

protected:
~NwAppGetDefaultAppUserModelIDFunction() override {}

DECLARE_EXTENSION_FUNCTION("nw.App.getDefaultAppUserModelID", UNKNOWN)
private:
DISALLOW_COPY_AND_ASSIGN(NwAppGetDefaultAppUserModelIDFunction);
};

class NwAppSetDefaultAppUserModelIDFunction : public NWSyncExtensionFunction {
public:
NwAppSetDefaultAppUserModelIDFunction(){}
bool RunNWSync(base::ListValue* response, std::string* error) override;

protected:
~NwAppSetDefaultAppUserModelIDFunction() override {}

DECLARE_EXTENSION_FUNCTION("nw.App.setDefaultAppUserModelID", UNKNOWN)
private:
DISALLOW_COPY_AND_ASSIGN(NwAppSetDefaultAppUserModelIDFunction);
};

} // namespace extensions
#endif
2 changes: 2 additions & 0 deletions src/api/nw_current_window_internal.idl
Expand Up @@ -44,5 +44,7 @@ namespace nw.currentWindowInternal {
static object getWinParamInternal();
static void getPrinters(GetPrintersCallback callback);
static void setPrintSettingsInternal(optional object options);
static DOMString getAppUserModelID();
static void setAppUserModelID(DOMString id);
};
};
3 changes: 3 additions & 0 deletions src/api/nw_window.idl
Expand Up @@ -39,6 +39,7 @@ namespace nw.Window {
[nodoc] DOMString? icon;
[nodoc] DOMString? inject_js_start;
[nodoc] DOMString? inject_js_end;
[nodoc] DOMString? app_user_model_id;
};

[noinline_doc] dictionary NWWindow {
Expand Down Expand Up @@ -72,6 +73,8 @@ namespace nw.Window {
static void removeAllListeners(DOMString event);
static void reload();
static void reloadIgnoringCache();
static DOMString getAppUserModelID();
static void setAppUserModelID(DOMString id);

static void eval(object frame, DOMString script);
static void evalNWBin(object frame, DOMString path);
Expand Down
43 changes: 43 additions & 0 deletions src/api/nw_window_api.cc
Expand Up @@ -38,6 +38,7 @@
#include "ui/gfx/platform_font.h"
#include "ui/display/win/dpi.h"
#include "ui/views/win/hwnd_util.h"
#include "chrome/browser/ui/views/apps/chrome_native_app_window_views_win.h"
#endif

#if defined(OS_LINUX)
Expand Down Expand Up @@ -746,5 +747,47 @@ bool NwCurrentWindowInternalSetShowInTaskbarFunction::RunAsync() {
return true;
}

bool NwCurrentWindowInternalGetAppUserModelIDFunction::RunNWSync(base::ListValue* response, std::string* error) {
#if defined(OS_WIN)
AppWindow* app_window = getAppWindow(this);

if (!app_window) {
*error = "cannot get current window; are you in background page/node context?";
return false;
}

ChromeNativeAppWindowViewsWin* native_app_window = static_cast<ChromeNativeAppWindowViewsWin*>(app_window->GetBaseWindow());
response->AppendString(native_app_window->app_model_id());
#endif
return true;
}

bool NwCurrentWindowInternalSetAppUserModelIDFunction::RunNWSync(base::ListValue* response, std::string* error) {
#if defined(OS_WIN)
EXTENSION_FUNCTION_VALIDATE(args_);

if (!args_->GetSize())
return false;
base::string16 app_id;
if (!args_->GetString(0, &app_id))
return false;
if (app_id.empty()) {
*error = "AppUserModelID cannot set to empty string";
return false;
}

AppWindow* app_window = getAppWindow(this);

if (!app_window) {
*error = "cannot get current window; are you in background page/node context?";
return false;
}

ChromeNativeAppWindowViewsWin* native_app_window = static_cast<ChromeNativeAppWindowViewsWin*>(app_window->GetBaseWindow());
native_app_window->SetAppModelId(app_id);
#endif
return true;
}

} // namespace extensions

20 changes: 20 additions & 0 deletions src/api/nw_window_api.h
Expand Up @@ -300,5 +300,25 @@ class NwCurrentWindowInternalSetPrintSettingsInternalFunction : public NWSyncExt
~NwCurrentWindowInternalSetPrintSettingsInternalFunction() override {}
DECLARE_EXTENSION_FUNCTION("nw.currentWindowInternal.setPrintSettingsInternal", UNKNOWN)
};

class NwCurrentWindowInternalGetAppUserModelIDFunction : public NWSyncExtensionFunction {
public:
NwCurrentWindowInternalGetAppUserModelIDFunction() {}
bool RunNWSync(base::ListValue* response, std::string* error) override;

protected:
~NwCurrentWindowInternalGetAppUserModelIDFunction() override {}
DECLARE_EXTENSION_FUNCTION("nw.currentWindowInternal.getAppUserModelID", UNKNOWN)
};

class NwCurrentWindowInternalSetAppUserModelIDFunction : public NWSyncExtensionFunction {
public:
NwCurrentWindowInternalSetAppUserModelIDFunction() {}
bool RunNWSync(base::ListValue* response, std::string* error) override;

protected:
~NwCurrentWindowInternalSetAppUserModelIDFunction() override {}
DECLARE_EXTENSION_FUNCTION("nw.currentWindowInternal.setAppUserModelID", UNKNOWN)
};
} // namespace extensions
#endif
1 change: 1 addition & 0 deletions src/common/shell_switches.cc
Expand Up @@ -112,6 +112,7 @@ const char kmNewInstance[] = "new-instance";
const char kmInjectJSDocStart[] = "inject_js_start";
const char kmInjectJSDocEnd[] = "inject_js_end";
const char kmInjectCSS[] = "inject-css";
const char kmAppUserModelID[] = "app_user_model_id";

#if defined(OS_WIN)
// Enable conversion from vector to raster for any page.
Expand Down
1 change: 1 addition & 0 deletions src/common/shell_switches.h
Expand Up @@ -35,6 +35,7 @@ extern NW_EXPORT const char kmWebkit[];
extern NW_EXPORT const char kmWindow[];
extern NW_EXPORT const char kmChromiumArgs[];
extern NW_EXPORT const char kmJsFlags[];
extern NW_EXPORT const char kmAppUserModelID[];

extern NW_EXPORT const char kmSingleInstance[];

Expand Down
7 changes: 6 additions & 1 deletion src/resources/api_nw_app.js
Expand Up @@ -71,6 +71,12 @@ nw_binding.registerCustomHook(function(bindingsAPI) {
apiFunctions.setHandleRequest('removeOriginAccessWhitelistEntry', function() {
nwNatives.removeOriginAccessWhitelistEntry.apply(this, arguments);
});
apiFunctions.setHandleRequest('getDefaultAppUserModelID', function() {
return sendRequest.sendRequestSync('nw.App.getDefaultAppUserModelID', arguments, this.definition.parameters, {})[0];
});
apiFunctions.setHandleRequest('setDefaultAppUserModelID', function() {
sendRequest.sendRequestSync('nw.App.setDefaultAppUserModelID', arguments, this.definition.parameters, {});
});
apiFunctions.setHandleRequest('once', function(event, listener) { //FIXME: unify with nw.Window
if (typeof listener !== 'function')
throw new TypeError('listener must be a function');
Expand Down Expand Up @@ -119,7 +125,6 @@ nw_binding.registerCustomHook(function(bindingsAPI) {
bindingsAPI.compiledApi.unregisterGlobalHotKey = function() {
return nw.Shortcut.unregisterGlobalHotKey.apply(nw.Shortcut, arguments);
};

});

exports.binding = nw_binding.generate();
Expand Down
14 changes: 14 additions & 0 deletions src/resources/api_nw_window.js
Expand Up @@ -164,6 +164,12 @@ nw_internal.registerCustomHook(function(bindingsAPI) {
apiFunctions.setHandleRequest('setMenu', function() {
return sendRequest.sendRequestSync('nw.currentWindowInternal.setMenu', arguments, this.definition.parameters, {})[0];
});
apiFunctions.setHandleRequest('getAppUserModelID', function() {
return sendRequest.sendRequestSync('nw.currentWindowInternal.getAppUserModelID', arguments, this.definition.parameters, {})[0];
});
apiFunctions.setHandleRequest('setAppUserModelID', function() {
return sendRequest.sendRequestSync('nw.currentWindowInternal.setAppUserModelID', arguments, this.definition.parameters, {})[0];
});
});

nw_binding.registerCustomHook(function(bindingsAPI) {
Expand Down Expand Up @@ -409,6 +415,12 @@ nw_binding.registerCustomHook(function(bindingsAPI) {
NWWindow.prototype.reloadIgnoringCache = function () {
currentNWWindowInternal.reloadIgnoringCache();
};
NWWindow.prototype.getAppUserModelID = function() {
return currentNWWindowInternal.getAppUserModelID();
};
NWWindow.prototype.setAppUserModelID = function(app_id) {
return currentNWWindowInternal.setAppUserModelID(app_id);
};
NWWindow.prototype.eval = function (frame, script) {
return nwNatives.evalScript(frame, script);
};
Expand Down Expand Up @@ -670,6 +682,8 @@ nw_binding.registerCustomHook(function(bindingsAPI) {
options.inject_js_start = params['inject_js_start'];
if (typeof params['inject_js_end'] == 'string')
options.inject_js_end = params['inject_js_end'];
if (typeof params['app_user_model_id'] == 'string')
options.app_user_model_id = params['app_user_model_id'];
if (params.transparent)
options.alphaEnabled = true;
if (params.kiosk === true)
Expand Down