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

feature: alt + grave behavior now implemented alongside alt + tick #3216

Merged
merged 4 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions debian/libmiral7.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,11 @@ libmiral.so.7 libmiral7 #MINVER#
(c++)"miral::MinimalWindowManager::MinimalWindowManager(miral::WindowManagerTools const&)@MIRAL_5.0" 5.0.0
(c++)"miral::MinimalWindowManager::MinimalWindowManager(miral::WindowManagerTools const&, MirInputEventModifier)@MIRAL_5.0" 5.0.0
(c++)"miral::MinimalWindowManager::advise_delete_app(miral::ApplicationInfo const&)@MIRAL_5.0" 5.0.0
(c++)"miral::MinimalWindowManager::advise_delete_window(miral::WindowInfo const&)@MIRAL_5.1" 5.0.0
(c++)"miral::MinimalWindowManager::advise_focus_gained(miral::WindowInfo const&)@MIRAL_5.0" 5.0.0
(c++)"miral::MinimalWindowManager::advise_focus_lost(miral::WindowInfo const&)@MIRAL_5.0" 5.0.0
(c++)"miral::MinimalWindowManager::advise_new_app(miral::ApplicationInfo&)@MIRAL_5.0" 5.0.0
(c++)"miral::MinimalWindowManager::advise_new_window(miral::WindowInfo const&)@MIRAL_5.1" 5.0.0
(c++)"miral::MinimalWindowManager::begin_pointer_move(miral::WindowInfo const&, MirInputEvent const*)@MIRAL_5.0" 5.0.0
(c++)"miral::MinimalWindowManager::begin_pointer_resize(miral::WindowInfo const&, MirInputEvent const*, MirResizeEdge const&)@MIRAL_5.0" 5.0.0
(c++)"miral::MinimalWindowManager::begin_touch_move(miral::WindowInfo const&, MirInputEvent const*)@MIRAL_5.0" 5.0.0
Expand Down Expand Up @@ -149,6 +151,8 @@ libmiral.so.7 libmiral7 #MINVER#
(c++)"miral::StartupInternalClient::StartupInternalClient(std::function<void (wl_display*)>, std::function<void (std::weak_ptr<mir::scene::Session>)>)@MIRAL_5.0" 5.0.0
(c++)"miral::StartupInternalClient::operator()(mir::Server&)@MIRAL_5.0" 5.0.0
(c++)"miral::StartupInternalClient::~StartupInternalClient()@MIRAL_5.0" 5.0.0
(c++)"miral::WaylandExtensions::Context::Context()@MIRAL_5.0" 5.0.0
(c++)"miral::WaylandExtensions::Context::~Context()@MIRAL_5.0" 5.0.0
Comment on lines +154 to +155
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh?! (I can't imagine why you're adding this - it should have been there for a long time already.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I regenerated the symbols, it got generated too

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hence the "Huh?!"

(c++)"miral::WaylandExtensions::EnableInfo::app() const@MIRAL_5.0" 5.0.0
(c++)"miral::WaylandExtensions::EnableInfo::name() const@MIRAL_5.0" 5.0.0
(c++)"miral::WaylandExtensions::EnableInfo::user_preference() const@MIRAL_5.0" 5.0.0
Expand Down Expand Up @@ -256,6 +260,7 @@ libmiral.so.7 libmiral7 #MINVER#
(c++)"miral::WindowManagerTools::active_window() const@MIRAL_5.0" 5.0.0
(c++)"miral::WindowManagerTools::add_tree_to_workspace(miral::Window const&, std::shared_ptr<miral::Workspace> const&)@MIRAL_5.0" 5.0.0
(c++)"miral::WindowManagerTools::ask_client_to_close(miral::Window const&)@MIRAL_5.0" 5.0.0
(c++)"miral::WindowManagerTools::can_select_window(miral::Window const&) const@MIRAL_5.1" 5.0.0
(c++)"miral::WindowManagerTools::count_applications() const@MIRAL_5.0" 5.0.0
(c++)"miral::WindowManagerTools::create_workspace()@MIRAL_5.0" 5.0.0
(c++)"miral::WindowManagerTools::drag_active_window(mir::geometry::generic::Displacement<int>)@MIRAL_5.0" 5.0.0
Expand Down Expand Up @@ -380,6 +385,7 @@ libmiral.so.7 libmiral7 #MINVER#
(c++)"miral::equivalent_display_area(miral::Output const&, miral::Output const&)@MIRAL_5.0" 5.0.0
(c++)"miral::kill(std::shared_ptr<mir::scene::Session> const&, int)@MIRAL_5.0" 5.0.0
(c++)"miral::name_of[abi:cxx11](std::shared_ptr<mir::scene::Session> const&)@MIRAL_5.0" 5.0.0
(c++)"miral::operator!=(miral::Window const&, std::shared_ptr<mir::scene::Surface> const&)@MIRAL_5.0" 5.0.0
(c++)"miral::operator<(miral::Window const&, miral::Window const&)@MIRAL_5.0" 5.0.0
(c++)"miral::operator==(miral::Output::PhysicalSizeMM const&, miral::Output::PhysicalSizeMM const&)@MIRAL_5.0" 5.0.0
(c++)"miral::operator==(miral::Window const&, miral::Window const&)@MIRAL_5.0" 5.0.0
Expand Down Expand Up @@ -422,4 +428,5 @@ libmiral.so.7 libmiral7 #MINVER#
(c++)"typeinfo for miral::WindowManagementPolicy@MIRAL_5.0" 5.0.0
(c++)"vtable for miral::CanonicalWindowManagerPolicy@MIRAL_5.0" 5.0.0
(c++)"vtable for miral::MinimalWindowManager@MIRAL_5.0" 5.0.0
(c++)"vtable for miral::WaylandExtensions::Context@MIRAL_5.0" 5.0.0
(c++)"vtable for miral::WindowManagementPolicy@MIRAL_5.0" 5.0.0
4 changes: 4 additions & 0 deletions include/miral/miral/minimal_window_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ class MinimalWindowManager : public WindowManagementPolicy

void advise_delete_app(miral::ApplicationInfo const& app_info) override;

void advise_new_window(WindowInfo const& app_info) override;

void advise_delete_window(WindowInfo const& app_info) override;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should document when these are introduced.

Suggested change
void advise_new_window(WindowInfo const& app_info) override;
void advise_delete_window(WindowInfo const& app_info) override;
/// \remark Since MirAL 5.0
void advise_new_window(WindowInfo const& app_info) override;
/// \remark Since MirAL 5.0
void advise_delete_window(WindowInfo const& app_info) override;

protected:
WindowManagerTools tools;

Expand Down
3 changes: 3 additions & 0 deletions include/miral/miral/window_manager_tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ class WindowManagerTools
/// \remark Since MirAL 3.10
auto window_to_select_application(const Application) const -> std::optional<Window>;

/// Check if the provided window can be selected
auto can_select_window(Window const&) const -> bool;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Check if the provided window can be selected
auto can_select_window(Window const&) const -> bool;
/// Check if the provided window can be selected
/// \remark Since MirAL 5.0
auto can_select_window(Window const&) const -> bool;


/// Find the topmost window at the cursor
auto window_at(mir::geometry::Point cursor) const -> Window;

Expand Down
121 changes: 57 additions & 64 deletions src/miral/application_selector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <miral/application_info.h>
#include <miral/application.h>
#include <mir/log.h>
#include <mir/scene/session.h>

using namespace miral;

Expand All @@ -31,8 +32,7 @@ ApplicationSelector::ApplicationSelector(miral::ApplicationSelector const& other
tools{other.tools},
focus_list{other.focus_list},
originally_selected{other.originally_selected},
selected{other.selected},
active_window{other.active_window}
selected{other.selected}
{
}

Expand All @@ -42,30 +42,23 @@ auto ApplicationSelector::operator=(ApplicationSelector const& other) -> Applica
focus_list = other.focus_list;
originally_selected = other.originally_selected;
selected = other.selected;
active_window = other.active_window;
return *this;
}

void ApplicationSelector::advise_new_app(Application const& application)
void ApplicationSelector::advise_new_window(WindowInfo const& window_info)
{
focus_list.push_back(application);
focus_list.push_back(window_info.window());
}

void ApplicationSelector::advise_focus_gained(WindowInfo const& window_info)
{
auto window = window_info.window();
if (!window)
{
return;
}

auto application = window.application();
if (!application)
{
return;
mir::fatal_error("advise_focus_gained: window_info did not reference a window");
}

auto it = find(application);
auto it = find(window);
if (!is_active())
{
// If we are not active, we move the newly focused item to the front of the list.
Expand All @@ -76,42 +69,34 @@ void ApplicationSelector::advise_focus_gained(WindowInfo const& window_info)
}

// Update the current selection
selected = application;
active_window = window;
selected = window;
}

void ApplicationSelector::advise_focus_lost(miral::WindowInfo const& window_info)
{
auto window = window_info.window();
if (!window)
{
mir::fatal_error("advise_focus_lost: window_info did not reference a window");
return;
}

auto application = window.application();
if (!application)
{
return;
}

if (selected.lock() == application)
{
selected.reset();
}
selected = Window();
}

void ApplicationSelector::advise_delete_app(Application const& application)
void ApplicationSelector::advise_delete_window(WindowInfo const& window_info)
{
auto it = find(application);
auto it = find(window_info.window());
if (it == focus_list.end())
{
mir::log_warning("ApplicationSelector::advise_delete_app could not delete the app.");
return;
}

// If we delete the selected application, we will try to select the next available one.
if (application == selected.lock())
if (*it == selected)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code no longer agrees wit hthe comment

{
auto application = it->application();
std::optional<Window> next_window = std::nullopt;
auto original_it = it;
do {
Expand All @@ -123,10 +108,10 @@ void ApplicationSelector::advise_delete_app(Application const& application)
{
break;
}
} while ((next_window = tools.window_to_select_application(it->lock())) == std::nullopt);
} while ((next_window = tools.window_to_select_application(application)) == std::nullopt);

if (next_window != std::nullopt)
active_window = next_window.value();
selected = next_window.value();

if (it != original_it)
selected = *it;
Expand All @@ -135,21 +120,22 @@ void ApplicationSelector::advise_delete_app(Application const& application)
focus_list.erase(it);
}

auto ApplicationSelector::next() -> Application
auto ApplicationSelector::next(bool within_app) -> Window
{
return advance(false);
return advance(false, within_app);
}

auto ApplicationSelector::prev() -> Application
auto ApplicationSelector::prev(bool within_app) -> Window
{
return advance(true);
return advance(true, within_app);
}

auto ApplicationSelector::complete() -> Application
auto ApplicationSelector::complete() -> Window
{
if (!is_active())
{
return nullptr;
mir::log_warning("complete: application selector is not active");
return {};
}

// Place the newly selected item at the front of the list.
Expand All @@ -159,46 +145,40 @@ auto ApplicationSelector::complete() -> Application
std::rotate(focus_list.begin(), it, it + 1);
}

originally_selected.reset();
return selected.lock();
originally_selected = Window();
is_moving = false;
return selected;
}

