summaryrefslogtreecommitdiffstats
path: root/mojo
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-13 21:36:27 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-13 21:36:27 +0000
commit90c6fd749c7da30b5afa2ac37b59dfd36642a505 (patch)
tree0e7c188167ea8b303f7f6be2576737253a28baef /mojo
parent92c91ea864d007b3d1b56510065b9b773b87a727 (diff)
downloadchromium_src-90c6fd749c7da30b5afa2ac37b59dfd36642a505.zip
chromium_src-90c6fd749c7da30b5afa2ac37b59dfd36642a505.tar.gz
chromium_src-90c6fd749c7da30b5afa2ac37b59dfd36642a505.tar.bz2
Adds a parameter to Launchable that is a ViewTreeNode to render in. Adds an image viewer app that decodes the provided data stream as PNG and renders it in a View associated with the supplied node.
R=aa@chromium.org, sky@chromium.org http://crbug.com/378151 Review URL: https://codereview.chromium.org/331563003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277084 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo')
-rw-r--r--mojo/examples/browser/browser.cc89
-rw-r--r--mojo/examples/html_viewer/html_viewer.cc46
-rw-r--r--mojo/examples/image_viewer/DEPS4
-rw-r--r--mojo/examples/image_viewer/image_viewer.cc137
-rw-r--r--mojo/examples/window_manager/window_manager.cc2
-rw-r--r--mojo/mojo.gyp1
-rw-r--r--mojo/mojo_examples.gypi28
-rw-r--r--mojo/services/launcher/launcher.cc34
-rw-r--r--mojo/services/public/cpp/input_events/lib/input_events_type_converters.cc3
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc27
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h1
-rw-r--r--mojo/services/public/cpp/view_manager/lib/view_tree_node.cc5
-rw-r--r--mojo/services/public/cpp/view_manager/view_tree_node.h3
-rw-r--r--mojo/services/public/interfaces/launcher/launcher.mojom11
-rw-r--r--mojo/services/public/interfaces/view_manager/view_manager.mojom3
-rw-r--r--mojo/services/view_manager/view_manager_connection.cc16
-rw-r--r--mojo/services/view_manager/view_manager_connection.h3
17 files changed, 376 insertions, 37 deletions
diff --git a/mojo/examples/browser/browser.cc b/mojo/examples/browser/browser.cc
index 9757d0f..35162c9 100644
--- a/mojo/examples/browser/browser.cc
+++ b/mojo/examples/browser/browser.cc
@@ -14,7 +14,7 @@
#include "mojo/views/views_init.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/controls/textfield/textfield_controller.h"
-#include "ui/views/layout/fill_layout.h"
+#include "ui/views/layout/layout_manager.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "url/gurl.h"
@@ -22,13 +22,62 @@
namespace mojo {
namespace examples {
+class NodeView : public views::View {
+ public:
+ explicit NodeView(view_manager::ViewTreeNode* node) : node_(node) {
+ // This class is provisional and assumes that the node has already been
+ // added to a parent. I suspect we'll want to make an improved version of
+ // this that lives in ui/views akin to NativeViewHost that properly
+ // attaches/detaches when the view is.
+ DCHECK(node->parent());
+ }
+ virtual ~NodeView() {}
+
+ // Overridden from views::View:
+ virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE {
+ node_->SetBounds(ConvertRectToWidget(GetLocalBounds()));
+ }
+
+ private:
+ view_manager::ViewTreeNode* node_;
+
+ DISALLOW_COPY_AND_ASSIGN(NodeView);
+};
+
+class BrowserLayoutManager : public views::LayoutManager {
+ public:
+ BrowserLayoutManager() {}
+ virtual ~BrowserLayoutManager() {}
+
+ private:
+ // Overridden from views::LayoutManager:
+ virtual void Layout(views::View* host) OVERRIDE {
+ // Browser view has two children:
+ // 1. text input field.
+ // 2. content view.
+ DCHECK_EQ(2, host->child_count());
+ views::View* text_field = host->child_at(0);
+ gfx::Size ps = text_field->GetPreferredSize();
+ text_field->SetBoundsRect(gfx::Rect(host->width(), ps.height()));
+ views::View* content_area = host->child_at(1);
+ content_area->SetBounds(0, text_field->bounds().bottom(), host->width(),
+ host->height() - text_field->bounds().bottom());
+ }
+ virtual gfx::Size GetPreferredSize(const views::View* host) const OVERRIDE {
+ return gfx::Size();
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserLayoutManager);
+};
+
// This is the basics of creating a views widget with a textfield.
// TODO: cleanup!
class Browser : public Application,
public view_manager::ViewManagerDelegate,
- public views::TextfieldController {
+ public views::TextfieldController,
+ public InterfaceImpl<launcher::LauncherClient> {
public:
- Browser() : view_manager_(NULL), view_(NULL) {}
+ Browser() : view_manager_(NULL), view_(NULL), content_node_(NULL) {}
virtual ~Browser() {
}
@@ -37,25 +86,27 @@ class Browser : public Application,
// Overridden from Application:
virtual void Initialize() MOJO_OVERRIDE {
views_init_.reset(new ViewsInit);
-
view_manager::ViewManager::Create(this, this);
-
ConnectTo("mojo:mojo_launcher", &launcher_);
+ launcher_.set_client(this);
}
- void CreateWidget() {
+ void CreateWidget(const gfx::Size& size) {
views::Textfield* textfield = new views::Textfield;
textfield->set_controller(this);
views::WidgetDelegateView* widget_delegate = new views::WidgetDelegateView;
widget_delegate->GetContentsView()->AddChildView(textfield);
- widget_delegate->GetContentsView()->SetLayoutManager(new views::FillLayout);
+ widget_delegate->GetContentsView()->AddChildView(
+ new NodeView(content_node_));
+ widget_delegate->GetContentsView()->SetLayoutManager(
+ new BrowserLayoutManager);
views::Widget* widget = new views::Widget;
views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
params.native_widget = new NativeWidgetViewManager(widget, view_);
params.delegate = widget_delegate;
- params.bounds = gfx::Rect(200, 200);
+ params.bounds = gfx::Rect(size.width(), size.height());
widget->Init(params);
widget->Show();
textfield->RequestFocus();
@@ -69,7 +120,12 @@ class Browser : public Application,
view_ = view_manager::View::Create(view_manager_);
view_manager_->GetRoots().front()->SetActiveView(view_);
- CreateWidget();
+ content_node_ = view_manager::ViewTreeNode::Create(view_manager_);
+ root->AddChild(content_node_);
+
+ root->SetFocus();
+
+ CreateWidget(root->bounds().size());
}
virtual void OnRootRemoved(view_manager::ViewManager* view_manager,
view_manager::ViewTreeNode* root) OVERRIDE {
@@ -86,10 +142,25 @@ class Browser : public Application,
return false;
}
+ // launcher::LauncherClient:
+ virtual void OnLaunch(
+ const String& handler_url,
+ URLResponsePtr response,
+ ScopedDataPipeConsumerHandle response_body_stream) OVERRIDE {
+ content_node_->Embed(handler_url);
+
+ launcher::LaunchablePtr launchable;
+ ConnectTo(handler_url, &launchable);
+ launchable->OnLaunch(response.Pass(),
+ response_body_stream.Pass(),
+ content_node_->id());
+ }
+
scoped_ptr<ViewsInit> views_init_;
view_manager::ViewManager* view_manager_;
view_manager::View* view_;
+ view_manager::ViewTreeNode* content_node_;
launcher::LauncherPtr launcher_;
DISALLOW_COPY_AND_ASSIGN(Browser);
diff --git a/mojo/examples/html_viewer/html_viewer.cc b/mojo/examples/html_viewer/html_viewer.cc
index ab41d95..de37c51 100644
--- a/mojo/examples/html_viewer/html_viewer.cc
+++ b/mojo/examples/html_viewer/html_viewer.cc
@@ -3,6 +3,11 @@
// found in the LICENSE file.
#include "mojo/public/cpp/application/application.h"
+#include "mojo/services/public/cpp/view_manager/view.h"
+#include "mojo/services/public/cpp/view_manager/view_manager.h"
+#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
+#include "mojo/services/public/cpp/view_manager/view_manager_types.h"
+#include "mojo/services/public/cpp/view_manager/view_tree_node.h"
#include "mojo/services/public/interfaces/launcher/launcher.mojom.h"
namespace mojo {
@@ -12,14 +17,15 @@ class HTMLViewer;
class LaunchableConnection : public InterfaceImpl<launcher::Launchable> {
public:
- LaunchableConnection() {}
+ explicit LaunchableConnection(HTMLViewer* viewer) : viewer_(viewer) {}
virtual ~LaunchableConnection() {}
private:
// Overridden from launcher::Launchable:
virtual void OnLaunch(
URLResponsePtr response,
- ScopedDataPipeConsumerHandle response_body_stream) MOJO_OVERRIDE {
+ ScopedDataPipeConsumerHandle response_body_stream,
+ view_manager::Id node_id) MOJO_OVERRIDE {
printf("In HTMLViewer, rendering url: %s\n", response->url.data());
printf("HTML: \n");
for (;;) {
@@ -41,21 +47,49 @@ class LaunchableConnection : public InterfaceImpl<launcher::Launchable> {
}
}
printf("\n>>>> EOF <<<<\n\n");
+
+ UpdateView();
}
+
+ void UpdateView();
+
+ HTMLViewer* viewer_;
+
+ DISALLOW_COPY_AND_ASSIGN(LaunchableConnection);
};
-class HTMLViewer : public Application {
+class HTMLViewer : public Application,
+ public view_manager::ViewManagerDelegate {
public:
- HTMLViewer() {}
+ HTMLViewer() : content_view_(NULL) {}
virtual ~HTMLViewer() {}
private:
+ friend class LaunchableConnection;
+
// Overridden from Application:
- virtual void Initialize() MOJO_OVERRIDE {
- AddService<LaunchableConnection>();
+ virtual void Initialize() OVERRIDE {
+ AddService<LaunchableConnection>(this);
+ view_manager::ViewManager::Create(this, this);
}
+
+ // Overridden from view_manager::ViewManagerDelegate:
+ virtual void OnRootAdded(view_manager::ViewManager* view_manager,
+ view_manager::ViewTreeNode* root) OVERRIDE {
+ content_view_ = view_manager::View::Create(view_manager);
+ root->SetActiveView(content_view_);
+ content_view_->SetColor(SK_ColorRED);
+ }
+
+ view_manager::View* content_view_;
+
+ DISALLOW_COPY_AND_ASSIGN(HTMLViewer);
};
+void LaunchableConnection::UpdateView() {
+ viewer_->content_view_->SetColor(SK_ColorGREEN);
+}
+
}
// static
diff --git a/mojo/examples/image_viewer/DEPS b/mojo/examples/image_viewer/DEPS
new file mode 100644
index 0000000..41134f5
--- /dev/null
+++ b/mojo/examples/image_viewer/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+third_party/skia/include",
+ "+ui/gfx",
+]
diff --git a/mojo/examples/image_viewer/image_viewer.cc b/mojo/examples/image_viewer/image_viewer.cc
new file mode 100644
index 0000000..73c4c12
--- /dev/null
+++ b/mojo/examples/image_viewer/image_viewer.cc
@@ -0,0 +1,137 @@
+// 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.
+
+#include <algorithm>
+
+#include "base/strings/string_tokenizer.h"
+#include "mojo/public/cpp/application/application.h"
+#include "mojo/services/public/cpp/view_manager/view.h"
+#include "mojo/services/public/cpp/view_manager/view_manager.h"
+#include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
+#include "mojo/services/public/cpp/view_manager/view_manager_types.h"
+#include "mojo/services/public/cpp/view_manager/view_tree_node.h"
+#include "mojo/services/public/interfaces/launcher/launcher.mojom.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/codec/png_codec.h"
+
+namespace mojo {
+namespace examples {
+
+class ImageViewer;
+
+class LaunchableConnection : public InterfaceImpl<launcher::Launchable> {
+ public:
+ explicit LaunchableConnection(ImageViewer* viewer) : viewer_(viewer) {}
+ virtual ~LaunchableConnection() {}
+
+ private:
+ // Overridden from launcher::Launchable:
+ virtual void OnLaunch(URLResponsePtr response,
+ ScopedDataPipeConsumerHandle response_body_stream,
+ uint32_t node_id) OVERRIDE {
+ int content_length = GetContentLength(response->headers);
+ unsigned char* data = new unsigned char[content_length];
+ unsigned char* buf = data;
+ uint32_t bytes_remaining = content_length;
+ uint32_t num_bytes = bytes_remaining;
+ while (bytes_remaining > 0) {
+ MojoResult result = ReadDataRaw(
+ response_body_stream.get(),
+ buf,
+ &num_bytes,
+ MOJO_READ_DATA_FLAG_NONE);
+ if (result == MOJO_RESULT_SHOULD_WAIT) {
+ Wait(response_body_stream.get(),
+ MOJO_WAIT_FLAG_READABLE,
+ MOJO_DEADLINE_INDEFINITE);
+ } else if (result == MOJO_RESULT_OK) {
+ buf += num_bytes;
+ num_bytes = bytes_remaining -= num_bytes;
+ } else {
+ break;
+ }
+ }
+
+ SkBitmap bitmap;
+ gfx::PNGCodec::Decode(static_cast<const unsigned char*>(data),
+ content_length, &bitmap);
+ UpdateView(node_id, bitmap);
+
+ delete[] data;
+ }
+
+ void UpdateView(view_manager::Id node_id, const SkBitmap& bitmap);
+
+ int GetContentLength(const Array<String>& headers) {
+ for (size_t i = 0; i < headers.size(); ++i) {
+ base::StringTokenizer t(headers[i], ": ;=");
+ while (t.GetNext()) {
+ if (!t.token_is_delim() && t.token() == "Content-Length") {
+ while (t.GetNext()) {
+ if (!t.token_is_delim())
+ return atoi(t.token().c_str());
+ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ ImageViewer* viewer_;
+
+ DISALLOW_COPY_AND_ASSIGN(LaunchableConnection);
+};
+
+class ImageViewer : public Application,
+ public view_manager::ViewManagerDelegate {
+ public:
+ ImageViewer() : content_view_(NULL) {}
+ virtual ~ImageViewer() {}
+
+ void UpdateView(view_manager::Id node_id, const SkBitmap& bitmap) {
+ bitmap_ = bitmap;
+ DrawBitmap();
+ }
+
+ private:
+ // Overridden from Application:
+ virtual void Initialize() OVERRIDE {
+ AddService<LaunchableConnection>(this);
+ view_manager::ViewManager::Create(this, this);
+ }
+
+ // Overridden from view_manager::ViewManagerDelegate:
+ virtual void OnRootAdded(view_manager::ViewManager* view_manager,
+ view_manager::ViewTreeNode* root) OVERRIDE {
+ content_view_ = view_manager::View::Create(view_manager);
+ root->SetActiveView(content_view_);
+ content_view_->SetColor(SK_ColorRED);
+ if (!bitmap_.isNull())
+ DrawBitmap();
+ }
+
+ void DrawBitmap() {
+ if (content_view_)
+ content_view_->SetContents(bitmap_);
+ }
+
+ view_manager::View* content_view_;
+ SkBitmap bitmap_;
+
+ DISALLOW_COPY_AND_ASSIGN(ImageViewer);
+};
+
+void LaunchableConnection::UpdateView(view_manager::Id node_id,
+ const SkBitmap& bitmap) {
+ viewer_->UpdateView(node_id, bitmap);
+}
+
+} // namespace examples
+
+// static
+Application* Application::Create() {
+ return new examples::ImageViewer;
+}
+
+} // namespace mojo
diff --git a/mojo/examples/window_manager/window_manager.cc b/mojo/examples/window_manager/window_manager.cc
index e9a561e..a385873 100644
--- a/mojo/examples/window_manager/window_manager.cc
+++ b/mojo/examples/window_manager/window_manager.cc
@@ -112,7 +112,7 @@ class WindowManager : public Application,
void CreateWindow(const std::string& url) {
ViewTreeNode* node = view_manager_->GetNodeById(parent_node_id_);
- gfx::Rect bounds(50, 50, 200, 200);
+ gfx::Rect bounds(50, 50, 400, 400);
if (!node->children().empty()) {
gfx::Point position = node->children().back()->bounds().origin();
position.Offset(50, 50);
diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp
index 0aedfdd..34b32ee 100644
--- a/mojo/mojo.gyp
+++ b/mojo/mojo.gyp
@@ -35,6 +35,7 @@
'mojo_cpp_bindings',
'mojo_geometry_lib',
'mojo_html_viewer',
+ 'mojo_image_viewer',
'mojo_js',
'mojo_js_bindings',
'mojo_js_unittests',
diff --git a/mojo/mojo_examples.gypi b/mojo/mojo_examples.gypi
index d7b9888..15c0e5d 100644
--- a/mojo/mojo_examples.gypi
+++ b/mojo/mojo_examples.gypi
@@ -95,17 +95,39 @@
'target_name': 'mojo_html_viewer',
'type': 'shared_library',
'dependencies': [
+ '../skia/skia.gyp:skia',
'mojo_application',
'mojo_cpp_bindings',
- 'mojo_environment_standalone',
+ 'mojo_environment_chromium',
'mojo_network_bindings',
'mojo_launcher_bindings',
- 'mojo_system',
+ 'mojo_system_impl',
'mojo_utility',
+ 'mojo_view_manager_lib',
],
'sources': [
'examples/html_viewer/html_viewer.cc',
- 'public/cpp/application/lib/mojo_main_standalone.cc',
+ 'public/cpp/application/lib/mojo_main_chromium.cc',
+ ],
+ },
+ {
+ 'target_name': 'mojo_image_viewer',
+ 'type': 'shared_library',
+ 'dependencies': [
+ '../skia/skia.gyp:skia',
+ '../ui/gfx/gfx.gyp:gfx',
+ 'mojo_application',
+ 'mojo_cpp_bindings',
+ 'mojo_environment_chromium',
+ 'mojo_network_bindings',
+ 'mojo_launcher_bindings',
+ 'mojo_system_impl',
+ 'mojo_utility',
+ 'mojo_view_manager_lib',
+ ],
+ 'sources': [
+ 'examples/image_viewer/image_viewer.cc',
+ 'public/cpp/application/lib/mojo_main_chromium.cc',
],
},
{
diff --git a/mojo/services/launcher/launcher.cc b/mojo/services/launcher/launcher.cc
index 3990425..b3a34a8 100644
--- a/mojo/services/launcher/launcher.cc
+++ b/mojo/services/launcher/launcher.cc
@@ -6,6 +6,7 @@
#include "base/message_loop/message_loop.h"
#include "base/strings/string_tokenizer.h"
#include "mojo/public/cpp/application/application.h"
+#include "mojo/services/public/cpp/view_manager/view_manager_types.h"
#include "mojo/services/public/interfaces/launcher/launcher.mojom.h"
#include "mojo/services/public/interfaces/network/network_service.mojom.h"
#include "mojo/services/public/interfaces/network/url_loader.mojom.h"
@@ -29,10 +30,12 @@ class LauncherConnection : public InterfaceImpl<Launcher> {
DISALLOW_COPY_AND_ASSIGN(LauncherConnection);
};
-class Launch : public URLLoaderClient {
+class LaunchInstance : public URLLoaderClient {
public:
- Launch(LauncherApp* app, const String& url);
- virtual ~Launch() {}
+ LaunchInstance(LauncherApp* app,
+ LauncherClient* client,
+ const String& url);
+ virtual ~LaunchInstance() {}
private:
// Overridden from URLLoaderClient:
@@ -72,11 +75,11 @@ class Launch : public URLLoaderClient {
LauncherApp* app_;
bool destroy_scheduled_;
+ LauncherClient* client_;
URLLoaderPtr url_loader_;
ScopedDataPipeConsumerHandle response_body_stream_;
- LaunchablePtr launchable_;
- DISALLOW_COPY_AND_ASSIGN(Launch);
+ DISALLOW_COPY_AND_ASSIGN(LaunchInstance);
};
class LauncherApp : public Application {
@@ -87,10 +90,6 @@ class LauncherApp : public Application {
}
virtual ~LauncherApp() {}
- void LaunchURL(const String& url) {
- new Launch(this, url);
- }
-
URLLoaderPtr CreateURLLoader() {
URLLoaderPtr loader;
network_service_->CreateURLLoader(Get(&loader));
@@ -119,12 +118,15 @@ class LauncherApp : public Application {
};
void LauncherConnection::Launch(const String& url) {
- app_->LaunchURL(url);
+ new LaunchInstance(app_, client(), url);
}
-Launch::Launch(LauncherApp* app, const String& url)
+LaunchInstance::LaunchInstance(LauncherApp* app,
+ LauncherClient* client,
+ const String& url)
: app_(app),
- destroy_scheduled_(false) {
+ destroy_scheduled_(false),
+ client_(client) {
url_loader_ = app_->CreateURLLoader();
url_loader_.set_client(this);
@@ -139,14 +141,14 @@ Launch::Launch(LauncherApp* app, const String& url)
url_loader_->Start(request.Pass(), data_pipe.producer_handle.Pass());
}
-void Launch::OnReceivedResponse(URLResponsePtr response) {
+void LaunchInstance::OnReceivedResponse(URLResponsePtr response) {
std::string content_type = GetContentType(response->headers);
std::string handler_url = app_->GetHandlerForContentType(content_type);
if (!handler_url.empty()) {
- app_->ConnectTo(handler_url, &launchable_);
- launchable_->OnLaunch(response.Pass(), response_body_stream_.Pass());
+ client_->OnLaunch(handler_url,
+ response.Pass(),
+ response_body_stream_.Pass());
}
- ScheduleDestroy();
}
} // namespace launcher
diff --git a/mojo/services/public/cpp/input_events/lib/input_events_type_converters.cc b/mojo/services/public/cpp/input_events/lib/input_events_type_converters.cc
index 5bf1e7f7..5a47d07 100644
--- a/mojo/services/public/cpp/input_events/lib/input_events_type_converters.cc
+++ b/mojo/services/public/cpp/input_events/lib/input_events_type_converters.cc
@@ -58,7 +58,8 @@ TypeConverter<EventPtr, scoped_ptr<ui::Event> >::ConvertTo(
break;
default:
// TODO: support other types.
- NOTIMPLEMENTED();
+ // NOTIMPLEMENTED();
+ ;
}
// TODO: need to support time_stamp.
return ui_event.Pass();
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
index 16e2321..3568ae5 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
@@ -477,6 +477,27 @@ class EmbedTransaction : public ViewManagerTransaction {
DISALLOW_COPY_AND_ASSIGN(EmbedTransaction);
};
+class SetFocusTransaction : public ViewManagerTransaction {
+ public:
+ SetFocusTransaction(Id node_id, ViewManagerSynchronizer* synchronizer)
+ : ViewManagerTransaction(synchronizer),
+ node_id_(node_id) {}
+ virtual ~SetFocusTransaction() {}
+
+ private:
+ // Overridden from ViewManagerTransaction:
+ virtual void DoCommit() OVERRIDE {
+ service()->SetFocus(node_id_, ActionCompletedCallback());
+ }
+ virtual void DoActionCompleted(bool success) OVERRIDE {
+ // TODO(beng): recovery?
+ }
+
+ const Id node_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(SetFocusTransaction);
+};
+
ViewManagerSynchronizer::ViewManagerSynchronizer(ViewManagerDelegate* delegate)
: connected_(false),
connection_id_(0),
@@ -585,6 +606,12 @@ void ViewManagerSynchronizer::SetViewContents(Id view_id,
Sync();
}
+void ViewManagerSynchronizer::SetFocus(Id node_id) {
+ DCHECK(connected_);
+ pending_transactions_.push_back(new SetFocusTransaction(node_id, this));
+ Sync();
+}
+
void ViewManagerSynchronizer::Embed(const String& url, Id node_id) {
DCHECK(connected_);
pending_transactions_.push_back(new EmbedTransaction(url, node_id, this));
diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h
index f888787..e9a90f4 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h
+++ b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h
@@ -56,6 +56,7 @@ class ViewManagerSynchronizer : public ViewManager,
void SetActiveView(Id node_id, Id view_id);
void SetBounds(Id node_id, const gfx::Rect& bounds);
void SetViewContents(Id view_id, const SkBitmap& contents);
+ void SetFocus(Id node_id);
void Embed(const String& url, Id node_id);
diff --git a/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc b/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
index 5a6c1d2..46972e8 100644
--- a/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
+++ b/mojo/services/public/cpp/view_manager/lib/view_tree_node.cc
@@ -357,6 +357,11 @@ void ViewTreeNode::SetActiveView(View* view) {
}
}
+void ViewTreeNode::SetFocus() {
+ if (manager_)
+ static_cast<ViewManagerSynchronizer*>(manager_)->SetFocus(id_);
+}
+
void ViewTreeNode::Embed(const String& url) {
static_cast<ViewManagerSynchronizer*>(manager_)->Embed(url, id_);
}
diff --git a/mojo/services/public/cpp/view_manager/view_tree_node.h b/mojo/services/public/cpp/view_manager/view_tree_node.h
index 2d9527c..b3f398e 100644
--- a/mojo/services/public/cpp/view_manager/view_tree_node.h
+++ b/mojo/services/public/cpp/view_manager/view_tree_node.h
@@ -65,6 +65,9 @@ class ViewTreeNode {
void SetActiveView(View* view);
View* active_view() { return active_view_; }
+ // Focus.
+ void SetFocus();
+
// Embedding.
void Embed(const String& url);
diff --git a/mojo/services/public/interfaces/launcher/launcher.mojom b/mojo/services/public/interfaces/launcher/launcher.mojom
index 7668f4e..95957dd 100644
--- a/mojo/services/public/interfaces/launcher/launcher.mojom
+++ b/mojo/services/public/interfaces/launcher/launcher.mojom
@@ -6,13 +6,22 @@ import "../network/url_loader.mojom"
module mojo.launcher {
+[Client=LauncherClient]
interface Launcher {
Launch(string url);
};
+[Client=Launcher]
+interface LauncherClient {
+ OnLaunch(string handler_url,
+ mojo.URLResponse response,
+ handle<data_pipe_consumer> response_body_stream);
+};
+
interface Launchable {
OnLaunch(mojo.URLResponse response,
- handle<data_pipe_consumer> response_body_stream);
+ handle<data_pipe_consumer> response_body_stream,
+ uint32 node_id);
};
}
diff --git a/mojo/services/public/interfaces/view_manager/view_manager.mojom b/mojo/services/public/interfaces/view_manager/view_manager.mojom
index e782798..303fb03 100644
--- a/mojo/services/public/interfaces/view_manager/view_manager.mojom
+++ b/mojo/services/public/interfaces/view_manager/view_manager.mojom
@@ -106,6 +106,9 @@ interface IViewManager {
handle<shared_buffer> buffer,
uint32 buffer_size) => (bool success);
+ // Sets focus to the specified node.
+ SetFocus(uint32 node_id) => (bool success);
+
// Embeds the app at |url| in the specified nodes. More specifically this
// creates a new connection to the specified url, expecting to get an
// IViewManagerClient and configures it with the root nodes |nodes|. Fails
diff --git a/mojo/services/view_manager/view_manager_connection.cc b/mojo/services/view_manager/view_manager_connection.cc
index c3053c0d..0d717ab 100644
--- a/mojo/services/view_manager/view_manager_connection.cc
+++ b/mojo/services/view_manager/view_manager_connection.cc
@@ -331,6 +331,11 @@ bool ViewManagerConnection::CanSetView(const Node* node,
return (view && view_id.connection_id == id_) || view_id == ViewId();
}
+bool ViewManagerConnection::CanSetFocus(const Node* node) const {
+ // TODO(beng): security.
+ return true;
+}
+
bool ViewManagerConnection::CanGetNodeTree(const Node* node) const {
return node &&
(IsNodeDescendantOfRoots(node) || node->id().connection_id == id_);
@@ -695,6 +700,17 @@ void ViewManagerConnection::SetViewContents(
callback.Run(true);
}
+void ViewManagerConnection::SetFocus(Id node_id,
+ const Callback<void(bool)> & callback) {
+ bool success = false;
+ Node* node = GetNode(NodeIdFromTransportId(node_id));
+ if (CanSetFocus(node)) {
+ success = true;
+ node->window()->Focus();
+ }
+ callback.Run(success);
+}
+
void ViewManagerConnection::SetNodeBounds(
Id node_id,
RectPtr bounds,
diff --git a/mojo/services/view_manager/view_manager_connection.h b/mojo/services/view_manager/view_manager_connection.h
index b2f326b..01c8f35 100644
--- a/mojo/services/view_manager/view_manager_connection.h
+++ b/mojo/services/view_manager/view_manager_connection.h
@@ -121,6 +121,7 @@ class MOJO_VIEW_MANAGER_EXPORT ViewManagerConnection
bool CanDeleteNode(const NodeId& node_id) const;
bool CanDeleteView(const ViewId& view_id) const;
bool CanSetView(const Node* node, const ViewId& view_id) const;
+ bool CanSetFocus(const Node* node) const;
bool CanGetNodeTree(const Node* node) const;
bool CanEmbed(const mojo::Array<uint32_t>& node_ids) const;
@@ -197,6 +198,8 @@ class MOJO_VIEW_MANAGER_EXPORT ViewManagerConnection
ScopedSharedBufferHandle buffer,
uint32_t buffer_size,
const Callback<void(bool)>& callback) OVERRIDE;
+ virtual void SetFocus(Id node_id,
+ const Callback<void(bool)> & callback) OVERRIDE;
virtual void SetNodeBounds(Id node_id,
RectPtr bounds,
const Callback<void(bool)>& callback) OVERRIDE;