diff options
author | Ken Moore <ken@pcbsd.org> | 2015-03-27 10:46:49 -0400 |
---|---|---|
committer | Ken Moore <ken@pcbsd.org> | 2015-03-27 10:46:49 -0400 |
commit | 612cf467ce1571d71a8183a1adb0d682b9fe2bf7 (patch) | |
tree | 9d023b2db9bfd29957560b53067e1c690177666a | |
parent | Merge pull request #78 from Nanolx/master (diff) | |
download | lumina-612cf467ce1571d71a8183a1adb0d682b9fe2bf7.tar.gz lumina-612cf467ce1571d71a8183a1adb0d682b9fe2bf7.tar.bz2 lumina-612cf467ce1571d71a8183a1adb0d682b9fe2bf7.zip |
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.
-rw-r--r-- | libLumina/LuminaX11.cpp | 80 | ||||
-rw-r--r-- | libLumina/LuminaX11.h | 4 | ||||
-rw-r--r-- | libLumina/libLumina.pro | 2 | ||||
-rw-r--r-- | lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp | 4 | ||||
-rw-r--r-- | lumina-fm/MainUI.cpp | 1 |
5 files changed, 88 insertions, 3 deletions
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 <xcb/xcb_ewmh.h> #include <xcb/xcb_icccm.h> #include <xcb/xcb_image.h> +#include <xcb/composite.h> //===== 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 diff --git a/libLumina/LuminaX11.h b/libLumina/LuminaX11.h index 62146ebe..beedae36 100644 --- a/libLumina/LuminaX11.h +++ b/libLumina/LuminaX11.h @@ -152,6 +152,10 @@ public: void MaximizeWindow(WId win, bool flagsonly = false); //request that the window become maximized void MoveResizeWindow(WId win, QRect geom); + //Window Embedding/Detaching (for system tray) + bool EmbedWindow(WId win, WId container); + bool UnembedWindow(WId win); + }; #endif
\ No newline at end of file diff --git a/libLumina/libLumina.pro b/libLumina/libLumina.pro index e0963fc6..1b78367a 100644 --- a/libLumina/libLumina.pro +++ b/libLumina/libLumina.pro @@ -42,7 +42,7 @@ SOURCES += LuminaXDG.cpp \ INCLUDEPATH += $$PREFIX/include -LIBS += -lX11 -lXrender -lXcomposite -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image +LIBS += -lX11 -lXrender -lXcomposite -lxcb -lxcb-ewmh -lxcb-icccm -lxcb-image -lxcb-composite include.path=$$PREFIX/include/ include.files=LuminaXDG.h \ diff --git a/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp b/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp index e966f389..7f12bb52 100644 --- a/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp +++ b/lumina-desktop/panel-plugins/systemtray/TrayIcon.cpp @@ -39,7 +39,7 @@ void TrayIcon::attachApp(WId id){ AID = id; IID = this->winId(); //embed directly into this widget //IID = LX11::CreateWindow( this->winId(), this->rect() ); //Create an intermediate window to be the parent - if( LX11::EmbedWindow(AID, IID) ){ + if( LSession::handle()->XCB->EmbedWindow(AID, IID) ){ LX11::RestoreWindow(AID); //make it visible //XSelectInput(QX11Info::display(), AID, StructureNotifyMask); //xcb_damage_create(QX11Info::connection(), dmgID, AID, XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES); @@ -69,7 +69,7 @@ void TrayIcon::detachApp(){ AID = 0; //Now detach the application window and clean up qDebug() << " - Unembed"; - LX11::UnembedWindow(tmp); + LSession::handle()->XCB->UnembedWindow(tmp); //if(dmgID!=0){ //XDamageDestroy(QX11Info::display(), dmgID); //} diff --git a/lumina-fm/MainUI.cpp b/lumina-fm/MainUI.cpp index e14d16d0..604e4c9c 100644 --- a/lumina-fm/MainUI.cpp +++ b/lumina-fm/MainUI.cpp @@ -8,6 +8,7 @@ #include "ui_MainUI.h" #include <QImageWriter> +#include <QFileInfo> #define DEBUG 0 |