diff --git a/src/config.cpp b/src/config.cpp index cc5d235..672d0e5 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -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++) { diff --git a/src/config.h b/src/config.h index 1fc846c..c945bc7 100644 --- a/src/config.h +++ b/src/config.h @@ -95,6 +95,7 @@ enum DefaultKeyCommand ToggleFloating, TogglePinnedToWorkspace, ToggleTabbing, + ToggleStacking, MAX }; diff --git a/src/container.h b/src/container.h index 0c62846..ab5ec3e 100644 --- a/src/container.h +++ b/src/container.h @@ -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(); diff --git a/src/container_group_container.h b/src/container_group_container.h index 4d1c505..727441a 100644 --- a/src/container_group_container.h +++ b/src/container_group_container.h @@ -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> containers; diff --git a/src/floating_tree_container.h b/src/floating_tree_container.h index 779d498..a6b4756 100644 --- a/src/floating_tree_container.h +++ b/src/floating_tree_container.h @@ -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 tree; diff --git a/src/floating_window_container.h b/src/floating_window_container.h index 39a29d1..cc9edce 100644 --- a/src/floating_window_container.h +++ b/src/floating_window_container.h @@ -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 get_parent() const override; diff --git a/src/leaf_container.cpp b/src/leaf_container.cpp index e8c4f1c..79172d1 100644 --- a/src/leaf_container.cpp +++ b/src/leaf_container.cpp @@ -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; } diff --git a/src/leaf_container.h b/src/leaf_container.h index 2db1d2e..bf6382c 100644 --- a/src/leaf_container.h +++ b/src/leaf_container.h @@ -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; diff --git a/src/node_common.h b/src/node_common.h index 371c07d..9086932 100644 --- a/src/node_common.h +++ b/src/node_common.h @@ -25,6 +25,7 @@ enum class LayoutScheme horizontal, vertical, tabbing, + stacking, none }; } diff --git a/src/parent_container.cpp b/src/parent_container.cpp index 156fde5..0a85b0a 100644 --- a/src/parent_container.cpp +++ b/src/parent_container.cpp @@ -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; +} \ No newline at end of file diff --git a/src/parent_container.h b/src/parent_container.h index fef02a7..84e85f8 100644 --- a/src/parent_container.h +++ b/src/parent_container.h @@ -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; diff --git a/src/policy.cpp b/src/policy.cpp index 59fd7ee..028f7cd 100644 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -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(); } \ No newline at end of file diff --git a/src/policy.h b/src/policy.h index b31d413..2503141 100644 --- a/src/policy.h +++ b/src/policy.h @@ -119,6 +119,7 @@ public: bool toggle_pinned_to_workspace(); bool set_is_pinned(bool); bool toggle_tabbing(); + bool toggle_stacking(); // Getters diff --git a/src/shell_component_container.h b/src/shell_component_container.h index 73f7a22..fa046fb 100644 --- a/src/shell_component_container.h +++ b/src/shell_component_container.h @@ -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: diff --git a/src/tiling_window_tree.cpp b/src/tiling_window_tree.cpp index 8d3bb6c..0e2da9f 100644 --- a/src/tiling_window_tree.cpp +++ b/src/tiling_window_tree.cpp @@ -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 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) diff --git a/src/tiling_window_tree.h b/src/tiling_window_tree.h index d373354..edfb69f 100644 --- a/src/tiling_window_tree.h +++ b/src/tiling_window_tree.h @@ -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&);