From 612cf467ce1571d71a8183a1adb0d682b9fe2bf7 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 27 Mar 2015 10:46:49 -0400 Subject: Update the system tray Embed/Unembed routines to use the XCB library instead of XLib. This bahaves exactly the same on my FreeBSD 10.x system - still need to test a FreeBSD 11.x system. --- libLumina/LuminaX11.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'libLumina/LuminaX11.cpp') diff --git a/libLumina/LuminaX11.cpp b/libLumina/LuminaX11.cpp index 43d4e577..65a2c9a7 100644 --- a/libLumina/LuminaX11.cpp +++ b/libLumina/LuminaX11.cpp @@ -26,6 +26,7 @@ #include #include #include +#include //===== WindowList() ======== @@ -1351,6 +1352,85 @@ void LXCB::MoveResizeWindow(WId win, QRect geom){ } +// === EmbedWindow() === +bool LXCB::EmbedWindow(WId win, WId container){ + if(win==0 || container==0){ return false; } + //Reparent the window + //XCompositeRedirectSubwindows(disp, container, CompositeRedirectAutomatic); //container/window should be aware of each other + //qDebug() << "Embed Window:" << win << container; + xcb_reparent_window(QX11Info::connection(), win, container, 0, 0); + //Map the window + xcb_map_window(QX11Info::connection(), win); + + //Initialize any atoms that will be needed + xcb_intern_atom_cookie_t acookie = xcb_intern_atom_unchecked(QX11Info::connection(), 0, 12, "_XEMBED_INFO"); + xcb_intern_atom_cookie_t ecookie = xcb_intern_atom_unchecked(QX11Info::connection(), 0, 7, "_XEMBED"); + + xcb_intern_atom_reply_t *areply = xcb_intern_atom_reply(QX11Info::connection(), acookie, NULL); + if(areply==0){ return false; } //unable to initialize the atom + xcb_atom_t embinfo = areply->atom; + free(areply); //done with this structure + + xcb_intern_atom_reply_t *ereply = xcb_intern_atom_reply(QX11Info::connection(), ecookie, NULL); + if(ereply==0){ return false; } //unable to initialize the atom + xcb_atom_t emb = ereply->atom; + free(ereply); //done with this structure + + //Check that the window has _XEMBED_INFO + //qDebug() << " - check for _XEMBED_INFO"; + xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(QX11Info::connection(), 0, win, embinfo, embinfo, 0, 2); + xcb_get_property_reply_t *reply = xcb_get_property_reply(QX11Info::connection(), cookie, NULL); + if(reply ==0 || reply->value_len<1){ + //Embed Error + if(reply!=0){ free(reply); } //done with the reply + return false; + } + free(reply); //done with the reply structure + + //Now send the embed event to the app + //qDebug() << " - send _XEMBED event"; + xcb_client_message_event_t event; + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; + event.window = win; + event.type = emb; //_XEMBED + event.data.data32[0] = CurrentTime; + event.data.data32[1] = 0; //XEMBED_EMBEDDED_NOTIFY + event.data.data32[2] = 0; + event.data.data32[3] = container; //WID of the container + event.data.data32[4] = 0; + + xcb_send_event(QX11Info::connection(), 0, win, XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *) &event); + + //Now setup any redirects and return + //qDebug() << " - select Input"; + //XSelectInput(disp, win, StructureNotifyMask); //Notify of structure changes + uint32_t val[] = {XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY}; + xcb_change_window_attributes(QX11Info::connection(), win, XCB_CW_EVENT_MASK, val); + //qDebug() << " - Composite Redirect"; + xcb_composite_redirect_window(QX11Info::connection(), win, XCB_COMPOSITE_REDIRECT_MANUAL); + + //qDebug() << " - Done"; + return true; +} + +// === Unembed Window() === +bool LXCB::UnembedWindow(WId win){ + //Display *disp = QX11Info::display(); + //Remove redirects + //XSelectInput(disp, win, NoEventMask); + uint32_t val[] = {XCB_EVENT_MASK_NO_EVENT}; + xcb_change_window_attributes(QX11Info::connection(), win, XCB_CW_EVENT_MASK, val); + //Make sure it is invisible + xcb_unmap_window(QX11Info::connection(), win); + //Reparent the window back to the root window + xcb_reparent_window(QX11Info::connection(), win, QX11Info::appRootWindow(), 0, 0); + return true; +} + + + + // === SetScreenWorkArea() === /*void LXCB::SetScreenWorkArea(unsigned int screen, QRect rect){ //This is only useful because Fluxbox does not set the _NET_WORKAREA root atom -- cgit From f6c1de2b36756803800199cf9c80a135de1a7a51 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 27 Mar 2015 14:29:03 -0400 Subject: Clean up a bit of the new XCB system tray embedding process. Still does not fix FreeBSD 11, but it is a lot more reliable now. --- libLumina/LuminaX11.cpp | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'libLumina/LuminaX11.cpp') diff --git a/libLumina/LuminaX11.cpp b/libLumina/LuminaX11.cpp index 65a2c9a7..ab992dc3 100644 --- a/libLumina/LuminaX11.cpp +++ b/libLumina/LuminaX11.cpp @@ -1358,27 +1358,29 @@ bool LXCB::EmbedWindow(WId win, WId container){ //Reparent the window //XCompositeRedirectSubwindows(disp, container, CompositeRedirectAutomatic); //container/window should be aware of each other //qDebug() << "Embed Window:" << win << container; - xcb_reparent_window(QX11Info::connection(), win, container, 0, 0); - //Map the window - xcb_map_window(QX11Info::connection(), win); + //Initialize any atoms that will be needed - xcb_intern_atom_cookie_t acookie = xcb_intern_atom_unchecked(QX11Info::connection(), 0, 12, "_XEMBED_INFO"); + //xcb_intern_atom_cookie_t acookie = xcb_intern_atom_unchecked(QX11Info::connection(), 0, 12, "_XEMBED_INFO"); xcb_intern_atom_cookie_t ecookie = xcb_intern_atom_unchecked(QX11Info::connection(), 0, 7, "_XEMBED"); - xcb_intern_atom_reply_t *areply = xcb_intern_atom_reply(QX11Info::connection(), acookie, NULL); + /*xcb_intern_atom_reply_t *areply = xcb_intern_atom_reply(QX11Info::connection(), acookie, NULL); if(areply==0){ return false; } //unable to initialize the atom xcb_atom_t embinfo = areply->atom; free(areply); //done with this structure - + */ xcb_intern_atom_reply_t *ereply = xcb_intern_atom_reply(QX11Info::connection(), ecookie, NULL); if(ereply==0){ return false; } //unable to initialize the atom xcb_atom_t emb = ereply->atom; free(ereply); //done with this structure + //Reparent the window into the container + xcb_reparent_window(QX11Info::connection(), win, container, 0, 0); + xcb_map_window(QX11Info::connection(), win); + //Check that the window has _XEMBED_INFO //qDebug() << " - check for _XEMBED_INFO"; - xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(QX11Info::connection(), 0, win, embinfo, embinfo, 0, 2); + /*xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(QX11Info::connection(), 0, win, embinfo, embinfo, 0, 2); xcb_get_property_reply_t *reply = xcb_get_property_reply(QX11Info::connection(), cookie, NULL); if(reply ==0 || reply->value_len<1){ //Embed Error @@ -1386,7 +1388,7 @@ bool LXCB::EmbedWindow(WId win, WId container){ return false; } free(reply); //done with the reply structure - +*/ //Now send the embed event to the app //qDebug() << " - send _XEMBED event"; xcb_client_message_event_t event; @@ -1410,6 +1412,9 @@ bool LXCB::EmbedWindow(WId win, WId container){ //qDebug() << " - Composite Redirect"; xcb_composite_redirect_window(QX11Info::connection(), win, XCB_COMPOSITE_REDIRECT_MANUAL); + //Now map the window (will be a transparent child of the container) + xcb_map_window(QX11Info::connection(), win); + //qDebug() << " - Done"; return true; } @@ -1428,6 +1433,21 @@ bool LXCB::UnembedWindow(WId win){ return true; } +// === GetTrayIconPixmap() === +/*QPixmap LXCB::SetTrayIconBackground(WId win, WId container, QSize size){ + //Get the image of the container, copy the tray image onto it, and re-draw the combined image onto the tray + xcb_pixmap_t back, fore; + xcb_create_pixmap(QX11Info::connection(), depth, back, container, size->width(), size->height()); + xcb_create_pixmap(QX11Info::connection(), depth, fore, win, size->width(), size->height()); + + //Copy the foreround pixmap onto the background pixmap + xcb_copy_area( QX11Info::connection(), win, container, GC, 0,0,0,0 size->width(), size->height()); + + + //Now free the pixmaps + xcb_free_pixmap(QX11Info::connection(), back); + xcb_free_pixmap(QX11Info::connection(), fore); +}*/ -- cgit From d1c12c2f13cdf7a318fa14f0f658e7d67bae3bc7 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 27 Mar 2015 15:00:30 -0400 Subject: Remove the XCB "WindowImage()" function from LuminaX11 - it is not working properly for some reason on FreeBSD11, and using the QScreen->grabWindow(ID) routine *does* work properly for some reason, so just use the Qt function instead from now on (maybe it has better fallback routines?). --- libLumina/LuminaX11.cpp | 57 ------------------------------------------------- 1 file changed, 57 deletions(-) (limited to 'libLumina/LuminaX11.cpp') diff --git a/libLumina/LuminaX11.cpp b/libLumina/LuminaX11.cpp index ab992dc3..51df70d5 100644 --- a/libLumina/LuminaX11.cpp +++ b/libLumina/LuminaX11.cpp @@ -1134,26 +1134,6 @@ QIcon LXCB::WindowIcon(WId win){ return icon; } -// === WindowImage() === -QPixmap LXCB::WindowImage(WId win){ - QPixmap pix; - - //First get the size of the window - xcb_get_geometry_cookie_t cookie = xcb_get_geometry_unchecked(QX11Info::connection(), win); - xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(QX11Info::connection(), cookie, NULL); - if(reply == 0){ return pix; } //could not determine window geometry - //Now get the image - xcb_image_t *img = xcb_image_get(QX11Info::connection(), win, 0, 0, reply->width, reply->height, (uint32_t) AllPlanes, XCB_IMAGE_FORMAT_Z_PIXMAP); - if(img!=0){ - //Now convert the image into a QPixmap - pix.convertFromImage( QImage( (const uchar*) img->data, img->width, img->height, img->stride, QImage::Format_ARGB32_Premultiplied) ); - //Clean up the xcb_image structure - xcb_image_destroy(img); - } - //Return the pixmap - return pix; -} - // === SetAsSticky() === void LXCB::SetAsSticky(WId win){ //Need to send a client message event for the window so the WM picks it up @@ -1355,20 +1335,11 @@ void LXCB::MoveResizeWindow(WId win, QRect geom){ // === EmbedWindow() === bool LXCB::EmbedWindow(WId win, WId container){ if(win==0 || container==0){ return false; } - //Reparent the window - //XCompositeRedirectSubwindows(disp, container, CompositeRedirectAutomatic); //container/window should be aware of each other //qDebug() << "Embed Window:" << win << container; - //Initialize any atoms that will be needed - //xcb_intern_atom_cookie_t acookie = xcb_intern_atom_unchecked(QX11Info::connection(), 0, 12, "_XEMBED_INFO"); xcb_intern_atom_cookie_t ecookie = xcb_intern_atom_unchecked(QX11Info::connection(), 0, 7, "_XEMBED"); - /*xcb_intern_atom_reply_t *areply = xcb_intern_atom_reply(QX11Info::connection(), acookie, NULL); - if(areply==0){ return false; } //unable to initialize the atom - xcb_atom_t embinfo = areply->atom; - free(areply); //done with this structure - */ xcb_intern_atom_reply_t *ereply = xcb_intern_atom_reply(QX11Info::connection(), ecookie, NULL); if(ereply==0){ return false; } //unable to initialize the atom xcb_atom_t emb = ereply->atom; @@ -1378,17 +1349,6 @@ bool LXCB::EmbedWindow(WId win, WId container){ xcb_reparent_window(QX11Info::connection(), win, container, 0, 0); xcb_map_window(QX11Info::connection(), win); - //Check that the window has _XEMBED_INFO - //qDebug() << " - check for _XEMBED_INFO"; - /*xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(QX11Info::connection(), 0, win, embinfo, embinfo, 0, 2); - xcb_get_property_reply_t *reply = xcb_get_property_reply(QX11Info::connection(), cookie, NULL); - if(reply ==0 || reply->value_len<1){ - //Embed Error - if(reply!=0){ free(reply); } //done with the reply - return false; - } - free(reply); //done with the reply structure -*/ //Now send the embed event to the app //qDebug() << " - send _XEMBED event"; xcb_client_message_event_t event; @@ -1433,23 +1393,6 @@ bool LXCB::UnembedWindow(WId win){ return true; } -// === GetTrayIconPixmap() === -/*QPixmap LXCB::SetTrayIconBackground(WId win, WId container, QSize size){ - //Get the image of the container, copy the tray image onto it, and re-draw the combined image onto the tray - xcb_pixmap_t back, fore; - xcb_create_pixmap(QX11Info::connection(), depth, back, container, size->width(), size->height()); - xcb_create_pixmap(QX11Info::connection(), depth, fore, win, size->width(), size->height()); - - //Copy the foreround pixmap onto the background pixmap - xcb_copy_area( QX11Info::connection(), win, container, GC, 0,0,0,0 size->width(), size->height()); - - - //Now free the pixmaps - xcb_free_pixmap(QX11Info::connection(), back); - xcb_free_pixmap(QX11Info::connection(), fore); -}*/ - - // === SetScreenWorkArea() === /*void LXCB::SetScreenWorkArea(unsigned int screen, QRect rect){ -- cgit