Commit c3875427 authored by bshe's avatar bshe Committed by Commit bot

Allow component IME extensions use app.window and add 'ime' boolean in...

Allow component IME extensions use app.window and add 'ime' boolean in CreateWindowOptions for app window

To create an IME window, an IME must be whitelisted, must have app.window.ime permission and must use set 'ime' and 'frame' this way:
chrome.app.window.create(url, {
  'ime': true,
  'frame': 'none
}, function() {})
Note only whitelisted component IME extensions can use this boolean parameter. See doc here: https://docs.google.com/a/google.com/document/d/1JQHpLu_RjN8C1Yi0i_eApS5SZtPoMDqvlq06YOwXCFU/edit

BUG=401984

Review URL: https://codereview.chromium.org/503383002

Cr-Commit-Position: refs/heads/master@{#297163}
parent 14ddc754
...@@ -641,8 +641,7 @@ void RootWindowController::ActivateKeyboard( ...@@ -641,8 +641,7 @@ void RootWindowController::ActivateKeyboard(
keyboard_controller->AddObserver(docked_layout_manager_); keyboard_controller->AddObserver(docked_layout_manager_);
keyboard_controller->AddObserver(workspace_controller_->layout_manager()); keyboard_controller->AddObserver(workspace_controller_->layout_manager());
Shell::GetInstance()->delegate()->VirtualKeyboardActivated(true); Shell::GetInstance()->delegate()->VirtualKeyboardActivated(true);
aura::Window* parent = GetContainer( aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
kShellWindowId_VirtualKeyboardParentContainer);
DCHECK(parent); DCHECK(parent);
aura::Window* keyboard_container = aura::Window* keyboard_container =
keyboard_controller->GetContainerWindow(); keyboard_controller->GetContainerWindow();
...@@ -662,8 +661,8 @@ void RootWindowController::DeactivateKeyboard( ...@@ -662,8 +661,8 @@ void RootWindowController::DeactivateKeyboard(
aura::Window* keyboard_container = aura::Window* keyboard_container =
keyboard_controller->GetContainerWindow(); keyboard_controller->GetContainerWindow();
if (keyboard_container->GetRootWindow() == GetRootWindow()) { if (keyboard_container->GetRootWindow() == GetRootWindow()) {
aura::Window* parent = GetContainer( aura::Window* parent =
kShellWindowId_VirtualKeyboardParentContainer); GetContainer(kShellWindowId_ImeWindowParentContainer);
DCHECK(parent); DCHECK(parent);
parent->RemoveChild(keyboard_container); parent->RemoveChild(keyboard_container);
// Virtual keyboard may be deactivated while still showing, notify all // Virtual keyboard may be deactivated while still showing, notify all
...@@ -679,8 +678,7 @@ void RootWindowController::DeactivateKeyboard( ...@@ -679,8 +678,7 @@ void RootWindowController::DeactivateKeyboard(
} }
bool RootWindowController::IsVirtualKeyboardWindow(aura::Window* window) { bool RootWindowController::IsVirtualKeyboardWindow(aura::Window* window) {
aura::Window* parent = GetContainer( aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
kShellWindowId_VirtualKeyboardParentContainer);
return parent ? parent->Contains(window) : false; return parent ? parent->Contains(window) : false;
} }
...@@ -1002,7 +1000,7 @@ void RootWindowController::CreateContainersInRootWindow( ...@@ -1002,7 +1000,7 @@ void RootWindowController::CreateContainersInRootWindow(
DescendantShouldStayInSameRootWindow(settings_bubble_container); DescendantShouldStayInSameRootWindow(settings_bubble_container);
aura::Window* virtual_keyboard_parent_container = aura::Window* virtual_keyboard_parent_container =
CreateContainer(kShellWindowId_VirtualKeyboardParentContainer, CreateContainer(kShellWindowId_ImeWindowParentContainer,
"VirtualKeyboardParentContainer", "VirtualKeyboardParentContainer",
lock_screen_related_containers); lock_screen_related_containers);
wm::SetSnapsChildrenToPhysicalPixelBoundary( wm::SetSnapsChildrenToPhysicalPixelBoundary(
......
...@@ -81,8 +81,8 @@ void ExpectAllContainers() { ...@@ -81,8 +81,8 @@ void ExpectAllContainers() {
Shell::GetContainer(root_window, kShellWindowId_SettingBubbleContainer)); Shell::GetContainer(root_window, kShellWindowId_SettingBubbleContainer));
EXPECT_TRUE( EXPECT_TRUE(
Shell::GetContainer(root_window, kShellWindowId_OverlayContainer)); Shell::GetContainer(root_window, kShellWindowId_OverlayContainer));
EXPECT_TRUE(Shell::GetContainer( EXPECT_TRUE(Shell::GetContainer(root_window,
root_window, kShellWindowId_VirtualKeyboardParentContainer)); kShellWindowId_ImeWindowParentContainer));
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
EXPECT_TRUE( EXPECT_TRUE(
Shell::GetContainer(root_window, kShellWindowId_MouseCursorContainer)); Shell::GetContainer(root_window, kShellWindowId_MouseCursorContainer));
......
...@@ -73,10 +73,10 @@ const int kShellWindowId_LockSystemModalContainer = 16; ...@@ -73,10 +73,10 @@ const int kShellWindowId_LockSystemModalContainer = 16;
// The container for the status area. // The container for the status area.
const int kShellWindowId_StatusContainer = 17; const int kShellWindowId_StatusContainer = 17;
// A parent container that holds the virtual keyboard container. This is to // A parent container that holds the virtual keyboard container and ime windows
// ensure that the virtual keyboard is stacked above most containers but below // if any. This is to ensure that the virtual keyboard or ime window is stacked
// the mouse cursor, context menus and the power off animation. // above most containers but below the mouse cursor and the power off animation.
const int kShellWindowId_VirtualKeyboardParentContainer = 18; const int kShellWindowId_ImeWindowParentContainer = 18;
// The container for menus. // The container for menus.
const int kShellWindowId_MenuContainer = 19; const int kShellWindowId_MenuContainer = 19;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"incognito": "split", "incognito": "split",
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7C0oB6YTnf69uhWnVTZl5TB/psHrJXgIPLYchFb0whlVCG8fqMo9lW/oxBmZXZ3N8T7zZrdYI/SUjoc9I5R/dMVVD2q4iKox+x7xlTbqSdVeOb6b9ZVJ24pLbO1L7feSNSBgR0t61jrC2eY/gf78h7w58UEQBPFT2mUxhhwodyQIDAQAB", "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7C0oB6YTnf69uhWnVTZl5TB/psHrJXgIPLYchFb0whlVCG8fqMo9lW/oxBmZXZ3N8T7zZrdYI/SUjoc9I5R/dMVVD2q4iKox+x7xlTbqSdVeOb6b9ZVJ24pLbO1L7feSNSBgR0t61jrC2eY/gf78h7w58UEQBPFT2mUxhhwodyQIDAQAB",
"permissions": [ "permissions": [
"app.window.ime",
"input", "input",
"inputMethodPrivate", "inputMethodPrivate",
"virtualKeyboardPrivate", "virtualKeyboardPrivate",
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
"description": "Chrome OS XKB", "description": "Chrome OS XKB",
"default_locale": "en", "default_locale": "en",
"permissions": [ "permissions": [
"app.window.ime",
"input", "input",
"metricsPrivate", "metricsPrivate",
"accessibilityFeatures.read" "accessibilityFeatures.read"
......
...@@ -52,6 +52,10 @@ ...@@ -52,6 +52,10 @@
#include "ui/aura/window_observer.h" #include "ui/aura/window_observer.h"
#endif #endif
#if defined(OS_CHROMEOS)
#include "ash/shell_window_ids.h"
#endif
using extensions::AppWindow; using extensions::AppWindow;
namespace { namespace {
...@@ -229,6 +233,14 @@ void ChromeNativeAppWindowViews::InitializeDefaultWindow( ...@@ -229,6 +233,14 @@ void ChromeNativeAppWindowViews::InitializeDefaultWindow(
#endif #endif
OnBeforeWidgetInit(&init_params, widget()); OnBeforeWidgetInit(&init_params, widget());
#if defined(OS_CHROMEOS)
if (create_params.is_ime_window) {
// Puts ime windows into ime window container.
init_params.parent =
ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(),
ash::kShellWindowId_ImeWindowParentContainer);
}
#endif
widget()->Init(init_params); widget()->Init(init_params);
// The frame insets are required to resolve the bounds specifications // The frame insets are required to resolve the bounds specifications
...@@ -257,6 +269,11 @@ void ChromeNativeAppWindowViews::InitializeDefaultWindow( ...@@ -257,6 +269,11 @@ void ChromeNativeAppWindowViews::InitializeDefaultWindow(
wm::SetShadowType(widget()->GetNativeWindow(), wm::SHADOW_TYPE_NONE); wm::SetShadowType(widget()->GetNativeWindow(), wm::SHADOW_TYPE_NONE);
} }
#if defined(OS_CHROMEOS)
if (create_params.is_ime_window)
return;
#endif
// Register accelarators supported by app windows. // Register accelarators supported by app windows.
// TODO(jeremya/stevenjb): should these be registered for panels too? // TODO(jeremya/stevenjb): should these be registered for panels too?
views::FocusManager* focus_manager = GetFocusManager(); views::FocusManager* focus_manager = GetFocusManager();
......
...@@ -42,7 +42,9 @@ ...@@ -42,7 +42,9 @@
"blacklist": [ "blacklist": [
"2FC374607C2DF285634B67C64A2E356C607091C3", // Quickoffice "2FC374607C2DF285634B67C64A2E356C607091C3", // Quickoffice
"3727DD3E564B6055387425027AD74C58784ACC15", // Quickoffice internal "3727DD3E564B6055387425027AD74C58784ACC15", // Quickoffice internal
"12E618C3C6E97495AAECF2AC12DEB082353241C6" // QO component extension "12E618C3C6E97495AAECF2AC12DEB082353241C6", // QO component extension
"06BE211D5F014BAB34BC22D9DDA09C63A81D828E", // Official xkb extension
"F94EE6AB36D6C6588670B2B01EB65212D9C64E33" // Open source xkb extension
], ],
"channel": "stable", "channel": "stable",
"extension_types": ["hosted_app", "extension", "legacy_packaged_app"], "extension_types": ["hosted_app", "extension", "legacy_packaged_app"],
......
...@@ -655,6 +655,7 @@ TEST(PermissionsTest, PermissionMessages) { ...@@ -655,6 +655,7 @@ TEST(PermissionsTest, PermissionMessages) {
skip.insert(APIPermission::kFullscreen); skip.insert(APIPermission::kFullscreen);
skip.insert(APIPermission::kGcm); skip.insert(APIPermission::kGcm);
skip.insert(APIPermission::kIdle); skip.insert(APIPermission::kIdle);
skip.insert(APIPermission::kImeWindowEnabled);
skip.insert(APIPermission::kIdltest); skip.insert(APIPermission::kIdltest);
skip.insert(APIPermission::kLogPrivate); skip.insert(APIPermission::kLogPrivate);
skip.insert(APIPermission::kNotifications); skip.insert(APIPermission::kNotifications);
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var error = "The \"ime\" option is not supported for platform app.";
function testImeEnabled(setOption, opt_setValue) {
var createOptions = { frame: 'none' };
if (setOption) {
createOptions.ime = opt_setValue;
chrome.app.window.create('index.html',
createOptions,
chrome.test.callbackFail(error));
} else {
chrome.app.window.create('index.html',
createOptions,
chrome.test.callbackPass(function(win){
}));
}
}
// All these tests are run with app.window.ime permission set and on a system
// with ime window support.
chrome.app.runtime.onLaunched.addListener(function() {
chrome.test.runTests([
// Window is created with ime explicitly set by platform app.
// Expect fail.
function testImeEnabledPermissionWithPlatformApp() {
testImeEnabled(true, true);
testImeEnabled(true, false);
},
// Window is created with ime not explicitly set.
// Expect pass.
function testImeEnabledPermissionImeNoInit() {
testImeEnabled(false);
}
]);
});
{
"name": "Windows API - ime (Has Permissions)",
"version": "1",
"manifest_version": 2,
"app": {
"background": {
"scripts": ["background.js"]
}
},
"permissions": ["app.window.ime"]
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var error = "IME extensions must create window with \"ime: true\" and " +
"\"frame: 'none'\".";
function testImeEnabled(createOptions) {
if (createOptions.frame == 'none' && createOptions.ime) {
chrome.app.window.create('index.html',
createOptions,
chrome.test.callbackPass(function(win) {}));
} else {
chrome.app.window.create('index.html',
createOptions,
chrome.test.callbackFail(error));
}
}
// All these tests are run with app.window.ime permission set and on a system
// with ime window support.
chrome.test.runTests([
// Window is created with ime set to true and frame set to none.
// Expect pass.
function testImeEnabledPermissionImeTrueFrameNone() {
testImeEnabled({ ime: true, frame: 'none' });
},
// Window is created with ime set to false or frame not set.
// Expect fail.
function testImeEnabledPermissionImeInitFalse() {
testImeEnabled({ ime: false, frame: 'none' });
testImeEnabled({ ime: false });
testImeEnabled({ ime: true });
},
// Window is created with ime not explicitly set.
// Expect fail.
function testImeEnabledPermissonImeNoInit() {
testImeEnabled({ frame: 'none' });
testImeEnabled({});
}
]);
{
"name": "Windows API - ime (Has Permissions)",
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7C0oB6YTnf69uhWnVTZl5TB/psHrJXgIPLYchFb0whlVCG8fqMo9lW/oxBmZXZ3N8T7zZrdYI/SUjoc9I5R/dMVVD2q4iKox+x7xlTbqSdVeOb6b9ZVJ24pLbO1L7feSNSBgR0t61jrC2eY/gf78h7w58UEQBPFT2mUxhhwodyQIDAQAB",
"version": "1",
"manifest_version": 2,
"background": {
"scripts": ["background.js"]
},
"permissions": ["app.window.ime"]
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var error = "The \"ime\" option is not supported for platform app.";
function testImeEnabled(setOption, opt_setValue) {
var createOptions = { frame: 'none' };
if (setOption) {
createOptions.ime = opt_setValue;
chrome.app.window.create('index.html',
createOptions,
chrome.test.callbackFail(error));
} else {
chrome.app.window.create('index.html',
createOptions,
chrome.test.callbackPass(function(win){}));
}
}
// All these tests are run without app.window.ime permission set and on a system
// with ime window support.
chrome.app.runtime.onLaunched.addListener(function() {
chrome.test.runTests([
// Window is created with ime explicitly set by platform app.
// Expect fail.
function testImeNoPermissionImeInitTrue() {
testImeEnabled(true, true);
testImeEnabled(true, false);
},
// Window is created with ime not explicitly set.
function testImeNoPermissionImeNoInit() {
testImeEnabled(false);
}
]);
});
{
"name": "Windows API - ime (Has Permissions)",
"version": "1",
"manifest_version": 2,
"app": {
"background": {
"scripts": ["background.js"]
}
}
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var error =
"Extensions require the \"app.window.ime\" permission to create windows.";
function testImeEnabled(imeValue) {
var createOptions = { frame: 'none' };
createOptions.ime = imeValue;
chrome.app.window.create('index.html',
createOptions,
chrome.test.callbackFail(error));
}
// All these tests are run without app.window.ime permission set and on a system
// with ime window support.
chrome.test.runTests([
// Window is created with ime set to true.
// Expect fail.
function testImeNoPermissionImeInitTrue() {
testImeEnabled(true);
},
// Window is created with ime set to false.
// Expect fail.
function testImeNoPermissionImeInitFalse() {
testImeEnabled(false);
}
]);
{
"name": "Windows API - ime (Has Permissions)",
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7C0oB6YTnf69uhWnVTZl5TB/psHrJXgIPLYchFb0whlVCG8fqMo9lW/oxBmZXZ3N8T7zZrdYI/SUjoc9I5R/dMVVD2q4iKox+x7xlTbqSdVeOb6b9ZVJ24pLbO1L7feSNSBgR0t61jrC2eY/gf78h7w58UEQBPFT2mUxhhwodyQIDAQAB",
"version": "1",
"manifest_version": 2,
"background": {
"scripts": ["background.js"]
}
}
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "extensions/browser/image_util.h" #include "extensions/browser/image_util.h"
#include "extensions/common/api/app_window.h" #include "extensions/common/api/app_window.h"
#include "extensions/common/features/simple_feature.h" #include "extensions/common/features/simple_feature.h"
#include "extensions/common/manifest.h"
#include "extensions/common/permissions/permissions_data.h" #include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/switches.h" #include "extensions/common/switches.h"
#include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColor.h"
...@@ -58,6 +59,18 @@ const char kAlphaEnabledNeedsFrameNone[] = ...@@ -58,6 +59,18 @@ const char kAlphaEnabledNeedsFrameNone[] =
"The alphaEnabled option can only be used with \"frame: 'none'\"."; "The alphaEnabled option can only be used with \"frame: 'none'\".";
const char kVisibleOnAllWorkspacesWrongChannel[] = const char kVisibleOnAllWorkspacesWrongChannel[] =
"The visibleOnAllWorkspaces option requires dev channel or newer."; "The visibleOnAllWorkspaces option requires dev channel or newer.";
const char kImeWindowMissingPermission[] =
"Extensions require the \"app.window.ime\" permission to create windows.";
const char kImeOptionIsNotSupported[] =
"The \"ime\" option is not supported for platform app.";
#if !defined(OS_CHROMEOS)
const char kImeWindowUnsupportedPlatform[] =
"The \"ime\" option can only be used on ChromeOS.";
#else
const char kImeOptionMustBeTrueAndNeedsFrameNone[] =
"IME extensions must create window with \"ime: true\" and "
"\"frame: 'none'\".";
#endif
} // namespace app_window_constants } // namespace app_window_constants
const char kNoneFrameOption[] = "none"; const char kNoneFrameOption[] = "none";
...@@ -204,6 +217,35 @@ bool AppWindowCreateFunction::RunAsync() { ...@@ -204,6 +217,35 @@ bool AppWindowCreateFunction::RunAsync() {
if (!GetFrameOptions(*options, &create_params)) if (!GetFrameOptions(*options, &create_params))
return false; return false;
if (extension()->GetType() == extensions::Manifest::TYPE_EXTENSION) {
// Whitelisted IME extensions are allowed to use this API to create IME
// specific windows to show accented characters or suggestions.
if (!extension()->permissions_data()->HasAPIPermission(
APIPermission::kImeWindowEnabled)) {
error_ = app_window_constants::kImeWindowMissingPermission;
return false;
}
#if !defined(OS_CHROMEOS)
// IME window is only supported on ChromeOS.
error_ = app_window_constants::kImeWindowUnsupportedPlatform;
return false;
#else
// IME extensions must create window with "ime: true" and "frame: none".
if (!options->ime.get() || !*options->ime.get() ||
create_params.frame != AppWindow::FRAME_NONE) {
error_ = app_window_constants::kImeOptionMustBeTrueAndNeedsFrameNone;
return false;
}
create_params.is_ime_window = true;
#endif // OS_CHROMEOS
} else {
if (options->ime.get()) {
error_ = app_window_constants::kImeOptionIsNotSupported;
return false;
}
}
if (options->alpha_enabled.get()) { if (options->alpha_enabled.get()) {
const char* whitelist[] = { const char* whitelist[] = {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
......
...@@ -168,4 +168,29 @@ IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, ...@@ -168,4 +168,29 @@ IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
<< message_; << message_;
} }
#if defined(OS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
WindowsApiImeWindowHasPermissions) {
EXPECT_TRUE(RunComponentExtensionTest(
"platform_apps/windows_api_ime/has_permissions_whitelisted"))
<< message_;
EXPECT_TRUE(RunPlatformAppTestWithFlags(
"platform_apps/windows_api_ime/has_permissions_platform_app",
kFlagIgnoreManifestWarnings))
<< message_;
}
IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest,
WindowsApiImeWindowNoPermissions) {
EXPECT_TRUE(RunComponentExtensionTest(
"platform_apps/windows_api_ime/no_permissions_whitelisted"))
<< message_;
EXPECT_TRUE(RunPlatformAppTest(
"platform_apps/windows_api_ime/no_permissions_platform_app"))
<< message_;
}
#endif // OS_CHROMEOS
} // namespace extensions } // namespace extensions
...@@ -152,6 +152,7 @@ AppWindow::CreateParams::CreateParams() ...@@ -152,6 +152,7 @@ AppWindow::CreateParams::CreateParams()
active_frame_color(SK_ColorBLACK), active_frame_color(SK_ColorBLACK),
inactive_frame_color(SK_ColorBLACK), inactive_frame_color(SK_ColorBLACK),
alpha_enabled(false), alpha_enabled(false),
is_ime_window(false),
creator_process_id(0), creator_process_id(0),
state(ui::SHOW_STATE_DEFAULT), state(ui::SHOW_STATE_DEFAULT),
hidden(false), hidden(false),
......
...@@ -150,6 +150,7 @@ class AppWindow : public content::WebContentsDelegate, ...@@ -150,6 +150,7 @@ class AppWindow : public content::WebContentsDelegate,
SkColor active_frame_color; SkColor active_frame_color;
SkColor inactive_frame_color; SkColor inactive_frame_color;
bool alpha_enabled; bool alpha_enabled;
bool is_ime_window;
// The initial content/inner bounds specification (excluding any window // The initial content/inner bounds specification (excluding any window
// decorations). // decorations).
......
...@@ -36,15 +36,29 @@ ...@@ -36,15 +36,29 @@
"12E618C3C6E97495AAECF2AC12DEB082353241C6" // QO component extension "12E618C3C6E97495AAECF2AC12DEB082353241C6" // QO component extension
] ]
}], }],
"app.window": { "app.window": [{
"channel": "stable", "channel": "stable",
"contexts": ["blessed_extension"], "contexts": ["blessed_extension"],
"extension_types": ["platform_app"], "extension_types": ["platform_app"],
"noparent": true "noparent": true
}, }, {
"app.window.canSetVisibleOnAllWorkspaces": { "channel": "stable",
"contexts": ["blessed_extension"],
"extension_types": ["extension"],
"noparent": true,
"component_extensions_auto_granted": false,
"whitelist": [
"06BE211D5F014BAB34BC22D9DDA09C63A81D828E", // Official xkb extension
"F94EE6AB36D6C6588670B2B01EB65212D9C64E33" // Open source xkb extension
]
}],
// This does not need to be a complex feature if we could set "noparent" here.
// But set "noparent" makes this feature available on stable channel. The
// issue is tracked in crbug.com/415750.
"app.window.canSetVisibleOnAllWorkspaces": [{
"contexts": ["blessed_extension"],
"channel": "dev" "channel": "dev"
}, }],
"app.currentWindowInternal": { "app.currentWindowInternal": {
"noparent": true, "noparent": true,
"internal": true, "internal": true,
......
...@@ -58,6 +58,17 @@ ...@@ -58,6 +58,17 @@
"channel": "stable", "channel": "stable",
"extension_types": ["platform_app"] "extension_types": ["platform_app"]
}, },
"app.window.ime": [
{
"channel": "stable",
"extension_types": ["extension"],
"platforms": ["chromeos"],
"whitelist": [
"06BE211D5F014BAB34BC22D9DDA09C63A81D828E",
"F94EE6AB36D6C6588670B2B01EB65212D9C64E33"
]
}
],
"audioCapture": [ "audioCapture": [
{ {
"channel": "stable", "channel": "stable",
......
...@@ -215,6 +215,12 @@ namespace app.window { ...@@ -215,6 +215,12 @@ namespace app.window {
// Type of window to create. // Type of window to create.
[nodoc] WindowType? type; [nodoc] WindowType? type;
// Creates a special ime window. This window is not focusable and can be
// stacked above virtual keyboard window. This is restriced to component ime
// extensions.
// Requires app.window.ime API permission.
[nodoc] boolean? ime;
// Frame type: <code>none</code> or <code>chrome</code> (defaults to // Frame type: <code>none</code> or <code>chrome</code> (defaults to
// <code>chrome</code>). For <code>none</code>, the // <code>chrome</code>). For <code>none</code>, the
// <code>-webkit-app-region</code> CSS property can be used to apply // <code>-webkit-app-region</code> CSS property can be used to apply
......
...@@ -113,6 +113,7 @@ class APIPermission { ...@@ -113,6 +113,7 @@ class APIPermission {
kIdentityPrivate, kIdentityPrivate,
kIdltest, kIdltest,
kIdle, kIdle,
kImeWindowEnabled,
kInfobars, kInfobars,
kInput, kInput,
kInputMethodPrivate, kInputMethodPrivate,
......
...@@ -80,6 +80,7 @@ std::vector<APIPermissionInfo*> ExtensionsAPIPermissions::GetAllPermissions() ...@@ -80,6 +80,7 @@ std::vector<APIPermissionInfo*> ExtensionsAPIPermissions::GetAllPermissions()
{APIPermission::kWebView, "webview", {APIPermission::kWebView, "webview",
APIPermissionInfo::kFlagCannotBeOptional}, APIPermissionInfo::kFlagCannotBeOptional},
{APIPermission::kWindowShape, "app.window.shape"}, {APIPermission::kWindowShape, "app.window.shape"},
{APIPermission::kImeWindowEnabled, "app.window.ime"},
}; };
std::vector<APIPermissionInfo*> permissions; std::vector<APIPermissionInfo*> permissions;
......
...@@ -402,4 +402,4 @@ function updateSizeConstraints(boundsType, constraints) { ...@@ -402,4 +402,4 @@ function updateSizeConstraints(boundsType, constraints) {
exports.binding = appWindow.generate(); exports.binding = appWindow.generate();
exports.onAppWindowClosed = onAppWindowClosed; exports.onAppWindowClosed = onAppWindowClosed;
exports.updateAppWindowProperties = updateAppWindowProperties; exports.updateAppWindowProperties = updateAppWindowProperties;
exports.appWindowShownForTests = onAppWindowShownForTests; exports.appWindowShownForTests = onAppWindowShownForTests;
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment