1 | /* |
---|---|
2 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
3 | SPDX-FileCopyrightText: 2020 David Redondo <kde@david-redondo.de> |
4 | */ |
5 | |
6 | #include "waylandinhibition_p.h" |
7 | |
8 | #include <QDebug> |
9 | #include <QGuiApplication> |
10 | #include <QSharedPointer> |
11 | #include <QWaylandClientExtensionTemplate> |
12 | #include <QtWaylandClientVersion> |
13 | #include <qpa/qplatformnativeinterface.h> |
14 | |
15 | #include "qwayland-keyboard-shortcuts-inhibit-unstable-v1.h" |
16 | |
17 | class ShortcutsInhibitor : public QtWayland::zwp_keyboard_shortcuts_inhibitor_v1 |
18 | { |
19 | public: |
20 | ShortcutsInhibitor(::zwp_keyboard_shortcuts_inhibitor_v1 *id) |
21 | : QtWayland::zwp_keyboard_shortcuts_inhibitor_v1(id) |
22 | { |
23 | } |
24 | |
25 | ~ShortcutsInhibitor() override |
26 | { |
27 | destroy(); |
28 | } |
29 | |
30 | void zwp_keyboard_shortcuts_inhibitor_v1_active() override |
31 | { |
32 | m_active = true; |
33 | } |
34 | |
35 | void zwp_keyboard_shortcuts_inhibitor_v1_inactive() override |
36 | { |
37 | m_active = false; |
38 | } |
39 | |
40 | bool isActive() const |
41 | { |
42 | return m_active; |
43 | } |
44 | |
45 | private: |
46 | bool m_active = false; |
47 | }; |
48 | |
49 | class ShortcutsInhibitManager : public QWaylandClientExtensionTemplate<ShortcutsInhibitManager>, public QtWayland::zwp_keyboard_shortcuts_inhibit_manager_v1 |
50 | { |
51 | public: |
52 | ShortcutsInhibitManager() |
53 | : QWaylandClientExtensionTemplate<ShortcutsInhibitManager>(1) |
54 | { |
55 | initialize(); |
56 | } |
57 | ~ShortcutsInhibitManager() override |
58 | { |
59 | if (isInitialized()) { |
60 | destroy(); |
61 | } |
62 | } |
63 | |
64 | void startInhibition(QWindow *window) |
65 | { |
66 | if (m_inhibitions.contains(key: window)) { |
67 | return; |
68 | } |
69 | QPlatformNativeInterface *nativeInterface = qGuiApp->platformNativeInterface(); |
70 | if (!nativeInterface) { |
71 | return; |
72 | } |
73 | auto seat = static_cast<wl_seat *>(nativeInterface->nativeResourceForIntegration(resource: "wl_seat")); |
74 | auto surface = static_cast<wl_surface *>(nativeInterface->nativeResourceForWindow(resource: "surface", window)); |
75 | if (!seat || !surface) { |
76 | return; |
77 | } |
78 | m_inhibitions[window].reset(t: new ShortcutsInhibitor(inhibit_shortcuts(surface, seat))); |
79 | } |
80 | |
81 | bool isInhibited(QWindow *window) const |
82 | { |
83 | return m_inhibitions.contains(key: window); |
84 | } |
85 | |
86 | void stopInhibition(QWindow *window) |
87 | { |
88 | m_inhibitions.remove(key: window); |
89 | } |
90 | |
91 | QHash<QWindow *, QSharedPointer<ShortcutsInhibitor>> m_inhibitions; |
92 | }; |
93 | |
94 | static std::shared_ptr<ShortcutsInhibitManager> theManager() |
95 | { |
96 | static std::weak_ptr<ShortcutsInhibitManager> managerInstance; |
97 | std::shared_ptr<ShortcutsInhibitManager> ret = managerInstance.lock(); |
98 | if (!ret) { |
99 | ret = std::make_shared<ShortcutsInhibitManager>(); |
100 | managerInstance = ret; |
101 | } |
102 | return ret; |
103 | } |
104 | |
105 | WaylandInhibition::WaylandInhibition(QWindow *window) |
106 | : ShortcutInhibition() |
107 | , m_window(window) |
108 | , m_manager(theManager()) |
109 | { |
110 | } |
111 | |
112 | WaylandInhibition::~WaylandInhibition() = default; |
113 | |
114 | bool WaylandInhibition::shortcutsAreInhibited() const |
115 | { |
116 | return m_manager->isInhibited(window: m_window); |
117 | } |
118 | |
119 | void WaylandInhibition::enableInhibition() |
120 | { |
121 | m_manager->startInhibition(window: m_window); |
122 | } |
123 | |
124 | void WaylandInhibition::disableInhibition() |
125 | { |
126 | m_manager->stopInhibition(window: m_window); |
127 | } |
128 |