aboutsummaryrefslogtreecommitdiff
path: root/src/SystemTray.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/SystemTray.cc')
-rw-r--r--src/SystemTray.cc47
1 files changed, 36 insertions, 11 deletions
diff --git a/src/SystemTray.cc b/src/SystemTray.cc
index fdccda0..00d9b11 100644
--- a/src/SystemTray.cc
+++ b/src/SystemTray.cc
@@ -52,6 +52,7 @@ public:
52 TrayWindow(Window win):FbTk::FbWindow(win), m_visible(false) { 52 TrayWindow(Window win):FbTk::FbWindow(win), m_visible(false) {
53 setEventMask(PropertyChangeMask); 53 setEventMask(PropertyChangeMask);
54 } 54 }
55
55 bool isVisible() { return m_visible; } 56 bool isVisible() { return m_visible; }
56 void show() { 57 void show() {
57 if (!m_visible) { 58 if (!m_visible) {
@@ -65,6 +66,7 @@ public:
65 FbTk::FbWindow::hide(); 66 FbTk::FbWindow::hide();
66 } 67 }
67 } 68 }
69
68private: 70private:
69 bool m_visible; 71 bool m_visible;
70}; 72};
@@ -132,9 +134,11 @@ SystemTray::SystemTray(const FbTk::FbWindow& parent, ButtonTheme& theme, BScreen
132 SubstructureNotifyMask | SubstructureRedirectMask), 134 SubstructureNotifyMask | SubstructureRedirectMask),
133 m_theme(theme), 135 m_theme(theme),
134 m_screen(screen), 136 m_screen(screen),
135 m_pixmap(0), m_num_visible_clients(0) { 137 m_pixmap(0), m_num_visible_clients(0),
136 138 m_selection_owner(m_window, 0, 0, 1, 1, SubstructureNotifyMask, false, false, CopyFromParent, InputOnly) {
139
137 FbTk::EventManager::instance()->add(*this, m_window); 140 FbTk::EventManager::instance()->add(*this, m_window);
141 FbTk::EventManager::instance()->add(*this, m_selection_owner);
138 m_theme.reconfigSig().attach(this); 142 m_theme.reconfigSig().attach(this);
139 screen.bgChangeSig().attach(this); 143 screen.bgChangeSig().attach(this);
140 144
@@ -162,7 +166,7 @@ SystemTray::SystemTray(const FbTk::FbWindow& parent, ButtonTheme& theme, BScreen
162 cerr<<__FILE__<<"(SystemTray(const FbTk::FbWindow)): SETTING OWNER!"<<endl; 166 cerr<<__FILE__<<"(SystemTray(const FbTk::FbWindow)): SETTING OWNER!"<<endl;
163#endif // DEBUG 167#endif // DEBUG
164 // set owner 168 // set owner
165 XSetSelectionOwner(disp, tray_atom, m_window.window(), CurrentTime); 169 XSetSelectionOwner(disp, tray_atom, m_selection_owner.window(), CurrentTime);
166 170
167 m_handler.reset(new SystemTrayHandler(*this)); 171 m_handler.reset(new SystemTrayHandler(*this));
168 172
@@ -190,7 +194,20 @@ SystemTray::SystemTray(const FbTk::FbWindow& parent, ButtonTheme& theme, BScreen
190 194
191SystemTray::~SystemTray() { 195SystemTray::~SystemTray() {
192 // remove us, else fluxbox might delete the memory too 196 // remove us, else fluxbox might delete the memory too
193 Fluxbox::instance()->removeAtomHandler(m_handler.get()); 197 Fluxbox* fluxbox = Fluxbox::instance();
198 fluxbox->removeAtomHandler(m_handler.get());
199 Display *disp = fluxbox->display();
200 // setup atom name to _NET_SYSTEM_TRAY_S<screen number>
201 char intbuff[16];
202 sprintf(intbuff, "%d", m_window.screenNumber());
203 string atom_name("_NET_SYSTEM_TRAY_S");
204 atom_name += intbuff; // append number
205
206 // get selection owner and see if it's free
207 Atom tray_atom = XInternAtom(disp, atom_name.c_str(), False);
208
209 // Properly give up selection.
210 XSetSelectionOwner(disp, tray_atom, None, CurrentTime);
194 removeAllClients(); 211 removeAllClients();
195 212
196 if (m_pixmap) 213 if (m_pixmap)
@@ -323,10 +340,11 @@ void SystemTray::addClient(Window win) {
323 FbTk::EventManager::instance()->add(*this, win); 340 FbTk::EventManager::instance()->add(*this, win);
324 XChangeSaveSet(FbTk::App::instance()->display(), win, SetModeInsert); 341 XChangeSaveSet(FbTk::App::instance()->display(), win, SetModeInsert);
325 traywin->reparent(m_window, 0, 0); 342 traywin->reparent(m_window, 0, 0);
343 traywin->addToSaveSet();
326 showClient(traywin); 344 showClient(traywin);
327} 345}
328 346
329void SystemTray::removeClient(Window win) { 347void SystemTray::removeClient(Window win, bool destroyed) {
330 ClientList::iterator tray_it = findClient(win); 348 ClientList::iterator tray_it = findClient(win);
331 if (tray_it == m_clients.end()) 349 if (tray_it == m_clients.end())
332 return; 350 return;
@@ -336,7 +354,11 @@ void SystemTray::removeClient(Window win) {
336#endif // DEBUG 354#endif // DEBUG
337 TrayWindow *traywin = *tray_it; 355 TrayWindow *traywin = *tray_it;
338 m_clients.erase(tray_it); 356 m_clients.erase(tray_it);
339 hideClient(traywin); 357 if (!destroyed) {
358 traywin->setEventMask(NoEventMask);
359 traywin->removeFromSaveSet();
360 }
361 hideClient(traywin, destroyed);
340 delete traywin; 362 delete traywin;
341} 363}
342 364
@@ -346,9 +368,9 @@ void SystemTray::exposeEvent(XExposeEvent &event) {
346 368
347void SystemTray::handleEvent(XEvent &event) { 369void SystemTray::handleEvent(XEvent &event) {
348 if (event.type == DestroyNotify) { 370 if (event.type == DestroyNotify) {
349 removeClient(event.xdestroywindow.window); 371 removeClient(event.xdestroywindow.window, true);
350 } else if (event.type == ReparentNotify && event.xreparent.parent != m_window.window()) { 372 } else if (event.type == ReparentNotify && event.xreparent.parent != m_window.window()) {
351 removeClient(event.xreparent.window); 373 removeClient(event.xreparent.window, false);
352 } else if (event.type == UnmapNotify && event.xany.send_event) { 374 } else if (event.type == UnmapNotify && event.xany.send_event) {
353 // we ignore server-generated events, which can occur 375 // we ignore server-generated events, which can occur
354 // on restart. The ICCCM says that a client must send 376 // on restart. The ICCCM says that a client must send
@@ -443,20 +465,23 @@ void SystemTray::rearrangeClients() {
443void SystemTray::removeAllClients() { 465void SystemTray::removeAllClients() {
444 BScreen *screen = Fluxbox::instance()->findScreen(window().screenNumber()); 466 BScreen *screen = Fluxbox::instance()->findScreen(window().screenNumber());
445 while (!m_clients.empty()) { 467 while (!m_clients.empty()) {
468 m_clients.back()->setEventMask(NoEventMask);
469 m_clients.back()->hide();
446 if (screen) 470 if (screen)
447 m_clients.back()->reparent(screen->rootWindow(), 0, 0); 471 m_clients.back()->reparent(screen->rootWindow(), 0, 0);
448 m_clients.back()->hide(); 472 m_clients.back()->removeFromSaveSet();
449 delete m_clients.back(); 473 delete m_clients.back();
450 m_clients.pop_back(); 474 m_clients.pop_back();
451 } 475 }
452 m_num_visible_clients = 0; 476 m_num_visible_clients = 0;
453} 477}
454 478
455void SystemTray::hideClient(TrayWindow *traywin) { 479void SystemTray::hideClient(TrayWindow *traywin, bool destroyed) {
456 if (!traywin || !traywin->isVisible()) 480 if (!traywin || !traywin->isVisible())
457 return; 481 return;
458 482
459 traywin->hide(); 483 if (!destroyed)
484 traywin->hide();
460 m_num_visible_clients--; 485 m_num_visible_clients--;
461 rearrangeClients(); 486 rearrangeClients();
462} 487}