2
* Copyright © 2015 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 3,
6
* as 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: Alan Griffiths <alan@octopull.co.uk>
19
#include "default_shell.h"
20
#include "mir/shell/focus_setter.h"
21
#include "mir/scene/prompt_session.h"
22
#include "mir/scene/session_coordinator.h"
23
#include "mir/scene/session.h"
24
#include "mir/scene/surface.h"
26
#include <boost/throw_exception.hpp>
30
namespace mf = mir::frontend;
31
namespace ms = mir::scene;
32
namespace msh = mir::shell;
34
msh::DefaultShell::DefaultShell(
35
std::shared_ptr<FocusSetter> const& focus_setter,
36
std::shared_ptr<scene::SessionCoordinator> const& session_coordinator) :
37
focus_setter(focus_setter),
38
session_coordinator(session_coordinator)
42
std::shared_ptr<mf::Session> msh::DefaultShell::open_session(
44
std::string const& name,
45
std::shared_ptr<mf::EventSink> const& sink)
47
auto const new_session = session_coordinator->open_session(client_pid, name, sink);
48
set_focus_to(new_session);
52
void msh::DefaultShell::close_session(
53
std::shared_ptr<mf::Session> const& session)
55
session_coordinator->close_session(std::dynamic_pointer_cast<ms::Session>(session));
57
std::unique_lock<std::mutex> lock(mutex);
58
set_focus_to_locked(lock, session_coordinator->successor_of(std::shared_ptr<ms::Session>()));
61
void msh::DefaultShell::focus_next()
63
std::unique_lock<std::mutex> lock(mutex);
64
auto focus = focus_application.lock();
66
focus = session_coordinator->successor_of(focus);
68
set_focus_to_locked(lock, focus);
71
std::weak_ptr<ms::Session> msh::DefaultShell::focussed_application() const
73
return focus_application;
76
void msh::DefaultShell::set_focus_to(
77
std::shared_ptr<scene::Session> const& focus)
79
std::unique_lock<std::mutex> lg(mutex);
80
set_focus_to_locked(lg, focus);
83
void msh::DefaultShell::handle_surface_created(
84
std::shared_ptr<mf::Session> const& session)
86
auto const focus = std::dynamic_pointer_cast<ms::Session>(session);
90
std::shared_ptr<mf::PromptSession> msh::DefaultShell::start_prompt_session_for(
91
std::shared_ptr<mf::Session> const& session,
92
scene::PromptSessionCreationParameters const& params)
94
auto const scene_session = std::dynamic_pointer_cast<ms::Session>(session);
96
return session_coordinator->start_prompt_session_for(scene_session, params);
99
void msh::DefaultShell::add_prompt_provider_for(
100
std::shared_ptr<mf::PromptSession> const& prompt_session,
101
std::shared_ptr<mf::Session> const& session)
103
auto const scene_prompt_session = std::dynamic_pointer_cast<ms::PromptSession>(prompt_session);
104
auto const scene_session = std::dynamic_pointer_cast<ms::Session>(session);
105
session_coordinator->add_prompt_provider_for(scene_prompt_session, scene_session);
108
void msh::DefaultShell::stop_prompt_session(std::shared_ptr<mf::PromptSession> const& prompt_session)
110
auto const scene_prompt_session = std::dynamic_pointer_cast<ms::PromptSession>(prompt_session);
111
session_coordinator->stop_prompt_session(scene_prompt_session);
114
mf::SurfaceId msh::DefaultShell::create_surface(std::shared_ptr<mf::Session> const& session, ms::SurfaceCreationParameters const& params)
116
auto const scene_session = std::dynamic_pointer_cast<ms::Session>(session);
117
auto const result = scene_session->create_surface(params);
121
void msh::DefaultShell::destroy_surface(std::shared_ptr<mf::Session> const& session, mf::SurfaceId surface)
123
auto const scene_session = std::dynamic_pointer_cast<ms::Session>(session);
124
scene_session->destroy_surface(surface);
127
int msh::DefaultShell::set_surface_attribute(
128
std::shared_ptr<mf::Session> const& session,
129
mf::SurfaceId surface_id,
130
MirSurfaceAttrib attrib,
133
// TODO this downcasting is clunky, but is temporary wiring of the new interaction route to the old implementation
135
BOOST_THROW_EXCEPTION(std::logic_error("invalid session"));
137
auto const surface = std::dynamic_pointer_cast<ms::Surface>(session->get_surface(surface_id));
140
BOOST_THROW_EXCEPTION(std::logic_error("invalid surface id"));
142
return surface->configure(attrib, value);
145
int msh::DefaultShell::get_surface_attribute(
146
std::shared_ptr<mf::Session> const& session,
147
mf::SurfaceId surface_id,
148
MirSurfaceAttrib attrib)
150
// TODO this downcasting is clunky, but is temporary wiring of the new interaction route to the old implementation
152
BOOST_THROW_EXCEPTION(std::logic_error("invalid session"));
154
auto const surface = std::dynamic_pointer_cast<ms::Surface>(session->get_surface(surface_id));
157
BOOST_THROW_EXCEPTION(std::logic_error("invalid surface id"));
159
return surface->query(attrib);
163
inline void msh::DefaultShell::set_focus_to_locked(std::unique_lock<std::mutex> const&, std::shared_ptr<ms::Session> const& session)
165
auto old_focus = focus_application.lock();
167
focus_setter->set_focus_to(session);
168
focus_application = session;
172
session_coordinator->set_focus_to(session);
176
session_coordinator->unset_focus();