Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: ash/wm/drag_window_resizer.cc

Issue 11411344: Extract the code for supporing extended desktop from WorkspaceWindowResizer into DragWindowResizer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix win_aura error Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ash/wm/drag_window_resizer.h ('k') | ash/wm/drag_window_resizer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/wm/drag_window_resizer.h"
6
7 #include "ash/display/mouse_cursor_event_filter.h"
8 #include "ash/screen_ash.h"
9 #include "ash/shell.h"
10 #include "ash/wm/coordinate_conversion.h"
11 #include "ash/wm/cursor_manager.h"
12 #include "ash/wm/drag_window_controller.h"
13 #include "ash/wm/property_util.h"
14 #include "ui/aura/client/aura_constants.h"
15 #include "ui/aura/env.h"
16 #include "ui/aura/root_window.h"
17 #include "ui/aura/window.h"
18 #include "ui/aura/window_delegate.h"
19 #include "ui/base/hit_test.h"
20 #include "ui/base/ui_base_types.h"
21 #include "ui/gfx/screen.h"
22
23 namespace ash {
24 namespace internal {
25
26 namespace {
27
28 // The maximum opacity of the drag phantom window.
29 const float kMaxOpacity = 0.8f;
30
31 // Returns true if Ash has more than one root window.
32 bool HasSecondaryRootWindow() {
33 return Shell::GetAllRootWindows().size() > 1;
34 }
35
36 // When there are two root windows, returns one of the root windows which is not
37 // |root_window|. Returns NULL if only one root window exists.
38 aura::RootWindow* GetAnotherRootWindow(aura::RootWindow* root_window) {
39 Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
40 if (root_windows.size() < 2)
41 return NULL;
42 DCHECK_EQ(2U, root_windows.size());
43 if (root_windows[0] == root_window)
44 return root_windows[1];
45 return root_windows[0];
46 }
47
48 }
49
50 DragWindowResizer::~DragWindowResizer() {
51 Shell* shell = Shell::GetInstance();
52 shell->mouse_cursor_filter()->set_mouse_warp_mode(
53 MouseCursorEventFilter::WARP_ALWAYS);
54 shell->mouse_cursor_filter()->HideSharedEdgeIndicator();
55
56 if (destroyed_)
57 *destroyed_ = true;
58 }
59
60 // static
61 DragWindowResizer* DragWindowResizer::Create(WindowResizer* window_resizer,
62 aura::Window* window,
63 const gfx::Point& location,
64 int window_component) {
65 Details details(window, location, window_component);
66 return details.is_resizable ?
67 new DragWindowResizer(window_resizer, details) : NULL;
68 }
69
70 void DragWindowResizer::Drag(const gfx::Point& location, int event_flags) {
71 bool destroyed = false;
72 destroyed_ = &destroyed;
73 window_resizer_->Drag(location, event_flags);
74 if (destroyed)
75 return;
76 destroyed_ = NULL;
77 last_mouse_location_ = location;
78
79 // Show a phantom window for dragging in another root window.
80 if (HasSecondaryRootWindow()) {
81 gfx::Point location_in_screen = location;
82 wm::ConvertPointToScreen(GetTarget()->parent(), &location_in_screen);
83 const bool in_original_root =
84 wm::GetRootWindowAt(location_in_screen) == GetTarget()->GetRootWindow();
85 UpdateDragWindow(GetTarget()->bounds(), in_original_root);
86 } else {
87 drag_window_controller_.reset();
88 }
89 }
90
91 void DragWindowResizer::CompleteDrag(int event_flags) {
92 window_resizer_->CompleteDrag(event_flags);
93
94 GetTarget()->layer()->SetOpacity(details_.initial_opacity);
95 drag_window_controller_.reset();
96
97 // Check if the destination is another display.
98 gfx::Point last_mouse_location_in_screen = last_mouse_location_;
99 wm::ConvertPointToScreen(GetTarget()->parent(),
100 &last_mouse_location_in_screen);
101 gfx::Screen* screen = Shell::GetScreen();
102 const gfx::Display dst_display =
103 screen->GetDisplayNearestPoint(last_mouse_location_in_screen);
104
105 if (dst_display.id() !=
106 screen->GetDisplayNearestWindow(GetTarget()->GetRootWindow()).id()) {
107 const gfx::Rect dst_bounds =
108 ScreenAsh::ConvertRectToScreen(GetTarget()->parent(),
109 GetTarget()->bounds());
110 GetTarget()->SetBoundsInScreen(dst_bounds, dst_display);
111 }
112 }
113
114 void DragWindowResizer::RevertDrag() {
115 window_resizer_->RevertDrag();
116
117 drag_window_controller_.reset();
118 GetTarget()->layer()->SetOpacity(details_.initial_opacity);
119 }
120
121 aura::Window* DragWindowResizer::GetTarget() {
122 return window_resizer_->GetTarget();
123 }
124
125 DragWindowResizer::DragWindowResizer(WindowResizer* window_resizer,
126 const Details& details)
127 : window_resizer_(window_resizer),
128 details_(details),
129 destroyed_(NULL) {
130 // The pointer should be confined in one display during resizing a window
131 // because the window cannot span two displays at the same time anyway. The
132 // exception is window/tab dragging operation. During that operation,
133 // |mouse_warp_mode_| should be set to WARP_DRAG so that the user could move a
134 // window/tab to another display.
135 MouseCursorEventFilter* mouse_cursor_filter =
136 Shell::GetInstance()->mouse_cursor_filter();
137 mouse_cursor_filter->set_mouse_warp_mode(
138 ShouldAllowMouseWarp() ?
139 MouseCursorEventFilter::WARP_DRAG : MouseCursorEventFilter::WARP_NONE);
140 if (ShouldAllowMouseWarp()) {
141 mouse_cursor_filter->ShowSharedEdgeIndicator(
142 details.window->GetRootWindow());
143 }
144 }
145
146 void DragWindowResizer::UpdateDragWindow(const gfx::Rect& bounds,
147 bool in_original_root) {
148 if (details_.window_component != HTCAPTION || !ShouldAllowMouseWarp())
149 return;
150
151 // It's available. Show a phantom window on the display if needed.
152 aura::RootWindow* another_root =
153 GetAnotherRootWindow(GetTarget()->GetRootWindow());
154 const gfx::Rect root_bounds_in_screen(another_root->GetBoundsInScreen());
155 const gfx::Rect bounds_in_screen =
156 ScreenAsh::ConvertRectToScreen(GetTarget()->parent(), bounds);
157 gfx::Rect bounds_in_another_root =
158 gfx::IntersectRects(root_bounds_in_screen, bounds_in_screen);
159 const float fraction_in_another_window =
160 (bounds_in_another_root.width() * bounds_in_another_root.height()) /
161 static_cast<float>(bounds.width() * bounds.height());
162
163 if (fraction_in_another_window > 0) {
164 if (!drag_window_controller_.get()) {
165 drag_window_controller_.reset(
166 new DragWindowController(GetTarget()));
167 // Always show the drag phantom on the |another_root| window.
168 drag_window_controller_->SetDestinationDisplay(
169 Shell::GetScreen()->GetDisplayMatching(
170 another_root->GetBoundsInScreen()));
171 drag_window_controller_->Show();
172 } else {
173 // No animation.
174 drag_window_controller_->SetBounds(bounds_in_screen);
175 }
176 const float phantom_opacity =
177 !in_original_root ? 1 : (kMaxOpacity * fraction_in_another_window);
178 const float window_opacity =
179 in_original_root ? 1 : (kMaxOpacity * (1 - fraction_in_another_window));
180 drag_window_controller_->SetOpacity(phantom_opacity);
181 GetTarget()->layer()->SetOpacity(window_opacity);
182 } else {
183 drag_window_controller_.reset();
184 GetTarget()->layer()->SetOpacity(1.0f);
185 }
186 }
187
188 bool DragWindowResizer::ShouldAllowMouseWarp() {
189 return (details_.window_component == HTCAPTION) &&
190 (GetTarget()->GetProperty(aura::client::kModalKey) ==
191 ui::MODAL_TYPE_NONE) &&
192 (GetTarget()->type() == aura::client::WINDOW_TYPE_NORMAL);
193 }
194
195 } // namespace internal
196 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/drag_window_resizer.h ('k') | ash/wm/drag_window_resizer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698