From b6c84775aba80ef12f3b9bd914111449d92009ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Wed, 13 Jun 2012 21:44:59 +0200 Subject: [PATCH] HACK around bug 288791 - search for likely panel proxies and raise them after destroying an effect input window BUG: 288791 REVIEW: 105245 FIXED-IN: 4.9 --- effects.cpp | 3 +++ screenedge.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ screenedge.h | 5 +++++ 3 files changed, 58 insertions(+) diff --git a/effects.cpp b/effects.cpp index 743bb9c607..c56f8d608d 100644 --- a/effects.cpp +++ b/effects.cpp @@ -985,6 +985,9 @@ void EffectsHandlerImpl::destroyInputWindow(Window w) if (pos.second == w) { input_windows.removeAll(pos); XDestroyWindow(display(), w); +#ifdef KWIN_BUILD_SCREENEDGES + Workspace::self()->screenEdge()->raisePanelProxies(); +#endif return; } } diff --git a/screenedge.cpp b/screenedge.cpp index 9f714946f5..380ec5d8ee 100644 --- a/screenedge.cpp +++ b/screenedge.cpp @@ -398,6 +398,56 @@ void ScreenEdge::ensureOnTop() delete [] windows; } +/* + * NOTICE THIS IS A HACK + * or at least a quite cumbersome way to handle conflictive electric borders + * (like for autohiding panels or whatever) + * the SANE solution is a central electric border daemon and a protocol + * what this function does is to search for windows on the screen edges that are + * * not our own screenedge + * * either very slim + * * or InputOnly + * and raises them on top of everything else, including our own screen borders + * this is typically (and for now ONLY) called when an effect input window is destroyed + * (which raised our electric borders) + */ + +void ScreenEdge::raisePanelProxies() +{ + XWindowAttributes attr; + Window dummy; + Window* windows = NULL; + unsigned int count = 0; + QRect screen = QRect(0, 0, displayWidth(), displayHeight()); + QVector proxies; + XQueryTree(display(), rootWindow(), &dummy, &dummy, &windows, &count); + for (unsigned int i = 0; i < count; ++i) { + if (m_screenEdgeWindows.contains(windows[i])) + continue; + if (XGetWindowAttributes(display(), windows[i], &attr)) { + if (attr.map_state == IsUnmapped) // a thousand Qt group leader dummies ... + continue; + const QRect geo(attr.x, attr.y, attr.width, attr.height); + if (geo.width() < 1 || geo.height() < 1) + continue; + if (!(geo.width() > 1 || geo.height() > 1)) + continue; // random 1x1 dummy windows, all your corners are belong to us >-) + if (attr.c_class != InputOnly && (geo.width() > 3 && geo.height() > 3)) + continue; + if (geo.x() != screen.x() && geo.right() != screen.right() && + geo.y() != screen.y() && geo.bottom() != screen.bottom()) + continue; + proxies << windows[i]; + } + } + if (!proxies.isEmpty()) { + XRaiseWindow(display(), proxies.data()[ 0 ]); + XRestackWindows(display(), proxies.data(), proxies.count()); + } + if (windows) + XFree(windows); +} + const QVector< Window >& ScreenEdge::windows() { return m_screenEdgeWindows; diff --git a/screenedge.h b/screenedge.h index 37645e498f..aa89bf06b0 100644 --- a/screenedge.h +++ b/screenedge.h @@ -90,6 +90,11 @@ public: * to do this if an effect input window is active. */ void ensureOnTop(); + /** + * Raise FOREIGN border windows to the real top of the screen. We usually need + * to do this after an effect input window was active. + */ + void raisePanelProxies(); /** * Called when the user entered an electric border with the mouse. * It may switch to another virtual desktop.