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
17class ShortcutsInhibitor : public QtWayland::zwp_keyboard_shortcuts_inhibitor_v1
18{
19public:
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
45private:
46 bool m_active = false;
47};
48
49class ShortcutsInhibitManager : public QWaylandClientExtensionTemplate<ShortcutsInhibitManager>, public QtWayland::zwp_keyboard_shortcuts_inhibit_manager_v1
50{
51public:
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
94static 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
105WaylandInhibition::WaylandInhibition(QWindow *window)
106 : ShortcutInhibition()
107 , m_window(window)
108 , m_manager(theManager())
109{
110}
111
112WaylandInhibition::~WaylandInhibition() = default;
113
114bool WaylandInhibition::shortcutsAreInhibited() const
115{
116 return m_manager->isInhibited(window: m_window);
117}
118
119void WaylandInhibition::enableInhibition()
120{
121 m_manager->startInhibition(window: m_window);
122}
123
124void WaylandInhibition::disableInhibition()
125{
126 m_manager->stopInhibition(window: m_window);
127}
128

source code of kguiaddons/src/recorder/waylandinhibition.cpp