#ifndef MIR_EXAMPLE_BASIC_WINDOW_MANAGER_H_
#define MIR_EXAMPLE_BASIC_WINDOW_MANAGER_H_
#include <map>
#include <mutex>
{
namespace examples
{
class WindowManagerTools
{
public:
using SurfaceInfoMap = std::map<std::weak_ptr<scene::Surface>, SurfaceInfo, std::owner_less<std::weak_ptr<scene::Surface>>>;
using SessionInfoMap = std::map<std::weak_ptr<scene::Session>, SessionInfo, std::owner_less<std::weak_ptr<scene::Session>>>;
virtual auto find_session(std::function<
bool(SessionInfo
const& info)>
const& predicate)
-> std::shared_ptr<scene::Session> = 0;
virtual auto info_for(std::weak_ptr<scene::Session>
const& session)
const -> SessionInfo& = 0;
virtual auto info_for(std::weak_ptr<scene::Surface>
const& surface)
const -> SurfaceInfo& = 0;
std::shared_ptr<scene::Session> const& focus,
std::shared_ptr<scene::Surface> const& surface) = 0;
virtual auto surface_at(geometry::Point cursor)
const -> std::shared_ptr<scene::Surface> = 0;
virtual void forget(std::weak_ptr<scene::Surface>
const& surface) = 0;
virtual void raise_tree(std::shared_ptr<scene::Surface>
const& root) = 0;
};
class WindowManagementPolicy
{
public:
virtual void handle_session_info_updated(
SessionInfoMap& session_info, geometry::Rectangles
const& displays) = 0;
virtual void handle_displays_updated(
SessionInfoMap& session_info, geometry::Rectangles
const& displays) = 0;
virtual auto handle_place_new_surface(
std::shared_ptr<scene::Session> const& session,
scene::SurfaceCreationParameters const& request_parameters)
-> scene::SurfaceCreationParameters = 0;
virtual void handle_new_surface(std::shared_ptr<scene::Session> const& session, std::shared_ptr<scene::Surface> const& surface) = 0;
virtual void handle_modify_surface(
std::shared_ptr<scene::Session> const& session,
std::shared_ptr<scene::Surface> const& surface,
shell::SurfaceSpecification const& modifications) = 0;
virtual void handle_delete_surface(std::shared_ptr<scene::Session> const& session, std::weak_ptr<scene::Surface> const& surface) = 0;
virtual int handle_set_state(std::shared_ptr<scene::Surface>
const& surface,
MirWindowState value) = 0;
virtual void generate_decorations_for(
std::shared_ptr<scene::Session> const& session, std::shared_ptr<scene::Surface> const& surface,
std::function<
frontend::SurfaceId(std::shared_ptr<scene::Session>
const&, scene::SurfaceCreationParameters
const&)>
const& build) = 0;
virtual void handle_raise_surface(
std::shared_ptr<scene::Session> const& session,
std::shared_ptr<scene::Surface> const& surface) = 0;
virtual ~WindowManagementPolicy() = default;
WindowManagementPolicy() = default;
WindowManagementPolicy(WindowManagementPolicy const&) = delete;
WindowManagementPolicy&
operator=(WindowManagementPolicy
const&) =
delete;
};
class BasicWindowManager : public virtual shell::WindowManager,
{
protected:
BasicWindowManager(
shell::FocusController* focus_controller,
std::unique_ptr<WindowManagementPolicy> policy);
public:
void add_session(std::shared_ptr<scene::Session> const& session) override;
void remove_session(std::shared_ptr<scene::Session> const& session) override;
auto add_surface(
std::shared_ptr<scene::Session> const& session,
scene::SurfaceCreationParameters const& params,
std::function<
frontend::SurfaceId(std::shared_ptr<scene::Session>
const& session, scene::SurfaceCreationParameters
const& params)>
const& build)
void modify_surface(
std::shared_ptr<scene::Session> const& session,
std::shared_ptr<scene::Surface> const& surface,
shell::SurfaceSpecification const& modifications) override;
void remove_surface(
std::shared_ptr<scene::Session> const& session,
std::weak_ptr<scene::Surface> const& surface) override;
void forget(std::weak_ptr<scene::Surface>
const& surface)
override;
void add_display(geometry::Rectangle const& area) override;
void remove_display(geometry::Rectangle const& area) override;
void handle_raise_surface(
std::shared_ptr<scene::Session> const& session,
std::shared_ptr<scene::Surface> const& surface,
uint64_t timestamp) override;
int set_surface_attribute(
std::shared_ptr<scene::Session> const& ,
std::shared_ptr<scene::Surface> const& surface,
int value) override;
auto find_session(std::function<
bool(SessionInfo
const& info)>
const& predicate)
-> std::shared_ptr<scene::Session> override;
auto info_for(std::weak_ptr<scene::Session>
const& session)
const -> SessionInfo&
override;
auto info_for(std::weak_ptr<scene::Surface>
const& surface)
const -> SurfaceInfo&
override;
std::shared_ptr<scene::Session> const& focus,
std::shared_ptr<scene::Surface> const& surface) override;
auto surface_at(geometry::Point cursor)
const -> std::shared_ptr<scene::Surface>
override;
void raise_tree(std::shared_ptr<scene::Surface>
const& root)
override;
private:
shell::FocusController* const focus_controller;
std::unique_ptr<WindowManagementPolicy> const policy;
std::mutex mutex;
geometry::Rectangles displays;
geometry::Point cursor;
uint64_t last_input_event_timestamp{0};
};
template<typename WMPolicy>
{
public:
template <typename... PolicyArgs>
shell::FocusController* focus_controller,
PolicyArgs&&... policy_args) :
BasicWindowManager(
focus_controller,
build_policy(std::forward<PolicyArgs>(policy_args)...))
{
}
private:
template <typename... PolicyArgs>
auto build_policy(PolicyArgs&&... policy_args)
-> std::unique_ptr<WMPolicy>
{
return std::unique_ptr<WMPolicy>(
new WMPolicy(this, std::forward<PolicyArgs>(policy_args)...));
}
};
}
}
#endif