[wayland] Drop wl-shell support
Summary: wl-shell is deprecated, and pretty much no one uses it. Reviewers: #kwin, davidedmundson Reviewed By: #kwin, davidedmundson Subscribers: davidedmundson, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D23562
This commit is contained in:
parent
d92d6e77ae
commit
7a5447bd17
4 changed files with 7 additions and 105 deletions
|
@ -41,7 +41,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <KWayland/Server/display.h>
|
#include <KWayland/Server/display.h>
|
||||||
#include <KWayland/Server/clientconnection.h>
|
#include <KWayland/Server/clientconnection.h>
|
||||||
#include <KWayland/Server/seat_interface.h>
|
#include <KWayland/Server/seat_interface.h>
|
||||||
#include <KWayland/Server/shell_interface.h>
|
|
||||||
#include <KWayland/Server/surface_interface.h>
|
#include <KWayland/Server/surface_interface.h>
|
||||||
#include <KWayland/Server/buffer_interface.h>
|
#include <KWayland/Server/buffer_interface.h>
|
||||||
#include <KWayland/Server/plasmashell_interface.h>
|
#include <KWayland/Server/plasmashell_interface.h>
|
||||||
|
@ -67,20 +66,8 @@ using namespace KWayland::Server;
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
ShellClient::ShellClient(ShellSurfaceInterface *surface)
|
|
||||||
: AbstractClient()
|
|
||||||
, m_shellSurface(surface)
|
|
||||||
, m_xdgShellSurface(nullptr)
|
|
||||||
, m_xdgShellPopup(nullptr)
|
|
||||||
{
|
|
||||||
setSurface(surface->surface());
|
|
||||||
init();
|
|
||||||
m_isInitialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ShellClient::ShellClient(XdgShellSurfaceInterface *surface)
|
ShellClient::ShellClient(XdgShellSurfaceInterface *surface)
|
||||||
: AbstractClient()
|
: AbstractClient()
|
||||||
, m_shellSurface(nullptr)
|
|
||||||
, m_xdgShellSurface(surface)
|
, m_xdgShellSurface(surface)
|
||||||
, m_xdgShellPopup(nullptr)
|
, m_xdgShellPopup(nullptr)
|
||||||
{
|
{
|
||||||
|
@ -92,7 +79,6 @@ ShellClient::ShellClient(XdgShellSurfaceInterface *surface)
|
||||||
|
|
||||||
ShellClient::ShellClient(XdgShellPopupInterface *surface)
|
ShellClient::ShellClient(XdgShellPopupInterface *surface)
|
||||||
: AbstractClient()
|
: AbstractClient()
|
||||||
, m_shellSurface(nullptr)
|
|
||||||
, m_xdgShellSurface(nullptr)
|
, m_xdgShellSurface(nullptr)
|
||||||
, m_xdgShellPopup(surface)
|
, m_xdgShellPopup(surface)
|
||||||
{
|
{
|
||||||
|
@ -186,11 +172,6 @@ void ShellClient::initSurface(T *shellSurface)
|
||||||
);
|
);
|
||||||
connect(shellSurface, &T::maximizedChanged, this,
|
connect(shellSurface, &T::maximizedChanged, this,
|
||||||
[this] (bool maximized) {
|
[this] (bool maximized) {
|
||||||
if (m_shellSurface && isFullScreen()) {
|
|
||||||
// ignore for wl_shell - there it is mutual exclusive and messes with the geometry
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the maximized state of the client hasn't been changed due to a window
|
// If the maximized state of the client hasn't been changed due to a window
|
||||||
// rule or because the requested state is the same as the current, then the
|
// rule or because the requested state is the same as the current, then the
|
||||||
// compositor still has to send a configure event.
|
// compositor still has to send a configure event.
|
||||||
|
@ -216,16 +197,7 @@ void ShellClient::init()
|
||||||
updateIcon();
|
updateIcon();
|
||||||
SurfaceInterface *s = surface();
|
SurfaceInterface *s = surface();
|
||||||
Q_ASSERT(s);
|
Q_ASSERT(s);
|
||||||
if (s->buffer()) {
|
ready_for_painting = false;
|
||||||
setReadyForPainting();
|
|
||||||
if (shouldExposeToWindowManagement()) {
|
|
||||||
setupWindowManagementInterface();
|
|
||||||
}
|
|
||||||
m_unmapped = false;
|
|
||||||
m_clientSize = s->size();
|
|
||||||
} else {
|
|
||||||
ready_for_painting = false;
|
|
||||||
}
|
|
||||||
doSetGeometry(QRect(QPoint(0, 0), m_clientSize));
|
doSetGeometry(QRect(QPoint(0, 0), m_clientSize));
|
||||||
if (waylandServer()->inputMethodConnection() == s->client()) {
|
if (waylandServer()->inputMethodConnection() == s->client()) {
|
||||||
m_windowType = NET::OnScreenDisplay;
|
m_windowType = NET::OnScreenDisplay;
|
||||||
|
@ -240,15 +212,7 @@ void ShellClient::init()
|
||||||
connect(s, &SurfaceInterface::unmapped, this, &ShellClient::unmap);
|
connect(s, &SurfaceInterface::unmapped, this, &ShellClient::unmap);
|
||||||
connect(s, &SurfaceInterface::unbound, this, &ShellClient::destroyClient);
|
connect(s, &SurfaceInterface::unbound, this, &ShellClient::destroyClient);
|
||||||
connect(s, &SurfaceInterface::destroyed, this, &ShellClient::destroyClient);
|
connect(s, &SurfaceInterface::destroyed, this, &ShellClient::destroyClient);
|
||||||
if (m_shellSurface) {
|
if (m_xdgShellSurface) {
|
||||||
initSurface(m_shellSurface);
|
|
||||||
auto setPopup = [this] {
|
|
||||||
// TODO: verify grab serial
|
|
||||||
m_hasPopupGrab = m_shellSurface->isPopup();
|
|
||||||
};
|
|
||||||
connect(m_shellSurface, &ShellSurfaceInterface::popupChanged, this, setPopup);
|
|
||||||
setPopup();
|
|
||||||
} else if (m_xdgShellSurface) {
|
|
||||||
initSurface(m_xdgShellSurface);
|
initSurface(m_xdgShellSurface);
|
||||||
|
|
||||||
auto global = static_cast<XdgShellInterface *>(m_xdgShellSurface->global());
|
auto global = static_cast<XdgShellInterface *>(m_xdgShellSurface->global());
|
||||||
|
@ -447,7 +411,6 @@ void ShellClient::destroyClient()
|
||||||
|
|
||||||
deleted->unrefWindow();
|
deleted->unrefWindow();
|
||||||
|
|
||||||
m_shellSurface = nullptr;
|
|
||||||
m_xdgShellSurface = nullptr;
|
m_xdgShellSurface = nullptr;
|
||||||
m_xdgShellPopup = nullptr;
|
m_xdgShellPopup = nullptr;
|
||||||
deleteClient(this);
|
deleteClient(this);
|
||||||
|
@ -666,7 +629,7 @@ void ShellClient::setGeometry(int x, int y, int w, int h, ForceGeometry_t force)
|
||||||
const QSize requestedClientSize = newGeometry.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom());
|
const QSize requestedClientSize = newGeometry.size() - QSize(borderLeft() + borderRight(), borderTop() + borderBottom());
|
||||||
const QSize requestedWindowGeometrySize = toWindowGeometry(newGeometry.size());
|
const QSize requestedWindowGeometrySize = toWindowGeometry(newGeometry.size());
|
||||||
|
|
||||||
if (requestedClientSize == m_clientSize && !isWaitingForMoveResizeSync() &&
|
if (requestedClientSize == m_clientSize &&
|
||||||
(m_requestedClientSize.isEmpty() || requestedWindowGeometrySize == m_requestedClientSize)) {
|
(m_requestedClientSize.isEmpty() || requestedWindowGeometrySize == m_requestedClientSize)) {
|
||||||
// size didn't change, and we don't need to explicitly request a new size
|
// size didn't change, and we don't need to explicitly request a new size
|
||||||
doSetGeometry(newGeometry);
|
doSetGeometry(newGeometry);
|
||||||
|
@ -1013,13 +976,7 @@ void ShellClient::setFullScreen(bool set, bool user)
|
||||||
if (wasFullscreen) {
|
if (wasFullscreen) {
|
||||||
workspace()->updateFocusMousePosition(Cursor::pos()); // may cause leave event
|
workspace()->updateFocusMousePosition(Cursor::pos()); // may cause leave event
|
||||||
} else {
|
} else {
|
||||||
// in shell surface, maximise mode and fullscreen are exclusive
|
m_geomFsRestore = geometry();
|
||||||
// fullscreen->toplevel should restore the state we had before maximising
|
|
||||||
if (m_shellSurface && m_maximizeMode == MaximizeMode::MaximizeFull) {
|
|
||||||
m_geomFsRestore = m_geomMaximizeRestore;
|
|
||||||
} else {
|
|
||||||
m_geomFsRestore = geometry();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
m_fullScreen = set;
|
m_fullScreen = set;
|
||||||
|
|
||||||
|
@ -1140,12 +1097,6 @@ bool ShellClient::acceptsFocus() const
|
||||||
// an unmapped window does not accept focus
|
// an unmapped window does not accept focus
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (m_shellSurface) {
|
|
||||||
if (m_shellSurface->isPopup()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return m_shellSurface->acceptsKeyboardFocus();
|
|
||||||
}
|
|
||||||
if (m_xdgShellSurface) {
|
if (m_xdgShellSurface) {
|
||||||
// TODO: proper
|
// TODO: proper
|
||||||
return true;
|
return true;
|
||||||
|
@ -1190,9 +1141,6 @@ void ShellClient::requestGeometry(const QRect &rect)
|
||||||
|
|
||||||
quint64 serialId = 0;
|
quint64 serialId = 0;
|
||||||
|
|
||||||
if (m_shellSurface && !size.isEmpty()) {
|
|
||||||
m_shellSurface->requestSize(size);
|
|
||||||
}
|
|
||||||
if (m_xdgShellSurface) {
|
if (m_xdgShellSurface) {
|
||||||
serialId = m_xdgShellSurface->configure(xdgSurfaceStates(), size);
|
serialId = m_xdgShellSurface->configure(xdgSurfaceStates(), size);
|
||||||
}
|
}
|
||||||
|
@ -1257,9 +1205,6 @@ void ShellClient::resizeWithChecks(int w, int h, ForceGeometry_t force)
|
||||||
if (h > area.height()) {
|
if (h > area.height()) {
|
||||||
h = area.height();
|
h = area.height();
|
||||||
}
|
}
|
||||||
if (m_shellSurface) {
|
|
||||||
m_shellSurface->requestSize(QSize(w, h));
|
|
||||||
}
|
|
||||||
if (m_xdgShellSurface) {
|
if (m_xdgShellSurface) {
|
||||||
m_xdgShellSurface->configure(xdgSurfaceStates(), QSize(w, h));
|
m_xdgShellSurface->configure(xdgSurfaceStates(), QSize(w, h));
|
||||||
}
|
}
|
||||||
|
@ -1526,9 +1471,6 @@ bool ShellClient::isTransient() const
|
||||||
void ShellClient::setTransient()
|
void ShellClient::setTransient()
|
||||||
{
|
{
|
||||||
SurfaceInterface *s = nullptr;
|
SurfaceInterface *s = nullptr;
|
||||||
if (m_shellSurface) {
|
|
||||||
s = m_shellSurface->transientFor().data();
|
|
||||||
}
|
|
||||||
if (m_xdgShellSurface) {
|
if (m_xdgShellSurface) {
|
||||||
if (auto transient = m_xdgShellSurface->transientFor().data()) {
|
if (auto transient = m_xdgShellSurface->transientFor().data()) {
|
||||||
s = transient->surface();
|
s = transient->surface();
|
||||||
|
@ -1555,8 +1497,7 @@ void ShellClient::setTransient()
|
||||||
|
|
||||||
bool ShellClient::hasTransientPlacementHint() const
|
bool ShellClient::hasTransientPlacementHint() const
|
||||||
{
|
{
|
||||||
return isTransient() && transientFor() != nullptr &&
|
return isTransient() && transientFor() && m_xdgShellPopup;
|
||||||
(m_shellSurface || m_xdgShellPopup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect ShellClient::transientPlacement(const QRect &bounds) const
|
QRect ShellClient::transientPlacement(const QRect &bounds) const
|
||||||
|
@ -1589,12 +1530,7 @@ QRect ShellClient::transientPlacement(const QRect &bounds) const
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (m_shellSurface) {
|
if (m_xdgShellPopup) {
|
||||||
anchorRect = QRect(m_shellSurface->transientOffset(), QSize(1,1));
|
|
||||||
anchorEdge = Qt::TopEdge | Qt::LeftEdge;
|
|
||||||
gravity = Qt::BottomEdge | Qt::RightEdge; //our single point represents the top left of the popup
|
|
||||||
constraintAdjustments = (PositionerConstraint::SlideX | PositionerConstraint::SlideY);
|
|
||||||
} else if (m_xdgShellPopup) {
|
|
||||||
anchorRect = m_xdgShellPopup->anchorRect();
|
anchorRect = m_xdgShellPopup->anchorRect();
|
||||||
anchorEdge = m_xdgShellPopup->anchorEdge();
|
anchorEdge = m_xdgShellPopup->anchorEdge();
|
||||||
gravity = m_xdgShellPopup->gravity();
|
gravity = m_xdgShellPopup->gravity();
|
||||||
|
@ -1736,14 +1672,6 @@ QPoint ShellClient::popupOffset(const QRect &anchorRect, const Qt::Edges anchorE
|
||||||
return anchorPoint + popupPosAdjust;
|
return anchorPoint + popupPosAdjust;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShellClient::isWaitingForMoveResizeSync() const
|
|
||||||
{
|
|
||||||
if (m_shellSurface) {
|
|
||||||
return !m_pendingConfigureRequests.isEmpty();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShellClient::doResizeSync()
|
void ShellClient::doResizeSync()
|
||||||
{
|
{
|
||||||
requestGeometry(moveResizeGeometry());
|
requestGeometry(moveResizeGeometry());
|
||||||
|
@ -1818,11 +1746,6 @@ bool ShellClient::shouldExposeToWindowManagement()
|
||||||
if (m_xdgShellPopup) {
|
if (m_xdgShellPopup) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (m_shellSurface) {
|
|
||||||
if (m_shellSurface->isTransient() && !m_shellSurface->acceptsKeyboardFocus()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1904,9 +1827,6 @@ bool ShellClient::hasPopupGrab() const
|
||||||
|
|
||||||
void ShellClient::popupDone()
|
void ShellClient::popupDone()
|
||||||
{
|
{
|
||||||
if (m_shellSurface) {
|
|
||||||
m_shellSurface->popupDone();
|
|
||||||
}
|
|
||||||
if (m_xdgShellPopup) {
|
if (m_xdgShellPopup) {
|
||||||
m_xdgShellPopup->popupDone();
|
m_xdgShellPopup->popupDone();
|
||||||
}
|
}
|
||||||
|
@ -1932,13 +1852,11 @@ void ShellClient::updateWindowMargins()
|
||||||
|
|
||||||
if (m_xdgShellSurface) {
|
if (m_xdgShellSurface) {
|
||||||
windowGeometry = m_xdgShellSurface->windowGeometry();
|
windowGeometry = m_xdgShellSurface->windowGeometry();
|
||||||
} else if (m_xdgShellPopup) {
|
} else {
|
||||||
windowGeometry = m_xdgShellPopup->windowGeometry();
|
windowGeometry = m_xdgShellPopup->windowGeometry();
|
||||||
if (!clientSize.isValid()) {
|
if (!clientSize.isValid()) {
|
||||||
clientSize = m_xdgShellPopup->initialSize();
|
clientSize = m_xdgShellPopup->initialSize();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (windowGeometry.isEmpty() ||
|
if (windowGeometry.isEmpty() ||
|
||||||
|
@ -1958,9 +1876,6 @@ bool ShellClient::isPopupWindow() const
|
||||||
if (Toplevel::isPopupWindow()) {
|
if (Toplevel::isPopupWindow()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (m_shellSurface != nullptr) {
|
|
||||||
return m_shellSurface->isPopup();
|
|
||||||
}
|
|
||||||
if (m_xdgShellPopup != nullptr) {
|
if (m_xdgShellPopup != nullptr) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ namespace KWayland
|
||||||
{
|
{
|
||||||
namespace Server
|
namespace Server
|
||||||
{
|
{
|
||||||
class ShellSurfaceInterface;
|
|
||||||
class ServerSideDecorationInterface;
|
class ServerSideDecorationInterface;
|
||||||
class ServerSideDecorationPaletteInterface;
|
class ServerSideDecorationPaletteInterface;
|
||||||
class AppMenuInterface;
|
class AppMenuInterface;
|
||||||
|
@ -53,7 +52,6 @@ class KWIN_EXPORT ShellClient : public AbstractClient
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ShellClient(KWayland::Server::ShellSurfaceInterface *surface);
|
|
||||||
ShellClient(KWayland::Server::XdgShellSurfaceInterface *surface);
|
ShellClient(KWayland::Server::XdgShellSurfaceInterface *surface);
|
||||||
ShellClient(KWayland::Server::XdgShellPopupInterface *surface);
|
ShellClient(KWayland::Server::XdgShellPopupInterface *surface);
|
||||||
~ShellClient() override;
|
~ShellClient() override;
|
||||||
|
@ -171,7 +169,6 @@ protected:
|
||||||
m_geomMaximizeRestore = geo;
|
m_geomMaximizeRestore = geo;
|
||||||
}
|
}
|
||||||
void doResizeSync() override;
|
void doResizeSync() override;
|
||||||
bool isWaitingForMoveResizeSync() const override;
|
|
||||||
bool acceptsFocus() const override;
|
bool acceptsFocus() const override;
|
||||||
void doMinimize() override;
|
void doMinimize() override;
|
||||||
void updateCaption() override;
|
void updateCaption() override;
|
||||||
|
@ -213,7 +210,6 @@ private:
|
||||||
|
|
||||||
QSize toWindowGeometry(const QSize &geometry) const;
|
QSize toWindowGeometry(const QSize &geometry) const;
|
||||||
|
|
||||||
KWayland::Server::ShellSurfaceInterface *m_shellSurface;
|
|
||||||
KWayland::Server::XdgShellSurfaceInterface *m_xdgShellSurface;
|
KWayland::Server::XdgShellSurfaceInterface *m_xdgShellSurface;
|
||||||
KWayland::Server::XdgShellPopupInterface *m_xdgShellPopup;
|
KWayland::Server::XdgShellPopupInterface *m_xdgShellPopup;
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <KWayland/Server/shadow_interface.h>
|
#include <KWayland/Server/shadow_interface.h>
|
||||||
#include <KWayland/Server/subcompositor_interface.h>
|
#include <KWayland/Server/subcompositor_interface.h>
|
||||||
#include <KWayland/Server/blur_interface.h>
|
#include <KWayland/Server/blur_interface.h>
|
||||||
#include <KWayland/Server/shell_interface.h>
|
|
||||||
#include <KWayland/Server/outputmanagement_interface.h>
|
#include <KWayland/Server/outputmanagement_interface.h>
|
||||||
#include <KWayland/Server/outputconfiguration_interface.h>
|
#include <KWayland/Server/outputconfiguration_interface.h>
|
||||||
#include <KWayland/Server/xdgdecoration_interface.h>
|
#include <KWayland/Server/xdgdecoration_interface.h>
|
||||||
|
@ -312,9 +311,6 @@ bool WaylandServer::init(const QByteArray &socketName, InitalizationFlags flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
m_shell = m_display->createShell(m_display);
|
|
||||||
m_shell->create();
|
|
||||||
connect(m_shell, &ShellInterface::surfaceCreated, this, &WaylandServer::createSurface<ShellSurfaceInterface>);
|
|
||||||
|
|
||||||
m_xdgShell5 = m_display->createXdgShell(XdgShellInterfaceVersion::UnstableV5, m_display);
|
m_xdgShell5 = m_display->createXdgShell(XdgShellInterfaceVersion::UnstableV5, m_display);
|
||||||
m_xdgShell5->create();
|
m_xdgShell5->create();
|
||||||
|
|
|
@ -49,7 +49,6 @@ class CompositorInterface;
|
||||||
class Display;
|
class Display;
|
||||||
class DataDeviceInterface;
|
class DataDeviceInterface;
|
||||||
class IdleInterface;
|
class IdleInterface;
|
||||||
class ShellInterface;
|
|
||||||
class SeatInterface;
|
class SeatInterface;
|
||||||
class DataDeviceManagerInterface;
|
class DataDeviceManagerInterface;
|
||||||
class ServerSideDecorationManagerInterface;
|
class ServerSideDecorationManagerInterface;
|
||||||
|
@ -107,9 +106,6 @@ public:
|
||||||
KWayland::Server::DataDeviceManagerInterface *dataDeviceManager() {
|
KWayland::Server::DataDeviceManagerInterface *dataDeviceManager() {
|
||||||
return m_dataDeviceManager;
|
return m_dataDeviceManager;
|
||||||
}
|
}
|
||||||
KWayland::Server::ShellInterface *shell() {
|
|
||||||
return m_shell;
|
|
||||||
}
|
|
||||||
KWayland::Server::PlasmaVirtualDesktopManagementInterface *virtualDesktopManagement() {
|
KWayland::Server::PlasmaVirtualDesktopManagementInterface *virtualDesktopManagement() {
|
||||||
return m_virtualDesktopManagement;
|
return m_virtualDesktopManagement;
|
||||||
}
|
}
|
||||||
|
@ -238,7 +234,6 @@ private:
|
||||||
KWayland::Server::CompositorInterface *m_compositor = nullptr;
|
KWayland::Server::CompositorInterface *m_compositor = nullptr;
|
||||||
KWayland::Server::SeatInterface *m_seat = nullptr;
|
KWayland::Server::SeatInterface *m_seat = nullptr;
|
||||||
KWayland::Server::DataDeviceManagerInterface *m_dataDeviceManager = nullptr;
|
KWayland::Server::DataDeviceManagerInterface *m_dataDeviceManager = nullptr;
|
||||||
KWayland::Server::ShellInterface *m_shell = nullptr;
|
|
||||||
KWayland::Server::XdgShellInterface *m_xdgShell5 = nullptr;
|
KWayland::Server::XdgShellInterface *m_xdgShell5 = nullptr;
|
||||||
KWayland::Server::XdgShellInterface *m_xdgShell6 = nullptr;
|
KWayland::Server::XdgShellInterface *m_xdgShell6 = nullptr;
|
||||||
KWayland::Server::XdgShellInterface *m_xdgShell = nullptr;
|
KWayland::Server::XdgShellInterface *m_xdgShell = nullptr;
|
||||||
|
|
Loading…
Reference in a new issue