Skip to content

Commit 9654b19

Browse files
committed
wayland/shortcuts-inhibit: merge multiple inhibitors on same surface
1 parent a764cec commit 9654b19

File tree

4 files changed

+53
-22
lines changed

4 files changed

+53
-22
lines changed

src/wayland/shortcuts_inhibit/inhibitor.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,15 @@ ShortcutsInhibitor::ShortcutsInhibitor() {
1818
});
1919
}
2020

21-
ShortcutsInhibitor::~ShortcutsInhibitor() { delete this->inhibitor; }
21+
ShortcutsInhibitor::~ShortcutsInhibitor() {
22+
if (!this->inhibitor) return;
23+
24+
auto* manager = impl::ShortcutsInhibitManager::instance();
25+
if (!manager) return;
26+
27+
QObject::disconnect(this->inhibitor, nullptr, this, nullptr);
28+
manager->unrefShortcutsInhibitor(this->inhibitor);
29+
}
2230

2331
QObject* ShortcutsInhibitor::window() const { return this->bWindowObject; }
2432

@@ -140,7 +148,7 @@ void ShortcutsInhibitor::onWaylandSurfaceCreated() {
140148

141149
if (this->inhibitor) {
142150
QObject::disconnect(this->inhibitor, nullptr, this, nullptr);
143-
delete this->inhibitor;
151+
manager->unrefShortcutsInhibitor(this->inhibitor);
144152
this->inhibitor = nullptr;
145153
}
146154
this->inhibitor = manager->createShortcutsInhibitor(this->mWaylandWindow);
@@ -156,13 +164,17 @@ void ShortcutsInhibitor::onWaylandSurfaceCreated() {
156164
}
157165

158166
void ShortcutsInhibitor::onWaylandSurfaceDestroyed() {
159-
if (this->inhibitor) {
160-
QObject::disconnect(this->inhibitor, nullptr, this, nullptr);
161-
auto wasActive = this->inhibitor->isActive();
162-
delete this->inhibitor;
163-
this->inhibitor = nullptr;
164-
if (wasActive) { emit this->activeChanged(); }
165-
}
167+
if (!this->inhibitor) return;
168+
169+
auto* manager = impl::ShortcutsInhibitManager::instance();
170+
if (!manager) return;
171+
172+
QObject::disconnect(this->inhibitor, nullptr, this, nullptr);
173+
auto wasActive = this->inhibitor->isActive();
174+
manager->unrefShortcutsInhibitor(this->inhibitor);
175+
this->inhibitor = nullptr;
176+
177+
if (wasActive) { emit this->activeChanged(); }
166178
}
167179

168180
} // namespace qs::wayland::shortcuts_inhibit

