⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qkeymapper_x11.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        // convert chars (8bit) to text (unicode).        if (mapper)            text = mapper->toUnicode(chars.data(), count, 0);        if (text.isEmpty()) {            // no mapper, or codec couldn't convert to unicode (this            // can happen when running in the C locale or with no LANG            // set). try converting from latin-1            text = QString::fromLatin1(chars);        }    }    modifiers = X11->translateModifiers(xmodifiers);    // Commentary in X11/keysymdef says that X codes match ASCII, so it    // is safe to use the locale functions to process X codes in ISO8859-1.    //    // This is mainly for compatibility - applications should not use the    // Qt keycodes between 128 and 255, but should rather use the    // QKeyEvent::text().    //    extern QTextCodec *qt_input_mapper; // from qapplication_x11.cpp    if (keysym < 128 || (keysym < 256 && (!qt_input_mapper || qt_input_mapper->mibEnum()==4))) {        // upper-case key, if known        code = isprint((int)keysym) ? toupper((int)keysym) : 0;    } else if (keysym >= XK_F1 && keysym <= XK_F35) {        // function keys        code = Qt::Key_F1 + ((int)keysym - XK_F1);    } else if (keysym >= XK_KP_Space && keysym <= XK_KP_9) {        if (keysym >= XK_KP_0) {            // numeric keypad keys            code = Qt::Key_0 + ((int)keysym - XK_KP_0);        } else {            code = translateKeySym(keysym);        }        modifiers |= Qt::KeypadModifier;    } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f && text.unicode()->unicode() != 0x7f && !(keysym >= XK_dead_grave && keysym <= XK_dead_horn)) {        code = text.unicode()->toUpper().unicode();    } else {        // any other keys        code = translateKeySym(keysym);        if (code == Qt::Key_Tab && (modifiers & Qt::ShiftModifier)) {            // map shift+tab to shift+backtab, QShortcutMap knows about it            // and will handle it.            code = Qt::Key_Backtab;            text = QString();        }    }    return text;}bool QKeyMapperPrivate::translateKeyEventInternal(QWidget *keyWidget,                                                  const XEvent *event,                                                  KeySym &keysym,                                                  int& count,                                                  QString& text,                                                  Qt::KeyboardModifiers &modifiers,                                                  int& code,                                                  QEvent::Type &type,                                                  bool statefulTranslation){    XKeyEvent xkeyevent = event->xkey;    int keycode = event->xkey.keycode;    // save the modifier state, we will use the keystate uint later by passing    // it to translateButtonState    uint keystate = event->xkey.state;    type = (event->type == XKeyPress) ? QEvent::KeyPress : QEvent::KeyRelease;    static int directionKeyEvent = 0;    static unsigned int lastWinId = 0;    extern bool qt_use_rtl_extensions; // from qapplication_x11.cpp    // translate pending direction change    if (statefulTranslation && qt_use_rtl_extensions && type == QEvent::KeyRelease) {        if (directionKeyEvent == Qt::Key_Direction_R || directionKeyEvent == Qt::Key_Direction_L) {            type = QEvent::KeyPress;            code = directionKeyEvent;            text = QString();            directionKeyEvent = 0;	    lastWinId = 0;            return true;        } else {            directionKeyEvent = 0;	    lastWinId = 0;        }    }    // some XmbLookupString implementations don't return buffer overflow correctly,    // so we increase the input buffer to allow for long strings...    // 256 chars * 2 bytes + 1 null-term == 513 bytes    QByteArray chars;    chars.resize(513);    count = XLookupString(&xkeyevent, chars.data(), chars.size(), &keysym, 0);    if (count && !keycode) {        extern int qt_ximComposingKeycode; // from qapplication_x11.cpp        keycode = qt_ximComposingKeycode;        qt_ximComposingKeycode = 0;    }    // translate the keysym + xmodifiers to Qt::Key_* + Qt::KeyboardModifiers    text = translateKeySym(keysym, keystate, code, modifiers, chars, count);    // Watch for keypresses and if its a key belonging to the Ctrl-Shift    // direction-changing accel, remember it.    // We keep track of those keys instead of using the event's state    // (to figure out whether the Ctrl modifier is held while Shift is pressed,    // or Shift is held while Ctrl is pressed) since the 'state' doesn't tell    // us whether the modifier held is Left or Right.    if (statefulTranslation && qt_use_rtl_extensions && type == QEvent::KeyPress) {        if (keysym == XK_Control_L || keysym == XK_Control_R            || keysym == XK_Shift_L || keysym == XK_Shift_R) {	    if (!directionKeyEvent) {		directionKeyEvent = keysym;		// This code exists in order to check that		// the event is occurred in the same widget.		lastWinId = keyWidget->internalWinId();	    }        } else {            // this can no longer be a direction-changing accel.            // if any other key was pressed.            directionKeyEvent = Qt::Key_Space;        }        if (directionKeyEvent && lastWinId == keyWidget->internalWinId()) {            if (keysym == XK_Shift_L && directionKeyEvent == XK_Control_L ||                keysym == XK_Control_L && directionKeyEvent == XK_Shift_L) {                directionKeyEvent = Qt::Key_Direction_L;            } else if (keysym == XK_Shift_R && directionKeyEvent == XK_Control_R ||                       keysym == XK_Control_R && directionKeyEvent == XK_Shift_R) {                directionKeyEvent = Qt::Key_Direction_R;            }        } else if (directionKeyEvent == Qt::Key_Direction_L                   || directionKeyEvent == Qt::Key_Direction_R) {            directionKeyEvent = Qt::Key_Space; // invalid        }    }    return true;}struct qt_auto_repeat_data{    // match the window and keycode with timestamp delta of 10 ms    Window window;    KeyCode keycode;    Time timestamp;    // queue scanner state    bool release;    bool error;};#if defined(Q_C_CALLBACKS)extern "C" {#endifstatic Bool qt_keypress_scanner(Display *, XEvent *event, XPointer arg){    if (event->type != XKeyPress && event->type != XKeyRelease)        return false;    qt_auto_repeat_data *data = (qt_auto_repeat_data *) arg;    if (data->error ||        event->xkey.window  != data->window ||        event->xkey.keycode != data->keycode)        return false;    if (event->type == XKeyPress) {        data->error = (! data->release || event->xkey.time - data->timestamp > 10);        return (! data->error);    }    // must be XKeyRelease event    if (data->release) {        // found a second release        data->error = true;        return false;    }    // found a single release    data->release = true;    data->timestamp = event->xkey.time;    return false;}static Bool qt_keyrelease_scanner(Display *, XEvent *event, XPointer arg){    const qt_auto_repeat_data *data = (const qt_auto_repeat_data *) arg;    return (event->type == XKeyRelease &&            event->xkey.window  == data->window &&            event->xkey.keycode == data->keycode);}#if defined(Q_C_CALLBACKS)}#endifbool QKeyMapperPrivate::translateKeyEvent(QWidget *keyWidget, const XEvent *event, bool grab){    int           code = -1;    int           count = 0;    Qt::KeyboardModifiers modifiers;    if (qt_sm_blockUserInput) // block user interaction during session management        return true;    Display *dpy = X11->display;    if (!keyWidget->isEnabled())        return true;    QEvent::Type type;    bool    autor = false;    QString text;    KeySym keysym = 0;    translateKeyEventInternal(keyWidget, event, keysym, count, text, modifiers, code, type);    // was this the last auto-repeater?    qt_auto_repeat_data auto_repeat_data;    auto_repeat_data.window = event->xkey.window;    auto_repeat_data.keycode = event->xkey.keycode;    auto_repeat_data.timestamp = event->xkey.time;    static uint curr_autorep = 0;    if (event->type == XKeyPress) {        if (curr_autorep == event->xkey.keycode) {            autor = true;            curr_autorep = 0;        }    } else {        // look ahead for auto-repeat        XEvent nextpress;        auto_repeat_data.release = true;        auto_repeat_data.error = false;        if (XCheckIfEvent(dpy, &nextpress, &qt_keypress_scanner,                          (XPointer) &auto_repeat_data)) {            autor = true;            // Put it back... we COULD send the event now and not need            // the static curr_autorep variable.            XPutBackEvent(dpy,&nextpress);        }        curr_autorep = autor ? event->xkey.keycode : 0;    }#if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)    // process accelerators before doing key compression    if (type == QEvent::KeyPress && !grab        && QApplicationPrivate::instance()->use_compat()) {        // send accel events if the keyboard is not grabbed        QKeyEventEx a(type, code, modifiers, text, autor, qMax(qMax(count,1), int(text.length())),                      event->xkey.keycode, keysym, event->xkey.state);        if (QApplicationPrivate::instance()->qt_tryAccelEvent(keyWidget, &a))            return true;    }#endif#ifndef QT_NO_IM    QInputContext *qic = keyWidget->inputContext();#endif    // compress keys    if (!text.isEmpty() && keyWidget->testAttribute(Qt::WA_KeyCompression) &&#ifndef QT_NO_IM        // Ordinary input methods require discrete key events to work        // properly, so key compression has to be disabled when input        // context exists.        //        // And further consideration, some complex input method        // require all key press/release events discretely even if        // the input method awares of key compression and compressed        // keys are ordinary alphabets. For example, the uim project        // is planning to implement "combinational shift" feature for        // a Japanese input method, uim-skk. It will work as follows.        //        // 1. press "r"        // 2. press "u"        // 3. release both "r" and "u" in arbitrary order        // 4. above key sequence generates "Ru"        //        // Of course further consideration about other participants        // such as key repeat mechanism is required to implement such        // feature.        !qic &&#endif // QT_NO_IM        // do not compress keys if the key event we just got above matches        // one of the key ranges used to compute stopCompression        !((code >= Qt::Key_Escape && code <= Qt::Key_SysReq)          || (code >= Qt::Key_Home && code <= Qt::Key_PageDown)          || (code >= Qt::Key_Super_L && code <= Qt::Key_Direction_R)          || (code == 0)          || (text.length() == 1 && text.unicode()->unicode() == '\n'))) {        // the widget wants key compression so it gets it        // sync the event queue, this makes key compress work better        XSync(dpy, false);        for (;;) {            XEvent        evRelease;            XEvent        evPress;            if (!XCheckTypedWindowEvent(dpy,event->xkey.window,                                        XKeyRelease,&evRelease))                break;            if (!XCheckTypedWindowEvent(dpy,event->xkey.window,                                        XKeyPress,&evPress)) {                XPutBackEvent(dpy, &evRelease);                break;            }            QString textIntern;            int codeIntern = -1;            int countIntern = 0;            Qt::KeyboardModifiers modifiersIntern;            QEvent::Type t;            KeySym keySymIntern;            translateKeyEventInternal(keyWidget, &evPress, keySymIntern, countIntern, textIntern,                                      modifiersIntern, codeIntern, t);            // use stopCompression to stop key compression for the following            // key event ranges:            bool stopCompression =                // 1) misc keys                (codeIntern >= Qt::Key_Escape && codeIntern <= Qt::Key_SysReq)                // 2) cursor movement                || (codeIntern >= Qt::Key_Home && codeIntern <= Qt::Key_PageDown)                // 3) extra keys                || (codeIntern >= Qt::Key_Super_L && codeIntern <= Qt::Key_Direction_R)                // 4) something that a) doesn't translate to text or b) translates                //    to newline text                || (codeIntern == 0)                || (textIntern.length() == 1 && textIntern.unicode()->unicode() == '\n');            if (modifiersIntern == modifiers && !textIntern.isEmpty() && !stopCompression) {                text += textIntern;                count += countIntern;            } else {                XPutBackEvent(dpy, &evPress);                XPutBackEvent(dpy, &evRelease);                break;            }        }    }    // autorepeat compression makes sense for all widgets (Windows    // does it automatically ....)    if (event->type == XKeyPress && text.length() <= 1#ifndef QT_NO_IM        // input methods need discrete key events        && !qic#endif// QT_NO_IM	) {        XEvent dummy;        for (;;) {            auto_repeat_data.release = false;            auto_repeat_data.error = false;            if (! XCheckIfEvent(dpy, &dummy, &qt_keypress_scanner,                                (XPointer) &auto_repeat_data))                break;            if (! XCheckIfEvent(dpy, &dummy, &qt_keyrelease_scanner,                                (XPointer) &auto_repeat_data))                break;            count++;            if (!text.isEmpty())                text += text[0];        }    }    return QKeyMapper::sendKeyEvent(keyWidget, grab, type, code, modifiers, text, autor,                                    qMax(qMax(count,1), int(text.length())),                                    event->xkey.keycode, keysym, event->xkey.state);}bool QKeyMapper::sendKeyEvent(QWidget *keyWidget, bool grab,                              QEvent::Type type, int code, Qt::KeyboardModifiers modifiers,                              const QString &text, bool autorepeat, int count,                              quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers){    // try the menukey first    if (type == QEvent::KeyPress && code == Qt::Key_Menu) {        QPoint pos = keyWidget->inputMethodQuery(Qt::ImMicroFocus).toRect().center();        QContextMenuEvent e(QContextMenuEvent::Keyboard, pos, keyWidget->mapToGlobal(pos));        qt_sendSpontaneousEvent(keyWidget, &e);        if(e.isAccepted())            return true;    }    Q_UNUSED(grab);    QKeyEventEx e(type, code, modifiers, text, autorepeat, qMax(qMax(count,1), int(text.length())),                  nativeScanCode, nativeVirtualKey, nativeModifiers);    return qt_sendSpontaneousEvent(keyWidget, &e);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -