Skip to content

Commit 9adde25

Browse files
committed
wayland/shortcuts-inhibitor: fix rest
1 parent 146152b commit 9adde25

File tree

3 files changed

+94
-32
lines changed

3 files changed

+94
-32
lines changed

src/wayland/shortcuts_inhibit/inhibitor.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#include "inhibitor.hpp"
22

33
#include <private/qwaylandwindow_p.h>
4+
#include <qguiapplication.h>
45
#include <qlogging.h>
56
#include <qloggingcategory.h>
67
#include <qobject.h>
8+
#include <qtmetamacros.h>
79

810
#include "../../window/proxywindow.hpp"
911
#include "../../window/windowinterface.hpp"
@@ -19,8 +21,19 @@ ShortcutInhibitor::ShortcutInhibitor() {
1921

2022
this->bActive.setBinding([this]() {
2123
auto* inhibitor = this->bInhibitor.value();
22-
return inhibitor ? inhibitor->bindableActive().value() : false;
24+
if (!inhibitor) return false;
25+
if (!inhibitor->bindableActive().value()) return false;
26+
return this->bWindow.value() == this->bFocusedWindow;
2327
});
28+
29+
QObject::connect(
30+
dynamic_cast<QGuiApplication*>(QGuiApplication::instance()),
31+
&QGuiApplication::focusWindowChanged,
32+
this,
33+
&ShortcutInhibitor::onFocusedWindowChanged
34+
);
35+
36+
this->onFocusedWindowChanged(QGuiApplication::focusWindow());
2437
}
2538

