blob: acf07bf935d12a8ec261bd4bfb99c9c42bd22dd0 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/frame/browser_frame_ash.h"
#include <memory>
#include "ash/public/cpp/window_properties.h"
#include "ash/public/cpp/window_state_type.h"
#include "ash/shell.h"
#include "ash/wm/window_properties.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_state_delegate.h"
#include "ash/wm/window_util.h"
#include "base/macros.h"
#include "build/build_config.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/views/view.h"
namespace {
// BrowserWindowStateDelegate class handles a user's fullscreen
// request (Shift+F4/F4).
class BrowserWindowStateDelegate : public ash::wm::WindowStateDelegate {
public:
explicit BrowserWindowStateDelegate(Browser* browser)
: browser_(browser) {
DCHECK(browser_);
}
~BrowserWindowStateDelegate() override {}
// Overridden from ash::wm::WindowStateDelegate.
bool ToggleFullscreen(ash::wm::WindowState* window_state) override {
DCHECK(window_state->IsFullscreen() || window_state->CanMaximize());
// Windows which cannot be maximized should not be fullscreened.
if (!window_state->IsFullscreen() && !window_state->CanMaximize())
return true;
chrome::ToggleFullscreenMode(browser_);
return true;
}
private:
Browser* browser_; // not owned.
DISALLOW_COPY_AND_ASSIGN(BrowserWindowStateDelegate);
};
} // namespace
///////////////////////////////////////////////////////////////////////////////
// BrowserFrameAsh, public:
BrowserFrameAsh::BrowserFrameAsh(BrowserFrame* browser_frame,
BrowserView* browser_view)
: views::NativeWidgetAura(browser_frame),
browser_view_(browser_view) {
GetNativeWindow()->SetName("BrowserFrameAsh");
Browser* browser = browser_view->browser();
// Turn on auto window management if we don't need an explicit bounds.
// This way the requested bounds are honored.
if (!browser->bounds_overridden() && !browser->is_session_restore())
SetWindowAutoManaged();
}
BrowserFrameAsh::~BrowserFrameAsh() {}
///////////////////////////////////////////////////////////////////////////////
// BrowserFrameAsh, views::NativeWidgetAura overrides:
void BrowserFrameAsh::OnWidgetInitDone() {
Browser* browser = browser_view_->browser();
ash::wm::WindowState* window_state =
ash::wm::GetWindowState(GetNativeWindow());
window_state->SetDelegate(
std::make_unique<BrowserWindowStateDelegate>(browser));
// For legacy reasons v1 apps (like Secure Shell) are allowed to consume keys
// like brightness, volume, etc. Otherwise these keys are handled by the
// Ash window manager.
window_state->SetCanConsumeSystemKeys(browser->is_app());
}
void BrowserFrameAsh::OnBoundsChanged(const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
NativeWidgetAura::OnBoundsChanged(old_bounds, new_bounds);
if (GetNativeWindow()->transparent()) {
GetNativeWindow()->SetOpaqueRegionsForOcclusion(
{gfx::Rect(new_bounds.size())});
}
}
void BrowserFrameAsh::OnWindowTargetVisibilityChanged(bool visible) {
if (visible) {
// Once the window has been shown we know the requested bounds
// (if provided) have been honored and we can switch on window management.
SetWindowAutoManaged();
}
views::NativeWidgetAura::OnWindowTargetVisibilityChanged(visible);
}
////////////////////////////////////////////////////////////////////////////////
// BrowserFrameAsh, NativeBrowserFrame implementation:
bool BrowserFrameAsh::ShouldSaveWindowPlacement() const {
return nullptr == GetWidget()->GetNativeWindow()->GetProperty(
ash::kRestoreBoundsOverrideKey);
}
void BrowserFrameAsh::GetWindowPlacement(
gfx::Rect* bounds,
ui::WindowShowState* show_state) const {
gfx::Rect* override_bounds = GetWidget()->GetNativeWindow()->GetProperty(
ash::kRestoreBoundsOverrideKey);
if (override_bounds && !override_bounds->IsEmpty()) {
*bounds = *override_bounds;
*show_state =
ash::ToWindowShowState(GetWidget()->GetNativeWindow()->GetProperty(
ash::kRestoreWindowStateTypeOverrideKey));
} else {
*bounds = GetWidget()->GetRestoredBounds();
*show_state = GetWidget()->GetNativeWindow()->GetProperty(
aura::client::kShowStateKey);
}
// Session restore might be unable to correctly restore other states.
// For the record, https://crbug.com/396272
if (*show_state != ui::SHOW_STATE_MAXIMIZED &&
*show_state != ui::SHOW_STATE_MINIMIZED) {
*show_state = ui::SHOW_STATE_NORMAL;
}
}
content::KeyboardEventProcessingResult BrowserFrameAsh::PreHandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) {
return content::KeyboardEventProcessingResult::NOT_HANDLED;
}
bool BrowserFrameAsh::HandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) {
return false;
}
views::Widget::InitParams BrowserFrameAsh::GetWidgetParams() {
views::Widget::InitParams params;
params.native_widget = this;
params.context = ash::Shell::GetPrimaryRootWindow();
return params;
}
bool BrowserFrameAsh::UseCustomFrame() const {
return true;
}
bool BrowserFrameAsh::UsesNativeSystemMenu() const {
return false;
}
int BrowserFrameAsh::GetMinimizeButtonOffset() const {
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// BrowserFrameAsh, private:
void BrowserFrameAsh::SetWindowAutoManaged() {
// For browser window in Chrome OS, we should only enable the auto window
// management logic for tabbed browser.
if (!browser_view_->browser()->is_type_popup())
GetNativeWindow()->SetProperty(ash::kWindowPositionManagedTypeKey, true);
}