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

Add APIs to override decoration managers and customize decorations (Take 2) #3666

Draft
wants to merge 27 commits into
base: main
Choose a base branch
from

Conversation

tarek-y-ismail
Copy link
Contributor

@tarek-y-ismail tarek-y-ismail commented Nov 12, 2024

Attempt 1: Naive. Trying to expose an internal (an unstable) mir API to users.
Attempt 2: Bottom up. Trying to bring out the API from msd::BasicDecoration and expose it via adapters.
Attempt 3: Top down. Trying to extract the minimal API needed for users to implement at least something similar to msd::BasicDecoration (The code is nasty on purpose)

Copy link
Contributor

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

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

Proposing the interface for review without "dragging implementation code along" is good.

However, I would rather have focused first on separating out the "policy" part of decorations as otherwise the miral::*Decoration* interface is somewhat speculative. (In particular, there's no way to "hook up" input in the current draft.)

examples/miral-shell/decoration/CMakeLists.txt Outdated Show resolved Hide resolved
{
public:
static auto build(
std::function<void(std::weak_ptr<mir::shell::Shell> const& shell)> on_init,
Copy link
Contributor

Choose a reason for hiding this comment

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

User code shouldn't be using Shell so there's no point to this functor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looking at BasicDecoration, it uses the shell for a bunch of things: resizing itself, moving, maximizing, minimizing, etc..

Is there another way to access this functionality?

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it would be a good thing to work on isolating the decoration "strategy" code before designing the API to customise it?

src/include/server/mir/default_server_configuration.h Outdated Show resolved Hide resolved
src/miral/custom_decorations.cpp Outdated Show resolved Hide resolved
src/miral/custom_decorations.cpp Outdated Show resolved Hide resolved
src/server/shell/default_configuration.cpp Outdated Show resolved Hide resolved
src/server/symbols.map Show resolved Hide resolved
examples/miral-shell/shell_main.cpp Outdated Show resolved Hide resolved
@@ -135,6 +138,7 @@ int main(int argc, char const* argv[])

return runner.run_with(
{
CustomDecorations{UserDecorationManagerExample::get_adapter()},
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the adaptor created once on program startup and used for all decorations? Or might it need to maintain state associated with each window (and therefore be created once per window?)

Copy link
Contributor Author

@tarek-y-ismail tarek-y-ismail Nov 13, 2024

Choose a reason for hiding this comment

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

Is the adaptor created once on program startup and used for all decorations?

Yep.

Or might it need to maintain state associated with each window (and therefore be created once per window?)

As it stands with BasicDecoration, the manager keeps track of decorations, and each decoration has it's own window-specific state.

Comment on lines +39 to +54
class DecorationManagerBuilder
{
public:
static auto build(
std::function<void(std::weak_ptr<mir::shell::Shell> const& shell)> on_init,
std::function<void(std::shared_ptr<mir::scene::Surface> const& surface)> on_decorate,
std::function<void(std::shared_ptr<mir::scene::Surface> const& surface)> on_undecorate,
std::function<void()> on_undecorate_all) -> DecorationManagerBuilder;

auto done() -> std::shared_ptr<DecorationManagerAdapter>;

private:
DecorationManagerBuilder();
std::shared_ptr<DecorationManagerAdapter> adapter;
};
}
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. I think the implementation type should be opaque (e.g. DecorationManagerBuilder::Self) for future proofing. (It could currently be a trivial subclass of DecorationManagerAdapter)
  2. There needs to be a way to attach functors for input handling in addition to the decorate handling.

tarek-y-ismail and others added 18 commits November 13, 2024 11:30
This should guarantee that the lifetime is extended since `self` is a
shared ptr
The implementation is now called `UserDecoration` and is implemented as
an external class in miral-shell. The interface does book keeping of the
necessary data members.
Copy link
Contributor

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

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

OK, you said this was "ready to review", but I now see it change whilst reviewing. I'll leave it for now and just post what I've seen so far

Comment on lines 17 to 19
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why?

Copy link
Contributor

Choose a reason for hiding this comment

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

Unused?

Copy link
Contributor

Choose a reason for hiding this comment

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

Unused?

@@ -14,6 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "decoration/decoration.h"
#include "miral/decoration.h"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
#include "miral/decoration.h"

Comment on lines +43 to +44
#include <string>
#include <vector>
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
#include <string>
#include <vector>

Comment on lines +142 to +172
return runner.run_with({
CustomDecorations{UserDecoration::create_manager},
CursorTheme{"default:DMZ-White"},
WaylandExtensions{},
X11Support{},
ConfigureDecorations{},
window_managers,
display_configuration_options,
external_client_launcher,
launcher,
config_keymap,
AppendEventFilter{quit_on_ctrl_alt_bksp},
StartupInternalClient{spinner},
ConfigurationOption{run_startup_apps, "startup-apps", "Colon separated list of startup apps", ""},
pre_init(ConfigurationOption{
[&](std::string const& typeface)
{
::wallpaper::font_file(typeface);
},
"shell-wallpaper-font",
"font file to use for wallpaper",
::wallpaper::font_file()}),
ConfigurationOption{
[&](std::string const& cmd)
{
terminal_cmd = cmd;
},
"shell-terminal-emulator",
"terminal emulator to use",
terminal_cmd},
});
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the only substantive change is adding CustomDecorations{UserDecoration::create_manager},. The rest is unnecessary, and distracting, whitespace adjustment

Copy link
Contributor

Choose a reason for hiding this comment

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

Not used by the example: shouldn't be part of the API

Comment on lines +43 to 52
class DecorationBasicManager
{
public:
DecorationBasicManager(mir::Server&, Decoration::DecorationBuilder&&);

auto to_adapter() -> std::shared_ptr<DecorationManagerAdapter>;
private:
Decoration(Decoration const&) = delete;
Decoration& operator=(Decoration const&) = delete;
struct Self;
std::shared_ptr<Self> self;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

There doesn't seem to be much purpose to this class. It takes "stuff" in its constructor and returns "other stuff" from to_adapter() - that's pretty much a function in disguise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants