bool App::nativeEvent(xcb_generic_event_t* event) { if ((event->response_type & ~0x80) == XCB_KEY_PRESS) { auto keypress = reinterpret_cast<xcb_key_press_event_t*>(event); if (keypress->event == QX11Info::appRootWindow()) { auto sym = xcb_key_press_lookup_keysym(m_syms, keypress, 0); uint state = keypress->state & USED_MASK; bool forward; if ((forward = m_triggersList.contains(qMakePair<uint, uint>(sym, state))) || m_triggersList.contains(qMakePair<uint, uint>(sym, state & (~XCB_MOD_MASK_SHIFT)))) { if (m_keyboardGrabbed) { ibus_panel_impanel_navigate(m_impanel, false, forward); } else { if (grabXKeyboard()) { ibus_panel_impanel_navigate(m_impanel, true, forward); } else { ibus_panel_impanel_move_next(m_impanel); } } } } } else if ((event->response_type & ~0x80) == XCB_KEY_RELEASE) { auto keyrelease = reinterpret_cast<xcb_key_release_event_t*>(event); if (keyrelease->event == QX11Info::appRootWindow()) { keyRelease(keyrelease); } } return false; }
void WindowSelector::start(std::function<void(KWin::Toplevel*)> callback, const QByteArray &cursorName) { xcb_cursor_t cursor = createCursor(cursorName); if (m_active) { callback(nullptr); return; } xcb_connection_t *c = connection(); ScopedCPointer<xcb_grab_pointer_reply_t> grabPointer(xcb_grab_pointer_reply(c, xcb_grab_pointer_unchecked(c, false, rootWindow(), XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_WINDOW_NONE, cursor, XCB_TIME_CURRENT_TIME), NULL)); if (grabPointer.isNull() || grabPointer->status != XCB_GRAB_STATUS_SUCCESS) { callback(nullptr); return; } m_active = grabXKeyboard(); if (!m_active) { xcb_ungrab_pointer(connection(), XCB_TIME_CURRENT_TIME); callback(nullptr); return; } grabXServer(); m_callback = callback; }
void KillWindow::start() { static Cursor kill_cursor = 0; if (!kill_cursor) kill_cursor = XCreateFontCursor(display(), XC_pirate); if (XGrabPointer(display(), rootWindow(), False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask, GrabModeAsync, GrabModeAsync, None, kill_cursor, CurrentTime) == GrabSuccess) { grabXKeyboard(); XEvent ev; int return_pressed = 0; int escape_pressed = 0; int button_released = 0; grabXServer(); while (!return_pressed && !escape_pressed && !button_released) { XMaskEvent(display(), KeyPressMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask, &ev); if (ev.type == KeyPress) { int kc = XKeycodeToKeysym(display(), ev.xkey.keycode, 0); int mx = 0; int my = 0; return_pressed = (kc == XK_Return) || (kc == XK_space); escape_pressed = (kc == XK_Escape); if (kc == XK_Left) mx = -10; if (kc == XK_Right) mx = 10; if (kc == XK_Up) my = -10; if (kc == XK_Down) my = 10; if (ev.xkey.state & ControlMask) { mx /= 10; my /= 10; } QCursor::setPos(cursorPos()+QPoint(mx, my)); } if (ev.type == ButtonRelease) { button_released = (ev.xbutton.button == Button1); if ( ev.xbutton.button == Button3 ) { escape_pressed = true; break; } if( ev.xbutton.button == Button1 || ev.xbutton.button == Button2 ) workspace->killWindowId(ev.xbutton.subwindow); } continue; } if (return_pressed) { Window root, child; int dummy1, dummy2, dummy3, dummy4; unsigned int dummy5; if( XQueryPointer( display(), rootWindow(), &root, &child, &dummy1, &dummy2, &dummy3, &dummy4, &dummy5 ) == true && child != None ) workspace->killWindowId( child ); } ungrabXServer(); ungrabXKeyboard(); XUngrabPointer(display(), CurrentTime); } }