1) Additional work on tq app -> tde app translation.

2) Make sure to exit app after restore if no app window can be grabbed
3) Save state only for known applications (app with empty name will not
be saved and restored)

Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
pull/2/head
Michele Calgaro 5 years ago
parent 5c2a45303e
commit 88fbf7e81a
Signed by: MicheleC
GPG Key ID: 2A75B7CA8ADED5CF

@ -47,8 +47,7 @@ CustomTrayLabel::CustomTrayLabel(Window w, TQWidget* p, const TQString& t)
installMenu(); installMenu();
} }
CustomTrayLabel::CustomTrayLabel(const TQStringList& argv, pid_t pid, CustomTrayLabel::CustomTrayLabel(const TQStringList& argv, pid_t pid, TQWidget* parent)
TQWidget* parent)
: TQTrayLabel(argv, pid, parent), mUndockWhenDead(false) : TQTrayLabel(argv, pid, parent), mUndockWhenDead(false)
{ {
installMenu(); installMenu();
@ -124,6 +123,11 @@ void CustomTrayLabel::installMenu()
setAcceptDrops(true); // and you thought this function only installs the menu setAcceptDrops(true); // and you thought this function only installs the menu
} }
void CustomTrayLabel::enableSessionManagement(bool sm)
{
mSessionManagement->setOn(!appName().isEmpty() && sm);
}
// Session Management // Session Management
bool CustomTrayLabel::restoreState(TDEConfig *config) bool CustomTrayLabel::restoreState(TDEConfig *config)
{ {
@ -132,13 +136,20 @@ bool CustomTrayLabel::restoreState(TDEConfig *config)
return TQTrayLabel::restoreState(config); return TQTrayLabel::restoreState(config);
} }
void CustomTrayLabel::saveState(TDEConfig *config) bool CustomTrayLabel::saveState(TDEConfig *config)
{ {
if (!mSessionManagement->isOn()) return; if (!mSessionManagement->isOn())
{
return false;
}
TQTrayLabel::saveState(config); if (!TQTrayLabel::saveState(config))
{
return false;
}
config->writeEntry("DockWhenObscured", isDockWhenObscured()); config->writeEntry("DockWhenObscured", isDockWhenObscured());
TRACE("WM=%i DWO=%i", isDockWhenMinimized(), isDockWhenObscured()); TRACE("WM=%i DWO=%i", isDockWhenMinimized(), isDockWhenObscured());
return true;
} }
static bool which(const char *app) static bool which(const char *app)
@ -177,6 +188,7 @@ void CustomTrayLabel::setSkipTaskbar(bool skip)
void CustomTrayLabel::setAppName(const TQString& name) void CustomTrayLabel::setAppName(const TQString& name)
{ {
//FIXME HACK relies on window and application name being the same.
TQTrayLabel::setAppName(name.lower()); TQTrayLabel::setAppName(name.lower());
} }

@ -43,7 +43,7 @@ public:
CustomTrayLabel(const TQStringList& argv, pid_t pid, TQWidget* parent = 0); CustomTrayLabel(const TQStringList& argv, pid_t pid, TQWidget* parent = 0);
// Session management // Session management
void saveState(TDEConfig *config); bool saveState(TDEConfig *config);
bool restoreState(TDEConfig *config); bool restoreState(TDEConfig *config);
bool isDockWhenObscured(void) const { return mDockWhenObscured->isOn(); } bool isDockWhenObscured(void) const { return mDockWhenObscured->isOn(); }
@ -57,7 +57,7 @@ public slots:
void setSkipTaskbar(bool skip); void setSkipTaskbar(bool skip);
void setDockWhenObscured(bool dock) { mDockWhenObscured->setOn(dock); } void setDockWhenObscured(bool dock) { mDockWhenObscured->setOn(dock); }
void enableSessionManagement(bool sm) { mSessionManagement->setOn(sm); } void enableSessionManagement(bool sm);
protected: protected:
void dropEvent(TQDropEvent *ev); void dropEvent(TQDropEvent *ev);

