GCC Code Coverage Report


Directory: ./
File: server/selection_pool.h
Date: 2024-01-22 17:25:27
Exec Total Coverage
Lines: 60 61 98.4%
Branches: 36 46 78.3%

Line Branch Exec Source
1 /*
2 SPDX-FileCopyrightText: 2020, 2021 Roman Gilg <subdiff@gmail.com>
3 SPDX-FileCopyrightText: 2021 Francesco Sorrentino <francesco.sorr@gmail.com>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only
6 */
7 #pragma once
8
9 #include "seat.h"
10 #include "surface.h"
11 #include "utils.h"
12
13 #include <vector>
14
15 namespace Wrapland::Server
16 {
17
18 template<typename Device, typename Source, void (Seat::*signal)(Source*)>
19 struct selection_pool {
20 618 explicit selection_pool(Seat* seat);
21
22 void register_device(Device* device);
23 void set_focused_surface(Surface* surface);
24
25 void set_selection(Source* source);
26
27
2/4
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 309 times.
✗ Branch 3 not taken.
618 struct {
28 std::vector<Device*> devices;
29 618 Source* source{nullptr};
30 QMetaObject::Connection source_destroy_notifier;
31 } focus;
32
33 std::vector<Device*> devices;
34
35 private:
36 void transmit(Source* source);
37
38 Seat* seat;
39 };
40
41 template<typename Device, typename Source, void (Seat::*signal)(Source*)>
42 618 selection_pool<Device, Source, signal>::selection_pool(Seat* seat)
43 618 : seat{seat}
44 {
45 618 }
46
47 template<typename Device, typename Source, void (Seat::*signal)(Source*)>
48 39 void selection_pool<Device, Source, signal>::register_device(Device* device)
49 {
50 39 devices.push_back(device);
51
52 78 QObject::connect(device, &Device::resourceDestroyed, seat, [this, device] {
53 39 remove_one(devices, device);
54 39 remove_one(focus.devices, device);
55 39 });
56
57 68 QObject::connect(device, &Device::selection_changed, seat, [this, device] {
58
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 22 times.
29 if (has_keyboard_focus(device, seat)) {
59 22 set_selection(device->selection());
60 22 }
61 29 });
62
63
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 4 times.
39 if (has_keyboard_focus(device, seat)) {
64 4 focus.devices.push_back(device);
65
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (focus.source) {
66 2 device->send_selection(focus.source);
67 2 }
68 4 }
69 39 }
70
71 template<typename Device, typename Source, void (Seat::*signal)(Source*)>
72 224 void selection_pool<Device, Source, signal>::set_focused_surface(Surface* surface)
73 {
74
4/4
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 11 times.
224 if (!surface) {
75 // No surface set. Per protocol we just won't send future selection events to the client.
76 22 focus.devices = {};
77 22 return;
78 }
79
80
4/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 99 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 101 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
202 if (focus.devices.size() && focus.devices.front()->client() == surface->client()) {
81 // No client change. Selection must not be resent.
82 return;
83 }
84
85 202 focus.devices = interfacesForSurface(surface, devices);
86
4/4
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 99 times.
✓ Branch 3 taken 2 times.
202 if (focus.source) {
87 5 transmit(focus.source);
88 5 }
89 224 }
90
91 template<typename Device, typename Source, void (Seat::*signal)(Source*)>
92 38 void selection_pool<Device, Source, signal>::set_selection(Source* source)
93 {
94
4/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 2 times.
38 if (focus.source == source) {
95 9 return;
96 }
97
98 29 auto old_source = focus.source;
99 29 focus.source = source;
100
101 29 QObject::disconnect(focus.source_destroy_notifier);
102 29 focus.source_destroy_notifier = QMetaObject::Connection();
103
104
4/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
29 if (source) {
105 44 focus.source_destroy_notifier
106 53 = QObject::connect(source, &Source::resourceDestroyed, seat, [this] {
107 9 focus.source = nullptr;
108 9 transmit(nullptr);
109
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
9 Q_EMIT(seat->*signal)(nullptr);
110 9 });
111 22 }
112
113 29 transmit(source);
114
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
29 Q_EMIT(seat->*signal)(source);
115
116
4/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 4 times.
29 if (old_source) {
117 13 old_source->cancel();
118 13 }
119 38 }
120
121 template<typename Device, typename Source, void (Seat::*signal)(Source*)>
122 43 void selection_pool<Device, Source, signal>::transmit(Source* source)
123 {
124 88 std::for_each(focus.devices.begin(), focus.devices.end(), [source](Device* dev) {
125 45 dev->send_selection(source);
126 45 });
127 43 }
128
129 }
130