// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WM_MULTI_DISPLAY_PERSISTENT_WINDOW_CONTROLLER_H_
#define ASH_WM_MULTI_DISPLAY_PERSISTENT_WINDOW_CONTROLLER_H_
#include <unordered_map>
#include "ash/ash_export.h"
#include "ash/public/cpp/session/session_observer.h"
#include "base/functional/callback.h"
#include "ui/aura/window_tracker.h"
#include "ui/display/display_observer.h"
namespace ash {
// Observes display changes and saves/restores window bounds persistently in
// multi-displays scenario. It will observe and restore window bounds
// persistently on screen rotation as well.
class ASH_EXPORT PersistentWindowController : public display::DisplayObserver,
public SessionObserver {
public:
// Public so it can be used by unit tests.
constexpr static char kNumOfWindowsRestoredOnDisplayAdded[] =
"Ash.PersistentWindow.NumOfWindowsRestoredOnDisplayAdded";
constexpr static char kNumOfWindowsRestoredOnScreenRotation[] =
"Ash.PersistentWindow.NumOfWindowsRestoredOnScreenRotation";
PersistentWindowController();
PersistentWindowController(const PersistentWindowController&) = delete;
PersistentWindowController& operator=(const PersistentWindowController&) =
delete;
~PersistentWindowController() override;
private:
// display::DisplayObserver:
void OnWillProcessDisplayChanges() override;
void OnDisplayAdded(const display::Display& new_display) override;
void OnDisplayRemoved(const display::Display& old_display) override;
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override;
void OnDidProcessDisplayChanges() override;
// SessionObserver:
void OnFirstSessionStarted() override;
// Called when restoring persistent window placement on display added.
void MaybeRestorePersistentWindowBoundsOnDisplayAdded();
// Called when restoring persistent window placement on screen rotation.
void MaybeRestorePersistentWindowBoundsOnScreenRotation();
// Callback binded on display added and run on display changes are processed.
base::OnceClosure display_added_restore_callback_;
// Callback binded on display rotation happens and run on display changes are
// processed.
base::OnceClosure screen_rotation_restore_callback_;
// Temporary storage that stores windows that may need persistent info
// stored on display removal. Cleared when display changes are processed.
aura::WindowTracker need_persistent_info_windows_;
// Tracking the screen orientation of each display before screen rotation
// take effect. Key is the display id, value is true if the display is in
// the landscape orientation, otherwise false. This is used to help restore
// windows' bounds on screen rotation. It is needed since the target rotation
// already changed even inside OnWillProcessDisplayChanges, which means the
// screen orientation checked there will be the updated orientation when
// screen rotation happens. So we get the initial screen orientation
// OnFirstSessionStarted and store the updated ones inside
// OnDidProcessDisplayChanges.
std::unordered_map<int64_t, bool> is_landscape_orientation_map_;
// Register for DisplayObserver callbacks.
display::ScopedDisplayObserver display_observer_{this};
};
} // namespace ash
#endif // ASH_WM_MULTI_DISPLAY_PERSISTENT_WINDOW_CONTROLLER_H_