src/wayland/shortcuts_inhibit/inhibitor.hpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,12 @@ class ShortcutsInhibitor: public QObject {
3232
///
3333
/// Must be set to a non null value to enable the inhibitor.
3434
Q_PROPERTY(QObject* window READ window WRITE setWindow NOTIFY windowChanged);
35-
/// Whether the inhibitor is currently active. The inhibitor is active when the compositor
36-
/// has granted the request and shortcuts are being inhibited.
35+
/// Whether the inhibitor is currently active. The inhibitor is only active when the
36+
/// associated window has keyboard focus and the compositor has granted the request.
3737
///
3838
/// The compositor may deactivate the inhibitor if the user requests normal shortcuts to be restored.
3939
/// When inactive, there is no way to programmatically reactivate it - the user must do so through
4040
/// compositor-specific mechanisms.
41-
///
42-
/// Note that if the surface loses focus or is destroyed, the inhibitor becomes irrelevant and this
43-
/// property will become false, but no inactive event is sent by the compositor in those cases.
4441
Q_PROPERTY(bool active READ isActive NOTIFY activeChanged);
4542
// clang-format on
4643

src/wayland/shortcuts_inhibit/proto.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,26 +40,46 @@ ShortcutsInhibitManager::createShortcutsInhibitor(QtWaylandClient::QWaylandWindo
4040
auto* wlSurface = surface->surface();
4141

4242
if (this->inhibitors.contains(wlSurface)) {
43-
qCWarning(logShortcutsInhibit)
44-
<< "An inhibitor already exists for surface, skipping creation." << wlSurface;
45-
return nullptr;
43+
auto* inhibitor = this->inhibitors.value(wlSurface);
44+
this->refCounts[inhibitor]++;
45+
qCDebug(logShortcutsInhibit) << "Reusing existing inhibitor" << inhibitor << "for surface"
46+
<< wlSurface << "- refcount:" << this->refCounts[inhibitor];
47+
return inhibitor;
4648
}
4749

4850
auto* inhibitor =
4951
new ShortcutsInhibitor(this->inhibit_shortcuts(wlSurface, inputDevice->object()), wlSurface);
5052
this->inhibitors.insert(wlSurface, inhibitor);
53+
this->refCounts.insert(inhibitor, 1);
5154
qCDebug(logShortcutsInhibit) << "Created inhibitor" << inhibitor << "for surface" << wlSurface;
5255
return inhibitor;
5356
}
5457

55-
void ShortcutsInhibitManager::destroyShortcutsInhibitor(ShortcutsInhibitor* inhibitor) {
56-
if (inhibitor) { this->inhibitors.remove(inhibitor->surface()); }
58+
void ShortcutsInhibitManager::refShortcutsInhibitor(ShortcutsInhibitor* inhibitor) {
59+
if (inhibitor && this->refCounts.contains(inhibitor)) {
60+
this->refCounts[inhibitor]++;
61+
qCDebug(logShortcutsInhibit) << "Incremented refcount for inhibitor" << inhibitor
62+
<< "- refcount:" << this->refCounts[inhibitor];
63+
}
64+
}
65+
66+
void ShortcutsInhibitManager::unrefShortcutsInhibitor(ShortcutsInhibitor* inhibitor) {
67+
if (!inhibitor || !this->refCounts.contains(inhibitor)) return;
68+
69+
this->refCounts[inhibitor]--;
70+
qCDebug(logShortcutsInhibit) << "Decremented refcount for inhibitor" << inhibitor
71+
<< "- refcount:" << this->refCounts[inhibitor];
72+
73+
if (this->refCounts[inhibitor] <= 0) {
74+
qCDebug(logShortcutsInhibit) << "Refcount reached 0, destroying inhibitor" << inhibitor;
75+
this->inhibitors.remove(inhibitor->surface());
76+
this->refCounts.remove(inhibitor);
77+
delete inhibitor;
78+
}
5779
}
5880

5981
ShortcutsInhibitor::~ShortcutsInhibitor() {
6082
qCDebug(logShortcutsInhibit) << "Destroying inhibitor" << this << "for surface" << this->mSurface;
61-
auto* manager = ShortcutsInhibitManager::instance();
62-
if (manager) { manager->destroyShortcutsInhibitor(this); }
6383
if (this->isInitialized()) this->destroy();
6484
}
6585

src/wayland/shortcuts_inhibit/proto.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ class ShortcutsInhibitManager
1818
explicit ShortcutsInhibitManager();
1919

2020
ShortcutsInhibitor* createShortcutsInhibitor(QtWaylandClient::QWaylandWindow* surface);
21-
void destroyShortcutsInhibitor(ShortcutsInhibitor* inhibitor);
21+
void refShortcutsInhibitor(ShortcutsInhibitor* inhibitor);
22+
void unrefShortcutsInhibitor(ShortcutsInhibitor* inhibitor);
2223

2324
static ShortcutsInhibitManager* instance();
2425

2526
private:
2627
QHash<wl_surface*, ShortcutsInhibitor*> inhibitors;
28+
QHash<ShortcutsInhibitor*, int> refCounts;
2729
};
2830

2931
class ShortcutsInhibitor

0 commit comments

Comments
 (0)