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

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

Issue 657583003: Chrome OS: Ash support for >=3 displays. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased at 306637. Created 6 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/wm/drag_window_resizer.h" 5 #include "ash/wm/drag_window_resizer.h"
6 6
7 #include "ash/display/mouse_cursor_event_filter.h" 7 #include "ash/display/mouse_cursor_event_filter.h"
8 #include "ash/screen_util.h" 8 #include "ash/screen_util.h"
9 #include "ash/shell.h" 9 #include "ash/shell.h"
10 #include "ash/wm/coordinate_conversion.h" 10 #include "ash/wm/coordinate_conversion.h"
(...skipping 12 matching lines...) Expand all
23 #include "ui/wm/core/coordinate_conversion.h" 23 #include "ui/wm/core/coordinate_conversion.h"
24 #include "ui/wm/core/window_util.h" 24 #include "ui/wm/core/window_util.h"
25 25
26 namespace ash { 26 namespace ash {
27 namespace { 27 namespace {
28 28
29 // The maximum opacity of the drag phantom window. 29 // The maximum opacity of the drag phantom window.
30 const float kMaxOpacity = 0.8f; 30 const float kMaxOpacity = 0.8f;
31 31
32 // Returns true if Ash has more than one root window. 32 // Returns true if Ash has more than one root window.
33 bool HasSecondaryRootWindow() { 33 bool HasSecondaryRootWindows() {
34 return Shell::GetAllRootWindows().size() > 1; 34 return Shell::GetAllRootWindows().size() > 1;
35 } 35 }
36 36
37 // When there are two root windows, returns one of the root windows which is not 37 // When there are more than one root windows, returns all root windows which are
38 // |root_window|. Returns NULL if only one root window exists. 38 // not |root_window|. Returns an empty vector if only one root window exists.
39 aura::Window* GetAnotherRootWindow(aura::Window* root_window) { 39 std::vector<aura::Window*> GetOtherRootWindows(aura::Window* root_window) {
40 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 40 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
41 std::vector<aura::Window*> other_root_windows;
oshima 2014/12/05 22:18:15 any reason not to use aura::Window::Windows?
hshi1 2014/12/05 23:25:12 Done.
41 if (root_windows.size() < 2) 42 if (root_windows.size() < 2)
42 return NULL; 43 return other_root_windows;
43 DCHECK_EQ(2U, root_windows.size()); 44 for (size_t i = 0; i < root_windows.size(); ++i) {
44 if (root_windows[0] == root_window) 45 if (root_windows[i] != root_window)
45 return root_windows[1]; 46 other_root_windows.push_back(root_windows[i]);
46 return root_windows[0]; 47 }
48 return other_root_windows;
47 } 49 }
48 50
49 } // namespace 51 } // namespace
50 52
51 // static 53 // static
52 DragWindowResizer* DragWindowResizer::instance_ = NULL; 54 DragWindowResizer* DragWindowResizer::instance_ = NULL;
53 55
54 DragWindowResizer::~DragWindowResizer() { 56 DragWindowResizer::~DragWindowResizer() {
55 if (window_state_) 57 if (window_state_)
56 window_state_->DeleteDragDetails(); 58 window_state_->DeleteDragDetails();
(...skipping 14 matching lines...) Expand all
71 73
72 void DragWindowResizer::Drag(const gfx::Point& location, int event_flags) { 74 void DragWindowResizer::Drag(const gfx::Point& location, int event_flags) {
73 base::WeakPtr<DragWindowResizer> resizer(weak_ptr_factory_.GetWeakPtr()); 75 base::WeakPtr<DragWindowResizer> resizer(weak_ptr_factory_.GetWeakPtr());
74 next_window_resizer_->Drag(location, event_flags); 76 next_window_resizer_->Drag(location, event_flags);
75 77
76 if (!resizer) 78 if (!resizer)
77 return; 79 return;
78 80
79 last_mouse_location_ = location; 81 last_mouse_location_ = location;
80 // Show a phantom window for dragging in another root window. 82 // Show a phantom window for dragging in another root window.
81 if (HasSecondaryRootWindow()) { 83 if (HasSecondaryRootWindows()) {
82 gfx::Point location_in_screen = location; 84 gfx::Point location_in_screen = location;
83 ::wm::ConvertPointToScreen(GetTarget()->parent(), &location_in_screen); 85 ::wm::ConvertPointToScreen(GetTarget()->parent(), &location_in_screen);
84 const bool in_original_root = 86 const bool in_original_root =
85 wm::GetRootWindowAt(location_in_screen) == GetTarget()->GetRootWindow(); 87 wm::GetRootWindowAt(location_in_screen) == GetTarget()->GetRootWindow();
86 UpdateDragWindow(GetTarget()->bounds(), in_original_root); 88 UpdateDragWindow(GetTarget()->bounds(), in_original_root);
87 } else { 89 } else {
88 drag_window_controller_.reset(); 90 drag_window_controllers_.clear();
89 } 91 }
90 } 92 }
91 93
92 void DragWindowResizer::CompleteDrag() { 94 void DragWindowResizer::CompleteDrag() {
93 next_window_resizer_->CompleteDrag(); 95 next_window_resizer_->CompleteDrag();
94 96
95 GetTarget()->layer()->SetOpacity(details().initial_opacity); 97 GetTarget()->layer()->SetOpacity(details().initial_opacity);
96 drag_window_controller_.reset(); 98 drag_window_controllers_.clear();
97 99
98 // Check if the destination is another display. 100 // Check if the destination is another display.
99 gfx::Point last_mouse_location_in_screen = last_mouse_location_; 101 gfx::Point last_mouse_location_in_screen = last_mouse_location_;
100 ::wm::ConvertPointToScreen(GetTarget()->parent(), 102 ::wm::ConvertPointToScreen(GetTarget()->parent(),
101 &last_mouse_location_in_screen); 103 &last_mouse_location_in_screen);
102 gfx::Screen* screen = Shell::GetScreen(); 104 gfx::Screen* screen = Shell::GetScreen();
103 const gfx::Display dst_display = 105 const gfx::Display dst_display =
104 screen->GetDisplayNearestPoint(last_mouse_location_in_screen); 106 screen->GetDisplayNearestPoint(last_mouse_location_in_screen);
105 107
106 if (dst_display.id() != 108 if (dst_display.id() !=
(...skipping 24 matching lines...) Expand all
131 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility( 133 ash::wm::AdjustBoundsToEnsureMinimumWindowVisibility(
132 dst_display.bounds(), &dst_bounds); 134 dst_display.bounds(), &dst_bounds);
133 135
134 GetTarget()->SetBoundsInScreen(dst_bounds, dst_display); 136 GetTarget()->SetBoundsInScreen(dst_bounds, dst_display);
135 } 137 }
136 } 138 }
137 139
138 void DragWindowResizer::RevertDrag() { 140 void DragWindowResizer::RevertDrag() {
139 next_window_resizer_->RevertDrag(); 141 next_window_resizer_->RevertDrag();
140 142
141 drag_window_controller_.reset(); 143 drag_window_controllers_.clear();
142 GetTarget()->layer()->SetOpacity(details().initial_opacity); 144 GetTarget()->layer()->SetOpacity(details().initial_opacity);
143 } 145 }
144 146
145 DragWindowResizer::DragWindowResizer(WindowResizer* next_window_resizer, 147 DragWindowResizer::DragWindowResizer(WindowResizer* next_window_resizer,
146 wm::WindowState* window_state) 148 wm::WindowState* window_state)
147 : WindowResizer(window_state), 149 : WindowResizer(window_state),
148 next_window_resizer_(next_window_resizer), 150 next_window_resizer_(next_window_resizer),
149 weak_ptr_factory_(this) { 151 weak_ptr_factory_(this) {
150 // The pointer should be confined in one display during resizing a window 152 // The pointer should be confined in one display during resizing a window
151 // because the window cannot span two displays at the same time anyway. The 153 // because the window cannot span two displays at the same time anyway. The
152 // exception is window/tab dragging operation. During that operation, 154 // exception is window/tab dragging operation. During that operation,
153 // |mouse_warp_mode_| should be set to WARP_DRAG so that the user could move a 155 // |mouse_warp_mode_| should be set to WARP_DRAG so that the user could move a
154 // window/tab to another display. 156 // window/tab to another display.
155 MouseCursorEventFilter* mouse_cursor_filter = 157 MouseCursorEventFilter* mouse_cursor_filter =
156 Shell::GetInstance()->mouse_cursor_filter(); 158 Shell::GetInstance()->mouse_cursor_filter();
157 mouse_cursor_filter->set_mouse_warp_mode( 159 mouse_cursor_filter->set_mouse_warp_mode(
158 ShouldAllowMouseWarp() ? 160 ShouldAllowMouseWarp() ?
159 MouseCursorEventFilter::WARP_DRAG : MouseCursorEventFilter::WARP_NONE); 161 MouseCursorEventFilter::WARP_DRAG : MouseCursorEventFilter::WARP_NONE);
160 if (ShouldAllowMouseWarp()) 162 if (ShouldAllowMouseWarp())
161 mouse_cursor_filter->ShowSharedEdgeIndicator(GetTarget()->GetRootWindow()); 163 mouse_cursor_filter->ShowSharedEdgeIndicator(GetTarget()->GetRootWindow());
162 instance_ = this; 164 instance_ = this;
163 } 165 }
164 166
165 void DragWindowResizer::UpdateDragWindow(const gfx::Rect& bounds, 167 void DragWindowResizer::UpdateDragWindow(const gfx::Rect& bounds,
166 bool in_original_root) { 168 bool in_original_root) {
167 if (details().window_component != HTCAPTION || !ShouldAllowMouseWarp()) 169 if (details().window_component != HTCAPTION || !ShouldAllowMouseWarp())
168 return; 170 return;
169 171
170 // It's available. Show a phantom window on the display if needed. 172 // It's available. Show a phantom window on the display if needed.
171 aura::Window* another_root = 173 std::vector<aura::Window*> other_roots =
172 GetAnotherRootWindow(GetTarget()->GetRootWindow()); 174 GetOtherRootWindows(GetTarget()->GetRootWindow());
173 const gfx::Rect root_bounds_in_screen(another_root->GetBoundsInScreen()); 175 size_t drag_window_controller_count = 0;
174 const gfx::Rect bounds_in_screen = 176 for (size_t i = 0; i < other_roots.size(); ++i) {
177 aura::Window* another_root = other_roots[i];
178 const gfx::Rect root_bounds_in_screen(another_root->GetBoundsInScreen());
179 const gfx::Rect bounds_in_screen =
175 ScreenUtil::ConvertRectToScreen(GetTarget()->parent(), bounds); 180 ScreenUtil::ConvertRectToScreen(GetTarget()->parent(), bounds);
176 gfx::Rect bounds_in_another_root = 181 gfx::Rect bounds_in_another_root =
177 gfx::IntersectRects(root_bounds_in_screen, bounds_in_screen); 182 gfx::IntersectRects(root_bounds_in_screen, bounds_in_screen);
178 const float fraction_in_another_window = 183 const float fraction_in_another_window =
179 (bounds_in_another_root.width() * bounds_in_another_root.height()) / 184 (bounds_in_another_root.width() * bounds_in_another_root.height()) /
180 static_cast<float>(bounds.width() * bounds.height()); 185 static_cast<float>(bounds.width() * bounds.height());
181 186
182 if (fraction_in_another_window > 0) { 187 if (fraction_in_another_window > 0) {
183 if (!drag_window_controller_) { 188 if (drag_window_controllers_.size() < ++drag_window_controller_count)
184 drag_window_controller_.reset( 189 drag_window_controllers_.resize(drag_window_controller_count);
185 new DragWindowController(GetTarget())); 190 scoped_ptr<DragWindowController>& drag_window_controller =
186 // Always show the drag phantom on the |another_root| window. 191 drag_window_controllers_.back();
187 drag_window_controller_->SetDestinationDisplay( 192 if (!drag_window_controller) {
188 Shell::GetScreen()->GetDisplayNearestWindow(another_root)); 193 drag_window_controller.reset(new DragWindowController(GetTarget()));
189 drag_window_controller_->Show(); 194 // Always show the drag phantom on the |another_root| window.
195 drag_window_controller->SetDestinationDisplay(
196 Shell::GetScreen()->GetDisplayNearestWindow(another_root));
197 drag_window_controller->Show();
198 } else {
199 // No animation.
200 drag_window_controller->SetBounds(bounds_in_screen);
201 }
202 const float phantom_opacity =
203 !in_original_root ? 1 : (kMaxOpacity * fraction_in_another_window);
oshima 2014/12/05 22:18:15 indent
hshi1 2014/12/05 23:25:12 Done.
204 const float window_opacity =
205 in_original_root ? 1
206 : (kMaxOpacity * (1 - fraction_in_another_window));
207 drag_window_controller->SetOpacity(phantom_opacity);
208 GetTarget()->layer()->SetOpacity(window_opacity);
190 } else { 209 } else {
191 // No animation. 210 GetTarget()->layer()->SetOpacity(1.0f);
192 drag_window_controller_->SetBounds(bounds_in_screen);
193 } 211 }
194 const float phantom_opacity =
195 !in_original_root ? 1 : (kMaxOpacity * fraction_in_another_window);
196 const float window_opacity =
197 in_original_root ? 1 : (kMaxOpacity * (1 - fraction_in_another_window));
198 drag_window_controller_->SetOpacity(phantom_opacity);
199 GetTarget()->layer()->SetOpacity(window_opacity);
200 } else {
201 drag_window_controller_.reset();
202 GetTarget()->layer()->SetOpacity(1.0f);
203 } 212 }
213
214 // If we have more drag window controllers allocated than needed, release the
215 // excess controllers by shrinking the vector |drag_window_controller_|.
216 DCHECK_GE(drag_window_controllers_.size(), drag_window_controller_count);
217 if (drag_window_controllers_.size() > drag_window_controller_count)
218 drag_window_controllers_.resize(drag_window_controller_count);
204 } 219 }
205 220
206 bool DragWindowResizer::ShouldAllowMouseWarp() { 221 bool DragWindowResizer::ShouldAllowMouseWarp() {
207 return (details().window_component == HTCAPTION) && 222 return (details().window_component == HTCAPTION) &&
208 !::wm::GetTransientParent(GetTarget()) && 223 !::wm::GetTransientParent(GetTarget()) &&
209 (GetTarget()->type() == ui::wm::WINDOW_TYPE_NORMAL || 224 (GetTarget()->type() == ui::wm::WINDOW_TYPE_NORMAL ||
210 GetTarget()->type() == ui::wm::WINDOW_TYPE_PANEL); 225 GetTarget()->type() == ui::wm::WINDOW_TYPE_PANEL);
211 } 226 }
212 227
213 } // namespace ash 228 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698