all repos — fluxbox @ d77de67332b95f5fec7a6a8de703b2a57c8d67aa

custom fork of the fluxbox windowmanager

fix KDE dockapps on restart
simonb simonb
commit

d77de67332b95f5fec7a6a8de703b2a57c8d67aa

parent

538e33fedb8ea0730b17c6f92e9f3e4705343ca6

3 files changed, 87 insertions(+), 46 deletions(-)

jump to
M ChangeLogChangeLog

@@ -1,5 +1,8 @@

(Format: Year/Month/Day) Changes for 1.0.0: +*07/08/06: + * Fix KDE Dockapps on restart (dont unmap), and some minor tweaks (Simon) + SystemTray.hh/cc *07/08/05: * When saving window info for rememberm use class name AND instance name, AND role if present. (Simon)
M src/SystemTray.ccsrc/SystemTray.cc

@@ -49,11 +49,12 @@

/// helper class for tray windows, so we dont call XDestroyWindow class TrayWindow: public FbTk::FbWindow { public: - TrayWindow(Window win):FbTk::FbWindow(win), m_visible(false) { + TrayWindow(Window win, bool using_xembed):FbTk::FbWindow(win), m_visible(false), m_xembedded(using_xembed) { setEventMask(PropertyChangeMask); } bool isVisible() { return m_visible; } + bool isXEmbedded() { return m_xembedded; } void show() { if (!m_visible) { m_visible = true;

@@ -67,8 +68,33 @@ FbTk::FbWindow::hide();

} } +/* Flags for _XEMBED_INFO */ +#define XEMBED_MAPPED (1 << 0) + + bool getMappedDefault() const { + Atom actual_type; + int actual_format; + unsigned long nitems, bytes_after; + unsigned long *prop; + bool mapped = false; + Atom embed_info = SystemTray::getXEmbedInfoAtom(); + if (property(embed_info, 0l, 2l, false, embed_info, + &actual_type, &actual_format, &nitems, &bytes_after, + (unsigned char **) &prop) && prop != 0) { + mapped = (bool)(static_cast<unsigned long>(prop[1]) & XEMBED_MAPPED); + XFree(static_cast<void *>(prop)); + +#ifdef DEBUG + cerr<<__FILE__<<"(SystemTray::TrayWindow::getMappedDefault(): XEMBED_MAPPED = "<<mapped<<endl; +#endif // DEBUG + + } + return true; + } + private: bool m_visible; + bool m_xembedded; // using xembed protocol? (i.e. unmap when done) }; /// handles clientmessage event and notifies systemtray

@@ -104,7 +130,7 @@ if (winclient.screenNumber() != m_tray.window().screenNumber())

return; winclient.setEventMask(StructureNotifyMask | SubstructureNotifyMask | EnterWindowMask); - m_tray.addClient(winclient.window()); + m_tray.addClient(winclient.window(), false); };

@@ -183,7 +209,7 @@ ce.xclient.window = root_window;

ce.xclient.format = 32; ce.xclient.data.l[0] = CurrentTime; // timestamp ce.xclient.data.l[1] = tray_atom; // manager selection atom - ce.xclient.data.l[2] = m_window.window(); // the window owning the selection + ce.xclient.data.l[2] = m_selection_owner.window(); // the window owning the selection ce.xclient.data.l[3] = 0l; // selection specific data ce.xclient.data.l[4] = 0l; // selection specific data

