Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Crash when window flashes #336

Merged
merged 5 commits into from
Jun 27, 2024
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
46 changes: 33 additions & 13 deletions src/modules/foreign-toplevel/foreigntoplevelmanagerv1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <qwxdgshell.h>

#include <QDebug>
#include <QFile>
#include <QRegularExpression>
#include <QTimer>

#include <sys/socket.h>
Expand All @@ -33,8 +35,7 @@

static ForeignToplevelV1 *FOREIGN_TOPLEVEL_MANAGER = nullptr;

ForeignToplevelAttached::ForeignToplevelAttached(WSurface *target,
ForeignToplevelV1 *manager)
ForeignToplevelAttached::ForeignToplevelAttached(WSurface *target, ForeignToplevelV1 *manager)
: QObject(target)
, m_target(target)
, m_manager(manager)
Expand Down Expand Up @@ -130,36 +131,53 @@
return m_manager->global;
}

void ForeignToplevelV1::add(WToplevelSurface *surface)

Check warning on line 134 in src/modules/foreign-toplevel/foreigntoplevelmanagerv1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'add' is never used.
{
/* TODO: dde-desktop and dde-launchpad are not supported yet */
wl_client *client = surface->surface()->handle()->handle()->resource->client;

Check warning on line 137 in src/modules/foreign-toplevel/foreigntoplevelmanagerv1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Local variable 'client' shadows outer variable
pid_t pid;

Check warning on line 138 in src/modules/foreign-toplevel/foreigntoplevelmanagerv1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Local variable 'pid' shadows outer variable
wl_client_get_credentials(client, &pid, nullptr, nullptr);

QString programName;
QFile file(QString("/proc/%1/status").arg(pid));
if (file.open(QFile::ReadOnly)) {
programName =
QString(file.readLine()).section(QRegularExpression("([\\t ]*:[\\t ]*|\\n)"), 1, 1);
}

if (programName == "dde-desktop" || programName == "dde-launchpad") {
return;
}
/* TODO: end */

auto handle = std::shared_ptr<treeland_foreign_toplevel_handle_v1>(
treeland_foreign_toplevel_handle_v1::create(m_manager));
m_surfaces.insert({ surface, handle });

// initSurface
std::vector<QMetaObject::Connection> connection;

connection.push_back(connect(surface, &WToplevelSurface::titleChanged, this, [=] {
connection.push_back(surface->safeConnect(&WToplevelSurface::titleChanged, this, [=] {
handle->set_title(surface->title());
}));

connection.push_back(connect(surface, &WToplevelSurface::appIdChanged, this, [=] {
connection.push_back(surface->safeConnect(&WToplevelSurface::appIdChanged, this, [=] {
handle->set_app_id(surface->appId());
}));

connection.push_back(connect(surface, &WToplevelSurface::minimizeChanged, this, [=] {
connection.push_back(surface->safeConnect(&WToplevelSurface::minimizeChanged, this, [=] {
handle->set_minimized(surface->isMinimized());
}));

connection.push_back(connect(surface, &WToplevelSurface::maximizeChanged, this, [=] {
connection.push_back(surface->safeConnect(&WToplevelSurface::maximizeChanged, this, [=] {
handle->set_maximized(surface->isMaximized());
}));

connection.push_back(connect(surface, &WToplevelSurface::fullscreenChanged, this, [=] {
connection.push_back(surface->safeConnect(&WToplevelSurface::fullscreenChanged, this, [=] {
handle->set_fullscreen(surface->isFullScreen());
}));

connection.push_back(connect(surface, &WToplevelSurface::activateChanged, this, [=] {
connection.push_back(surface->safeConnect(&WToplevelSurface::activateChanged, this, [=] {
handle->set_activated(surface->isActivated());
}));

Expand Down Expand Up @@ -247,6 +265,10 @@

void ForeignToplevelV1::remove(WToplevelSurface *surface)
{
if (!m_surfaces.count(surface)) {
return;
}

for (auto co : m_connections[surface]) {
QObject::disconnect(co);
}
Expand Down Expand Up @@ -311,16 +333,14 @@
&ForeignToplevelV1::requestDockClose);
}

ForeignToplevelAttached *ForeignToplevelV1::qmlAttachedProperties(QObject *target)
ForeignToplevelAttached *ForeignToplevelV1::Attached(QObject *target)

Check warning on line 336 in src/modules/foreign-toplevel/foreigntoplevelmanagerv1.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'Attached' is never used.
{
if (auto *surface = qobject_cast<WXdgSurface *>(target)) {
return new ForeignToplevelAttached(surface->surface(),
FOREIGN_TOPLEVEL_MANAGER);
return new ForeignToplevelAttached(surface->surface(), FOREIGN_TOPLEVEL_MANAGER);
}

if (auto *surface = qobject_cast<WXWaylandSurface *>(target)) {
return new ForeignToplevelAttached(surface->surface(),
FOREIGN_TOPLEVEL_MANAGER);
return new ForeignToplevelAttached(surface->surface(), FOREIGN_TOPLEVEL_MANAGER);
}

return nullptr;
Expand Down
3 changes: 1 addition & 2 deletions src/modules/foreign-toplevel/foreigntoplevelmanagerv1.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ class ForeignToplevelAttached : public QObject
class ForeignToplevelV1 : public QObject, public WServerInterface
{
Q_OBJECT
QML_ATTACHED(ForeignToplevelAttached)

public:
explicit ForeignToplevelV1(QObject *parent = nullptr);
Expand All @@ -50,7 +49,7 @@ class ForeignToplevelV1 : public QObject, public WServerInterface
Q_INVOKABLE void enterDockPreview(WSurface *relative_surface);
Q_INVOKABLE void leaveDockPreview(WSurface *relative_surface);

static ForeignToplevelAttached *qmlAttachedProperties(QObject *target);
Q_INVOKABLE ForeignToplevelAttached *Attached(QObject *target);

Q_SIGNALS:
void requestMaximize(WToplevelSurface *surface,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ struct treeland_foreign_toplevel_handle_v1 : public QObject
uint32_t identifier;
pid_t pid;

treeland_foreign_toplevel_handle_v1 *parent;
treeland_foreign_toplevel_handle_v1 *parent{ nullptr };
QList<treeland_foreign_toplevel_handle_v1_output>
outputs; // treeland_foreign_toplevel_v1_output.link
uint32_t state; // enum treeland_foreign_toplevel_v1_state
Expand Down
2 changes: 1 addition & 1 deletion src/modules/personalization/personalizationmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ QQuickItem *QuickPersonalizationManagerAttached::backgroundImage() const
return PERSONALIZATION_IMAGE;
}

QuickPersonalizationManagerAttached *PersonalizationV1::qmlAttachedProperties(QObject *target)
QuickPersonalizationManagerAttached *PersonalizationV1::Attached(QObject *target)
{
if (auto *surface = qobject_cast<WXdgSurface *>(target)) {
return new QuickPersonalizationManagerAttached(surface->surface(), PERSONALIZATION_MANAGER);
Expand Down
3 changes: 1 addition & 2 deletions src/modules/personalization/personalizationmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ class QuickPersonalizationManagerAttached : public QObject
class PersonalizationV1 : public QObject, public WServerInterface
{
Q_OBJECT
QML_ATTACHED(QuickPersonalizationManagerAttached)

Q_PROPERTY(uid_t userId READ userId WRITE setUserId NOTIFY userIdChanged FINAL)
Q_PROPERTY(QString cursorTheme READ cursorTheme WRITE setCursorTheme NOTIFY cursorThemeChanged FINAL)
Expand All @@ -70,7 +69,7 @@ class PersonalizationV1 : public QObject, public WServerInterface
void onGetCursorTheme(personalization_cursor_context_v1 *context);
void onGetCursorSize(personalization_cursor_context_v1 *context);

static QuickPersonalizationManagerAttached *qmlAttachedProperties(QObject *target);
Q_INVOKABLE QuickPersonalizationManagerAttached *Attached(QObject *target);

uid_t userId();
void setUserId(uid_t uid);
Expand Down
4 changes: 3 additions & 1 deletion src/qml/DockPreview.qml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Item {

function close() {
visible = false;
filterModel.desiredSurfaces = []
stopped();
}

Expand Down Expand Up @@ -150,6 +151,7 @@ Item {
model: filterModel
delegate: Item {
required property Item item
required property var wrapper
property Item surfaceItem: item
width: 180
height: 180
Expand Down Expand Up @@ -191,7 +193,7 @@ Item {
MouseArea {
anchors.fill: parent
onClicked: {
surfaceActivated(surfaceItem);
surfaceActivated(wrapper);
exitedTimer.start();
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/qml/Main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Item {
Item {
id: outputLayout
// register backgroundImage
property var personalizationMapper: outputLayout.PersonalizationV1
property var personalizationMapper: PersonalizationV1.Attach(outputLayout)

DynamicCreatorComponent {
id: outputDelegateCreator
Expand Down
5 changes: 4 additions & 1 deletion src/qml/StackToplevelHelper.qml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Item {
required property DynamicCreatorComponent creator
required property SurfaceItemFactory surfaceWrapper
property WindowDecoration decoration
property var quickForeignToplevelManageMapper: waylandSurface.ForeignToplevelV1
property var quickForeignToplevelManageMapper: ForeignToplevelV1.Attached(waylandSurface)

property OutputItem output
property CoordMapper outputCoordMapper
Expand Down Expand Up @@ -238,6 +238,7 @@ Item {
WaylibHelper.itemStackToTop(surface)
if (surface.effectiveVisible) {
Helper.activatedSurface = waylandSurface
surface.focus = true;
}
}
}
Expand Down Expand Up @@ -316,6 +317,7 @@ Item {
waylandSurface.setMinimize(true)

if (Helper.activatedSurface === waylandSurface) {
Helper.activatedSurface = null
surface.parent.selectSurfaceToActivate()
}
}
Expand All @@ -335,6 +337,7 @@ Item {
Helper.activatedSurface = waylandSurface

surface.visible = true;
surface.focus = true;

waylandSurface.setMinimize(false)
}
Expand Down
6 changes: 3 additions & 3 deletions src/qml/StackWorkspace.qml
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ FocusScope {
}

Connections {
target: ForeignToplevel
target: ForeignToplevelV1
function onRequestDockPreview(surfaces, target, abs, direction) {
dockPreview.show(surfaces, getSurfaceItemFromWaylandSurface(target), abs, direction)
}
Expand All @@ -413,10 +413,10 @@ FocusScope {
anchors.fill: parent
visible: false
onEntered: (relativeSurface) => {
ForeignToplevel.enterDockPreview(relativeSurface)
ForeignToplevelV1.enterDockPreview(relativeSurface)
}
onExited: (relativeSurface) => {
ForeignToplevel.leaveDockPreview(relativeSurface)
ForeignToplevelV1.leaveDockPreview(relativeSurface)
}
onSurfaceActivated: (surfaceItem) => {
surfaceItem.cancelMinimize()
Expand Down
2 changes: 1 addition & 1 deletion src/qml/SurfaceWrapper.qml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ SurfaceItemFactory {

property var doDestroy: helper.doDestroy
property var cancelMinimize: helper.cancelMinimize
property var personalizationMapper: waylandSurface.PersonalizationV1
property var personalizationMapper: PersonalizationV1.Attach(waylandSurface)
property int outputCounter: 0
property alias toplevelSurfaceItem: root.surfaceItem
property alias decoration: decoration
Expand Down
2 changes: 1 addition & 1 deletion src/qml/ToplevelContainer.qml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ FocusScope {
}

function selectSurfaceToActivate() {
const nextIndex = surfacesModel.findIf( (data) => !data.item.shellSurface.isMinimized )
const nextIndex = surfacesModel.findIf( (data) => Helper.selectSurfaceToActivate(data.item.shellSurface))
if (nextIndex >= 0)
Helper.activatedSurface = surfacesModel.get(nextIndex).item.shellSurface
else Helper.activatedSurface = null
Expand Down
27 changes: 25 additions & 2 deletions src/utils/helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,7 @@ void Helper::initProtocols(WOutputRenderWindow *window)
Q_ARG(int, m_currentWorkspaceId));
auto wid = retValue.toQObject()->property("wsid");

qCDebug(HelperDebugLog)
<< "new xwayland surface, wid: " << wid;
qCDebug(HelperDebugLog) << "new xwayland surface, wid: " << wid;

initProperties.setProperty("workspaceId", engine->toScriptValue(wid));

Expand Down Expand Up @@ -616,6 +615,21 @@ std::pair<WOutput *, OutputInfo *> Helper::getFirstOutputOfSurface(WToplevelSurf
return std::make_pair(nullptr, nullptr);
}

bool Helper::selectSurfaceToActivate(WToplevelSurface *surface) const {
if (!surface) {
return false;
}

if (surface->isMinimized()) {
return false;
}

if (surface->doesNotAcceptFocus())
return false;

return true;
}

void Helper::setMovingItem(WSurfaceItem *newMovingItem)
{
if (moveReiszeState.movingItem == newMovingItem)
Expand Down Expand Up @@ -918,6 +932,15 @@ void Helper::setActivateSurface(WToplevelSurface *newActivate)
m_activateSurface->setActivate(false);
}
m_activateSurface = newActivate;

static QMetaObject::Connection invalidCheck;
disconnect(invalidCheck);
invalidCheck =
connect(newActivate, &WToplevelSurface::aboutToBeInvalidated, this, [newActivate, this] {
newActivate->setActivate(false);
setActivateSurface(nullptr);
});

if (newActivate)
newActivate->setActivate(true);
Q_EMIT activatedSurfaceChanged();
Expand Down
2 changes: 2 additions & 0 deletions src/utils/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ class Helper : public WSeatEventFilter
Q_INVOKABLE Margins getOutputExclusiveMargins(WOutput *output);
std::pair<WOutput *, OutputInfo *> getFirstOutputOfSurface(WToplevelSurface *surface);

Q_INVOKABLE bool selectSurfaceToActivate(WToplevelSurface *surface) const;

public Q_SLOTS:
void startMove(WToplevelSurface *surface, WSurfaceItem *shell, WSeat *seat, int serial);
void startResize(
Expand Down
Loading