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 "kguiaddons_debug.h" |
9 | |
10 | #include <QDebug> |
11 | #include <QGuiApplication> |
12 | #include <QSharedPointer> |
13 | #include <QWaylandClientExtensionTemplate> |
14 | #include <QWindow> |
15 | #include <qpa/qplatformwindow_p.h> |
16 | |
17 | #include "qwayland-keyboard-shortcuts-inhibit-unstable-v1.h" |
18 | |
19 | class ShortcutsInhibitor : public QtWayland::zwp_keyboard_shortcuts_inhibitor_v1 |
20 | { |
21 | public: |
22 | ShortcutsInhibitor(::zwp_keyboard_shortcuts_inhibitor_v1 *id) |
23 | : QtWayland::zwp_keyboard_shortcuts_inhibitor_v1(id) |
24 | { |
25 | } |
26 | |
27 | ~ShortcutsInhibitor() override |
28 | { |
29 | destroy(); |
30 | } |
31 | |
32 | void zwp_keyboard_shortcuts_inhibitor_v1_active() override |
33 | { |
34 | m_active = true; |
35 | } |
36 | |
37 | void zwp_keyboard_shortcuts_inhibitor_v1_inactive() override |
38 | { |
39 | m_active = false; |
40 | } |
41 | |
42 | bool isActive() const |
43 | { |
44 | return m_active; |
45 | } |
46 | |
47 | private: |
48 | bool m_active = false; |
49 | }; |
50 | |
51 | class ShortcutsInhibitManager : public QWaylandClientExtensionTemplate<ShortcutsInhibitManager>, public QtWayland::zwp_keyboard_shortcuts_inhibit_manager_v1 |
52 | { |
53 | public: |
54 | ShortcutsInhibitManager() |
55 | : QWaylandClientExtensionTemplate<ShortcutsInhibitManager>(1) |
56 | { |
57 | initialize(); |
58 | } |
59 | ~ShortcutsInhibitManager() override |
60 | { |
61 | if (isInitialized()) { |
62 | destroy(); |
63 | } |
64 | } |
65 | |
66 | void startInhibition(QWindow *window) |
67 | { |
68 | if (m_inhibitions.contains(key: window)) { |
69 | return; |
70 | } |
71 | auto waylandApp = qGuiApp->nativeInterface<QNativeInterface::QWaylandApplication>(); |
72 | auto waylandWindow = window->nativeInterface<QNativeInterface::Private::QWaylandWindow>(); |
73 | if (!waylandApp || !waylandWindow) { |
74 | return; |
75 | } |
76 | |
77 | auto seat = waylandApp->lastInputSeat(); |
78 | auto surface = waylandWindow->surface(); |
79 | |
80 | if (!seat || !surface) { |
81 | return; |
82 | } |
83 | m_inhibitions[window].reset(t: new ShortcutsInhibitor(inhibit_shortcuts(surface, seat))); |
84 | } |
85 | |
86 | bool isInhibited(QWindow *window) const |
87 | { |
88 | return m_inhibitions.contains(key: window); |
89 | } |
90 | |
91 | void stopInhibition(QWindow *window) |
92 | { |
93 | m_inhibitions.remove(key: window); |
94 | } |
95 | |
96 | QHash<QWindow *, QSharedPointer<ShortcutsInhibitor>> m_inhibitions; |
97 | }; |
98 | |
99 | static std::shared_ptr<ShortcutsInhibitManager> theManager() |
100 | { |
101 | static std::weak_ptr<ShortcutsInhibitManager> managerInstance; |
102 | std::shared_ptr<ShortcutsInhibitManager> ret = managerInstance.lock(); |
103 | if (!ret) { |
104 | ret = std::make_shared<ShortcutsInhibitManager>(); |
105 | managerInstance = ret; |
106 | } |
107 | return ret; |
108 | } |
109 | |
110 | WaylandInhibition::WaylandInhibition(QWindow *window) |
111 | : ShortcutInhibition() |
112 | , m_window(window) |
113 | , m_manager(theManager()) |
114 | { |
115 | } |
116 | |
117 | WaylandInhibition::~WaylandInhibition() = default; |
118 | |
119 | bool WaylandInhibition::shortcutsAreInhibited() const |
120 | { |
121 | return m_manager->isInhibited(window: m_window); |
122 | } |
123 | |
124 | void WaylandInhibition::enableInhibition() |
125 | { |
126 | if (!m_manager->isActive()) { |
127 | qCInfo(KGUIADDONS_LOG) << "The compositor does not support the keyboard-shortcuts-inhibit-unstable-v1 protocol. Inhibiting shortcuts will not work."; |
128 | return; |
129 | } |
130 | m_manager->startInhibition(window: m_window); |
131 | } |
132 | |
133 | void WaylandInhibition::disableInhibition() |
134 | { |
135 | if (!m_manager->isActive()) { |
136 | return; |
137 | } |
138 | m_manager->stopInhibition(window: m_window); |
139 | } |
140 |