Delegate screen edge reservation error handling to user
Window screen edge reservation relies on Window::showOnScreenEdge() getting called when the screen edge can't be reserved. That makes screen edge code not easy to follow. This change makes ScreenEdges::reserve() indicate if a screen edge has been successfully reserved and delegate error handling to the user. In most cases, if a screen edge has not been successfully hidden, you just need to avoid calling hideClient() and wait until the next moment when the window can be hidden again. Note that it differs from the current behavior but it's for a good reason. If the panel can't be hidden now, the panel has no idea how to handle it; only the compositor knows when it can be hidden again.
This commit is contained in:
parent
687415076f
commit
71e8fad1f6
4 changed files with 26 additions and 28 deletions
|
@ -322,8 +322,11 @@ void LayerShellV1Window::installAutoHideScreenEdgeV1(KWaylandServer::AutoHideScr
|
|||
|
||||
void LayerShellV1Window::reserveScreenEdge()
|
||||
{
|
||||
hideClient();
|
||||
workspace()->screenEdges()->reserve(this, m_screenEdge->border());
|
||||
if (workspace()->screenEdges()->reserve(this, m_screenEdge->border())) {
|
||||
hideClient();
|
||||
} else {
|
||||
showClient();
|
||||
}
|
||||
}
|
||||
|
||||
void LayerShellV1Window::unreserveScreenEdge()
|
||||
|
|
|
@ -1279,7 +1279,7 @@ void ScreenEdges::unreserve(ElectricBorder border, QObject *object)
|
|||
}
|
||||
}
|
||||
|
||||
void ScreenEdges::reserve(Window *client, ElectricBorder border)
|
||||
bool ScreenEdges::reserve(Window *client, ElectricBorder border)
|
||||
{
|
||||
const auto it = std::remove_if(m_edges.begin(), m_edges.end(), [client](const auto &edge) {
|
||||
return edge->client() == client;
|
||||
|
@ -1288,11 +1288,9 @@ void ScreenEdges::reserve(Window *client, ElectricBorder border)
|
|||
m_edges.erase(it, m_edges.end());
|
||||
|
||||
if (border != ElectricNone) {
|
||||
createEdgeForClient(client, border);
|
||||
return createEdgeForClient(client, border);
|
||||
} else {
|
||||
if (hadBorder) { // show again
|
||||
client->showOnScreenEdge();
|
||||
}
|
||||
return hadBorder;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1314,7 +1312,7 @@ void ScreenEdges::unreserveTouch(ElectricBorder border, QAction *action)
|
|||
}
|
||||
}
|
||||
|
||||
void ScreenEdges::createEdgeForClient(Window *client, ElectricBorder border)
|
||||
bool ScreenEdges::createEdgeForClient(Window *client, ElectricBorder border)
|
||||
{
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
|
@ -1385,10 +1383,10 @@ void ScreenEdges::createEdgeForClient(Window *client, ElectricBorder border)
|
|||
Edge *edge = m_edges.back().get();
|
||||
edge->setClient(client);
|
||||
edge->reserve();
|
||||
} else {
|
||||
// we could not create an edge window, so don't allow the window to hide
|
||||
client->showOnScreenEdge();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScreenEdges::deleteEdgeForClient(Window *window)
|
||||
|
|
|
@ -298,7 +298,7 @@ public:
|
|||
* @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)
|
||||
*/
|
||||
void reserve(KWin::Window *client, ElectricBorder border);
|
||||
bool reserve(KWin::Window *client, ElectricBorder border);
|
||||
|
||||
/**
|
||||
* Mark the specified screen edge as reserved for touch gestures. This method is provided for
|
||||
|
@ -409,7 +409,7 @@ private:
|
|||
void setRemainActiveOnFullscreen(bool remainActive);
|
||||
ElectricBorderAction actionForEdge(Edge *edge) const;
|
||||
ElectricBorderAction actionForTouchEdge(Edge *edge) const;
|
||||
void createEdgeForClient(Window *client, ElectricBorder border);
|
||||
bool createEdgeForClient(Window *client, ElectricBorder border);
|
||||
void deleteEdgeForClient(Window *client);
|
||||
bool m_desktopSwitching;
|
||||
bool m_desktopSwitchingMovingClients;
|
||||
|
|
|
@ -2917,29 +2917,26 @@ void X11Window::readShowOnScreenEdge(Xcb::Property &property)
|
|||
if (border != ElectricNone) {
|
||||
disconnect(m_edgeGeometryTrackingConnection);
|
||||
|
||||
hideClient();
|
||||
const bool successfullyHidden = isHiddenInternal();
|
||||
auto reserveScreenEdge = [this, border]() {
|
||||
if (workspace()->screenEdges()->reserve(this, border)) {
|
||||
hideClient();
|
||||
} else {
|
||||
showClient();
|
||||
}
|
||||
};
|
||||
|
||||
m_edgeGeometryTrackingConnection = connect(this, &X11Window::frameGeometryChanged, this, [this, border]() {
|
||||
hideClient();
|
||||
workspace()->screenEdges()->reserve(this, border);
|
||||
});
|
||||
|
||||
if (successfullyHidden) {
|
||||
workspace()->screenEdges()->reserve(this, border);
|
||||
} else {
|
||||
workspace()->screenEdges()->reserve(this, ElectricNone);
|
||||
}
|
||||
reserveScreenEdge();
|
||||
m_edgeGeometryTrackingConnection = connect(this, &X11Window::frameGeometryChanged, this, reserveScreenEdge);
|
||||
} else if (!property.isNull() && property->type != XCB_ATOM_NONE) {
|
||||
// property value is incorrect, delete the property
|
||||
// so that the client knows that it is not hidden
|
||||
xcb_delete_property(kwinApp()->x11Connection(), window(), atoms->kde_screen_edge_show);
|
||||
} else {
|
||||
// restore
|
||||
// TODO: add proper unreserve
|
||||
|
||||
// this will call showOnScreenEdge to reset the state
|
||||
disconnect(m_edgeGeometryTrackingConnection);
|
||||
|
||||
showClient();
|
||||
|
||||
workspace()->screenEdges()->reserve(this, ElectricNone);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue