#ifndef ASH_WM_MODE_WM_MODE_CONTROLLER_H_
#define ASH_WM_MODE_WM_MODE_CONTROLLER_H_
#include <memory>
#include <optional>
#include <string_view>
#include "ash/ash_export.h"
#include "ash/shell_observer.h"
#include "ash/wm/desks/desks_controller.h"
#include "ash/wm/desks/desks_util.h"
#include "ash/wm_mode/pie_menu_view.h"
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "ui/aura/window_observer.h"
#include "ui/compositor/layer_delegate.h"
#include "ui/compositor/layer_owner.h"
#include "ui/events/event_handler.h"
#include "ui/gfx/geometry/point.h"
#include "ui/views/widget/unique_widget_ptr.h"
namespace aura {
class Window;
}
namespace ui {
class LocatedEvent;
}
namespace ash {
class WindowDimmer;
class ASH_EXPORT WmModeController : public ShellObserver,
public ui::EventHandler,
public ui::LayerOwner,
public ui::LayerDelegate,
public aura::WindowObserver,
public PieMenuView::Delegate,
public DesksController::Observer {
public:
enum PieMenuButtonIds {
kSnapButtonId = 0,
kMoveToDeskButtonId = 1,
kResizeButtonId = 2,
kDeskButtonIdStart = 3,
kDeskButtonIdEnd = kDeskButtonIdStart + desks_util::kDesksUpperLimit - 1,
};
WmModeController();
WmModeController(const WmModeController&) = delete;
WmModeController& operator=(const WmModeController&) = delete;
~WmModeController() override;
static WmModeController* Get();
bool is_active() const { return is_active_; }
aura::Window* selected_window() { return selected_window_; }
views::Widget* pie_menu_widget() { return pie_menu_widget_.get(); }
void Toggle();
void OnRootWindowAdded(aura::Window* root_window) override;
void OnRootWindowWillShutdown(aura::Window* root_window) override;
void OnMouseEvent(ui::MouseEvent* event) override;
void OnTouchEvent(ui::TouchEvent* event) override;
std::string_view GetLogContext() const override;
void OnPaintLayer(const ui::PaintContext& context) override;
void OnDeviceScaleFactorChanged(float old_device_scale_factor,
float new_device_scale_factor) override {}
void OnWindowDestroying(aura::Window* window) override;
void OnPieMenuButtonPressed(int button_id) override;
void OnDeskAdded(const Desk* desk, bool from_undo) override;
void OnDeskRemoved(const Desk* desk) override;
void OnDeskReordered(int old_index, int new_index) override;
void OnDeskActivationChanged(const Desk* activated,
const Desk* deactivated) override;
void OnDeskNameChanged(const Desk* desk,
const std::u16string& new_name) override;
private:
friend class WmModeTests;
void UpdateDimmers();
void UpdateTrayButtons();
void OnLocatedEvent(ui::LocatedEvent* event);
void CreateLayer();
void MaybeChangeRoot(aura::Window* new_root);
void SetSelectedWindow(aura::Window* window);
void ScheduleRepaint();
void BuildPieMenu();
void MaybeRebuildMoveToDeskSubMenu();
bool IsTargetingPieMenu(aura::Window* event_target) const;
aura::Window* GetTopMostWindowAtPoint(
const gfx::Point& screen_location) const;
void MaybeRefreshPieMenu();
void MoveSelectedWindowToDeskAtIndex(int index);
bool is_active_ = false;
raw_ptr<aura::Window> current_root_ = nullptr;
raw_ptr<aura::Window, DanglingUntriaged> selected_window_ = nullptr;
views::UniqueWidgetPtr pie_menu_widget_;
raw_ptr<PieMenuView> pie_menu_view_ = nullptr;
base::flat_map<aura::Window*, std::unique_ptr<WindowDimmer>> dimmers_;
std::optional<gfx::Point> last_release_event_screen_point_;
};
}
#endif