Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 48 additions & 2 deletions src/treeland/StackToplevelHelper.qml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Item {
required property ListModel dockModel
required property DynamicCreatorComponent creator
property WindowDecoration decoration
property var quickForeignToplevelManageMapper: waylandSurface.TreeLandForeignToplevelManagerV1

property OutputItem output
property CoordMapper outputCoordMapper
Expand Down Expand Up @@ -102,6 +103,51 @@ Item {
}
}

Connections {
target: quickForeignToplevelManageMapper

function onRequestMaximize(maximized) {
if (maximized) {
connOfSurface.onRequestCancelMaximize()
} else {
connOfSurface.onRequestMaximize()
}
}

function onRequestMinimize(minimized) {
if (minimized) {
connOfSurface.onRequestMinimize()
TreeLandHelper.activatedSurface = null
} else {
connOfSurface.onRequestCancelMinimize()
}
}

function onRequestActivate(activated) {
if (activated && waylandSurface.isMinimized) {
cancelMinimize()
}

surface.focus = activated
TreeLandHelper.activatedSurface = activated ? surface : null
}

function onRequestFullscreen(fullscreen) {
// TODO: add full screen action
}

function onRequestClose() {
if (waylandSurface.close)
waylandSurface.close()
else
waylandSurface.surface.unmap()
}

function onRectangleChanged(edges) {
connOfSurface.onRequestResize(null, edges, null)
}
}

