mirror of
https://github.com/miracle-wm-org/miracle-wm.git
synced 2024-11-27 00:11:40 +03:00
feature: moving windows between workspaces
This commit is contained in:
parent
030e06428e
commit
0e9eea63e2
11
USERGUIDE.md
11
USERGUIDE.md
@ -21,6 +21,8 @@
|
||||
- `meta + shift + q`: Quit the selected application
|
||||
- `meta + shift + e`: Close the compositor
|
||||
- `meta + f`: Toggle fullscreen on the window
|
||||
- `meta + [0-9]`: Move to workspace *n*
|
||||
- `meta + shift + [0-9]`: Move active window to workspace *n*
|
||||
|
||||
# Pointer Behavior
|
||||
- Hovering over a window will select the window
|
||||
@ -65,7 +67,14 @@ First, let's define some reoccurring data types in the configuration file:
|
||||
struct DefaultActionOverride
|
||||
{
|
||||
// Name of the action to override
|
||||
name: "terminal" | "request_vertical" | "request_horizontal" | "toggle_resize" | "move_up" | "move_down" | "move_left" | "move_right" | "select_up" | "select_down" | "select_left" | "select_right" | "quit_active_window" | "quit_compositor" | "fullscreen";
|
||||
name: "terminal" | "request_vertical" | "request_horizontal" | "toggle_resize" | "move_up" | "move_down"
|
||||
| "move_left" | "move_right" | "select_up" | "select_down" | "select_left" | "select_right"
|
||||
| "quit_active_window" | "quit_compositor" | "fullscreen" | "select_workspace_1" | "select_workspace_2"
|
||||
| "select_workspace_3" | "select_workspace_4" | "select_workspace_5" | "select_workspace_6"
|
||||
| "select_workspace_7" | "select_workspace_8" | "select_workspace_9" | "select_workspace_0"
|
||||
| "move_to_workspace_1" | "move_to_workspace_2" | "move_to_workspace_3" | "move_to_workspace_4"
|
||||
| "move_to_workspace_5" | "move_to_workspace_6" | "move_to_workspace_7" | "move_to_workspace_8"
|
||||
| "move_to_workspace_9" | "move_to_workspace_0"
|
||||
|
||||
// Action will fire based on this key event
|
||||
action: "up" | "down" | "repeat" | "modifiers";
|
||||
|
@ -121,6 +121,26 @@ MiracleConfig::MiracleConfig()
|
||||
key_command = DefaultKeyCommand::SelectWorkspace9;
|
||||
else if (name == "select_workspace_0")
|
||||
key_command = DefaultKeyCommand::SelectWorkspace0;
|
||||
else if (name == "move_to_workspace_1")
|
||||
key_command = DefaultKeyCommand::MoveToWorkspace1;
|
||||
else if (name == "move_to_workspace_2")
|
||||
key_command = DefaultKeyCommand::MoveToWorkspace2;
|
||||
else if (name == "move_to_workspace_3")
|
||||
key_command = DefaultKeyCommand::MoveToWorkspace3;
|
||||
else if (name == "move_to_workspace_4")
|
||||
key_command = DefaultKeyCommand::MoveToWorkspace4;
|
||||
else if (name == "move_to_workspace_5")
|
||||
key_command = DefaultKeyCommand::MoveToWorkspace5;
|
||||
else if (name == "move_to_workspace_6")
|
||||
key_command = DefaultKeyCommand::MoveToWorkspace6;
|
||||
else if (name == "move_to_workspace_7")
|
||||
key_command = DefaultKeyCommand::MoveToWorkspace7;
|
||||
else if (name == "move_to_workspace_8")
|
||||
key_command = DefaultKeyCommand::MoveToWorkspace8;
|
||||
else if (name == "move_to_workspace_9")
|
||||
key_command = DefaultKeyCommand::MoveToWorkspace9;
|
||||
else if (name == "move_to_workspace_0")
|
||||
key_command = DefaultKeyCommand::MoveToWorkspace0;
|
||||
else {
|
||||
mir::log_error("default_action_overrides: Unknown key command override: %s", name.c_str());
|
||||
continue;
|
||||
@ -299,6 +319,56 @@ MiracleConfig::MiracleConfig()
|
||||
MirKeyboardAction ::mir_keyboard_action_down,
|
||||
miracle_input_event_modifier_default,
|
||||
KEY_0
|
||||
},
|
||||
{
|
||||
MirKeyboardAction ::mir_keyboard_action_down,
|
||||
miracle_input_event_modifier_default | mir_input_event_modifier_shift,
|
||||
KEY_1
|
||||
},
|
||||
{
|
||||
MirKeyboardAction ::mir_keyboard_action_down,
|
||||
miracle_input_event_modifier_default | mir_input_event_modifier_shift,
|
||||
KEY_2
|
||||
},
|
||||
{
|
||||
MirKeyboardAction ::mir_keyboard_action_down,
|
||||
miracle_input_event_modifier_default | mir_input_event_modifier_shift,
|
||||
KEY_3
|
||||
},
|
||||
{
|
||||
MirKeyboardAction ::mir_keyboard_action_down,
|
||||
miracle_input_event_modifier_default | mir_input_event_modifier_shift,
|
||||
KEY_4
|
||||
},
|
||||
{
|
||||
MirKeyboardAction ::mir_keyboard_action_down,
|
||||
miracle_input_event_modifier_default | mir_input_event_modifier_shift,
|
||||
KEY_5
|
||||
},
|
||||
{
|
||||
MirKeyboardAction ::mir_keyboard_action_down,
|
||||
miracle_input_event_modifier_default | mir_input_event_modifier_shift,
|
||||
KEY_6
|
||||
},
|
||||
{
|
||||
MirKeyboardAction ::mir_keyboard_action_down,
|
||||
miracle_input_event_modifier_default | mir_input_event_modifier_shift,
|
||||
KEY_7
|
||||
},
|
||||
{
|
||||
MirKeyboardAction ::mir_keyboard_action_down,
|
||||
miracle_input_event_modifier_default | mir_input_event_modifier_shift,
|
||||
KEY_8
|
||||
},
|
||||
{
|
||||
MirKeyboardAction ::mir_keyboard_action_down,
|
||||
miracle_input_event_modifier_default | mir_input_event_modifier_shift,
|
||||
KEY_9
|
||||
},
|
||||
{
|
||||
MirKeyboardAction ::mir_keyboard_action_down,
|
||||
miracle_input_event_modifier_default | mir_input_event_modifier_shift,
|
||||
KEY_0
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < DefaultKeyCommand::MAX; i++)
|
||||
|
@ -36,6 +36,16 @@ enum DefaultKeyCommand
|
||||
SelectWorkspace8,
|
||||
SelectWorkspace9,
|
||||
SelectWorkspace0,
|
||||
MoveToWorkspace1,
|
||||
MoveToWorkspace2,
|
||||
MoveToWorkspace3,
|
||||
MoveToWorkspace4,
|
||||
MoveToWorkspace5,
|
||||
MoveToWorkspace6,
|
||||
MoveToWorkspace7,
|
||||
MoveToWorkspace8,
|
||||
MoveToWorkspace9,
|
||||
MoveToWorkspace0,
|
||||
MAX
|
||||
};
|
||||
|
||||
|
@ -189,6 +189,36 @@ bool MiracleWindowManagementPolicy::handle_keyboard_event(MirKeyboardEvent const
|
||||
case SelectWorkspace0:
|
||||
workspace_manager.request_workspace(active_output->screen, '0');
|
||||
break;
|
||||
case MoveToWorkspace1:
|
||||
workspace_manager.move_active_to_workspace(active_output->screen, '1');
|
||||
break;
|
||||
case MoveToWorkspace2:
|
||||
workspace_manager.move_active_to_workspace(active_output->screen, '2');
|
||||
break;
|
||||
case MoveToWorkspace3:
|
||||
workspace_manager.move_active_to_workspace(active_output->screen, '3');
|
||||
break;
|
||||
case MoveToWorkspace4:
|
||||
workspace_manager.move_active_to_workspace(active_output->screen, '4');
|
||||
break;
|
||||
case MoveToWorkspace5:
|
||||
workspace_manager.move_active_to_workspace(active_output->screen, '5');
|
||||
break;
|
||||
case MoveToWorkspace6:
|
||||
workspace_manager.move_active_to_workspace(active_output->screen, '6');
|
||||
break;
|
||||
case MoveToWorkspace7:
|
||||
workspace_manager.move_active_to_workspace(active_output->screen, '7');
|
||||
break;
|
||||
case MoveToWorkspace8:
|
||||
workspace_manager.move_active_to_workspace(active_output->screen, '8');
|
||||
break;
|
||||
case MoveToWorkspace9:
|
||||
workspace_manager.move_active_to_workspace(active_output->screen, '9');
|
||||
break;
|
||||
case MoveToWorkspace0:
|
||||
workspace_manager.move_active_to_workspace(active_output->screen, '0');
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Unknown key_command: " << key_command << std::endl;
|
||||
break;
|
||||
|
@ -810,3 +810,9 @@ void WindowTree::show()
|
||||
}
|
||||
nodes_to_resurrect.clear();
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Node> WindowTree::get_root_node()
|
||||
{
|
||||
return root_lane;
|
||||
}
|
@ -108,6 +108,8 @@ public:
|
||||
/// Shows the entire tree
|
||||
void show();
|
||||
|
||||
std::shared_ptr<Node> get_root_node();
|
||||
|
||||
private:
|
||||
struct MoveResult
|
||||
{
|
||||
|
@ -15,14 +15,14 @@ WorkspaceManager::WorkspaceManager(WindowManagerTools const& tools) :
|
||||
{
|
||||
}
|
||||
|
||||
bool WorkspaceManager::request_workspace(std::shared_ptr<Screen> screen, char key)
|
||||
std::shared_ptr<Screen> WorkspaceManager::request_workspace(std::shared_ptr<Screen> screen, char key)
|
||||
{
|
||||
for (auto workspace : workspaces)
|
||||
{
|
||||
if (workspace.key == key)
|
||||
{
|
||||
workspace.screen->make_workspace_active(key);
|
||||
return true;
|
||||
return workspace.screen;
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ bool WorkspaceManager::request_workspace(std::shared_ptr<Screen> screen, char ke
|
||||
screen
|
||||
});
|
||||
screen->advise_new_workspace(key);
|
||||
return true;
|
||||
return screen;
|
||||
}
|
||||
|
||||
bool WorkspaceManager::request_first_available_workspace(std::shared_ptr<Screen> screen)
|
||||
@ -48,228 +48,30 @@ bool WorkspaceManager::request_first_available_workspace(std::shared_ptr<Screen>
|
||||
}
|
||||
|
||||
if (can_use)
|
||||
return request_workspace(screen, DEFAULT_WORKSPACES[i]);
|
||||
{
|
||||
request_workspace(screen, DEFAULT_WORKSPACES[i]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WorkspaceManager::move_active_to_workspace(std::shared_ptr<Screen> screen, char workspace)
|
||||
{
|
||||
auto window = tools_.active_window();
|
||||
if (!window)
|
||||
return false;
|
||||
|
||||
//
|
||||
//void miracle::WorkspaceManager::jump_to_workspace(bool take_active, int index)
|
||||
//{
|
||||
// tools_.invoke_under_lock(
|
||||
// [this, take_active, index]
|
||||
// {
|
||||
// if (active_workspace_index != index)
|
||||
// {
|
||||
// auto const old_workspace = active_workspace_index;
|
||||
// auto const& window = take_active ? tools_.active_window() : Window{};
|
||||
// auto const& old_active = workspaces[active_workspace_index];
|
||||
//
|
||||
// while (workspaces.size() - 1 < index)
|
||||
// workspaces.push_back(tools_.create_workspace());
|
||||
//
|
||||
// auto const& new_active = workspaces[index];
|
||||
// change_active_workspace(new_active, old_active, window);
|
||||
// erase_if_empty(std::next(workspaces.begin(), old_workspace));
|
||||
// active_workspace_index = index;
|
||||
// }
|
||||
// });
|
||||
//}
|
||||
//
|
||||
//void miracle::WorkspaceManager::workspace_begin(bool take_active)
|
||||
//{
|
||||
// jump_to_workspace(take_active, 0);
|
||||
//}
|
||||
//
|
||||
//void miracle::WorkspaceManager::workspace_end(bool take_active)
|
||||
//{
|
||||
// jump_to_workspace(take_active, workspaces.size() - 1);
|
||||
//}
|
||||
//
|
||||
//void miracle::WorkspaceManager::workspace_up(bool take_active)
|
||||
//{
|
||||
// if (active_workspace_index != 0)
|
||||
// jump_to_workspace(take_active, active_workspace_index - 1);
|
||||
//}
|
||||
//
|
||||
//void miracle::WorkspaceManager::workspace_down(bool take_active)
|
||||
//{
|
||||
// if (active_workspace_index != workspaces.size() - 1)
|
||||
// jump_to_workspace(active_workspace_index + 1, take_active);
|
||||
//}
|
||||
//
|
||||
//void miracle::WorkspaceManager::erase_if_empty(workspace_list::iterator const& old_workspace)
|
||||
//{
|
||||
// bool empty = true;
|
||||
// tools_.for_each_window_in_workspace(*old_workspace, [&](auto ww)
|
||||
// {
|
||||
// if (is_application(tools_.info_for(ww).depth_layer()))
|
||||
// empty = false;
|
||||
// });
|
||||
// if (empty)
|
||||
// {
|
||||
// workspace_to_active.erase(*old_workspace);
|
||||
// workspaces.erase(old_workspace);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void miracle::WorkspaceManager::apply_workspace_hidden_to(Window const& window)
|
||||
//{
|
||||
// auto const& window_info = tools_.info_for(window);
|
||||
// auto& workspace_info = workspace_info_for(window_info);
|
||||
// if (!workspace_info.in_hidden_workspace)
|
||||
// {
|
||||
// workspace_info.in_hidden_workspace = true;
|
||||
// workspace_info.old_state = window_info.state();
|
||||
//
|
||||
// WindowSpecification modifications;
|
||||
// modifications.state() = mir_window_state_hidden;
|
||||
// tools_.place_and_size_for_state(modifications, window_info);
|
||||
// tools_.modify_window(window_info.window(), modifications);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void miracle::WorkspaceManager::apply_workspace_visible_to(Window const& window)
|
||||
//{
|
||||
// auto const& window_info = tools_.info_for(window);
|
||||
// auto& workspace_info = workspace_info_for(window_info);
|
||||
// if (workspace_info.in_hidden_workspace)
|
||||
// {
|
||||
// workspace_info.in_hidden_workspace = false;
|
||||
// WindowSpecification modifications;
|
||||
// modifications.state() = workspace_info.old_state;
|
||||
// tools_.place_and_size_for_state(modifications, window_info);
|
||||
// tools_.modify_window(window_info.window(), modifications);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void miracle::WorkspaceManager::change_active_workspace(
|
||||
// std::shared_ptr<Workspace> const& new_active,
|
||||
// std::shared_ptr<Workspace> const& old_active,
|
||||
// Window const& window)
|
||||
//{
|
||||
// if (new_active == old_active) return;
|
||||
//
|
||||
// auto const old_active_window = tools_.active_window();
|
||||
// auto const old_active_window_shell = old_active_window &&
|
||||
// !is_application(tools_.info_for(old_active_window).depth_layer());
|
||||
//
|
||||
// if (!old_active_window || old_active_window_shell)
|
||||
// {
|
||||
// // If there's no active window, the first shown grabs focus: get the right one
|
||||
// if (auto const ww = workspace_to_active[new_active])
|
||||
// {
|
||||
// tools_.for_each_workspace_containing(ww, [&](std::shared_ptr<Workspace> const& ws)
|
||||
// {
|
||||
// if (ws == new_active)
|
||||
// {
|
||||
// apply_workspace_visible_to(ww);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// // If focus was on a shell window, put it on an app
|
||||
// if (old_active_window_shell)
|
||||
// tools_.select_active_window(ww);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// tools_.remove_tree_from_workspace(window, old_active);
|
||||
// tools_.add_tree_to_workspace(window, new_active);
|
||||
//
|
||||
// tools_.for_each_window_in_workspace(new_active, [&](Window const& ww)
|
||||
// {
|
||||
// if (is_application(tools_.info_for(ww).depth_layer()))
|
||||
// {
|
||||
// apply_workspace_visible_to(ww);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// bool hide_old_active = false;
|
||||
// tools_.for_each_window_in_workspace(old_active, [&](Window const& ww)
|
||||
// {
|
||||
// if (is_application(tools_.info_for(ww).depth_layer()))
|
||||
// {
|
||||
// if (ww == old_active_window)
|
||||
// {
|
||||
// // If we hide the active window focus will shift: do that last
|
||||
// hide_old_active = true;
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// apply_workspace_hidden_to(ww);
|
||||
// return;
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// if (hide_old_active)
|
||||
// {
|
||||
// apply_workspace_hidden_to(old_active_window);
|
||||
//
|
||||
// // Remember the old active_window when we switch away
|
||||
// workspace_to_active[old_active] = old_active_window;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//void miracle::WorkspaceManager::advise_adding_to_workspace(std::shared_ptr<Workspace> const& workspace,
|
||||
// std::vector<Window> const& windows)
|
||||
//{
|
||||
// if (windows.empty())
|
||||
// return;
|
||||
//
|
||||
// for (auto const& window : windows)
|
||||
// {
|
||||
// if (workspace == workspaces[active_workspace_index])
|
||||
// {
|
||||
// apply_workspace_visible_to(window);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// apply_workspace_hidden_to(window);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//auto miracle::WorkspaceManager::active_workspace() const -> std::shared_ptr<Workspace>
|
||||
//{
|
||||
// return workspaces[active_workspace_index];
|
||||
//}
|
||||
//
|
||||
//bool miracle::WorkspaceManager::is_application(MirDepthLayer layer)
|
||||
//{
|
||||
// switch (layer)
|
||||
// {
|
||||
// case mir_depth_layer_application:
|
||||
// case mir_depth_layer_always_on_top:
|
||||
// return true;
|
||||
//
|
||||
// default:;
|
||||
// return false;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//bool miracle::WorkspaceManager::in_hidden_workspace(WindowInfo const& info) const
|
||||
//{
|
||||
// auto& workspace_info = workspace_info_for(info);
|
||||
//
|
||||
// return workspace_info.in_hidden_workspace;
|
||||
//}
|
||||
//
|
||||
//void miracle::WorkspaceManager::advise_new_window(WindowInfo const& window_info)
|
||||
//{
|
||||
// if (auto const& parent = window_info.parent())
|
||||
// {
|
||||
// if (workspace_info_for(tools_.info_for(parent)).in_hidden_workspace)
|
||||
// apply_workspace_hidden_to(window_info.window());
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// tools_.add_tree_to_workspace(window_info.window(), active_workspace());
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//auto miracle::WorkspaceManager::make_workspace_info() -> std::shared_ptr<WorkspaceInfo>
|
||||
//{
|
||||
// return std::make_shared<WorkspaceInfo>();
|
||||
//}
|
||||
auto& original_tree = screen->get_active_tree();
|
||||
auto window_node = original_tree.get_root_node()->find_node_for_window(window);
|
||||
original_tree.advise_delete_window(window);
|
||||
|
||||
auto screen_to_move_to = request_workspace(screen, workspace);
|
||||
miral::WindowSpecification spec;
|
||||
spec = screen_to_move_to->get_active_tree().allocate_position(spec);
|
||||
tools_.modify_window(window, spec);
|
||||
screen_to_move_to->get_active_tree().advise_new_window(tools_.info_for(window));
|
||||
screen_to_move_to->get_active_tree().handle_window_ready(tools_.info_for(window));
|
||||
return true;
|
||||
}
|
@ -43,40 +43,11 @@ public:
|
||||
/// is created on the current Screen. If it does exist, we navigate
|
||||
/// to the screen containing that workspace and show it if it
|
||||
/// isn't already shown.
|
||||
bool request_workspace(std::shared_ptr<Screen> screen, char workspace);
|
||||
std::shared_ptr<Screen> request_workspace(std::shared_ptr<Screen> screen, char workspace);
|
||||
|
||||
bool request_first_available_workspace(std::shared_ptr<Screen> screen);
|
||||
|
||||
// void workspace_begin(bool take_active);
|
||||
//
|
||||
// void workspace_end(bool take_active);
|
||||
//
|
||||
// void workspace_up(bool take_active);
|
||||
//
|
||||
// void workspace_down(bool take_active);
|
||||
//
|
||||
// void jump_to_workspace(bool take_active, int index);
|
||||
//
|
||||
// void apply_workspace_hidden_to(Window const& window);
|
||||
//
|
||||
// void apply_workspace_visible_to(Window const& window);
|
||||
//
|
||||
// void change_active_workspace(
|
||||
// std::shared_ptr<Workspace> const& ww,
|
||||
// std::shared_ptr<Workspace> const& old_active,
|
||||
// miral::Window const& window);
|
||||
//
|
||||
// void advise_new_window(const WindowInfo &window_info);
|
||||
//
|
||||
// void advise_adding_to_workspace(
|
||||
// std::shared_ptr<Workspace> const& workspace,
|
||||
// std::vector<Window> const& windows);
|
||||
//
|
||||
// auto active_workspace() const -> std::shared_ptr<Workspace>;
|
||||
//
|
||||
// bool in_hidden_workspace(WindowInfo const& info) const;
|
||||
//
|
||||
// static bool is_application(MirDepthLayer layer);
|
||||
bool move_active_to_workspace(std::shared_ptr<Screen> screen, char workspace);
|
||||
|
||||
private:
|
||||
WindowManagerTools tools_;
|
||||
|
Loading…
Reference in New Issue
Block a user