blob: 62b9fab55a16fbee9b028bf132ea5147040281f8 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "headless/lib/browser/headless_window.h"
#include "ui/display/screen.h"
namespace headless {
HeadlessWindow::HeadlessWindow(HeadlessWindowDelegate* delegate)
: delegate_(delegate) {
CHECK(delegate);
}
HeadlessWindow::~HeadlessWindow() = default;
void HeadlessWindow::SetVisible(bool visible) {
UpdateVisible(visible);
}
void HeadlessWindow::SetBounds(const gfx::Rect& bounds) {
UpdateBounds(bounds);
}
void HeadlessWindow::SetWindowState(HeadlessWindowState window_state) {
if (window_state == window_state_) {
return;
}
// Ignore transitions to states other than normal while in full screen state.
// See http://crbug.com/429423225.
if (window_state_ == HeadlessWindowState::kFullscreen &&
window_state != HeadlessWindowState::kNormal) {
return;
}
bool set_visible = false;
switch (window_state) {
case HeadlessWindowState::kNormal:
RestoreWindowBounds();
if (window_state_ == HeadlessWindowState::kMinimized) {
set_visible = true;
}
break;
case HeadlessWindowState::kMinimized:
// Minimized windows are hidden but retain their normal size and position.
if (visible_) {
UpdateVisible(/*visible*/ false);
}
RestoreWindowBounds();
break;
case HeadlessWindowState::kMaximized:
if (window_state_ != HeadlessWindowState::kFullscreen) {
restored_bounds_ = bounds_;
}
ZoomWindowBounds();
set_visible = true;
break;
case HeadlessWindowState::kFullscreen:
if (window_state_ != HeadlessWindowState::kMaximized) {
restored_bounds_ = bounds_;
}
ZoomWindowBounds();
set_visible = true;
break;
}
UpdateWindowState(window_state);
// Make window visible after the window state has been changed.
if (set_visible && !visible_) {
UpdateVisible(/*visible*/ true);
}
}
void HeadlessWindow::ZoomWindowBounds() {
const gfx::Rect zoomed_bounds =
display::Screen::Get()->GetDisplayMatching(bounds_).work_area();
UpdateBounds(zoomed_bounds);
}
void HeadlessWindow::RestoreWindowBounds() {
if (restored_bounds_) {
const gfx::Rect restored_bounds = restored_bounds_.value();
restored_bounds_.reset();
UpdateBounds(restored_bounds);
}
}
void HeadlessWindow::UpdateVisible(bool visible) {
if (visible != visible_) {
visible_ = visible;
delegate_->OnVisibilityChanged();
}
}
void HeadlessWindow::UpdateBounds(const gfx::Rect& bounds) {
if (bounds != bounds_) {
const gfx::Rect old_bounds = bounds_;
bounds_ = bounds;
delegate_->OnBoundsChanged({old_bounds});
}
}
void HeadlessWindow::UpdateWindowState(HeadlessWindowState window_state) {
if (window_state != window_state_) {
const HeadlessWindowState old_window_state = window_state_;
window_state_ = window_state;
delegate_->OnWindowStateChanged(old_window_state);
}
}
} // namespace headless