1+ #include " inhibitor.hpp"
2+
3+ #include < private/qwaylandwindow_p.h>
4+ #include < qlogging.h>
5+ #include < qobject.h>
6+ #include < qtmetamacros.h>
7+
8+ #include " ../../window/proxywindow.hpp"
9+ #include " ../../window/windowinterface.hpp"
10+ #include " proto.hpp"
11+
12+ namespace qs ::wayland::shortcuts_inhibit {
13+ using QtWaylandClient::QWaylandWindow;
14+
15+ ShortcutsInhibitor::ShortcutsInhibitor () {
16+ this ->bBoundWindow .setBinding ([this ] {
17+ return this ->bEnabled ? this ->bWindowObject .value () : nullptr ;
18+ });
19+ }
20+
21+ ShortcutsInhibitor::~ShortcutsInhibitor () { delete this ->inhibitor ; }
22+
23+ QObject* ShortcutsInhibitor::window () const { return this ->bWindowObject ; }
24+
25+ void ShortcutsInhibitor::setWindow (QObject* window) {
26+ if (window == this ->bWindowObject ) return ;
27+
28+ auto * proxyWindow = qobject_cast<ProxyWindowBase*>(window);
29+
30+ if (proxyWindow == nullptr ) {
31+ if (auto * iface = qobject_cast<WindowInterface*>(window)) {
32+ proxyWindow = iface->proxyWindow ();
33+ }
34+ }
35+
36+ this ->bWindowObject = proxyWindow ? window : nullptr ;
37+ }
38+
39+ void ShortcutsInhibitor::boundWindowChanged () {
40+ auto * window = this ->bBoundWindow .value ();
41+ auto * proxyWindow = qobject_cast<ProxyWindowBase*>(window);
42+
43+ if (proxyWindow == nullptr ) {
44+ if (auto * iface = qobject_cast<WindowInterface*>(window)) {
45+ proxyWindow = iface->proxyWindow ();
46+ }
47+ }
48+
49+ if (proxyWindow == this ->proxyWindow ) return ;
50+
51+ if (this ->mWaylandWindow ) {
52+ QObject::disconnect (this ->mWaylandWindow , nullptr , this , nullptr );
53+ this ->mWaylandWindow = nullptr ;
54+ this ->onWaylandSurfaceDestroyed ();
55+ }
56+
57+ if (this ->proxyWindow ) {
58+ QObject::disconnect (this ->proxyWindow , nullptr , this , nullptr );
59+ this ->proxyWindow = nullptr ;
60+ }
61+
62+ if (proxyWindow) {
63+ this ->proxyWindow = proxyWindow;
64+
65+ QObject::connect (
66+ proxyWindow,
67+ &QObject::destroyed,
68+ this ,
69+ &ShortcutsInhibitor::onWindowDestroyed
70+ );
71+
72+ QObject::connect (
73+ proxyWindow,
74+ &ProxyWindowBase::backerVisibilityChanged,
75+ this ,
76+ &ShortcutsInhibitor::onWindowVisibilityChanged
77+ );
78+
79+ this ->onWindowVisibilityChanged ();
80+ }
81+
82+ emit this ->windowChanged ();
83+ }
84+
85+ void ShortcutsInhibitor::onWindowDestroyed () {
86+ this ->proxyWindow = nullptr ;
87+ this ->onWaylandSurfaceDestroyed ();
88+ this ->bWindowObject = nullptr ;
89+ }
90+
91+ void ShortcutsInhibitor::onWindowVisibilityChanged () {
92+ if (!this ->proxyWindow ->isVisibleDirect ()) return ;
93+
94+ auto * window = this ->proxyWindow ->backingWindow ();
95+ if (!window->handle ()) window->create ();
96+
97+ auto * waylandWindow = dynamic_cast <QWaylandWindow*>(window->handle ());
98+ if (waylandWindow == this ->mWaylandWindow ) return ;
99+ this ->mWaylandWindow = waylandWindow;
100+
101+ QObject::connect (
102+ waylandWindow,
103+ &QObject::destroyed,
104+ this ,
105+ &ShortcutsInhibitor::onWaylandWindowDestroyed
106+ );
107+
108+ QObject::connect (
109+ waylandWindow,
110+ &QWaylandWindow::surfaceCreated,
111+ this ,
112+ &ShortcutsInhibitor::onWaylandSurfaceCreated
113+ );
114+
115+ QObject::connect (
116+ waylandWindow,
117+ &QWaylandWindow::surfaceDestroyed,
118+ this ,
119+ &ShortcutsInhibitor::onWaylandSurfaceDestroyed
120+ );
121+
122+ if (waylandWindow->surface ()) this ->onWaylandSurfaceCreated ();
123+ }
124+
125+ void ShortcutsInhibitor::onWaylandWindowDestroyed () { this ->mWaylandWindow = nullptr ; }
126+
127+ void ShortcutsInhibitor::onWaylandSurfaceCreated () {
128+ auto * manager = impl::ShortcutsInhibitManager::instance ();
129+
130+ if (!manager) {
131+ qWarning () << " Cannot enable shortcuts inhibitor as keyboard-shortcuts-inhibit-unstable-v1 is "
132+ " not supported by "
133+ " the current compositor." ;
134+ return ;
135+ }
136+
137+ delete this ->inhibitor ;
138+ this ->inhibitor = manager->createShortcutsInhibitor (this ->mWaylandWindow );
139+ }
140+
141+ void ShortcutsInhibitor::onWaylandSurfaceDestroyed () {
142+ delete this ->inhibitor ;
143+ this ->inhibitor = nullptr ;
144+ }
145+
146+ } // namespace qs::wayland::shortcuts_inhibit
0 commit comments