@ -40,13 +40,13 @@ static void sighandler(int sig)
{ {
if (sig == SIGUSR1) if (sig == SIGUSR1)
{ {
DUMP_TRACE((TQDir::homeDirPath() + "/tdedocker.trace").ascii()); DUMP_TRACE((TQDir::homeDirPath() + "/tdedocker.trace").local8Bit());
return; return;
} }
tqDebug("%s", i18n("Caught signal %1. Cleaning up.").arg(sig).local8Bit().data()); tqDebug("%s", i18n("Caught signal %1. Cleaning up.").arg(sig).local8Bit().data());
((TDEDocker *)tqApp)->trayLabelMgr()->undockAll(); ((TDEDocker*)TDEApplication::kApplication())->trayLabelMgr()->undockAll();
::exit(0); TDEApplication::kApplication()->quit();
} }
static const TDECmdLineOptions options[] = static const TDECmdLineOptions options[] =
@ -69,12 +69,6 @@ static const TDECmdLineOptions options[] =
//extern "C" int KDE_EXPORT kdemain(int argc, char* argv[]) //extern "C" int KDE_EXPORT kdemain(int argc, char* argv[])
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// setup signal handlers that undock and quit
signal(SIGHUP, sighandler);
signal(SIGTERM, sighandler);
signal(SIGINT, sighandler);
signal(SIGUSR1, sighandler);
TDEAboutData about("tdedocker", I18N_NOOP("tdedocker"), "1.3", TDEAboutData about("tdedocker", I18N_NOOP("tdedocker"), "1.3",
I18N_NOOP("Docks any application into the system tray\nNOTE: Use -d for all startup scripts."), TDEAboutData::License_GPL); I18N_NOOP("Docks any application into the system tray\nNOTE: Use -d for all startup scripts."), TDEAboutData::License_GPL);
about.addAuthor("John Schember", I18N_NOOP("Original KDocker maintainer"), "john@nachtimwald.com"); about.addAuthor("John Schember", I18N_NOOP("Original KDocker maintainer"), "john@nachtimwald.com");
@ -87,5 +81,11 @@ int main(int argc, char *argv[])
TDEDocker::addCmdLineOptions(); TDEDocker::addCmdLineOptions();
TDEDocker app; TDEDocker app;
// setup signal handlers that undock and quit (must be done after the TDEApplication constructor has run)
signal(SIGHUP, sighandler);
signal(SIGTERM, sighandler);
signal(SIGINT, sighandler);
signal(SIGUSR1, sighandler);
return app.exec(); return app.exec();
} }

