~unity-system-compositor-team/unity-system-compositor/trunk

« back to all changes in this revision

Viewing changes to src/system_compositor.cpp

  • Committer: CI bot
  • Author(s): Michael Terry, Mirco Müller
  • Date: 2014-05-29 14:38:31 UTC
  • mfrom: (115.5.35 new-gl-screen)
  • Revision ID: ps-jenkins@lists.canonical.com-20140529143831-q29e2sm9im8852mu
This branch adds a new option "--spinner=/path" which allows for an interstitial 'busy wait' program to be specified during boot and between greeter and user sessions. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
class SystemCompositorShell : public mf::Shell
49
49
{
50
50
public:
51
 
    SystemCompositorShell(std::shared_ptr<mf::Shell> const& self,
 
51
    SystemCompositorShell(SystemCompositor *compositor,
 
52
                          std::shared_ptr<mf::Shell> const& self,
52
53
                          std::shared_ptr<msh::FocusController> const& focus_controller)
53
 
        : self(self), focus_controller{focus_controller} {}
 
54
        : compositor{compositor}, self(self), focus_controller{focus_controller} {}
54
55
 
55
56
    std::shared_ptr<mf::Session> session_named(std::string const& name)
56
57
    {
60
61
    void set_active_session(std::string const& name)
61
62
    {
62
63
        active_session = name;
63
 
 
64
 
        if (auto session = std::static_pointer_cast<msc::Session>(session_named(name)))
65
 
            focus_controller->set_focus_to(session);
66
 
        else
67
 
            std::cerr << "Unable to set active session, unknown client name " << name << std::endl;
 
64
        update_session_focus();
68
65
    }
69
66
 
70
67
    void set_next_session(std::string const& name)
71
68
    {
72
 
        if (auto const session = std::static_pointer_cast<msc::Session>(session_named(name)))
73
 
        {
74
 
            focus_controller->set_focus_to(session); // raise session inside its depth id set
75
 
            set_active_session(active_session); // to restore input focus to where it should be
76
 
        }
77
 
        else
78
 
            std::cerr << "Unable to set next session, unknown client name " << name << std::endl;
 
69
        next_session = name;
 
70
        update_session_focus();
79
71
    }
80
72
 
81
73
private:
 
74
    void update_session_focus()
 
75
    {
 
76
        auto spinner = std::static_pointer_cast<msc::Session>(session_named(spinner_session));
 
77
        auto next = std::static_pointer_cast<msc::Session>(session_named(next_session));
 
78
        auto active = std::static_pointer_cast<msc::Session>(session_named(active_session));
 
79
 
 
80
        if (spinner)
 
81
            spinner->hide();
 
82
 
 
83
        if (next)
 
84
        {
 
85
            std::cerr << "Setting next focus to session " << next_session;
 
86
            focus_controller->set_focus_to(next);
 
87
        }
 
88
        else if (spinner)
 
89
        {
 
90
            std::cerr << "Setting next focus to spinner";
 
91
            spinner->show();
 
92
            focus_controller->set_focus_to(spinner);
 
93
        }
 
94
 
 
95
        if (active)
 
96
        {
 
97
            std::cerr << "; active focus to session " << active_session << std::endl;
 
98
            focus_controller->set_focus_to(active);
 
99
        }
 
100
        else if (spinner)
 
101
        {
 
102
            std::cerr << "; active focus to spinner" << std::endl;
 
103
            spinner->show();
 
104
            focus_controller->set_focus_to(spinner);
 
105
        }
 
106
    }
 
107
 
82
108
    std::shared_ptr<mf::Session> open_session(
83
109
        pid_t client_pid,
84
110
        std::string const& name,
85
111
        std::shared_ptr<mf::EventSink> const& sink)
86
112
    {
 
113
        std::cerr << "Opening session " << name << std::endl;
87
114
        auto result = self->open_session(client_pid, name, sink);
88
115
        sessions[name] = result;
89
116
 
90
 
        // Opening a new session will steal focus from our active session, so
91
 
        // restore the focus if needed.
92
 
        set_active_session(active_session);
 
117
        if (client_pid == compositor->get_spinner_pid())
 
118
            spinner_session = name;
93
119
 
94
120
        return result;
95
121
    }
96
122
 
97
123
    void close_session(std::shared_ptr<mf::Session> const& session)
98
124
    {
 
125
        std::cerr << "Closing session " << session->name() << std::endl;
 
126
 
 
127
        if (session->name() == spinner_session)
 
128
            spinner_session = "";
 
129
 
99
130
        sessions.erase(session->name());
100
131
        self->close_session(session);
101
132
    }
110
141
    void handle_surface_created(std::shared_ptr<mf::Session> const& session)
111
142
    {
112
143
        self->handle_surface_created(session);
 
144
 
 
145
        // Opening a new surface will steal focus from our active surface, so
 
146
        // restore the focus if needed.
 
147
        update_session_focus();
113
148
    }
114
149
 
 
150
    SystemCompositor *compositor;
115
151
    std::shared_ptr<mf::Shell> const self;
116
152
    std::shared_ptr<msh::FocusController> const focus_controller;
117
153
    std::map<std::string, std::shared_ptr<mf::Session>> sessions;
118
154
    std::string active_session;
 
155
    std::string next_session;
 
156
    std::string spinner_session;
119
157
};
120
158
 
121
159
class SystemCompositorServerConfiguration : public mir::DefaultServerConfiguration
158
196
        return x;
159
197
    }
160
198
 
 
199
    std::string spinner()
 
200
    {
 
201
        // TODO: once our default spinner is ready for use everywhere, replace
 
202
        // default value with DEFAULT_SPINNER instead of the empty string.
 
203
        auto x = the_options()->get("spinner", "");
 
204
        boost::trim(x);
 
205
        return x;
 
206
    }
 
207
 
161
208
    bool public_socket()
162
209
    {
163
210
        return !the_options()->is_set("no-file") && the_options()->get("public-socket", true);
217
264
        return sc_shell([this]
218
265
        {
219
266
            return std::make_shared<SystemCompositorShell>(
 
267
                compositor,
220
268
                mir::DefaultServerConfiguration::the_frontend_shell(),
221
269
                the_focus_controller());
222
270
        });
244
292
            ("to-dm-fd", po::value<int>(),  "File descriptor of write end of pipe to display manager [int]")
245
293
            ("blacklist", po::value<std::string>(), "Video blacklist regex to use")
246
294
            ("version", "Show version of Unity System Compositor")
 
295
            ("spinner", po::value<std::string>(), "Path to spinner executable")
247
296
            ("public-socket", po::value<bool>(), "Make the socket file publicly writable")
248
297
            ("power-off-delay", po::value<int>(), "Delay in milliseconds before powering off screen [int]")
249
298
            ("enable-hardware-cursor", po::value<bool>(), "Enable the hardware cursor (disabled by default)");
354
403
        active_session->set_lifecycle_state(mir_lifecycle_state_resumed);
355
404
}
356
405
 
 
406
pid_t SystemCompositor::get_spinner_pid() const
 
407
{
 
408
    return spinner_process.pid();
 
409
}
 
410
 
357
411
void SystemCompositor::set_active_session(std::string client_name)
358
412
{
359
413
    std::cerr << "set_active_session" << std::endl;
381
435
    io_service.run();
382
436
}
383
437
 
 
438
void SystemCompositor::launch_spinner()
 
439
{
 
440
    if (config->spinner().empty())
 
441
        return;
 
442
 
 
443
    // Launch spinner process to provide default background when a session isn't ready
 
444
    QStringList env = QProcess::systemEnvironment();
 
445
    env << "MIR_SOCKET=" + QString(config->get_socket_file().c_str());
 
446
    spinner_process.setEnvironment(env);
 
447
    spinner_process.start(config->spinner().c_str());
 
448
}
 
449
 
384
450
void SystemCompositor::qt_main(int argc, char **argv)
385
451
{
386
452
    QCoreApplication app(argc, argv);
387
453
    DBusScreen dbus_screen(config, config->power_off_delay());
 
454
    launch_spinner();
388
455
    app.exec();
389
456
}