From fa3fa8c3ca15023295bef91be8b913af4c551513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 20 Dec 2012 14:03:02 +0100 Subject: [PATCH] Port Input Window handling for Effects to XCB REVIEW: 107817 --- effects.cpp | 72 ++++++++++++++++++++++------------ effects.h | 6 ++- libkwineffects/kwineffects.cpp | 4 +- libkwineffects/kwineffects.h | 10 ++--- 4 files changed, 56 insertions(+), 36 deletions(-) diff --git a/effects.cpp b/effects.cpp index b3758aa68d..56fddcd96a 100644 --- a/effects.cpp +++ b/effects.cpp @@ -55,6 +55,7 @@ along with this program. If not, see . #include #include "composite.h" +#include "xcbutils.h" namespace KWin @@ -152,8 +153,9 @@ EffectsHandlerImpl::~EffectsHandlerImpl() ungrabKeyboard(); foreach (const EffectPair & ep, loaded_effects) unloadEffect(ep.first); - foreach (const InputWindowPair & pos, input_windows) - XDestroyWindow(display(), pos.second); + foreach (const InputWindowPair & pos, input_windows) { + xcb_destroy_window(connection(), pos.second); + } } void EffectsHandlerImpl::setupClientConnections(Client* c) @@ -1026,46 +1028,52 @@ QRect EffectsHandlerImpl::clientArea(clientAreaOption opt, const QPoint& p, int return Workspace::self()->clientArea(opt, p, desktop); } -Window EffectsHandlerImpl::createInputWindow(Effect* e, int x, int y, int w, int h, const QCursor& cursor) +xcb_window_t EffectsHandlerImpl::createInputWindow(Effect* e, int x, int y, int w, int h, const QCursor& cursor) { - Window win = 0; + xcb_window_t win = XCB_WINDOW_NONE; QList::iterator it = input_windows.begin(); while (it != input_windows.end()) { if (it->first != e) { ++it; continue; } - XWindowAttributes attr; - if (!XGetWindowAttributes(display(), it->second, &attr)) { + Xcb::WindowAttributes attributes(it->second); + Xcb::WindowGeometry geometry(it->second); + if (!attributes) { // this is some random junk that certainly should no be here kDebug(1212) << "found input window that is NOT on the server, something is VERY broken here"; Q_ASSERT(false); // exit in debug mode - for releases we'll be a bit more graceful it = input_windows.erase(it); continue; } - if (attr.x == x && attr.y == y && attr.width == w && attr.height == h) { + if (geometry.rect() == QRect(x, y, w, h)) { win = it->second; // re-use break; - } else if (attr.map_state == IsUnmapped) { + } else if (attributes->map_state == XCB_MAP_STATE_UNMAPPED) { // probably old one, likely no longer of interest - XDestroyWindow(display(), it->second); + xcb_destroy_window(connection(), it->second); it = input_windows.erase(it); continue; } ++it; } - if (!win) { - XSetWindowAttributes attrs; - attrs.override_redirect = True; - win = XCreateWindow(display(), rootWindow(), x, y, w, h, 0, 0, InputOnly, CopyFromParent, - CWOverrideRedirect, &attrs); + if (win == XCB_WINDOW_NONE) { + win = xcb_generate_id(connection()); // TODO keeping on top? // TODO enter/leave notify? - XSelectInput(display(), win, ButtonPressMask | ButtonReleaseMask | PointerMotionMask); - XDefineCursor(display(), win, cursor.handle()); + const uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_CURSOR; + const uint32_t values[] = { + true, + XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION, + static_cast(cursor.handle()) + }; + xcb_create_window(connection(), 0, win, rootWindow(), x, y, w, h, 0, XCB_WINDOW_CLASS_INPUT_ONLY, + XCB_COPY_FROM_PARENT, mask, values); input_windows.append(qMakePair(e, win)); } - XMapRaised(display(), win); + xcb_map_window(connection(), win); + const uint32_t values[] = { XCB_STACK_MODE_ABOVE }; + xcb_configure_window(connection(), win, XCB_CONFIG_WINDOW_STACK_MODE, values); // Raise electric border windows above the input windows // so they can still be triggered. #ifdef KWIN_BUILD_SCREENEDGES @@ -1077,11 +1085,11 @@ Window EffectsHandlerImpl::createInputWindow(Effect* e, int x, int y, int w, int return win; } -void EffectsHandlerImpl::destroyInputWindow(Window w) +void EffectsHandlerImpl::destroyInputWindow(xcb_window_t w) { foreach (const InputWindowPair & pos, input_windows) { if (pos.second == w) { - XUnmapWindow(display(), w); + xcb_unmap_window(connection(), w); #ifdef KWIN_BUILD_SCREENEDGES Workspace::self()->screenEdge()->raisePanelProxies(); #endif @@ -1136,16 +1144,28 @@ void EffectsHandlerImpl::checkInputWindowStacking() { if (input_windows.count() == 0) return; - Window* wins = new Window[input_windows.count()]; - int pos = 0; + xcb_window_t* wins = new xcb_window_t[input_windows.count()]; + QList attributes; foreach (const InputWindowPair &it, input_windows) { - XWindowAttributes attr; - if (XGetWindowAttributes(display(), it.second, &attr) && attr.map_state != IsUnmapped) - wins[pos++] = it.second; + attributes << Xcb::WindowAttributes(it.second); + } + int pos = 0; + for (QList::iterator it = attributes.begin(); it != attributes.end(); ++it) { + if (*it && (*it)->map_state != XCB_MAP_STATE_UNMAPPED) { + wins[pos++] = (*it).window(); + } } if (pos) { - XRaiseWindow(display(), wins[0]); - XRestackWindows(display(), wins, pos); + const uint32_t values[] = { XCB_STACK_MODE_ABOVE }; + xcb_configure_window(connection(), wins[0], XCB_CONFIG_WINDOW_STACK_MODE, values); + for (int i=1; i InputWindowPair; class ThumbnailItem; @@ -133,9 +134,9 @@ public: virtual double animationTimeFactor() const; virtual WindowQuadType newWindowQuadType(); - virtual Window createInputWindow(Effect* e, int x, int y, int w, int h, const QCursor& cursor); + virtual xcb_window_t createInputWindow(Effect* e, int x, int y, int w, int h, const QCursor& cursor); using EffectsHandler::createInputWindow; - virtual void destroyInputWindow(Window w); + virtual void destroyInputWindow(xcb_window_t w); virtual bool checkInputWindowEvent(XEvent* e); virtual void checkInputWindowStacking(); @@ -242,6 +243,7 @@ private: QHash m_managedProperties; Compositor *m_compositor; Scene *m_scene; + QList< InputWindowPair > input_windows; }; class EffectWindowImpl : public EffectWindow diff --git a/libkwineffects/kwineffects.cpp b/libkwineffects/kwineffects.cpp index 4895ca0e1e..fa1015a496 100644 --- a/libkwineffects/kwineffects.cpp +++ b/libkwineffects/kwineffects.cpp @@ -595,12 +595,12 @@ EffectsHandler::~EffectsHandler() assert(loaded_effects.count() == 0); } -Window EffectsHandler::createInputWindow(Effect* e, const QRect& r, const QCursor& cursor) +xcb_window_t EffectsHandler::createInputWindow(Effect* e, const QRect& r, const QCursor& cursor) { return createInputWindow(e, r.x(), r.y(), r.width(), r.height(), cursor); } -Window EffectsHandler::createFullScreenInputWindow(Effect* e, const QCursor& cursor) +xcb_window_t EffectsHandler::createFullScreenInputWindow(Effect* e, const QCursor& cursor) { return createInputWindow(e, 0, 0, displayWidth(), displayHeight(), cursor); } diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h index 46c8bc303d..f1e2add39d 100644 --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -72,7 +72,6 @@ class ScreenPrePaintData; class ScreenPaintData; typedef QPair< QString, Effect* > EffectPair; -typedef QPair< Effect*, Window > InputWindowPair; typedef QList< KWin::EffectWindow* > EffectWindowList; @@ -634,10 +633,10 @@ public: // Functions for handling input - e.g. when an Expose-like effect is shown, an input window // covering the whole screen is created and all mouse events will be intercepted by it. // The effect's windowInputMouseEvent() will get called with such events. - virtual Window createInputWindow(Effect* e, int x, int y, int w, int h, const QCursor& cursor) = 0; - Window createInputWindow(Effect* e, const QRect& r, const QCursor& cursor); - virtual Window createFullScreenInputWindow(Effect* e, const QCursor& cursor); - virtual void destroyInputWindow(Window w) = 0; + virtual xcb_window_t createInputWindow(Effect* e, int x, int y, int w, int h, const QCursor& cursor) = 0; + xcb_window_t createInputWindow(Effect* e, const QRect& r, const QCursor& cursor); + virtual xcb_window_t createFullScreenInputWindow(Effect* e, const QCursor& cursor); + virtual void destroyInputWindow(xcb_window_t w) = 0; virtual QPoint cursorPos() const = 0; virtual bool grabKeyboard(Effect* effect) = 0; virtual void ungrabKeyboard() = 0; @@ -1161,7 +1160,6 @@ Q_SIGNALS: protected: QVector< EffectPair > loaded_effects; QHash< QString, KLibrary* > effect_libraries; - QList< InputWindowPair > input_windows; //QHash< QString, EffectFactory* > effect_factories; CompositingType compositing_type; };