Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix minimized windows being focused when a focused window is closed #3698

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
14 changes: 12 additions & 2 deletions src/miral/application_selector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,11 @@ auto ApplicationSelector::advance(bool reverse, bool within_app) -> Window
// This means that there is no other selectable window in the list but
// the currently selected one, so we don't need to select anything.
if (*it == selected)
{
if(!tools.info_for(selected).is_visible())
tools.select_active_window(selected);
return selected;
}

if (within_app)
{
Expand Down Expand Up @@ -271,7 +275,13 @@ auto ApplicationSelector::advance(bool reverse, bool within_app) -> Window

auto next_state_to_preserve = tools.info_for(next_window.value()).state();
tools.select_active_window(next_window.value());
restore_state = next_state_to_preserve;

// Don't re-minimize windows selected with alt tab on focus loss
if(next_state_to_preserve != mir_window_state_minimized)
restore_state = next_state_to_preserve;
else
restore_state.reset();

return next_window.value();
}

Expand All @@ -281,4 +291,4 @@ auto ApplicationSelector::find(Window window) -> std::vector<Window>::iterator
{
return window == other;
});
}
}
69 changes: 37 additions & 32 deletions src/miral/basic_window_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,22 +294,17 @@ void miral::BasicWindowManager::refocus(
// Try to activate to recently active window of any application in a shared workspace
{
miral::Window new_focus;
auto workspaces_containing_window_mut = workspaces_containing_window;
std::sort(workspaces_containing_window_mut.begin(), workspaces_containing_window_mut.end());

mru_active_windows.enumerate([&](miral::Window& window)
mru_active_windows.enumerate(
[&](miral::Window& other_window)
{
// select_active_window() calls set_focus_to() which updates mru_active_windows and changes window
auto const w = window;
if (!info_for(other_window).is_visible())
return true;

for (auto const& workspace : workspaces_containing(w))
{
for (auto const& ww : workspaces_containing_window)
{
if (ww == workspace)
{
return !(new_focus = select_active_window(w));
}
}
}
if (window_workspaces_intersect(workspaces_containing_window_mut, other_window))
return !(new_focus = select_active_window(other_window));

return true;
});
Expand All @@ -328,14 +323,15 @@ void miral::BasicWindowManager::refocus(
{
// select_active_window() calls set_focus_to() which updates mru_active_windows and changes window
auto const w = window;
if(!info_for(w).is_visible()) return true;
return !(new_focus = select_active_window(w));
});

if (new_focus) return;
}

// Fallback to cycling through applications
focus_next_application();
// Can't focus anything else
focus_controller->set_focus_to(nullptr, nullptr);
}

void miral::BasicWindowManager::erase(miral::WindowInfo const& info)
Expand Down Expand Up @@ -1494,24 +1490,17 @@ void miral::BasicWindowManager::set_state(miral::WindowInfo& window_info, MirWin

if (window == active_window() || !active_window())
{
auto const workspaces_containing_window = workspaces_containing(window);
auto workspaces_containing_window = workspaces_containing(window);
std::sort(workspaces_containing_window.begin(), workspaces_containing_window.end());

// Try to activate to recently active window of any application
mru_active_windows.enumerate([&](Window& candidate)
{
if (candidate == window)
if (candidate == window || !info_for(candidate).is_visible())
return true;
auto const w = candidate;
for (auto const& workspace : workspaces_containing(w))
{
for (auto const& ww : workspaces_containing_window)
{
if (ww == workspace)
{
return !(select_active_window(w));
}
}
}

if(window_workspaces_intersect(workspaces_containing_window, candidate))
select_active_window(candidate);

return true;
});
Expand All @@ -1521,10 +1510,9 @@ void miral::BasicWindowManager::set_state(miral::WindowInfo& window_info, MirWin
if (window == active_window() || !active_window())
mru_active_windows.enumerate([&](Window& candidate)
{
if (candidate == window)
if (candidate == window || !info_for(candidate).is_visible())
return true;
auto const w = candidate;
return !(select_active_window(w));
return !(select_active_window(candidate));
});

if (window == active_window())
Expand Down Expand Up @@ -2993,4 +2981,21 @@ void miral::BasicWindowManager::move_cursor_to(mir::geometry::PointF point)
sink->handle_input(std::move(event));
});
});
}
}

auto miral::BasicWindowManager::window_workspaces_intersect(std::vector<std::shared_ptr<Workspace>> const& w1_workspaces, Window const& w2) const -> bool
{
auto w2_workspaces = workspaces_containing(w2);
std::sort(w2_workspaces.begin(), w2_workspaces.end());

auto intersection = std::vector<std::shared_ptr<Workspace>>();

std::set_intersection(
w1_workspaces.begin(),
w1_workspaces.end(),
w2_workspaces.begin(),
w2_workspaces.end(),
std::back_inserter(intersection));

return !intersection.empty();
}
4 changes: 4 additions & 0 deletions src/miral/basic_window_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,10 @@ class BasicWindowManager : public virtual mir::shell::WindowManager,
void for_each_descendent_in(WindowInfo const& info, std::function<void(const Window&)> func);
/// Gathers windows provided WindowInfo
auto collect_windows(WindowInfo const& info) -> SurfaceSet;

// w1_workspaces must be sorted
auto window_workspaces_intersect(
std::vector<std::shared_ptr<Workspace>> const& w1_workspaces, Window const& w2) const -> bool;
};
}

Expand Down
3 changes: 1 addition & 2 deletions src/server/frontend_wayland/input_method_v1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,6 @@ mf::InputPanelV1::InputPanelV1(
OutputManager* const output_manager,
std::shared_ptr<scene::TextInputHub> const text_input_hub)
: Global(display, Version<1>()),
display{display},
wayland_executor{wayland_executor},
shell{shell},
seat{seat},
Expand All @@ -594,4 +593,4 @@ void mf::InputPanelV1::bind(wl_resource *new_resource)
new_resource,
text_input_hub
};
}
}
3 changes: 1 addition & 2 deletions src/server/frontend_wayland/input_method_v1.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ class InputPanelV1 : public wayland::InputPanelV1::Global
class Instance;
void bind(wl_resource* new_zwp_input_panel_v1) override;

wl_display* display;
std::shared_ptr<Executor> const wayland_executor;
std::shared_ptr<shell::Shell> const shell;
WlSeat* seat;
Expand All @@ -83,4 +82,4 @@ class InputPanelV1 : public wayland::InputPanelV1::Global
}
}

#endif
#endif
Loading