Mir
server_example_basic_window_manager.h
Go to the documentation of this file.
1 /*
2  * Copyright © 2015 Canonical Ltd.
3  *
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.
7  *
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.
12  *
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/>.
15  *
16  * Authored By: Alan Griffiths <alan@octopull.co.uk>
17  */
18 
19 #ifndef MIR_EXAMPLE_BASIC_WINDOW_MANAGER_H_
20 #define MIR_EXAMPLE_BASIC_WINDOW_MANAGER_H_
21 
23 #include "mir/scene/session.h"
24 #include "mir/scene/surface.h"
28 
29 #include <map>
30 #include <mutex>
31 
34 
35 namespace mir
36 {
37 namespace examples
38 {
39 using shell::SurfaceSet;
40 
41 template<typename Info>
42 struct SurfaceTo
43 {
44  using type = std::map<std::weak_ptr<scene::Surface>, Info, std::owner_less<std::weak_ptr<scene::Surface>>>;
45 };
46 
47 template<typename Info>
48 struct SessionTo
49 {
50  using type = std::map<std::weak_ptr<scene::Session>, Info, std::owner_less<std::weak_ptr<scene::Session>>>;
51 };
52 
56 // TODO extract commonality with FocusController (once that's separated from shell::FocusController)
57 template<typename SessionInfo, typename SurfaceInfo>
59 {
60 public:
61  virtual auto find_session(std::function<bool(SessionInfo const& info)> const& predicate)
62  -> std::shared_ptr<scene::Session> = 0;
63 
64  virtual auto info_for(std::weak_ptr<scene::Session> const& session) const -> SessionInfo& = 0;
65 
66  virtual auto info_for(std::weak_ptr<scene::Surface> const& surface) const -> SurfaceInfo& = 0;
67 
68  virtual std::shared_ptr<scene::Session> focused_session() const = 0;
69 
70  virtual std::shared_ptr<scene::Surface> focused_surface() const = 0;
71 
72  virtual void focus_next_session() = 0;
73 
74  virtual void set_focus_to(
75  std::shared_ptr<scene::Session> const& focus,
76  std::shared_ptr<scene::Surface> const& surface) = 0;
77 
78  virtual auto surface_at(geometry::Point cursor) const -> std::shared_ptr<scene::Surface> = 0;
79 
80  virtual void raise(SurfaceSet const& surfaces) = 0;
81 
82  virtual auto active_display() -> geometry::Rectangle const = 0;
83 
84  virtual void forget(std::weak_ptr<scene::Surface> const& surface) = 0;
85 
86  virtual ~BasicWindowManagerToolsCopy() = default;
87  BasicWindowManagerToolsCopy() = default;
90 };
91 
112 template<typename WindowManagementPolicy, typename SessionInfo, typename SurfaceInfo>
114  private BasicWindowManagerToolsCopy<SessionInfo, SurfaceInfo>
115 {
116 public:
117  template <typename... PolicyArgs>
119  shell::FocusController* focus_controller,
120  PolicyArgs&&... policy_args) :
121  focus_controller(focus_controller),
122  policy(this, std::forward<PolicyArgs>(policy_args)...)
123  {
124  }
125 
126 private:
127  void add_session(std::shared_ptr<scene::Session> const& session) override
128  {
129  std::lock_guard<decltype(mutex)> lock(mutex);
130  session_info[session] = SessionInfo();
131  policy.handle_session_info_updated(session_info, displays);
132  }
133 
134  void remove_session(std::shared_ptr<scene::Session> const& session) override
135  {
136  std::lock_guard<decltype(mutex)> lock(mutex);
137  session_info.erase(session);
138  policy.handle_session_info_updated(session_info, displays);
139  }
140 
141  frontend::SurfaceId add_surface(
142  std::shared_ptr<scene::Session> const& session,
143  scene::SurfaceCreationParameters const& params,
144  std::function<frontend::SurfaceId(std::shared_ptr<scene::Session> const& session, scene::SurfaceCreationParameters const& params)> const& build) override
145  {
146  std::lock_guard<decltype(mutex)> lock(mutex);
147  scene::SurfaceCreationParameters const placed_params = policy.handle_place_new_surface(session, params);
148  auto const result = build(session, placed_params);
149  auto const surface = session->surface(result);
150  surface_info.emplace(surface, SurfaceInfo{session, surface, placed_params});
151  policy.handle_new_surface(session, surface);
152  policy.generate_decorations_for(session, surface, surface_info, build);
153  return result;
154  }
155 
156  void modify_surface(
157  std::shared_ptr<scene::Session> const& session,
158  std::shared_ptr<scene::Surface> const& surface,
159  shell::SurfaceSpecification const& modifications) override
160  {
161  std::lock_guard<decltype(mutex)> lock(mutex);
162  policy.handle_modify_surface(session, surface, modifications);
163  }
164 
165  void remove_surface(
166  std::shared_ptr<scene::Session> const& session,
167  std::weak_ptr<scene::Surface> const& surface) override
168  {
169  std::lock_guard<decltype(mutex)> lock(mutex);
170  policy.handle_delete_surface(session, surface);
171 
172  surface_info.erase(surface);
173  }
174 
175  void forget(std::weak_ptr<scene::Surface> const& surface) override
176  {
177  surface_info.erase(surface);
178  }
179 
180  void add_display(geometry::Rectangle const& area) override
181  {
182  std::lock_guard<decltype(mutex)> lock(mutex);
183  displays.add(area);
184  policy.handle_displays_updated(session_info, displays);
185  }
186 
187  void remove_display(geometry::Rectangle const& area) override
188  {
189  std::lock_guard<decltype(mutex)> lock(mutex);
190  displays.remove(area);
191  policy.handle_displays_updated(session_info, displays);
192  }
193 
194  bool handle_keyboard_event(MirKeyboardEvent const* event) override
195  {
196  std::lock_guard<decltype(mutex)> lock(mutex);
197  return policy.handle_keyboard_event(event);
198  }
199 
200  bool handle_touch_event(MirTouchEvent const* event) override
201  {
202  std::lock_guard<decltype(mutex)> lock(mutex);
203  return policy.handle_touch_event(event);
204  }
205 
206  bool handle_pointer_event(MirPointerEvent const* event) override
207  {
208  std::lock_guard<decltype(mutex)> lock(mutex);
209 
210  cursor = {
213 
214  return policy.handle_pointer_event(event);
215  }
216 
217  int set_surface_attribute(
218  std::shared_ptr<scene::Session> const& /*session*/,
219  std::shared_ptr<scene::Surface> const& surface,
220  MirSurfaceAttrib attrib,
221  int value) override
222  {
223  std::lock_guard<decltype(mutex)> lock(mutex);
224  switch (attrib)
225  {
227  {
228  auto const state = policy.handle_set_state(surface, MirSurfaceState(value));
229  return surface->configure(attrib, state);
230  }
231  default:
232  return surface->configure(attrib, value);
233  }
234  }
235 
236  auto find_session(std::function<bool(SessionInfo const& info)> const& predicate)
237  -> std::shared_ptr<scene::Session> override
238  {
239  for(auto& info : session_info)
240  {
241  if (predicate(info.second))
242  {
243  return info.first.lock();
244  }
245  }
246 
247  return std::shared_ptr<scene::Session>{};
248  }
249 
250  auto info_for(std::weak_ptr<scene::Session> const& session) const -> SessionInfo& override
251  {
252  return const_cast<SessionInfo&>(session_info.at(session));
253  }
254 
255  auto info_for(std::weak_ptr<scene::Surface> const& surface) const -> SurfaceInfo& override
256  {
257  return const_cast<SurfaceInfo&>(surface_info.at(surface));
258  }
259 
260  std::shared_ptr<scene::Session> focused_session() const override
261  {
262  return focus_controller->focused_session();
263  }
264 
265  std::shared_ptr<scene::Surface> focused_surface() const override
266  {
267  return focus_controller->focused_surface();
268  }
269 
270  void focus_next_session() override
271  {
272  focus_controller->focus_next_session();
273  }
274 
275  void set_focus_to(
276  std::shared_ptr<scene::Session> const& focus,
277  std::shared_ptr<scene::Surface> const& surface) override
278  {
279  focus_controller->set_focus_to(focus, surface);
280  }
281 
282  auto surface_at(geometry::Point cursor) const -> std::shared_ptr<scene::Surface> override
283  {
284  return focus_controller->surface_at(cursor);
285  }
286 
287  void raise(SurfaceSet const& surfaces) override
288  {
289  focus_controller->raise(surfaces);
290  }
291 
292  auto active_display() -> geometry::Rectangle const override
293  {
294  geometry::Rectangle result;
295 
296  // 1. If a window has input focus, whichever display contains the largest
297  // proportion of the area of that window.
298  if (auto const surface = focused_surface())
299  {
300  auto const surface_rect = surface->input_bounds();
301  int max_overlap_area = -1;
302 
303  for (auto const& display : displays)
304  {
305  auto const intersection = surface_rect.intersection_with(display).size;
306  if (intersection.width.as_int()*intersection.height.as_int() > max_overlap_area)
307  {
308  max_overlap_area = intersection.width.as_int()*intersection.height.as_int();
309  result = display;
310  }
311  }
312  return result;
313  }
314 
315  // 2. Otherwise, if any window previously had input focus, for the window that had
316  // it most recently, the display that contained the largest proportion of the
317  // area of that window at the moment it closed, as long as that display is still
318  // available.
319 
320  // 3. Otherwise, the display that contains the pointer, if there is one.
321  for (auto const& display : displays)
322  {
323  if (display.contains(cursor))
324  {
325  // Ignore the (unspecified) possiblity of overlapping displays
326  return display;
327  }
328  }
329 
330  // 4. Otherwise, the primary display, if there is one (for example, the laptop display).
331 
332  // 5. Otherwise, the first display.
333  if (displays.size())
334  result = *displays.begin();
335 
336  return result;
337  }
338 
339  shell::FocusController* const focus_controller;
340  WindowManagementPolicy policy;
341 
342  std::mutex mutex;
343  typename SessionTo<SessionInfo>::type session_info;
344  typename SurfaceTo<SurfaceInfo>::type surface_info;
345  geometry::Rectangles displays;
346  geometry::Point cursor;
347 };
348 }
349 }
350 
351 #endif /* MIR_EXAMPLE_BASIC_WINDOW_MANAGER_H_ */
virtual void set_focus_to(std::shared_ptr< scene::Session > const &focus, std::shared_ptr< scene::Surface > const &surface)=0
All things Mir.
Definition: atomic_callback.h:25
IntWrapper< detail::SessionsSurfaceIdTag > SurfaceId
Definition: surface_id.h:29
Definition: common.h:38
interface to provide window management logic
Definition: window_manager.h:37
std::map< std::weak_ptr< scene::Surface >, SurfaceInfo, std::owner_less< std::weak_ptr< scene::Surface >>> type
Definition: server_example_basic_window_manager.h:44
Definition: point.h:30
virtual std::shared_ptr< scene::Session > focused_session() const =0
Definition: server_example_basic_window_manager.h:42
virtual auto active_display() -> geometry::Rectangle const =0
struct MirPointerEvent MirPointerEvent
An event type describing a change in pointer device state.
Definition: pointer_event.h:35
STL namespace.
virtual auto info_for(std::weak_ptr< scene::Session > const &session) const -> SessionInfo &=0
std::set< std::weak_ptr< scene::Surface >, std::owner_less< std::weak_ptr< scene::Surface >>> SurfaceSet
Definition: focus_controller.h:32
virtual auto surface_at(geometry::Point cursor) const -> std::shared_ptr< scene::Surface >=0
Definition: focus_controller.h:38
std::map< std::weak_ptr< scene::Session >, SessionInfo, std::owner_less< std::weak_ptr< scene::Session >>> type
Definition: server_example_basic_window_manager.h:50
void remove(Rectangle const &rect)
removes at most one matching rectangle
Definition: rectangles.cpp:56
The interface through which the policy instructs the controller. These functions assume that the Basi...
Definition: server_example_basic_window_manager.h:58
float mir_pointer_event_axis_value(MirPointerEvent const *pev, MirPointerAxis axis)
Retrieve the axis value reported by a given pointer event.
Definition: input_event.cpp:388
BasicWindowManagerToolsCopy & operator=(BasicWindowManagerToolsCopy const &)=delete
virtual std::shared_ptr< scene::Surface > focused_surface() const =0
struct MirTouchEvent MirTouchEvent
An event type describing a change in touch device state.
Definition: touch_event.h:33
MirSurfaceState
Definition: common.h:64
virtual auto find_session(std::function< bool(SessionInfo const &info)> const &predicate) -> std::shared_ptr< scene::Session >=0
virtual void forget(std::weak_ptr< scene::Surface > const &surface)=0
virtual auto focused_session() const -> std::shared_ptr< scene::Session >=0
virtual void raise(SurfaceSet const &surfaces)=0
virtual void set_focus_to(std::shared_ptr< scene::Session > const &focus_session, std::shared_ptr< scene::Surface > const &focus_surface)=0
Definition: pointer_event.h:58
MirSurfaceAttrib
Attributes of a surface that the client and server/shell may wish to get or set over the wire...
Definition: common.h:34
A policy based window manager. This takes care of the management of any meta implementation held for ...
Definition: server_example_basic_window_manager.h:113
struct MirKeyboardEvent MirKeyboardEvent
An event type describing a change in keyboard state.
Definition: keyboard_event.h:44
virtual std::shared_ptr< scene::Surface > focused_surface() const =0
Definition: rectangle.h:33
Definition: pointer_event.h:60
void add(Rectangle const &rect)
Definition: rectangles.cpp:51
virtual auto surface_at(geometry::Point cursor) const -> std::shared_ptr< scene::Surface >=0
BasicWindowManagerCopy(shell::FocusController *focus_controller, PolicyArgs &&...policy_args)
Definition: server_example_basic_window_manager.h:118
virtual void focus_next_session()=0
Definition: server_example_basic_window_manager.h:48

Copyright © 2012-2015 Canonical Ltd.
Generated on Thu Oct 8 16:20:16 UTC 2015