summaryrefslogtreecommitdiffstats
path: root/views/desktop
diff options
context:
space:
mode:
authoroshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-19 19:06:15 +0000
committeroshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-19 19:06:15 +0000
commit8647714eef4b0eb718c5b2682f14c9b0f5ecce13 (patch)
treee38a7ec5f5839f3f2ffbe5c546bac5406e09258a /views/desktop
parent02fe9c2b6adab15311c621a611d2405f1ea6551b (diff)
downloadchromium_src-8647714eef4b0eb718c5b2682f14c9b0f5ecce13.zip
chromium_src-8647714eef4b0eb718c5b2682f14c9b0f5ecce13.tar.gz
chromium_src-8647714eef4b0eb718c5b2682f14c9b0f5ecce13.tar.bz2
Simple WindowManager that can move/resize window.
Fixes TouchFrame's NonClientHitTest to ignore VirtualKeyboard area. Move mouse capture logic to Window Manager so that nested mouse capture with nested NWVs works correctly. Note1: This is a tentative WM that allows us to move/resize window in views desktop until we have real window manager based on aura/layer API. Note2: There is an compositor related issue and doesn't work well when compositor is enabled. I'll look into it after this CL. Review URL: http://codereview.chromium.org/7530017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97492 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/desktop')
-rw-r--r--views/desktop/desktop_window_manager.cc193
-rw-r--r--views/desktop/desktop_window_manager.h69
-rw-r--r--views/desktop/desktop_window_view.cc6
3 files changed, 267 insertions, 1 deletions
diff --git a/views/desktop/desktop_window_manager.cc b/views/desktop/desktop_window_manager.cc
new file mode 100644
index 0000000..7276ecc
--- /dev/null
+++ b/views/desktop/desktop_window_manager.cc
@@ -0,0 +1,193 @@
+// Copyright (c) 2011 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 "views/desktop/desktop_window_manager.h"
+
+#include "views/events/event.h"
+#include "views/widget/widget.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/rect.h"
+#include "views/widget/widget.h"
+#include "views/widget/native_widget_private.h"
+#include "views/widget/native_widget_views.h"
+#include "views/widget/widget_delegate.h"
+#if defined(OS_LINUX)
+#include "views/window/hit_test.h"
+#endif
+#include "views/window/non_client_view.h"
+
+namespace {
+
+class MoveWindowController : public views::desktop::WindowController {
+ public:
+ MoveWindowController(views::Widget* widget, const gfx::Point& start)
+ : target_(widget),
+ offset_(start) {
+ }
+
+ virtual ~MoveWindowController() {
+ }
+
+ bool OnMouseEvent(const views::MouseEvent& event) {
+ if (event.type()== ui::ET_MOUSE_DRAGGED) {
+ gfx::Point origin = event.location().Subtract(offset_);
+ gfx::Rect rect = target_->GetWindowScreenBounds();
+ rect.set_origin(origin);
+ target_->SetBounds(rect);
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ views::Widget* target_;
+ gfx::Point offset_;
+
+ DISALLOW_COPY_AND_ASSIGN(MoveWindowController);
+};
+
+// Simple resize controller that handle all resize as if the bottom
+// right corner is selected.
+class ResizeWindowController : public views::desktop::WindowController {
+ public:
+ ResizeWindowController(views::Widget* widget)
+ : target_(widget) {
+ }
+
+ virtual ~ResizeWindowController() {
+ }
+
+ bool OnMouseEvent(const views::MouseEvent& event) OVERRIDE {
+ if (event.type()== ui::ET_MOUSE_DRAGGED) {
+ gfx::Point location = event.location();
+ gfx::Rect rect = target_->GetWindowScreenBounds();
+ gfx::Point size = location.Subtract(rect.origin());
+ target_->SetSize(gfx::Size(std::max(10, size.x()),
+ std::max(10, size.y())));
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ views::Widget* target_;
+
+ DISALLOW_COPY_AND_ASSIGN(ResizeWindowController);
+};
+
+} // namespace
+
+namespace views {
+namespace desktop {
+
+WindowController::WindowController() {
+}
+
+WindowController::~WindowController() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DesktopWindowManager, public:
+
+DesktopWindowManager::DesktopWindowManager(Widget* desktop)
+ : desktop_(desktop),
+ mouse_capture_(NULL) {
+}
+
+DesktopWindowManager::~DesktopWindowManager() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DesktopWindowManager, WindowManager implementation:
+
+void DesktopWindowManager::StartMoveDrag(
+ views::Widget* widget,
+ const gfx::Point& point) {
+ DCHECK(!window_controller_.get());
+ DCHECK(!HasMouseCapture());
+ if (!widget->IsMaximized() && !widget->IsMinimized()) {
+ gfx::Point new_point = point;
+ if (desktop_->non_client_view()) {
+ gfx::Rect client =
+ desktop_->non_client_view()->frame_view()->GetBoundsForClientView();
+ new_point.Offset(client.x(), client.y());
+ }
+ SetMouseCapture();
+ window_controller_.reset(new MoveWindowController(widget, new_point));
+ }
+}
+
+void DesktopWindowManager::StartResizeDrag(
+ views::Widget* widget, const gfx::Point& point, int hittest_code) {
+ DCHECK(!window_controller_.get());
+ DCHECK(!HasMouseCapture());
+ if (!widget->IsMaximized() &&
+ !widget->IsMinimized() &&
+ (widget->widget_delegate() || widget->widget_delegate()->CanResize())) {
+ SetMouseCapture();
+ window_controller_.reset(new ResizeWindowController(widget));
+ }
+}
+
+bool DesktopWindowManager::SetMouseCapture(views::Widget* widget) {
+ if (mouse_capture_)
+ return false;
+ if (mouse_capture_ == widget)
+ return true;
+ DCHECK(!HasMouseCapture());
+ SetMouseCapture();
+ mouse_capture_ = widget;
+ return true;
+}
+
+bool DesktopWindowManager::ReleaseMouseCapture(views::Widget* widget) {
+ if (!widget || mouse_capture_ != widget)
+ return false;
+ DCHECK(HasMouseCapture());
+ ReleaseMouseCapture();
+ mouse_capture_ = NULL;
+ return true;
+}
+
+bool DesktopWindowManager::HasMouseCapture(const views::Widget* widget) const {
+ return widget && mouse_capture_ == widget;
+}
+
+bool DesktopWindowManager::HandleMouseEvent(
+ views::Widget* widget, const views::MouseEvent& event) {
+
+ if (window_controller_.get()) {
+ if (!window_controller_->OnMouseEvent(event)) {
+ ReleaseMouseCapture();
+ window_controller_.reset();
+ }
+ return true;
+ }
+
+ if (mouse_capture_) {
+ views::MouseEvent translated(event, widget->GetRootView(),
+ mouse_capture_->GetRootView());
+ mouse_capture_->OnMouseEvent(translated);
+ return true;
+ }
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DesktopWindowManager, private:
+
+void DesktopWindowManager::SetMouseCapture() {
+ return desktop_->native_widget_private()->SetMouseCapture();
+}
+
+void DesktopWindowManager::ReleaseMouseCapture() {
+ return desktop_->native_widget_private()->ReleaseMouseCapture();
+}
+
+bool DesktopWindowManager::HasMouseCapture() const {
+ return desktop_->native_widget_private()->HasMouseCapture();
+}
+
+} // namespace desktop
+} // namespace views
diff --git a/views/desktop/desktop_window_manager.h b/views/desktop/desktop_window_manager.h
new file mode 100644
index 0000000..146bb2a
--- /dev/null
+++ b/views/desktop/desktop_window_manager.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2011 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 VIEWS_DESKTOP_DESKTOP_WINDOW_MANAGER_H_
+#define VIEWS_DESKTOP_DESKTOP_WINDOW_MANAGER_H_
+
+#include "base/compiler_specific.h"
+#include "base/scoped_ptr.h"
+#include "views/widget/window_manager.h"
+
+namespace gfx {
+class Point;
+}
+
+namespace views {
+class Widget;
+
+namespace desktop {
+class WindowController;
+
+// A tentative window manager for views destktop until we have *right*
+// implementation based on aura/layer API. This is minimum
+// implmenetation and complicated actio like moving transformed window
+// doesn't work. TODO(oshima): move active widget to WindowManager.
+class DesktopWindowManager : public views::WindowManager {
+ public:
+ DesktopWindowManager(Widget* desktop);
+ virtual ~DesktopWindowManager();
+
+ // views::WindowManager implementations:
+ virtual void StartMoveDrag(views::Widget* widget,
+ const gfx::Point& point) OVERRIDE;
+ virtual void StartResizeDrag(views::Widget* widget,
+ const gfx::Point& point,
+ int hittest_code);
+ virtual bool SetMouseCapture(views::Widget* widget) OVERRIDE;
+ virtual bool ReleaseMouseCapture(views::Widget* widget) OVERRIDE;
+ virtual bool HasMouseCapture(const views::Widget* widget) const OVERRIDE;
+ virtual bool HandleMouseEvent(views::Widget* widget,
+ const views::MouseEvent& event) OVERRIDE;
+
+ private:
+ void SetMouseCapture();
+ void ReleaseMouseCapture();
+ bool HasMouseCapture() const;
+
+ views::Widget* desktop_;
+ views::Widget* mouse_capture_;
+ scoped_ptr<WindowController> window_controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(DesktopWindowManager);
+};
+
+// An behavioral interface for objects implements window resize/movement.
+class WindowController {
+ public:
+ WindowController();
+ virtual ~WindowController();
+ virtual bool OnMouseEvent(const views::MouseEvent& event) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WindowController);
+};
+
+} // namespace desktop
+} // namespace views
+
+#endif // VIEWS_DESKTOP_DESKTOP_WINDOW_MANAGER_H_
diff --git a/views/desktop/desktop_window_view.cc b/views/desktop/desktop_window_view.cc
index 966f2fc..1c3c72f 100644
--- a/views/desktop/desktop_window_view.cc
+++ b/views/desktop/desktop_window_view.cc
@@ -8,6 +8,7 @@
#include "ui/gfx/transform.h"
#include "views/desktop/desktop_background.h"
#include "views/desktop/desktop_window_root_view.h"
+#include "views/desktop/desktop_window_manager.h"
#include "views/layer_property_setter.h"
#include "views/widget/native_widget_view.h"
#include "views/widget/native_widget_views.h"
@@ -51,7 +52,8 @@ class DesktopWindow : public Widget {
if (native_widget)
return native_widget->delegate()->OnMouseEvent(event);
}
- return Widget::OnMouseEvent(event);
+ return WindowManager::Get()->HandleMouseEvent(this, event) ||
+ Widget::OnMouseEvent(event);
}
DesktopWindowView* desktop_window_view_;
@@ -128,6 +130,8 @@ void DesktopWindowView::CreateDesktopWindow(DesktopType type) {
views::Widget* window = new DesktopWindow(desktop_window_view);
desktop_window_view->widget_ = window;
+ WindowManager::Install(new DesktopWindowManager(window));
+
views::Widget::InitParams params;
params.delegate = desktop_window_view;
// In this environment, CreateChromeWindow will default to creating a views-