Skip to content

Commit dfca280

Browse files
committed
Use qwaylandscanner
1 parent e3b5339 commit dfca280

20 files changed

+340
-841
lines changed

.gitmodules

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[submodule "lib/wayland-protocols/wayland-protocols"]
2+
path = lib/wayland-protocols/wayland-protocols
3+
url = https://gitlab.freedesktop.org/wayland/wayland-protocols.git
4+
[submodule "lib/wayland-protocols/wlr-protocols"]
5+
path = lib/wayland-protocols/wlr-protocols
6+
url = https://github.com/swaywm/wlr-protocols.git

lib/Wm/wayland/waylandbackend.cpp

+30-39
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,24 @@
2626
#include <qpa/qplatformnativeinterface.h>
2727

2828
#include <wayland-client.h>
29-
#include "wlr-foreign-toplevel-management-unstable-v1-proto.h"
3029

3130
#include <Shell>
3231
#include <tlogger.h>
3332

3433
#include "waylandwindow.h"
3534

3635
struct WaylandBackendPrivate {
36+
WaylandBackend* parent;
3737
WaylandAccessibility* accessibility;
3838

3939
wl_display* display;
4040
wl_seat* seat;
41-
zwlr_foreign_toplevel_manager_v1* toplevelManager = nullptr;
4241
QMap<zwlr_foreign_toplevel_handle_v1*, WaylandWindowPtr> windows;
4342
};
4443

4544
WaylandBackend::WaylandBackend() : WmBackend() {
4645
d = new WaylandBackendPrivate();
46+
d->parent = this;
4747
d->accessibility = new WaylandAccessibility(this);
4848

4949
LayerShellQt::Shell::useLayerShell();
@@ -54,8 +54,7 @@ WaylandBackend::WaylandBackend() : WmBackend() {
5454
wl_registry_listener listener = {
5555
[](void* data, wl_registry * registry, quint32 name, const char* interface, quint32 version) {
5656
if (strcmp(interface, zwlr_foreign_toplevel_manager_v1_interface.name) == 0) {
57-
zwlr_foreign_toplevel_manager_v1* toplevelManager = static_cast<zwlr_foreign_toplevel_manager_v1*>(wl_registry_bind(registry, name, &zwlr_foreign_toplevel_manager_v1_interface, std::min(version, static_cast<quint32>(3))));
58-
static_cast<WaylandBackendPrivate*>(data)->toplevelManager = toplevelManager;
57+
static_cast<WaylandBackendPrivate*>(data)->parent->QtWayland::zwlr_foreign_toplevel_manager_v1::init(registry, name, qMin<quint32>(version, 3));
5958
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
6059
wl_seat* seat = static_cast<wl_seat*>(wl_registry_bind(registry, name, &wl_seat_interface, std::min(version, static_cast<quint32>(1))));
6160
static_cast<WaylandBackendPrivate*>(data)->seat = seat;
@@ -72,17 +71,7 @@ WaylandBackend::WaylandBackend() : WmBackend() {
7271
wl_registry_add_listener(registry, &listener, d);
7372
wl_display_roundtrip(d->display);
7473

75-
if (d->toplevelManager) {
76-
zwlr_foreign_toplevel_manager_v1_listener* toplevelEvents = new zwlr_foreign_toplevel_manager_v1_listener();
77-
toplevelEvents->toplevel = [](void* data, struct zwlr_foreign_toplevel_manager_v1 * zwlr_foreign_toplevel_manager_v1, struct zwlr_foreign_toplevel_handle_v1 * toplevel) {
78-
static_cast<WaylandBackend*>(data)->newToplevel(toplevel);
79-
};
80-
toplevelEvents->finished = [](void* data, struct zwlr_foreign_toplevel_manager_v1 * zwlr_foreign_toplevel_manager_v1) {
81-
82-
};
83-
84-
zwlr_foreign_toplevel_manager_v1_add_listener(d->toplevelManager, toplevelEvents, this);
85-
} else {
74+
if (!this->QtWayland::zwlr_foreign_toplevel_manager_v1::isInitialized()) {
8675
tWarn("WaylandBackend") << "The compositor doesn't support the wlr-foreign-toplevel-management protocol";
8776
}
8877
wl_registry_destroy(registry);
@@ -104,13 +93,6 @@ wl_seat* WaylandBackend::seat() {
10493
return d->seat;
10594
}
10695

107-
void WaylandBackend::newToplevel(zwlr_foreign_toplevel_handle_v1* toplevel) {
108-
WaylandWindowPtr window = new WaylandWindow(toplevel, this);
109-
d->windows.insert(toplevel, window);
110-
111-
emit windowAdded(window.data());
112-
}
113-
11496
void WaylandBackend::signalToplevelClosed(zwlr_foreign_toplevel_handle_v1* toplevel) {
11597
WaylandWindowPtr window = d->windows.value(toplevel);
11698
emit windowRemoved(window.data());
@@ -180,6 +162,7 @@ void WaylandBackend::setSystemWindow(QWidget* widget, DesktopWm::SystemWindowTyp
180162
break;
181163
case DesktopWm::SystemWindowTypeNotification:
182164
layerWindow->setLayer(LayerShellQt::Window::LayerOverlay);
165+
layerWindow->setExclusiveZone(0);
183166
break;
184167
case DesktopWm::SystemWindowTypeMenu:
185168
layerWindow->setLayer(LayerShellQt::Window::LayerOverlay);
@@ -196,23 +179,23 @@ void WaylandBackend::setScreenMarginForWindow(QWidget* widget, QScreen* screen,
196179
//TODO: Implement
197180

198181
// QTimer::singleShot(1000, [ = ] {
199-
// LayerShellQt::Window::get(widget->windowHandle())->setExclusiveZone(width);
200-
// LayerShellQt::Window::Anchors anchors;
201-
// switch (edge) {
202-
// case Qt::TopEdge:
203-
// anchors = static_cast<LayerShellQt::Window::Anchors>(LayerShellQt::Window::AnchorLeft | LayerShellQt::Window::AnchorRight);
204-
// break;
205-
// case Qt::LeftEdge:
206-
// anchors = static_cast<LayerShellQt::Window::Anchors>(LayerShellQt::Window::AnchorLeft | LayerShellQt::Window::AnchorTop | LayerShellQt::Window::AnchorBottom);
207-
// break;
208-
// case Qt::RightEdge:
209-
// anchors = LayerShellQt::Window::AnchorRight;
210-
// break;
211-
// case Qt::BottomEdge:
212-
// anchors = LayerShellQt::Window::AnchorBottom;
213-
// break;
214-
// }
215-
// LayerShellQt::Window::get(widget->windowHandle())->setAnchors(anchors);
182+
// LayerShellQt::Window::get(widget->windowHandle())->setExclusiveZone(20);
183+
// LayerShellQt::Window::Anchors anchors;
184+
// switch (edge) {
185+
// case Qt::TopEdge:
186+
// anchors = static_cast<LayerShellQt::Window::Anchors>(LayerShellQt::Window::AnchorLeft | LayerShellQt::Window::AnchorRight | LayerShellQt::Window::AnchorTop);
187+
// break;
188+
// case Qt::LeftEdge:
189+
// anchors = static_cast<LayerShellQt::Window::Anchors>(LayerShellQt::Window::AnchorLeft | LayerShellQt::Window::AnchorTop | LayerShellQt::Window::AnchorBottom);
190+
// break;
191+
// case Qt::RightEdge:
192+
// anchors = LayerShellQt::Window::AnchorRight;
193+
// break;
194+
// case Qt::BottomEdge:
195+
// anchors = LayerShellQt::Window::AnchorBottom;
196+
// break;
197+
// }
198+
// LayerShellQt::Window::get(widget->windowHandle())->setAnchors(anchors);
216199
// });
217200

218201
}
@@ -239,3 +222,11 @@ quint64 WaylandBackend::grabKey(Qt::Key key, Qt::KeyboardModifiers modifiers) {
239222
void WaylandBackend::ungrabKey(quint64 grab) {
240223
//TODO: Implement
241224
}
225+
226+
227+
void WaylandBackend::zwlr_foreign_toplevel_manager_v1_toplevel(::zwlr_foreign_toplevel_handle_v1* toplevel) {
228+
WaylandWindowPtr window = new WaylandWindow(toplevel, this);
229+
d->windows.insert(toplevel, window);
230+
231+
emit windowAdded(window.data());
232+
}

lib/Wm/wayland/waylandbackend.h

+9-5
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,14 @@
2222

2323
#include <QObject>
2424
#include "../private/wmbackend.h"
25+
#include "qwayland-wlr-foreign-toplevel-management-unstable-v1.h"
2526

2627
struct zwlr_foreign_toplevel_handle_v1;
2728
struct WaylandBackendPrivate;
28-
struct WaylandWindowEventListener;
29+
struct WaylandWindow;
2930
struct wl_display;
3031
struct wl_seat;
31-
class WaylandBackend : public WmBackend {
32+
class WaylandBackend : public WmBackend, public QtWayland::zwlr_foreign_toplevel_manager_v1 {
3233
Q_OBJECT
3334
public:
3435
explicit WaylandBackend();
@@ -38,14 +39,13 @@ class WaylandBackend : public WmBackend {
3839
wl_display* display();
3940
wl_seat* seat();
4041

41-
void newToplevel(zwlr_foreign_toplevel_handle_v1* toplevel);
4242
signals:
4343

4444
protected:
45-
void signalToplevelClosed(zwlr_foreign_toplevel_handle_v1* toplevel);
45+
void signalToplevelClosed(::zwlr_foreign_toplevel_handle_v1* toplevel);
4646

4747
private:
48-
friend WaylandWindowEventListener;
48+
friend WaylandWindow;
4949
WaylandBackendPrivate* d;
5050

5151
// WmBackend interface
@@ -67,6 +67,10 @@ class WaylandBackend : public WmBackend {
6767
quint64 msecsIdle();
6868
quint64 grabKey(Qt::Key key, Qt::KeyboardModifiers modifiers);
6969
void ungrabKey(quint64 grab);
70+
71+
// zwlr_foreign_toplevel_manager_v1 interface
72+
protected:
73+
void zwlr_foreign_toplevel_manager_v1_toplevel(::zwlr_foreign_toplevel_handle_v1* toplevel);
7074
};
7175

7276
#endif // WAYLANDBACKEND_H

lib/Wm/wayland/waylandwindow.cpp

+47-79
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,8 @@
2222
#include <QRect>
2323
#include <QIcon>
2424
#include "waylandbackend.h"
25-
#include "wlr-foreign-toplevel-management-unstable-v1-proto.h"
2625

2726
struct WaylandWindowPrivate {
28-
zwlr_foreign_toplevel_handle_v1* handle;
2927
WaylandBackend* backend;
3028
WaylandWindowEventListener* listener;
3129

@@ -49,85 +47,13 @@ struct WaylandWindowEventListener {
4947
WaylandWindowEventListener(WaylandWindow* parentWindow) {
5048
this->parent = parentWindow;
5149
}
52-
53-
void titleChanged(QString title) {
54-
this->parent->d->title = title;
55-
emit this->parent->titleChanged();
56-
}
57-
58-
void applicationChanged(QString application) {
59-
ApplicationPointer newApp(new Application(application));
60-
if (newApp->isValid()) {
61-
this->parent->d->application = newApp;
62-
} else {
63-
this->parent->d->application.clear();
64-
}
65-
66-
emit this->parent->applicationChanged();
67-
emit this->parent->iconChanged();
68-
}
69-
70-
void stateChanged(wl_array* state) {
71-
WaylandWindowPrivate::WindowStateFlags windowState = WaylandWindowPrivate::NoState;
72-
for (quint32* flag = static_cast<quint32*>(state->data); reinterpret_cast<char*>(flag) < (static_cast<char*>(state->data) + state->size); flag++) {
73-
if (*flag == ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED) {
74-
windowState |= WaylandWindowPrivate::Activated;
75-
}
76-
if (*flag == ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED) {
77-
windowState |= WaylandWindowPrivate::Maximised;
78-
}
79-
if (*flag == ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED) {
80-
windowState |= WaylandWindowPrivate::Minimised;
81-
}
82-
}
83-
84-
this->parent->d->state = windowState;
85-
emit this->parent->windowStateChanged();
86-
emit this->parent->d->backend->activeWindowChanged();
87-
}
88-
89-
void closed() {
90-
this->parent->d->backend->signalToplevelClosed(this->parent->d->handle);
91-
}
9250
};
9351

94-
WaylandWindow::WaylandWindow(zwlr_foreign_toplevel_handle_v1* handle, WaylandBackend* backend) : DesktopWmWindow() {
52+
WaylandWindow::WaylandWindow(::zwlr_foreign_toplevel_handle_v1* handle, WaylandBackend* backend) : DesktopWmWindow(), QtWayland::zwlr_foreign_toplevel_handle_v1(handle) {
9553
d = new WaylandWindowPrivate();
96-
d->handle = handle;
9754
d->backend = backend;
9855

9956
d->listener = new WaylandWindowEventListener(this);
100-
101-
zwlr_foreign_toplevel_handle_v1_listener* listener = new zwlr_foreign_toplevel_handle_v1_listener();
102-
listener->title = [](void* data, struct zwlr_foreign_toplevel_handle_v1 * zwlr_foreign_toplevel_handle_v1, const char* title) {
103-
Q_UNUSED(zwlr_foreign_toplevel_handle_v1)
104-
static_cast<WaylandWindowEventListener*>(data)->titleChanged(QString::fromLocal8Bit(title));
105-
};
106-
listener->app_id = [](void* data, struct zwlr_foreign_toplevel_handle_v1 * zwlr_foreign_toplevel_handle_v1, const char* app_id) {
107-
Q_UNUSED(zwlr_foreign_toplevel_handle_v1)
108-
static_cast<WaylandWindowEventListener*>(data)->applicationChanged(QString::fromLocal8Bit(app_id));
109-
};
110-
listener->output_enter = [](void* data, struct zwlr_foreign_toplevel_handle_v1 * zwlr_foreign_toplevel_handle_v1, struct wl_output * output) {
111-
112-
};
113-
listener->output_leave = [](void* data, struct zwlr_foreign_toplevel_handle_v1 * zwlr_foreign_toplevel_handle_v1, struct wl_output * output) {
114-
115-
};
116-
listener->state = [](void* data, struct zwlr_foreign_toplevel_handle_v1 * zwlr_foreign_toplevel_handle_v1, struct wl_array * state) {
117-
Q_UNUSED(zwlr_foreign_toplevel_handle_v1)
118-
static_cast<WaylandWindowEventListener*>(data)->stateChanged(state);
119-
};
120-
listener->done = [](void* data, struct zwlr_foreign_toplevel_handle_v1 * zwlr_foreign_toplevel_handle_v1) {
121-
122-
};
123-
listener->closed = [](void* data, struct zwlr_foreign_toplevel_handle_v1 * zwlr_foreign_toplevel_handle_v1) {
124-
Q_UNUSED(zwlr_foreign_toplevel_handle_v1)
125-
static_cast<WaylandWindowEventListener*>(data)->closed();
126-
};
127-
listener->parent = [](void* data, struct zwlr_foreign_toplevel_handle_v1 * zwlr_foreign_toplevel_handle_v1, struct zwlr_foreign_toplevel_handle_v1 * parent) {
128-
129-
};
130-
zwlr_foreign_toplevel_handle_v1_add_listener(handle, listener, d->listener);
13157
wl_display_roundtrip(backend->display());
13258
}
13359

@@ -190,12 +116,54 @@ ApplicationPointer WaylandWindow::application() {
190116

191117
void WaylandWindow::activate() {
192118
wl_seat* seat = d->backend->seat();
193-
zwlr_foreign_toplevel_handle_v1_activate(d->handle, seat);
119+
this->QtWayland::zwlr_foreign_toplevel_handle_v1::activate(seat);
194120
}
195121

196-
void WaylandWindow::close() {
197-
zwlr_foreign_toplevel_handle_v1_close(d->handle);
122+
void WaylandWindow::kill() {
198123
}
199124

200-
void WaylandWindow::kill() {
125+
126+
void WaylandWindow::zwlr_foreign_toplevel_handle_v1_title(const QString& title) {
127+
d->title = title;
128+
emit titleChanged();
129+
}
130+
131+
void WaylandWindow::zwlr_foreign_toplevel_handle_v1_app_id(const QString& app_id) {
132+
ApplicationPointer newApp(new Application(app_id));
133+
if (newApp->isValid()) {
134+
d->application = newApp;
135+
} else {
136+
d->application.clear();
137+
}
138+
139+
emit applicationChanged();
140+
emit iconChanged();
141+
}
142+
143+
void WaylandWindow::zwlr_foreign_toplevel_handle_v1_state(wl_array* state) {
144+
WaylandWindowPrivate::WindowStateFlags windowState = WaylandWindowPrivate::NoState;
145+
for (quint32* flag = static_cast<quint32*>(state->data); reinterpret_cast<char*>(flag) < (static_cast<char*>(state->data) + state->size); flag++) {
146+
if (*flag == ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED) {
147+
windowState |= WaylandWindowPrivate::Activated;
148+
}
149+
if (*flag == ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED) {
150+
windowState |= WaylandWindowPrivate::Maximised;
151+
}
152+
if (*flag == ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED) {
153+
windowState |= WaylandWindowPrivate::Minimised;
154+
}
155+
}
156+
157+
d->state = windowState;
158+
emit windowStateChanged();
159+
emit d->backend->activeWindowChanged();
160+
}
161+
162+
void WaylandWindow::zwlr_foreign_toplevel_handle_v1_closed() {
163+
d->backend->signalToplevelClosed(this->object());
164+
d->backend->activeWindowChanged();
165+
}
166+
167+
void WaylandWindow::close() {
168+
this->QtWayland::zwlr_foreign_toplevel_handle_v1::close();
201169
}

lib/Wm/wayland/waylandwindow.h

+11-2
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,16 @@
2222

2323
#include <QPointer>
2424
#include "Wm/desktopwmwindow.h"
25+
#include "qwayland-wlr-foreign-toplevel-management-unstable-v1.h"
2526

2627
struct zwlr_foreign_toplevel_handle_v1;
2728
struct WaylandWindowPrivate;
2829
struct WaylandWindowEventListener;
2930
class WaylandBackend;
30-
class WaylandWindow : public DesktopWmWindow {
31+
class WaylandWindow : public DesktopWmWindow, public QtWayland::zwlr_foreign_toplevel_handle_v1 {
3132
Q_OBJECT
3233
public:
33-
explicit WaylandWindow(zwlr_foreign_toplevel_handle_v1* handle, WaylandBackend* backend);
34+
explicit WaylandWindow(::zwlr_foreign_toplevel_handle_v1* handle, WaylandBackend* backend);
3435
~WaylandWindow();
3536

3637
bool isActive();
@@ -61,6 +62,14 @@ class WaylandWindow : public DesktopWmWindow {
6162
void activate();
6263
void close();
6364
void kill();
65+
66+
// zwlr_foreign_toplevel_handle_v1 interface
67+
protected:
68+
void zwlr_foreign_toplevel_handle_v1_title(const QString& title);
69+
void zwlr_foreign_toplevel_handle_v1_app_id(const QString& app_id);
70+
void zwlr_foreign_toplevel_handle_v1_state(wl_array* state);
71+
void zwlr_foreign_toplevel_handle_v1_closed();
72+
6473
};
6574
typedef QPointer<WaylandWindow> WaylandWindowPtr;
6675

0 commit comments

Comments
 (0)