Commit 9054c441 authored by ben's avatar ben Committed by Commit bot

Window controls

Also fixes:
. a bug in NVVM where the WTH is reset. It's also reset by the NWA it subclasses, resulting in a UAF.
. needed some more schedulepaints in display manager to handle the window being removed. I am running into what looks like a bug/misunderstanding w/schedule paint, but I decided not to worry about it since this code is getting blown up once james lands.

R=sky@chromium.org
BUG=none

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

Cr-Commit-Position: refs/heads/master@{#294528}
parent 018aad6f
include_rules = [
"+ui/gfx/geometry",
"+ui/views",
]
// 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 "mojo/examples/wm_flow/wm/frame_controller.h"
#include "base/strings/utf_string_conversions.h"
#include "mojo/services/public/cpp/view_manager/view.h"
#include "mojo/views/native_widget_view_manager.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/layout/layout_manager.h"
#include "ui/views/widget/widget.h"
class FrameController::LayoutManager : public views::LayoutManager,
public views::ButtonListener {
public:
explicit LayoutManager(FrameController* controller)
: controller_(controller),
close_button_(
new views::LabelButton(this, base::ASCIIToUTF16("Begone"))),
maximize_button_(
new views::LabelButton(this, base::ASCIIToUTF16("Embiggen"))) {}
virtual ~LayoutManager() {}
private:
static const int kButtonFrameMargin = 5;
static const int kButtonFrameSpacing = 2;
static const int kFrameSize = 10;
// Overridden from views::LayoutManager:
virtual void Installed(views::View* host) OVERRIDE {
host->AddChildView(close_button_);
host->AddChildView(maximize_button_);
}
virtual void Layout(views::View* host) OVERRIDE {
gfx::Size ps = close_button_->GetPreferredSize();
gfx::Rect bounds = host->GetLocalBounds();
close_button_->SetBounds(bounds.right() - kButtonFrameMargin - ps.width(),
kButtonFrameMargin, ps.width(), ps.height());
ps = maximize_button_->GetPreferredSize();
maximize_button_->SetBounds(
close_button_->x() - kButtonFrameSpacing - ps.width(),
kButtonFrameMargin, ps.width(), ps.height());
bounds.Inset(kFrameSize,
close_button_->bounds().bottom() + kButtonFrameMargin,
kFrameSize, kFrameSize);
controller_->app_view_->SetBounds(bounds);
}
virtual gfx::Size GetPreferredSize(const views::View* host) const OVERRIDE {
return gfx::Size();
}
// Overridden from views::ButtonListener:
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE {
if (sender == close_button_)
controller_->CloseWindow();
else if (sender == maximize_button_)
controller_->ToggleMaximize();
}
FrameController* controller_;
views::Button* close_button_;
views::Button* maximize_button_;
DISALLOW_COPY_AND_ASSIGN(LayoutManager);
};
////////////////////////////////////////////////////////////////////////////////
// FrameController, public:
FrameController::FrameController(mojo::View* view, mojo::View** app_view)
: view_(view),
app_view_(mojo::View::Create(view->view_manager())),
frame_view_(new views::View),
frame_view_layout_manager_(new LayoutManager(this)),
widget_(new views::Widget),
maximized_(false) {
view_->AddChild(app_view_);
view_->AddObserver(this);
*app_view = app_view_;
frame_view_->set_background(
views::Background::CreateSolidBackground(SK_ColorBLUE));
frame_view_->SetLayoutManager(frame_view_layout_manager_);
views::Widget::InitParams params(
views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
params.native_widget = new mojo::NativeWidgetViewManager(widget_, view_);
params.bounds = gfx::Rect(view_->bounds().size());
widget_->Init(params);
widget_->SetContentsView(frame_view_);
widget_->Show();
}
FrameController::~FrameController() {}
void FrameController::CloseWindow() {
app_view_->Destroy();
view_->Destroy();
}
void FrameController::ToggleMaximize() {
if (!maximized_)
restored_bounds_ = view_->bounds();
maximized_ = !maximized_;
if (maximized_)
view_->SetBounds(view_->parent()->bounds());
else
view_->SetBounds(restored_bounds_);
}
////////////////////////////////////////////////////////////////////////////////
// FrameController, mojo::ViewObserver implementation:
void FrameController::OnViewDestroyed(mojo::View* view) {
view_->RemoveObserver(this);
delete this;
}
// 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.
#ifndef MOJO_EXAMPLES_WM_FLOW_WM_FRAME_CONTROLLER_H_
#define MOJO_EXAMPLES_WM_FLOW_WM_FRAME_CONTROLLER_H_
#include "mojo/services/public/cpp/view_manager/view_observer.h"
#include "ui/gfx/geometry/rect.h"
namespace mojo {
class NativeWidgetViewManager;
class View;
}
namespace views {
class View;
class Widget;
}
// FrameController encapsulates the window manager's frame additions to a window
// created by an application. It renders the content of the frame and responds
// to any events targeted at it.
class FrameController : mojo::ViewObserver {
public:
FrameController(mojo::View* view, mojo::View** app_view);
virtual ~FrameController();
void CloseWindow();
void ToggleMaximize();
private:
class LayoutManager;
friend class LayoutManager;
virtual void OnViewDestroyed(mojo::View* view) MOJO_OVERRIDE;
mojo::View* view_;
mojo::View* app_view_;
views::View* frame_view_;
LayoutManager* frame_view_layout_manager_;
views::Widget* widget_;
bool maximized_;
gfx::Rect restored_bounds_;
DISALLOW_COPY_AND_ASSIGN(FrameController);
};
#endif // MOJO_EXAMPLES_WM_FLOW_WM_FRAME_CONTROLLER_H_
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "mojo/examples/wm_flow/wm/frame_controller.h"
#include "mojo/public/c/system/main.h"
#include "mojo/public/cpp/application/application_delegate.h"
#include "mojo/public/cpp/application/application_impl.h"
......@@ -13,6 +14,7 @@
#include "mojo/services/public/cpp/view_manager/window_manager_delegate.h"
#include "mojo/services/public/interfaces/input_events/input_events.mojom.h"
#include "mojo/services/window_manager/window_manager_app.h"
#include "mojo/views/views_init.h"
namespace examples {
......@@ -65,25 +67,16 @@ class SimpleWM : public mojo::ApplicationDelegate,
const mojo::String& url,
mojo::InterfaceRequest<mojo::ServiceProvider> service_provider)
MOJO_OVERRIDE {
mojo::View* frame_view = mojo::View::Create(view_manager_);
mojo::View* app_view = NULL;
mojo::View* frame_view = CreateTopLevelWindow(&app_view);
window_container_->AddChild(frame_view);
frame_view->SetBounds(gfx::Rect(next_window_origin_, gfx::Size(400, 400)));
frame_view->SetColor(SK_ColorBLUE);
frame_view->AddObserver(this);
mojo::View* embed_view = mojo::View::Create(view_manager_);
gfx::Rect client_bounds(frame_view->bounds().size());
client_bounds.Inset(10, 30, 10, 10);
embed_view->SetBounds(client_bounds);
frame_view->AddChild(embed_view);
// TODO(beng): We're dropping the |service_provider| passed from the client
// on the floor here and passing our own. Seems like we should
// be sending both. I'm not yet sure how this sould work for
// N levels of proxying.
embed_view->Embed(url, scoped_ptr<mojo::ServiceProviderImpl>(
app_view->Embed(url, scoped_ptr<mojo::ServiceProviderImpl>(
new mojo::ServiceProviderImpl).Pass());
next_window_origin_.Offset(50, 50);
}
virtual void DispatchEvent(mojo::EventPtr event) MOJO_OVERRIDE {}
......@@ -107,6 +100,15 @@ class SimpleWM : public mojo::ApplicationDelegate,
next_window_origin_.Offset(-50, -50);
}
mojo::View* CreateTopLevelWindow(mojo::View** app_view) {
mojo::View* frame_view = mojo::View::Create(view_manager_);
frame_view->SetBounds(gfx::Rect(next_window_origin_, gfx::Size(400, 400)));
next_window_origin_.Offset(50, 50);
new FrameController(frame_view, app_view);
return frame_view;
}
scoped_ptr<mojo::WindowManagerApp> window_manager_app_;
mojo::ViewManager* view_manager_;
......@@ -121,6 +123,7 @@ class SimpleWM : public mojo::ApplicationDelegate,
} // namespace examples
MojoResult MojoMain(MojoHandle shell_handle) {
mojo::ViewsInit views_init;
mojo::ApplicationRunnerChromium runner(new examples::SimpleWM);
return runner.Run(shell_handle);
}
......@@ -745,12 +745,17 @@
'type': 'loadable_module',
'dependencies': [
'../base/base.gyp:base',
'../skia/skia.gyp:skia',
'../ui/views/views.gyp:views',
'mojo_base.gyp:mojo_application_chromium',
'mojo_core_window_manager_lib',
'mojo_view_manager_lib',
'mojo_views_support',
'<(mojo_system_for_loadable_module)',
],
'sources': [
'examples/wm_flow/wm/frame_controller.cc',
'examples/wm_flow/wm/frame_controller.h',
'examples/wm_flow/wm/wm.cc',
],
},
......
......@@ -39,6 +39,8 @@ class View {
// Destroys this view and all its children.
void Destroy();
ViewManager* view_manager() { return manager_; }
// Configuration.
Id id() const { return id_; }
......
......@@ -252,6 +252,15 @@ void ConnectionManager::OnViewHierarchyChanged(const ServerView* view,
const ServerView* old_parent) {
if (!display_manager_.in_setup())
ProcessViewHierarchyChanged(view, new_parent, old_parent);
// TODO(beng): optimize.
if (old_parent) {
display_manager_.SchedulePaint(old_parent,
gfx::Rect(old_parent->bounds().size()));
}
if (new_parent) {
display_manager_.SchedulePaint(new_parent,
gfx::Rect(new_parent->bounds().size()));
}
}
void ConnectionManager::OnViewBoundsChanged(const ServerView* view,
......
......@@ -139,7 +139,6 @@ void NativeWidgetViewManager::OnViewDestroyed(View* view) {
DCHECK_EQ(view, view_);
view->RemoveObserver(this);
view_ = NULL;
window_tree_host_.reset();
}
void NativeWidgetViewManager::OnViewBoundsChanged(View* view,
......
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