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