示例#1
0
void TitleWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
    Plasma::IconWidget::mouseMoveEvent(event);
    if (m_drag && (event->buttons() & Qt::LeftButton))
    {
        WId wid = KWindowSystem::activeWindow();
        if (wid) {
            XUngrabPointer(QX11Info::display(), QX11Info::appTime());
            NETRootInfo rootInfo(QX11Info::display(), NET::WMMoveResize);
            KWindowInfo info = KWindowSystem::windowInfo(wid, NET::WMGeometry);
            int x;
            int y;
            QPointF p = event->screenPos();
            if (p.x() > info.geometry().x() && p.x() < info.geometry().x() + info.geometry().width())
                x = p.x();
            else
                x = info.geometry().x();
            if (p.y() > info.geometry().y() && p.y() < info.geometry().y() + info.geometry().height())
                y = p.y();
            else
                y = info.geometry().y();
            rootInfo.moveResizeRequest( wid, x, y, NET::Move);
        }

    }
}
示例#2
0
void WindowManager::startDrag(QWidget *widget, const QPoint& position)
{
    if (!(enabled() && widget)) {
        return;
    }
    if (QWidget::mouseGrabber()) {
        return;
    }

    // ungrab pointer
    if (useWMMoveResize()) {
        #if defined Q_WS_X11 && QT_VERSION < 0x050000
        #ifndef ENABLE_KDE_SUPPORT
        static const Atom constNetMoveResize = XInternAtom(QX11Info::display(), "_NET_WM_MOVERESIZE", False);
        //...Taken from bespin...
        // stolen... errr "adapted!" from QSizeGrip
        QX11Info info;
        XEvent xev;
        xev.xclient.type = ClientMessage;
        xev.xclient.message_type = constNetMoveResize;
        xev.xclient.display = QX11Info::display();
        xev.xclient.window = widget->window()->winId();
        xev.xclient.format = 32;
        xev.xclient.data.l[0] = position.x();
        xev.xclient.data.l[1] = position.y();
        xev.xclient.data.l[2] = 8; // NET::Move
        xev.xclient.data.l[3] = Button1;
        xev.xclient.data.l[4] = 0;
        XUngrabPointer(QX11Info::display(), QX11Info::appTime());
        XSendEvent(QX11Info::display(), QX11Info::appRootWindow(info.screen()), False,
                   SubstructureRedirectMask | SubstructureNotifyMask, &xev);
        #else
        XUngrabPointer(QX11Info::display(), QX11Info::appTime());
        NETRootInfo rootInfo(QX11Info::display(), NET::WMMoveResize);
        rootInfo.moveResizeRequest(widget->window()->winId(), position.x(), position.y(), NET::Move);
        #endif // !ENABLE_KDE_SUPPORT
        #endif
    }

    if (!useWMMoveResize() && !_cursorOverride) {
        qApp->setOverrideCursor(Qt::DragMoveCursor);
        _cursorOverride = true;
    }

    _dragInProgress = true;
    return;
}
示例#3
0
文件: layers.cpp 项目: 8l/kwin
/*!
  Propagates the managed clients to the world.
  Called ONLY from updateStackingOrder().
 */
void Workspace::propagateClients(bool propagate_new_clients)
{
    // restack the windows according to the stacking order
    // supportWindow > electric borders > clients > hidden clients
    QVector<xcb_window_t> newWindowStack;

    // Stack all windows under the support window. The support window is
    // not used for anything (besides the NETWM property), and it's not shown,
    // but it was lowered after kwin startup. Stacking all clients below
    // it ensures that no client will be ever shown above override-redirect
    // windows (e.g. popups).
    newWindowStack << rootInfo()->supportWindow();

    newWindowStack << ScreenEdges::self()->windows();

    newWindowStack.reserve(newWindowStack.size() + 2*stacking_order.size()); // *2 for inputWindow

    for (int i = stacking_order.size() - 1; i >= 0; --i) {
        Client *client = qobject_cast<Client*>(stacking_order.at(i));
        if (!client || client->hiddenPreview()) {
            continue;
        }

        if (client->inputId())
            // Stack the input window above the frame
            newWindowStack << client->inputId();

        newWindowStack << client->frameId();
    }

    // when having hidden previews, stack hidden windows below everything else
    // (as far as pure X stacking order is concerned), in order to avoid having
    // these windows that should be unmapped to interfere with other windows
    for (int i = stacking_order.size() - 1; i >= 0; --i) {
        Client *client = qobject_cast<Client*>(stacking_order.at(i));
        if (!client || !client->hiddenPreview())
            continue;
        newWindowStack << client->frameId();
    }
    // TODO isn't it too inefficient to restack always all clients?
    // TODO don't restack not visible windows?
    assert(newWindowStack.at(0) == rootInfo()->supportWindow());
    Xcb::restackWindows(newWindowStack);

    int pos = 0;
    xcb_window_t *cl(nullptr);
    if (propagate_new_clients) {
        cl = new xcb_window_t[ desktops.count() + clients.count()];
        // TODO this is still not completely in the map order
        for (ClientList::ConstIterator it = desktops.constBegin(); it != desktops.constEnd(); ++it)
            cl[pos++] = (*it)->window();
        for (ClientList::ConstIterator it = clients.constBegin(); it != clients.constEnd(); ++it)
            cl[pos++] = (*it)->window();
        rootInfo()->setClientList(cl, pos);
        delete [] cl;
    }

    cl = new xcb_window_t[ stacking_order.count()];
    pos = 0;
    for (ToplevelList::ConstIterator it = stacking_order.constBegin(); it != stacking_order.constEnd(); ++it) {
        if ((*it)->isClient())
            cl[pos++] = (*it)->window();
    }
    rootInfo()->setClientListStacking(cl, pos);
    delete [] cl;

    // Make the cached stacking order invalid here, in case we need the new stacking order before we get
    // the matching event, due to X being asynchronous.
    x_stacking_dirty = true;
}