aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/FbTk/FbWindow.cc8
-rw-r--r--src/FbTk/FbWindow.hh3
-rw-r--r--src/SystemTray.cc47
-rw-r--r--src/SystemTray.hh8
-rw-r--r--src/fluxbox.cc2
5 files changed, 55 insertions, 13 deletions
diff --git a/src/FbTk/FbWindow.cc b/src/FbTk/FbWindow.cc
index 2c2bb24..f8141cf 100644
--- a/src/FbTk/FbWindow.cc
+++ b/src/FbTk/FbWindow.cc
@@ -556,6 +556,14 @@ void FbWindow::deleteProperty(Atom property) {
556 XDeleteProperty(display(), m_window, property); 556 XDeleteProperty(display(), m_window, property);
557} 557}
558 558
559void FbWindow::addToSaveSet() {
560 XAddToSaveSet(display(), m_window);
561}
562
563void FbWindow::removeFromSaveSet() {
564 XRemoveFromSaveSet(display(), m_window);
565}
566
559int FbWindow::screenNumber() const { 567int FbWindow::screenNumber() const {
560 return m_screen_num; 568 return m_screen_num;
561} 569}
diff --git a/src/FbTk/FbWindow.hh b/src/FbTk/FbWindow.hh
index a1b93cc..091fb48 100644
--- a/src/FbTk/FbWindow.hh
+++ b/src/FbTk/FbWindow.hh
@@ -165,6 +165,9 @@ public:
165 165
166 std::string textProperty(Atom property) const; 166 std::string textProperty(Atom property) const;
167 167
168 void addToSaveSet();
169 void removeFromSaveSet();
170
168 /// @return parent FbWindow 171 /// @return parent FbWindow
169 const FbWindow *parent() const { return m_parent; } 172 const FbWindow *parent() const { return m_parent; }
170 /// @return real X window 173 /// @return real X window
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}
diff --git a/src/SystemTray.hh b/src/SystemTray.hh
index 392ca11..557d1e4 100644
--- a/src/SystemTray.hh
+++ b/src/SystemTray.hh
@@ -60,7 +60,7 @@ public:
60 void handleEvent(XEvent &event); 60 void handleEvent(XEvent &event);
61 61
62 void addClient(Window win); 62 void addClient(Window win);
63 void removeClient(Window win); 63 void removeClient(Window win, bool destroyed);
64 64
65 unsigned int width() const; 65 unsigned int width() const;
66 unsigned int height() const; 66 unsigned int height() const;
@@ -83,7 +83,7 @@ private:
83 83
84 void rearrangeClients(); 84 void rearrangeClients();
85 void removeAllClients(); 85 void removeAllClients();
86 void hideClient(TrayWindow *traywin); 86 void hideClient(TrayWindow *traywin, bool destroyed = false);
87 void showClient(TrayWindow *traywin); 87 void showClient(TrayWindow *traywin);
88 88
89 FbTk::FbWindow m_window; 89 FbTk::FbWindow m_window;
@@ -95,6 +95,10 @@ private:
95 95
96 ClientList m_clients; 96 ClientList m_clients;
97 size_t m_num_visible_clients; 97 size_t m_num_visible_clients;
98
99 // gaim/pidgin seems to barf if the selection is not an independent window.
100 // I suspect it's an interacton with parent relationship and gdk window caching.
101 FbTk::FbWindow m_selection_owner;
98}; 102};
99 103
100#endif // SYSTEMTRAY_HH 104#endif // SYSTEMTRAY_HH
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index 248c897..80d055b 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -254,6 +254,7 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
254 SignalHandler &sigh = SignalHandler::instance(); 254 SignalHandler &sigh = SignalHandler::instance();
255 sigh.registerHandler(SIGSEGV, this); 255 sigh.registerHandler(SIGSEGV, this);
256 sigh.registerHandler(SIGFPE, this); 256 sigh.registerHandler(SIGFPE, this);
257 sigh.registerHandler(SIGPIPE, this); // e.g. output sent to grep
257 sigh.registerHandler(SIGTERM, this); 258 sigh.registerHandler(SIGTERM, this);
258 sigh.registerHandler(SIGINT, this); 259 sigh.registerHandler(SIGINT, this);
259 sigh.registerHandler(SIGCHLD, this); 260 sigh.registerHandler(SIGCHLD, this);
@@ -1059,6 +1060,7 @@ void Fluxbox::handleSignal(int signum) {
1059 break; 1060 break;
1060 case SIGFPE: 1061 case SIGFPE:
1061 case SIGINT: 1062 case SIGINT:
1063 case SIGPIPE:
1062 case SIGTERM: 1064 case SIGTERM:
1063 shutdown(); 1065 shutdown();
1064 break; 1066 break;