Commit b3fdf35b authored by Mitsuru Oshima's avatar Mitsuru Oshima Committed by Commit Bot

Add frame mode/visibility to AppWindowInfo

* frame mode is either normal, immersive (auto hide) or none if
  the window is frameless.
* frame is visible if the frame is fully visible (normal, maximized),
  or revelaed state in immersive.

Bug: 1021604
Test: covered by unittests
Change-Id: I62f2e176af3d690fb4a8c7da557c0ba522d7eea8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1906951Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarRicardo Quesada <ricardoq@chromium.org>
Commit-Queue: Mitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#714440}
parent eaf9f1d5
......@@ -578,6 +578,13 @@ aura::Window* GetActiveWindow() {
return wm::GetActivationClient(list[0]->GetRootWindow())->GetActiveWindow();
}
bool IsFrameVisible(views::Widget* widget) {
views::NonClientFrameView* frame_view =
widget->non_client_view() ? widget->non_client_view()->frame_view()
: nullptr;
return frame_view && frame_view->GetEnabled() && frame_view->GetVisible();
}
} // namespace
class WindowStateChangeObserver : public aura::WindowObserver {
......@@ -3060,39 +3067,60 @@ AutotestPrivateGetAppWindowListFunction::Run() {
}
// Frame information
auto* widget = views::Widget::GetWidgetForNativeWindow(window);
auto* immersive_controller =
ash::ImmersiveFullscreenController::Get(widget);
// The widget that hosts the immersive frame can be different from the
// application's widget itself. Use the widget from the immersive
// controller to obtain the FrameHeader.
auto* frame_header = ash::FrameHeader::Get(immersive_controller->widget());
window_info.caption_height = frame_header->GetHeaderHeight();
const ash::CaptionButtonModel* button_model =
frame_header->GetCaptionButtonModel();
int caption_button_enabled_status = 0;
int caption_button_visible_status = 0;
constexpr views::CaptionButtonIcon all_button_icons[] = {
views::CAPTION_BUTTON_ICON_MINIMIZE,
views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE,
views::CAPTION_BUTTON_ICON_CLOSE,
views::CAPTION_BUTTON_ICON_LEFT_SNAPPED,
views::CAPTION_BUTTON_ICON_RIGHT_SNAPPED,
views::CAPTION_BUTTON_ICON_BACK,
views::CAPTION_BUTTON_ICON_LOCATION,
views::CAPTION_BUTTON_ICON_MENU,
views::CAPTION_BUTTON_ICON_ZOOM};
for (const auto button : all_button_icons) {
if (button_model->IsEnabled(button))
caption_button_enabled_status |= (1 << button);
if (button_model->IsVisible(button))
caption_button_visible_status |= (1 << button);
auto* immersive_controller = ash::ImmersiveFullscreenController::Get(
views::Widget::GetWidgetForNativeWindow(window));
if (immersive_controller) {
// The widget that hosts the immersive frame can be different from the
// application's widget itself. Use the widget from the immersive
// controller to obtain the FrameHeader.
auto* widget = immersive_controller->widget();
if (immersive_controller->IsEnabled()) {
window_info.frame_mode =
api::autotest_private::FrameMode::FRAME_MODE_IMMERSIVE;
window_info.is_frame_visible = immersive_controller->IsRevealed();
} else {
window_info.frame_mode =
api::autotest_private::FrameMode::FRAME_MODE_NORMAL;
window_info.is_frame_visible = IsFrameVisible(widget);
}
auto* frame_header = ash::FrameHeader::Get(widget);
window_info.caption_height = frame_header->GetHeaderHeight();
const ash::CaptionButtonModel* button_model =
frame_header->GetCaptionButtonModel();
int caption_button_enabled_status = 0;
int caption_button_visible_status = 0;
constexpr views::CaptionButtonIcon all_button_icons[] = {
views::CAPTION_BUTTON_ICON_MINIMIZE,
views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE,
views::CAPTION_BUTTON_ICON_CLOSE,
views::CAPTION_BUTTON_ICON_LEFT_SNAPPED,
views::CAPTION_BUTTON_ICON_RIGHT_SNAPPED,
views::CAPTION_BUTTON_ICON_BACK,
views::CAPTION_BUTTON_ICON_LOCATION,
views::CAPTION_BUTTON_ICON_MENU,
views::CAPTION_BUTTON_ICON_ZOOM};
for (const auto button : all_button_icons) {
if (button_model->IsEnabled(button))
caption_button_enabled_status |= (1 << button);
if (button_model->IsVisible(button))
caption_button_visible_status |= (1 << button);
}
window_info.caption_button_enabled_status = caption_button_enabled_status;
window_info.caption_button_visible_status = caption_button_visible_status;
} else {
auto* widget = views::Widget::GetWidgetForNativeWindow(window);
// All widgets for app windows in chromeos should have a frame with
// immersive controller. Non app windows may not have a frame and
// frame mode will be NONE.
DCHECK(!widget || widget->GetNativeWindow()->type() !=
aura::client::WINDOW_TYPE_NORMAL);
window_info.frame_mode =
api::autotest_private::FrameMode::FRAME_MODE_NONE;
window_info.is_frame_visible = false;
}
window_info.caption_button_enabled_status = caption_button_enabled_status;
window_info.caption_button_visible_status = caption_button_visible_status;
result_list.emplace_back(std::move(window_info));
}
......
......@@ -335,6 +335,12 @@ namespace autotestPrivate {
ExtensionApp
};
// The frame mode of a window. None if the window is framesless.
enum FrameMode {
Normal,
Immersive
};
dictionary AppWindowInfo {
// The identifier of the window. This shouldn't change across the time.
long id;
......@@ -380,6 +386,8 @@ namespace autotestPrivate {
boolean hasCapture;
// Window frame info
FrameMode frameMode;
boolean isFrameVisible;
long captionHeight;
// The bitset of the enabled caption buttons. See
// ui/views/window/caption_button_types.h.
......
......@@ -13,6 +13,10 @@ function newAcceletator(keyCode, shift, control, alt, search) {
return accelerator;
};
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
var defaultTests = [
// logout/restart/shutdown don't do anything as we don't want to kill the
// browser with these tests.
......@@ -646,16 +650,35 @@ var defaultTests = [
window.captionButtonVisibleStatus,
kMinimizeMask | kMaximizeRestoreMask | kCloseMask |
kLeftSnappedMask | kRightSnappedMask);
chrome.test.assertEq('Normal', window.frameMode);
chrome.test.assertTrue(window.isFrameVisible);
var change = new Object();
change.eventType = 'WMEventMaximize';
change.eventType = 'WMEventFullscreen';
chrome.autotestPrivate.setAppWindowState(
window.id,
change,
function(state) {
chrome.test.assertEq(state, 'Maximized');
chrome.test.assertNoLastError();
chrome.test.succeed();
chrome.test.assertEq(state, 'Fullscreen');
chrome.autotestPrivate.getAppWindowList(async function(list) {
var window = list[browserFrameIndex];
chrome.test.assertEq('Immersive', window.frameMode);
chrome.test.assertTrue(window.isFrameVisible);
// Hide animation finishes in 400ms. Wait 2x for safety.
await sleep(800);
chrome.autotestPrivate.getAppWindowList(function(list) {
var window = list[browserFrameIndex];
chrome.test.assertEq('Immersive', window.frameMode);
chrome.test.assertFalse(window.isFrameVisible);
// The frame should still have the same buttons.
chrome.test.assertEq(
window.captionButtonVisibleStatus,
kMinimizeMask | kMaximizeRestoreMask | kCloseMask |
kLeftSnappedMask | kRightSnappedMask);
chrome.test.assertNoLastError();
chrome.test.succeed();
});
});
});
}
chrome.test.assertTrue(-1 != browserFrameIndex);
......@@ -833,9 +856,6 @@ var arcPerformanceTracingTests = [
function arcAppTracingNormal() {
chrome.autotestPrivate.arcAppTracingStart(async function() {
chrome.test.assertNoLastError();
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// We generate 15 frames in test.
await sleep(250);
chrome.autotestPrivate.arcAppTracingStopAndAnalyze(
......
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