// Copyright 2015 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/apps/chrome_native_app_window_views_aura.h" #include #include "apps/ui/views/app_window_frame_view.h" #include "base/macros.h" #include "build/build_config.h" #include "chrome/browser/ui/views/apps/app_window_easy_resize_window_targeter.h" #include "chrome/browser/ui/views/apps/shaped_app_window_targeter.h" #include "chrome/browser/web_applications/web_app.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" #include "ui/base/models/simple_menu_model.h" #include "ui/gfx/image/image_skia.h" #include "ui/views/widget/widget.h" #if defined(OS_LINUX) #include "chrome/browser/shell_integration_linux.h" #endif using extensions::AppWindow; ChromeNativeAppWindowViewsAura::ChromeNativeAppWindowViewsAura() { } ChromeNativeAppWindowViewsAura::~ChromeNativeAppWindowViewsAura() { } ui::WindowShowState ChromeNativeAppWindowViewsAura::GetRestorableState( const ui::WindowShowState restore_state) const { // Whitelist states to return so that invalid and transient states // are not saved and used to restore windows when they are recreated. switch (restore_state) { case ui::SHOW_STATE_NORMAL: case ui::SHOW_STATE_MAXIMIZED: case ui::SHOW_STATE_FULLSCREEN: return restore_state; case ui::SHOW_STATE_DEFAULT: case ui::SHOW_STATE_MINIMIZED: case ui::SHOW_STATE_INACTIVE: case ui::SHOW_STATE_DOCKED: case ui::SHOW_STATE_END: return ui::SHOW_STATE_NORMAL; } return ui::SHOW_STATE_NORMAL; } void ChromeNativeAppWindowViewsAura::OnBeforeWidgetInit( const AppWindow::CreateParams& create_params, views::Widget::InitParams* init_params, views::Widget* widget) { #if defined(OS_LINUX) && !defined(OS_CHROMEOS) std::string app_name = web_app::GenerateApplicationNameFromExtensionId( app_window()->extension_id()); // Set up a custom WM_CLASS for app windows. This allows task switchers in // X11 environments to distinguish them from main browser windows. init_params->wm_class_name = web_app::GetWMClassFromAppName(app_name); init_params->wm_class_class = shell_integration_linux::GetProgramClassName(); const char kX11WindowRoleApp[] = "app"; init_params->wm_role_name = std::string(kX11WindowRoleApp); #endif ChromeNativeAppWindowViews::OnBeforeWidgetInit(create_params, init_params, widget); } views::NonClientFrameView* ChromeNativeAppWindowViewsAura::CreateNonStandardAppFrame() { apps::AppWindowFrameView* frame = new apps::AppWindowFrameView(widget(), this, HasFrameColor(), ActiveFrameColor(), InactiveFrameColor()); frame->Init(); // Install an easy resize window targeter, which ensures that the root window // (not the app) receives mouse events on the edges. aura::Window* window = widget()->GetNativeWindow(); // Add the AppWindowEasyResizeWindowTargeter on the window, not its root // window. The root window does not have a delegate, which is needed to // handle the event in Linux. window->SetEventTargeter( scoped_ptr(new AppWindowEasyResizeWindowTargeter( window, gfx::Insets(frame->resize_inside_bounds_size()), this))); return frame; } ui::WindowShowState ChromeNativeAppWindowViewsAura::GetRestoredState() const { // Use kRestoreShowStateKey in case a window is minimized/hidden. ui::WindowShowState restore_state = widget()->GetNativeWindow()->GetProperty( aura::client::kRestoreShowStateKey); // First normal states are checked. if (IsMaximized()) return ui::SHOW_STATE_MAXIMIZED; if (IsFullscreen()) { return ui::SHOW_STATE_FULLSCREEN; } if (widget()->GetNativeWindow()->GetProperty( aura::client::kShowStateKey) == ui::SHOW_STATE_DOCKED || widget()->GetNativeWindow()->GetProperty( aura::client::kRestoreShowStateKey) == ui::SHOW_STATE_DOCKED) { return ui::SHOW_STATE_DOCKED; } return GetRestorableState(restore_state); } bool ChromeNativeAppWindowViewsAura::IsAlwaysOnTop() const { return widget()->IsAlwaysOnTop(); } void ChromeNativeAppWindowViewsAura::UpdateShape(scoped_ptr region) { bool had_shape = !!shape(); ChromeNativeAppWindowViews::UpdateShape(std::move(region)); aura::Window* native_window = widget()->GetNativeWindow(); if (shape() && !had_shape) { native_window->SetEventTargeter(scoped_ptr( new ShapedAppWindowTargeter(native_window, this))); } else if (!shape() && had_shape) { native_window->SetEventTargeter(scoped_ptr()); } }