| 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 |