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

View File

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

View File

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

View File

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

View File

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

View File

@ -83,6 +83,7 @@ public:
bool move_by(Direction, int) override; bool move_by(Direction, int) override;
bool move_to(int, int) override; bool move_to(int, int) override;
bool toggle_tabbing() override { return false; }; bool toggle_tabbing() override { return false; };
bool toggle_stacking() override { return false; };
std::weak_ptr<ParentContainer> get_parent() const override; 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) if (sh_parent->get_direction() == LayoutScheme::tabbing)
tree->request_horizontal_layout(*this); tree->request_horizontal_layout(*this);
else 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; return true;
} }

View File

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

View File

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

View File

@ -195,7 +195,7 @@ geom::Rectangle ParentContainer::create_space(int pending_index)
}; };
pending_logical_rect = new_node_logical_rect; 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; 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 }; 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++) for (size_t idx = 0; idx < sub_nodes.size(); idx++)
{ {
@ -564,7 +564,7 @@ void ParentContainer::relayout()
node->set_logical_area(rectangle); node->set_logical_area(rectangle);
} }
} }
else if (scheme == LayoutScheme::tabbing) else if (scheme == LayoutScheme::tabbing || scheme == LayoutScheme::stacking)
{ {
for (auto const& node : sub_nodes) for (auto const& node : sub_nodes)
node->set_logical_area(placement_area); node->set_logical_area(placement_area);
@ -627,7 +627,7 @@ void ParentContainer::set_tree(TilingWindowTree* tree_)
void ParentContainer::on_focus_gained() void ParentContainer::on_focus_gained()
{ {
if (scheme == LayoutScheme::tabbing) if (scheme == LayoutScheme::tabbing || scheme == LayoutScheme::stacking)
{ {
for (auto const& container : sub_nodes) for (auto const& container : sub_nodes)
{ {
@ -765,3 +765,14 @@ bool ParentContainer::toggle_tabbing()
relayout(); relayout();
return true; 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 move_to(int x, int y) override;
bool is_fullscreen() const override; bool is_fullscreen() const override;
bool toggle_tabbing() override; bool toggle_tabbing() override;
bool toggle_stacking() override;
private: private:
WindowController& node_interface; WindowController& node_interface;

View File

@ -191,6 +191,8 @@ bool Policy::handle_keyboard_event(MirKeyboardEvent const* event)
return toggle_pinned_to_workspace(); return toggle_pinned_to_workspace();
case ToggleTabbing: case ToggleTabbing:
return toggle_tabbing(); return toggle_tabbing();
case ToggleStacking:
return toggle_stacking();
default: default:
std::cerr << "Unknown key_command: " << key_command << std::endl; std::cerr << "Unknown key_command: " << key_command << std::endl;
break; break;
@ -851,3 +853,14 @@ bool Policy::toggle_tabbing()
return state.active->toggle_tabbing(); 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 toggle_pinned_to_workspace();
bool set_is_pinned(bool); bool set_is_pinned(bool);
bool toggle_tabbing(); bool toggle_tabbing();
bool toggle_stacking();
// Getters // Getters

View File

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

View File

@ -251,11 +251,16 @@ void TilingWindowTree::request_horizontal_layout(Container& container)
handle_layout_scheme(LayoutScheme::horizontal, 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); 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) void TilingWindowTree::toggle_layout(Container& container)
{ {
auto parent = Container::as_parent(container.get_parent().lock()); 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 // 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]. // 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 = parent->convert_to_parent(container.shared_from_this());
parent->set_direction(scheme); parent->set_direction(scheme);
@ -407,7 +414,7 @@ std::shared_ptr<LeafContainer> TilingWindowTree::handle_select(
{ {
auto grandparent_direction = parent->get_direction(); auto grandparent_direction = parent->get_direction();
int index = parent->get_index_of_node(current_node); 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)) || !is_vertical && (grandparent_direction == LayoutScheme::horizontal || grandparent_direction == LayoutScheme::tabbing))
{ {
if (is_negative) if (is_negative)

View File

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