feature: implementation of stacking windows (#242)

This commit is contained in:
Matthew Kosarek 2024-09-10 06:09:54 -04:00 committed by GitHub
parent 1b88e8bd2b
commit 826e5a844b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 72 additions and 12 deletions

View File

@ -434,6 +434,8 @@ void FilesystemConfiguration::_reload()
key_command = DefaultKeyCommand::TogglePinnedToWorkspace;
else if (name == "toggle_tabbing")
key_command = DefaultKeyCommand::ToggleTabbing;
else if (name == "toggle_stacking")
key_command = DefaultKeyCommand::ToggleStacking;
else
{
mir::log_error("default_action_overrides: Unknown key command override: %s", name.c_str());
@ -1251,7 +1253,10 @@ FilesystemConfiguration::ConfigDetails::ConfigDetails()
KEY_P },
{ MirKeyboardAction ::mir_keyboard_action_down,
miracle_input_event_modifier_default,
KEY_W }
KEY_W },
{ MirKeyboardAction ::mir_keyboard_action_down,
miracle_input_event_modifier_default,
KEY_S }
};
for (int i = 0; i < DefaultKeyCommand::MAX; i++)
{

View File

@ -95,6 +95,7 @@ enum DefaultKeyCommand
ToggleFloating,
TogglePinnedToWorkspace,
ToggleTabbing,
ToggleStacking,
MAX
};

View File

@ -117,6 +117,7 @@ public:
virtual bool move_by(Direction, int pixels) = 0;
virtual bool move_to(int x, int y) = 0;
virtual bool toggle_tabbing() = 0;
virtual bool toggle_stacking() = 0;
bool is_leaf();
bool is_lane();

View File

@ -86,6 +86,7 @@ public:
bool move_by(Direction direction, int pixels) override;
bool move_to(int x, int y) override;
bool toggle_tabbing() override { return false; };
bool toggle_stacking() override { return false; };
private:
std::vector<std::weak_ptr<Container>> containers;

View File

@ -85,6 +85,7 @@ public:
bool move_by(Direction direction, int pixels) override;
bool move_to(int x, int y) override;
bool toggle_tabbing() override { return false; };
bool toggle_stacking() override { return false; };
private:
std::unique_ptr<TilingWindowTree> tree;

View File

@ -83,6 +83,7 @@ public:
bool move_by(Direction, int) override;
bool move_to(int, int) override;
bool toggle_tabbing() override { return false; };
bool toggle_stacking() override { return false; };
std::weak_ptr<ParentContainer> get_parent() const override;

View File

@ -367,7 +367,19 @@ bool LeafContainer::toggle_tabbing()
if (sh_parent->get_direction() == LayoutScheme::tabbing)
tree->request_horizontal_layout(*this);
else
tree->requested_tabbing_layout(*this);
tree->request_tabbing_layout(*this);
}
return true;
}
bool LeafContainer::toggle_stacking()
{
if (auto sh_parent = parent.lock())
{
if (sh_parent->get_direction() == LayoutScheme::stacking)
tree->request_horizontal_layout(*this);
else
tree->request_stacking_layout(*this);
}
return true;
}

View File

@ -95,6 +95,7 @@ public:
bool move_by(Direction, int) override;
bool move_to(int, int) override;
bool toggle_tabbing() override;
bool toggle_stacking() override;
private:
WindowController& window_controller;

View File

@ -25,6 +25,7 @@ enum class LayoutScheme
horizontal,
vertical,
tabbing,
stacking,
none
};
}

View File