Connections {
target: decoration

Expand Down Expand Up @@ -305,8 +351,8 @@ Item {
return

surface.focus = false;
if (TreeLandHelper.activeSurface === surface)
TreeLandHelper.activeSurface = null;
if (TreeLandHelper.activatedSurface === surface)
TreeLandHelper.activatedSurface = null;

surface.visible = false;
dockModel.append({ source: surface });
Expand Down
109 changes: 90 additions & 19 deletions src/treeland/foreigntoplevelmanagerv1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,57 @@ extern "C" {
#undef static
}

static QuickForeignToplevelManagerV1 *FOREIGN_TOPLEVEL_MANAGER = nullptr;

QuickForeignToplevelManagerAttached::QuickForeignToplevelManagerAttached(WSurface *target, QuickForeignToplevelManagerV1 *manager)
: QObject(manager)
, m_target(target)
, m_manager(manager)
{
connect(manager, &QuickForeignToplevelManagerV1::requestActivate, this, [this](WXdgSurface *surface, [[maybe_unused]] treeland_foreign_toplevel_handle_v1_activated_event *event) {
if (surface->surface() != m_target) {
return;
}

Q_EMIT requestActivate(true);
});
connect(manager, &QuickForeignToplevelManagerV1::requestMinimize, this, [this](WXdgSurface *surface, treeland_foreign_toplevel_handle_v1_minimized_event *event) {
if (surface->surface() != m_target) {
return;
}

Q_EMIT requestMinimize(event->minimized);
});
connect(manager, &QuickForeignToplevelManagerV1::requestMaximize, this, [this](WXdgSurface *surface, treeland_foreign_toplevel_handle_v1_maximized_event *event) {
if (surface->surface() != m_target) {
return;
}

Q_EMIT requestMaximize(event->maximized);
});
connect(manager, &QuickForeignToplevelManagerV1::requestFullscreen, this, [this](WXdgSurface *surface, treeland_foreign_toplevel_handle_v1_fullscreen_event *event) {
if (surface->surface() != m_target) {
return;
}

Q_EMIT requestFullscreen(event->fullscreen);
});
connect(manager, &QuickForeignToplevelManagerV1::requestClose, this, [this](WXdgSurface *surface) {
if (surface->surface() != m_target) {
return;
}

Q_EMIT requestClose();
});
connect(manager, &QuickForeignToplevelManagerV1::rectangleChanged, this, [this](WXdgSurface *surface, treeland_foreign_toplevel_handle_v1_set_rectangle_event *event) {
if (surface->surface() != m_target) {
return;
}

Q_EMIT rectangleChanged({event->x, event->y, event->width, event->height});
});
}

class QuickForeignToplevelManagerV1Private : public WObjectPrivate {
public:
QuickForeignToplevelManagerV1Private(QuickForeignToplevelManagerV1 *qq)
Expand All @@ -44,14 +95,14 @@ class QuickForeignToplevelManagerV1Private : public WObjectPrivate {
connection.push_back(QObject::connect(surface, &WXdgSurface::appIdChanged, q_func(),
[=] { handle->setAppId(surface->appId().toUtf8()); }));

connection.push_back(QObject::connect(surface, &WXdgSurface::requestMinimize, q_func(),
connection.push_back(QObject::connect(surface, &WXdgSurface::minimizeChanged, q_func(),
[=] { handle->setMinimized(surface->isMinimized()); }));

connection.push_back(QObject::connect(surface, &WXdgSurface::requestMaximize, q_func(),
connection.push_back(QObject::connect(surface, &WXdgSurface::maximizeChanged, q_func(),
[=] { handle->setMaximized(surface->isMaximized()); }));

connection.push_back(QObject::connect(
surface, &WXdgSurface::requestFullscreen, q_func(),
surface, &WXdgSurface::fullscreenChanged, q_func(),
[=] { handle->setFullScreen(surface->isFullScreen()); }));

connection.push_back(QObject::connect(surface, &WXdgSurface::activateChanged, q_func(),
Expand All @@ -78,37 +129,37 @@ class QuickForeignToplevelManagerV1Private : public WObjectPrivate {

connection.push_back(QObject::connect(handle.get(),
&TreeLandForeignToplevelHandleV1::requestActivate,
surface,
[surface](treeland_foreign_toplevel_handle_v1_activated_event *event) {
surface->setActivate(event->toplevel->state & TREELAND_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED);
q_func(),
[surface, this, handle](treeland_foreign_toplevel_handle_v1_activated_event *event) {
Q_EMIT q_func()->requestActivate(surface, event);
}));

connection.push_back(QObject::connect(handle.get(),
&TreeLandForeignToplevelHandleV1::requestMaximize,
surface,
[surface](treeland_foreign_toplevel_handle_v1_maximized_event *event) {
surface->setMaximize(event->maximized);
q_func(),
[surface, this](treeland_foreign_toplevel_handle_v1_maximized_event *event) {
Q_EMIT q_func()->requestMaximize(surface, event);
}));

connection.push_back(QObject::connect(handle.get(),
&TreeLandForeignToplevelHandleV1::requestMinimize,
surface,
[surface](treeland_foreign_toplevel_handle_v1_minimized_event *event) {
surface->setMinimize(event->minimized);
q_func(),
[surface, this, handle](treeland_foreign_toplevel_handle_v1_minimized_event *event) {
Q_EMIT q_func()->requestMinimize(surface, event);
}));

connection.push_back(QObject::connect(handle.get(),
&TreeLandForeignToplevelHandleV1::requestFullscreen,
surface,
[surface](treeland_foreign_toplevel_handle_v1_fullscreen_event *event) {
surface->setFullScreen(event->fullscreen);
q_func(),
[surface, this](treeland_foreign_toplevel_handle_v1_fullscreen_event *event) {
Q_EMIT q_func()->requestFullscreen(surface, event);
}));

connection.push_back(QObject::connect(handle.get(),
&TreeLandForeignToplevelHandleV1::requestClose,
surface,
[surface] {
surface->handle()->topToplevel()->sendClose();
q_func(),
[surface, this] {
Q_EMIT q_func()->requestClose(surface);
}));

wl_client *client = surface->handle()->handle()->resource->client;
Expand All @@ -120,6 +171,10 @@ class QuickForeignToplevelManagerV1Private : public WObjectPrivate {

Q_EMIT surface->titleChanged();
Q_EMIT surface->appIdChanged();
Q_EMIT surface->minimizeChanged();
Q_EMIT surface->maximizeChanged();
Q_EMIT surface->fullscreenChanged();
Q_EMIT surface->activateChanged();

connections.insert({surface, connection});
}
Expand Down Expand Up @@ -158,7 +213,14 @@ class QuickForeignToplevelManagerV1Private : public WObjectPrivate {

QuickForeignToplevelManagerV1::QuickForeignToplevelManagerV1(QObject *parent)
: WQuickWaylandServerInterface(parent)
, WObject(*new QuickForeignToplevelManagerV1Private(this), nullptr) {}
, WObject(*new QuickForeignToplevelManagerV1Private(this), nullptr)
{
if (FOREIGN_TOPLEVEL_MANAGER) {
qFatal("There are multiple instances of QuickForeignToplevelManagerV1");
}

FOREIGN_TOPLEVEL_MANAGER = this;
}

void QuickForeignToplevelManagerV1::add(WXdgSurface *surface) {
W_D(QuickForeignToplevelManagerV1);
Expand All @@ -176,3 +238,12 @@ void QuickForeignToplevelManagerV1::create() {

d->manager = TreeLandForeignToplevelManagerV1::create(server()->handle());
}

QuickForeignToplevelManagerAttached *QuickForeignToplevelManagerV1::qmlAttachedProperties(QObject *target)
{
if (auto *surface = qobject_cast<WXdgSurface*>(target)) {
return new QuickForeignToplevelManagerAttached(surface->surface(), FOREIGN_TOPLEVEL_MANAGER);
}

return nullptr;
}
45 changes: 45 additions & 0 deletions src/treeland/foreigntoplevelmanagerv1.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
#include <QObject>
#include <QQmlEngine>

struct treeland_foreign_toplevel_handle_v1_maximized_event;
struct treeland_foreign_toplevel_handle_v1_minimized_event;
struct treeland_foreign_toplevel_handle_v1_activated_event;
struct treeland_foreign_toplevel_handle_v1_fullscreen_event;
struct treeland_foreign_toplevel_handle_v1_set_rectangle_event;

QW_USE_NAMESPACE
WAYLIB_SERVER_USE_NAMESPACE

Expand Down Expand Up @@ -54,19 +60,58 @@ class WXdgSurface;
class WOutput;
WAYLIB_SERVER_END_NAMESPACE

class QuickForeignToplevelManagerV1;
class QuickForeignToplevelManagerAttached : public QObject
{
Q_OBJECT
QML_ANONYMOUS

public:
QuickForeignToplevelManagerAttached(WSurface *target, QuickForeignToplevelManagerV1 *manager);

Q_SIGNALS:
void requestMaximize(bool maximized);
void requestMinimize(bool minimized);
void requestActivate(bool activated);
void requestFullscreen(bool fullscreen);
void requestClose();
void rectangleChanged(const QRect &rect);

private:
WSurface *m_target;
QuickForeignToplevelManagerV1 *m_manager;
};

class QuickForeignToplevelManagerV1Private;
class QuickForeignToplevelManagerV1 : public WQuickWaylandServerInterface, public WObject
{
Q_OBJECT
QML_NAMED_ELEMENT(TreeLandForeignToplevelManagerV1)
W_DECLARE_PRIVATE(QuickForeignToplevelManagerV1)
QML_ATTACHED(QuickForeignToplevelManagerAttached)

public:
explicit QuickForeignToplevelManagerV1(QObject *parent = nullptr);

Q_INVOKABLE void add(WXdgSurface *surface);
Q_INVOKABLE void remove(WXdgSurface *surface);

static QuickForeignToplevelManagerAttached *qmlAttachedProperties(QObject *target);

Q_SIGNALS:
void requestMaximize(WXdgSurface *surface, treeland_foreign_toplevel_handle_v1_maximized_event *event);
void requestMinimize(WXdgSurface *surface, treeland_foreign_toplevel_handle_v1_minimized_event *event);
void requestActivate(WXdgSurface *surface, treeland_foreign_toplevel_handle_v1_activated_event *event);
void requestFullscreen(WXdgSurface *surface, treeland_foreign_toplevel_handle_v1_fullscreen_event *event);
void requestClose(WXdgSurface *surface);
void rectangleChanged(WXdgSurface *surface, treeland_foreign_toplevel_handle_v1_set_rectangle_event *event);

private:
void create() override;
};

Q_DECLARE_OPAQUE_POINTER(treeland_foreign_toplevel_handle_v1_maximized_event*);
Q_DECLARE_OPAQUE_POINTER(treeland_foreign_toplevel_handle_v1_minimized_event*);
Q_DECLARE_OPAQUE_POINTER(treeland_foreign_toplevel_handle_v1_activated_event*);
Q_DECLARE_OPAQUE_POINTER(treeland_foreign_toplevel_handle_v1_fullscreen_event*);
Q_DECLARE_OPAQUE_POINTER(treeland_foreign_toplevel_handle_v1_set_rectangle_event*);
5 changes: 3 additions & 2 deletions src/treeland/helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,11 +410,12 @@ WToplevelSurface *Helper::activatedSurface() const

void Helper::setActivateSurface(WToplevelSurface *newActivate)
{
if (newActivate && newActivate->doesNotAcceptFocus())
if (m_activateSurface == newActivate)
return;

if (m_activateSurface == newActivate)
if (newActivate && newActivate->doesNotAcceptFocus())
return;

if (m_activateSurface) {
if (newActivate) {
if (m_activateSurface->keyboardFocusPriority() > newActivate->keyboardFocusPriority())
Expand Down