Fix system tray restart issues
This commit is contained in:
parent
c144b7344d
commit
b273360331
7 changed files with 60 additions and 14 deletions
|
@ -1,5 +1,9 @@
|
|||
(Format: Year/Month/Day)
|
||||
Changes for 1.0.0:
|
||||
*07/08/05:
|
||||
* Fix System Tray restart issues (Simon)
|
||||
(including gaim/pidgin crash-on-restart)
|
||||
src/SystemTray.hh/cc src/FbTk/FbWindow.hh/cc
|
||||
*07/07/31:
|
||||
* Change _NET_WM_WINDOW_TYPE_MENU to use TINY decoration type (Mark)
|
||||
Ewmh.cc
|
||||
|
|
|
@ -141,7 +141,7 @@ void Ewmh::initForScreen(BScreen &screen) {
|
|||
m_net_wm_state_fullscreen,
|
||||
m_net_wm_state_hidden,
|
||||
m_net_wm_state_skip_taskbar,
|
||||
m_net_wm_state_modal,
|
||||
// m_net_wm_state_modal,
|
||||
m_net_wm_state_below,
|
||||
m_net_wm_state_above,
|
||||
m_net_wm_state_demands_attention,
|
||||
|
|
|
@ -556,6 +556,14 @@ void FbWindow::deleteProperty(Atom property) {
|
|||
XDeleteProperty(display(), m_window, property);
|
||||
}
|
||||
|
||||
void FbWindow::addToSaveSet() {
|
||||
XAddToSaveSet(display(), m_window);
|
||||
}
|
||||
|
||||
void FbWindow::removeFromSaveSet() {
|
||||
XRemoveFromSaveSet(display(), m_window);
|
||||
}
|
||||
|
||||
int FbWindow::screenNumber() const {
|
||||
return m_screen_num;
|
||||
}
|
||||
|
|
|
@ -165,6 +165,9 @@ public:
|
|||
|
||||
std::string textProperty(Atom property) const;
|
||||
|
||||
void addToSaveSet();
|
||||
void removeFromSaveSet();
|
||||
|
||||
/// @return parent FbWindow
|
||||
const FbWindow *parent() const { return m_parent; }
|
||||
/// @return real X window
|
||||
|
|
|
@ -52,6 +52,7 @@ public:
|
|||
TrayWindow(Window win):FbTk::FbWindow(win), m_visible(false) {
|
||||
setEventMask(PropertyChangeMask);
|
||||
}
|
||||
|
||||
bool isVisible() { return m_visible; }
|
||||
void show() {
|
||||
if (!m_visible) {
|
||||
|
@ -65,6 +66,7 @@ public:
|
|||
FbTk::FbWindow::hide();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_visible;
|
||||
};
|
||||
|
@ -132,9 +134,11 @@ SystemTray::SystemTray(const FbTk::FbWindow& parent, ButtonTheme& theme, BScreen
|
|||
SubstructureNotifyMask | SubstructureRedirectMask),
|
||||
m_theme(theme),
|
||||
m_screen(screen),
|
||||
m_pixmap(0), m_num_visible_clients(0) {
|
||||
|
||||
m_pixmap(0), m_num_visible_clients(0),
|
||||
m_selection_owner(m_window, 0, 0, 1, 1, SubstructureNotifyMask, false, false, CopyFromParent, InputOnly) {
|
||||
|
||||
FbTk::EventManager::instance()->add(*this, m_window);
|
||||
FbTk::EventManager::instance()->add(*this, m_selection_owner);
|
||||
m_theme.reconfigSig().attach(this);
|
||||
screen.bgChangeSig().attach(this);
|
||||
|
||||
|
@ -162,7 +166,7 @@ SystemTray::SystemTray(const FbTk::FbWindow& parent, ButtonTheme& theme, BScreen
|
|||
cerr<<__FILE__<<"(SystemTray(const FbTk::FbWindow)): SETTING OWNER!"<<endl;
|
||||
#endif // DEBUG
|
||||
// set owner
|
||||
XSetSelectionOwner(disp, tray_atom, m_window.window(), CurrentTime);
|
||||
XSetSelectionOwner(disp, tray_atom, m_selection_owner.window(), CurrentTime);
|
||||
|
||||
m_handler.reset(new SystemTrayHandler(*this));
|
||||
|
||||
|
@ -190,7 +194,20 @@ SystemTray::SystemTray(const FbTk::FbWindow& parent, ButtonTheme& theme, BScreen
|
|||
|
||||
SystemTray::~SystemTray() {
|
||||
// remove us, else fluxbox might delete the memory too
|
||||
Fluxbox::instance()->removeAtomHandler(m_handler.get());
|
||||
Fluxbox* fluxbox = Fluxbox::instance();
|
||||
fluxbox->removeAtomHandler(m_handler.get());
|
||||
Display *disp = fluxbox->display();
|
||||
// setup atom name to _NET_SYSTEM_TRAY_S<screen number>
|
||||
char intbuff[16];
|
||||
sprintf(intbuff, "%d", m_window.screenNumber());
|
||||
string atom_name("_NET_SYSTEM_TRAY_S");
|
||||
atom_name += intbuff; // append number
|
||||
|
||||
// get selection owner and see if it's free
|
||||
Atom tray_atom = XInternAtom(disp, atom_name.c_str(), False);
|
||||
|
||||
// Properly give up selection.
|
||||
XSetSelectionOwner(disp, tray_atom, None, CurrentTime);
|
||||
removeAllClients();
|
||||
|
||||
if (m_pixmap)
|
||||
|
@ -323,10 +340,11 @@ void SystemTray::addClient(Window win) {
|
|||
FbTk::EventManager::instance()->add(*this, win);
|
||||
XChangeSaveSet(FbTk::App::instance()->display(), win, SetModeInsert);
|
||||
traywin->reparent(m_window, 0, 0);
|
||||
traywin->addToSaveSet();
|
||||
showClient(traywin);
|
||||
}
|
||||
|
||||
void SystemTray::removeClient(Window win) {
|
||||
void SystemTray::removeClient(Window win, bool destroyed) {
|
||||
ClientList::iterator tray_it = findClient(win);
|
||||
if (tray_it == m_clients.end())
|
||||
return;
|
||||
|
@ -336,7 +354,11 @@ void SystemTray::removeClient(Window win) {
|
|||
#endif // DEBUG
|
||||
TrayWindow *traywin = *tray_it;
|
||||
m_clients.erase(tray_it);
|
||||
hideClient(traywin);
|
||||
if (!destroyed) {
|
||||
traywin->setEventMask(NoEventMask);
|
||||
traywin->removeFromSaveSet();
|
||||
}
|
||||
hideClient(traywin, destroyed);
|
||||
delete traywin;
|
||||
}
|
||||
|
||||
|
@ -346,9 +368,9 @@ void SystemTray::exposeEvent(XExposeEvent &event) {
|
|||
|
||||
void SystemTray::handleEvent(XEvent &event) {
|
||||
if (event.type == DestroyNotify) {
|
||||
removeClient(event.xdestroywindow.window);
|
||||
removeClient(event.xdestroywindow.window, true);
|
||||
} else if (event.type == ReparentNotify && event.xreparent.parent != m_window.window()) {
|
||||
removeClient(event.xreparent.window);
|
||||
removeClient(event.xreparent.window, false);
|
||||
} else if (event.type == UnmapNotify && event.xany.send_event) {
|
||||
// we ignore server-generated events, which can occur
|
||||
// on restart. The ICCCM says that a client must send
|
||||
|
@ -443,20 +465,23 @@ void SystemTray::rearrangeClients() {
|
|||
void SystemTray::removeAllClients() {
|
||||
BScreen *screen = Fluxbox::instance()->findScreen(window().screenNumber());
|
||||
while (!m_clients.empty()) {
|
||||
m_clients.back()->setEventMask(NoEventMask);
|
||||
m_clients.back()->hide();
|
||||
if (screen)
|
||||
m_clients.back()->reparent(screen->rootWindow(), 0, 0);
|
||||
m_clients.back()->hide();
|
||||
m_clients.back()->removeFromSaveSet();
|
||||
delete m_clients.back();
|
||||
m_clients.pop_back();
|
||||
}
|
||||
m_num_visible_clients = 0;
|
||||
}
|
||||
|
||||
void SystemTray::hideClient(TrayWindow *traywin) {
|
||||
void SystemTray::hideClient(TrayWindow *traywin, bool destroyed) {
|
||||
if (!traywin || !traywin->isVisible())
|
||||
return;
|
||||
|
||||
traywin->hide();
|
||||
if (!destroyed)
|
||||
traywin->hide();
|
||||
m_num_visible_clients--;
|
||||
rearrangeClients();
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ public:
|
|||
void handleEvent(XEvent &event);
|
||||
|
||||
void addClient(Window win);
|
||||
void removeClient(Window win);
|
||||
void removeClient(Window win, bool destroyed);
|
||||
|
||||
unsigned int width() const;
|
||||
unsigned int height() const;
|
||||
|
@ -83,7 +83,7 @@ private:
|
|||
|
||||
void rearrangeClients();
|
||||
void removeAllClients();
|
||||
void hideClient(TrayWindow *traywin);
|
||||
void hideClient(TrayWindow *traywin, bool destroyed = false);
|
||||
void showClient(TrayWindow *traywin);
|
||||
|
||||
FbTk::FbWindow m_window;
|
||||
|
@ -95,6 +95,10 @@ private:
|
|||
|
||||
ClientList m_clients;
|
||||
size_t m_num_visible_clients;
|
||||
|
||||
// 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
|
||||
|
|
|
@ -255,6 +255,7 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
|
|||
SignalHandler &sigh = SignalHandler::instance();
|
||||
sigh.registerHandler(SIGSEGV, this);
|
||||
sigh.registerHandler(SIGFPE, this);
|
||||
sigh.registerHandler(SIGPIPE, this); // e.g. output sent to grep
|
||||
sigh.registerHandler(SIGTERM, this);
|
||||
sigh.registerHandler(SIGINT, this);
|
||||
sigh.registerHandler(SIGCHLD, this);
|
||||
|
@ -1091,6 +1092,7 @@ void Fluxbox::handleSignal(int signum) {
|
|||
break;
|
||||
case SIGFPE:
|
||||
case SIGINT:
|
||||
case SIGPIPE:
|
||||
case SIGTERM:
|
||||
shutdown();
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue