2
* Copyright © 2014 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License version 3 as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Authored by: Alexandros Frantzis <alexandros.frantzis@canonical.com>
19
#include "session_switcher.h"
22
usc::SessionSwitcher::SessionSwitcher(std::shared_ptr<Spinner> const& spinner)
23
: spinner_process{spinner},
28
void usc::SessionSwitcher::add(std::shared_ptr<Session> const& session, pid_t pid)
30
std::lock_guard<std::mutex> lock{mutex};
32
if (pid == spinner_process->pid())
33
spinner_name = session->name();
35
sessions[session->name()] = SessionInfo(session);
36
update_displayed_sessions();
39
void usc::SessionSwitcher::remove(std::string const& name)
41
std::lock_guard<std::mutex> lock{mutex};
43
if (name == spinner_name)
47
update_displayed_sessions();
50
void usc::SessionSwitcher::set_active_session(std::string const& name)
52
std::lock_guard<std::mutex> lock{mutex};
55
update_displayed_sessions();
58
void usc::SessionSwitcher::set_next_session(std::string const& name)
60
std::lock_guard<std::mutex> lock{mutex};
63
update_displayed_sessions();
66
void usc::SessionSwitcher::mark_ready(mir::scene::Session const* scene_session)
68
std::lock_guard<std::mutex> lock{mutex};
70
for (auto& pair : sessions)
72
if (pair.second.session && pair.second.session->corresponds_to(scene_session))
73
pair.second.ready = true;
76
update_displayed_sessions();
79
void usc::SessionSwitcher::update_displayed_sessions()
81
hide_uninteresting_sessions();
83
bool show_spinner = false;
84
ShowMode show_spinner_mode{ShowMode::as_next};
85
bool const allowed_to_display_active =
86
is_session_ready_for_display(next_name) ||
87
!is_session_expected_to_become_ready(next_name) ||
90
if (allowed_to_display_active && is_session_ready_for_display(active_name))
92
show_session(active_name, ShowMode::as_active);
95
else if (is_session_expected_to_become_ready(active_name))
98
show_spinner_mode = ShowMode::as_active;
103
if (is_session_ready_for_display(next_name))
105
show_session(next_name, ShowMode::as_next);
107
else if (is_session_expected_to_become_ready(next_name))
110
show_spinner_mode = ShowMode::as_next;
113
else if (is_session_ready_for_display(next_name))
115
hide_session(next_name);
119
ensure_spinner_will_be_shown(show_spinner_mode);
121
ensure_spinner_is_not_running();
124
void usc::SessionSwitcher::hide_uninteresting_sessions()
126
for (auto const& pair : sessions)
128
if (pair.second.session->name() != active_name &&
129
pair.second.session->name() != next_name)
131
pair.second.session->hide();
136
bool usc::SessionSwitcher::is_session_ready_for_display(std::string const& name)
138
auto const iter = sessions.find(name);
139
if (iter == sessions.end())
142
return iter->second.session && iter->second.ready;
145
bool usc::SessionSwitcher::is_session_expected_to_become_ready(std::string const& name)
147
return !name.empty();
150
void usc::SessionSwitcher::show_session(
151
std::string const& name,
154
auto& session = sessions[name].session;
156
if (show_mode == ShowMode::as_active)
157
session->raise_and_focus();
162
void usc::SessionSwitcher::hide_session(std::string const& name)
164
auto& session = sessions[name].session;
168
void usc::SessionSwitcher::ensure_spinner_will_be_shown(ShowMode show_mode)
170
auto const iter = sessions.find(spinner_name);
171
if (iter == sessions.end())
173
spinner_process->ensure_running();
177
if (show_mode == ShowMode::as_active)
178
iter->second.session->raise_and_focus();
179
iter->second.session->show();
183
void usc::SessionSwitcher::ensure_spinner_is_not_running()
185
spinner_process->kill();