2639
ShortcutInhibitor::~ShortcutInhibitor() {
@@ -32,7 +45,7 @@ ShortcutInhibitor::~ShortcutInhibitor() {
3245
manager->unrefShortcutsInhibitor(this->bInhibitor);
3346
}
3447

35-
void ShortcutInhibitor::boundWindowChanged() {
48+
void ShortcutInhibitor::onBoundWindowChanged() {
3649
auto* window = this->bBoundWindow.value();
3750
auto* proxyWindow = qobject_cast<ProxyWindowBase*>(window);
3851

@@ -44,17 +57,17 @@ void ShortcutInhibitor::boundWindowChanged() {
4457

4558
if (proxyWindow == this->proxyWindow) return;
4659

60+
if (this->proxyWindow) {
61+
QObject::disconnect(this->proxyWindow, nullptr, this, nullptr);
62+
this->proxyWindow = nullptr;
63+
}
64+
4765
if (this->mWaylandWindow) {
4866
QObject::disconnect(this->mWaylandWindow, nullptr, this, nullptr);
4967
this->mWaylandWindow = nullptr;
5068
this->onWaylandSurfaceDestroyed();
5169
}
5270

53-
if (this->proxyWindow) {
54-
QObject::disconnect(this->proxyWindow, nullptr, this, nullptr);
55-
this->proxyWindow = nullptr;
56-
}
57-
5871
if (proxyWindow) {
5972
this->proxyWindow = proxyWindow;
6073

@@ -74,7 +87,6 @@ void ShortcutInhibitor::boundWindowChanged() {
7487
void ShortcutInhibitor::onWindowDestroyed() {
7588
this->proxyWindow = nullptr;
7689
this->onWaylandSurfaceDestroyed();
77-
this->bWindowObject = nullptr;
7890
}
7991

8092
void ShortcutInhibitor::onWindowVisibilityChanged() {
@@ -90,6 +102,7 @@ void ShortcutInhibitor::onWindowVisibilityChanged() {
90102
}
91103
if (waylandWindow == this->mWaylandWindow) return;
92104
this->mWaylandWindow = waylandWindow;
105+
this->bWindow = window;
93106

94107
QObject::connect(
95108
waylandWindow,
@@ -144,7 +157,7 @@ void ShortcutInhibitor::onWaylandSurfaceDestroyed() {
144157
this->bInhibitor = nullptr;
145158
}
146159

147-
void ShortcutInhibitor::inhibitorChanged() {
160+
void ShortcutInhibitor::onInhibitorChanged() {
148161
auto* inhibitor = this->bInhibitor.value();
149162
if (inhibitor) {
150163
QObject::connect(
@@ -162,7 +175,12 @@ void ShortcutInhibitor::onInhibitorActiveChanged() {
162175
// Compositor has deactivated the inhibitor, making it invalid.
163176
// Set enabled to false so the user can enable it again to create a new inhibitor.
164177
this->bEnabled = false;
178+
emit this->cancelled();
165179
}
166180
}
167181

182+
void ShortcutInhibitor::onFocusedWindowChanged(QWindow* focusedWindow) {
183+
this->bFocusedWindow = focusedWindow;
184+
}
185+
168186
} // namespace qs::wayland::shortcuts_inhibit

src/wayland/shortcuts_inhibit/inhibitor.hpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <qqmlintegration.h>
66
#include <qtclasshelpermacros.h>
77
#include <qtmetamacros.h>
8+
#include <qwindow.h>
89

910
#include "../../window/proxywindow.hpp"
1011
#include "proto.hpp"
@@ -29,11 +30,12 @@ class ShortcutInhibitor: public QObject {
2930
/// If the shortcuts inhibitor should be enabled. Defaults to false.
3031
Q_PROPERTY(bool enabled READ default WRITE default NOTIFY enabledChanged BINDABLE bindableEnabled);
3132
/// The window to associate the shortcuts inhibitor with.
33+
/// The inhibitor will only inhibit shortcuts pressed while this window has keyboard focus.
3234
///
3335
/// Must be set to a non null value to enable the inhibitor.
3436
Q_PROPERTY(QObject* window READ default WRITE default NOTIFY windowChanged BINDABLE bindableWindow);
35-
/// Whether the inhibitor is currently active. The inhibitor is only active when the
36-
/// compositor has granted the request.
37+
/// Whether the inhibitor is currently active. The inhibitor is only active if @@enabled is true,
38+
/// @@window has keyboard focus, and the compositor grants the inhibit request.
3739
///
3840
/// The compositor may deactivate the inhibitor at any time (for example, if the user requests
3941
/// normal shortcuts to be restored). When deactivated by the compositor, the inhibitor cannot be
@@ -54,6 +56,8 @@ class ShortcutInhibitor: public QObject {
5456
void enabledChanged();
5557
void windowChanged();
5658
void activeChanged();
59+
/// Sent if the compositor cancels the inhibitor while it is active.
60+
void cancelled();
5761

5862
private slots:
5963
void onWindowDestroyed();
@@ -64,16 +68,20 @@ private slots:
6468
void onInhibitorActiveChanged();
6569

6670
private:
67-
void boundWindowChanged();
68-
void inhibitorChanged();
71+
void onBoundWindowChanged();
72+
void onInhibitorChanged();
73+
void onFocusedWindowChanged(QWindow* focusedWindow);
74+
6975
ProxyWindowBase* proxyWindow = nullptr;
7076
QtWaylandClient::QWaylandWindow* mWaylandWindow = nullptr;
7177

7278
// clang-format off
7379
Q_OBJECT_BINDABLE_PROPERTY(ShortcutInhibitor, bool, bEnabled, &ShortcutInhibitor::enabledChanged);
7480
Q_OBJECT_BINDABLE_PROPERTY(ShortcutInhibitor, QObject*, bWindowObject, &ShortcutInhibitor::windowChanged);
75-
Q_OBJECT_BINDABLE_PROPERTY(ShortcutInhibitor, QObject*, bBoundWindow, &ShortcutInhibitor::boundWindowChanged);
76-
Q_OBJECT_BINDABLE_PROPERTY(ShortcutInhibitor, impl::ShortcutsInhibitor*, bInhibitor, &ShortcutInhibitor::inhibitorChanged);
81+
Q_OBJECT_BINDABLE_PROPERTY(ShortcutInhibitor, QObject*, bBoundWindow, &ShortcutInhibitor::onBoundWindowChanged);
82+
Q_OBJECT_BINDABLE_PROPERTY(ShortcutInhibitor, impl::ShortcutsInhibitor*, bInhibitor, &ShortcutInhibitor::onInhibitorChanged);
83+
Q_OBJECT_BINDABLE_PROPERTY(ShortcutInhibitor, QWindow*, bWindow);
84+
Q_OBJECT_BINDABLE_PROPERTY(ShortcutInhibitor, QWindow*, bFocusedWindow);
7785
Q_OBJECT_BINDABLE_PROPERTY(ShortcutInhibitor, bool, bActive, &ShortcutInhibitor::activeChanged);
7886
// clang-format on
7987
};

src/wayland/shortcuts_inhibit/test/manual/test.qml

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,62 @@ import QtQuick.Controls
44
import Quickshell
55
import Quickshell.Wayland
66

7-
FloatingWindow {
8-
id: w
9-
color: contentItem.palette.window
7+
Scope {
8+
Timer {
9+
id: toggleTimer
10+
interval: 100
11+
onTriggered: windowLoader.active = true
12+
}
1013

11-
ColumnLayout {
12-
anchors.centerIn: parent
14+
LazyLoader {
15+
id: windowLoader
16+
active: true
1317

14-
CheckBox {
15-
id: enabledCb
16-
text: "Enabled"
17-
}
18+
property bool enabled: false
1819

19-
Label {
20-
text: `Active: ${inhibitor.active}`
21-
}
22-
}
20+
FloatingWindow {
21+
id: w
22+
color: contentItem.palette.window
23+
24+
ColumnLayout {
25+
anchors.centerIn: parent
26+
27+
CheckBox {
28+
id: loadedCb
29+
text: "Loaded"
30+
checked: true
31+
}
2332

24-
ShortcutInhibitor {
25-
id: inhibitor
26-
window: w
27-
enabled: enabledCb.checked
33+
CheckBox {
34+
id: enabledCb
35+
text: "Enabled"
36+
checked: windowLoader.enabled
37+
onCheckedChanged: windowLoader.enabled = checked
38+
}
39+
40+
Label {
41+
text: `Active: ${inhibitorLoader.item?.active ?? false}`
42+
}
43+
44+
Button {
45+
text: "Toggle Window"
46+
onClicked: {
47+
windowLoader.active = false;
48+
toggleTimer.start();
49+
}
50+
}
51+
}
52+
53+
LazyLoader {
54+
id: inhibitorLoader
55+
active: loadedCb.checked
56+
57+
ShortcutInhibitor {
58+
window: w
59+
enabled: enabledCb.checked
60+
onCancelled: enabledCb.checked = false
61+
}
62+
}
63+
}
2864
}
2965
}

0 commit comments

Comments
 (0)