@@ -275,9 +301,9 @@ bool SystemTray::clientMessage(const XClientMessageEvent &event) {

static const int SYSTEM_TRAY_REQUEST_DOCK = 0; // static const int SYSTEM_TRAY_BEGIN_MESSAGE = 1; // static const int SYSTEM_TRAY_CANCEL_MESSAGE = 2; + static Atom systray_opcode_atom = XInternAtom(FbTk::App::instance()->display(), "_NET_SYSTEM_TRAY_OPCODE", False); - if (event.message_type == - XInternAtom(FbTk::App::instance()->display(), "_NET_SYSTEM_TRAY_OPCODE", False)) { + if (event.message_type == systray_opcode_atom) { int type = event.data.l[1]; if (type == SYSTEM_TRAY_REQUEST_DOCK) {

@@ -285,7 +311,7 @@ #ifdef DEBUG

cerr<<"SystemTray::clientMessage(const XClientMessageEvent): SYSTEM_TRAY_REQUEST_DOCK"<<endl; cerr<<"window = event.data.l[2] = "<<event.data.l[2]<<endl; #endif // DEBUG - addClient(event.data.l[2]); + addClient(event.data.l[2], true); } /* else if (type == SYSTEM_TRAY_BEGIN_MESSAGE)

@@ -312,7 +338,7 @@

return it; } -void SystemTray::addClient(Window win) { +void SystemTray::addClient(Window win, bool using_xembed) { if (win == 0) return;

@@ -320,17 +346,17 @@ ClientList::iterator it = findClient(win);

if (it != m_clients.end()) return; + Display *disp = Fluxbox::instance()->display(); // make sure we have the same screen number XWindowAttributes attr; attr.screen = 0; - if (XGetWindowAttributes(FbTk::App::instance()->display(), - win, &attr) != 0 && + if (XGetWindowAttributes(disp, win, &attr) != 0 && attr.screen != 0 && XScreenNumberOfScreen(attr.screen) != window().screenNumber()) { return; } - TrayWindow *traywin = new TrayWindow(win); + TrayWindow *traywin = new TrayWindow(win, using_xembed); #ifdef DEBUG cerr<<"SystemTray::addClient(Window): 0x"<<hex<<win<<dec<<endl;

@@ -338,10 +364,31 @@ #endif // DEBUG

m_clients.push_back(traywin); FbTk::EventManager::instance()->add(*this, win); - XChangeSaveSet(FbTk::App::instance()->display(), win, SetModeInsert); traywin->reparent(m_window, 0, 0); traywin->addToSaveSet(); - showClient(traywin); + + if (using_xembed) { + static Atom xembed_atom = XInternAtom(disp, "_XEMBED", False); + +#define XEMBED_EMBEDDED_NOTIFY 0 + // send embedded message + XEvent ce; + ce.xclient.type = ClientMessage; + ce.xclient.message_type = xembed_atom; + ce.xclient.display = disp; + ce.xclient.window = win; + ce.xclient.format = 32; + ce.xclient.data.l[0] = CurrentTime; // timestamp + ce.xclient.data.l[1] = XEMBED_EMBEDDED_NOTIFY; + ce.xclient.data.l[2] = 0l; // The protocol version we support + ce.xclient.data.l[3] = m_window.window(); // the window owning the selection + ce.xclient.data.l[4] = 0l; // unused + + XSendEvent(disp, win, false, NoEventMask, &ce); + } + + if (traywin->getMappedDefault()) + showClient(traywin); } void SystemTray::removeClient(Window win, bool destroyed) {

@@ -404,36 +451,15 @@

} else if (event.type == PropertyNotify) { ClientList::iterator it = findClient(event.xproperty.window); if (it != m_clients.end()) { - Atom embed_info = XInternAtom(FbTk::App::instance()->display(),"_XEMBED_INFO",false); - if (event.xproperty.atom == embed_info) { - -/* Flags for _XEMBED_INFO */ -#define XEMBED_MAPPED (1 << 0) - - TrayWindow *traywin = *it; - Atom actual_type; - int actual_format; - unsigned long nitems, bytes_after; - unsigned long *prop; - if (traywin->property(embed_info, 0l, 2l, false, embed_info, - &actual_type, &actual_format, &nitems, &bytes_after, - (unsigned char **) &prop)) { - - bool mapped = (bool)(static_cast<unsigned long>(prop[1]) & XEMBED_MAPPED); - XFree(static_cast<void *>(prop)); - -#ifdef DEBUG - cerr<<__FILE__<<"(SystemTray::handleEvent(XEvent)): XEMBED_MAPPED = "<<mapped<<endl; -#endif // DEBUG - - if (mapped) - showClient(traywin); - else - hideClient(traywin); - } + if (event.xproperty.atom == getXEmbedInfoAtom()) { + if ((*it)->getMappedDefault()) + showClient(*it); + else + hideClient(*it); } } - } + } + } void SystemTray::rearrangeClients() {

@@ -465,12 +491,16 @@

void SystemTray::removeAllClients() { BScreen *screen = Fluxbox::instance()->findScreen(window().screenNumber()); while (!m_clients.empty()) { - m_clients.back()->setEventMask(NoEventMask); - m_clients.back()->hide(); + TrayWindow * traywin = m_clients.back(); + traywin->setEventMask(NoEventMask); + + if (traywin->isXEmbedded()) + traywin->hide(); + if (screen) - m_clients.back()->reparent(screen->rootWindow(), 0, 0); - m_clients.back()->removeFromSaveSet(); - delete m_clients.back(); + traywin->reparent(screen->rootWindow(), 0, 0, false); + traywin->removeFromSaveSet(); + delete traywin; m_clients.pop_back(); } m_num_visible_clients = 0;

@@ -524,3 +554,8 @@ (*client_it)->show();

} } + +Atom SystemTray::getXEmbedInfoAtom() { +static Atom theatom = XInternAtom(Fluxbox::instance()->display(), "_XEMBED_INFO", False); +return theatom; +}
M src/SystemTray.hhsrc/SystemTray.hh

@@ -59,7 +59,7 @@ bool clientMessage(const XClientMessageEvent &event);

void exposeEvent(XExposeEvent &event); void handleEvent(XEvent &event); - void addClient(Window win); + void addClient(Window win, bool using_xembed); void removeClient(Window win, bool destroyed); unsigned int width() const;

@@ -73,6 +73,8 @@ inline void renderTheme(unsigned char alpha) { m_window.setAlpha(alpha); update(0); }

inline void updateSizing() {} void parentMoved() { m_window.parentMoved(); } + + static Atom getXEmbedInfoAtom(); private:

@@ -99,6 +101,7 @@

// gaim/pidgin seems to barf if the selection is not an independent window. // I suspect it's an interacton with parent relationship and gdk window caching. FbTk::FbWindow m_selection_owner; + }; #endif // SYSTEMTRAY_HH