forked from winft/como
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcursor.h
102 lines (85 loc) · 2.46 KB
/
cursor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*
SPDX-FileCopyrightText: 2021 Roman Gilg <[email protected]>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "como_export.h"
#include <QImage>
#include <QObject>
#include <QPoint>
#include <memory>
namespace KWin::render
{
class COMO_EXPORT cursor_qobject : public QObject
{
Q_OBJECT
Q_SIGNALS:
void changed();
};
template<typename Platform>
class cursor
{
public:
cursor(Platform& platform)
: qobject{std::make_unique<cursor_qobject>()}
, platform{platform}
{
QObject::connect(
qobject.get(), &cursor_qobject::changed, qobject.get(), [this] { rerender(); });
}
void set_enabled(bool enable)
{
if (qEnvironmentVariableIsSet("KWIN_FORCE_SW_CURSOR")) {
enable = true;
}
if (enabled == enable) {
return;
}
enabled = enable;
auto cursor = platform.base.mod.space->input->cursor.get();
using cursor_t = typename decltype(platform.base.mod.space->input->cursor)::element_type;
if (enable) {
cursor->start_image_tracking();
notifiers.pos = QObject::connect(
cursor, &cursor_t::pos_changed, qobject.get(), [this] { rerender(); });
notifiers.image = QObject::connect(
cursor, &cursor_t::image_changed, qobject.get(), &cursor_qobject::changed);
} else {
cursor->stop_image_tracking();
QObject::disconnect(notifiers.pos);
QObject::disconnect(notifiers.image);
}
}
QImage image() const
{
return platform.base.mod.space->input->cursor->image();
}
QPoint hotspot() const
{
return platform.base.mod.space->input->cursor->hotspot();
}
void mark_as_rendered()
{
if (enabled) {
last_rendered_geometry
= QRect(platform.base.mod.space->input->cursor->pos() - hotspot(), image().size());
}
platform.base.mod.space->input->cursor->mark_as_rendered();
}
std::unique_ptr<cursor_qobject> qobject;
bool enabled{false};
private:
void rerender()
{
platform.addRepaint(last_rendered_geometry);
platform.addRepaint(
QRect(platform.base.mod.space->input->cursor->pos() - hotspot(), image().size()));
}
Platform& platform;
QRect last_rendered_geometry;
struct {
QMetaObject::Connection pos;
QMetaObject::Connection image;
} notifiers;
};
}