18#include <X11/cursorfont.h>
21#include <xcb/xcb_keysyms.h>
53 m_active = activate(cursorName);
58 m_callback = callback;
64 callback(QPoint(-1, -1));
68 m_active = activate();
70 callback(QPoint(-1, -1));
73 m_pointSelectionFallback = callback;
76bool WindowSelector::activate(
const QByteArray &cursorName)
78 xcb_cursor_t cursor = createCursor(cursorName);
81 UniqueCPtr<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),
nullptr));
82 if (!grabPointer || grabPointer->status != XCB_GRAB_STATUS_SUCCESS) {
89 xcb_ungrab_pointer(
connection(), XCB_TIME_CURRENT_TIME);
94xcb_cursor_t WindowSelector::createCursor(
const QByteArray &cursorName)
96 if (cursorName.isEmpty()) {
100 if (cursor != XCB_CURSOR_NONE) {
103 if (cursorName == QByteArrayLiteral(
"pirate")) {
105 static xcb_cursor_t kill_cursor = XCB_CURSOR_NONE;
106 if (kill_cursor != XCB_CURSOR_NONE) {
111 const xcb_font_t cursorFont = xcb_generate_id(c);
112 xcb_open_font(c, cursorFont, strlen(
"cursor"),
"cursor");
113 cursor = xcb_generate_id(c);
114 xcb_create_glyph_cursor(c, cursor, cursorFont, cursorFont,
118 kill_cursor = cursor;
125 if (
event->response_type == XCB_BUTTON_RELEASE) {
126 xcb_button_release_event_t *buttonEvent =
reinterpret_cast<xcb_button_release_event_t *
>(
event);
127 handleButtonRelease(buttonEvent->detail, buttonEvent->child);
128 }
else if (
event->response_type == XCB_KEY_PRESS) {
129 xcb_key_press_event_t *keyEvent =
reinterpret_cast<xcb_key_press_event_t *
>(
event);
130 handleKeyPress(keyEvent->detail, keyEvent->state);
144void WindowSelector::handleButtonRelease(xcb_button_t button, xcb_window_t window)
146 if (button == XCB_BUTTON_INDEX_3) {
151 if (button == XCB_BUTTON_INDEX_1 || button == XCB_BUTTON_INDEX_2) {
153 selectWindowId(window);
154 }
else if (m_pointSelectionFallback) {
162void WindowSelector::handleKeyPress(xcb_keycode_t keycode, uint16_t state)
165 xcb_keysym_t kc = xcb_key_symbols_get_keysym(symbols, keycode, 0);
168 const bool returnPressed = (kc == XK_Return) || (kc == XK_space);
169 const bool escapePressed = (kc == XK_Escape);
173 if (kc == XK_Right) {
182 if (state & XCB_MOD_MASK_CONTROL) {
189 selectWindowUnderPointer();
190 }
else if (m_pointSelectionFallback) {
194 if (returnPressed || escapePressed) {
200 xcb_key_symbols_free(symbols);
203void WindowSelector::selectWindowUnderPointer()
206 if (!pointer.isNull() && pointer->child != XCB_WINDOW_NONE) {
207 selectWindowId(pointer->child);
211void WindowSelector::release()
214 xcb_ungrab_pointer(
connection(), XCB_TIME_CURRENT_TIME);
217 m_callback = std::function<void(KWin::Window *)>();
218 m_pointSelectionFallback = std::function<void(const QPointF &)>();
221void WindowSelector::selectWindowId(xcb_window_t window_to_select)
223 if (window_to_select == XCB_WINDOW_NONE) {
227 xcb_window_t window = window_to_select;
228 X11Window *client =
nullptr;
234 Xcb::Tree tree(window);
235 if (window == tree->root) {
239 window = tree->parent;
248void WindowSelector::cancelCallback()
252 }
else if (m_pointSelectionFallback) {
253 m_pointSelectionFallback(QPoint(-1, -1));
xcb_cursor_t x11Cursor(CursorShape shape)
void setPos(const QPointF &pos)
void start(std::function< void(KWin::Window *)> callback, const QByteArray &cursorName)
void processEvent(xcb_generic_event_t *event)
bool event(xcb_generic_event_t *event) override
~WindowSelector() override
X11Window * findClient(std::function< bool(const X11Window *)> func) const
Finds the first Client matching the condition expressed by passed in func.
static Workspace * self()
KWIN_EXPORT xcb_window_t rootWindow()
KWIN_EXPORT xcb_connection_t * connection()
void KWIN_EXPORT ungrabXKeyboard()
void KWIN_EXPORT grabXServer()
void KWIN_EXPORT ungrabXServer()
bool KWIN_EXPORT grabXKeyboard(xcb_window_t w=XCB_WINDOW_NONE)
std::unique_ptr< T, CDeleter > UniqueCPtr
struct _XCBKeySymbols xcb_key_symbols_t