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