void ApplicationSelector::cancel()
{
std::optional<Window> window_to_select;
if ((window_to_select = tools.window_to_select_application(originally_selected.lock())) != std::nullopt)
{
tools.select_active_window(window_to_select.value());
}
else
{
mir::log_warning("ApplicationSelector::cancel: Failed to select the root.");
}

originally_selected.reset();
tools.select_active_window(originally_selected);
originally_selected = Window();
is_moving = false;
}

auto ApplicationSelector::is_active() -> bool
auto ApplicationSelector::is_active() const -> bool
{
return !originally_selected.expired();
return is_moving;
}

auto ApplicationSelector::get_focused() -> Application
auto ApplicationSelector::get_focused() -> Window
{
return selected.lock();
return selected;
}

auto ApplicationSelector::advance(bool reverse) -> Application
auto ApplicationSelector::advance(bool reverse, bool within_app) -> Window
{
if (focus_list.empty())
{
return nullptr;
return {};
}

if (!is_active())
{
originally_selected = focus_list.front();
selected = originally_selected;
is_moving = true;
}

// Attempt to focus the next application after the selected application.
Expand Down Expand Up @@ -230,34 +210,47 @@ auto ApplicationSelector::advance(bool reverse) -> Application
// We made it all the way through the list but failed to find anything.
if (it == start_it)
break;
} while ((next_window = tools.window_to_select_application(it->lock())) == std::nullopt);

