kwin: Port Client::embedClient() to xcb
This commit is contained in:
parent
c679ec6508
commit
19aaf48a02
1 changed files with 56 additions and 38 deletions
94
manage.cpp
94
manage.cpp
|
@ -617,48 +617,66 @@ void Client::embedClient(Window w, const XWindowAttributes& attr)
|
||||||
assert(wrapper == None);
|
assert(wrapper == None);
|
||||||
client = w;
|
client = w;
|
||||||
|
|
||||||
// We don't want the window to be destroyed when we are destroyed
|
const xcb_visualid_t visualid = XVisualIDFromVisual(attr.visual);
|
||||||
XAddToSaveSet(display(), client);
|
const uint32_t zero_value = 0;
|
||||||
XSelectInput(display(), client, NoEventMask);
|
|
||||||
XUnmapWindow(display(), client);
|
|
||||||
XWindowChanges wc; // Set the border width to 0
|
|
||||||
wc.border_width = 0; // TODO: Possibly save this, and also use it for initial configuring of the window
|
|
||||||
XConfigureWindow(display(), client, CWBorderWidth, &wc);
|
|
||||||
|
|
||||||
XSetWindowAttributes swa;
|
xcb_connection_t *conn = connection();
|
||||||
swa.colormap = attr.colormap;
|
|
||||||
swa.background_pixmap = None;
|
// We don't want the window to be destroyed when we quit
|
||||||
swa.border_pixel = 0;
|
xcb_change_save_set(conn, XCB_SET_MODE_INSERT, client);
|
||||||
|
|
||||||
|
xcb_change_window_attributes(conn, client, XCB_CW_EVENT_MASK, &zero_value);
|
||||||
|
xcb_unmap_window(conn, client);
|
||||||
|
xcb_configure_window(conn, client, XCB_CONFIG_WINDOW_BORDER_WIDTH, &zero_value);
|
||||||
|
|
||||||
|
// Note: These values must match the order in the xcb_cw_t enum
|
||||||
|
const uint32_t cw_values[] = {
|
||||||
|
0, // back_pixmap
|
||||||
|
0, // border_pixel
|
||||||
|
attr.colormap, // colormap
|
||||||
|
QCursor(Qt::ArrowCursor).handle() // cursor
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint32_t cw_mask = XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL |
|
||||||
|
XCB_CW_COLORMAP | XCB_CW_CURSOR;
|
||||||
|
|
||||||
|
const uint32_t common_event_mask = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
|
||||||
|
XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
|
||||||
|
XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
|
||||||
|
XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_POINTER_MOTION |
|
||||||
|
XCB_EVENT_MASK_KEYMAP_STATE |
|
||||||
|
XCB_EVENT_MASK_FOCUS_CHANGE |
|
||||||
|
XCB_EVENT_MASK_EXPOSURE |
|
||||||
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
|
||||||
|
|
||||||
|
const uint32_t frame_event_mask = common_event_mask | XCB_EVENT_MASK_PROPERTY_CHANGE;
|
||||||
|
const uint32_t wrapper_event_mask = common_event_mask | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY;
|
||||||
|
|
||||||
|
const uint32_t client_event_mask = XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE |
|
||||||
|
XCB_EVENT_MASK_COLOR_MAP_CHANGE |
|
||||||
|
XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
|
||||||
|
XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE;
|
||||||
|
|
||||||
|
// Create the frame window
|
||||||
|
xcb_window_t frame = xcb_generate_id(conn);
|
||||||
|
xcb_create_window(conn, attr.depth, frame, rootWindow(), 0, 0, 1, 1, 0,
|
||||||
|
XCB_WINDOW_CLASS_INPUT_OUTPUT, visualid, cw_mask, cw_values);
|
||||||
|
|
||||||
Window frame = XCreateWindow(display(), rootWindow(), 0, 0, 1, 1, 0,
|
|
||||||
attr.depth, InputOutput, attr.visual, CWColormap | CWBackPixmap | CWBorderPixel, &swa);
|
|
||||||
setWindowHandles(client, frame);
|
setWindowHandles(client, frame);
|
||||||
wrapper = XCreateWindow(display(), frame, 0, 0, 1, 1, 0,
|
|
||||||
attr.depth, InputOutput, attr.visual, CWColormap | CWBackPixmap | CWBorderPixel, &swa);
|
|
||||||
|
|
||||||
XDefineCursor(display(), frame, QCursor(Qt::ArrowCursor).handle());
|
// Create the wrapper window
|
||||||
// Some apps are stupid and don't define their own cursor - set the arrow one for them
|
wrapper = xcb_generate_id(conn);
|
||||||
XDefineCursor(display(), wrapper, QCursor(Qt::ArrowCursor).handle());
|
xcb_create_window(conn, attr.depth, wrapper, frame, 0, 0, 1, 1, 0,
|
||||||
XReparentWindow(display(), client, wrapper, 0, 0);
|
XCB_WINDOW_CLASS_INPUT_OUTPUT, visualid, cw_mask, cw_values);
|
||||||
XSelectInput(display(), frame,
|
|
||||||
KeyPressMask | KeyReleaseMask |
|
xcb_reparent_window(conn, client, wrapper, 0, 0);
|
||||||
ButtonPressMask | ButtonReleaseMask |
|
|
||||||
KeymapStateMask |
|
// We could specify the event masks when we create the windows, but the original
|
||||||
ButtonMotionMask |
|
// Xlib code didn't. Let's preserve that behavior here for now so we don't end up
|
||||||
PointerMotionMask |
|
// receiving any unexpected events from the wrapper creation or the reparenting.
|
||||||
EnterWindowMask | LeaveWindowMask |
|
xcb_change_window_attributes(conn, frame, XCB_CW_EVENT_MASK, &frame_event_mask);
|
||||||
FocusChangeMask |
|
xcb_change_window_attributes(conn, wrapper, XCB_CW_EVENT_MASK, &wrapper_event_mask);
|
||||||
ExposureMask |
|
xcb_change_window_attributes(conn, client, XCB_CW_EVENT_MASK, &client_event_mask);
|
||||||
PropertyChangeMask |
|
|
||||||
StructureNotifyMask | SubstructureRedirectMask);
|
|
||||||
XSelectInput(display(), wrapper, ClientWinMask | SubstructureNotifyMask);
|
|
||||||
XSelectInput(display(), client,
|
|
||||||
FocusChangeMask |
|
|
||||||
PropertyChangeMask |
|
|
||||||
ColormapChangeMask |
|
|
||||||
EnterWindowMask | LeaveWindowMask |
|
|
||||||
KeyPressMask | KeyReleaseMask
|
|
||||||
);
|
|
||||||
|
|
||||||
updateMouseGrab();
|
updateMouseGrab();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue