File indexing completed on 2024-04-21 03:54:13
0001 /* 0002 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0003 SPDX-FileCopyrightText: 2020 David Redondo <kde@david-redondo.de> 0004 */ 0005 0006 #include "waylandinhibition_p.h" 0007 0008 #include <QDebug> 0009 #include <QGuiApplication> 0010 #include <QSharedPointer> 0011 #include <QWaylandClientExtensionTemplate> 0012 #include <QtWaylandClientVersion> 0013 #include <qpa/qplatformnativeinterface.h> 0014 0015 #include "qwayland-keyboard-shortcuts-inhibit-unstable-v1.h" 0016 0017 class ShortcutsInhibitor : public QtWayland::zwp_keyboard_shortcuts_inhibitor_v1 0018 { 0019 public: 0020 ShortcutsInhibitor(::zwp_keyboard_shortcuts_inhibitor_v1 *id) 0021 : QtWayland::zwp_keyboard_shortcuts_inhibitor_v1(id) 0022 { 0023 } 0024 0025 ~ShortcutsInhibitor() override 0026 { 0027 destroy(); 0028 } 0029 0030 void zwp_keyboard_shortcuts_inhibitor_v1_active() override 0031 { 0032 m_active = true; 0033 } 0034 0035 void zwp_keyboard_shortcuts_inhibitor_v1_inactive() override 0036 { 0037 m_active = false; 0038 } 0039 0040 bool isActive() const 0041 { 0042 return m_active; 0043 } 0044 0045 private: 0046 bool m_active = false; 0047 }; 0048 0049 class ShortcutsInhibitManager : public QWaylandClientExtensionTemplate<ShortcutsInhibitManager>, public QtWayland::zwp_keyboard_shortcuts_inhibit_manager_v1 0050 { 0051 public: 0052 ShortcutsInhibitManager() 0053 : QWaylandClientExtensionTemplate<ShortcutsInhibitManager>(1) 0054 { 0055 initialize(); 0056 } 0057 ~ShortcutsInhibitManager() override 0058 { 0059 if (isInitialized()) { 0060 destroy(); 0061 } 0062 } 0063 0064 void startInhibition(QWindow *window) 0065 { 0066 if (m_inhibitions.contains(window)) { 0067 return; 0068 } 0069 QPlatformNativeInterface *nativeInterface = qGuiApp->platformNativeInterface(); 0070 if (!nativeInterface) { 0071 return; 0072 } 0073 auto seat = static_cast<wl_seat *>(nativeInterface->nativeResourceForIntegration("wl_seat")); 0074 auto surface = static_cast<wl_surface *>(nativeInterface->nativeResourceForWindow("surface", window)); 0075 if (!seat || !surface) { 0076 return; 0077 } 0078 m_inhibitions[window].reset(new ShortcutsInhibitor(inhibit_shortcuts(surface, seat))); 0079 } 0080 0081 bool isInhibited(QWindow *window) const 0082 { 0083 return m_inhibitions.contains(window); 0084 } 0085 0086 void stopInhibition(QWindow *window) 0087 { 0088 m_inhibitions.remove(window); 0089 } 0090 0091 QHash<QWindow *, QSharedPointer<ShortcutsInhibitor>> m_inhibitions; 0092 }; 0093 0094 static std::shared_ptr<ShortcutsInhibitManager> theManager() 0095 { 0096 static std::weak_ptr<ShortcutsInhibitManager> managerInstance; 0097 std::shared_ptr<ShortcutsInhibitManager> ret = managerInstance.lock(); 0098 if (!ret) { 0099 ret = std::make_shared<ShortcutsInhibitManager>(); 0100 managerInstance = ret; 0101 } 0102 return ret; 0103 } 0104 0105 WaylandInhibition::WaylandInhibition(QWindow *window) 0106 : ShortcutInhibition() 0107 , m_window(window) 0108 , m_manager(theManager()) 0109 { 0110 } 0111 0112 WaylandInhibition::~WaylandInhibition() = default; 0113 0114 bool WaylandInhibition::shortcutsAreInhibited() const 0115 { 0116 return m_manager->isInhibited(m_window); 0117 } 0118 0119 void WaylandInhibition::enableInhibition() 0120 { 0121 m_manager->startInhibition(m_window); 0122 } 0123 0124 void WaylandInhibition::disableInhibition() 0125 { 0126 m_manager->stopInhibition(m_window); 0127 }