@ -83,7 +83,7 @@ const char *TQTrayLabel::me(void) const
{ {
static char temp[100]; static char temp[100];
snprintf(temp, sizeof(temp), "(%s,PID=%i,WID=0x%x)", snprintf(temp, sizeof(temp), "(%s,PID=%i,WID=0x%x)",
mProgName[0].local8Bit().data(), mPid, (unsigned) mDockedWindow); appName().local8Bit().data(), mPid, (unsigned) mDockedWindow);
return temp; return temp;
} }
@ -99,7 +99,9 @@ TQTrayLabel::TQTrayLabel(const TQStringList& pname, pid_t pid, TQWidget* parent)
mDockedWindow(None), mProgName(pname), mPid(pid) mDockedWindow(None), mProgName(pname), mPid(pid)
{ {
if (pname[0].at(0) != '/' && pname[0].find('/', 1) > 0) if (pname[0].at(0) != '/' && pname[0].find('/', 1) > 0)
mProgName[0] = TQFileInfo(pname[0]).absFilePath(); // convert to absolute {
mProgName.push_front(TQFileInfo(pname[0]).absFilePath()); // convert to absolute
}
initialize(); initialize();
} }
@ -113,6 +115,18 @@ TQTrayLabel::~TQTrayLabel()
map(); map();
} }
void TQTrayLabel::setAppName(const TQString &prog)
{
if (mProgName.count() == 0)
{
mProgName.push_front(prog);
}
else
{
mProgName[0] = prog;
}
}
/* /*
* Scans the windows in the desktop and checks if a window exists that we might * Scans the windows in the desktop and checks if a window exists that we might
* be interested in * be interested in
@ -122,7 +136,7 @@ void TQTrayLabel::scanClients()
Window r, parent, *children; Window r, parent, *children;
unsigned nchildren = 0; unsigned nchildren = 0;
Display *display = TQPaintDevice::x11AppDisplay(); Display *display = TQPaintDevice::x11AppDisplay();
TQString ename = TQFileInfo(mProgName[0]).fileName(); // strip out the path TQString ename = TQFileInfo(appName()).fileName(); // strip out the path
XQueryTree(display, tqt_xrootwin(), &r, &parent, &children, &nchildren); XQueryTree(display, tqt_xrootwin(), &r, &parent, &children, &nchildren);
TRACE("%s nchildren=%i", me(), nchildren); TRACE("%s nchildren=%i", me(), nchildren);
@ -671,7 +685,10 @@ bool TQTrayLabel::x11EventFilter(XEvent *ev)
if (event->window == mSysTray) if (event->window == mSysTray)
{ {
if (event->type != DestroyNotify) return FALSE; // not interested in others if (event->type != DestroyNotify)
{
return false; // not interested in others
}
emit sysTrayDestroyed(); emit sysTrayDestroyed();
mSysTray = None; mSysTray = None;
TRACE("%s SystemTray disappeared. Starting timer", me()); TRACE("%s SystemTray disappeared. Starting timer", me());
@ -713,8 +730,10 @@ bool TQTrayLabel::x11EventFilter(XEvent *ev)
Display *display = TQPaintDevice::x11AppDisplay(); Display *display = TQPaintDevice::x11AppDisplay();
Window w = XmuClientWindow(display, ((XMapEvent *) event)->window); Window w = XmuClientWindow(display, ((XMapEvent *) event)->window);
if (!isNormalWindow(display, w)) return FALSE; if (!isNormalWindow(display, w)) return FALSE;
if (!analyzeWindow(display, w, mPid, if (!analyzeWindow(display, w, mPid, TQFileInfo(appName()).fileName().local8Bit()))
TQFileInfo(mProgName[0]).fileName().local8Bit())) return FALSE; {
return false;
}
// All right. Lets dock this baby // All right. Lets dock this baby
setDockedWindow(w); setDockedWindow(w);
return true; return true;
@ -772,8 +791,13 @@ void TQTrayLabel::propertyChangeEvent(Atom property)
} }
// Session Management // Session Management
void TQTrayLabel::saveState(TDEConfig *config) bool TQTrayLabel::saveState(TDEConfig *config)
{ {
if (appName().isEmpty())
{
return false;
}
TRACE("%s saving state", me()); TRACE("%s saving state", me());
config->writeEntry("Application", mProgName.join(" ")); config->writeEntry("Application", mProgName.join(" "));
config->writeEntry("BalloonTimeout", mBalloonTimeout); config->writeEntry("BalloonTimeout", mBalloonTimeout);
@ -781,6 +805,7 @@ void TQTrayLabel::saveState(TDEConfig *config)
config->writeEntry("DockWhenMinimized", mDockWhenMinimized); config->writeEntry("DockWhenMinimized", mDockWhenMinimized);
config->writeEntry("SkipTaskbar", mSkippingTaskbar); config->writeEntry("SkipTaskbar", mSkippingTaskbar);
config->writeEntry("Withdraw", mWithdrawn); config->writeEntry("Withdraw", mWithdrawn);
return true;
} }
bool TQTrayLabel::restoreState(TDEConfig *config) bool TQTrayLabel::restoreState(TDEConfig *config)

@ -60,8 +60,8 @@ public:
bool isWithdrawn(void) const { return mWithdrawn; } bool isWithdrawn(void) const { return mWithdrawn; }
bool isDockWhenMinimized(void) const { return mDockWhenMinimized; } bool isDockWhenMinimized(void) const { return mDockWhenMinimized; }
TQString appName(void) const { return mProgName[0]; } TQString appName(void) const { return (mProgName.count() > 0) ? mProgName[0] : TQString::null; }
virtual void setAppName(const TQString& prog) { mProgName[0] = prog; } virtual void setAppName(const TQString& prog);
TQString appClass(void) const { return mClass; } TQString appClass(void) const { return mClass; }
TQString appTitle(void) const { return mTitle; } TQString appTitle(void) const { return mTitle; }
TQPixmap appIcon(void) const { return mAppIcon; } TQPixmap appIcon(void) const { return mAppIcon; }
@ -70,7 +70,7 @@ public:
bool x11EventFilter(XEvent * event); bool x11EventFilter(XEvent * event);
// Session Management // Session Management
virtual void saveState(TDEConfig *config); virtual bool saveState(TDEConfig *config);
virtual bool restoreState(TDEConfig *config); virtual bool restoreState(TDEConfig *config);
public slots: public slots:

@ -23,7 +23,6 @@
#include <tqfile.h> #include <tqfile.h>
#include <tqtextcodec.h> #include <tqtextcodec.h>
#include <tqtextstream.h> #include <tqtextstream.h>
#include <tqtimer.h>
#include <tqstring.h> #include <tqstring.h>
#include <tdecmdlineargs.h> #include <tdecmdlineargs.h>
@ -43,7 +42,21 @@
#define TMPFILE_PREFIX TQString("/tmp/tdedocker.") #define TMPFILE_PREFIX TQString("/tmp/tdedocker.")
TDEDocker::TDEDocker() TDEDocker::TDEDocker()
: TDEApplication(), mTrayLabelMgr(NULL), firstSaveState(true) : TDEApplication(), mTrayLabelMgr(NULL)
{
// Set ourselves up to be called from the application loop
connect(&mInitTimer, SIGNAL(timeout()), this, SLOT(doInit()));
mInitTimer.start(0, true);
// Required so that the saved config is correctly loaded
// (see TrayLabelMgr::doRestoreSession() for usage)
if (TDEApplication::kApplication()->isRestored())
{
TDEApplication::kApplication()->sessionConfig();
}
}
void TDEDocker::doInit()
{ {
INIT_TRACE(); INIT_TRACE();
/* /*
@ -58,12 +71,6 @@ TDEDocker::TDEDocker()
if (prev_instance == None) if (prev_instance == None)
{ {
if (TDEApplication::kApplication()->isRestored())
{
// Required so that the saved config is correctly loaded
// (see TrayLabelMgr::doRestoreSession() for usage)
TDEApplication::kApplication()->sessionConfig();
}
mSelectionOwner = XCreateSimpleWindow(display, tqt_xrootwin(), 1, 1, 1, 1, 1, 1, 1); mSelectionOwner = XCreateSimpleWindow(display, tqt_xrootwin(), 1, 1, 1, 1, 1, 1, 1);
XSetSelectionOwner(display, tdedocker, mSelectionOwner, CurrentTime); XSetSelectionOwner(display, tdedocker, mSelectionOwner, CurrentTime);
TRACE("Selection owner set to 0x%x", (unsigned) mSelectionOwner); TRACE("Selection owner set to 0x%x", (unsigned) mSelectionOwner);
@ -118,7 +125,7 @@ void TDEDocker::notifyPreviousInstance(Window prevInstance)
XSendEvent(display, prevInstance, False, 0, (XEvent *) &dock_event); XSendEvent(display, prevInstance, False, 0, (XEvent *) &dock_event);
XSync(display, False); XSync(display, False);
::exit(0); quit();
} }
/* /*

@ -22,6 +22,7 @@
#ifndef _TDEDOCKER_H #ifndef _TDEDOCKER_H
#define _TDEDOCKER_H #define _TDEDOCKER_H
#include <tqtimer.h>
#include <tdeapplication.h> #include <tdeapplication.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -41,12 +42,15 @@ public:
protected: protected:
bool x11EventFilter(XEvent * event); bool x11EventFilter(XEvent * event);
private slots:
void doInit();
private: private:
void notifyPreviousInstance(Window prevInstance); void notifyPreviousInstance(Window prevInstance);
Window mSelectionOwner; Window mSelectionOwner;
TrayLabelMgr *mTrayLabelMgr; TrayLabelMgr *mTrayLabelMgr;
bool firstSaveState; TQTimer mInitTimer;
}; };
#endif // _TDEDOCKER_H #endif // _TDEDOCKER_H

@ -1,5 +1,4 @@
#ifdef ENABLE_TRACING #ifdef ENABLE_TRACING
#include <tqapplication.h>
#include <tqtextedit.h> #include <tqtextedit.h>
#include <tqfile.h> #include <tqfile.h>
#include <stdio.h> #include <stdio.h>
@ -38,6 +37,7 @@ void DUMP_TRACE(const char *f)
{ {
TQTextStream stream(&file); TQTextStream stream(&file);
stream << tracer->text(); stream << tracer->text();
file.close();
} }
} }

@ -37,7 +37,6 @@
#include <stdlib.h> #include <stdlib.h>
TrayLabelMgr* TrayLabelMgr::gTrayLabelMgr = NULL; TrayLabelMgr* TrayLabelMgr::gTrayLabelMgr = NULL;
const char *TrayLabelMgr::mOptionString = "+bdefi:lmop:qtw:";
TrayLabelMgr* TrayLabelMgr::instance() TrayLabelMgr* TrayLabelMgr::instance()
{ {
@ -85,7 +84,7 @@ void TrayLabelMgr::startup(void)
state == SysTrayAbsent ? i18n("No system tray found") : i18n("System tray appears to be hidden"), state == SysTrayAbsent ? i18n("No system tray found") : i18n("System tray appears to be hidden"),
i18n("TDEDocker")) == KMessageBox::Cancel) i18n("TDEDocker")) == KMessageBox::Cancel)
{ {
tqApp->quit(); TDEApplication::kApplication()->quit();
return; return;
} }
} }
@ -106,8 +105,13 @@ void TrayLabelMgr::startup(void)
// Process the request Q from previous instances // Process the request Q from previous instances
TRACE("Request queue has %i requests", mRequestQ.count()); TRACE("Request queue has %i requests", mRequestQ.count());
for(unsigned i=0; i < mRequestQ.count(); i++) for(unsigned i=0; i < mRequestQ.count(); i++)
{
ok |= processCommand(mRequestQ[i]); ok |= processCommand(mRequestQ[i]);
if (!ok) tqApp->quit(); }
if (!ok)
{
TDEApplication::kApplication()->quit();
}
} }
// Initialize a TQTrayLabel after its creation // Initialize a TQTrayLabel after its creation
@ -258,7 +262,7 @@ bool TrayLabelMgr::processCommand(int argc, char** argv)
optind = 0; // initialise the getopt static optind = 0; // initialise the getopt static
while ((option = getopt(argc, argv, mOptionString)) != EOF) while ((option = getopt(argc, argv, "+bdefi:lmop:qtw:")) != EOF)
{ {
switch (option) switch (option)
{ {
@ -364,7 +368,7 @@ TQTrayLabel *TrayLabelMgr::selectAndDock(Window w, bool checkNormality)
if (!isWindowDocked(w)) return new CustomTrayLabel(w); if (!isWindowDocked(w)) return new CustomTrayLabel(w);
TRACE("0x%x is not docked", (unsigned) w); TRACE("0x%x is alredy docked", (unsigned) w);
KMessageBox::error(NULL, i18n("This window is already docked.\n" KMessageBox::error(NULL, i18n("This window is already docked.\n"
"Click on system tray icon to toggle docking."), i18n("TDEDocker")); "Click on system tray icon to toggle docking."), i18n("TDEDocker"));
@ -407,7 +411,9 @@ TQTrayLabel *TrayLabelMgr::dockApplication(char *argv[])
if (execvp(argv[0], argv) == -1) if (execvp(argv[0], argv) == -1)
{ {
tqDebug("%s", i18n("Failed to exec [%1]: %2").arg(argv[0]).arg(strerror(errno)).local8Bit().data()); tqDebug("%s", i18n("Failed to exec [%1]: %2").arg(argv[0]).arg(strerror(errno)).local8Bit().data());
::exit(0); // will become a zombie in some systems :( // Exit the forked process only.
// Using TDEApplication::kApplication()->quit() crashes the parent application.
exit(0);
return NULL; return NULL;
} }
} }
@ -423,7 +429,7 @@ TQTrayLabel *TrayLabelMgr::dockApplication(char *argv[])
if (argv[i]) cmd_line << argv[i]; else break; if (argv[i]) cmd_line << argv[i]; else break;
TQTrayLabel *label = new CustomTrayLabel(cmd_line, pid); TQTrayLabel *label = new CustomTrayLabel(cmd_line, pid);
tqApp->syncX(); TDEApplication::kApplication()->syncX();
write(filedes[1], buf, sizeof(buf)); write(filedes[1], buf, sizeof(buf));
close(filedes[0]); close(filedes[0]);
close(filedes[1]); close(filedes[1]);
@ -453,7 +459,10 @@ void TrayLabelMgr::trayLabelDestroyed(TQObject *t)
{ {
bool reconnect = ((TQObject *)mTrayLabels.getLast() == t); bool reconnect = ((TQObject *)mTrayLabels.getLast() == t);
mTrayLabels.removeRef((TQTrayLabel*)t); mTrayLabels.removeRef((TQTrayLabel*)t);
if (mTrayLabels.isEmpty()) tqApp->quit(); if (mTrayLabels.isEmpty())
{
TDEApplication::kApplication()->quit();
}
else if (reconnect) else if (reconnect)
{ {
TRACE("Reconnecting"); TRACE("Reconnecting");
@ -500,13 +509,17 @@ void TrayLabelMgr::doRestoreSession()
TRACE("Restoring session"); TRACE("Restoring session");
TDEConfig *config = TDEApplication::kApplication()->sessionConfig(); TDEConfig *config = TDEApplication::kApplication()->sessionConfig();
for (int i = 1; ; ++i) if (config->hasGroup("General"))
{ {
if (!config->hasGroup("Instance" + TQString::number(i))) config->setGroup("General");
int count = config->readNumEntry("InstanceCount", 0);
for (int i = 0; i < count; ++i)
{ {
return; if (!config->hasGroup(TQString::number(i)))
{
break;
} }
config->setGroup("Instance" + TQString::number(i)); config->setGroup(TQString::number(i));
TQString pname = config->readEntry("Application", TQString::null); TQString pname = config->readEntry("Application", TQString::null);
if (!pname.isEmpty()) if (!pname.isEmpty())
{ {
@ -515,24 +528,39 @@ void TrayLabelMgr::doRestoreSession()
mTrayLabels.getFirst()->restoreState(config); mTrayLabels.getFirst()->restoreState(config);
} }
} }
}
// Exit if no application could be restored
if (mTrayLabels.isEmpty())
{
TDEApplication::kApplication()->quit();
}
} }
bool TrayLabelMgr::saveState(TQSessionManager &sm) bool TrayLabelMgr::saveState(TQSessionManager &sm)
{ {
TRACE("Saving session"); TRACE("Saving session");
int i = 1; int i = 0;
TQTrayLabel *t; TQTrayLabel *t;
TDEConfig *config = TDEApplication::kApplication()->sessionConfig(); TDEConfig *config = TDEApplication::kApplication()->sessionConfig();
TQPtrListIterator <TQTrayLabel> it(mTrayLabels); TQPtrListIterator<TQTrayLabel> it(mTrayLabels);
for (it.toFirst(); it.current(); ++it) for (it.toFirst(); it.current(); ++it)
{ {
t = it.current(); t = it.current();
TRACE("Saving instance %i", i); config->setGroup(TQString::number(i));
config->setGroup("Instance" + TQString::number(i)); if (t->saveState(config))
t->saveState(config); {
TRACE("Saved instance %i", i);
++i; ++i;
} }
else
{
config->deleteGroup(TQString::number(i));
}
}
config->setGroup("General");
config->writeEntry("InstanceCount", i);
return true; return true;
} }

@ -40,7 +40,6 @@ class TrayLabelMgr : public TQObject, public KSessionManaged
public: public:
static TrayLabelMgr* instance(); static TrayLabelMgr* instance();
static TQString options(void) { return TQString(mOptionString); }
~TrayLabelMgr(); ~TrayLabelMgr();
@ -79,7 +78,6 @@ private:
bool mReady; bool mReady;
int mHiddenLabelsCount; int mHiddenLabelsCount;
static const char *mOptionString;
static TrayLabelMgr *gTrayLabelMgr; static TrayLabelMgr *gTrayLabelMgr;
}; };

Loading…
Cancel
Save