Commit 4c18d156 authored by Roman Gilg's avatar Roman Gilg

[xwl] Support stack optimizing X drag source clients

Summary:
Some X clients acting as drag sources might try to optimize finding the current
target window by checking if a window manager, that sets the root window
_NET_CLIENT_LIST_STACKING property, is present. An example for this is Chromium
and since KWin sets the property the drag proxy windows must be added to this
list. Otherwise the origin client will not detect the proxy window and not send
an XdndEnter message.

Test Plan: Manually with Chromium.

Reviewers: #kwin

Subscribers: zzag, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D15628
parent 522d2935
......@@ -170,6 +170,8 @@ void Workspace::propagateClients(bool propagate_new_clients)
newWindowStack << ScreenEdges::self()->windows();
newWindowStack << manual_overlays;
newWindowStack.reserve(newWindowStack.size() + 2*stacking_order.size()); // *2 for inputWindow
for (int i = stacking_order.size() - 1; i >= 0; --i) {
......@@ -202,7 +204,10 @@ void Workspace::propagateClients(bool propagate_new_clients)
int pos = 0;
xcb_window_t *cl(nullptr);
if (propagate_new_clients) {
cl = new xcb_window_t[ desktops.count() + clients.count()];
cl = new xcb_window_t[ manual_overlays.count() + desktops.count() + clients.count()];
for (const auto win : manual_overlays) {
cl[pos++] = win;
}
// TODO this is still not completely in the map order
for (ClientList::ConstIterator it = desktops.constBegin(); it != desktops.constEnd(); ++it)
cl[pos++] = (*it)->window();
......@@ -212,12 +217,15 @@ void Workspace::propagateClients(bool propagate_new_clients)
delete [] cl;
}
cl = new xcb_window_t[ stacking_order.count()];
cl = new xcb_window_t[ manual_overlays.count() + stacking_order.count()];
pos = 0;
for (ToplevelList::ConstIterator it = stacking_order.constBegin(); it != stacking_order.constEnd(); ++it) {
if ((*it)->isClient())
cl[pos++] = (*it)->window();
}
for (const auto win : manual_overlays) {
cl[pos++] = win;
}
rootInfo()->setClientListStacking(cl, pos);
delete [] cl;
......
......@@ -278,6 +278,13 @@ public:
void windowToNextDesktop(AbstractClient* c);
void sendClientToScreen(AbstractClient* c, int screen);
void addManualOverlay(xcb_window_t id) {
manual_overlays << id;
}
void removeManualOverlay(xcb_window_t id) {
manual_overlays.removeOne(id);
}
/**
* Shows the menu operations menu for the client and makes it active if
* it's not already.
......@@ -564,6 +571,7 @@ private:
ToplevelList unconstrained_stacking_order; // Topmost last
ToplevelList stacking_order; // Topmost last
QVector<xcb_window_t> manual_overlays; //Topmost last
bool force_restacking;
ToplevelList x_stacking; // From XQueryTree()
std::unique_ptr<Xcb::Tree> m_xStackingQueryTree;
......
......@@ -316,12 +316,9 @@ WlVisit::WlVisit(AbstractClient *target, XToWlDrag *drag)
32, 1, &version);
xcb_map_window(xcbConn, m_window);
workspace()->addManualOverlay(m_window);
workspace()->updateStackingOrder(true);
const uint32_t stackValues[] = { XCB_STACK_MODE_ABOVE };
xcb_configure_window (xcbConn,
m_window,
XCB_CONFIG_WINDOW_STACK_MODE,
stackValues);
xcb_flush(xcbConn);
m_mapped = true;
}
......@@ -541,6 +538,8 @@ void WlVisit::unmapProxyWindow()
}
auto *xcbConn = kwinApp()->x11Connection();
xcb_unmap_window(xcbConn, m_window);
workspace()->removeManualOverlay(m_window);
workspace()->updateStackingOrder(true);
xcb_flush(xcbConn);
m_mapped = false;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment