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() { ...@@ -578,6 +578,13 @@ aura::Window* GetActiveWindow() {
return wm::GetActivationClient(list[0]->GetRootWindow())->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 } // namespace
class WindowStateChangeObserver : public aura::WindowObserver { class WindowStateChangeObserver : public aura::WindowObserver {
...@@ -3060,39 +3067,60 @@ AutotestPrivateGetAppWindowListFunction::Run() { ...@@ -3060,39 +3067,60 @@ AutotestPrivateGetAppWindowListFunction::Run() {
} }
// Frame information // Frame information
auto* widget = views::Widget::GetWidgetForNativeWindow(window); auto* immersive_controller = ash::ImmersiveFullscreenController::Get(
auto* immersive_controller = views::Widget::GetWidgetForNativeWindow(window));
ash::ImmersiveFullscreenController::Get(widget); if (immersive_controller) {
// The widget that hosts the immersive frame can be different from the // The widget that hosts the immersive frame can be different from the
// application's widget itself. Use the widget from the immersive // application's widget itself. Use the widget from the immersive
// controller to obtain the FrameHeader. // controller to obtain the FrameHeader.
auto* frame_header = ash::FrameHeader::Get(immersive_controller->widget()); auto* widget = immersive_controller->widget();
window_info.caption_height = frame_header->GetHeaderHeight(); if (immersive_controller->IsEnabled()) {
window_info.frame_mode =
const ash::CaptionButtonModel* button_model = api::autotest_private::FrameMode::FRAME_MODE_IMMERSIVE;
frame_header->GetCaptionButtonModel(); window_info.is_frame_visible = immersive_controller->IsRevealed();
int caption_button_enabled_status = 0; } else {
int caption_button_visible_status = 0; window_info.frame_mode =
api::autotest_private::FrameMode::FRAME_MODE_NORMAL;
constexpr views::CaptionButtonIcon all_button_icons[] = { window_info.is_frame_visible = IsFrameVisible(widget);
views::CAPTION_BUTTON_ICON_MINIMIZE, }
views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE, auto* frame_header = ash::FrameHeader::Get(widget);
views::CAPTION_BUTTON_ICON_CLOSE, window_info.caption_height = frame_header->GetHeaderHeight();
views::CAPTION_BUTTON_ICON_LEFT_SNAPPED,
views::CAPTION_BUTTON_ICON_RIGHT_SNAPPED, const ash::CaptionButtonModel* button_model =
views::CAPTION_BUTTON_ICON_BACK, frame_header->GetCaptionButtonModel();
views::CAPTION_BUTTON_ICON_LOCATION, int caption_button_enabled_status = 0;
views::CAPTION_BUTTON_ICON_MENU, int caption_button_visible_status = 0;
views::CAPTION_BUTTON_ICON_ZOOM};
constexpr views::CaptionButtonIcon all_button_icons[] = {
for (const auto button : all_button_icons) { views::CAPTION_BUTTON_ICON_MINIMIZE,
if (button_model->IsEnabled(button)) views::CAPTION_BUTTON_ICON_MAXIMIZE_RESTORE,
caption_button_enabled_status |= (1 << button); views::CAPTION_BUTTON_ICON_CLOSE,
if (button_model->IsVisible(button)) views::CAPTION_BUTTON_ICON_LEFT_SNAPPED,
caption_button_visible_status |= (1 << button); 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)); result_list.emplace_back(std::move(window_info));
} }
......
...@@ -335,6 +335,12 @@ namespace autotestPrivate { ...@@ -335,6 +335,12 @@ namespace autotestPrivate {
ExtensionApp ExtensionApp
}; };
// The frame mode of a window. None if the window is framesless.
enum FrameMode {
Normal,
Immersive
};
dictionary AppWindowInfo { dictionary AppWindowInfo {
// The identifier of the window. This shouldn't change across the time. // The identifier of the window. This shouldn't change across the time.
long id; long id;
...@@ -380,6 +386,8 @@ namespace autotestPrivate { ...@@ -380,6 +386,8 @@ namespace autotestPrivate {
boolean hasCapture; boolean hasCapture;
// Window frame info // Window frame info
FrameMode frameMode;
boolean isFrameVisible;
long captionHeight; long captionHeight;
// The bitset of the enabled caption buttons. See // The bitset of the enabled caption buttons. See
// ui/views/window/caption_button_types.h. // ui/views/window/caption_button_types.h.
......
...@@ -13,6 +13,10 @@ function newAcceletator(keyCode, shift, control, alt, search) { ...@@ -13,6 +13,10 @@ function newAcceletator(keyCode, shift, control, alt, search) {
return accelerator; return accelerator;
}; };
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
var defaultTests = [ var defaultTests = [
// logout/restart/shutdown don't do anything as we don't want to kill the // logout/restart/shutdown don't do anything as we don't want to kill the
// browser with these tests. // browser with these tests.
...@@ -646,16 +650,35 @@ var defaultTests = [ ...@@ -646,16 +650,35 @@ var defaultTests = [
window.captionButtonVisibleStatus, window.captionButtonVisibleStatus,
kMinimizeMask | kMaximizeRestoreMask | kCloseMask | kMinimizeMask | kMaximizeRestoreMask | kCloseMask |
kLeftSnappedMask | kRightSnappedMask); kLeftSnappedMask | kRightSnappedMask);
chrome.test.assertEq('Normal', window.frameMode);
chrome.test.assertTrue(window.isFrameVisible);
var change = new Object(); var change = new Object();
change.eventType = 'WMEventMaximize'; change.eventType = 'WMEventFullscreen';
chrome.autotestPrivate.setAppWindowState( chrome.autotestPrivate.setAppWindowState(
window.id, window.id,
change, change,
function(state) { function(state) {
chrome.test.assertEq(state, 'Maximized'); chrome.test.assertEq(state, 'Fullscreen');
chrome.test.assertNoLastError(); chrome.autotestPrivate.getAppWindowList(async function(list) {
chrome.test.succeed(); 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); chrome.test.assertTrue(-1 != browserFrameIndex);
...@@ -833,9 +856,6 @@ var arcPerformanceTracingTests = [ ...@@ -833,9 +856,6 @@ var arcPerformanceTracingTests = [
function arcAppTracingNormal() { function arcAppTracingNormal() {
chrome.autotestPrivate.arcAppTracingStart(async function() { chrome.autotestPrivate.arcAppTracingStart(async function() {
chrome.test.assertNoLastError(); chrome.test.assertNoLastError();
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// We generate 15 frames in test. // We generate 15 frames in test.
await sleep(250); await sleep(250);
chrome.autotestPrivate.arcAppTracingStopAndAnalyze( 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