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

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

Issue 10883069: Added restore functionality for maximize full/left/right (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed Created 8 years, 3 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/workspace/frame_maximize_button.h" 5 #include "ash/wm/workspace/frame_maximize_button.h"
6 6
7 #include "ash/launcher/launcher.h" 7 #include "ash/launcher/launcher.h"
8 #include "ash/screen_ash.h" 8 #include "ash/screen_ash.h"
9 #include "ash/shell.h" 9 #include "ash/shell.h"
10 #include "ash/wm/property_util.h" 10 #include "ash/wm/property_util.h"
(...skipping 17 matching lines...) Expand all
28 namespace ash { 28 namespace ash {
29 29
30 namespace { 30 namespace {
31 31
32 // Delay before forcing an update of the snap location. 32 // Delay before forcing an update of the snap location.
33 const int kUpdateDelayMS = 400; 33 const int kUpdateDelayMS = 400;
34 34
35 // The delay of the bubble appearance. 35 // The delay of the bubble appearance.
36 const int kBubbleAppearanceDelayMS = 500; 36 const int kBubbleAppearanceDelayMS = 500;
37 37
38 // The minimum sanp size in percent of the screen width.
39 const int kMinSnapSizePercent = 50;
38 } 40 }
39 41
40 // EscapeEventFilter is installed on the RootWindow to track when the escape key 42 // EscapeEventFilter is installed on the RootWindow to track when the escape key
41 // is pressed. We use an EventFilter for this as the FrameMaximizeButton 43 // is pressed. We use an EventFilter for this as the FrameMaximizeButton
42 // normally does not get focus. 44 // normally does not get focus.
43 class FrameMaximizeButton::EscapeEventFilter : public aura::EventFilter { 45 class FrameMaximizeButton::EscapeEventFilter : public aura::EventFilter {
44 public: 46 public:
45 explicit EscapeEventFilter(FrameMaximizeButton* button); 47 explicit EscapeEventFilter(FrameMaximizeButton* button);
46 virtual ~EscapeEventFilter(); 48 virtual ~EscapeEventFilter();
47 49
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 void FrameMaximizeButton::OnMouseEntered(const ui::MouseEvent& event) { 207 void FrameMaximizeButton::OnMouseEntered(const ui::MouseEvent& event) {
206 ImageButton::OnMouseEntered(event); 208 ImageButton::OnMouseEntered(event);
207 if (!maximizer_.get()) { 209 if (!maximizer_.get()) {
208 DCHECK(GetWidget()); 210 DCHECK(GetWidget());
209 if (!window_) { 211 if (!window_) {
210 window_ = frame_->GetWidget()->GetNativeWindow(); 212 window_ = frame_->GetWidget()->GetNativeWindow();
211 window_->AddObserver(this); 213 window_->AddObserver(this);
212 } 214 }
213 maximizer_.reset(new MaximizeBubbleController( 215 maximizer_.reset(new MaximizeBubbleController(
214 this, 216 this,
215 frame_->GetWidget()->IsMaximized(), 217 GetMaximizeBubbleFrameState(),
216 bubble_appearance_delay_ms_)); 218 bubble_appearance_delay_ms_));
217 } 219 }
218 } 220 }
219 221
220 void FrameMaximizeButton::OnMouseExited(const ui::MouseEvent& event) { 222 void FrameMaximizeButton::OnMouseExited(const ui::MouseEvent& event) {
221 ImageButton::OnMouseExited(event); 223 ImageButton::OnMouseExited(event);
222 // Remove the bubble menu when the button is not pressed and the mouse is not 224 // Remove the bubble menu when the button is not pressed and the mouse is not
223 // within the bubble. 225 // within the bubble.
224 if (!is_snap_enabled_ && maximizer_.get()) { 226 if (!is_snap_enabled_ && maximizer_.get()) {
225 if (maximizer_->GetBubbleWindow()) { 227 if (maximizer_->GetBubbleWindow()) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 299
298 return ImageButton::OnGestureEvent(event); 300 return ImageButton::OnGestureEvent(event);
299 } 301 }
300 302
301 void FrameMaximizeButton::ProcessStartEvent(const ui::LocatedEvent& event) { 303 void FrameMaximizeButton::ProcessStartEvent(const ui::LocatedEvent& event) {
302 DCHECK(is_snap_enabled_); 304 DCHECK(is_snap_enabled_);
303 // Prepare the help menu. 305 // Prepare the help menu.
304 if (!maximizer_.get()) { 306 if (!maximizer_.get()) {
305 maximizer_.reset(new MaximizeBubbleController( 307 maximizer_.reset(new MaximizeBubbleController(
306 this, 308 this,
307 frame_->GetWidget()->IsMaximized(), 309 GetMaximizeBubbleFrameState(),
308 bubble_appearance_delay_ms_)); 310 bubble_appearance_delay_ms_));
309 } else { 311 } else {
310 // If the menu did not show up yet, we delay it even a bit more. 312 // If the menu did not show up yet, we delay it even a bit more.
311 maximizer_->DelayCreation(); 313 maximizer_->DelayCreation();
312 } 314 }
313 snap_sizer_.reset(NULL); 315 snap_sizer_.reset(NULL);
314 InstallEventFilter(); 316 InstallEventFilter();
315 snap_type_ = SNAP_NONE; 317 snap_type_ = SNAP_NONE;
316 press_location_ = event.location(); 318 press_location_ = event.location();
317 exceeded_drag_threshold_ = false; 319 exceeded_drag_threshold_ = false;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 } 427 }
426 if (maximizer_.get()) { 428 if (maximizer_.get()) {
427 phantom_window_->set_phantom_below_window(maximizer_->GetBubbleWindow()); 429 phantom_window_->set_phantom_below_window(maximizer_->GetBubbleWindow());
428 maximizer_->SetSnapType(snap_type_); 430 maximizer_->SetSnapType(snap_type_);
429 } 431 }
430 phantom_window_->Show(ScreenBoundsForType(snap_type_, *snap_sizer_.get())); 432 phantom_window_->Show(ScreenBoundsForType(snap_type_, *snap_sizer_.get()));
431 } 433 }
432 434
433 SnapType FrameMaximizeButton::SnapTypeForLocation( 435 SnapType FrameMaximizeButton::SnapTypeForLocation(
434 const gfx::Point& location) const { 436 const gfx::Point& location) const {
437 MaximizeBubbleFrameState maximize_type = GetMaximizeBubbleFrameState();
435 int delta_x = location.x() - press_location_.x(); 438 int delta_x = location.x() - press_location_.x();
436 int delta_y = location.y() - press_location_.y(); 439 int delta_y = location.y() - press_location_.y();
437 if (!views::View::ExceededDragThreshold(delta_x, delta_y)) 440 if (!views::View::ExceededDragThreshold(delta_x, delta_y))
438 return !frame_->GetWidget()->IsMaximized() ? SNAP_MAXIMIZE : SNAP_RESTORE; 441 return maximize_type != FRAME_STATE_FULL ? SNAP_MAXIMIZE : SNAP_RESTORE;
439 else if (delta_x < 0 && delta_y > delta_x && delta_y < -delta_x) 442 else if (delta_x < 0 && delta_y > delta_x && delta_y < -delta_x)
440 return SNAP_LEFT; 443 return maximize_type == FRAME_STATE_SNAP_LEFT ? SNAP_RESTORE : SNAP_LEFT;
441 else if (delta_x > 0 && delta_y > -delta_x && delta_y < delta_x) 444 else if (delta_x > 0 && delta_y > -delta_x && delta_y < delta_x)
442 return SNAP_RIGHT; 445 return maximize_type == FRAME_STATE_SNAP_RIGHT ? SNAP_RESTORE : SNAP_RIGHT;
443 else if (delta_y > 0) 446 else if (delta_y > 0)
444 return SNAP_MINIMIZE; 447 return SNAP_MINIMIZE;
445 return !frame_->GetWidget()->IsMaximized() ? SNAP_MAXIMIZE : SNAP_RESTORE; 448 return maximize_type != FRAME_STATE_FULL ? SNAP_MAXIMIZE : SNAP_RESTORE;
446 } 449 }
447 450
448 gfx::Rect FrameMaximizeButton::ScreenBoundsForType( 451 gfx::Rect FrameMaximizeButton::ScreenBoundsForType(
449 SnapType type, 452 SnapType type,
450 const SnapSizer& snap_sizer) const { 453 const SnapSizer& snap_sizer) const {
451 aura::Window* window = frame_->GetWidget()->GetNativeWindow(); 454 aura::Window* window = frame_->GetWidget()->GetNativeWindow();
452 switch (type) { 455 switch (type) {
453 case SNAP_LEFT: 456 case SNAP_LEFT:
454 case SNAP_RIGHT: 457 case SNAP_RIGHT:
455 return ScreenAsh::ConvertRectToScreen( 458 return ScreenAsh::ConvertRectToScreen(
456 frame_->GetWidget()->GetNativeView()->parent(), 459 frame_->GetWidget()->GetNativeView()->parent(),
457 snap_sizer.target_bounds()); 460 snap_sizer.target_bounds());
458 case SNAP_MAXIMIZE: 461 case SNAP_MAXIMIZE:
459 return ScreenAsh::ConvertRectToScreen( 462 return ScreenAsh::ConvertRectToScreen(
460 window->parent(), 463 window->parent(),
461 ScreenAsh::GetMaximizedWindowBoundsInParent(window)); 464 ScreenAsh::GetMaximizedWindowBoundsInParent(window));
462 case SNAP_MINIMIZE: { 465 case SNAP_MINIMIZE: {
463 Launcher* launcher = Shell::GetInstance()->launcher(); 466 Launcher* launcher = Shell::GetInstance()->launcher();
464 gfx::Rect item_rect(launcher->GetScreenBoundsOfItemIconForWindow(window)); 467 gfx::Rect item_rect(launcher->GetScreenBoundsOfItemIconForWindow(
468 window));
465 if (!item_rect.IsEmpty()) { 469 if (!item_rect.IsEmpty()) {
466 // PhantomWindowController insets slightly, outset it so the phantom 470 // PhantomWindowController insets slightly, outset it so the phantom
467 // doesn't appear inset. 471 // doesn't appear inset.
468 item_rect.Inset(-8, -8); 472 item_rect.Inset(-8, -8);
469 return item_rect; 473 return item_rect;
470 } 474 }
471 return launcher->widget()->GetWindowBoundsInScreen(); 475 return launcher->widget()->GetWindowBoundsInScreen();
472 } 476 }
473 case SNAP_RESTORE: { 477 case SNAP_RESTORE: {
474 const gfx::Rect* restore = GetRestoreBoundsInScreen(window); 478 const gfx::Rect* restore = GetRestoreBoundsInScreen(window);
475 return restore ? 479 return restore ?
476 *restore : frame_->GetWidget()->GetWindowBoundsInScreen(); 480 *restore : frame_->GetWidget()->GetWindowBoundsInScreen();
477 } 481 }
478 case SNAP_NONE: 482 case SNAP_NONE:
479 NOTREACHED(); 483 NOTREACHED();
480 } 484 }
481 return gfx::Rect(); 485 return gfx::Rect();
482 } 486 }
483 487
484 gfx::Point FrameMaximizeButton::LocationForSnapSizer( 488 gfx::Point FrameMaximizeButton::LocationForSnapSizer(
485 const gfx::Point& location) const { 489 const gfx::Point& location) const {
486 gfx::Point result(location); 490 gfx::Point result(location);
487 views::View::ConvertPointToScreen(this, &result); 491 views::View::ConvertPointToScreen(this, &result);
488 return result; 492 return result;
489 } 493 }
490 494
491 void FrameMaximizeButton::Snap(const SnapSizer& snap_sizer) { 495 void FrameMaximizeButton::Snap(const SnapSizer& snap_sizer) {
496 views::Widget* widget = frame_->GetWidget();
492 switch (snap_type_) { 497 switch (snap_type_) {
493 case SNAP_LEFT: 498 case SNAP_LEFT:
494 case SNAP_RIGHT: 499 case SNAP_RIGHT: {
495 if (frame_->GetWidget()->IsMaximized()) { 500 // Get the window coordinates on the screen for restore purposes.
496 ash::SetRestoreBoundsInScreen(frame_->GetWidget()->GetNativeWindow(), 501 gfx::Rect restore = widget->GetNativeWindow()->bounds();
502 if (widget->IsMaximized()) {
503 // If it was maximized we need to recover the old restore set.
504 restore = *ash::GetRestoreBoundsInScreen(widget->GetNativeWindow());
sky 2012/08/29 17:29:20 This will crash if GetRestoreBoundsInScreen return
Mr4D (OOO till 08-26) 2012/08/29 18:57:34 I thought that in maximized mode the restore recta
sky 2012/08/29 21:08:50 A DCHECK is the right thing. It says you expect th
505 // Set the restore size we want to restore to.
506 ash::SetRestoreBoundsInScreen(widget->GetNativeWindow(),
sky 2012/08/29 17:29:20 Why do you need to set the restore bounds here as
Mr4D (OOO till 08-26) 2012/08/29 18:57:34 This is from the original code: We need to exit ma
497 ScreenBoundsForType(snap_type_, 507 ScreenBoundsForType(snap_type_,
498 snap_sizer)); 508 snap_sizer));
499 frame_->GetWidget()->Restore(); 509 widget->Restore();
sky 2012/08/29 17:29:20 Gah. Looking at this whole branch it seems wrong.
Mr4D (OOO till 08-26) 2012/08/29 18:57:34 This code predates my doing and was only taken ove
sky 2012/08/29 21:08:50 Good point.
500 } else { 510 } else {
501 frame_->GetWidget()->SetBounds(ScreenBoundsForType(snap_type_, 511 widget->SetBounds(ScreenBoundsForType(snap_type_, snap_sizer));
502 snap_sizer)); 512 }
513 // Remember the widow's bounds for restoration.
514 ash::SetRestoreBoundsInScreen(widget->GetNativeWindow(), restore);
503 } 515 }
504 break; 516 break;
505 case SNAP_MAXIMIZE: 517 case SNAP_MAXIMIZE:
506 frame_->GetWidget()->Maximize(); 518 widget->Maximize();
507 break; 519 break;
508 case SNAP_MINIMIZE: 520 case SNAP_MINIMIZE:
509 frame_->GetWidget()->Minimize(); 521 widget->Minimize();
510 break; 522 break;
511 case SNAP_RESTORE: 523 case SNAP_RESTORE:
512 frame_->GetWidget()->Restore(); 524 widget->Restore();
513 break; 525 break;
514 case SNAP_NONE: 526 case SNAP_NONE:
515 NOTREACHED(); 527 NOTREACHED();
516 } 528 }
517 } 529 }
518 530
531 MaximizeBubbleFrameState FrameMaximizeButton::GetMaximizeBubbleFrameState(
532 ) const {
sky 2012/08/29 17:29:20 Wrap FMB::GetMa.. to the next line, eg: MaximizeBu
Mr4D (OOO till 08-26) 2012/08/29 18:57:34 Done.
533 // When there are no restore bounds, we are in normal mode.
534 if (!ash::GetRestoreBoundsInScreen(
535 frame_->GetWidget()->GetNativeWindow()))
536 return FRAME_STATE_NONE;
537 // The normal maximized test can be used.
538 if (frame_->GetWidget()->IsMaximized())
539 return FRAME_STATE_FULL;
540 // For Left/right maximize we need to check the dimensions.
541 gfx::Rect bounds = frame_->GetWidget()->GetWindowBoundsInScreen();
542 gfx::Rect screen = gfx::Screen::GetDisplayMatching(bounds).work_area();
543 if (bounds.width() < (screen.width() * kMinSnapSizePercent) / 100)
544 return FRAME_STATE_NONE;
545 // We have to be in a maximize mode at this point.
546 DCHECK(bounds.y() == screen.y());
547 DCHECK(bounds.height() >= screen.height());
548 if (bounds.x() == screen.x())
549 return FRAME_STATE_SNAP_LEFT;
550 if (bounds.right() == screen.right())
551 return FRAME_STATE_SNAP_RIGHT;
552 NOTREACHED();
sky 2012/08/29 17:29:20 Won't you hit this if you resize the window horizo
Mr4D (OOO till 08-26) 2012/08/29 18:57:34 This state is still ominous to me and contradicts
553 return FRAME_STATE_NONE;
554 }
555
519 } // namespace ash 556 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698