if (within_app)
{
if (it->application() == originally_selected.application() && tools.can_select_window(*it))
next_window = *it;
else
next_window = std::nullopt;
}
else
{
next_window = tools.window_to_select_application(it->application());
}
} while (next_window == std::nullopt);

if (it == start_it || next_window == std::nullopt)
{
// next_window will be a garbage window in this case, so let's not select it
return start_it->lock();
return *start_it;
}

// Swap the tree order first and then select the new window
if (it->lock() == originally_selected.lock())
if (*it == originally_selected)
{
// Edge case: if we have gone full circle around the list back to the original app
// then we will wind up in a situation where the original app - now in the second z-order
// position - will be swapped with the final app, putting the final app in the second position.
for (auto window: tools.info_for(selected).windows())
auto application = it->application();
for (auto& window: tools.info_for(application).windows())
tools.send_tree_to_back(window);
}
else
tools.swap_tree_order(next_window.value(), active_window);
tools.swap_tree_order(next_window.value(), selected);

tools.select_active_window(next_window.value());
return it->lock();
return *it;
}

auto ApplicationSelector::find(WeakApplication application) -> std::vector<WeakApplication>::iterator
auto ApplicationSelector::find(Window window) -> std::vector<Window>::iterator
{
return std::find_if(focus_list.begin(), focus_list.end(), [&](WeakApplication const& existing_application)
return std::find_if(focus_list.begin(), focus_list.end(), [&](Window const& other)
{
return !existing_application.owner_before(application) && !application.owner_before(existing_application);
return window == other;
});
}
Loading
Loading