Commit 09492e79 authored by jackhou@chromium.org's avatar jackhou@chromium.org

[Win Aero] Correctly set the minimum window size.

This also fixes the value of [inner|outer]Bounds.[width|height]
to account for the border added by
AppWindowDesktopWindowTreeHostWin::GetClientAreaInsets

BUG=394567, 395929

Review URL: https://codereview.chromium.org/405323002

Cr-Commit-Position: refs/heads/master@{#289257}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289257 0039d316-1c4b-4281-b951-d872f2087c98
parent 2de78461
...@@ -11,6 +11,15 @@ ...@@ -11,6 +11,15 @@
#include "base/mac/mac_util.h" #include "base/mac/mac_util.h"
#endif #endif
#if defined(OS_WIN)
#include <windows.h>
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
#include "ui/views/win/hwnd_message_handler_delegate.h"
#include "ui/views/win/hwnd_util.h"
#endif
using apps::NativeAppWindow; using apps::NativeAppWindow;
// Helper class that has to be created in the stack to check if the fullscreen // Helper class that has to be created in the stack to check if the fullscreen
...@@ -69,6 +78,9 @@ class AppWindowInteractiveTest : public extensions::PlatformAppBrowserTest { ...@@ -69,6 +78,9 @@ class AppWindowInteractiveTest : public extensions::PlatformAppBrowserTest {
content::RunAllPendingInMessageLoop(); content::RunAllPendingInMessageLoop();
} }
} }
// This test is a method so that we can test with each frame type.
void TestOuterBoundsHelper(const std::string& frame_type);
}; };
IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, ESCLeavesFullscreenWindow) { IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, ESCLeavesFullscreenWindow) {
...@@ -318,6 +330,85 @@ IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, ...@@ -318,6 +330,85 @@ IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
EXPECT_TRUE(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen()); EXPECT_TRUE(GetFirstAppWindow()->GetBaseWindow()->IsFullscreen());
} }
IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest, TestInnerBounds) {
ASSERT_TRUE(RunAppWindowInteractiveTest("testInnerBounds")) << message_;
}
void AppWindowInteractiveTest::TestOuterBoundsHelper(
const std::string& frame_type) {
ExtensionTestMessageListener launched_listener("Launched", true);
const extensions::Extension* app =
LoadAndLaunchPlatformApp("outer_bounds", &launched_listener);
launched_listener.Reply(frame_type);
launched_listener.Reset();
ASSERT_TRUE(launched_listener.WaitUntilSatisfied());
apps::AppWindow* window = GetFirstAppWindowForApp(app->id());
gfx::Rect window_bounds;
gfx::Size min_size, max_size;
#if defined(OS_WIN)
// Get the bounds from the HWND.
HWND hwnd = views::HWNDForNativeWindow(window->GetNativeWindow());
RECT rect;
::GetWindowRect(hwnd, &rect);
window_bounds = gfx::Rect(
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
// HWNDMessageHandler calls this when responding to WM_GETMINMAXSIZE, so it's
// the closest to what the window will see.
views::HWNDMessageHandlerDelegate* host =
static_cast<views::HWNDMessageHandlerDelegate*>(
static_cast<views::DesktopWindowTreeHostWin*>(
aura::WindowTreeHost::GetForAcceleratedWidget(hwnd)));
host->GetMinMaxSize(&min_size, &max_size);
// Note that this does not include the the client area insets so we need to
// add them.
gfx::Insets insets;
host->GetClientAreaInsets(&insets);
min_size = gfx::Size(min_size.width() + insets.left() + insets.right(),
min_size.height() + insets.top() + insets.bottom());
max_size = gfx::Size(
max_size.width() ? max_size.width() + insets.left() + insets.right() : 0,
max_size.height() ? max_size.height() + insets.top() + insets.bottom()
: 0);
#endif // defined(OS_WIN)
// These match the values in the outer_bounds/test.js
EXPECT_EQ(gfx::Rect(10, 11, 300, 301), window_bounds);
EXPECT_EQ(window->GetBaseWindow()->GetBounds(), window_bounds);
EXPECT_EQ(200, min_size.width());
EXPECT_EQ(201, min_size.height());
EXPECT_EQ(400, max_size.width());
EXPECT_EQ(401, max_size.height());
}
// TODO(jackhou): Make this test work for other OSes.
#if !defined(OS_WIN)
#define MAYBE_TestOuterBoundsFrameChrome DISABLED_TestOuterBoundsFrameChrome
#define MAYBE_TestOuterBoundsFrameNone DISABLED_TestOuterBoundsFrameNone
#define MAYBE_TestOuterBoundsFrameColor DISABLED_TestOuterBoundsFrameColor
#else
#define MAYBE_TestOuterBoundsFrameChrome TestOuterBoundsFrameChrome
#define MAYBE_TestOuterBoundsFrameNone TestOuterBoundsFrameNone
#define MAYBE_TestOuterBoundsFrameColor TestOuterBoundsFrameColor
#endif
// Test that the outer bounds match that of the native window.
IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
MAYBE_TestOuterBoundsFrameChrome) {
TestOuterBoundsHelper("chrome");
}
IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
MAYBE_TestOuterBoundsFrameNone) {
TestOuterBoundsHelper("none");
}
IN_PROC_BROWSER_TEST_F(AppWindowInteractiveTest,
MAYBE_TestOuterBoundsFrameColor) {
TestOuterBoundsHelper("color");
}
// This test does not work on Linux Aura because ShowInactive() is not // This test does not work on Linux Aura because ShowInactive() is not
// implemented. See http://crbug.com/325142 // implemented. See http://crbug.com/325142
// It also does not work on Windows because of the document being focused even // It also does not work on Windows because of the document being focused even
......
...@@ -35,12 +35,12 @@ bool AppWindowDesktopWindowTreeHostWin::GetClientAreaInsets( ...@@ -35,12 +35,12 @@ bool AppWindowDesktopWindowTreeHostWin::GetClientAreaInsets(
// This tells Windows that most of the window is a client area, meaning Chrome // This tells Windows that most of the window is a client area, meaning Chrome
// will draw it. Windows still fills in the glass bits because of the // will draw it. Windows still fills in the glass bits because of the
// DwmExtendFrameIntoClientArea call in |UpdateDWMFrame|. // DwmExtendFrameIntoClientArea call in |UpdateDWMFrame|.
// The 1 pixel edge is left on the sides and bottom as without this // Without this 1 pixel offset on the right and bottom:
// * windows paint in a more standard way, and // * windows paint in a more standard way, and
// * get weird black bars at the top when maximized in multiple monitor // * get weird black bars at the top when maximized in multiple monitor
// configurations. // configurations.
int border_thickness = 1; int border_thickness = 1;
insets->Set(0, border_thickness, border_thickness, border_thickness); insets->Set(0, 0, border_thickness, border_thickness);
return true; return true;
} }
......
...@@ -56,6 +56,10 @@ gfx::Rect GlassAppWindowFrameViewWin::GetBoundsForClientView() const { ...@@ -56,6 +56,10 @@ gfx::Rect GlassAppWindowFrameViewWin::GetBoundsForClientView() const {
gfx::Rect GlassAppWindowFrameViewWin::GetWindowBoundsForClientBounds( gfx::Rect GlassAppWindowFrameViewWin::GetWindowBoundsForClientBounds(
const gfx::Rect& client_bounds) const { const gfx::Rect& client_bounds) const {
gfx::Insets insets = GetGlassInsets(); gfx::Insets insets = GetGlassInsets();
// Our bounds are not the same as the window's due to the offset added by
// AppWindowDesktopWindowTreeHostWin::GetClientAreaInsets. So account for it
// here.
insets += gfx::Insets(0, 0, 1, 1);
return gfx::Rect(client_bounds.x() - insets.left(), return gfx::Rect(client_bounds.x() - insets.left(),
client_bounds.y() - insets.top(), client_bounds.y() - insets.top(),
client_bounds.width() + insets.left() + insets.right(), client_bounds.width() + insets.left() + insets.right(),
...@@ -114,8 +118,10 @@ const char* GlassAppWindowFrameViewWin::GetClassName() const { ...@@ -114,8 +118,10 @@ const char* GlassAppWindowFrameViewWin::GetClassName() const {
gfx::Size GlassAppWindowFrameViewWin::GetMinimumSize() const { gfx::Size GlassAppWindowFrameViewWin::GetMinimumSize() const {
gfx::Size min_size = widget_->client_view()->GetMinimumSize(); gfx::Size min_size = widget_->client_view()->GetMinimumSize();
gfx::Rect client_bounds = GetBoundsForClientView(); gfx::Rect client_bounds = GetBoundsForClientView();
min_size.Enlarge(0, client_bounds.y()); min_size.Enlarge(width() - client_bounds.width(),
height() - client_bounds.height());
return min_size; return min_size;
} }
......
<!--
* Copyright (c) 2012 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.
-->
<html>
<body>
<script src="main.js"></script>
</body>
</html>
{
"name": "Platform App Test: outer bounds platform app",
"version": "1",
"app": {
"background": {
"scripts": ["test.js"]
}
}
}
// Copyright 2014 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.
chrome.app.runtime.onLaunched.addListener(function() {
chrome.test.sendMessage('Launched', function (response) {
var frameType = response == 'color' ? { color: '#ff0000' } : response;
chrome.app.window.create('main.html', {
frame: frameType,
outerBounds: {
left: 10,
top: 11,
width: 300,
height: 301,
minWidth: 200,
minHeight: 201,
maxWidth: 400,
maxHeight: 401
}
}, function () {
// Send this again as the test is waiting for the window to be ready.
chrome.test.sendMessage('Launched');
});
});
});
...@@ -49,6 +49,58 @@ function testWindowNeverGetsFocus(win) { ...@@ -49,6 +49,58 @@ function testWindowNeverGetsFocus(win) {
}); });
} }
// Test that the window's content size is the same as our inner bounds.
// This has to be an interactive test because contentWindow.innerWidth|Height is
// sometimes 0 in the browser test due to an unidentified race condition.
function testInnerBounds() {
var innerBounds = {
width: 300,
height: 301,
minWidth: 200,
minHeight: 201,
maxWidth: 400,
maxHeight: 401
};
function assertInnerBounds(win) {
chrome.test.assertEq(300, win.contentWindow.innerWidth);
chrome.test.assertEq(301, win.contentWindow.innerHeight);
chrome.test.assertEq(300, win.innerBounds.width);
chrome.test.assertEq(301, win.innerBounds.height);
chrome.test.assertEq(200, win.innerBounds.minWidth);
chrome.test.assertEq(201, win.innerBounds.minHeight);
chrome.test.assertEq(400, win.innerBounds.maxWidth);
chrome.test.assertEq(401, win.innerBounds.maxHeight);
}
chrome.test.runTests([
function createFrameChrome() {
chrome.app.window.create('test.html', {
innerBounds: innerBounds
}, callbackPass(function (win) {
assertInnerBounds(win);
}));
},
function createFrameNone() {
chrome.app.window.create('test.html', {
frame: 'none',
innerBounds: innerBounds
}, callbackPass(function (win) {
assertInnerBounds(win);
}));
},
function createFrameColor() {
chrome.app.window.create('test.html', {
frame: {color: '#ff0000'},
innerBounds: innerBounds
}, callbackPass(function (win) {
assertInnerBounds(win);
}));
}
]);
}
function testCreate() { function testCreate() {
chrome.test.runTests([ chrome.test.runTests([
function createUnfocusedWindow() { function createUnfocusedWindow() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment