Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
Porting unity-system-compositor to MirAL #1
Comments
jsalatas
added
enhancement
help wanted
labels
Jul 12, 2017
WebDrake
commented
Jul 28, 2017
|
@AlanGriffiths I'm curious about this, though I'd really appreciate a bit more info before I commit to actually doing this (time is limited...). I've never worked on this kind of project before (which is part of why it's interesting) so would appreciate any advice you can share on getting started and getting up to speed. First question: how come there is a dependency on Second, can the immediate focus here be on stripping out any references to Third, it seems fairly trivial to build the present code on an Ubuntu 16.04 system once the dependencies are installed (all from repos), but is there any particular setup I should aim for (particularly w.r.t. getting set up with having MirAL available, since I don't see any Finally, are there any particular libraries or technologies that I should make sure to read up on and understand properly before diving into this? Thanks in advance for any advice that you can share. |
|
@WebDrake libmiral is not in the standard repos of 16.04. It is however in yunit's repo for 16.04. |
|
@WebDrake I'm happy share advice. We all have to make good use of limited time. Q1: Mir makes a strong distinction between clients and servers. Clients can paint surfaces and place them within a window, but the server controls the display and organizes the windows. Unlike X11 (for example) the shell logic exists in the server process which requires libmirserver. Q2: you've understood correctly, it is only the direct dependencies on libmirserver that are at issue here. (See the references below for the reasons.) Q3: MirAL wasn't an official project when Ubuntu 16.04 was released and adding a new project to an LTS needs more justification than currently exists. MirAL is in the 17.04 archive, but I suspect you will need some small additions to this code, so building it yourself will likely be necessary in any case. For development purposes you can follow the build instructions in the project directory, followed by:
This will install into /usr/local/ which avoids disrupting your system files. You can clear this out with:
I'd recommend this over using the yunit ppa on a development system (at the current time I think that is only ready for "disposable" test systems). A few of references for background: |
WebDrake
commented
Jul 29, 2017
|
@AlanGriffiths thanks very much for the detailed reply and the references! I've cloned upstream MirAL and unity-system-compositor using I'll take a while to read and understand the references (and code) as best I can, and follow up once I have results and/or further questions. |
WebDrake
commented
Jul 29, 2017
|
One quick further question. Do I understand right that the |
|
Not quite. The ones from mircore are also OK... $ find /usr/include/mircore/mir /usr/include/mirclient/mir/ -type f |
WebDrake
commented
Aug 7, 2017
|
What about |
|
I've not investigated, but I suspect any of those in USC those will be transitive dependencies through mirserver. |
WebDrake
commented
Aug 7, 2017
|
OK. I'm going through the codebase right now and will post a summary of findings/speculations about what needs to be addressed and how. |
WebDrake
commented
Aug 9, 2017
|
Brief summary of where I'm at. There are 2 ways in which mir functionality is included in USC: one via direct import of mir headers ( So, we can search for files that have these direct dependencies as follows: $ find ./src/ -type f -print0 | xargs -0 grep -e "include <mir" -e "namespace mir" | cut -d : -f1 | uniq | sort
./src/clock.h
./src/dbus_event_loop.h
./src/display_configuration_policy.cpp
./src/display_configuration_policy.h
./src/main.cpp
./src/mir_input_configuration.h
./src/mir_screen.cpp
./src/mir_screen.h
./src/screen_event_handler.cpp
./src/screen_event_handler.h
./src/screen.h
./src/server.cpp
./src/server.h
./src/session_monitor.h
./src/session_switcher.cpp
./src/system_compositor.cpp
./src/system_compositor.h
./src/window_manager.hNote, this is incomplete given that Let's examine a few of these in detail:
int main(argc, char const* argv[])
{
MirRunner runner{argc, argv};
// ... set up some other required data structures ...
return runner.run_with(required, data, structures);
}... since
Action itemsBased on the above, as far as I can see the work required can broadly be split into two parts:
Does all of this make sense? Have I misunderstood anything, or does this sound like a viable way forward? |
WebDrake
commented
Aug 9, 2017
Ah, re-reading |
|
That sounds like a very good summary of the current status. Your plan is very like what I did with the QtMir code, so there's reason to think it viable. As for the use of CachePtr - I'm not entirely convinced this is appropriate here. I suspect it exists in USC for historical reasons and is just a copy of an idiom used internally by Mir. Vis: This allows single-instance parts of the system infrastructure to be lazily-constructed, so long as something in the system is holding a shared_ptr<> to the part the weak_ptr<> will refer to it. But as soon as the last shared_ptr<> goes the part will be destroyed (and the weak_ptr<> will refer to nothing). It makes the initialisation code a little easier to maintain than trying to track the dependencies explicitly. |
|
Oh, and a passing thought: your best platform for experimenting with USC is probably Ubuntu 17.04 - this uses USC as part of the Unity8 desktop and you will be able to see the effect of a usr/local install of your build without changing any other components. |
WebDrake
commented
Aug 9, 2017
Yes, I had similar suspicions. I'll see if it's possible to remove as a by-product of the MirAL transition.
Thanks for that suggestion; until now I had just been running I have some work-in-progress here, in any case: The next step from here is to try to unpick the init callback added to the server instance in |
WebDrake
commented
Aug 10, 2017
|
@AlanGriffiths I have some questions related to command-line argument handling in MirAL. Context: Part of that transition could be done by just transitioning other parts of the code to use However, there are a few further complications.
Note, handling the |
WebDrake
commented
Aug 10, 2017
I note that if I take them outside the callback, they consistently return |
|
Some of these options are a mystery to me. I'd be inclined to check whether they are actually used (that involves spelunking though startup scripts). "public-socket" - seems to re-implement (badly) the functionality of "arw-file" with an oddly implemented default of "true". I doubt the option is ever supplied or set to false and it would be easier to simply "setenv("MIR_SERVER_ARW_FILE", "on", 1)" at the top of main(). At least as an interim measure. AFAICS "version" and "blacklist" can be implemented using miral::CommandLineOption - and that can be used in usc::SystemCompositor::run(). E.g.
The display manager config is a little more involved but basically needs to collect some parameters and then run some startup commands. This can be done with miral::CommandLineOption - note that these execute in the order they are applied to the server (so the earlier options can store the values for use by the later ones). The difficult bit here is Server::the_screen() has dependencies on Mir internals, I don't think that can yet be supported through MirAL. |
It happens during initialization, but depends on the platform. E.g. in mgmh::EGLHelper::setup() for mesa. You need the code to be in an init callback - but you can use miral::CommandLineOption to set that up. |
WebDrake
commented
Aug 10, 2017
I'd considered using an exception like this, but won't this cause the program to exit with |
It will if you just exit with the return code from run_with() (which is what the "blacklist" logic wants anyway). I was presuming that wouldn't harm anyone using "version" (because I imagine nobody uses it). But you can ignore what run_with() returns if you need to. |
WebDrake
commented
Aug 10, 2017
|
Yes, for miral::CommandLineOption version_flag{
[](bool is_set)
{
if (is_set)
{
std::cerr << "unity-system-compositor " << USC_VERSION << std::endl;
exit(0);
}
},
"version", "Show version of Unity System Compositor"};(I'm not sure if the |
It (or the kernel) should. OTOH I avoid exit() unless in main() - it tends to screw with testing. I'd set a flag:
|
WebDrake
referenced this issue
in WebDrake/unity-system-compositor
Aug 15, 2017
Open
Work-in-progress converting USC to use MirAL #1
WebDrake
commented
Aug 15, 2017
|
OK, time for a check-in I think. The latest state of the work can be reviewed in this PR: WebDrake#1 Note that I've deliberately submitted the PR within my own fork, since it's still work-in-progress, and since the master branch here is still missing the most recent patches from upstream (launchpad) USC. What's been done so far:
The current extent of testing is that it builds, that |
WebDrake
commented
Aug 15, 2017
|
Regarding earlier discussion about how to handle the
whereas if the opening of auto const server = std::make_shared<mir::Server>();
miral::CommandLineOption version_flag{
[](bool is_set)
{
if (is_set)
{
//std::cerr << "unity-system-compositor " << USC_VERSION << std::endl;
BOOST_THROW_EXCEPTION(
mir::AbnormalExit{std::string{"unity-system-compositor "} + USC_VERSION});
}
},
"version", "Show version of Unity System Compositor"
};
version_flag(*server);... then the output is very different:
|
Please notice that you don't commit to master in yunit repos. You commit to upstream which is a clean branch without any debian packaging specifics. Please have a look at the Developr's Howto Wiki https://github.com/yunit-io/documentation/wiki/Developer's-Howto and make sure you understand how git-buildpackage works |
Does it passes the tests or not yet? |
WebDrake
commented
Aug 15, 2017
My comments also apply to We should probably discuss that in the other issue I raised, though.
All the changes made have been checked against the available unit and integration tests (I've made that a minimum condition for making any commit). However, I think those are likely inadequate to the question of whether the code really works. There looks to be a lot that they don't cover. A simple example is this commit: WebDrake/unity-system-compositor@c42f366 Originally the |
|
The idea here is that canonical would stop maintaining these packages, so I imported these in git having in mind that we don't need to pull it again from launchpad. Obviously this doesn't seem to be the case so I'm just wondering if it is a good idea to submit your work to launchpad and then I can pull it from there. Regarding the tests, if all tests pass but it doesn't actually work for some reason, you probably need to write additional tests to cover that or (if you are busy to do so) open an issue explaining what needs to be done. |
|
as a final note, please notice that your mirserver-to-miral branch contains the debian directory (packaging) which we don't want to merge into our upstream. How will you take care of it? |
WebDrake
commented
Aug 15, 2017
Yes, I was thinking the same thing. But bear in mind this situation (of a local patch in an "upstream" branch) also applies to plenty of other yunit-io repos where upstream is actively maintained (e.g. MirAL). So it might be worth trying to set up a branch scheme that supports both use cases (i.e. one where yunit-io is now the maintainer, and ones where there is a real upstream). Personally I would be inclined to split things into:
... which looks to me to be quite in line with the git-buildpackage guidelines (certainly with their spirit and intent).
I don't think it should be an issue as that would be the original upstream
I'm happy to try to do so (either write them, or raise an issue) but it's not entirely obvious that these things are readily testable (I rather assume there would already be tests for them if they were). A lot of the issues are concerned with the sequence in which things happen during USC's startup, and hence they involve things like the DBus event loop, etc., where it's not obvious to me how one would mock these things. @AlanGriffiths I wonder if you could advise on what CI was/is used for USC other than that already defined via |
So another slightly different approach would be to create a new branch (let's call it launchpad) which would be in sync and could be fast-forwarded to launchpad's branch. That branch can be merged to our upstream (ie yunit's cleaned up branch) and from upstream we could have a master as we have now. Will that work for you? |
|
Oh an additional note here: based on my proposal above: we should create PRs to yunit's upstream branch. If for any reason you want to create a PR to launchpad branch then you should do it in yunit project but in launchpad an yunit will pull from there. Right? |
WebDrake
commented
Aug 15, 2017
|
@jsalatas can I suggest we follow up on the branch question in the dedicated issue? I would rather not further derail the focus of this issue from the mirserver -> miral transition. The TL;DR is that I'm happy to submit upstream (via Launchpad) or to work out some appropriate way of managing the code here. But I think the point of taking in code is a little way off, so we don't need to address that question now. |
|
OK! Please open an issue when you are ready to commit. |
WebDrake
commented
Aug 15, 2017
I will do so, or else I will announce it here. But in the meantime, any feedback or remarks on the patches already written would be very welcome. Apart from the questions above, this was the main point of checking in ;-) |
WebDrake
commented
Aug 15, 2017
|
@AlanGriffiths a further question related to Just as an experiment, I tried a super-simple "app" that only attempts to implement the #include <miral/command_line_option.h>
#include <miral/runner.h>
#include <iostream>
int main(int argc, char const* argv[])
{
miral::MirRunner runner{argc, argv, "unity-system-compositor.conf"};
miral::CommandLineOption version_flag{
[](bool is_set)
{
if (is_set)
{
std::cerr << "unity-system-compositor " << USC_VERSION << std::endl;
exit(0);
}
},
"version", "Show version of Unity System Compositor"
};
return runner.run_with({version_flag});
}Running the resulting executable with the
... which suggests that I'll dig deeper into this in the next days, but can you advise what's going on here and what is needed in order to address it? |
|
@WebDrake it looks as though one thing you are missing is the package mir-graphics-drivers-desktop. The CI for USC was never to my satisfaction: it depends on manual testing to ensure it worked. Even manual testing was a PITA (I added the --debug-without-dm and --debug-active-session-name options to make it possible to run from the desktop). You can run USC on X as follows:
And connect to it like this:
(This latter command will only work a couple of times in "debug" mode because the display manager is stubbed out.) I'll try to take a deeper look later today, but I may not get time. PS Canonical isn't maintaining USC, so you needn't worry about "upstream changes". |
WebDrake
commented
Aug 16, 2017
Ah, thanks! I can confirm that the stub "USC" above works once that is installed. It just outputs a lot more log messages than the real one before it gets to the version info. It also opens up a blank window (without the
Thanks for confirming what I already strongly suspected. To take one example: the
Cool; I shall have a play with this. Anything in particular I should be watching out for in terms of behaviour? Do I understand right that the second command will run
Understood. In the case of USC it's simply about making sure that the yunit-io repo has the latest code from Launchpad. |
WebDrake
commented
Aug 16, 2017
|
Oh, and:
Don't worry! I'm having fun with this and I'm not going to be bothered if it takes time to reply to my questions. On the contrary, I'm very grateful for all the generous help you're offering. |
WebDrake
commented
Aug 16, 2017
|
Regarding testing suggestions: if I run
... which appears to be down to a failed call to Going by the remarks here: https://stackoverflow.com/questions/4560877/dbus-bus-request-name-connections-are-not-allowed-to-own-the-service#4561515 ... I assume that I must be missing a custom config file in |
I think MirAL is missing a feature you need. So I've written it: https://code.launchpad.net/~alan-griffiths/miral/pre_init-CommandLineOption/+merge/329098 |
I need "sudo" to avoid that (but I have USC installed from archive, which may pull in some dbus config). |
WebDrake
commented
Aug 16, 2017
Oh, fantastic! Thank you so much. Would it help if I tested this locally with my stub app? |
Yes, it would be nice to confirm it solves your problem. |
WebDrake
commented
Aug 16, 2017
I needed to place the |
WebDrake
commented
Aug 16, 2017
|
Thus far I've come across two faulty patches that generate segfaults. The first was a premature use of The second involved moving how the DM connection was initialized, and looks like it might involve some problems with |
WebDrake
commented
Aug 16, 2017
|
The patches in WebDrake#1 have been updated to fix the segfaults. Everything here seems to work as far as sudo dbus-run-session unity-system-compositor --debug-without-dm --file /tmp/usc-socket
miral-shell --host /tmp/usc-socket... is concerned. I think the patches could be cleaned up a bit further, however (e.g. the breaking out of code to the separate |
WebDrake
commented
Aug 16, 2017
|
@AlanGriffiths I can confirm that auto const config = std::make_shared<mir::Server>();
miral::CommandLineOption version_flag{
[](bool is_set)
{
if (is_set)
{
std::cerr << "unity-system-compositor " << USC_VERSION << std::endl;
exit(EXIT_SUCCESS);
}
},
"version", "Show version of Unity System Compositor"
};
pre_init(version_flag)(*config);and also from a stub use of int main(int argc, char const* argv[])
{
miral::MirRunner runner{argc, argv, "unity-system-compositor.conf"};
miral::CommandLineOption version_flag{
[](bool is_set)
{
if (is_set)
{
std::cerr << "unity-system-compositor " << USC_VERSION << std::endl;
exit(EXIT_SUCCESS);
}
},
"version", "Show version of Unity System Compositor"
};
return runner.run_with({pre_init(version_flag)});
}... I get the same minimal output, without any windows opening:
... which matches the output of unmodified USC. I see there's some ongoing discussion about whether to use this feature or make all command-line options pre-init by default. Either way I think it's a useful feature (for example, it will probably be useful in order to separate out the blacklist feature of USC). |
|
@WebDrake I had a very quick play with your branch. I installed it and miral trunk on a test system. (There's a gotcha - USC is installed and run from /usr/sbin so the one in /usr/local isn't picked up.) Anyway, the Unity8 desktop runs on this stack with no obvious problems. So far so good. |
WebDrake
commented
Aug 17, 2017
|
@AlanGriffiths hah, snap, I was just about to write a summary of where I'm at and ask what next steps might be for testing ;-) Thank you for getting there ahead of me! I should say thank you to everyone involved for a very clean codebase that's been very easy to refactor. It's been striking how much has been possible to do working fairly 'blind' just on the basis of how the code fits together. Anyway, if you're happy with things, maybe we should work on getting this into the repo sooner rather than later, so that I don't build up a larger patch backlog than is needed. @jsalatas I'll follow up in the other issue about what would be convenient for submitting a PR against this repo. Where I'm at, just for the record: I've cleaned up the patchset in WebDrake#1 further as discussed yesterday, including adding a strict MirAL >= 1.5 dependency. I've also taken advantage of the I might edit the patches a little further (e.g. to add some helpful comments), but I think this part can be considered pretty much done. Next steps development-wise will be to try to unpick much of the use of From next week I'll have access to a machine that I can put 17.04 on for more in-depth testing. In the meantime, can you advise on any more in-depth things I can do with the USC-on-X testing than just running |
|
@WebDrake as far as USC-on-X I'm not sure there's a lot more you can do. While you could run apps on the miral session using miral-run/miral-xrun but that really just tests Mir-on-(Mir-on-X) and nothing USC specific. The point of USC is integration with the display manager and repowerd (so that things like suspend/resume are applied correctly). The critical place to test that is a phone image (as that has the more complex lifecycle), but I'm not sure how feasible that is currently. |
WebDrake
referenced this issue
Aug 17, 2017
Open
'upstream' branch is not a clean copy of upstream code #3
WebDrake
commented
Aug 17, 2017
Sounds like it might be worth involving the UBPorts folks here. @jsalatas are there any concrete plans for how the two projects will share code? |
Forwarded it to UBPorts' developers group.
Not yet. I guess we will figure it out when yunit on 16.04 using Qt 5.9 is ready (I'm working on this). |
WebDrake
commented
Aug 18, 2017
Cool. Do you have a cross-ref to their issue/forum? Bear in mind they'll need to build the latest trunk MirAL for this to work.
Nice, good luck! I'll probably be AFK from now until Tuesday, so let's catch up on all this in a few days' time. |
|
Actually I asked them in their developer's telegram group. No answer/feedback yet. I guess they will follow up here. |
WebDrake
commented
Aug 21, 2017
So to install my custom USC I'd either need to symlink it (risky I guess) or manually copy it to |
|
Hmmmm....... I would recommend you to build a deb package and install it normally. |
|
Any of those options will work (with corresponding provisos about restoring your system to normal). So long as you understand that a local install doesn't "just work". |
WebDrake
commented
Aug 22, 2017
|
@AlanGriffiths so |
WebDrake
commented
Aug 22, 2017
|
(In any case, I have things working: this is on a 16.04 system with the Yunit overlay. I used a symlink, for now, just to try things out.) |
WebDrake
commented
Aug 30, 2017
|
Just to check in — I'll try to be back on this soon (having a busy week). In the meantime, any feedback from the UBPorts folks? |
|
Take your time. No news from UBPorts yet |
WebDrake
commented
Oct 21, 2017
•
|
Hello folks -- sorry for the long radio silence. It's been a busy patch. Thank you for the nice blog-post shoutouts in the meantime :-) Anyway, @AlanGriffiths I've been looking through the code again and considering next steps, and there are a couple of things I was hoping to get your opinion on. Specifically, I'm interested in the bits of code related to setting up the display-manager connection: if (server.get_options()->is_set("from-dm-fd") &&
server.get_options()->is_set("to-dm-fd"))
{
dm_connection = std::make_shared<usc::AsioDMConnection>(
server.get_options()->get("from-dm-fd", -1),
server.get_options()->get("to-dm-fd", -1),
the_session_switcher());
}
else if (server.get_options()->is_set("debug-without-dm"))
{
dm_connection = std::make_shared<NullDMMessageHandler>(
the_session_switcher(),
server.get_options()->get<std::string>("debug-active-session-name"));
}
else
{
BOOST_THROW_EXCEPTION(mir::AbnormalExit("to and from FDs are required for display manager"));
}What's interesting about this is that it mixes up several concepts: This doesn't seem possible to implement as a conventional The question is whether it is really necessary to worry about that. I've tried to preserve application behaviour precisely so far, but this looks like a case where we could reasonably change things without any obvious impact, as follows:
Thoughts? Unless there are alternative suggestions, I think I'm going to proceed like this. |
|
Hi @WebDrake welcome back to activity. The pre-existing code is misleading. The default value of -1 is spurious: it can never be used as we've already tested is_set(). (Using -1 as a file handle would doubtless fail in some way, but would be pointless replicating.) There's no need to replicate this confusion: the behaviour can be replicated with the Optional overloads. I'll try to look at your PR later today. |
WebDrake
commented
Oct 24, 2017
I found out by running the compositor locally without
Anyway, I'll rework in line with your suggestion. I actually did use |
jsalatas commentedJul 12, 2017
unity-system-compositor links directly to libmirserver will make it harder for Yunit to incorporate Mir releases as they happen as this requires rebuilding against a new libmirserver ABI.
This was suggested by Alan Griffiths at https://forum.yunit.io/viewtopic.php?f=6&p=285