Implement show on screen edge for Wayland
Summary: This change ports ScreenEdges to operate on AbstractClient instead of Client. For this AbstractClient gained a new pure virtual method showOnScreenEdge which is also implemented in ShellClient. In ShellClient the functionality is bound for the case windows can cover a panel. If triggered the panel gets raised again. The auto hiding panel, though, is not yet implemented. For that the protocol needs to be adjusted to give a hint to the compositor when to hide and hint back to the panel when it was shown. This needs a change in KWayland and thus is not 5.8 material. Test Plan: See added test case Reviewers: #kwin, #plasma_on_wayland Subscribers: plasma-devel, kwin Tags: #plasma_on_wayland, #kwin Differential Revision: https://phabricator.kde.org/D2793
This commit is contained in:
parent
73dd1b9e46
commit
dd3c6d6cc2
9 changed files with 200 additions and 22 deletions
|
@ -580,6 +580,13 @@ public:
|
||||||
|
|
||||||
QRect inputGeometry() const override;
|
QRect inputGeometry() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the AbstractClient after it had been hidden due to show on screen edge functionality.
|
||||||
|
* The AbstractClient also gets raised (e.g. Panel mode windows can cover) and the AbstractClient
|
||||||
|
* gets informed in a window specific way that it is shown and raised again.
|
||||||
|
**/
|
||||||
|
virtual void showOnScreenEdge() = 0;
|
||||||
|
|
||||||
// TODO: remove boolean trap
|
// TODO: remove boolean trap
|
||||||
static bool belongToSameApplication(const AbstractClient* c1, const AbstractClient* c2, bool active_hack = false);
|
static bool belongToSameApplication(const AbstractClient* c1, const AbstractClient* c2, bool active_hack = false);
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#include "kwin_wayland_test.h"
|
#include "kwin_wayland_test.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "cursor.h"
|
||||||
#include "shell_client.h"
|
#include "shell_client.h"
|
||||||
#include "screens.h"
|
#include "screens.h"
|
||||||
#include "wayland_server.h"
|
#include "wayland_server.h"
|
||||||
|
@ -53,6 +54,8 @@ private Q_SLOTS:
|
||||||
void testAcceptsFocus();
|
void testAcceptsFocus();
|
||||||
|
|
||||||
void testDesktopIsOpaque();
|
void testDesktopIsOpaque();
|
||||||
|
void testPanelWindowsCanCover_data();
|
||||||
|
void testPanelWindowsCanCover();
|
||||||
void testOSDPlacement();
|
void testOSDPlacement();
|
||||||
void testPanelTypeHasStrut_data();
|
void testPanelTypeHasStrut_data();
|
||||||
void testPanelTypeHasStrut();
|
void testPanelTypeHasStrut();
|
||||||
|
@ -81,6 +84,8 @@ void PlasmaSurfaceTest::init()
|
||||||
m_compositor = Test::waylandCompositor();
|
m_compositor = Test::waylandCompositor();
|
||||||
m_shell = Test::waylandShell();
|
m_shell = Test::waylandShell();
|
||||||
m_plasmaShell = Test::waylandPlasmaShell();
|
m_plasmaShell = Test::waylandPlasmaShell();
|
||||||
|
|
||||||
|
KWin::Cursor::setPos(640, 512);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlasmaSurfaceTest::cleanup()
|
void PlasmaSurfaceTest::cleanup()
|
||||||
|
@ -283,5 +288,85 @@ void PlasmaSurfaceTest::testPanelTypeHasStrut()
|
||||||
QTEST(c->layer(), "expectedLayer");
|
QTEST(c->layer(), "expectedLayer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlasmaSurfaceTest::testPanelWindowsCanCover_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QRect>("panelGeometry");
|
||||||
|
QTest::addColumn<QRect>("windowGeometry");
|
||||||
|
QTest::addColumn<QPoint>("triggerPoint");
|
||||||
|
|
||||||
|
QTest::newRow("top-full-edge") << QRect(0, 0, 1280, 30) << QRect(0, 0, 200, 300) << QPoint(100, 0);
|
||||||
|
QTest::newRow("top-left-edge") << QRect(0, 0, 1000, 30) << QRect(0, 0, 200, 300) << QPoint(100, 0);
|
||||||
|
QTest::newRow("top-right-edge") << QRect(280, 0, 1000, 30) << QRect(1000, 0, 200, 300) << QPoint(1000, 0);
|
||||||
|
QTest::newRow("bottom-full-edge") << QRect(0, 994, 1280, 30) << QRect(0, 724, 200, 300) << QPoint(100, 1023);
|
||||||
|
QTest::newRow("bottom-left-edge") << QRect(0, 994, 1000, 30) << QRect(0, 724, 200, 300) << QPoint(100, 1023);
|
||||||
|
QTest::newRow("bottom-right-edge") << QRect(280, 994, 1000, 30) << QRect(1000, 724, 200, 300) << QPoint(1000, 1023);
|
||||||
|
QTest::newRow("left-full-edge") << QRect(0, 0, 30, 1024) << QRect(0, 0, 200, 300) << QPoint(0, 100);
|
||||||
|
QTest::newRow("left-top-edge") << QRect(0, 0, 30, 800) << QRect(0, 0, 200, 300) << QPoint(0, 100);
|
||||||
|
QTest::newRow("left-bottom-edge") << QRect(0, 200, 30, 824) << QRect(0, 0, 200, 300) << QPoint(0, 250);
|
||||||
|
QTest::newRow("right-full-edge") << QRect(1250, 0, 30, 1024) << QRect(1080, 0, 200, 300) << QPoint(1279, 100);
|
||||||
|
QTest::newRow("right-top-edge") << QRect(1250, 0, 30, 800) << QRect(1080, 0, 200, 300) << QPoint(1279, 100);
|
||||||
|
QTest::newRow("right-bottom-edge") << QRect(1250, 200, 30, 824) << QRect(1080, 0, 200, 300) << QPoint(1279, 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlasmaSurfaceTest::testPanelWindowsCanCover()
|
||||||
|
{
|
||||||
|
// this test verifies the behavior of a panel with windows can cover
|
||||||
|
// triggering the screen edge should raise the panel.
|
||||||
|
QScopedPointer<Surface> surface(Test::createSurface());
|
||||||
|
QVERIFY(!surface.isNull());
|
||||||
|
QScopedPointer<QObject> shellSurface(Test::createShellSurface(Test::ShellSurfaceType::WlShell, surface.data()));
|
||||||
|
QVERIFY(!shellSurface.isNull());
|
||||||
|
QScopedPointer<PlasmaShellSurface> plasmaSurface(m_plasmaShell->createSurface(surface.data()));
|
||||||
|
QVERIFY(!plasmaSurface.isNull());
|
||||||
|
plasmaSurface->setRole(PlasmaShellSurface::Role::Panel);
|
||||||
|
QFETCH(QRect, panelGeometry);
|
||||||
|
plasmaSurface->setPosition(panelGeometry.topLeft());
|
||||||
|
plasmaSurface->setPanelBehavior(PlasmaShellSurface::PanelBehavior::WindowsCanCover);
|
||||||
|
|
||||||
|
|
||||||
|
// now render and map the window
|
||||||
|
auto panel = Test::renderAndWaitForShown(surface.data(), panelGeometry.size(), Qt::blue);
|
||||||
|
|
||||||
|
QVERIFY(panel);
|
||||||
|
QCOMPARE(panel->windowType(), NET::Dock);
|
||||||
|
QVERIFY(panel->isDock());
|
||||||
|
QCOMPARE(panel->geometry(), panelGeometry);
|
||||||
|
QCOMPARE(panel->hasStrut(), false);
|
||||||
|
QCOMPARE(workspace()->clientArea(MaximizeArea, 0, 0), QRect(0, 0, 1280, 1024));
|
||||||
|
QCOMPARE(panel->layer(), KWin::NormalLayer);
|
||||||
|
|
||||||
|
// create a Window
|
||||||
|
QScopedPointer<Surface> surface2(Test::createSurface());
|
||||||
|
QVERIFY(!surface2.isNull());
|
||||||
|
QScopedPointer<QObject> shellSurface2(Test::createShellSurface(Test::ShellSurfaceType::WlShell, surface2.data()));
|
||||||
|
QVERIFY(!shellSurface2.isNull());
|
||||||
|
|
||||||
|
QFETCH(QRect, windowGeometry);
|
||||||
|
auto c = Test::renderAndWaitForShown(surface2.data(), windowGeometry.size(), Qt::red);
|
||||||
|
|
||||||
|
QVERIFY(c);
|
||||||
|
QCOMPARE(c->windowType(), NET::Normal);
|
||||||
|
QVERIFY(c->isActive());
|
||||||
|
QCOMPARE(c->layer(), KWin::NormalLayer);
|
||||||
|
c->move(windowGeometry.topLeft());
|
||||||
|
QCOMPARE(c->geometry(), windowGeometry);
|
||||||
|
|
||||||
|
auto stackingOrder = workspace()->stackingOrder();
|
||||||
|
QCOMPARE(stackingOrder.count(), 2);
|
||||||
|
QCOMPARE(stackingOrder.first(), panel);
|
||||||
|
QCOMPARE(stackingOrder.last(), c);
|
||||||
|
|
||||||
|
QSignalSpy stackingOrderChangedSpy(workspace(), &Workspace::stackingOrderChanged);
|
||||||
|
QVERIFY(stackingOrderChangedSpy.isValid());
|
||||||
|
// trigger screenedge
|
||||||
|
QFETCH(QPoint, triggerPoint);
|
||||||
|
KWin::Cursor::setPos(triggerPoint);
|
||||||
|
QCOMPARE(stackingOrderChangedSpy.count(), 1);
|
||||||
|
stackingOrder = workspace()->stackingOrder();
|
||||||
|
QCOMPARE(stackingOrder.count(), 2);
|
||||||
|
QCOMPARE(stackingOrder.first(), c);
|
||||||
|
QCOMPARE(stackingOrder.last(), panel);
|
||||||
|
}
|
||||||
|
|
||||||
WAYLANDTEST_MAIN(PlasmaSurfaceTest)
|
WAYLANDTEST_MAIN(PlasmaSurfaceTest)
|
||||||
#include "plasma_surface_test.moc"
|
#include "plasma_surface_test.moc"
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
void setHiddenInternal(bool set);
|
void setHiddenInternal(bool set);
|
||||||
void setGeometry(const QRect &rect);
|
void setGeometry(const QRect &rect);
|
||||||
void setKeepBelow(bool);
|
void setKeepBelow(bool);
|
||||||
|
virtual void showOnScreenEdge() = 0;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void geometryChanged();
|
void geometryChanged();
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
virtual ~Client();
|
virtual ~Client();
|
||||||
|
|
||||||
bool isResize() const;
|
bool isResize() const;
|
||||||
void showOnScreenEdge();
|
void showOnScreenEdge() override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
2
client.h
2
client.h
|
@ -329,7 +329,7 @@ public:
|
||||||
* Restores the Client after it had been hidden due to show on screen edge functionality.
|
* Restores the Client after it had been hidden due to show on screen edge functionality.
|
||||||
* In addition the property gets deleted so that the Client knows that it is visible again.
|
* In addition the property gets deleted so that the Client knows that it is visible again.
|
||||||
**/
|
**/
|
||||||
void showOnScreenEdge();
|
void showOnScreenEdge() override;
|
||||||
|
|
||||||
static void cleanupX11();
|
static void cleanupX11();
|
||||||
|
|
||||||
|
|
|
@ -555,13 +555,7 @@ ScreenEdges::ScreenEdges(QObject *parent)
|
||||||
QWidget w;
|
QWidget w;
|
||||||
m_cornerOffset = (w.physicalDpiX() + w.physicalDpiY() + 5) / 6;
|
m_cornerOffset = (w.physicalDpiX() + w.physicalDpiY() + 5) / 6;
|
||||||
|
|
||||||
connect(workspace(), &Workspace::clientRemoved, this, [this](KWin::AbstractClient *c) {
|
connect(workspace(), &Workspace::clientRemoved, this, &ScreenEdges::deleteEdgeForClient);
|
||||||
Client *client = qobject_cast<Client*>(c);
|
|
||||||
if (!client) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
deleteEdgeForClient(client);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenEdges::~ScreenEdges()
|
ScreenEdges::~ScreenEdges()
|
||||||
|
@ -985,7 +979,7 @@ void ScreenEdges::unreserve(ElectricBorder border, QObject *object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenEdges::reserve(Client *client, ElectricBorder border)
|
void ScreenEdges::reserve(AbstractClient *client, ElectricBorder border)
|
||||||
{
|
{
|
||||||
bool hadBorder = false;
|
bool hadBorder = false;
|
||||||
auto it = m_edges.begin();
|
auto it = m_edges.begin();
|
||||||
|
@ -1014,7 +1008,7 @@ void ScreenEdges::reserve(Client *client, ElectricBorder border)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenEdges::createEdgeForClient(Client *client, ElectricBorder border)
|
void ScreenEdges::createEdgeForClient(AbstractClient *client, ElectricBorder border)
|
||||||
{
|
{
|
||||||
int y = 0;
|
int y = 0;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
@ -1087,7 +1081,7 @@ void ScreenEdges::createEdgeForClient(Client *client, ElectricBorder border)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenEdges::deleteEdgeForClient(Client* c)
|
void ScreenEdges::deleteEdgeForClient(AbstractClient* c)
|
||||||
{
|
{
|
||||||
auto it = m_edges.begin();
|
auto it = m_edges.begin();
|
||||||
while (it != m_edges.end()) {
|
while (it != m_edges.end()) {
|
||||||
|
|
18
screenedge.h
18
screenedge.h
|
@ -43,7 +43,7 @@ class QMouseEvent;
|
||||||
|
|
||||||
namespace KWin {
|
namespace KWin {
|
||||||
|
|
||||||
class Client;
|
class AbstractClient;
|
||||||
class ScreenEdges;
|
class ScreenEdges;
|
||||||
|
|
||||||
class KWIN_EXPORT Edge : public QObject
|
class KWIN_EXPORT Edge : public QObject
|
||||||
|
@ -70,8 +70,8 @@ public:
|
||||||
void startApproaching();
|
void startApproaching();
|
||||||
void stopApproaching();
|
void stopApproaching();
|
||||||
bool isApproaching() const;
|
bool isApproaching() const;
|
||||||
void setClient(Client *client);
|
void setClient(AbstractClient *client);
|
||||||
Client *client() const;
|
AbstractClient *client() const;
|
||||||
const QRect &geometry() const;
|
const QRect &geometry() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,7 +129,7 @@ private:
|
||||||
int m_lastApproachingFactor;
|
int m_lastApproachingFactor;
|
||||||
bool m_blocked;
|
bool m_blocked;
|
||||||
bool m_pushBackBlocked;
|
bool m_pushBackBlocked;
|
||||||
Client *m_client;
|
AbstractClient *m_client;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -257,7 +257,7 @@ public:
|
||||||
* @param client The Client for which an Edge should be reserved
|
* @param client The Client for which an Edge should be reserved
|
||||||
* @param border The border which the client wants to use, only proper borders are supported (no corners)
|
* @param border The border which the client wants to use, only proper borders are supported (no corners)
|
||||||
**/
|
**/
|
||||||
void reserve(KWin::Client *client, ElectricBorder border);
|
void reserve(KWin::AbstractClient *client, ElectricBorder border);
|
||||||
/**
|
/**
|
||||||
* Reserve desktop switching for screen edges, if @p isToReserve is @c true. Unreserve otherwise.
|
* Reserve desktop switching for screen edges, if @p isToReserve is @c true. Unreserve otherwise.
|
||||||
* @param reserve indicated weather desktop switching should be reserved or unreseved
|
* @param reserve indicated weather desktop switching should be reserved or unreseved
|
||||||
|
@ -339,8 +339,8 @@ private:
|
||||||
ElectricBorderAction actionForEdge(Edge *edge) const;
|
ElectricBorderAction actionForEdge(Edge *edge) const;
|
||||||
bool handleEnterNotifiy(xcb_window_t window, const QPoint &point, const QDateTime ×tamp);
|
bool handleEnterNotifiy(xcb_window_t window, const QPoint &point, const QDateTime ×tamp);
|
||||||
bool handleDndNotify(xcb_window_t window, const QPoint &point);
|
bool handleDndNotify(xcb_window_t window, const QPoint &point);
|
||||||
void createEdgeForClient(Client *client, ElectricBorder border);
|
void createEdgeForClient(AbstractClient *client, ElectricBorder border);
|
||||||
void deleteEdgeForClient(Client *client);
|
void deleteEdgeForClient(AbstractClient *client);
|
||||||
bool m_desktopSwitching;
|
bool m_desktopSwitching;
|
||||||
bool m_desktopSwitchingMovingClients;
|
bool m_desktopSwitchingMovingClients;
|
||||||
QSize m_cursorPushBackDistance;
|
QSize m_cursorPushBackDistance;
|
||||||
|
@ -452,12 +452,12 @@ inline bool Edge::isBlocked() const
|
||||||
return m_blocked;
|
return m_blocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Edge::setClient(Client *client)
|
inline void Edge::setClient(AbstractClient *client)
|
||||||
{
|
{
|
||||||
m_client = client;
|
m_client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Client *Edge::client() const
|
inline AbstractClient *Edge::client() const
|
||||||
{
|
{
|
||||||
return m_client;
|
return m_client;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include "cursor.h"
|
#include "cursor.h"
|
||||||
#include "deleted.h"
|
#include "deleted.h"
|
||||||
#include "placement.h"
|
#include "placement.h"
|
||||||
|
#include "screenedge.h"
|
||||||
#include "screens.h"
|
#include "screens.h"
|
||||||
#include "wayland_server.h"
|
#include "wayland_server.h"
|
||||||
#include "workspace.h"
|
#include "workspace.h"
|
||||||
|
@ -407,6 +408,7 @@ void ShellClient::markAsMapped()
|
||||||
if (shouldExposeToWindowManagement()) {
|
if (shouldExposeToWindowManagement()) {
|
||||||
setupWindowManagementInterface();
|
setupWindowManagementInterface();
|
||||||
}
|
}
|
||||||
|
updateShowOnScreenEdge();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShellClient::createDecoration(const QRect &oldGeom)
|
void ShellClient::createDecoration(const QRect &oldGeom)
|
||||||
|
@ -1018,12 +1020,15 @@ void ShellClient::installPlasmaShellSurface(PlasmaShellSurfaceInterface *surface
|
||||||
connect(surface, &PlasmaShellSurfaceInterface::positionChanged, this, updatePosition);
|
connect(surface, &PlasmaShellSurfaceInterface::positionChanged, this, updatePosition);
|
||||||
connect(surface, &PlasmaShellSurfaceInterface::roleChanged, this, updateRole);
|
connect(surface, &PlasmaShellSurfaceInterface::roleChanged, this, updateRole);
|
||||||
connect(surface, &PlasmaShellSurfaceInterface::panelBehaviorChanged, this,
|
connect(surface, &PlasmaShellSurfaceInterface::panelBehaviorChanged, this,
|
||||||
[] {
|
[this] {
|
||||||
|
updateShowOnScreenEdge();
|
||||||
workspace()->updateClientArea();
|
workspace()->updateClientArea();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
updatePosition();
|
updatePosition();
|
||||||
updateRole();
|
updateRole();
|
||||||
|
updateShowOnScreenEdge();
|
||||||
|
connect(this, &ShellClient::geometryChanged, this, &ShellClient::updateShowOnScreenEdge);
|
||||||
|
|
||||||
setSkipTaskbar(surface->skipTaskbar());
|
setSkipTaskbar(surface->skipTaskbar());
|
||||||
connect(surface, &PlasmaShellSurfaceInterface::skipTaskbarChanged, this, [this] {
|
connect(surface, &PlasmaShellSurfaceInterface::skipTaskbarChanged, this, [this] {
|
||||||
|
@ -1031,6 +1036,79 @@ void ShellClient::installPlasmaShellSurface(PlasmaShellSurfaceInterface *surface
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShellClient::updateShowOnScreenEdge()
|
||||||
|
{
|
||||||
|
if (!ScreenEdges::self()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_unmapped || !m_plasmaShellSurface || m_plasmaShellSurface->role() != PlasmaShellSurfaceInterface::Role::Panel) {
|
||||||
|
ScreenEdges::self()->reserve(this, ElectricNone);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_plasmaShellSurface->panelBehavior() == PlasmaShellSurfaceInterface::PanelBehavior::AutoHide ||
|
||||||
|
m_plasmaShellSurface->panelBehavior() == PlasmaShellSurfaceInterface::PanelBehavior::WindowsCanCover) {
|
||||||
|
// screen edge API requires an edge, thus we need to figure out which edge the window borders
|
||||||
|
Qt::Edges edges;
|
||||||
|
for (int i = 0; i < screens()->count(); i++) {
|
||||||
|
const auto &screenGeo = screens()->geometry(i);
|
||||||
|
if (screenGeo.x() == geom.x()) {
|
||||||
|
edges |= Qt::LeftEdge;
|
||||||
|
}
|
||||||
|
if (screenGeo.x() + screenGeo.width() == geom.x() + geom.width()) {
|
||||||
|
edges |= Qt::RightEdge;
|
||||||
|
}
|
||||||
|
if (screenGeo.y() == geom.y()) {
|
||||||
|
edges |= Qt::TopEdge;
|
||||||
|
}
|
||||||
|
if (screenGeo.y() + screenGeo.height() == geom.y() + geom.height()) {
|
||||||
|
edges |= Qt::BottomEdge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// a panel might border multiple screen edges. E.g. a horizontal panel at the bottom will
|
||||||
|
// also border the left and right edge
|
||||||
|
// let's remove such cases
|
||||||
|
if (edges.testFlag(Qt::LeftEdge) && edges.testFlag(Qt::RightEdge)) {
|
||||||
|
edges = edges & (~(Qt::LeftEdge | Qt::RightEdge));
|
||||||
|
}
|
||||||
|
if (edges.testFlag(Qt::TopEdge) && edges.testFlag(Qt::BottomEdge)) {
|
||||||
|
edges = edges & (~(Qt::TopEdge | Qt::BottomEdge));
|
||||||
|
}
|
||||||
|
// it's still possible that a panel borders two edges, e.g. bottom and left
|
||||||
|
// in that case the one which is sharing more with the edge wins
|
||||||
|
auto check = [this](Qt::Edges edges, Qt::Edge horiz, Qt::Edge vert) {
|
||||||
|
if (edges.testFlag(horiz) && edges.testFlag(vert)) {
|
||||||
|
if (geom.width() >= geom.height()) {
|
||||||
|
return edges & ~horiz;
|
||||||
|
} else {
|
||||||
|
return edges & ~vert;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return edges;
|
||||||
|
};
|
||||||
|
edges = check(edges, Qt::LeftEdge, Qt::TopEdge);
|
||||||
|
edges = check(edges, Qt::LeftEdge, Qt::BottomEdge);
|
||||||
|
edges = check(edges, Qt::RightEdge, Qt::TopEdge);
|
||||||
|
edges = check(edges, Qt::RightEdge, Qt::BottomEdge);
|
||||||
|
|
||||||
|
ElectricBorder border = ElectricNone;
|
||||||
|
if (edges.testFlag(Qt::LeftEdge)) {
|
||||||
|
border = ElectricLeft;
|
||||||
|
}
|
||||||
|
if (edges.testFlag(Qt::RightEdge)) {
|
||||||
|
border = ElectricRight;
|
||||||
|
}
|
||||||
|
if (edges.testFlag(Qt::TopEdge)) {
|
||||||
|
border = ElectricTop;
|
||||||
|
}
|
||||||
|
if (edges.testFlag(Qt::BottomEdge)) {
|
||||||
|
border = ElectricBottom;
|
||||||
|
}
|
||||||
|
ScreenEdges::self()->reserve(this, border);
|
||||||
|
} else {
|
||||||
|
ScreenEdges::self()->reserve(this, ElectricNone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ShellClient::isInitialPositionSet() const
|
bool ShellClient::isInitialPositionSet() const
|
||||||
{
|
{
|
||||||
if (m_plasmaShellSurface) {
|
if (m_plasmaShellSurface) {
|
||||||
|
@ -1243,4 +1321,14 @@ void ShellClient::placeIn(QRect &area)
|
||||||
setGeometryRestore(geometry());
|
setGeometryRestore(geometry());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShellClient::showOnScreenEdge()
|
||||||
|
{
|
||||||
|
if (!m_plasmaShellSurface || m_unmapped) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO: handle show
|
||||||
|
workspace()->raiseClient(this);
|
||||||
|
// TODO: inform the client about being shown again
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,8 @@ public:
|
||||||
bool setupCompositing() override;
|
bool setupCompositing() override;
|
||||||
void finishCompositing(ReleaseReason releaseReason = ReleaseReason::Release) override;
|
void finishCompositing(ReleaseReason releaseReason = ReleaseReason::Release) override;
|
||||||
|
|
||||||
|
void showOnScreenEdge() override;
|
||||||
|
|
||||||
// TODO: const-ref
|
// TODO: const-ref
|
||||||
void placeIn(QRect &area);
|
void placeIn(QRect &area);
|
||||||
|
|
||||||
|
@ -164,6 +166,7 @@ private:
|
||||||
void setTransient();
|
void setTransient();
|
||||||
bool shouldExposeToWindowManagement();
|
bool shouldExposeToWindowManagement();
|
||||||
KWayland::Server::XdgShellSurfaceInterface::States xdgSurfaceStates() const;
|
KWayland::Server::XdgShellSurfaceInterface::States xdgSurfaceStates() const;
|
||||||
|
void updateShowOnScreenEdge();
|
||||||
static void deleteClient(ShellClient *c);
|
static void deleteClient(ShellClient *c);
|
||||||
|
|
||||||
KWayland::Server::ShellSurfaceInterface *m_shellSurface;
|
KWayland::Server::ShellSurfaceInterface *m_shellSurface;
|
||||||
|
|
Loading…
Reference in a new issue