#include "qxtwindowsystem.h" /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #include #include #include static WindowList qxt_getWindows(Atom prop) { WindowList res; Atom type = 0; int format = 0; uchar* data = 0; ulong count, after; Display* display = QX11Info::display(); Window window = QX11Info::appRootWindow(); if (XGetWindowProperty(display, window, prop, 0, 1024 * sizeof(Window) / 4, False, AnyPropertyType, &type, &format, &count, &after, &data) == Success) { Window* list = reinterpret_cast(data); for (uint i = 0; i < count; ++i) res += list[i]; if (data) XFree(data); } return res; } WindowList QxtWindowSystem::windows() { static Atom net_clients = 0; if (!net_clients) net_clients = XInternAtom(QX11Info::display(), "_NET_CLIENT_LIST_STACKING", True); return qxt_getWindows(net_clients); } WId QxtWindowSystem::activeWindow() { static Atom net_active = 0; if (!net_active) net_active = XInternAtom(QX11Info::display(), "_NET_ACTIVE_WINDOW", True); return qxt_getWindows(net_active).value(0); } WId QxtWindowSystem::findWindow(const QString& title) { Window result = 0; WindowList list = windows(); foreach (const Window &wid, list) { if (windowTitle(wid) == title) { result = wid; break; } } return result; } WId QxtWindowSystem::windowAt(const QPoint& pos) { Window result = 0; WindowList list = windows(); for (int i = list.size() - 1; i >= 0; --i) { WId wid = list.at(i); if (windowGeometry(wid).contains(pos)) { result = wid; break; } } return result; } QString QxtWindowSystem::windowTitle(WId window) { QString name; char* str = 0; if (XFetchName(QX11Info::display(), window, &str)) name = QString::fromLatin1(str); if (str) XFree(str); return name; } QRect QxtWindowSystem::windowGeometry(WId window) { int x, y; uint width, height, border, depth; Window root, child; Display* display = QX11Info::display(); XGetGeometry(display, window, &root, &x, &y, &width, &height, &border, &depth); XTranslateCoordinates(display, window, root, x, y, &x, &y, &child); static Atom net_frame = 0; if (!net_frame) net_frame = XInternAtom(QX11Info::display(), "_NET_FRAME_EXTENTS", True); QRect rect(x, y, width, height); Atom type = 0; int format = 0; uchar* data = 0; ulong count, after; if (XGetWindowProperty(display, window, net_frame, 0, 4, False, AnyPropertyType, &type, &format, &count, &after, &data) == Success) { // _NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32 if (count == 4) { long* extents = reinterpret_cast(data); rect.adjust(-extents[0], -extents[2], extents[1], extents[3]); } if (data) XFree(data); } return rect; } typedef struct { Window window; /* screen saver window - may not exist */ int state; /* ScreenSaverOff, ScreenSaverOn, ScreenSaverDisabled*/ int kind; /* ScreenSaverBlanked, ...Internal, ...External */ unsigned long til_or_since; /* time til or since screen saver */ unsigned long idle; /* total time since last user input */ unsigned long eventMask; /* currently selected events for this client */ } XScreenSaverInfo; typedef XScreenSaverInfo* (*XScreenSaverAllocInfo)(); typedef Status (*XScreenSaverQueryInfo)(Display* display, Drawable drawable, XScreenSaverInfo* info); static XScreenSaverAllocInfo _xScreenSaverAllocInfo = 0; static XScreenSaverQueryInfo _xScreenSaverQueryInfo = 0; uint QxtWindowSystem::idleTime() { static bool xssResolved = false; if (!xssResolved) { QLibrary xssLib(QLatin1String("Xss"), 1); if (xssLib.load()) { _xScreenSaverAllocInfo = (XScreenSaverAllocInfo) xssLib.resolve("XScreenSaverAllocInfo"); _xScreenSaverQueryInfo = (XScreenSaverQueryInfo) xssLib.resolve("XScreenSaverQueryInfo"); xssResolved = true; } } uint idle = 0; if (xssResolved) { XScreenSaverInfo* info = _xScreenSaverAllocInfo(); const int screen = QX11Info::appScreen(); unsigned long rootWindow = (unsigned long)QX11Info::appRootWindow(screen); _xScreenSaverQueryInfo(QX11Info::display(), (Drawable) rootWindow, info); idle = info->idle; if (info) XFree(info); } return idle; }