15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/window_sizer/window_sizer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/shell.h"
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/window_positioner.h"
968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_state.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool WindowSizer::GetBrowserBoundsAsh(gfx::Rect* bounds,
17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                      ui::WindowShowState* show_state) const {
18a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!browser_ ||
19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      browser_->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH)
20a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return false;
21a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool determined = false;
23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (bounds->IsEmpty()) {
24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (browser_->is_type_tabbed()) {
25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      GetTabbedBrowserBoundsAsh(bounds, show_state);
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      determined = true;
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else if (browser_->is_trusted_source()) {
28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      // For trusted popups (v1 apps and system windows), do not use the last
29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      // active window bounds, only use saved or default bounds.
30a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      if (!GetSavedWindowBounds(bounds, show_state))
31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        GetDefaultWindowBounds(GetTargetDisplay(gfx::Rect()), bounds);
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      determined = true;
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else {
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // In Ash, prioritize the last saved |show_state|. If you have questions
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // or comments about this behavior please contact oshima@chromium.org.
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      if (state_provider_) {
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        gfx::Rect ignored_bounds, ignored_work_area;
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        state_provider_->GetPersistentState(&ignored_bounds,
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                            &ignored_work_area,
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                            show_state);
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      }
42a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    }
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else if (browser_->is_type_popup() && bounds->origin().IsOrigin()) {
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // In case of a popup with an 'unspecified' location in ash, we are
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // looking for a good screen location. We are interpreting (0,0) as an
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // unspecified location.
47a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    *bounds = ash::Shell::GetInstance()->window_positioner()->
48a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        GetPopupPosition(*bounds);
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    determined = true;
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (browser_->is_type_tabbed() && *show_state == ui::SHOW_STATE_DEFAULT) {
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    gfx::Display display = screen_->GetDisplayMatching(*bounds);
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    gfx::Rect work_area = display.work_area();
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bounds->AdjustToFit(work_area);
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (*bounds == work_area) {
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // A |browser_| that occupies the whole work area gets maximized.
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // |bounds| returned here become the restore bounds once the window
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // gets maximized after this method returns. Return a sensible default
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      // in order to make restored state visibly different from maximized.
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *show_state = ui::SHOW_STATE_MAXIMIZED;
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *bounds = ash::WindowPositioner::GetDefaultWindowBounds(display);
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      determined = true;
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
65a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return determined;
67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
68a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void WindowSizer::GetTabbedBrowserBoundsAsh(
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    gfx::Rect* bounds_in_screen,
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ui::WindowShowState* show_state) const {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(show_state);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bounds_in_screen);
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(browser_->is_type_tabbed());
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(bounds_in_screen->IsEmpty());
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::WindowShowState passed_show_state = *show_state;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool is_saved_bounds = GetSavedWindowBounds(bounds_in_screen, show_state);
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gfx::Display display;
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (is_saved_bounds) {
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    display = screen_->GetDisplayMatching(*bounds_in_screen);
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else {
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // If there is no saved bounds (hence bounds_in_screen is empty), use the
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // target display.
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    display = target_display_provider_->GetTargetDisplay(screen_,
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                         *bounds_in_screen);
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    *bounds_in_screen = ash::WindowPositioner::GetDefaultWindowBounds(display);
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (browser_->is_session_restore()) {
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // This is a fall-through case when there is no bounds recorded
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // for restored window, and should not be used except for the case
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // above.  The regular path is handled in
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // |WindowSizer::DetermineWindowBoundsAndShowState|.
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Note: How restore bounds/show state data are passed.
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // The restore bounds is passed via |Browser::override_bounds()| in
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // |chrome::GetBrowserWindowBoundsAndShowState()|.
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // The restore state is passed via |Browser::initial_state()| in
1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // |WindowSizer::GetWindowDefaultShowState|.
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bounds_in_screen->AdjustToFit(display.work_area());
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // The |browser_window| is non NULL when this is called after
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // browser's aura window is created.
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  aura::Window* browser_window =
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      browser_->window() ? browser_->window()->GetNativeWindow() : NULL;
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ash::WindowPositioner::GetBoundsAndShowStateForNewWindow(
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      screen_,
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      browser_window,
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      is_saved_bounds,
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      passed_show_state,
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      bounds_in_screen,
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      show_state);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
119