Mir

Merge lp:~alan-griffiths/mir/even-NullWindowManager-configures-surface into lp:mir

Proposed by Alan Griffiths
Status: Rejected
Rejected by: Alan Griffiths
Proposed branch: lp:~alan-griffiths/mir/even-NullWindowManager-configures-surface
Merge into: lp:mir
Diff against target: 264 lines (+69/-68)
5 files modified
include/server/mir/shell/skeleton_window_manager.h (+4/-4)
src/server/shell/CMakeLists.txt (+3/-3)
src/server/shell/abstract_shell.cpp (+1/-1)
src/server/shell/skeleton_window_manager.cpp (+39/-38)
src/server/symbols.map (+22/-22)
To merge this branch: bzr merge lp:~alan-griffiths/mir/even-NullWindowManager-configures-surface
Reviewer Review Type Date Requested Status
Alexandros Frantzis (community) Needs Information
Daniel van Vugt Needs Fixing
PS Jenkins bot (community) continuous-integration Approve
Robert Carr (community) Approve
Review via email: mp+254123@code.launchpad.net

Commit message

shell: add surface->configure() call to NullWindowManager::set_surface_attribute()

Description of the change

shell: add surface->configure() call to NullWindowManager::set_surface_attribute()

back in -c2391 AbstractShell stopped configuring the surface to give the window manager more control. But that silently changed NullWindowManager from allowing everything to preventing everything. This reverts that unintended effect.

Yes, as downstreams can NullWindowManager there ought to be some tests about. I've added it to my list but wanted this fix to have a chance to land early.

To post a comment you must log in.
Revision history for this message
Robert Carr (robertcarr) wrote :

Raises some questions about the name ;) but ok.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

It's not the first time the difference between Null, Stub and Fake has become murky.

Although I suspect if this class is being used in libmirserver in production then a name other than "Null..." is called for.

review: Needs Information
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

In fact if "NullSomething" is in production use, the base class "Something" should become the null implementation. Instead of a pure virtual interface.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Hopefully a name with raising fewer questions.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) :
review: Abstain
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

It's slightly better, but I think removing the words {Skelton,Null} (and avoiding the pure virtual base class) would be much better.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
2427. By Alan Griffiths

merge lp:mir

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Come to think of it, establishing new precedent is important. Because people often refer to precedent and consistency in their reasoning. Even as a reason to reject more simplistic and maintainable designs. So we need to break the mold ASAP.

In cases like this where a class used in production is kind of like Null, kind of like Stub, and very much useful in its bare form, I think this is where those prefixes (including Skeleton) should not be used. So rename SkeletonWindowManager -> WindowManager and remove the existing pure virtual one.

This not only results in less typing, but fewer classes and less maintenance. As "Null" and "Stub" forms need never exist (they do implicitly). You can still add a Mock form later if required.

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> Come to think of it, establishing new precedent is important. Because people
> often refer to precedent and consistency in their reasoning. Even as a reason
> to reject more simplistic and maintainable designs.

I agree that precedents are important. However, "new precedents" should be avoided when they break consistency and introduce simplistic designs.

> So we need to break the
> mold ASAP.

I do not see any need (and certainly not an urgent one) to break from the well established industry practice of having pure virtual interfaces. (This has been widely followed for at least 20 years. See, for example, Barton & Nackman from 1994.)

> In cases like this where a class used in production is kind of like Null, kind
> of like Stub, and very much useful in its bare form, I think this is where
> those prefixes (including Skeleton) should not be used. So rename
> SkeletonWindowManager -> WindowManager and remove the existing pure virtual
> one.

I can remember when I was naive enough to "know better" and entertained thought like this, but experience has taught me that what appear at first to be exceptions are often not as the system evolves over time.

> This not only results in less typing, but fewer classes and less maintenance.
> As "Null" and "Stub" forms need never exist (they do implicitly). You can
> still add a Mock form later if required.

Much more important than reducing typing is reducing reading. Avoiding the need to go look at the implementation of what looks like an interface to discover whether it actually has an implementation is going to save far more time over the life of a project than saving eight keystrokes.

Introducing a precedent like the one you propose will add that cost to every interface in the system - as the reader will never be certain which classes are exceptions to the general rule.

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

In addition to being consistent with our existing practices, implementing a pure abstract/interface is more straightforward for users since they can be sure it comes without any hidden baggage.

I do have some concerns about having a Null/SkeletonWindowManager in the first place (at least as a public production interface), though. Allowing users to inherit from such a class, creates a coupling with the implementation, which I am not convinced is worth it for what this class has to offer (at the moment at least). Why, as things stand, do we want to offer SkeletonWindowManager vs just offering the WindowManager interface?

review: Needs Information
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> I do have some concerns about having a Null/SkeletonWindowManager in the first
> place (at least as a public production interface), though. Allowing users to
> inherit from such a class, creates a coupling with the implementation, which I
> am not convinced is worth it for what this class has to offer (at the moment
> at least). Why, as things stand, do we want to offer SkeletonWindowManager vs
> just offering the WindowManager interface?

As the window manager has to implement some minimal (as opposed to null) behavior I think we should provide this (as opposed to documenting it).

The use comes in two places:

1. the default window management logic is inconvenient for a number of our acceptance tests (e.g. they don't expect surfaces to be resized or placed). These use SkeletonWindowManager to disable the default.

2. Unity8 also finds the default window management logic is inconvenient and, as it currently uses different (older) customization points[*]. NullWindowManager provides a simple way to disable the default.

[*] It is very plausible that, after 0.13, Unity8 will be able to migrate to using the WindowManager interface for customizing window management (and we will then remove the interfaces it currently employs).

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> As the window manager has to implement some minimal (as opposed to null) behavior I think we
> should provide this (as opposed to documenting it).
>
> The use comes in two places:
>
> 1. the default window management logic is inconvenient for a number of our acceptance tests
> (e.g. they don't expect surfaces to be resized or placed). These use SkeletonWindowManager
> to disable the default.
>
> 2. Unity8 also finds the default window management logic is inconvenient and, as it currently
> uses different (older) customization points[*]. NullWindowManager provides a simple way to
> disable the default.

I am OK providing an (almost) null implementation for the use cases you mention. I would prefer it if it was not possible to inherit from this class, though.

To use the SkeletonWindowManager class as a base effectively, especially the methods that have a non-null implementation, the user needs to know what that class method do and do not do, which may change between releases, and I think this is a bigger burden for the user than just having to know that, e.g., set_surface_attribute() needs to configure the surface.

How about making SkeletonWindowManager "final", or perhaps a function "shared_ptr<WindowManager> make_skeleton_window_manager()" (and make the class internal)?

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> I am OK providing an (almost) null implementation for the use cases you
> mention. I would prefer it if it was not possible to inherit from this class,
> though.

Why? It is entirely possible for a responsible user to specialize the class successfully.

> To use the SkeletonWindowManager class as a base effectively, especially the
> methods that have a non-null implementation, the user needs to know what that
> class method do and do not do, which may change between releases, and I think
> this is a bigger burden for the user than just having to know that, e.g.,
> set_surface_attribute() needs to configure the surface.

I don't think that is true. If overriding from a concrete class one should (with rare exceptions) call the overridden function from the override. For the user to assume that it is null omitting the call is a mistake, but not one we should be protecting them from.

> How about making SkeletonWindowManager "final", or perhaps a function
> "shared_ptr<WindowManager> make_skeleton_window_manager()" (and make the class
> internal)?

Personally, I'd only ever declare a class or method final if overriding were automatically an error (or, somehow, violates a design contract). But I could live with it.

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> Why? It is entirely possible for a responsible user to specialize the class successfully

It is entirely possible, and more straightforward (IMO, read below), for a responsible user to directly use the WindowManager interface directly, too :)

> I don't think that is true. If overriding from a concrete class one should (with rare exceptions)
> call the overridden function from the override. For the user to assume that it is null omitting the
> call is a mistake, but not one we should be protecting them from.

I am more concerned about the order of the call to the overriden function in the new code, rather than whether the function is called or not. In order to write correct code the user needs to know what the overriden function does (e.g. in the set_surface_attribute() case that it calls surface->configure()), to avoid performing the same action again (e.g. call surface->configure() again), and ensure that it's called at the correct point in the new code.

In addition, we are making the implementation details of SkeletonWindowManager part of our effective ABI.

All of the above are general issues with inheriting implementation, and present a trade-off that sometimes is worth it. I am leaning towards "not worth it" in this particular case.

Needs discussion

review: Needs Information
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

I have to correct my earlier answer:

Although I had some tests using [Null|Skeleton]WindowManager at one point there no longer any on any active branch.

OTOH unity-system-compositor /src/window_manager.h derives from mir::shell::NullWindowManager and this use would be broken by making the class final.

The use in Unity8 is as described.

So, given the discussion this has provoked here I'm probably best just moving the code to the downstream projects.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Equally, my 20+ years of programming experience tells me to do the opposite. :) I can suggest, but not force change. Mir is a democracy.

Unmerged revisions

2427. By Alan Griffiths

merge lp:mir

2426. By Alan Griffiths

merge lp:mir

2425. By Alan Griffiths

NullWindowManager => SkeletonWindowManager

2424. By Alan Griffiths

NullWindowManager should configure surface

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== renamed file 'include/server/mir/shell/null_window_manager.h' => 'include/server/mir/shell/skeleton_window_manager.h'
--- include/server/mir/shell/null_window_manager.h 2015-03-25 02:48:40 +0000
+++ include/server/mir/shell/skeleton_window_manager.h 2015-03-27 12:00:42 +0000
@@ -16,8 +16,8 @@
16 * Authored By: Alan Griffiths <alan@octopull.co.uk>16 * Authored By: Alan Griffiths <alan@octopull.co.uk>
17 */17 */
1818
19#ifndef MIR_SHELL_NULL_WINDOW_MANAGER_H_19#ifndef MIR_SHELL_SKELETON_WINDOW_MANAGER_H_
20#define MIR_SHELL_NULL_WINDOW_MANAGER_H_20#define MIR_SHELL_SKELETON_WINDOW_MANAGER_H_
2121
22#include "mir/shell/window_manager.h"22#include "mir/shell/window_manager.h"
2323
@@ -25,7 +25,7 @@
25{25{
26namespace shell26namespace shell
27{27{
28class NullWindowManager : public WindowManager28class SkeletonWindowManager : public WindowManager
29{29{
30public:30public:
31 void add_session(std::shared_ptr<scene::Session> const& session) override;31 void add_session(std::shared_ptr<scene::Session> const& session) override;
@@ -60,4 +60,4 @@
60}60}
61}61}
6262
63#endif /* MIR_SHELL_NULL_WINDOW_MANAGER_H_ */63#endif /* MIR_SHELL_SKELETON_WINDOW_MANAGER_H_ */
6464
=== modified file 'src/server/shell/CMakeLists.txt'
--- src/server/shell/CMakeLists.txt 2015-03-25 02:48:40 +0000
+++ src/server/shell/CMakeLists.txt 2015-03-27 12:00:42 +0000
@@ -2,13 +2,13 @@
2 SHELL_SOURCES2 SHELL_SOURCES
33
4 abstract_shell.cpp4 abstract_shell.cpp
5 default_configuration.cpp
5 default_placement_strategy.cpp6 default_placement_strategy.cpp
7 default_window_manager.cpp
6 frontend_shell.cpp8 frontend_shell.cpp
7 graphics_display_layout.cpp9 graphics_display_layout.cpp
8 default_configuration.cpp
9 default_window_manager.cpp
10 null_window_manager.cpp
11 shell_wrapper.cpp10 shell_wrapper.cpp
11 skeleton_window_manager.cpp
12)12)
1313
14add_library(14add_library(
1515
=== modified file 'src/server/shell/abstract_shell.cpp'
--- src/server/shell/abstract_shell.cpp 2015-03-25 02:48:40 +0000
+++ src/server/shell/abstract_shell.cpp 2015-03-27 12:00:42 +0000
@@ -18,7 +18,7 @@
1818
19#include "mir/shell/abstract_shell.h"19#include "mir/shell/abstract_shell.h"
20#include "mir/shell/input_targeter.h"20#include "mir/shell/input_targeter.h"
21#include "mir/shell/null_window_manager.h"21#include "mir/shell/window_manager.h"
22#include "mir/scene/prompt_session.h"22#include "mir/scene/prompt_session.h"
23#include "mir/scene/prompt_session_manager.h"23#include "mir/scene/prompt_session_manager.h"
24#include "mir/scene/session_coordinator.h"24#include "mir/scene/session_coordinator.h"
2525
=== renamed file 'src/server/shell/null_window_manager.cpp' => 'src/server/shell/skeleton_window_manager.cpp'
--- src/server/shell/null_window_manager.cpp 2015-03-25 02:48:40 +0000
+++ src/server/shell/skeleton_window_manager.cpp 2015-03-27 12:00:42 +0000
@@ -16,22 +16,23 @@
16 * Authored By: Alan Griffiths <alan@octopull.co.uk>16 * Authored By: Alan Griffiths <alan@octopull.co.uk>
17 */17 */
1818
19#include "mir/shell/null_window_manager.h"19#include "mir/shell/skeleton_window_manager.h"
20#include "mir/scene/surface.h"
2021
21namespace mf = mir::frontend;22namespace mf = mir::frontend;
22namespace ms = mir::scene;23namespace ms = mir::scene;
23namespace msh = mir::shell;24namespace msh = mir::shell;
2425
2526
26void msh::NullWindowManager::add_session(std::shared_ptr<scene::Session> const& /*session*/)27void msh::SkeletonWindowManager::add_session(std::shared_ptr<scene::Session> const& /*session*/)
27{28{
28}29}
2930
30void msh::NullWindowManager::remove_session(std::shared_ptr<scene::Session> const& /*session*/)31void msh::SkeletonWindowManager::remove_session(std::shared_ptr<scene::Session> const& /*session*/)
31{32{
32}33}
3334
34auto msh::NullWindowManager::add_surface(35auto msh::SkeletonWindowManager::add_surface(
35 std::shared_ptr<scene::Session> const& session,36 std::shared_ptr<scene::Session> const& session,
36 scene::SurfaceCreationParameters const& params,37 scene::SurfaceCreationParameters const& params,
37 std::function<frontend::SurfaceId(std::shared_ptr<scene::Session> const& session, scene::SurfaceCreationParameters const& params)> const& build)38 std::function<frontend::SurfaceId(std::shared_ptr<scene::Session> const& session, scene::SurfaceCreationParameters const& params)> const& build)
@@ -40,40 +41,40 @@
40 return build(session, params);41 return build(session, params);
41}42}
4243
43void msh::NullWindowManager::remove_surface(44void msh::SkeletonWindowManager::remove_surface(
44 std::shared_ptr<scene::Session> const& /*session*/,45 std::shared_ptr<scene::Session> const& /*session*/,
45 std::weak_ptr<scene::Surface> const& /*surface*/)46 std::weak_ptr<scene::Surface> const& /*surface*/)
46{47{
47}48}
4849
49void msh::NullWindowManager::add_display(geometry::Rectangle const& /*area*/)50void msh::SkeletonWindowManager::add_display(geometry::Rectangle const& /*area*/)
50{51{
51}52}
5253
53void msh::NullWindowManager::remove_display(geometry::Rectangle const& /*area*/)54void msh::SkeletonWindowManager::remove_display(geometry::Rectangle const& /*area*/)
54{55{
55}56}
5657
57bool msh::NullWindowManager::handle_key_event(MirKeyboardEvent const* /*event*/)58bool msh::SkeletonWindowManager::handle_key_event(MirKeyboardEvent const* /*event*/)
58{59{
59 return false;60 return false;
60}61}
6162
62bool msh::NullWindowManager::handle_touch_event(MirTouchEvent const* /*event*/)63bool msh::SkeletonWindowManager::handle_touch_event(MirTouchEvent const* /*event*/)
63{64{
64 return false;65 return false;
65}66}
6667
67bool msh::NullWindowManager::handle_pointer_event(MirPointerEvent const* /*event*/)68bool msh::SkeletonWindowManager::handle_pointer_event(MirPointerEvent const* /*event*/)
68{69{
69 return false;70 return false;
70}71}
7172
72int msh::NullWindowManager::set_surface_attribute(73int msh::SkeletonWindowManager::set_surface_attribute(
73 std::shared_ptr<scene::Session> const& /*session*/,74 std::shared_ptr<scene::Session> const& /*session*/,
74 std::shared_ptr<scene::Surface> const& /*surface*/,75 std::shared_ptr<scene::Surface> const& surface,
75 MirSurfaceAttrib /*attrib*/,76 MirSurfaceAttrib attrib,
76 int value)77 int value)
77{78{
78 return value;79 return surface->configure(attrib, value);
79}80}
8081
=== modified file 'src/server/symbols.map'
--- src/server/symbols.map 2015-03-27 06:58:51 +0000
+++ src/server/symbols.map 2015-03-27 12:00:42 +0000
@@ -222,16 +222,6 @@
222 mir::shell::InputTargeter::?InputTargeter*;222 mir::shell::InputTargeter::?InputTargeter*;
223 mir::shell::InputTargeter::InputTargeter*;223 mir::shell::InputTargeter::InputTargeter*;
224 mir::shell::InputTargeter::operator*;224 mir::shell::InputTargeter::operator*;
225 mir::shell::NullWindowManager::add_display*;
226 mir::shell::NullWindowManager::add_session*;
227 mir::shell::NullWindowManager::add_surface*;
228 mir::shell::NullWindowManager::handle_key_event*;
229 mir::shell::NullWindowManager::handle_pointer_event*;
230 mir::shell::NullWindowManager::handle_touch_event*;
231 mir::shell::NullWindowManager::remove_display*;
232 mir::shell::NullWindowManager::remove_session*;
233 mir::shell::NullWindowManager::remove_surface*;
234 mir::shell::NullWindowManager::set_surface_attribute*;
235 mir::shell::ShellWrapper::add_display*;225 mir::shell::ShellWrapper::add_display*;
236 mir::shell::ShellWrapper::add_prompt_provider_for*;226 mir::shell::ShellWrapper::add_prompt_provider_for*;
237 mir::shell::ShellWrapper::close_session*;227 mir::shell::ShellWrapper::close_session*;
@@ -251,6 +241,16 @@
251 mir::shell::ShellWrapper::start_prompt_session_for*;241 mir::shell::ShellWrapper::start_prompt_session_for*;
252 mir::shell::ShellWrapper::stop_prompt_session*;242 mir::shell::ShellWrapper::stop_prompt_session*;
253 mir::shell::ShellWrapper::surface_at*;243 mir::shell::ShellWrapper::surface_at*;
244 mir::shell::SkeletonWindowManager::add_display*;
245 mir::shell::SkeletonWindowManager::add_session*;
246 mir::shell::SkeletonWindowManager::add_surface*;
247 mir::shell::SkeletonWindowManager::handle_key_event*;
248 mir::shell::SkeletonWindowManager::handle_pointer_event*;
249 mir::shell::SkeletonWindowManager::handle_touch_event*;
250 mir::shell::SkeletonWindowManager::remove_display*;
251 mir::shell::SkeletonWindowManager::remove_session*;
252 mir::shell::SkeletonWindowManager::remove_surface*;
253 mir::shell::SkeletonWindowManager::set_surface_attribute*;
254 mir::shell::WindowManager::operator*;254 mir::shell::WindowManager::operator*;
255 mir::shell::WindowManager::?WindowManager*;255 mir::shell::WindowManager::?WindowManager*;
256 mir::shell::WindowManager::WindowManager*;256 mir::shell::WindowManager::WindowManager*;
@@ -324,16 +324,6 @@
324 non-virtual?thunk?to?mir::shell::FocusController::?FocusController*;324 non-virtual?thunk?to?mir::shell::FocusController::?FocusController*;
325 non-virtual?thunk?to?mir::shell::HostLifecycleEventListener::?HostLifecycleEventListener*;325 non-virtual?thunk?to?mir::shell::HostLifecycleEventListener::?HostLifecycleEventListener*;
326 non-virtual?thunk?to?mir::shell::InputTargeter::?InputTargeter*;326 non-virtual?thunk?to?mir::shell::InputTargeter::?InputTargeter*;
327 non-virtual?thunk?to?mir::shell::NullWindowManager::add_display*;
328 non-virtual?thunk?to?mir::shell::NullWindowManager::add_session*;
329 non-virtual?thunk?to?mir::shell::NullWindowManager::add_surface*;
330 non-virtual?thunk?to?mir::shell::NullWindowManager::handle_key_event*;
331 non-virtual?thunk?to?mir::shell::NullWindowManager::handle_pointer_event*;
332 non-virtual?thunk?to?mir::shell::NullWindowManager::handle_touch_event*;
333 non-virtual?thunk?to?mir::shell::NullWindowManager::remove_display*;
334 non-virtual?thunk?to?mir::shell::NullWindowManager::remove_session*;
335 non-virtual?thunk?to?mir::shell::NullWindowManager::remove_surface*;
336 non-virtual?thunk?to?mir::shell::NullWindowManager::set_surface_attribute*;
337 non-virtual?thunk?to?mir::shell::ShellWrapper::add_display*;327 non-virtual?thunk?to?mir::shell::ShellWrapper::add_display*;
338 non-virtual?thunk?to?mir::shell::ShellWrapper::add_prompt_provider_for*;328 non-virtual?thunk?to?mir::shell::ShellWrapper::add_prompt_provider_for*;
339 non-virtual?thunk?to?mir::shell::ShellWrapper::close_session*;329 non-virtual?thunk?to?mir::shell::ShellWrapper::close_session*;
@@ -352,6 +342,16 @@
352 non-virtual?thunk?to?mir::shell::ShellWrapper::start_prompt_session_for*;342 non-virtual?thunk?to?mir::shell::ShellWrapper::start_prompt_session_for*;
353 non-virtual?thunk?to?mir::shell::ShellWrapper::stop_prompt_session*;343 non-virtual?thunk?to?mir::shell::ShellWrapper::stop_prompt_session*;
354 non-virtual?thunk?to?mir::shell::ShellWrapper::surface_at*;344 non-virtual?thunk?to?mir::shell::ShellWrapper::surface_at*;
345 non-virtual?thunk?to?mir::shell::SkeletonWindowManager::add_display*;
346 non-virtual?thunk?to?mir::shell::SkeletonWindowManager::add_session*;
347 non-virtual?thunk?to?mir::shell::SkeletonWindowManager::add_surface*;
348 non-virtual?thunk?to?mir::shell::SkeletonWindowManager::handle_key_event*;
349 non-virtual?thunk?to?mir::shell::SkeletonWindowManager::handle_pointer_event*;
350 non-virtual?thunk?to?mir::shell::SkeletonWindowManager::handle_touch_event*;
351 non-virtual?thunk?to?mir::shell::SkeletonWindowManager::remove_display*;
352 non-virtual?thunk?to?mir::shell::SkeletonWindowManager::remove_session*;
353 non-virtual?thunk?to?mir::shell::SkeletonWindowManager::remove_surface*;
354 non-virtual?thunk?to?mir::shell::SkeletonWindowManager::set_surface_attribute*;
355 non-virtual?thunk?to?mir::shell::WindowManager::?WindowManager*;355 non-virtual?thunk?to?mir::shell::WindowManager::?WindowManager*;
356 non-virtual?thunk?to?mir::time::Alarm::?Alarm*;356 non-virtual?thunk?to?mir::time::Alarm::?Alarm*;
357 non-virtual?thunk?to?mir::time::AlarmFactory::?AlarmFactory*;357 non-virtual?thunk?to?mir::time::AlarmFactory::?AlarmFactory*;
@@ -405,9 +405,9 @@
405 typeinfo?for?mir::shell::FocusController;405 typeinfo?for?mir::shell::FocusController;
406 typeinfo?for?mir::shell::HostLifecycleEventListener;406 typeinfo?for?mir::shell::HostLifecycleEventListener;
407 typeinfo?for?mir::shell::InputTargeter;407 typeinfo?for?mir::shell::InputTargeter;
408 typeinfo?for?mir::shell::NullWindowManager;
409 typeinfo?for?mir::shell::Shell;408 typeinfo?for?mir::shell::Shell;
410 typeinfo?for?mir::shell::ShellWrapper;409 typeinfo?for?mir::shell::ShellWrapper;
410 typeinfo?for?mir::shell::SkeletonWindowManager;
411 typeinfo?for?mir::shell::WindowManager;411 typeinfo?for?mir::shell::WindowManager;
412 typeinfo?for?mir::time::Alarm;412 typeinfo?for?mir::time::Alarm;
413 typeinfo?for?mir::time::AlarmFactory;413 typeinfo?for?mir::time::AlarmFactory;
@@ -461,9 +461,9 @@
461 vtable?for?mir::shell::FocusController;461 vtable?for?mir::shell::FocusController;
462 vtable?for?mir::shell::HostLifecycleEventListener;462 vtable?for?mir::shell::HostLifecycleEventListener;
463 vtable?for?mir::shell::InputTargeter;463 vtable?for?mir::shell::InputTargeter;
464 vtable?for?mir::shell::NullWindowManager;
465 vtable?for?mir::shell::Shell;464 vtable?for?mir::shell::Shell;
466 vtable?for?mir::shell::ShellWrapper;465 vtable?for?mir::shell::ShellWrapper;
466 vtable?for?mir::shell::SkeletonWindowManager;
467 vtable?for?mir::shell::WindowManager;467 vtable?for?mir::shell::WindowManager;
468 vtable?for?mir::time::Alarm;468 vtable?for?mir::time::Alarm;
469 vtable?for?mir::time::AlarmFactory;469 vtable?for?mir::time::AlarmFactory;

Subscribers

People subscribed via source and target branches