📄 qwidget_x11.cpp
字号:
e.xclient.message_type = ATOM(WM_CHANGE_STATE); e.xclient.display = X11->display; e.xclient.window = data->winid; e.xclient.format = 32; e.xclient.data.l[0] = IconicState; e.xclient.data.l[1] = 0; e.xclient.data.l[2] = 0; e.xclient.data.l[3] = 0; e.xclient.data.l[4] = 0; XSendEvent(X11->display, RootWindow(X11->display,d->xinfo.screen()), False, (SubstructureNotifyMask|SubstructureRedirectMask), &e); } else { setAttribute(Qt::WA_Mapped); XMapWindow(X11->display, winId()); } } needShow = false; } } data->window_state = newstate; if (needShow) show(); if (newstate & Qt::WindowActive) activateWindow(); QWindowStateChangeEvent e(oldstate); QApplication::sendEvent(this, &e);}/*! \internal Platform-specific part of QWidget::show().*/void QWidgetPrivate::show_sys(){ Q_Q(QWidget); if (q->isWindow()) { XWMHints *h = XGetWMHints(X11->display, q->winId()); XWMHints wm_hints; bool got_hints = h != 0; if (!got_hints) { h = &wm_hints; h->flags = 0; } h->initial_state = q->isMinimized() ? IconicState : NormalState; h->flags |= StateHint; XSetWMHints(X11->display, q->winId(), h); if (got_hints) XFree((char *)h); // udpate WM_TRANSIENT_FOR if (isTransient(q)) { QWidget *p = q->parentWidget(); if (p) p = p->window(); if (p) { // transient for window XSetTransientForHint(X11->display, q->winId(), p->winId()); } else { // transient for group XSetTransientForHint(X11->display, q->winId(), X11->wm_client_leader); } } // update _MOTIF_WM_HINTS QtMWMHints mwmhints = GetMWMHints(X11->display, q->winId()); if (data.window_modality != Qt::NonModal) { switch (data.window_modality) { case Qt::WindowModal: mwmhints.input_mode = MWM_INPUT_PRIMARY_APPLICATION_MODAL; break; case Qt::ApplicationModal: default: mwmhints.input_mode = MWM_INPUT_FULL_APPLICATION_MODAL; break; } mwmhints.flags |= MWM_HINTS_INPUT_MODE; } else { mwmhints.input_mode = MWM_INPUT_MODELESS; mwmhints.flags &= ~MWM_HINTS_INPUT_MODE; } if (q->minimumSize() == q->maximumSize()) { // fixed size, remove the resize handle (since mwm/dtwm // isn't smart enough to do it itself) mwmhints.flags |= MWM_HINTS_FUNCTIONS; if (mwmhints.functions == MWM_FUNC_ALL) { mwmhints.functions = (MWM_FUNC_MOVE | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_CLOSE); } else { mwmhints.functions &= ~MWM_FUNC_RESIZE; } mwmhints.flags |= MWM_HINTS_DECORATIONS; if (mwmhints.decorations == MWM_DECOR_ALL) { mwmhints.decorations = (MWM_DECOR_BORDER | MWM_DECOR_TITLE | MWM_DECOR_MENU | MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE); } else { mwmhints.decorations &= ~MWM_DECOR_RESIZEH; } } SetMWMHints(X11->display, q->winId(), mwmhints); // set _NET_WM_STATE Atom net_winstates[6] = { 0, 0, 0, 0, 0, 0 }; int curr_winstate = 0; Qt::WindowFlags flags = q->windowFlags(); if (flags & Qt::WindowStaysOnTopHint) { net_winstates[curr_winstate++] = ATOM(_NET_WM_STATE_ABOVE); net_winstates[curr_winstate++] = ATOM(_NET_WM_STATE_STAYS_ON_TOP); } if (q->isFullScreen()) { net_winstates[curr_winstate++] = ATOM(_NET_WM_STATE_FULLSCREEN); } if (q->isMaximized()) { net_winstates[curr_winstate++] = ATOM(_NET_WM_STATE_MAXIMIZED_HORZ); net_winstates[curr_winstate++] = ATOM(_NET_WM_STATE_MAXIMIZED_VERT); } if (data.window_modality != Qt::NonModal) { net_winstates[curr_winstate++] = ATOM(_NET_WM_STATE_MODAL); } if (curr_winstate > 0) { XChangeProperty(X11->display, q->winId(), ATOM(_NET_WM_STATE), XA_ATOM, 32, PropModeReplace, (unsigned char *) net_winstates, curr_winstate); } else { XDeleteProperty(X11->display, q->winId(), ATOM(_NET_WM_STATE)); } // set _NET_WM_USER_TIME if (X11->userTime != CurrentTime) { XChangeProperty(X11->display, q->winId(), ATOM(_NET_WM_USER_TIME), XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &X11->userTime, 1); } if (!topData()->embedded && (topData()->validWMState || topData()->waitingForMapNotify) && !q->isMinimized()) { X11->deferred_map.append(q); return; } if (q->isMaximized() && !q->isFullScreen() && !(qt_net_supports(ATOM(_NET_WM_STATE_MAXIMIZED_HORZ)) && qt_net_supports(ATOM(_NET_WM_STATE_MAXIMIZED_VERT)))) { XMapWindow(X11->display, q->winId()); qt_x11_wait_for_window_manager(q); // if the wm was not smart enough to adjust our size, do that manually updateFrameStrut(); QRect maxRect = QApplication::desktop()->availableGeometry(q); QTLWExtra *top = topData(); QRect normalRect = top->normalGeometry; q->setGeometry(maxRect.x() + top->fleft, maxRect.y() + top->ftop, maxRect.width() - top->fleft - top->fright, maxRect.height() - top->ftop - top->fbottom); // restore the original normalGeometry top->normalGeometry = normalRect; // internalSetGeometry() clears the maximized flag... make sure we set it back data.window_state = data.window_state | Qt::WindowMaximized; q->setAttribute(Qt::WA_Mapped); return; } if (q->isFullScreen() && !qt_net_supports(ATOM(_NET_WM_STATE_FULLSCREEN))) { XMapWindow(X11->display, q->winId()); qt_x11_wait_for_window_manager(q); q->setAttribute(Qt::WA_Mapped); return; } } invalidateBuffer(q->rect()); if (q->testAttribute(Qt::WA_OutsideWSRange)) return; q->setAttribute(Qt::WA_Mapped); if (q->isWindow()) topData()->waitingForMapNotify = 1; if (!q->isWindow() && (!q->autoFillBackground() || q->palette().brush(q->backgroundRole()).style() == Qt::LinearGradientPattern)) { XSetWindowBackgroundPixmap(X11->display, q->winId(), XNone); XMapWindow(X11->display, q->winId()); updateSystemBackground(); return; } XMapWindow(X11->display, q->winId()); // Freedesktop.org Startup Notification if (X11->startupId && q->isWindow()) { QByteArray message("remove: ID="); message.append(X11->startupId); sendStartupMessage(message.constData()); X11->startupId = 0; }}/*! \internal Platform-specific part of QWidget::show().*/void QWidgetPrivate::sendStartupMessage(const char *message) const{ Q_Q(const QWidget); if (!message) return; XEvent xevent; xevent.xclient.type = ClientMessage; xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO_BEGIN); xevent.xclient.display = X11->display; xevent.xclient.window = q->winId(); xevent.xclient.format = 8; Window rootWindow = RootWindow(X11->display, DefaultScreen(X11->display)); uint sent = 0; uint length = strlen(message) + 1; do { if (sent == 20) xevent.xclient.message_type = ATOM(_NET_STARTUP_INFO); for (uint i = 0; i < 20 && i + sent <= length; i++) xevent.xclient.data.b[i] = message[i + sent++]; XSendEvent(X11->display, rootWindow, false, PropertyChangeMask, &xevent); } while (sent <= length);}/*! \internal Platform-specific part of QWidget::hide().*/void QWidgetPrivate::hide_sys(){ Q_Q(QWidget); deactivateWidgetCleanup(); if (q->isWindow()) { X11->deferred_map.removeAll(q); if (q->winId()) // in nsplugin, may be 0 XWithdrawWindow(X11->display, q->winId(), xinfo.screen()); QTLWExtra *top = topData(); data.crect.moveTopLeft(QPoint(data.crect.x() - top->fleft, data.crect.y() - top->ftop)); // zero the frame strut and mark it dirty top->fleft = top->fright = top->ftop = top->fbottom = 0; data.fstrut_dirty = true; XFlush(X11->display); } else { invalidateBuffer(q->rect()); q->setAttribute(Qt::WA_Mapped, false); if (q->winId()) // in nsplugin, may be 0 XUnmapWindow(X11->display, q->winId()); }}void QWidgetPrivate::raise_sys(){ Q_Q(QWidget); XRaiseWindow(X11->display, q->winId()); if(!q->isWindow()) invalidateBuffer(q->rect());}void QWidgetPrivate::lower_sys(){ Q_Q(QWidget); XLowerWindow(X11->display, q->winId()); if(!q->isWindow()) invalidateBuffer(q->rect());}void QWidgetPrivate::stackUnder_sys(QWidget* w){ Q_Q(QWidget); Window stack[2]; stack[0] = w->winId();; stack[1] = q->winId(); XRestackWindows(X11->display, stack, 2); if(!q->isWindow()) invalidateBuffer(q->rect());}static void do_size_hints(QWidget* widget, QWExtra *x){ XSizeHints s; s.flags = 0; if (x) { s.x = widget->x(); s.y = widget->y(); s.width = widget->width(); s.height = widget->height(); if (x->minw > 0 || x->minh > 0) { // add minimum size hints s.flags |= PMinSize; s.min_width = qMin(XCOORD_MAX, x->minw); s.min_height = qMin(XCOORD_MAX, x->minh); } if (x->maxw < QWIDGETSIZE_MAX || x->maxh < QWIDGETSIZE_MAX) { // add maximum size hints s.flags |= PMaxSize; s.max_width = qMin(XCOORD_MAX, x->maxw); s.max_height = qMin(XCOORD_MAX, x->maxh); } if (x->topextra && (x->topextra->incw > 0 || x->topextra->inch > 0)) { // add resize increment hints s.flags |= PResizeInc | PBaseSize; s.width_inc = x->topextra->incw; s.height_inc = x->topextra->inch; s.base_width = x->topextra->basew; s.base_height = x->topextra->baseh; } if (x->topextra && x->topextra->uspos) { // user (i.e. command-line) specified position s.flags |= USPosition; s.flags |= PPosition; } if (x->topextra && x->topextra->ussize) { // user (i.e. command-line) specified size s.flags |= USSize; s.flags |= PSize; } } s.flags |= PWinGravity; s.win_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity; XSetWMNormalHints(X11->display, widget->winId(), &s);}/* Helper function for non-toplevel widgets. Helps to map Qt's 32bit coordinate system to X11's 16bit coordinate system. Sets the geometry of the widget to data.crect, but clipped to sizes that X can handle. Unmaps widgets that are completely outside the valid range. Maintains data.wrect, which is the geometry of the X widget, measured in this widget's coordinate system. if the parent is n
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -