Skip to content

Commit ff9fd78

Browse files
committed
wip ext-ws
1 parent 9b31823 commit ff9fd78

18 files changed

+779
-0
lines changed

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ add_subdirectory(window)
1111
add_subdirectory(io)
1212
add_subdirectory(widgets)
1313
add_subdirectory(ui)
14+
add_subdirectory(windowmanager)
1415

1516
if (CRASH_REPORTER)
1617
add_subdirectory(crash)

src/wayland/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ if (HYPRLAND)
113113
add_subdirectory(hyprland)
114114
endif()
115115

116+
add_subdirectory(windowmanager)
117+
116118
# widgets for qmenu
117119
target_link_libraries(quickshell-wayland PRIVATE
118120
Qt::Quick Qt::Widgets Qt::WaylandClient Qt::WaylandClientPrivate
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
qt_add_library(quickshell-wayland-windowsystem STATIC
2+
windowmanager.cpp
3+
workspace.cpp
4+
ext_workspace.cpp
5+
)
6+
7+
add_library(quickshell-wayland-windowsystem-init OBJECT init.cpp)
8+
target_link_libraries(quickshell-wayland-windowsystem-init PRIVATE Qt::Quick)
9+
10+
#wl_proto(wlp-ext-foreign-toplevel ext-foreign-toplevel-list-v1 "${WAYLAND_PROTOCOLS}/staging/ext-foreign-toplevel-list")
11+
wl_proto(wlp-ext-workspace ext-workspace-v1 "${WAYLAND_PROTOCOLS}/staging/ext-workspace")
12+
13+
target_link_libraries(quickshell-wayland-windowsystem PRIVATE
14+
Qt::WaylandClient Qt::WaylandClientPrivate wayland-client
15+
Qt::Quick # for pch? potentially, check w/ gcc
16+
17+
wlp-ext-foreign-toplevel wlp-ext-workspace
18+
)
19+
20+
target_link_libraries(quickshell PRIVATE quickshell-wayland-windowsystem quickshell-wayland-windowsystem-init)
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#include "ext_workspace.hpp"
2+
3+
#include <qloggingcategory.h>
4+
#include <qtmetamacros.h>
5+
#include <qtypes.h>
6+
7+
#include "qwayland-ext-workspace-v1.h"
8+
#include "wayland-ext-workspace-v1-client-protocol.h"
9+
10+
namespace qs::wayland::workspace {
11+
12+
Q_LOGGING_CATEGORY(logWorkspace, "quickshell.wm.wayland.workspace");
13+
14+
WorkspaceManager::WorkspaceManager(): QWaylandClientExtensionTemplate(1) { this->initialize(); }
15+
16+
WorkspaceManager* WorkspaceManager::instance() {
17+
static auto* instance = new WorkspaceManager();
18+
return instance;
19+
}
20+
21+
void WorkspaceManager::ext_workspace_manager_v1_workspace_group(
22+
::ext_workspace_group_handle_v1* workspaceGroup
23+
) {
24+
// todo
25+
}
26+
27+
void WorkspaceManager::ext_workspace_manager_v1_workspace(::ext_workspace_handle_v1* workspace) {
28+
auto* qws = new Workspace(workspace);
29+
qCDebug(logWorkspace) << "Created workspace" << qws;
30+
this->mWorkspaces.insert(workspace, qws);
31+
emit this->workspaceCreated(qws);
32+
};
33+
34+
void WorkspaceManager::destroyWorkspace(Workspace* workspace) {
35+
this->destroyedWorkspaces.append(workspace);
36+
emit this->workspaceDestroyed(workspace);
37+
}
38+
39+
void WorkspaceManager::ext_workspace_manager_v1_done() {
40+
qCDebug(logWorkspace) << "Workspace changes done";
41+
emit this->serverCommit();
42+
43+
for (auto* workspace: this->destroyedWorkspaces) delete workspace;
44+
this->destroyedWorkspaces.clear();
45+
}
46+
47+
void WorkspaceManager::ext_workspace_manager_v1_finished() {
48+
// todo
49+
}
50+
51+
WorkspaceGroup::~WorkspaceGroup() { this->destroy(); }
52+
void WorkspaceGroup::ext_workspace_group_handle_v1_removed() { delete this; }
53+
54+
Workspace::~Workspace() {
55+
if (this->isInitialized()) this->destroy();
56+
}
57+
58+
void Workspace::ext_workspace_handle_v1_id(const QString& id) {
59+
qCDebug(logWorkspace) << "Updated id for" << this << "to" << id;
60+
this->id = id;
61+
}
62+
63+
void Workspace::ext_workspace_handle_v1_name(const QString& name) {
64+
qCDebug(logWorkspace) << "Updated name for" << this << "to" << name;
65+
this->name = name;
66+
}
67+
68+
void Workspace::ext_workspace_handle_v1_coordinates(wl_array* coordinates) {
69+
this->coordinates.clear();
70+
71+
auto* data = static_cast<qint32*>(coordinates->data);
72+
auto size = static_cast<qsizetype>(coordinates->size / sizeof(qint32));
73+
74+
for (auto i = 0; i != size; ++i) {
75+
this->coordinates.append(data[i]); // NOLINT
76+
}
77+
78+
qCDebug(logWorkspace) << "Updated coordinates for" << this << "to" << this->coordinates;
79+
}
80+
81+
void Workspace::ext_workspace_handle_v1_state(quint32 state) {
82+
this->active = state & QtWayland::ext_workspace_handle_v1::state_active;
83+
this->urgent = state & QtWayland::ext_workspace_handle_v1::state_urgent;
84+
this->hidden = state & QtWayland::ext_workspace_handle_v1::state_hidden;
85+
86+
qCDebug(logWorkspace).nospace() << "Updated state for " << this << " to [active: " << this->active
87+
<< ", urgent: " << this->urgent << ", hidden: " << this->hidden
88+
<< ']';
89+
}
90+
91+
void Workspace::ext_workspace_handle_v1_capabilities(quint32 capabilities) {
92+
this->canActivate =
93+
capabilities & QtWayland::ext_workspace_handle_v1::workspace_capabilities_activate;
94+
this->canDeactivate =
95+
capabilities & QtWayland::ext_workspace_handle_v1::workspace_capabilities_deactivate;
96+
this->canRemove =
97+
capabilities & QtWayland::ext_workspace_handle_v1::workspace_capabilities_remove;
98+
this->canAssign =
99+
capabilities & QtWayland::ext_workspace_handle_v1::workspace_capabilities_assign;
100+
101+
qCDebug(logWorkspace).nospace() << "Updated capabilities for " << this
102+
<< " to [activate: " << this->canActivate
103+
<< ", deactivate: " << this->canDeactivate
104+
<< ", remove: " << this->canRemove
105+
<< ", assign: " << this->canAssign << ']';
106+
}
107+
108+
void Workspace::ext_workspace_handle_v1_removed() {
109+
qCDebug(logWorkspace) << "Destroyed workspace" << this;
110+
this->destroy();
111+
WorkspaceManager::instance()->destroyWorkspace(this);
112+
}
113+
114+
} // namespace qs::wayland::workspace
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#pragma once
2+
3+
#include <qcontainerfwd.h>
4+
#include <qlist.h>
5+
#include <qloggingcategory.h>
6+
#include <qscreen.h>
7+
#include <qscreen_platform.h>
8+
#include <qtclasshelpermacros.h>
9+
#include <qtmetamacros.h>
10+
#include <qtypes.h>
11+
#include <qwayland-ext-workspace-v1.h>
12+
#include <qwaylandclientextension.h>
13+
#include <wayland-ext-workspace-v1-client-protocol.h>
14+
15+
namespace qs::wayland::workspace {
16+
17+
Q_DECLARE_LOGGING_CATEGORY(logWorkspace);
18+
19+
class WorkspaceGroup;
20+
class Workspace;
21+
22+
class WorkspaceManager
23+
: public QWaylandClientExtensionTemplate<WorkspaceManager>
24+
, public QtWayland::ext_workspace_manager_v1 {
25+
Q_OBJECT;
26+
27+
public:
28+
static WorkspaceManager* instance();
29+
30+
[[nodiscard]] QList<Workspace*> workspaces() { return this->mWorkspaces.values(); }
31+
32+
signals:
33+
void serverCommit();
34+
void workspaceCreated(Workspace* workspace);
35+
void workspaceDestroyed(Workspace* workspace);
36+
37+
protected:
38+
void ext_workspace_manager_v1_workspace_group(::ext_workspace_group_handle_v1* workspaceGroup
39+
) override;
40+
void ext_workspace_manager_v1_workspace(::ext_workspace_handle_v1* workspace) override;
41+
void ext_workspace_manager_v1_done() override;
42+
void ext_workspace_manager_v1_finished() override;
43+
44+
private:
45+
WorkspaceManager();
46+
47+
void destroyWorkspace(Workspace* workspace);
48+
49+
QHash<::ext_workspace_group_handle_v1*, WorkspaceGroup*> mGroups;
50+
QHash<::ext_workspace_handle_v1*, Workspace*> mWorkspaces;
51+
QList<Workspace*> destroyedWorkspaces;
52+
53+
friend class WorkspaceGroup;
54+
friend class Workspace;
55+
};
56+
57+
class WorkspaceGroup: public QtWayland::ext_workspace_group_handle_v1 {
58+
public:
59+
WorkspaceGroup(::ext_workspace_group_handle_v1* handle)
60+
: QtWayland::ext_workspace_group_handle_v1(handle) {}
61+
~WorkspaceGroup() override;
62+
Q_DISABLE_COPY_MOVE(WorkspaceGroup);
63+
64+
protected:
65+
/*void ext_workspace_group_handle_v1_capabilities(uint32_t capabilities) override;
66+
void ext_workspace_group_handle_v1_output_enter(::wl_output* output) override;
67+
void ext_workspace_group_handle_v1_output_leave(::wl_output* output) override;
68+
void ext_workspace_group_handle_v1_workspace_enter(::ext_workspace_handle_v1* workspace) override;
69+
void ext_workspace_group_handle_v1_workspace_leave(::ext_workspace_handle_v1* workspace) override;*/
70+
void ext_workspace_group_handle_v1_removed() override;
71+
72+
private:
73+
QList<QScreen*> screens;
74+
QList<wl_output*> pendingScreens;
75+
};
76+
77+
class Workspace: public QtWayland::ext_workspace_handle_v1 {
78+
public:
79+
Workspace(::ext_workspace_handle_v1* handle): QtWayland::ext_workspace_handle_v1(handle) {}
80+
~Workspace() override;
81+
Q_DISABLE_COPY_MOVE(Workspace);
82+
83+
QString id;
84+
QString name;
85+
QList<qint32> coordinates;
86+
87+
bool active : 1 = false;
88+
bool urgent : 1 = false;
89+
bool hidden : 1 = false;
90+
91+
bool canActivate : 1 = false;
92+
bool canDeactivate : 1 = false;
93+
bool canRemove : 1 = false;
94+
bool canAssign : 1 = false;
95+
96+
protected:
97+
void ext_workspace_handle_v1_id(const QString& id) override;
98+
void ext_workspace_handle_v1_name(const QString& name) override;
99+
void ext_workspace_handle_v1_coordinates(wl_array* coordinates) override;
100+
void ext_workspace_handle_v1_state(uint32_t state) override;
101+
void ext_workspace_handle_v1_capabilities(uint32_t capabilities) override;
102+
void ext_workspace_handle_v1_removed() override;
103+
104+
private:
105+
//void enterGroup(WorkspaceGroup* group);
106+
//void leaveGroup(WorkspaceGroup* group);
107+
108+
friend class WorkspaceGroup;
109+
};
110+
111+
} // namespace qs::wayland::workspace

src/wayland/windowmanager/init.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <qguiapplication.h>
2+
3+
#include "../../core/plugin.hpp"
4+
5+
namespace qs::wm::wayland {
6+
void installWmProvider();
7+
}
8+
9+
namespace {
10+
11+
class WaylandWmPlugin: public QsEnginePlugin {
12+
QList<QString> dependencies() override { return {"window"}; }
13+
14+
bool applies() override { return QGuiApplication::platformName() == "wayland"; }
15+
16+
void init() override { qs::wm::wayland::installWmProvider(); }
17+
};
18+
19+
QS_REGISTER_PLUGIN(WaylandWmPlugin);
20+
21+
} // namespace
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include "windowmanager.hpp"
2+
3+
namespace qs::wm::wayland {
4+
5+
WaylandWindowManager* WaylandWindowManager::instance() {
6+
static auto* instance = new WaylandWindowManager();
7+
return instance;
8+
}
9+
10+
void installWmProvider() {
11+
qs::wm::WindowManager::setProvider([]() { return WaylandWindowManager::instance(); });
12+
}
13+
14+
} // namespace qs::wm::wayland
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#pragma once
2+
3+
#include <qtmetamacros.h>
4+
5+
#include "../../windowmanager/windowmanager.hpp"
6+
#include "workspace.hpp"
7+
8+
namespace qs::wm::wayland {
9+
10+
class WaylandWindowManager: public WindowManager {
11+
Q_OBJECT;
12+
13+
public:
14+
static WaylandWindowManager* instance();
15+
16+
[[nodiscard]] UntypedObjectModel* workspaces() const override {
17+
return &WorkspaceManager::instance()->mWorkspaces;
18+
}
19+
};
20+
21+
} // namespace qs::wm::wayland

0 commit comments

Comments
 (0)