mirror of
https://github.com/miracle-wm-org/miracle-wm.git
synced 2024-11-29 16:39:40 +03:00
refactor: a Container is used as the active element instead of a miral::Window (#201)
This commit is contained in:
parent
16047a0f03
commit
ea33fb1c72
@ -19,10 +19,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define MIRACLE_WM_COMPOSITOR_STATE_H
|
||||
|
||||
#include <mir/geometry/point.h>
|
||||
#include <miral/window.h>
|
||||
#include <memory>
|
||||
|
||||
namespace miracle
|
||||
{
|
||||
class Container;
|
||||
|
||||
enum class WindowManagerMode
|
||||
{
|
||||
normal = 0,
|
||||
@ -37,7 +39,7 @@ struct CompositorState
|
||||
{
|
||||
mir::geometry::Point cursor_position;
|
||||
WindowManagerMode mode = WindowManagerMode::normal;
|
||||
miral::Window active_window;
|
||||
std::shared_ptr<Container> active;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ using namespace miracle;
|
||||
ContainerType miracle::container_type_from_string(std::string const& str)
|
||||
{
|
||||
if (str == "tiled")
|
||||
return ContainerType::tiled;
|
||||
return ContainerType::leaf;
|
||||
else if (str == "floating")
|
||||
return ContainerType::floating;
|
||||
else if (str == "shell")
|
||||
|
@ -43,7 +43,7 @@ class Output;
|
||||
enum class ContainerType
|
||||
{
|
||||
none,
|
||||
tiled,
|
||||
leaf,
|
||||
floating,
|
||||
shell,
|
||||
parent
|
||||
@ -104,6 +104,7 @@ public:
|
||||
virtual uint32_t animation_handle() const = 0;
|
||||
virtual void animation_handle(uint32_t) = 0;
|
||||
virtual bool is_focused() const = 0;
|
||||
virtual bool is_fullscreen() const = 0;
|
||||
virtual std::optional<miral::Window> window() const = 0;
|
||||
virtual bool select_next(Direction) = 0;
|
||||
virtual bool pinned() const = 0;
|
||||
|
@ -30,7 +30,7 @@ using namespace miracle;
|
||||
|
||||
FloatingContainer::FloatingContainer(
|
||||
miral::Window const& window,
|
||||
miral::MinimalWindowManager& wm,
|
||||
std::shared_ptr<miral::MinimalWindowManager> const& wm,
|
||||
WindowController& window_controller,
|
||||
Workspace* workspace,
|
||||
CompositorState const& state) :
|
||||
@ -84,31 +84,31 @@ size_t FloatingContainer::get_min_width() const
|
||||
void FloatingContainer::handle_ready()
|
||||
{
|
||||
auto& info = window_controller.info_for(window_);
|
||||
wm.handle_window_ready(info);
|
||||
wm->handle_window_ready(info);
|
||||
}
|
||||
|
||||
void FloatingContainer::handle_modify(miral::WindowSpecification const& modifications)
|
||||
{
|
||||
auto& info = window_controller.info_for(window_);
|
||||
wm.handle_modify_window(info, modifications);
|
||||
wm->handle_modify_window(info, modifications);
|
||||
}
|
||||
|
||||
void FloatingContainer::handle_request_move(MirInputEvent const* input_event)
|
||||
{
|
||||
wm.handle_request_move(
|
||||
wm->handle_request_move(
|
||||
window_controller.info_for(window_), input_event);
|
||||
}
|
||||
|
||||
void FloatingContainer::handle_request_resize(
|
||||
MirInputEvent const* input_event, MirResizeEdge edge)
|
||||
{
|
||||
wm.handle_request_resize(
|
||||
wm->handle_request_resize(
|
||||
window_controller.info_for(window_), input_event, edge);
|
||||
}
|
||||
|
||||
void FloatingContainer::handle_raise()
|
||||
{
|
||||
wm.handle_raise_window(window_controller.info_for(window_));
|
||||
wm->handle_raise_window(window_controller.info_for(window_));
|
||||
}
|
||||
|
||||
void FloatingContainer::on_open()
|
||||
@ -118,23 +118,26 @@ void FloatingContainer::on_open()
|
||||
|
||||
void FloatingContainer::on_focus_gained()
|
||||
{
|
||||
wm.advise_focus_gained(window_controller.info_for(window_));
|
||||
if (get_output()->get_active_workspace()->get_workspace() != workspace_->get_workspace())
|
||||
return;
|
||||
|
||||
wm->advise_focus_gained(window_controller.info_for(window_));
|
||||
}
|
||||
|
||||
void FloatingContainer::on_focus_lost()
|
||||
{
|
||||
wm.advise_focus_lost(window_controller.info_for(window_));
|
||||
wm->advise_focus_lost(window_controller.info_for(window_));
|
||||
}
|
||||
|
||||
void FloatingContainer::on_move_to(geom::Point const& top_left)
|
||||
{
|
||||
wm.advise_move_to(window_controller.info_for(window_), top_left);
|
||||
wm->advise_move_to(window_controller.info_for(window_), top_left);
|
||||
}
|
||||
|
||||
mir::geometry::Rectangle FloatingContainer::confirm_placement(
|
||||
MirWindowState state, mir::geometry::Rectangle const& placement)
|
||||
{
|
||||
return wm.confirm_placement_on_display(
|
||||
return wm->confirm_placement_on_display(
|
||||
window_controller.info_for(window_),
|
||||
state,
|
||||
placement);
|
||||
@ -195,6 +198,11 @@ Workspace* FloatingContainer::get_workspace() const
|
||||
return workspace_;
|
||||
}
|
||||
|
||||
void FloatingContainer::set_workspace(Workspace* workspace)
|
||||
{
|
||||
workspace_ = workspace;
|
||||
}
|
||||
|
||||
Output* FloatingContainer::get_output() const
|
||||
{
|
||||
return workspace_->get_output();
|
||||
@ -222,7 +230,12 @@ void FloatingContainer::animation_handle(uint32_t handle)
|
||||
|
||||
bool FloatingContainer::is_focused() const
|
||||
{
|
||||
return state.active_window == window_;
|
||||
return state.active.get() == this;
|
||||
}
|
||||
|
||||
bool FloatingContainer::is_fullscreen() const
|
||||
{
|
||||
return window_controller.is_fullscreen(window_);
|
||||
}
|
||||
|
||||
ContainerType FloatingContainer::get_type() const
|
||||
|
@ -33,7 +33,7 @@ class FloatingContainer : public Container
|
||||
public:
|
||||
FloatingContainer(
|
||||
miral::Window const&,
|
||||
miral::MinimalWindowManager& wm,
|
||||
std::shared_ptr<miral::MinimalWindowManager> const& wm,
|
||||
WindowController& window_controller,
|
||||
Workspace* workspace,
|
||||
CompositorState const& state);
|
||||
@ -67,12 +67,14 @@ public:
|
||||
void restore_state(MirWindowState state) override;
|
||||
std::optional<MirWindowState> restore_state() override;
|
||||
Workspace* get_workspace() const override;
|
||||
void set_workspace(Workspace*);
|
||||
Output* get_output() const override;
|
||||
glm::mat4 get_transform() const override;
|
||||
void set_transform(glm::mat4 transform) override;
|
||||
uint32_t animation_handle() const override;
|
||||
void animation_handle(uint32_t uint_32) override;
|
||||
bool is_focused() const override;
|
||||
bool is_fullscreen() const override;
|
||||
ContainerType get_type() const override;
|
||||
glm::mat4 get_workspace_transform() const override;
|
||||
glm::mat4 get_output_transform() const override;
|
||||
@ -85,7 +87,7 @@ public:
|
||||
|
||||
private:
|
||||
miral::Window window_;
|
||||
miral::MinimalWindowManager& wm;
|
||||
std::shared_ptr<miral::MinimalWindowManager> wm;
|
||||
WindowController& window_controller;
|
||||
CompositorState const& state;
|
||||
|
||||
|
@ -198,7 +198,7 @@ void I3CommandExecutor::process_focus(I3Command const& command, I3ScopedCommandL
|
||||
if (!container)
|
||||
return;
|
||||
|
||||
if (container->get_type() != ContainerType::tiled)
|
||||
if (container->get_type() != ContainerType::leaf)
|
||||
{
|
||||
mir::log_warning("Cannot focus prev when a tiling window is not selected");
|
||||
return;
|
||||
@ -224,7 +224,7 @@ void I3CommandExecutor::process_focus(I3Command const& command, I3ScopedCommandL
|
||||
if (!container)
|
||||
return;
|
||||
|
||||
if (container->get_type() != ContainerType::tiled)
|
||||
if (container->get_type() != ContainerType::leaf)
|
||||
{
|
||||
mir::log_warning("Cannot focus prev when a tiling window is not selected");
|
||||
return;
|
||||
@ -332,10 +332,10 @@ void I3CommandExecutor::process_move(I3Command const& command, I3ScopedCommandLi
|
||||
auto const& arg1 = command.arguments[index++];
|
||||
if (arg1 == "center")
|
||||
{
|
||||
auto active_window = policy.get_state().active_window;
|
||||
auto active = policy.get_state().active;
|
||||
auto area = active_output->get_area();
|
||||
float x = (float)area.size.width.as_int() / 2.f - (float)active_window.size().width.as_int() / 2.f;
|
||||
float y = (float)area.size.height.as_int() / 2.f - (float)active_window.size().height.as_int() / 2.f;
|
||||
float x = (float)area.size.width.as_int() / 2.f - (float)active->get_visible_area().size.width.as_int() / 2.f;
|
||||
float y = (float)area.size.height.as_int() / 2.f - (float)active->get_visible_area().size.height.as_int() / 2.f;
|
||||
policy.try_move_to((int)x, (int)y);
|
||||
}
|
||||
else if (arg1 == "mouse")
|
||||
@ -392,9 +392,9 @@ void I3CommandExecutor::process_move(I3Command const& command, I3ScopedCommandLi
|
||||
y = end_y;
|
||||
}
|
||||
|
||||
auto active_window = policy.get_state().active_window;
|
||||
float x_pos = x / 2.f - (float)active_window.size().width.as_int() / 2.f;
|
||||
float y_pos = y / 2.f - (float)active_window.size().height.as_int() / 2.f;
|
||||
auto active = policy.get_state().active;
|
||||
float x_pos = x / 2.f - (float)active->get_visible_area().size.width.as_int() / 2.f;
|
||||
float y_pos = y / 2.f - (float)active->get_visible_area().size.height.as_int() / 2.f;
|
||||
policy.try_move_to((int)x_pos, (int)y_pos);
|
||||
return;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ LeafContainer::LeafContainer(
|
||||
TilingWindowTree* tree,
|
||||
std::shared_ptr<ParentContainer> const& parent,
|
||||
CompositorState const& state) :
|
||||
node_interface { node_interface },
|
||||
window_controller {node_interface },
|
||||
logical_area { std::move(area) },
|
||||
config { config },
|
||||
tree { tree },
|
||||
@ -111,10 +111,10 @@ geom::Rectangle LeafContainer::get_visible_area() const
|
||||
|
||||
void LeafContainer::constrain()
|
||||
{
|
||||
if (node_interface.is_fullscreen(window_))
|
||||
node_interface.noclip(window_);
|
||||
if (window_controller.is_fullscreen(window_))
|
||||
window_controller.noclip(window_);
|
||||
else
|
||||
node_interface.clip(window_, get_visible_area());
|
||||
window_controller.clip(window_, get_visible_area());
|
||||
}
|
||||
|
||||
size_t LeafContainer::get_min_width() const
|
||||
@ -135,7 +135,7 @@ void LeafContainer::handle_ready()
|
||||
|
||||
void LeafContainer::handle_modify(miral::WindowSpecification const& modifications)
|
||||
{
|
||||
auto const& info = node_interface.info_for(window_);
|
||||
auto const& info = window_controller.info_for(window_);
|
||||
|
||||
// TODO: Check if the current workspace is active. If not, return early.
|
||||
|
||||
@ -160,12 +160,12 @@ void LeafContainer::handle_modify(miral::WindowSpecification const& modification
|
||||
mods.size().consume();
|
||||
}
|
||||
|
||||
node_interface.modify(window_, mods);
|
||||
window_controller.modify(window_, mods);
|
||||
}
|
||||
|
||||
void LeafContainer::handle_raise()
|
||||
{
|
||||
node_interface.select_active_window(window_);
|
||||
window_controller.select_active_window(window_);
|
||||
}
|
||||
|
||||
bool LeafContainer::resize(miracle::Direction direction)
|
||||
@ -181,13 +181,13 @@ void LeafContainer::show()
|
||||
|
||||
void LeafContainer::hide()
|
||||
{
|
||||
before_shown_state = node_interface.get_state(window_);
|
||||
before_shown_state = window_controller.get_state(window_);
|
||||
next_state = mir_window_state_hidden;
|
||||
}
|
||||
|
||||
bool LeafContainer::toggle_fullscreen()
|
||||
{
|
||||
if (node_interface.is_fullscreen(window_))
|
||||
if (window_controller.is_fullscreen(window_))
|
||||
next_state = mir_window_state_restored;
|
||||
else
|
||||
next_state = mir_window_state_fullscreen;
|
||||
@ -206,7 +206,7 @@ mir::geometry::Rectangle LeafContainer::confirm_placement(
|
||||
|
||||
void LeafContainer::on_open()
|
||||
{
|
||||
node_interface.open(window_);
|
||||
window_controller.open(window_);
|
||||
}
|
||||
|
||||
void LeafContainer::on_focus_gained()
|
||||
@ -224,14 +224,14 @@ void LeafContainer::on_move_to(geom::Point const&)
|
||||
|
||||
bool LeafContainer::is_fullscreen() const
|
||||
{
|
||||
return node_interface.is_fullscreen(window_);
|
||||
return window_controller.is_fullscreen(window_);
|
||||
}
|
||||
|
||||
void LeafContainer::commit_changes()
|
||||
{
|
||||
if (next_state)
|
||||
{
|
||||
node_interface.change_state(window_, next_state.value());
|
||||
window_controller.change_state(window_, next_state.value());
|
||||
constrain();
|
||||
next_state.reset();
|
||||
}
|
||||
@ -241,9 +241,9 @@ void LeafContainer::commit_changes()
|
||||
auto previous = get_visible_area();
|
||||
logical_area = next_logical_area.value();
|
||||
next_logical_area.reset();
|
||||
if (!node_interface.is_fullscreen(window_))
|
||||
if (!window_controller.is_fullscreen(window_))
|
||||
{
|
||||
node_interface.set_rectangle(window_, previous, get_visible_area());
|
||||
window_controller.set_rectangle(window_, previous, get_visible_area());
|
||||
constrain();
|
||||
}
|
||||
}
|
||||
@ -272,6 +272,11 @@ void LeafContainer::toggle_layout()
|
||||
tree->toggle_layout(*this);
|
||||
}
|
||||
|
||||
void LeafContainer::set_tree(TilingWindowTree* tree_)
|
||||
{
|
||||
tree = tree_;
|
||||
}
|
||||
|
||||
void LeafContainer::restore_state(MirWindowState state)
|
||||
{
|
||||
restore_state_ = state;
|
||||
@ -316,12 +321,12 @@ void LeafContainer::animation_handle(uint32_t handle)
|
||||
|
||||
bool LeafContainer::is_focused() const
|
||||
{
|
||||
return state.active_window == window_;
|
||||
return state.active.get() == this;
|
||||
}
|
||||
|
||||
ContainerType LeafContainer::get_type() const
|
||||
{
|
||||
return ContainerType::tiled;
|
||||
return ContainerType::leaf;
|
||||
}
|
||||
|
||||
bool LeafContainer::select_next(miracle::Direction direction)
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
void set_state(MirWindowState state);
|
||||
void show();
|
||||
void hide();
|
||||
bool is_fullscreen() const;
|
||||
bool is_fullscreen() const override;
|
||||
void constrain() override;
|
||||
size_t get_min_width() const override;
|
||||
size_t get_min_height() const override;
|
||||
@ -75,6 +75,7 @@ public:
|
||||
void request_horizontal_layout() override;
|
||||
void request_vertical_layout() override;
|
||||
void toggle_layout() override;
|
||||
void set_tree(TilingWindowTree* tree);
|
||||
|
||||
[[nodiscard]] TilingWindowTree* get_tree() const { return tree; }
|
||||
[[nodiscard]] std::optional<miral::Window> window() const override { return window_; }
|
||||
@ -97,7 +98,7 @@ public:
|
||||
bool move_to(int, int) override;
|
||||
|
||||
private:
|
||||
WindowController& node_interface;
|
||||
WindowController& window_controller;
|
||||
geom::Rectangle logical_area;
|
||||
std::optional<geom::Rectangle> next_logical_area;
|
||||
std::shared_ptr<MiracleConfig> config;
|
||||
|
@ -811,7 +811,7 @@ void FilesystemConfiguration::_load()
|
||||
{
|
||||
auto num = workspace["number"].as<int>();
|
||||
auto type = container_type_from_string(workspace["layout"].as<std::string>());
|
||||
if (type != ContainerType::tiled && type != ContainerType::floating)
|
||||
if (type != ContainerType::leaf && type != ContainerType::floating)
|
||||
{
|
||||
mir::log_error("layout should be 'tiled' or 'floating': L%d:%d", workspace["layout"].Mark().line, workspace["layout"].Mark().column);
|
||||
continue;
|
||||
@ -1155,5 +1155,5 @@ WorkspaceConfig FilesystemConfiguration::get_workspace_config(int key) const
|
||||
return config;
|
||||
}
|
||||
|
||||
return { key, ContainerType::tiled };
|
||||
return { key, ContainerType::leaf };
|
||||
}
|
@ -129,7 +129,7 @@ struct BorderConfig
|
||||
struct WorkspaceConfig
|
||||
{
|
||||
int num = -1;
|
||||
ContainerType layout = ContainerType::tiled;
|
||||
ContainerType layout = ContainerType::leaf;
|
||||
};
|
||||
|
||||
class MiracleConfig
|
||||
|
@ -42,7 +42,7 @@ Output::Output(
|
||||
WorkspaceManager& workspace_manager,
|
||||
geom::Rectangle const& area,
|
||||
miral::WindowManagerTools const& tools,
|
||||
miral::MinimalWindowManager& floating_window_manager,
|
||||
std::shared_ptr<miral::MinimalWindowManager> const& floating_window_manager,
|
||||
CompositorState& state,
|
||||
std::shared_ptr<MiracleConfig> const& config,
|
||||
WindowController& node_interface,
|
||||
@ -82,13 +82,13 @@ bool Output::handle_pointer_event(const MirPointerEvent* event)
|
||||
return true;
|
||||
|
||||
auto const action = mir_pointer_event_action(event);
|
||||
if (has_clicked_floating_window || get_active_workspace()->has_floating_window(state.active_window))
|
||||
if (has_clicked_floating_window || get_active_workspace()->has_floating_window(state.active))
|
||||
{
|
||||
if (action == mir_pointer_action_button_down)
|
||||
has_clicked_floating_window = true;
|
||||
else if (action == mir_pointer_action_button_up)
|
||||
has_clicked_floating_window = false;
|
||||
return floating_window_manager.handle_pointer_event(event);
|
||||
return floating_window_manager->handle_pointer_event(event);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -106,16 +106,16 @@ ContainerType Output::allocate_position(
|
||||
return get_active_workspace()->allocate_position(app_info, requested_specification, ideal_type);
|
||||
}
|
||||
|
||||
std::shared_ptr<Container> Output::advise_new_window(
|
||||
std::shared_ptr<Container> Output::create_container(
|
||||
miral::WindowInfo const& window_info, ContainerType type) const
|
||||
{
|
||||
return get_active_workspace()->advise_new_window(window_info, type);
|
||||
return get_active_workspace()->create_container(window_info, type);
|
||||
}
|
||||
|
||||
void Output::advise_delete_window(const std::shared_ptr<miracle::Container>& container)
|
||||
void Output::delete_container(std::shared_ptr<miracle::Container> const &container)
|
||||
{
|
||||
auto workspace = container->get_workspace();
|
||||
workspace->advise_delete_window(container);
|
||||
workspace->delete_container(container);
|
||||
}
|
||||
|
||||
bool Output::select_window_from_point(int x, int y) const
|
||||
@ -309,20 +309,13 @@ std::vector<miral::Window> Output::collect_all_windows() const
|
||||
|
||||
void Output::request_toggle_active_float()
|
||||
{
|
||||
if (tools.active_window() == Window())
|
||||
if (!state.active)
|
||||
{
|
||||
mir::log_warning("request_toggle_active_float: active window unset");
|
||||
mir::log_warning("request_toggle_active_float: active unset");
|
||||
return;
|
||||
}
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
if (!container)
|
||||
{
|
||||
mir::log_error("request_toggle_active_float: container not found");
|
||||
return;
|
||||
}
|
||||
|
||||
container->get_workspace()->toggle_floating(container);
|
||||
state.active->get_workspace()->toggle_floating(state.active);
|
||||
}
|
||||
|
||||
void Output::add_immediately(miral::Window& window, ContainerType hint)
|
||||
@ -336,10 +329,15 @@ void Output::add_immediately(miral::Window& window, ContainerType hint)
|
||||
|
||||
ContainerType type = allocate_position(tools.info_for(window.application()), spec, hint);
|
||||
tools.modify_window(window, spec);
|
||||
auto container = advise_new_window(window_controller.info_for(window), type);
|
||||
auto container = create_container(window_controller.info_for(window), type);
|
||||
container->handle_ready();
|
||||
}
|
||||
|
||||
void Output::graft(std::shared_ptr<Container> const& container)
|
||||
{
|
||||
get_active_workspace()->graft(container);
|
||||
}
|
||||
|
||||
geom::Rectangle Output::get_workspace_rectangle(int workspace) const
|
||||
{
|
||||
// TODO: Support vertical workspaces one day in the future
|
||||
|
14
src/output.h
14
src/output.h
@ -44,7 +44,7 @@ public:
|
||||
WorkspaceManager& workspace_manager,
|
||||
geom::Rectangle const& area,
|
||||
miral::WindowManagerTools const& tools,
|
||||
miral::MinimalWindowManager& floating_window_manager,
|
||||
std::shared_ptr<miral::MinimalWindowManager> const& floating_window_manager,
|
||||
CompositorState& state,
|
||||
std::shared_ptr<MiracleConfig> const& options,
|
||||
WindowController&,
|
||||
@ -53,8 +53,8 @@ public:
|
||||
|
||||
bool handle_pointer_event(MirPointerEvent const* event);
|
||||
ContainerType allocate_position(miral::ApplicationInfo const& app_info, miral::WindowSpecification& requested_specification, ContainerType hint = ContainerType::none);
|
||||
[[nodiscard]] std::shared_ptr<Container> advise_new_window(miral::WindowInfo const& window_info, ContainerType type) const;
|
||||
void advise_delete_window(std::shared_ptr<miracle::Container> const& container);
|
||||
[[nodiscard]] std::shared_ptr<Container> create_container(miral::WindowInfo const& window_info, ContainerType type) const;
|
||||
void delete_container(std::shared_ptr<miracle::Container> const &container);
|
||||
[[nodiscard]] bool select_window_from_point(int x, int y) const;
|
||||
void advise_new_workspace(int workspace);
|
||||
void advise_workspace_deleted(int workspace);
|
||||
@ -70,8 +70,12 @@ public:
|
||||
/// Immediately requests that the provided window be added to the output
|
||||
/// with the provided type. This is a deviation away from the typical
|
||||
/// window-adding flow where you first call 'place_new_window' followed
|
||||
/// by 'advise_new_window'.
|
||||
/// by 'create_container'.
|
||||
void add_immediately(miral::Window& window, ContainerType hint = ContainerType::none);
|
||||
|
||||
/// Takes an existing [Container] object and places it in an appropriate position
|
||||
/// on the active [Workspace].
|
||||
void graft(std::shared_ptr<Container> const& container);
|
||||
void set_is_active(bool new_is_active) { is_active_ = new_is_active; }
|
||||
void set_transform(glm::mat4 const& in);
|
||||
void set_position(glm::vec2 const&);
|
||||
@ -95,7 +99,7 @@ private:
|
||||
miral::Output output;
|
||||
WorkspaceManager& workspace_manager;
|
||||
miral::WindowManagerTools tools;
|
||||
miral::MinimalWindowManager& floating_window_manager;
|
||||
std::shared_ptr<miral::MinimalWindowManager> floating_window_manager;
|
||||
CompositorState& state;
|
||||
geom::Rectangle area;
|
||||
std::shared_ptr<MiracleConfig> config;
|
||||
|
@ -584,6 +584,11 @@ void ParentContainer::toggle_layout()
|
||||
{
|
||||
}
|
||||
|
||||
void ParentContainer::set_tree(TilingWindowTree* tree_)
|
||||
{
|
||||
tree = tree_;
|
||||
}
|
||||
|
||||
void ParentContainer::on_focus_gained()
|
||||
{
|
||||
}
|
||||
@ -599,7 +604,7 @@ void ParentContainer::on_move_to(mir::geometry::Point const& top_left)
|
||||
mir::geometry::Rectangle
|
||||
ParentContainer::confirm_placement(MirWindowState state, mir::geometry::Rectangle const& rectangle)
|
||||
{
|
||||
return mir::geometry::Rectangle();
|
||||
return rectangle;
|
||||
}
|
||||
|
||||
ContainerType ParentContainer::get_type() const
|
||||
@ -697,3 +702,8 @@ bool ParentContainer::move_to(int x, int y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ParentContainer::is_fullscreen() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ public:
|
||||
void request_horizontal_layout() override;
|
||||
void request_vertical_layout() override;
|
||||
void toggle_layout() override;
|
||||
void set_tree(TilingWindowTree*);
|
||||
void on_focus_gained() override;
|
||||
void on_focus_lost() override;
|
||||
void on_move_to(mir::geometry::Point const& top_left) override;
|
||||
@ -104,6 +105,8 @@ public:
|
||||
bool move_by(Direction direction, int pixels) override;
|
||||
bool move_to(int x, int y) override;
|
||||
|
||||
bool is_fullscreen() const override;
|
||||
|
||||
private:
|
||||
WindowController& node_interface;
|
||||
geom::Rectangle logical_area;
|
||||
|
109
src/policy.cpp
109
src/policy.cpp
@ -50,7 +50,7 @@ Policy::Policy(
|
||||
SurfaceTracker& surface_tracker,
|
||||
mir::Server const& server) :
|
||||
window_manager_tools { tools },
|
||||
floating_window_manager(tools, config->get_input_event_modifier()),
|
||||
floating_window_manager(std::make_shared<miral::MinimalWindowManager>(tools, config->get_input_event_modifier())),
|
||||
external_client_launcher { external_client_launcher },
|
||||
runner { runner },
|
||||
config { config },
|
||||
@ -243,7 +243,7 @@ void Policy::advise_new_window(miral::WindowInfo const& window_info)
|
||||
auto shared_output = pending_output.lock();
|
||||
if (!shared_output)
|
||||
{
|
||||
mir::log_warning("advise_new_window: output unavailable");
|
||||
mir::log_warning("create_container: output unavailable");
|
||||
auto window = window_info.window();
|
||||
if (!output_list.empty())
|
||||
{
|
||||
@ -262,7 +262,7 @@ void Policy::advise_new_window(miral::WindowInfo const& window_info)
|
||||
return;
|
||||
}
|
||||
|
||||
auto container = shared_output->advise_new_window(window_info, pending_type);
|
||||
auto container = shared_output->create_container(window_info, pending_type);
|
||||
|
||||
container->animation_handle(animator.register_animateable());
|
||||
container->on_open();
|
||||
@ -287,7 +287,6 @@ void Policy::handle_window_ready(miral::WindowInfo& window_info)
|
||||
|
||||
void Policy::advise_focus_gained(const miral::WindowInfo& window_info)
|
||||
{
|
||||
state.active_window = window_info.window();
|
||||
auto container = window_controller.get_container(window_info.window());
|
||||
if (!container)
|
||||
{
|
||||
@ -295,12 +294,12 @@ void Policy::advise_focus_gained(const miral::WindowInfo& window_info)
|
||||
return;
|
||||
}
|
||||
|
||||
state.active = container;
|
||||
container->on_focus_gained();
|
||||
}
|
||||
|
||||
void Policy::advise_focus_lost(const miral::WindowInfo& window_info)
|
||||
{
|
||||
state.active_window = Window();
|
||||
auto container = window_controller.get_container(window_info.window());
|
||||
if (!container)
|
||||
{
|
||||
@ -308,6 +307,8 @@ void Policy::advise_focus_lost(const miral::WindowInfo& window_info)
|
||||
return;
|
||||
}
|
||||
|
||||
if (container == state.active)
|
||||
state.active = nullptr;
|
||||
container->on_focus_lost();
|
||||
}
|
||||
|
||||
@ -326,17 +327,17 @@ void Policy::advise_delete_window(const miral::WindowInfo& window_info)
|
||||
auto container = window_controller.get_container(window_info.window());
|
||||
if (!container)
|
||||
{
|
||||
mir::log_error("advise_delete_window: container is not provided");
|
||||
mir::log_error("delete_container: container is not provided");
|
||||
return;
|
||||
}
|
||||
|
||||
if (container->get_output())
|
||||
container->get_output()->advise_delete_window(container);
|
||||
container->get_output()->delete_container(container);
|
||||
|
||||
surface_tracker.remove(window_info.window());
|
||||
|
||||
if (state.active_window == window_info.window())
|
||||
state.active_window = Window();
|
||||
if (state.active == container)
|
||||
state.active = nullptr;
|
||||
}
|
||||
|
||||
void Policy::advise_move_to(miral::WindowInfo const& window_info, geom::Point top_left)
|
||||
@ -547,21 +548,14 @@ void Policy::try_toggle_resize_mode()
|
||||
return;
|
||||
}
|
||||
|
||||
auto const& window = state.active_window;
|
||||
if (!window)
|
||||
{
|
||||
state.mode = WindowManagerMode::normal;
|
||||
return;
|
||||
}
|
||||
|
||||
auto container = window_controller.get_container(window);
|
||||
auto container = state.active;
|
||||
if (!container)
|
||||
{
|
||||
state.mode = WindowManagerMode::normal;
|
||||
return;
|
||||
}
|
||||
|
||||
if (container->get_type() != ContainerType::tiled)
|
||||
if (container->get_type() != ContainerType::leaf)
|
||||
{
|
||||
state.mode = WindowManagerMode::normal;
|
||||
return;
|
||||
@ -580,11 +574,10 @@ bool Policy::try_request_vertical()
|
||||
if (state.mode == WindowManagerMode::resizing)
|
||||
return false;
|
||||
|
||||
if (!state.active_window)
|
||||
if (!state.active)
|
||||
return false;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
container->request_vertical_layout();
|
||||
state.active->request_vertical_layout();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -593,11 +586,10 @@ bool Policy::try_toggle_layout()
|
||||
if (state.mode == WindowManagerMode::resizing)
|
||||
return false;
|
||||
|
||||
if (!state.active_window)
|
||||
if (!state.active)
|
||||
return false;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
container->toggle_layout();
|
||||
state.active->toggle_layout();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -606,11 +598,10 @@ bool Policy::try_request_horizontal()
|
||||
if (state.mode == WindowManagerMode::resizing)
|
||||
return false;
|
||||
|
||||
if (!state.active_window)
|
||||
if (!state.active)
|
||||
return false;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
container->request_horizontal_layout();
|
||||
state.active->request_horizontal_layout();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -619,11 +610,10 @@ bool Policy::try_resize(miracle::Direction direction)
|
||||
if (state.mode != WindowManagerMode::resizing)
|
||||
return false;
|
||||
|
||||
if (!state.active_window)
|
||||
if (!state.active)
|
||||
return false;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
return container->resize(direction);
|
||||
return state.active->resize(direction);
|
||||
}
|
||||
|
||||
bool Policy::try_move(miracle::Direction direction)
|
||||
@ -631,11 +621,10 @@ bool Policy::try_move(miracle::Direction direction)
|
||||
if (state.mode == WindowManagerMode::resizing)
|
||||
return false;
|
||||
|
||||
if (!state.active_window)
|
||||
if (!state.active)
|
||||
return false;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
return container->move(direction);
|
||||
return state.active->move(direction);
|
||||
}
|
||||
|
||||
bool Policy::try_move_by(miracle::Direction direction, int pixels)
|
||||
@ -643,11 +632,10 @@ bool Policy::try_move_by(miracle::Direction direction, int pixels)
|
||||
if (state.mode == WindowManagerMode::resizing)
|
||||
return false;
|
||||
|
||||
if (!state.active_window)
|
||||
if (!state.active)
|
||||
return false;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
return container->move_by(direction, pixels);
|
||||
return state.active->move_by(direction, pixels);
|
||||
}
|
||||
|
||||
bool Policy::try_move_to(int x, int y)
|
||||
@ -655,11 +643,10 @@ bool Policy::try_move_to(int x, int y)
|
||||
if (state.mode == WindowManagerMode::resizing)
|
||||
return false;
|
||||
|
||||
if (!state.active_window)
|
||||
if (!state.active)
|
||||
return false;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
return container->move_to(x, y);
|
||||
return state.active->move_to(x, y);
|
||||
}
|
||||
|
||||
bool Policy::try_select(miracle::Direction direction)
|
||||
@ -667,11 +654,10 @@ bool Policy::try_select(miracle::Direction direction)
|
||||
if (state.mode == WindowManagerMode::resizing)
|
||||
return false;
|
||||
|
||||
if (!state.active_window)
|
||||
if (!state.active)
|
||||
return false;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
return container->select_next(direction);
|
||||
return state.active->select_next(direction);
|
||||
}
|
||||
|
||||
bool Policy::try_close_window()
|
||||
@ -679,7 +665,14 @@ bool Policy::try_close_window()
|
||||
if (!active_output)
|
||||
return false;
|
||||
|
||||
window_controller.close(state.active_window);
|
||||
if (!state.active)
|
||||
return false;
|
||||
|
||||
auto window = state.active->window();
|
||||
if (!window)
|
||||
return false;
|
||||
|
||||
window_controller.close(window.value());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -694,11 +687,10 @@ bool Policy::try_toggle_fullscreen()
|
||||
if (state.mode == WindowManagerMode::resizing)
|
||||
return false;
|
||||
|
||||
if (!state.active_window)
|
||||
if (!state.active)
|
||||
return false;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
return container->toggle_fullscreen();
|
||||
return state.active->toggle_fullscreen();
|
||||
}
|
||||
|
||||
bool Policy::select_workspace(int number)
|
||||
@ -718,21 +710,18 @@ bool Policy::move_active_to_workspace(int number)
|
||||
if (state.mode == WindowManagerMode::resizing)
|
||||
return false;
|
||||
|
||||
if (!active_output || !state.active_window)
|
||||
if (!active_output || !state.active)
|
||||
return false;
|
||||
|
||||
auto& info = window_controller.info_for(state.active_window);
|
||||
if (window_helpers::is_window_fullscreen(info.state()))
|
||||
if (state.active->is_fullscreen())
|
||||
return false;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
auto window_to_move = state.active_window;
|
||||
active_output->advise_delete_window(container);
|
||||
state.active_window = Window();
|
||||
auto to_move = state.active;
|
||||
active_output->delete_container(state.active);
|
||||
state.active = nullptr;
|
||||
|
||||
auto screen_to_move_to = workspace_manager.request_workspace(active_output, number);
|
||||
screen_to_move_to->add_immediately(window_to_move, ContainerType::tiled);
|
||||
|
||||
screen_to_move_to->graft(to_move);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -753,11 +742,10 @@ bool Policy::toggle_pinned_to_workspace()
|
||||
if (state.mode == WindowManagerMode::resizing)
|
||||
return false;
|
||||
|
||||
if (!state.active_window)
|
||||
if (!state.active)
|
||||
return false;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
return container->pinned(!container->pinned());
|
||||
return state.active->pinned(!state.active->pinned());
|
||||
}
|
||||
|
||||
bool Policy::set_is_pinned(bool pinned)
|
||||
@ -765,9 +753,8 @@ bool Policy::set_is_pinned(bool pinned)
|
||||
if (state.mode == WindowManagerMode::resizing)
|
||||
return false;
|
||||
|
||||
if (!state.active_window)
|
||||
if (!state.active)
|
||||
return false;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
return container->pinned(pinned);
|
||||
return state.active->pinned(pinned);
|
||||
}
|
@ -130,7 +130,7 @@ private:
|
||||
ContainerType pending_type;
|
||||
std::vector<Window> orphaned_window_list;
|
||||
miral::WindowManagerTools window_manager_tools;
|
||||
miral::MinimalWindowManager floating_window_manager;
|
||||
std::shared_ptr<miral::MinimalWindowManager> floating_window_manager;
|
||||
AutoRestartingLauncher& external_client_launcher;
|
||||
miral::MirRunner& runner;
|
||||
std::shared_ptr<MiracleConfig> config;
|
||||
|
@ -225,7 +225,7 @@ Renderer::DrawData Renderer::get_draw_data(mir::graphics::Renderable const& rend
|
||||
auto tools = WindowToolsAccessor::get_instance().get_tools();
|
||||
auto& info = tools.info_for(window);
|
||||
auto userdata = static_pointer_cast<Container>(info.userdata());
|
||||
data.needs_outline = (userdata->get_type() == ContainerType::tiled || userdata->get_type() == ContainerType::floating)
|
||||
data.needs_outline = (userdata->get_type() == ContainerType::leaf || userdata->get_type() == ContainerType::floating)
|
||||
&& !info.parent();
|
||||
data.workspace_transform = userdata->get_output_transform() * userdata->get_workspace_transform();
|
||||
data.is_focused = userdata->is_focused();
|
||||
|
@ -230,4 +230,9 @@ bool ShellComponentContainer::move_to(int x, int y)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ShellComponentContainer::is_fullscreen() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
} // miracle
|
@ -77,6 +77,8 @@ public:
|
||||
bool move_by(Direction direction, int pixels) override;
|
||||
bool move_to(int x, int y) override;
|
||||
|
||||
bool is_fullscreen() const override;
|
||||
|
||||
private:
|
||||
miral::Window window_;
|
||||
WindowController& window_controller;
|
||||
|
@ -93,6 +93,20 @@ std::shared_ptr<LeafContainer> TilingWindowTree::confirm_window(
|
||||
return parent->confirm_window(window_info.window());
|
||||
}
|
||||
|
||||
void TilingWindowTree::graft(std::shared_ptr<ParentContainer> const& parent)
|
||||
{
|
||||
parent->set_tree(this);
|
||||
root_lane->graft_existing(parent, root_lane->num_nodes());
|
||||
root_lane->commit_changes();
|
||||
}
|
||||
|
||||
void TilingWindowTree::graft(std::shared_ptr<LeafContainer> const& leaf)
|
||||
{
|
||||
leaf->set_tree(this);
|
||||
root_lane->graft_existing(leaf, root_lane->num_nodes());
|
||||
root_lane->commit_changes();
|
||||
}
|
||||
|
||||
bool TilingWindowTree::resize_container(miracle::Direction direction, Container& container)
|
||||
{
|
||||
if (is_active_window_fullscreen)
|
||||
@ -363,8 +377,8 @@ std::shared_ptr<LeafContainer> TilingWindowTree::handle_select(
|
||||
// 4. If none match, we return nullptr
|
||||
bool is_vertical = is_vertical_direction(direction);
|
||||
bool is_negative = is_negative_direction(direction);
|
||||
auto& current_node = from;
|
||||
auto parent = Container::as_parent(current_node.get_parent().lock());
|
||||
auto current_node = from.shared_from_this();
|
||||
auto parent = Container::as_parent(current_node->get_parent().lock());
|
||||
if (!parent)
|
||||
{
|
||||
mir::log_warning("Cannot handle_select the root node");
|
||||
@ -390,7 +404,7 @@ std::shared_ptr<LeafContainer> TilingWindowTree::handle_select(
|
||||
}
|
||||
}
|
||||
|
||||
current_node = *parent;
|
||||
current_node = parent;
|
||||
parent = Container::as_parent(parent->get_parent().lock());
|
||||
} while (parent != nullptr);
|
||||
|
||||
@ -609,7 +623,7 @@ bool TilingWindowTree::advise_fullscreen_container(LeafContainer& container)
|
||||
bool TilingWindowTree::advise_restored_container(LeafContainer& container)
|
||||
{
|
||||
auto active = active_container();
|
||||
if (active->window() == container.window().value() && is_active_window_fullscreen)
|
||||
if (active && active->window() == container.window().value() && is_active_window_fullscreen)
|
||||
{
|
||||
is_active_window_fullscreen = false;
|
||||
container.set_logical_area(container.get_logical_area());
|
||||
@ -756,12 +770,5 @@ Workspace* TilingWindowTree::get_workspace() const
|
||||
|
||||
std::shared_ptr<LeafContainer> TilingWindowTree::active_container() const
|
||||
{
|
||||
if (!state.active_window)
|
||||
return nullptr;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
if (!container)
|
||||
return nullptr;
|
||||
|
||||
return Container::as_leaf(container);
|
||||
return Container::as_leaf(state.active);
|
||||
}
|
@ -68,6 +68,9 @@ public:
|
||||
miral::WindowInfo const&,
|
||||
std::shared_ptr<ParentContainer> const& container);
|
||||
|
||||
void graft(std::shared_ptr<ParentContainer> const&);
|
||||
void graft(std::shared_ptr<LeafContainer> const&);
|
||||
|
||||
/// Try to resize the current active window in the provided direction
|
||||
bool resize_container(Direction direction, Container&);
|
||||
|
||||
|
@ -194,7 +194,7 @@ void WindowManagerToolsWindowController::on_animation(
|
||||
{ spec.top_left().value().x.as_int(), spec.top_left().value().y.as_int() },
|
||||
{ scale.x, scale.y });
|
||||
|
||||
if (container->get_type() == ContainerType::tiled)
|
||||
if (container->get_type() == ContainerType::leaf)
|
||||
clip(window, new_rectangle);
|
||||
else
|
||||
noclip(window);
|
||||
|
@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "output.h"
|
||||
#include "tiling_window_tree.h"
|
||||
#include "window_helpers.h"
|
||||
#include "parent_container.h"
|
||||
|
||||
#include "floating_container.h"
|
||||
#include "shell_component_container.h"
|
||||
@ -73,7 +74,7 @@ Workspace::Workspace(
|
||||
std::shared_ptr<MiracleConfig> const& config,
|
||||
WindowController& window_controller,
|
||||
CompositorState const& state,
|
||||
miral::MinimalWindowManager& floating_window_manager) :
|
||||
std::shared_ptr<miral::MinimalWindowManager> const& floating_window_manager) :
|
||||
output { output },
|
||||
tools { tools },
|
||||
workspace { workspace },
|
||||
@ -113,14 +114,14 @@ ContainerType Workspace::allocate_position(
|
||||
: hint;
|
||||
switch (layout)
|
||||
{
|
||||
case ContainerType::tiled:
|
||||
case ContainerType::leaf:
|
||||
{
|
||||
requested_specification = tree->place_new_window(requested_specification, get_layout_container());
|
||||
return ContainerType::tiled;
|
||||
return ContainerType::leaf;
|
||||
}
|
||||
case ContainerType::floating:
|
||||
{
|
||||
requested_specification = floating_window_manager.place_new_window(app_info, requested_specification);
|
||||
requested_specification = floating_window_manager->place_new_window(app_info, requested_specification);
|
||||
requested_specification.server_side_decorated() = false;
|
||||
return ContainerType::floating;
|
||||
}
|
||||
@ -129,20 +130,20 @@ ContainerType Workspace::allocate_position(
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Container> Workspace::advise_new_window(
|
||||
std::shared_ptr<Container> Workspace::create_container(
|
||||
miral::WindowInfo const& window_info, ContainerType type)
|
||||
{
|
||||
std::shared_ptr<Container> container = nullptr;
|
||||
switch (type)
|
||||
{
|
||||
case ContainerType::tiled:
|
||||
case ContainerType::leaf:
|
||||
{
|
||||
container = tree->confirm_window(window_info, get_layout_container());
|
||||
break;
|
||||
}
|
||||
case ContainerType::floating:
|
||||
{
|
||||
floating_window_manager.advise_new_window(window_info);
|
||||
floating_window_manager->advise_new_window(window_info);
|
||||
container = add_floating_window(window_info.window());
|
||||
break;
|
||||
}
|
||||
@ -167,7 +168,7 @@ std::shared_ptr<Container> Workspace::advise_new_window(
|
||||
|
||||
// TODO: hack
|
||||
// Warning: We need to advise fullscreen only after we've associated the userdata() appropriately
|
||||
if (type == ContainerType::tiled && window_helpers::is_window_fullscreen(window_info.state()))
|
||||
if (type == ContainerType::leaf && window_helpers::is_window_fullscreen(window_info.state()))
|
||||
{
|
||||
tree->advise_fullscreen_container(*Container::as_leaf(container));
|
||||
}
|
||||
@ -183,23 +184,24 @@ void Workspace::handle_ready_hack(LeafContainer& container)
|
||||
window_controller.raise(window->window().value());
|
||||
|
||||
if (tree->has_fullscreen_window())
|
||||
window_controller.raise(state.active_window);
|
||||
window_controller.raise(state.active->window().value());
|
||||
}
|
||||
|
||||
void Workspace::advise_delete_window(std::shared_ptr<Container> const& container)
|
||||
void Workspace::delete_container(std::shared_ptr<Container> const &container)
|
||||
{
|
||||
switch (container->get_type())
|
||||
{
|
||||
case ContainerType::tiled:
|
||||
case ContainerType::leaf:
|
||||
{
|
||||
tree->advise_delete_window(container);
|
||||
break;
|
||||
}
|
||||
case ContainerType::floating:
|
||||
{
|
||||
auto window = Container::as_floating(container)->window().value();
|
||||
floating_window_manager.advise_delete_window(window_controller.info_for(window));
|
||||
remove_floating_window(window);
|
||||
auto floating = Container::as_floating(container);
|
||||
floating_window_manager->advise_delete_window(window_controller.info_for(floating->window().value()));
|
||||
floating_windows.erase(
|
||||
std::remove(floating_windows.begin(), floating_windows.end(), floating), floating_windows.end());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -273,7 +275,7 @@ bool Workspace::select_window_from_point(int x, int y)
|
||||
{
|
||||
auto window = floating->window().value();
|
||||
geom::Rectangle window_area(window.top_left(), window.size());
|
||||
if (window == state.active_window && window_area.contains(geom::Point(x, y)))
|
||||
if (floating == state.active && window_area.contains(geom::Point(x, y)))
|
||||
return false;
|
||||
else if (window_area.contains(geom::Point(x, y)))
|
||||
{
|
||||
@ -283,7 +285,7 @@ bool Workspace::select_window_from_point(int x, int y)
|
||||
}
|
||||
|
||||
auto node = tree->select_window_from_point(x, y);
|
||||
if (node && node->window().value() != state.active_window)
|
||||
if (node && node != state.active)
|
||||
{
|
||||
window_controller.select_active_window(node->window().value());
|
||||
return true;
|
||||
@ -301,7 +303,7 @@ void Workspace::toggle_floating(std::shared_ptr<Container> const& container)
|
||||
|
||||
switch (container->get_type())
|
||||
{
|
||||
case ContainerType::tiled:
|
||||
case ContainerType::leaf:
|
||||
{
|
||||
if (tree->has_fullscreen_window())
|
||||
{
|
||||
@ -310,14 +312,14 @@ void Workspace::toggle_floating(std::shared_ptr<Container> const& container)
|
||||
}
|
||||
|
||||
// First, remove the window from the tiling window tree
|
||||
advise_delete_window(window_controller.get_container(*window));
|
||||
delete_container(window_controller.get_container(*window));
|
||||
|
||||
// Next, ask the floating window manager to place the new window
|
||||
auto& prev_info = window_controller.info_for(*window);
|
||||
auto spec = window_helpers::copy_from(prev_info);
|
||||
spec.top_left() = geom::Point { window->top_left().x.as_int() + 20, window->top_left().y.as_int() + 20 };
|
||||
window_controller.noclip(*window);
|
||||
auto new_spec = floating_window_manager.place_new_window(
|
||||
auto new_spec = floating_window_manager->place_new_window(
|
||||
tools.info_for(window->application()),
|
||||
spec);
|
||||
tools.modify_window(*window, new_spec);
|
||||
@ -328,7 +330,7 @@ void Workspace::toggle_floating(std::shared_ptr<Container> const& container)
|
||||
case ContainerType::floating:
|
||||
{
|
||||
// First, remove the floating window
|
||||
advise_delete_window(window_controller.get_container(*window));
|
||||
delete_container(window_controller.get_container(*window));
|
||||
|
||||
// Next, ask the tiling tree to place the new window
|
||||
auto& prev_info = window_controller.info_for(*window);
|
||||
@ -336,7 +338,7 @@ void Workspace::toggle_floating(std::shared_ptr<Container> const& container)
|
||||
auto new_spec = tree->place_new_window(spec, nullptr);
|
||||
tools.modify_window(*window, new_spec);
|
||||
|
||||
new_type = ContainerType::tiled;
|
||||
new_type = ContainerType::leaf;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -346,9 +348,9 @@ void Workspace::toggle_floating(std::shared_ptr<Container> const& container)
|
||||
|
||||
// In all cases, advise a new window and pretend like it is ready again
|
||||
auto& info = window_controller.info_for(*window);
|
||||
auto new_container = advise_new_window(info, new_type);
|
||||
auto new_container = create_container(info, new_type);
|
||||
new_container->handle_ready();
|
||||
window_controller.select_active_window(state.active_window);
|
||||
window_controller.select_active_window(state.active->window().value());
|
||||
}
|
||||
|
||||
void Workspace::hide()
|
||||
@ -396,11 +398,11 @@ void Workspace::transfer_pinned_windows_to(std::shared_ptr<Workspace> const& oth
|
||||
}
|
||||
}
|
||||
|
||||
bool Workspace::has_floating_window(miral::Window const& window)
|
||||
bool Workspace::has_floating_window(std::shared_ptr<Container> const& container)
|
||||
{
|
||||
for (auto const& other : floating_windows)
|
||||
{
|
||||
if (other->window() == window)
|
||||
if (other == container)
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -415,14 +417,6 @@ std::shared_ptr<FloatingContainer> Workspace::add_floating_window(miral::Window
|
||||
return floating;
|
||||
}
|
||||
|
||||
void Workspace::remove_floating_window(miral::Window const& window)
|
||||
{
|
||||
floating_windows.erase(std::remove_if(floating_windows.begin(), floating_windows.end(), [&window](std::shared_ptr<FloatingContainer> const& floating)
|
||||
{
|
||||
return floating->window() == window;
|
||||
}));
|
||||
}
|
||||
|
||||
Output* Workspace::get_output()
|
||||
{
|
||||
return output;
|
||||
@ -448,6 +442,29 @@ bool Workspace::is_empty() const
|
||||
return tree->is_empty() && floating_windows.empty();
|
||||
}
|
||||
|
||||
void Workspace::graft(std::shared_ptr<Container> const& container)
|
||||
{
|
||||
switch (container->get_type())
|
||||
{
|
||||
case ContainerType::floating:
|
||||
{
|
||||
auto floating = Container::as_floating(container);
|
||||
floating->set_workspace(this);
|
||||
floating_windows.push_back(floating);
|
||||
break;
|
||||
}
|
||||
case ContainerType::parent:
|
||||
tree->graft(Container::as_parent(container));
|
||||
break;
|
||||
case ContainerType::leaf:
|
||||
tree->graft(Container::as_leaf(container));
|
||||
break;
|
||||
default:
|
||||
mir::log_error("Workspace::graft: ungraftable container type: %d", (int)container->get_type());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int Workspace::workspace_to_number(int workspace)
|
||||
{
|
||||
if (workspace == 0)
|
||||
@ -458,16 +475,15 @@ int Workspace::workspace_to_number(int workspace)
|
||||
|
||||
std::shared_ptr<ParentContainer> Workspace::get_layout_container()
|
||||
{
|
||||
if (!state.active_window)
|
||||
if (!state.active)
|
||||
return nullptr;
|
||||
|
||||
auto container = window_controller.get_container(state.active_window);
|
||||
if (!container)
|
||||
return nullptr;
|
||||
|
||||
auto parent = container->get_parent().lock();
|
||||
auto parent = state.active->get_parent().lock();
|
||||
if (!parent)
|
||||
return nullptr;
|
||||
|
||||
if (parent->get_workspace() != this)
|
||||
return nullptr;
|
||||
|
||||
return parent;
|
||||
}
|
@ -47,7 +47,7 @@ public:
|
||||
std::shared_ptr<MiracleConfig> const& config,
|
||||
WindowController& window_controller,
|
||||
CompositorState const& state,
|
||||
miral::MinimalWindowManager& floating_window_manager);
|
||||
std::shared_ptr<miral::MinimalWindowManager> const& floating_window_manager);
|
||||
|
||||
[[nodiscard]] int get_workspace() const;
|
||||
void set_area(mir::geometry::Rectangle const&);
|
||||
@ -57,22 +57,22 @@ public:
|
||||
miral::ApplicationInfo const& app_info,
|
||||
miral::WindowSpecification& requested_specification,
|
||||
ContainerType hint);
|
||||
std::shared_ptr<Container> advise_new_window(
|
||||
std::shared_ptr<Container> create_container(
|
||||
miral::WindowInfo const& window_info, ContainerType type);
|
||||
void handle_ready_hack(LeafContainer& container);
|
||||
void advise_delete_window(const std::shared_ptr<Container>& container);
|
||||
void delete_container(std::shared_ptr<Container> const &container);
|
||||
void show();
|
||||
void hide();
|
||||
void transfer_pinned_windows_to(std::shared_ptr<Workspace> const& other);
|
||||
void for_each_window(std::function<void(std::shared_ptr<Container>)> const&);
|
||||
bool select_window_from_point(int x, int y);
|
||||
void toggle_floating(std::shared_ptr<Container> const&);
|
||||
bool has_floating_window(miral::Window const&);
|
||||
bool has_floating_window(std::shared_ptr<Container> const&);
|
||||
std::shared_ptr<FloatingContainer> add_floating_window(miral::Window const&);
|
||||
void remove_floating_window(miral::Window const&);
|
||||
Output* get_output();
|
||||
void trigger_rerender();
|
||||
[[nodiscard]] bool is_empty() const;
|
||||
void graft(std::shared_ptr<Container> const&);
|
||||
static int workspace_to_number(int workspace);
|
||||
|
||||
private:
|
||||
@ -84,7 +84,7 @@ private:
|
||||
WindowController& window_controller;
|
||||
CompositorState const& state;
|
||||
std::shared_ptr<MiracleConfig> config;
|
||||
miral::MinimalWindowManager& floating_window_manager;
|
||||
std::shared_ptr<miral::MinimalWindowManager> floating_window_manager;
|
||||
|
||||
/// Retrieves the container that is currently being used for layout
|
||||
std::shared_ptr<ParentContainer> get_layout_container();
|
||||
|
@ -125,7 +125,7 @@ public:
|
||||
auto leaf = tree.confirm_window(info, nullptr);
|
||||
pairs.push_back({ window, leaf });
|
||||
|
||||
state.active_window = window;
|
||||
state.active = leaf;
|
||||
tree.advise_focus_gained(*leaf);
|
||||
return leaf;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user