📄 qwidget_x11.cpp
字号:
if (isWindow()) X11->deferred_map.removeAll(this); if (isModal()) { // just be sure we leave modal QApplicationPrivate::leaveModal(this); } else if ((windowType() == Qt::Popup)) qApp->d_func()->closePopup(this);#ifndef QT_NO_XRENDER if (d->picture) { if (destroyWindow) XRenderFreePicture(X11->display, d->picture); d->picture = 0; }#endif // QT_NO_XRENDER if ((windowType() == Qt::Desktop)) { if (acceptDrops()) X11->dndEnable(this, false); } else { if (destroyWindow) qt_XDestroyWindow(this, X11->display, data->winid); } d->setWinId(0); extern void qPRCleanup(QWidget *widget); // from qapplication_x11.cpp if (testAttribute(Qt::WA_WState_Reparented)) qPRCleanup(this); if(d->ic) { delete d->ic; } else { // release previous focus information participating with // preedit preservation of qic QInputContext *qic = inputContext(); if (qic) qic->widgetDestroyed(this); } }}void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WFlags f){ Q_Q(QWidget); if (q->isVisible() && q->parentWidget() && parent != q->parentWidget()) q->parentWidget()->d_func()->invalidateBuffer(q->geometry()); extern void qPRCreate(const QWidget *, Window); QCursor oldcurs; bool setcurs = q->testAttribute(Qt::WA_SetCursor); if (setcurs) { oldcurs = q->cursor(); q->unsetCursor(); } // dnd unregister (we will register again below) if (q->testAttribute(Qt::WA_DropSiteRegistered)) q->setAttribute(Qt::WA_DropSiteRegistered, false); // if we are a top then remove our dnd prop for now // it will get rest later if (q->isWindow()) X11->dndEnable(q, false); QWidget *oldparent = q->parentWidget(); WId old_winid = data.winid; if ((q->windowType() == Qt::Desktop)) old_winid = 0; setWinId(0); // hide and reparent our own window away. Otherwise we might get // destroyed when emitting the child remove event below. See QWorkspace. XUnmapWindow(X11->display, old_winid); XReparentWindow(X11->display, old_winid, RootWindow(X11->display, xinfo.screen()), 0, 0); if (q->isWindow() || !parent) { // we are toplevel, or reparenting to toplevel QTLWExtra *top = topData(); top->parentWinId = 0; // zero the frame strut and mark it dirty top->fleft = top->fright = top->ftop = top->fbottom = 0; data.fstrut_dirty = true; } if (q->isWindow()) { // reparenting from top-level, make sure show() works again QTLWExtra *top = topData(); top->waitingForMapNotify = 0; top->validWMState = 0; } QObjectPrivate::setParent_helper(parent); bool enable = q->isEnabled(); // remember status Qt::FocusPolicy fp = q->focusPolicy(); QSize s = q->size(); bool explicitlyHidden = q->testAttribute(Qt::WA_WState_Hidden) && q->testAttribute(Qt::WA_WState_ExplicitShowHide); data.window_flags = f; q->setAttribute(Qt::WA_WState_Created, false); q->setAttribute(Qt::WA_WState_Visible, false); q->setAttribute(Qt::WA_WState_Hidden, false); q->create(); if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden) q->setAttribute(Qt::WA_WState_Hidden); q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden); QObjectList chlist = q->children(); for (int i = 0; i < chlist.size(); ++i) { // reparent children QObject *obj = chlist.at(i); if (obj->isWidgetType()) { QWidget *w = (QWidget *)obj; if (xinfo.screen() != w->d_func()->xinfo.screen()) { // ### force setParent() to not shortcut out (because // ### we're setting the parent to the current parent) w->d_func()->parent = 0; w->setParent(q); } else if (!w->isWindow()) { w->d_func()->invalidateBuffer(w->rect()); XReparentWindow(X11->display, w->winId(), q->winId(), w->geometry().x(), w->geometry().y()); } else if (isTransient(w)) { /* when reparenting toplevel windows with toplevel-transient children, we need to make sure that the window manager gets the updated WM_TRANSIENT_FOR information... unfortunately, some window managers don't handle changing WM_TRANSIENT_FOR before the toplevel window is visible, so we unmap and remap all toplevel-transient children *after* the toplevel parent has been mapped. thankfully, this is easy in Qt :) note that the WM_TRANSIENT_FOR hint is actually updated in QWidgetPrivate::show_sys() */ XUnmapWindow(X11->display, w->winId()); QApplication::postEvent(w, new QEvent(QEvent::ShowWindowRequest)); } } } qPRCreate(q, old_winid); updateSystemBackground(); if (q->isWindow()) { uint window_state = data.window_state; const QRect r = topData()->normalGeometry; q->setGeometry(0, 0, s.width(), s.height()); data.window_state = window_state; topData()->normalGeometry = r; if (!extra->topextra->caption.isEmpty()) setWindowTitle_helper(extra->topextra->caption); } else { q->setGeometry(0, 0, s.width(), s.height()); } setEnabled_helper(enable); //preserving WA_ForceDisabled q->setFocusPolicy(fp); if (extra && !extra->mask.isEmpty()) { QRegion r = extra->mask; extra->mask = QRegion(); q->setMask(r); } if (old_winid) qt_XDestroyWindow(q, X11->display, old_winid); if (setcurs) q->setCursor(oldcurs); // ensure the dnd state of our old parent if (oldparent) oldparent->d_func()->fixupDnd(); // check if we need to register our dropsite if (q->testAttribute(Qt::WA_AcceptDrops) || (!q->isWindow() && q->parentWidget() && q->parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))) { q->setAttribute(Qt::WA_DropSiteRegistered, true); } else { // ensure that if any of our children need dnd then we have it set fixupDnd(); } invalidateBuffer(q->rect());}/*! Translates the widget coordinate \a pos to global screen coordinates. For example, \c{mapToGlobal(QPoint(0,0))} would give the global coordinates of the top-left pixel of the widget. \sa mapFromGlobal() mapTo() mapToParent()*/QPoint QWidget::mapToGlobal(const QPoint &pos) const{ Q_D(const QWidget); int x, y; Window child; QPoint p = d->mapToWS(pos); XTranslateCoordinates(X11->display, winId(), QApplication::desktop()->screen(d->xinfo.screen())->winId(), p.x(), p.y(), &x, &y, &child); return QPoint(x, y);}/*! Translates the global screen coordinate \a pos to widget coordinates. \sa mapToGlobal() mapFrom() mapFromParent()*/QPoint QWidget::mapFromGlobal(const QPoint &pos) const{ Q_D(const QWidget); int x, y; Window child; XTranslateCoordinates(X11->display, QApplication::desktop()->screen(d->xinfo.screen())->winId(), winId(), pos.x(), pos.y(), &x, &y, &child); return d->mapFromWS(QPoint(x, y));}void QWidgetPrivate::updateSystemBackground(){ Q_Q(QWidget); QBrush brush = q->palette().brush(QPalette::Active, q->backgroundRole()); Qt::WindowType type = q->windowType(); if (brush.style() == Qt::NoBrush || q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_UpdatesDisabled) || type == Qt::Popup || type == Qt::ToolTip ) XSetWindowBackgroundPixmap(X11->display, q->winId(), XNone); else if (brush.style() == Qt::SolidPattern && brush.isOpaque()) XSetWindowBackground(X11->display, q->winId(), QColormap::instance(xinfo.screen()).pixel(brush.color())); else if (isBackgroundInherited()) XSetWindowBackgroundPixmap(X11->display, q->winId(), ParentRelative); else if (brush.style() == Qt::TexturePattern) XSetWindowBackgroundPixmap(X11->display, q->winId(), brush.texture().data->x11ConvertToDefaultDepth()); else XSetWindowBackground(X11->display, q->winId(), QColormap::instance(xinfo.screen()).pixel(brush.color()));}void QWidget::setCursor(const QCursor &cursor){ Q_D(QWidget); if (cursor.shape() != Qt::ArrowCursor || (d->extra && d->extra->curs)) { d->createExtra(); delete d->extra->curs; d->extra->curs = new QCursor(cursor); } setAttribute(Qt::WA_SetCursor); qt_x11_enforce_cursor(this); XFlush(X11->display);}void QWidget::unsetCursor(){ Q_D(QWidget); if (d->extra) { delete d->extra->curs; d->extra->curs = 0; } if (!isWindow()) setAttribute(Qt::WA_SetCursor, false); qt_x11_enforce_cursor(this); XFlush(X11->display);}static XTextProperty*qstring_to_xtp(const QString& s){ static XTextProperty tp = { 0, 0, 0, 0 }; static bool free_prop = true; // we can't free tp.value in case it references // the data of the static QCString below. if (tp.value) { if (free_prop) XFree(tp.value); tp.value = 0; free_prop = true; } static const QTextCodec* mapper = QTextCodec::codecForLocale(); int errCode = 0; if (mapper) { QByteArray mapped = mapper->fromUnicode(s); char* tl[2]; tl[0] = mapped.data(); tl[1] = 0; errCode = XmbTextListToTextProperty(X11->display, tl, 1, XStdICCTextStyle, &tp);#if defined(QT_DEBUG) if (errCode < 0) qDebug("qstring_to_xtp result code %d", errCode);#endif } if (!mapper || errCode < 0) { static QByteArray qcs; qcs = s.toAscii(); tp.value = (uchar*)qcs.data(); tp.encoding = XA_STRING; tp.format = 8; tp.nitems = qcs.length(); free_prop = false; } // ### If we knew WM could understand unicode, we could use // ### a much simpler, cheaper encoding... /* tp.value = (XChar2b*)s.unicode(); tp.encoding = XA_UNICODE; // wish tp.format = 16; tp.nitems = s.length(); */ return &tp;}void QWidgetPrivate::setWindowTitle_sys(const QString &caption){ Q_Q(QWidget); XSetWMName(X11->display, q->winId(), qstring_to_xtp(caption)); QByteArray net_wm_name = caption.toUtf8(); XChangeProperty(X11->display, q->winId(), ATOM(_NET_WM_NAME), ATOM(UTF8_STRING), 8, PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());}void QWidgetPrivate::setWindowIcon_sys(bool forceReset){ Q_Q(QWidget); QTLWExtra *topData = extra->topextra; if (topData->iconPixmap && !forceReset) // already been set return; XWMHints *h = XGetWMHints(X11->display, q->winId()); XWMHints wm_hints; if (!h) { h = &wm_hints; h->flags = 0; } QIcon icon = q->windowIcon(); QSize size = icon.actualSize(QSize(64, 64)); if (!icon.isNull() && !size.isEmpty()) { QPixmap pixmap = icon.pixmap(size); // set the _NET_WM_ICON property QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32); QVector<long> icon_data(2 + image.width()*image.height()); icon_data[0] = image.width(); icon_data[1] = image.height(); if (sizeof(long) == sizeof(quint32)) { memcpy(icon_data.data() + 2, image.scanLine(0), image.numBytes()); } else { for (int y = 0; y < image.height(); ++y) { uint *scanLine = reinterpret_cast<uint *>(image.scanLine(y)); for (int x = 0; x < image.width(); ++x) icon_data[2 + y*image.width() + x] = scanLine[x]; } } XChangeProperty(X11->display, q->winId(), ATOM(_NET_WM_ICON), XA_CARDINAL, 32, PropModeReplace, (unsigned char *) icon_data.data(), icon_data.size()); /* if the app is not using the default visual, convert the icon to 1bpp as stated in the ICCCM section 4.1.2.4; otherwise, create the icon pixmap in the default depth (even though this violates the ICCCM) */ if (!QX11Info::appDefaultVisual(xinfo.screen())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -