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

Side by Side Diff: ash/wm/caption_buttons/frame_maximize_button.cc

Issue 169443005: Fix crash which occurs when a widget destroys itself as a result of ET_GESTURE_TAP_DOWN (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months 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 | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698