summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-03 18:23:18 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-03 18:23:18 +0000
commit2a3197bb6a8a4c6f3a7affadce28cda638906131 (patch)
tree3269ee97d0c0e180d7529169178571f0c56060eb
parent820de97b4820ef0da82d9ee74f3009dc88d3c93e (diff)
downloadchromium_src-2a3197bb6a8a4c6f3a7affadce28cda638906131.zip
chromium_src-2a3197bb6a8a4c6f3a7affadce28cda638906131.tar.gz
chromium_src-2a3197bb6a8a4c6f3a7affadce28cda638906131.tar.bz2
Adds some widget methods I'm going to need for dragging real browsers:
. RunMoveLoop/EndMoveLoop. The new TabDragController will invoke this to start dragging a window. . SetMouseCapture/ReleaseMouseCapture - I have to futz with mouse capture during tab dragging. . SetVisibilityChangedAnimationsEnabled - so that I can disable the aero show/hide effect when showing a new browser. BUG=98345 TEST=none R=ben@chromium.org Review URL: http://codereview.chromium.org/9022039 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@116149 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/wm/toplevel_window_event_filter.cc43
-rw-r--r--ash/wm/toplevel_window_event_filter.h21
-rw-r--r--ui/aura/aura.gyp4
-rw-r--r--ui/aura/client/window_move_client.cc24
-rw-r--r--ui/aura/client/window_move_client.h41
-rw-r--r--ui/views/widget/native_widget_aura.cc22
-rw-r--r--ui/views/widget/native_widget_aura.h5
-rw-r--r--ui/views/widget/native_widget_gtk.cc15
-rw-r--r--ui/views/widget/native_widget_gtk.h5
-rw-r--r--ui/views/widget/native_widget_private.h5
-rw-r--r--ui/views/widget/native_widget_win.cc136
-rw-r--r--ui/views/widget/native_widget_win.h5
-rw-r--r--ui/views/widget/widget.cc26
-rw-r--r--ui/views/widget/widget.h29
14 files changed, 360 insertions, 21 deletions
diff --git a/ash/wm/toplevel_window_event_filter.cc b/ash/wm/toplevel_window_event_filter.cc
index c4d0695..c173ce7 100644
--- a/ash/wm/toplevel_window_event_filter.cc
+++ b/ash/wm/toplevel_window_event_filter.cc
@@ -1,10 +1,11 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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 "ash/wm/toplevel_window_event_filter.h"
#include "ash/wm/window_util.h"
+#include "base/message_loop.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/cursor.h"
#include "ui/aura/event.h"
@@ -13,6 +14,7 @@
#include "ui/aura/window_delegate.h"
#include "ui/base/hit_test.h"
#include "ui/base/ui_base_types.h"
+#include "ui/gfx/screen.h"
namespace ash {
@@ -135,7 +137,9 @@ void ToggleMaximizedState(aura::Window* window) {
ToplevelWindowEventFilter::ToplevelWindowEventFilter(aura::Window* owner)
: EventFilter(owner),
+ in_move_loop_(false),
window_component_(HTNOWHERE) {
+ aura::client::SetWindowMoveClient(owner, this);
}
ToplevelWindowEventFilter::~ToplevelWindowEventFilter() {
@@ -163,13 +167,17 @@ bool ToplevelWindowEventFilter::PreHandleMouseEvent(aura::Window* target,
event->flags() & ui::EF_IS_DOUBLE_CLICK) {
ToggleMaximizedState(target);
}
- UpdateLocationFromEvent(target, event);
+ UpdateMouseDownLocation(target, event->location());
return GetBoundsChangeForWindowComponent(window_component_) !=
kBoundsChange_None;
case ui::ET_MOUSE_DRAGGED:
return HandleDrag(target, event);
case ui::ET_MOUSE_RELEASED:
window_component_ = HTNOWHERE;
+ if (in_move_loop_) {
+ MessageLoop::current()->Quit();
+ in_move_loop_ = false;
+ }
break;
default:
break;
@@ -191,7 +199,7 @@ ui::TouchStatus ToplevelWindowEventFilter::PreHandleTouchEvent(
// Handle touch move by simulate mouse drag with single touch.
switch (event->type()) {
case ui::ET_TOUCH_PRESSED:
- UpdateLocationFromEvent(target, event);
+ UpdateMouseDownLocation(target, event->location());
pressed_touch_ids_.insert(event->touch_id());
if (pressed_touch_ids_.size() == 1)
return ui::TOUCH_STATUS_START;
@@ -215,6 +223,29 @@ ui::TouchStatus ToplevelWindowEventFilter::PreHandleTouchEvent(
return ui::TOUCH_STATUS_UNKNOWN;
}
+void ToplevelWindowEventFilter::RunMoveLoop(aura::Window* source) {
+ DCHECK(!in_move_loop_); // Can only handle one nested loop at a time.
+ in_move_loop_ = true;
+ window_component_ = HTCAPTION;
+ gfx::Point source_mouse_location(gfx::Screen::GetCursorScreenPoint());
+ aura::Window::ConvertPointToWindow(
+ aura::RootWindow::GetInstance(), source, &source_mouse_location);
+ UpdateMouseDownLocation(source, source_mouse_location);
+ MessageLoopForUI::current()->RunWithDispatcher(
+ aura::RootWindow::GetInstance()->GetDispatcher());
+ in_move_loop_ = false;
+}
+
+void ToplevelWindowEventFilter::EndMoveLoop() {
+ if (!in_move_loop_)
+ return;
+
+ in_move_loop_ = false;
+ window_component_ = HTNOWHERE;
+ MessageLoopForUI::current()->Quit();
+ aura::RootWindow::GetInstance()->PostNativeEvent(ui::CreateNoopEvent());
+}
+
void ToplevelWindowEventFilter::MoveWindowToFront(aura::Window* target) {
aura::Window* parent = target->parent();
aura::Window* child = target;
@@ -263,11 +294,11 @@ bool ToplevelWindowEventFilter::HandleDrag(aura::Window* target,
return true;
}
-void ToplevelWindowEventFilter::UpdateLocationFromEvent(
+void ToplevelWindowEventFilter::UpdateMouseDownLocation(
aura::Window* target,
- aura::LocatedEvent* event) {
+ const gfx::Point& location) {
mouse_down_bounds_ = target->bounds();
- mouse_down_offset_in_parent_ = event->location();
+ mouse_down_offset_in_parent_ = location;
aura::Window::ConvertPointToWindow(target, target->parent(),
&mouse_down_offset_in_parent_);
}
diff --git a/ash/wm/toplevel_window_event_filter.h b/ash/wm/toplevel_window_event_filter.h
index b548289..ea3661d 100644
--- a/ash/wm/toplevel_window_event_filter.h
+++ b/ash/wm/toplevel_window_event_filter.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -9,6 +9,7 @@
#include <set>
#include "base/compiler_specific.h"
+#include "ui/aura/client/window_move_client.h"
#include "ui/aura/event_filter.h"
#include "ash/ash_export.h"
#include "ui/gfx/point.h"
@@ -22,7 +23,9 @@ class Window;
namespace ash {
-class ASH_EXPORT ToplevelWindowEventFilter : public aura::EventFilter {
+class ASH_EXPORT ToplevelWindowEventFilter :
+ public aura::EventFilter,
+ public aura::client::WindowMoveClient {
public:
explicit ToplevelWindowEventFilter(aura::Window* owner);
virtual ~ToplevelWindowEventFilter();
@@ -35,6 +38,10 @@ class ASH_EXPORT ToplevelWindowEventFilter : public aura::EventFilter {
virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target,
aura::TouchEvent* event) OVERRIDE;
+ // Overridden form aura::client::WindowMoveClient:
+ virtual void RunMoveLoop(aura::Window* source) OVERRIDE;
+ virtual void EndMoveLoop() OVERRIDE;
+
protected:
// Returns the |window_component_|. See the variable definition below for
// more details.
@@ -50,9 +57,10 @@ class ASH_EXPORT ToplevelWindowEventFilter : public aura::EventFilter {
// The return value is returned by OnMouseEvent() above.
bool HandleDrag(aura::Window* target, aura::LocatedEvent* event);
- // Updates the event location to window.
- void UpdateLocationFromEvent(aura::Window* target,
- aura::LocatedEvent* event);
+ // Updates |mouse_down_offset_in_parent_| and |mouse_down_bounds_| from
+ // |location|.
+ void UpdateMouseDownLocation(aura::Window* target,
+ const gfx::Point& location);
// Updates the |window_component_| using the |event|'s location.
void UpdateWindowComponentForEvent(aura::Window* window,
@@ -91,6 +99,9 @@ class ASH_EXPORT ToplevelWindowEventFilter : public aura::EventFilter {
// The bounds of the target window when the mouse was pressed.
gfx::Rect mouse_down_bounds_;
+ // Are we running a nested message loop from RunMoveLoop().
+ bool in_move_loop_;
+
// The window component (hit-test code) the mouse is currently over.
int window_component_;
diff --git a/ui/aura/aura.gyp b/ui/aura/aura.gyp
index 5c70bb5..2348f02 100644
--- a/ui/aura/aura.gyp
+++ b/ui/aura/aura.gyp
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
+# Copyright (c) 2012 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.
@@ -39,6 +39,8 @@
'client/stacking_client.h',
'client/tooltip_client.cc',
'client/tooltip_client.h',
+ 'client/window_move_client.cc',
+ 'client/window_move_client.h',
'client/window_types.h',
'cursor.h',
'root_window_host.h',
diff --git a/ui/aura/client/window_move_client.cc b/ui/aura/client/window_move_client.cc
new file mode 100644
index 0000000..8257713
--- /dev/null
+++ b/ui/aura/client/window_move_client.cc
@@ -0,0 +1,24 @@
+// Copyright (c) 2012 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 "ui/aura/client/window_move_client.h"
+
+#include "ui/aura/window.h"
+
+namespace aura {
+namespace client {
+
+const char kWindowMoveClientKey[] = "WindowMoveClient";
+
+void SetWindowMoveClient(Window* window, WindowMoveClient* client) {
+ window->SetProperty(kWindowMoveClientKey, client);
+}
+
+WindowMoveClient* GetWindowMoveClient(Window* window) {
+ return reinterpret_cast<WindowMoveClient*>(
+ window->GetProperty(kWindowMoveClientKey));
+}
+
+} // namespace client
+} // namespace aura
diff --git a/ui/aura/client/window_move_client.h b/ui/aura/client/window_move_client.h
new file mode 100644
index 0000000..5392e47
--- /dev/null
+++ b/ui/aura/client/window_move_client.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2012 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 UI_AURA_CLIENT_WINDOW_MOVE_CLIENT_H_
+#define UI_AURA_CLIENT_WINDOW_MOVE_CLIENT_H_
+#pragma once
+
+#include "ui/aura/aura_export.h"
+
+namespace aura {
+class Window;
+namespace client {
+
+// A property key to store a client that handles window moves. The type of
+// the value is |aura::client::WindowMoveClient*|.
+AURA_EXPORT extern const char kWindowMoveClientKey[];
+
+// An interface implemented by an object that manages programatically keyed
+// window moving.
+class AURA_EXPORT WindowMoveClient {
+ public:
+ // Starts a nested message loop for moving the window.
+ virtual void RunMoveLoop(Window* window) = 0;
+
+ // Ends a previously started move loop.
+ virtual void EndMoveLoop() = 0;
+
+ protected:
+ virtual ~WindowMoveClient() {}
+};
+
+// Sets/Gets the activation client for the specified window.
+AURA_EXPORT void SetWindowMoveClient(Window* window,
+ WindowMoveClient* client);
+AURA_EXPORT WindowMoveClient* GetWindowMoveClient(Window* window);
+
+} // namespace client
+} // namespace aura
+
+#endif // UI_AURA_CLIENT_WINDOW_MOVE_CLIENT_H_
diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc
index da2a1da..687d7ca 100644
--- a/ui/views/widget/native_widget_aura.cc
+++ b/ui/views/widget/native_widget_aura.cc
@@ -9,6 +9,7 @@
#include "ui/aura/client/activation_client.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/drag_drop_client.h"
+#include "ui/aura/client/window_move_client.h"
#include "ui/aura/client/window_types.h"
#include "ui/aura/event.h"
#include "ui/aura/root_window.h"
@@ -554,6 +555,27 @@ void NativeWidgetAura::SetInactiveRenderingDisabled(bool value) {
active_window_observer_.reset(new ActiveWindowObserver(this));
}
+Widget::MoveLoopResult NativeWidgetAura::RunMoveLoop() {
+ if (window_->parent() &&
+ aura::client::GetWindowMoveClient(window_->parent())) {
+ SetMouseCapture();
+ aura::client::GetWindowMoveClient(window_->parent())->RunMoveLoop(window_);
+ return Widget::MOVE_LOOP_SUCCESSFUL;
+ }
+ return Widget::MOVE_LOOP_CANCELED;
+}
+
+void NativeWidgetAura::EndMoveLoop() {
+ if (window_->parent() &&
+ aura::client::GetWindowMoveClient(window_->parent())) {
+ aura::client::GetWindowMoveClient(window_->parent())->EndMoveLoop();
+ }
+}
+
+void NativeWidgetAura::SetVisibilityChangedAnimationsEnabled(bool value) {
+ // Nothing needed on aura.
+}
+
////////////////////////////////////////////////////////////////////////////////
// NativeWidgetAura, views::InputMethodDelegate implementation:
diff --git a/ui/views/widget/native_widget_aura.h b/ui/views/widget/native_widget_aura.h
index 121b89b..874615c 100644
--- a/ui/views/widget/native_widget_aura.h
+++ b/ui/views/widget/native_widget_aura.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -118,6 +118,9 @@ class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate,
virtual void FocusNativeView(gfx::NativeView native_view) OVERRIDE;
virtual gfx::Rect GetWorkAreaBoundsInScreen() const OVERRIDE;
virtual void SetInactiveRenderingDisabled(bool value) OVERRIDE;
+ virtual Widget::MoveLoopResult RunMoveLoop() OVERRIDE;
+ virtual void EndMoveLoop() OVERRIDE;
+ virtual void SetVisibilityChangedAnimationsEnabled(bool value) OVERRIDE;
// Overridden from views::InputMethodDelegate:
virtual void DispatchKeyEventPostIME(const KeyEvent& key) OVERRIDE;
diff --git a/ui/views/widget/native_widget_gtk.cc b/ui/views/widget/native_widget_gtk.cc
index 2bf0ef3..3cf2188 100644
--- a/ui/views/widget/native_widget_gtk.cc
+++ b/ui/views/widget/native_widget_gtk.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -1284,6 +1284,19 @@ gfx::Rect NativeWidgetGtk::GetWorkAreaBoundsInScreen() const {
void NativeWidgetGtk::SetInactiveRenderingDisabled(bool value) {
}
+Widget::MoveLoopResult NativeWidgetGtk::RunMoveLoop() {
+ NOTIMPLEMENTED();
+ return Widget::MOVE_LOOP_CANCELED;
+}
+
+void NativeWidgetGtk::EndMoveLoop() {
+ NOTIMPLEMENTED();
+}
+
+void NativeWidgetGtk::SetVisibilityChangedAnimationsEnabled(bool value) {
+ // Nothing needed on gtk.
+}
+
////////////////////////////////////////////////////////////////////////////////
// NativeWidgetGtk, protected:
diff --git a/ui/views/widget/native_widget_gtk.h b/ui/views/widget/native_widget_gtk.h
index 7c9e0e3..d3437d4 100644
--- a/ui/views/widget/native_widget_gtk.h
+++ b/ui/views/widget/native_widget_gtk.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -222,6 +222,9 @@ class VIEWS_EXPORT NativeWidgetGtk : public internal::NativeWidgetPrivate,
virtual void FocusNativeView(gfx::NativeView native_view) OVERRIDE;
virtual gfx::Rect GetWorkAreaBoundsInScreen() const OVERRIDE;
virtual void SetInactiveRenderingDisabled(bool value) OVERRIDE;
+ virtual Widget::MoveLoopResult RunMoveLoop() OVERRIDE;
+ virtual void EndMoveLoop() OVERRIDE;
+ virtual void SetVisibilityChangedAnimationsEnabled(bool value) OVERRIDE;
protected:
// Modifies event coordinates to the targeted widget contained by this widget.
diff --git a/ui/views/widget/native_widget_private.h b/ui/views/widget/native_widget_private.h
index a5702c3..46441fd 100644
--- a/ui/views/widget/native_widget_private.h
+++ b/ui/views/widget/native_widget_private.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -202,6 +202,9 @@ class VIEWS_EXPORT NativeWidgetPrivate : public NativeWidget,
virtual void FocusNativeView(gfx::NativeView native_view) = 0;
virtual gfx::Rect GetWorkAreaBoundsInScreen() const = 0;
virtual void SetInactiveRenderingDisabled(bool value) = 0;
+ virtual Widget::MoveLoopResult RunMoveLoop() = 0;
+ virtual void EndMoveLoop() = 0;
+ virtual void SetVisibilityChangedAnimationsEnabled(bool value) = 0;
// Overridden from NativeWidget:
virtual internal::NativeWidgetPrivate* AsNativeWidgetPrivate() OVERRIDE;
diff --git a/ui/views/widget/native_widget_win.cc b/ui/views/widget/native_widget_win.cc
index 9af3a4d..d0e57c7 100644
--- a/ui/views/widget/native_widget_win.cc
+++ b/ui/views/widget/native_widget_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -56,6 +56,116 @@ namespace views {
namespace {
+// MoveLoopMouseWatcher is used to determine if the user canceled or completed a
+// move. win32 doesn't appear to offer a way to determine the result of a move,
+// so we install hooks to determine if we got a mouse up and assume the move
+// completed.
+class MoveLoopMouseWatcher {
+ public:
+ explicit MoveLoopMouseWatcher(NativeWidgetWin* host);
+ ~MoveLoopMouseWatcher();
+
+ // Returns true if the mouse is up, or if we couldn't install the hook.
+ bool got_mouse_up() const { return got_mouse_up_; }
+
+ private:
+ // Instance that owns the hook. We only allow one instance to hook the mouse
+ // at a time.
+ static MoveLoopMouseWatcher* instance_;
+
+ // Key and mouse callbacks from the hook.
+ static LRESULT CALLBACK MouseHook(int n_code, WPARAM w_param, LPARAM l_param);
+ static LRESULT CALLBACK KeyHook(int n_code, WPARAM w_param, LPARAM l_param);
+
+ void Unhook();
+
+ // NativeWidgetWin that created us.
+ NativeWidgetWin* host_;
+
+ // Did we get a mouse up?
+ bool got_mouse_up_;
+
+ // Hook identifiers.
+ HHOOK mouse_hook_;
+ HHOOK key_hook_;
+
+ DISALLOW_COPY_AND_ASSIGN(MoveLoopMouseWatcher);
+};
+
+// static
+MoveLoopMouseWatcher* MoveLoopMouseWatcher::instance_ = NULL;
+
+MoveLoopMouseWatcher::MoveLoopMouseWatcher(NativeWidgetWin* host)
+ : host_(host),
+ got_mouse_up_(false),
+ mouse_hook_(NULL),
+ key_hook_(NULL) {
+ // Only one instance can be active at a time.
+ if (instance_)
+ instance_->Unhook();
+
+ mouse_hook_ = SetWindowsHookEx(
+ WH_MOUSE, &MouseHook, NULL, GetCurrentThreadId());
+ if (mouse_hook_) {
+ instance_ = this;
+ // We don't care if setting the key hook succeeded.
+ key_hook_ = SetWindowsHookEx(
+ WH_KEYBOARD, &KeyHook, NULL, GetCurrentThreadId());
+ }
+ if (instance_ != this) {
+ // Failed installation. Assume we got a mouse up in this case, otherwise
+ // we'll think all drags were canceled.
+ got_mouse_up_ = true;
+ }
+}
+
+MoveLoopMouseWatcher::~MoveLoopMouseWatcher() {
+ Unhook();
+}
+
+void MoveLoopMouseWatcher::Unhook() {
+ if (instance_ != this)
+ return;
+
+ DCHECK(mouse_hook_);
+ UnhookWindowsHookEx(mouse_hook_);
+ if (key_hook_)
+ UnhookWindowsHookEx(key_hook_);
+ key_hook_ = NULL;
+ mouse_hook_ = NULL;
+ instance_ = NULL;
+}
+
+// static
+LRESULT CALLBACK MoveLoopMouseWatcher::MouseHook(int n_code,
+ WPARAM w_param,
+ LPARAM l_param) {
+ DCHECK(instance_);
+ if (n_code == HC_ACTION && w_param == WM_LBUTTONUP)
+ instance_->got_mouse_up_ = true;
+ return CallNextHookEx(instance_->mouse_hook_, n_code, w_param, l_param);
+}
+
+// static
+LRESULT CALLBACK MoveLoopMouseWatcher::KeyHook(int n_code,
+ WPARAM w_param,
+ LPARAM l_param) {
+ if (n_code == HC_ACTION && w_param == VK_ESCAPE) {
+ int value = TRUE;
+ HRESULT result = DwmSetWindowAttribute(
+ instance_->host_->GetNativeView(),
+ DWMWA_TRANSITIONS_FORCEDISABLED,
+ &value,
+ sizeof(value));
+ // Hide the window on escape, otherwise the window is visibly going to snap
+ // back to the original location before we close it.
+ // This behavior is specific to tab dragging, in that we generally wouldn't
+ // want this functionality if we have other consumers using this API.
+ instance_->host_->Hide();
+ }
+ return CallNextHookEx(instance_->key_hook_, n_code, w_param, l_param);
+}
+
// Get the source HWND of the specified message. Depending on the message, the
// source HWND is encoded in either the WPARAM or the LPARAM value.
HWND GetControlHWNDForMessage(UINT message, WPARAM w_param, LPARAM l_param) {
@@ -717,7 +827,8 @@ void NativeWidgetWin::StackAbove(gfx::NativeView native_view) {
}
void NativeWidgetWin::StackAtTop() {
- NOTIMPLEMENTED();
+ SetWindowPos(HWND_TOP, 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
}
void NativeWidgetWin::SetShape(gfx::NativeRegion region) {
@@ -998,6 +1109,27 @@ gfx::Rect NativeWidgetWin::GetWorkAreaBoundsInScreen() const {
void NativeWidgetWin::SetInactiveRenderingDisabled(bool value) {
}
+Widget::MoveLoopResult NativeWidgetWin::RunMoveLoop() {
+ ReleaseMouseCapture();
+ MoveLoopMouseWatcher watcher(this);
+ SendMessage(hwnd(), WM_SYSCOMMAND, SC_MOVE | 0x0002, GetMessagePos());
+ // Windows doesn't appear to offer a way to determine whether the user
+ // canceled the move or not. We assume if the user released the mouse it was
+ // successful.
+ return watcher.got_mouse_up() ? Widget::MOVE_LOOP_SUCCESSFUL :
+ Widget::MOVE_LOOP_CANCELED;
+}
+
+void NativeWidgetWin::EndMoveLoop() {
+ SendMessage(hwnd(), WM_CANCELMODE, 0, 0);
+}
+
+void NativeWidgetWin::SetVisibilityChangedAnimationsEnabled(bool value) {
+ int dwm_value = value ? FALSE : TRUE;
+ DwmSetWindowAttribute(
+ hwnd(), DWMWA_TRANSITIONS_FORCEDISABLED, &dwm_value, sizeof(dwm_value));
+}
+
////////////////////////////////////////////////////////////////////////////////
// NativeWidgetWin, MessageLoop::Observer implementation:
diff --git a/ui/views/widget/native_widget_win.h b/ui/views/widget/native_widget_win.h
index 1daf32e..c6cd9c8 100644
--- a/ui/views/widget/native_widget_win.h
+++ b/ui/views/widget/native_widget_win.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -254,6 +254,9 @@ class VIEWS_EXPORT NativeWidgetWin : public ui::WindowImpl,
virtual void FocusNativeView(gfx::NativeView native_view) OVERRIDE;
virtual gfx::Rect GetWorkAreaBoundsInScreen() const OVERRIDE;
virtual void SetInactiveRenderingDisabled(bool value) OVERRIDE;
+ virtual Widget::MoveLoopResult RunMoveLoop() OVERRIDE;
+ virtual void EndMoveLoop() OVERRIDE;
+ virtual void SetVisibilityChangedAnimationsEnabled(bool value) OVERRIDE;
protected:
// Information saved before going into fullscreen mode, used to restore the
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index 3b3d086..51fed47 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -444,6 +444,18 @@ void Widget::SetBoundsConstrained(const gfx::Rect& bounds) {
}
}
+void Widget::SetVisibilityChangedAnimationsEnabled(bool value) {
+ native_widget_->SetVisibilityChangedAnimationsEnabled(value);
+}
+
+Widget::MoveLoopResult Widget::RunMoveLoop() {
+ return native_widget_->RunMoveLoop();
+}
+
+void Widget::EndMoveLoop() {
+ native_widget_->EndMoveLoop();
+}
+
void Widget::StackAboveWidget(Widget* widget) {
native_widget_->StackAbove(widget->GetNativeView());
}
@@ -799,6 +811,18 @@ NativeWidget* Widget::native_widget() {
return native_widget_;
}
+void Widget::SetMouseCapture(views::View* view) {
+ is_mouse_button_pressed_ = true;
+ root_view_->SetMouseHandler(view);
+ if (!native_widget_->HasMouseCapture())
+ native_widget_->SetMouseCapture();
+}
+
+void Widget::ReleaseMouseCapture() {
+ if (native_widget_->HasMouseCapture())
+ native_widget_->ReleaseMouseCapture();
+}
+
const Event* Widget::GetCurrentEvent() {
return event_stack_.empty() ? NULL : event_stack_.top()->event();
}
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h
index 2af755c..f00d6b7 100644
--- a/ui/views/widget/widget.h
+++ b/ui/views/widget/widget.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -107,6 +107,15 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
FRAME_TYPE_FORCE_NATIVE // Force the native frame.
};
+ // Result from RunMoveLoop().
+ enum MoveLoopResult {
+ // The move loop completed successfully.
+ MOVE_LOOP_SUCCESSFUL,
+
+ // The user canceled the move loop.
+ MOVE_LOOP_CANCELED
+ };
+
struct VIEWS_EXPORT InitParams {
enum Type {
TYPE_WINDOW, // A decorated Window, like a frame window.
@@ -306,6 +315,18 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
// non-child widgets.
void SetBoundsConstrained(const gfx::Rect& bounds);
+ // Sets whether animations that occur when visibility is changed are enabled.
+ // Default is true.
+ void SetVisibilityChangedAnimationsEnabled(bool value);
+
+ // Starts a nested message loop that moves the window. This can be used to
+ // start a window move operation from a mouse moved event. This returns when
+ // the move completes.
+ MoveLoopResult RunMoveLoop();
+
+ // Stops a previously started move loop. This is not immediate.
+ void EndMoveLoop();
+
// Places the widget in front of the specified widget in z-order.
void StackAboveWidget(Widget* widget);
void StackAbove(gfx::NativeView native_view);
@@ -533,6 +554,12 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
return native_widget_;
}
+ // Sets mouse capture on the specified view.
+ void SetMouseCapture(views::View* view);
+
+ // Releases mouse capture.
+ void ReleaseMouseCapture();
+
// Returns the current event being processed. If there are multiple events
// being processed at the same time (e.g. one event triggers another event),
// then the most recent event is returned. Returns NULL if no event is being