OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/caption_buttons/frame_maximize_button.h" | 5 #include "ash/wm/caption_buttons/frame_maximize_button.h" |
6 | 6 |
7 #include "ash/metrics/user_metrics_recorder.h" | 7 #include "ash/metrics/user_metrics_recorder.h" |
8 #include "ash/screen_util.h" | 8 #include "ash/screen_util.h" |
9 #include "ash/shelf/shelf_widget.h" | 9 #include "ash/shelf/shelf_widget.h" |
10 #include "ash/shell.h" | 10 #include "ash/shell.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 namespace ash { | 31 namespace ash { |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 // Delay before forcing an update of the snap location. | 35 // Delay before forcing an update of the snap location. |
36 const int kUpdateDelayMS = 400; | 36 const int kUpdateDelayMS = 400; |
37 | 37 |
38 // The delay of the bubble appearance. | 38 // The delay of the bubble appearance. |
39 const int kBubbleAppearanceDelayMS = 500; | 39 const int kBubbleAppearanceDelayMS = 500; |
40 | 40 |
41 } // namespace | 41 // The minimum sanp size in percent of the screen width. |
| 42 const int kMinSnapSizePercent = 50; |
| 43 } |
42 | 44 |
43 // EscapeEventFilter is installed on the RootWindow to track when the escape key | 45 // EscapeEventFilter is installed on the RootWindow to track when the escape key |
44 // is pressed. We use an EventFilter for this as the FrameMaximizeButton | 46 // is pressed. We use an EventFilter for this as the FrameMaximizeButton |
45 // normally does not get focus. | 47 // normally does not get focus. |
46 class FrameMaximizeButton::EscapeEventFilter : public ui::EventHandler { | 48 class FrameMaximizeButton::EscapeEventFilter : public ui::EventHandler { |
47 public: | 49 public: |
48 explicit EscapeEventFilter(FrameMaximizeButton* button); | 50 explicit EscapeEventFilter(FrameMaximizeButton* button); |
49 virtual ~EscapeEventFilter(); | 51 virtual ~EscapeEventFilter(); |
50 | 52 |
51 // EventFilter overrides: | 53 // EventFilter overrides: |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 default: | 142 default: |
141 // We should not come here. | 143 // We should not come here. |
142 NOTREACHED(); | 144 NOTREACHED(); |
143 } | 145 } |
144 // Note: There is no hover with touch - we can therefore pass false for touch | 146 // Note: There is no hover with touch - we can therefore pass false for touch |
145 // operations. | 147 // operations. |
146 UpdateSnap(location, true, false); | 148 UpdateSnap(location, true, false); |
147 } | 149 } |
148 | 150 |
149 void FrameMaximizeButton::ExecuteSnapAndCloseMenu(SnapType snap_type) { | 151 void FrameMaximizeButton::ExecuteSnapAndCloseMenu(SnapType snap_type) { |
150 if (snap_type_ != snap_type) { | 152 // We can come here with no snap type set in case that the mouse opened the |
151 // This occurs if mouse hover opened the maximize bubble and a user | 153 // maximize button and a touch event "touched" a button. |
152 // "touched" one of the maximize bubble's buttons. | 154 if (snap_type_ == SNAP_NONE) |
153 SnapButtonHovered(snap_type); | 155 SnapButtonHovered(snap_type); |
154 } | |
155 | 156 |
156 Cancel(true); | 157 Cancel(true); |
157 // Tell our menu to close. | 158 // Tell our menu to close. |
158 maximizer_.reset(); | 159 maximizer_.reset(); |
159 snap_type_ = snap_type; | 160 snap_type_ = snap_type; |
160 // Since Snap might destroy |this|, but the snap_sizer needs to be destroyed, | 161 // Since Snap might destroy |this|, but the snap_sizer needs to be destroyed, |
161 // The ownership of the snap_sizer is taken now. | 162 // The ownership of the snap_sizer is taken now. |
162 scoped_ptr<SnapSizer> snap_sizer(snap_sizer_.release()); | 163 scoped_ptr<SnapSizer> snap_sizer(snap_sizer_.release()); |
163 Snap(snap_sizer.get()); | 164 Snap(snap_sizer.get()); |
164 } | 165 } |
(...skipping 18 matching lines...) Expand all Loading... |
183 void FrameMaximizeButton::OnWindowPropertyChanged(aura::Window* window, | 184 void FrameMaximizeButton::OnWindowPropertyChanged(aura::Window* window, |
184 const void* key, | 185 const void* key, |
185 intptr_t old) { | 186 intptr_t old) { |
186 Cancel(false); | 187 Cancel(false); |
187 } | 188 } |
188 | 189 |
189 void FrameMaximizeButton::OnWindowDestroying(aura::Window* window) { | 190 void FrameMaximizeButton::OnWindowDestroying(aura::Window* window) { |
190 maximizer_.reset(); | 191 maximizer_.reset(); |
191 if (observing_frame_) { | 192 if (observing_frame_) { |
192 CHECK_EQ(frame_->GetNativeWindow(), window); | 193 CHECK_EQ(frame_->GetNativeWindow(), window); |
193 window->RemoveObserver(this); | 194 frame_->GetNativeWindow()->RemoveObserver(this); |
194 wm::GetWindowState(window)->RemoveObserver(this); | |
195 frame_->RemoveObserver(this); | 195 frame_->RemoveObserver(this); |
196 observing_frame_ = false; | 196 observing_frame_ = false; |
197 } | 197 } |
198 } | 198 } |
199 | 199 |
200 void FrameMaximizeButton::OnWindowShowTypeChanged(wm::WindowState* window_state, | |
201 wm::WindowShowType old_type) { | |
202 Cancel(false); | |
203 } | |
204 | |
205 void FrameMaximizeButton::OnWidgetActivationChanged(views::Widget* widget, | 200 void FrameMaximizeButton::OnWidgetActivationChanged(views::Widget* widget, |
206 bool active) { | 201 bool active) { |
207 // Upon losing focus, the bubble menu and the phantom window should hide. | 202 // Upon losing focus, the bubble menu and the phantom window should hide. |
208 if (!active) | 203 if (!active) |
209 Cancel(false); | 204 Cancel(false); |
210 } | 205 } |
211 | 206 |
212 bool FrameMaximizeButton::OnMousePressed(const ui::MouseEvent& event) { | 207 bool FrameMaximizeButton::OnMousePressed(const ui::MouseEvent& event) { |
213 // If we are already in a mouse click / drag operation, a second button down | 208 // If we are already in a mouse click / drag operation, a second button down |
214 // call will cancel (this addresses crbug.com/143755). | 209 // call will cancel (this addresses crbug.com/143755). |
215 if (is_snap_enabled_) { | 210 if (is_snap_enabled_) { |
216 Cancel(false); | 211 Cancel(false); |
217 } else { | 212 } else { |
218 is_snap_enabled_ = event.IsOnlyLeftMouseButton(); | 213 is_snap_enabled_ = event.IsOnlyLeftMouseButton(); |
219 if (is_snap_enabled_) | 214 if (is_snap_enabled_) |
220 ProcessStartEvent(event); | 215 ProcessStartEvent(event); |
221 } | 216 } |
222 FrameCaptionButton::OnMousePressed(event); | 217 FrameCaptionButton::OnMousePressed(event); |
223 return true; | 218 return true; |
224 } | 219 } |
225 | 220 |
226 void FrameMaximizeButton::OnMouseEntered(const ui::MouseEvent& event) { | 221 void FrameMaximizeButton::OnMouseEntered(const ui::MouseEvent& event) { |
227 FrameCaptionButton::OnMouseEntered(event); | 222 FrameCaptionButton::OnMouseEntered(event); |
228 if (!maximizer_) { | 223 if (!maximizer_) { |
229 DCHECK(GetWidget()); | 224 DCHECK(GetWidget()); |
230 if (!observing_frame_) { | 225 if (!observing_frame_) { |
231 observing_frame_ = true; | 226 observing_frame_ = true; |
232 aura::Window* window = frame_->GetNativeWindow(); | 227 frame_->GetNativeWindow()->AddObserver(this); |
233 window->AddObserver(this); | |
234 wm::GetWindowState(window)->AddObserver(this); | |
235 frame_->AddObserver(this); | 228 frame_->AddObserver(this); |
236 } | 229 } |
237 maximizer_.reset(new MaximizeBubbleController( | 230 maximizer_.reset(new MaximizeBubbleController( |
238 this, | 231 this, |
239 GetMaximizeBubbleFrameState(), | 232 GetMaximizeBubbleFrameState(), |
240 bubble_appearance_delay_ms_)); | 233 bubble_appearance_delay_ms_)); |
241 } | 234 } |
242 } | 235 } |
243 | 236 |
244 void FrameMaximizeButton::OnMouseExited(const ui::MouseEvent& event) { | 237 void FrameMaximizeButton::OnMouseExited(const ui::MouseEvent& event) { |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 break; | 551 break; |
559 case SNAP_NONE: | 552 case SNAP_NONE: |
560 NOTREACHED(); | 553 NOTREACHED(); |
561 } | 554 } |
562 } | 555 } |
563 | 556 |
564 MaximizeBubbleFrameState | 557 MaximizeBubbleFrameState |
565 FrameMaximizeButton::GetMaximizeBubbleFrameState() const { | 558 FrameMaximizeButton::GetMaximizeBubbleFrameState() const { |
566 wm::WindowState* window_state = | 559 wm::WindowState* window_state = |
567 wm::GetWindowState(frame_->GetNativeWindow()); | 560 wm::GetWindowState(frame_->GetNativeWindow()); |
568 switch (window_state->window_show_type()) { | 561 // When there are no restore bounds, we are in normal mode. |
569 case wm::SHOW_TYPE_MAXIMIZED: | 562 if (!window_state->HasRestoreBounds()) |
570 case wm::SHOW_TYPE_FULLSCREEN: | 563 return FRAME_STATE_NONE; |
571 return FRAME_STATE_FULL; | 564 // The normal maximized test can be used. |
572 case wm::SHOW_TYPE_LEFT_SNAPPED: | 565 if (frame_->IsMaximized()) |
573 return FRAME_STATE_SNAP_LEFT; | 566 return FRAME_STATE_FULL; |
574 case wm::SHOW_TYPE_RIGHT_SNAPPED: | 567 // For Left/right maximize we need to check the dimensions. |
575 return FRAME_STATE_SNAP_RIGHT; | 568 gfx::Rect bounds = frame_->GetWindowBoundsInScreen(); |
576 case wm::SHOW_TYPE_DEFAULT: | 569 gfx::Rect screen = Shell::GetScreen()->GetDisplayNearestWindow( |
577 case wm::SHOW_TYPE_NORMAL: | 570 frame_->GetNativeView()).work_area(); |
578 case wm::SHOW_TYPE_MINIMIZED: | 571 if (bounds.width() < (screen.width() * kMinSnapSizePercent) / 100) |
579 case wm::SHOW_TYPE_INACTIVE: | 572 return FRAME_STATE_NONE; |
580 case wm::SHOW_TYPE_DETACHED: | 573 // We might still have a horizontally filled window at this point which we |
581 case wm::SHOW_TYPE_END: | 574 // treat as no special state. |
582 case wm::SHOW_TYPE_AUTO_POSITIONED: | 575 if (bounds.y() != screen.y() || bounds.height() != screen.height()) |
583 return FRAME_STATE_NONE; | 576 return FRAME_STATE_NONE; |
584 } | 577 |
| 578 // We have to be in a maximize mode at this point. |
| 579 if (bounds.x() == screen.x()) |
| 580 return FRAME_STATE_SNAP_LEFT; |
| 581 if (bounds.right() == screen.right()) |
| 582 return FRAME_STATE_SNAP_RIGHT; |
| 583 // If we come here, it is likely caused by the fact that the |
| 584 // "VerticalResizeDoubleClick" stored a restore rectangle. In that case |
| 585 // we allow all maximize operations (and keep the restore rectangle). |
585 return FRAME_STATE_NONE; | 586 return FRAME_STATE_NONE; |
586 } | 587 } |
587 | 588 |
588 } // namespace ash | 589 } // namespace ash |
OLD | NEW |