@ -195,7 +195,7 @@ geom::Rectangle ParentContainer::create_space(int pending_index)
};
pending_logical_rect = new_node_logical_rect;
}
else if (scheme == LayoutScheme::tabbing)
else if (scheme == LayoutScheme::tabbing || scheme == LayoutScheme::stacking)
{
pending_logical_rect = placement_area;
}
@ -364,7 +364,7 @@ void ParentContainer::set_logical_area(const geom::Rectangle& target_rect)
pending_size_updates.back().size.height = geom::Height { pending_size_updates.back().size.height.as_int() + leftover_height };
}
}
else if (scheme == LayoutScheme::tabbing)
else if (scheme == LayoutScheme::tabbing || scheme == LayoutScheme::stacking)
{
for (size_t idx = 0; idx < sub_nodes.size(); idx++)
{
@ -564,7 +564,7 @@ void ParentContainer::relayout()
node->set_logical_area(rectangle);
}
}
else if (scheme == LayoutScheme::tabbing)
else if (scheme == LayoutScheme::tabbing || scheme == LayoutScheme::stacking)
{
for (auto const& node : sub_nodes)
node->set_logical_area(placement_area);
@ -627,7 +627,7 @@ void ParentContainer::set_tree(TilingWindowTree* tree_)
void ParentContainer::on_focus_gained()
{
if (scheme == LayoutScheme::tabbing)
if (scheme == LayoutScheme::tabbing || scheme == LayoutScheme::stacking)
{
for (auto const& container : sub_nodes)
{
@ -765,3 +765,14 @@ bool ParentContainer::toggle_tabbing()
relayout();
return true;
}
bool ParentContainer::toggle_stacking()
{
if (scheme == LayoutScheme::stacking)
scheme = LayoutScheme::horizontal;
else
scheme = LayoutScheme::stacking;
relayout();
return true;
}

View File

@ -107,6 +107,7 @@ public:
bool move_to(int x, int y) override;
bool is_fullscreen() const override;
bool toggle_tabbing() override;
bool toggle_stacking() override;
private:
WindowController& node_interface;

View File

@ -191,6 +191,8 @@ bool Policy::handle_keyboard_event(MirKeyboardEvent const* event)
return toggle_pinned_to_workspace();
case ToggleTabbing:
return toggle_tabbing();
case ToggleStacking:
return toggle_stacking();
default:
std::cerr << "Unknown key_command: " << key_command << std::endl;
break;
@ -850,4 +852,15 @@ bool Policy::toggle_tabbing()
return false;
return state.active->toggle_tabbing();
}
bool Policy::toggle_stacking()
{
if (state.mode == WindowManagerMode::resizing)
return false;
if (!state.active)
return false;
return state.active->toggle_stacking();
}

View File

@ -119,6 +119,7 @@ public:
bool toggle_pinned_to_workspace();
bool set_is_pinned(bool);
bool toggle_tabbing();
bool toggle_stacking();
// Getters

View File

@ -77,7 +77,7 @@ public:
bool move_by(Direction direction, int pixels) override;
bool move_to(int x, int y) override;
bool toggle_tabbing() override { return false; };
bool toggle_stacking() override { return false; };
bool is_fullscreen() const override;
private:

View File

@ -251,11 +251,16 @@ void TilingWindowTree::request_horizontal_layout(Container& container)
handle_layout_scheme(LayoutScheme::horizontal, container);
}
void TilingWindowTree::requested_tabbing_layout(Container& container)
void TilingWindowTree::request_tabbing_layout(Container& container)
{
handle_layout_scheme(LayoutScheme::tabbing, container);
}
void TilingWindowTree::request_stacking_layout(Container& container)
{
handle_layout_scheme(LayoutScheme::stacking, container);
}
void TilingWindowTree::toggle_layout(Container& container)
{
auto parent = Container::as_parent(container.get_parent().lock());
@ -286,9 +291,11 @@ void TilingWindowTree::handle_layout_scheme(LayoutScheme scheme, Container& cont
}
// If the parent already has more than just [container] as a child AND
// the parent is NOT a tabbing parent, then we create a new parent for this
// the parent is NOT a tabbing/stacking parent, then we create a new parent for this
// single [container].
if (parent->num_nodes() > 1 && parent->get_direction() != LayoutScheme::tabbing)
if (parent->num_nodes() > 1
&& parent->get_direction() != LayoutScheme::tabbing
&& parent->get_direction() != LayoutScheme::stacking)
parent = parent->convert_to_parent(container.shared_from_this());
parent->set_direction(scheme);
@ -407,7 +414,7 @@ std::shared_ptr<LeafContainer> TilingWindowTree::handle_select(
{
auto grandparent_direction = parent->get_direction();
int index = parent->get_index_of_node(current_node);
if (is_vertical && grandparent_direction == LayoutScheme::vertical
if (is_vertical && (grandparent_direction == LayoutScheme::vertical || grandparent_direction == LayoutScheme::stacking)
|| !is_vertical && (grandparent_direction == LayoutScheme::horizontal || grandparent_direction == LayoutScheme::tabbing))
{
if (is_negative)

View File

@ -91,8 +91,11 @@ public:
/// Request a change to horizontal window placement
void request_horizontal_layout(Container&);
/// Request that the provided container become tabbed.
void request_tabbing_layout(Container&);
/// Request that the provided container become stacked.
void requested_tabbing_layout(Container&);
void request_stacking_layout(Container&);
// Request a change from the current layout scheme to another layout scheme
void toggle_layout(Container&);