diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 02193f4..30f4c63 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,6 +35,7 @@ tde_add_executable( tdedocker AUTOMOC trace.cpp traylabelmgr.cpp util.cpp + trace.cpp LINK tdecore-shared tdeui-shared DCOP-shared ${XMU_LIBRARIES} ${XPM_LIBRARIES} diff --git a/src/customtraylabel.cpp b/src/customtraylabel.cpp index e27dbba..87e50ac 100644 --- a/src/customtraylabel.cpp +++ b/src/customtraylabel.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. - * + * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -21,22 +21,25 @@ #include #include -#include +#include #include #include -#include #include -#include #include +#include +#include #include +#include +#include +#include #include #include +#include #include "trace.h" -#include "customtraylabel.h" #include "traylabelmgr.h" -#include "tdedocker.h" +#include "customtraylabel.h" CustomTrayLabel::CustomTrayLabel(Window w, TQWidget* p, const TQString& t) : TQTrayLabel(w, p, t), mUndockWhenDead(false) @@ -51,34 +54,25 @@ CustomTrayLabel::CustomTrayLabel(const TQStringList& argv, pid_t pid, installMenu(); } -/* - * Installs a popup menu on the tray label - */ +// Installs a popup menu on the tray label void CustomTrayLabel::installMenu() { - //TQPixmap tdedocker_png(TDEGlobal::iconLoader()->loadIcon("tdedocker", TDEIcon::NoGroup, TDEIcon::SizeSmall)); - TQPixmap *tdedocker_png = new TQPixmap("tdedocker"); - setIcon(*tdedocker_png); + TQPixmap tdedocker_png(TDEGlobal::iconLoader()->loadIcon("tdedocker", TDEIcon::NoGroup, TDEIcon::SizeSmall)); + setIcon(tdedocker_png); TrayLabelMgr *tlMgr = TrayLabelMgr::instance(); - mOptionsMenu = new TQPopupMenu(this); + mOptionsMenu = new TDEPopupMenu(this); mSessionManagement = new TQAction(i18n("Dock when session restored"), 0, this); mSessionManagement->setToggleAction(true); connect(mSessionManagement, SIGNAL(toggled(bool)), this, SLOT(enableSessionManagement(bool))); mSessionManagement->addTo(mOptionsMenu); - mAutoLaunch = new TQAction(i18n("Launch on startup"), 0, this); - mAutoLaunch->setToggleAction(true); - connect(mAutoLaunch, SIGNAL(activated()), - this, SLOT(slotSetLaunchOnStartup())); - mAutoLaunch->addTo(mOptionsMenu); - mOptionsMenu->insertItem(i18n("Set Icon"), this, SLOT(setCustomIcon())); mBalloonTimeout = new TQAction(i18n("Set balloon timeout"), 0, this); connect(mBalloonTimeout, SIGNAL(activated()), - this, SLOT(slotSetBalloonTimeout())); + this, SLOT(slotSetBalloonTimeout())); mBalloonTimeout->addTo(mOptionsMenu); mDockWhenObscured = new TQAction(i18n("Dock when obscured"), 0, this); @@ -94,10 +88,10 @@ void CustomTrayLabel::installMenu() mDockWhenMinimized->addTo(mOptionsMenu); mDockWhenFocusLost = new TQAction(i18n("Dock when focus lost"), 0, this); - mDockWhenFocusLost->setToggleAction(true); - connect(mDockWhenFocusLost, SIGNAL(toggled(bool)), - this, SLOT(setDockWhenFocusLost(bool))); - mDockWhenFocusLost->addTo(mOptionsMenu); + mDockWhenFocusLost->setToggleAction(true); + connect(mDockWhenFocusLost, SIGNAL(toggled(bool)), + this, SLOT(setDockWhenFocusLost(bool))); + mDockWhenFocusLost->addTo(mOptionsMenu); mSkipTaskbar = new TQAction(i18n("Skip taskbar"), 0, this); mSkipTaskbar->setToggleAction(true); @@ -106,9 +100,6 @@ void CustomTrayLabel::installMenu() mSkipTaskbar->addTo(mOptionsMenu); mMainMenu = new TQPopupMenu(this); - mMainMenu->insertItem(TQIconSet(*tdedocker_png), - i18n("About TDEDocker"), tlMgr, SLOT(about())); - mMainMenu->insertSeparator(); mMainMenu->insertItem(i18n("Options"), mOptionsMenu); mMainMenu->insertItem(i18n("Dock Another"), tlMgr, SLOT(dockAnother())); mMainMenu->insertItem(i18n("Undock All"), tlMgr, SLOT(undockAll())); @@ -117,12 +108,15 @@ void CustomTrayLabel::installMenu() mShowId = mMainMenu->insertItem(TQString("Show/Hide [untitled]"), this, SLOT(toggleShow())); mMainMenu->insertItem(TQString(i18n("Undock")), this, SLOT(undock())); - mMainMenu->insertItem(TQString(i18n("Close")), this, SLOT(close())); + mMainMenu->insertSeparator(); + + mMainMenu->insertItem(SmallIcon("help"),KStdGuiItem::help().text(), (new KHelpMenu(this, TDEGlobal::instance()->aboutData()))->menu(), false); + TDEAction *quitAction = KStdAction::quit(this, SLOT(close()), NULL); + quitAction->plug(mMainMenu); connect(mMainMenu, SIGNAL(aboutToShow()), this, SLOT(updateMenu())); // Apply defaults here - setLaunchOnStartup(false); setDockWhenObscured(false); enableSessionManagement(true); mDockWhenMinimized->setOn(isDockWhenMinimized()); @@ -130,28 +124,21 @@ void CustomTrayLabel::installMenu() setAcceptDrops(true); // and you thought this function only installs the menu } -/* - * Session Management - */ -bool CustomTrayLabel::restoreState(TQSettings& settings) +// Session Management +bool CustomTrayLabel::restoreState(TDEConfig *config) { - mAutoLaunch->setOn(settings.readBoolEntry("/LaunchOnStartup")); - setDockWhenObscured(settings.readBoolEntry("/DockWhenObscured")); - TRACE("AutoLaunch=%i DWM=%i DWO=%i", isLaunchOnStartup(), - isDockWhenMinimized(), isDockWhenObscured()); - return TQTrayLabel::restoreState(settings); + setDockWhenObscured(config->readBoolEntry("DockWhenObscured", false)); + TRACE("DWM=%i DWO=%i", isDockWhenMinimized(), isDockWhenObscured()); + return TQTrayLabel::restoreState(config); } -bool CustomTrayLabel::saveState(TQSettings& settings) +void CustomTrayLabel::saveState(TDEConfig *config) { - if (!mSessionManagement->isOn()) return false; + if (!mSessionManagement->isOn()) return; - TQTrayLabel::saveState(settings); - settings.writeEntry("/LaunchOnStartup", isLaunchOnStartup()); - settings.writeEntry("/DockWhenObscured", isDockWhenObscured()); - TRACE("AutoLaunch=%i DWM=%i DWO=%i", isLaunchOnStartup(), - isDockWhenMinimized(), isDockWhenObscured()); - return true; + TQTrayLabel::saveState(config); + config->writeEntry("DockWhenObscured", isDockWhenObscured()); + TRACE("WM=%i DWO=%i", isDockWhenMinimized(), isDockWhenObscured()); } static bool which(const char *app) @@ -214,9 +201,8 @@ void CustomTrayLabel::setCustomIcon(void) icon = TQFileDialog::getOpenFileName(); if (icon.isNull()) return; // user cancelled if (!TQPixmap(icon).isNull()) break; - TRACE("Attempting to set icon to %s", icon.latin1()); - TQMessageBox::critical(this, i18n("TDEDocker"), - i18n("%1 is not a valid icon").arg(icon)); + TRACE("Attempting to set icon to %s", icon.local8Bit()); + KMessageBox::error(this, i18n("%1 is not a valid icon").arg(icon), i18n("TDEDocker")); } setTrayIcon(icon); @@ -228,56 +214,12 @@ void CustomTrayLabel::slotSetBalloonTimeout(void) bool ok; int timeout = TQInputDialog::getInteger(i18n("TDEDocker"), i18n("Enter balloon timeout (secs). 0 to disable ballooning"), - balloonTimeout()/1000, 0, 60, 1, &ok); - + balloonTimeout()/1000, 0, 60, 1, &ok); + if (!ok) return; setBalloonTimeout(timeout * 1000); } -void CustomTrayLabel::setLaunchOnStartup(bool launch) -{ - mAutoLaunch->setOn(launch); - slotSetLaunchOnStartup(); // fake an "activated" signal -} - -void CustomTrayLabel::slotSetLaunchOnStartup() -{ - TRACE("%i", mAutoLaunch->isOn()); - if (!mAutoLaunch->isOn()) return; - TQString app = appName(); - - TRACE("Validating %s", app.latin1()); - - while (true) - { - if (which(app.latin1())) - { - TRACE("Autolaunch enabled to %s", app.latin1()); - setAppName(app); - mAutoLaunch->setOn(true); - return; - } - - // Request user to provide file name himself - if (TQMessageBox::critical(NULL, i18n("TDEDocker"), - i18n("\"%1\" is not a valid executable " - "or was not found in your $PATH").arg(app), - i18n("Select program"), i18n("Cancel")) == 1) - { - mAutoLaunch->setOn(false); - return; // cancelled - } - - app = TQFileDialog::getOpenFileName(); - if (app.isNull()) - { - TRACE("Disabling auto launch"); - mAutoLaunch->setOn(false); - return; - } - } -} - // Called when we are just about to display the menu void CustomTrayLabel::updateMenu(void) { @@ -310,13 +252,19 @@ void CustomTrayLabel::obscureEvent(void) void CustomTrayLabel::focusLostEvent() { - if (mDockWhenFocusLost->isOn()) withdraw(); + if (mDockWhenFocusLost->isOn()) withdraw(); } -void CustomTrayLabel::mouseReleaseEvent(TQMouseEvent * ev) +void CustomTrayLabel::mouseReleaseEvent(TQMouseEvent *ev) { if (ev->button() == TQt::RightButton) + { mMainMenu->popup(ev->globalPos()); +/* contextMenuAboutToShow(contextMenu()); + contextMenu()->popup(e->globalPos()); + e->accept(); + return;*/ + } else toggleShow(); } @@ -356,9 +304,8 @@ bool CustomTrayLabel::canDockWindow(Window w) void CustomTrayLabel::dropEvent(TQDropEvent *) { - TQMessageBox::information(NULL, "TDEDocker", - i18n("You cannot drop an item into the tray icon. Drop it on the window\n" - "that is brought in front when you hover the item over the tray icon")); + KMessageBox::error(NULL, i18n("You cannot drop an item into the tray icon. Drop it on the window\n" + "that is brought in front when you hover the item over the tray icon"), i18n("TDEDocker")); } diff --git a/src/customtraylabel.h b/src/customtraylabel.h index d7fa764..c022ec4 100644 --- a/src/customtraylabel.h +++ b/src/customtraylabel.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. - * + * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -28,6 +28,7 @@ class TQStringList; class TQPopupMenu; +class TDEPopupMenu; class TQString; class TQSettings; class TQWidget; @@ -42,10 +43,9 @@ public: CustomTrayLabel(const TQStringList& argv, pid_t pid, TQWidget* parent = 0); // Session management - bool saveState(TQSettings& settings); - bool restoreState(TQSettings& settings); + void saveState(TDEConfig *config); + bool restoreState(TDEConfig *config); - bool isLaunchOnStartup(void) const { return mAutoLaunch->isOn(); } bool isDockWhenObscured(void) const { return mDockWhenObscured->isOn(); } void setAppName(const TQString& name); @@ -53,10 +53,9 @@ public: public slots: // overridden to update our menu void setDockWhenMinimized(bool dwm); - void setDockWhenFocusLost(bool dfl) { mDockWhenFocusLost->setOn(dfl); } + void setDockWhenFocusLost(bool dfl) { mDockWhenFocusLost->setOn(dfl); } void setSkipTaskbar(bool skip); - void setLaunchOnStartup(bool launch); void setDockWhenObscured(bool dock) { mDockWhenObscured->setOn(dock); } void enableSessionManagement(bool sm) { mSessionManagement->setOn(sm); } @@ -75,15 +74,14 @@ private slots: void setCustomIcon(void); void updateMenu(); void slotSetBalloonTimeout(void); - void slotSetLaunchOnStartup(void); private: void installMenu(); bool mUndockWhenDead; - TQPopupMenu *mOptionsMenu, *mMainMenu; - TQAction *mDockOnRestore, *mAutoLaunch, *mBalloonTimeout, *mSkipTaskbar, - *mDockWhenMinimized, *mDockWhenObscured, *mSessionManagement, - *mDockWhenFocusLost; + TQPopupMenu *mMainMenu; + TDEPopupMenu *mOptionsMenu; + TQAction *mDockOnRestore, *mBalloonTimeout, *mSkipTaskbar, *mDockWhenMinimized, + *mDockWhenObscured, *mSessionManagement, *mDockWhenFocusLost; int mShowId; }; diff --git a/src/main.cpp b/src/main.cpp index 1cd955e..b61d52e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,6 +24,10 @@ #include #include +#include +#include +#include +#include #include #include @@ -36,14 +40,33 @@ static void sighandler(int sig) { if (sig == SIGUSR1) { - DUMP_TRACE(TQDir::homeDirPath() + "/tdedocker.trace"); + DUMP_TRACE((TQDir::homeDirPath() + "/tdedocker.trace").ascii()); return; } tqDebug("%s", i18n("Caught signal %1. Cleaning up.").arg(sig).local8Bit().data()); ((TDEDocker *)tqApp)->trayLabelMgr()->undockAll(); + ::exit(0); } +static const TDECmdLineOptions options[] = +{ + { "b", I18N_NOOP("Dont warn about non-normal windows (blind mode)"), 0L }, + { "d", I18N_NOOP("Disable session management"), 0L }, + { "e", I18N_NOOP("Enable session management"), 0L }, + { "f", I18N_NOOP("Dock window that has the focus(active window)"), 0L }, + { "i icon", I18N_NOOP("Custom dock Icon"), 0L }, + { "m", I18N_NOOP("Keep application window mapped (dont hide on dock)"), 0L }, + { "o", I18N_NOOP("Dock when obscured"), 0L }, + { "p secs", I18N_NOOP("Set ballooning timeout (popup time)"), 0L }, + { "q", I18N_NOOP("Disable ballooning title changes (quiet)"), 0L }, + { "t", I18N_NOOP("Remove this application from the task bar"), 0L }, + { "w wid", I18N_NOOP("Window id of the application to dock"), 0L }, + { "+[command ]", I18N_NOOP("Application to dock"), 0 }, + TDECmdLineLastOption +}; + +//extern "C" int KDE_EXPORT kdemain(int argc, char* argv[]) int main(int argc, char *argv[]) { // setup signal handlers that undock and quit @@ -52,6 +75,17 @@ int main(int argc, char *argv[]) signal(SIGINT, sighandler); signal(SIGUSR1, sighandler); - TDEDocker app(argc, argv); + 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); + about.addAuthor("John Schember", I18N_NOOP("Original KDocker maintainer"), "john@nachtimwald.com"); + about.addAuthor("Girish Ramakrishnan", I18N_NOOP("Original KDocker developer"), "ramakrishnan.girish@gmail.com"); + + TDEGlobal::locale()->setMainCatalogue("tdedocker"); + + TDECmdLineArgs::init(argc, argv, &about); + TDECmdLineArgs::addCmdLineOptions(options); + TDEDocker::addCmdLineOptions(); + TDEDocker app; + return app.exec(); } diff --git a/src/qtraylabel.cpp b/src/qtraylabel.cpp index 38a8381..a74ba48 100644 --- a/src/qtraylabel.cpp +++ b/src/qtraylabel.cpp @@ -30,7 +30,7 @@ #include #include #include "trace.h" -#include "qtraylabel.h" +#include #include #include @@ -43,9 +43,10 @@ #include #include #include - #include "util.h" +#include "qtraylabel.h" + void TQTrayLabel::initialize(void) { mDocked = false; @@ -82,7 +83,7 @@ const char *TQTrayLabel::me(void) const { static char temp[100]; snprintf(temp, sizeof(temp), "(%s,PID=%i,WID=0x%x)", - mProgName[0].latin1(), mPid, (unsigned) mDockedWindow); + mProgName[0].local8Bit().data(), mPid, (unsigned) mDockedWindow); return temp; } @@ -128,15 +129,15 @@ void TQTrayLabel::scanClients() for(unsigned i=0; itext().latin1(), TQToolTip::textFor(this).latin1()); - + mBalloon->text().local8Bit(), TQToolTip::textFor(this).local8Bit()); + if (mBalloon->text() == TQToolTip::textFor(this)) return; #if 0 // I_GOT_NETWM_BALLOONING_TO_WORK // if you can get NET WM ballooning to work let me know @@ -528,7 +529,7 @@ void TQTrayLabel::balloonText() SubstructureNotifyMask | SubstructureRedirectMask, l, sizeof(l)); int length = mTitle.length(); - const char *data = mTitle.latin1(); + const char *data = mTitle.local8Bit(); while (length > 0) { sendMessage(display, mSystemTray, winId(), "_NET_SYSTEM_TRAY_MESSAGE_DATA", 8, @@ -564,7 +565,7 @@ void TQTrayLabel::handleTitleChange(void) XFetchName(display, mDockedWindow, &window_name); mTitle = window_name; - TRACE("%s has title [%s]", me(), mTitle.latin1()); + TRACE("%s has title [%s]", me(), mTitle.local8Bit()); if (window_name) XFree(window_name); XClassHint ch; @@ -698,10 +699,10 @@ bool TQTrayLabel::x11EventFilter(XEvent *ev) mWithdrawn = true; unmapEvent(); } - else if (event->type == FocusOut) - { - focusLostEvent(); - } + else if (event->type == FocusOut) + { + focusLostEvent(); + } return true; // Dont process this again } @@ -712,8 +713,8 @@ bool TQTrayLabel::x11EventFilter(XEvent *ev) Display *display = TQPaintDevice::x11AppDisplay(); Window w = XmuClientWindow(display, ((XMapEvent *) event)->window); if (!isNormalWindow(display, w)) return FALSE; - if (!analyzeWindow(display, w, mPid, - TQFileInfo(mProgName[0]).fileName().latin1())) return FALSE; + if (!analyzeWindow(display, w, mPid, + TQFileInfo(mProgName[0]).fileName().local8Bit())) return FALSE; // All right. Lets dock this baby setDockedWindow(w); return true; @@ -759,8 +760,8 @@ void TQTrayLabel::propertyChangeEvent(Atom property) unsigned long nitems, after; unsigned char *data = NULL; int r = XGetWindowProperty(display, mDockedWindow, WM_STATE, - 0, 1, False, AnyPropertyType, &type, - &format, &nitems, &after, &data); + 0, 1, False, AnyPropertyType, &type, + &format, &nitems, &after, &data); if ((r == Success) && data && (*(long *) data == IconicState)) { @@ -771,40 +772,37 @@ void TQTrayLabel::propertyChangeEvent(Atom property) } // Session Management -bool TQTrayLabel::saveState(TQSettings &settings) +void TQTrayLabel::saveState(TDEConfig *config) { TRACE("%s saving state", me()); - settings.writeEntry("/Application", mProgName.join(" ")); - settings.writeEntry("/CustomIcon", mCustomIcon); - settings.writeEntry("/BalloonTimeout", mBalloonTimeout); - settings.writeEntry("/DockWhenMinimized", mDockWhenMinimized); - settings.writeEntry("/SkipTaskbar", mSkippingTaskbar); - settings.writeEntry("/Withdraw", mWithdrawn); - return true; + config->writeEntry("Application", mProgName.join(" ")); + config->writeEntry("BalloonTimeout", mBalloonTimeout); + config->writeEntry("CustomIcon", mCustomIcon); + config->writeEntry("DockWhenMinimized", mDockWhenMinimized); + config->writeEntry("SkipTaskbar", mSkippingTaskbar); + config->writeEntry("Withdraw", mWithdrawn); } -bool TQTrayLabel::restoreState(TQSettings &settings) +bool TQTrayLabel::restoreState(TDEConfig *config) { TRACE("%s restoring state", me()); - mCustomIcon = settings.readEntry("/CustomIcon"); - setBalloonTimeout(settings.readNumEntry("/BalloonTimeout")); - setDockWhenMinimized(settings.readBoolEntry("/DockWhenMinimized")); - setSkipTaskbar(settings.readBoolEntry("/SkipTaskbar")); - mWithdrawn = settings.readBoolEntry("/Withdraw"); + setBalloonTimeout(config->readNumEntry("BalloonTimeout", 4000)); + mCustomIcon = config->readEntry("CustomIcon", TQString::null); + setDockWhenMinimized(config->readBoolEntry("DockWhenMinimized", false)); + setSkipTaskbar(config->readBoolEntry("SkipTaskbar", false)); + mWithdrawn = config->readBoolEntry("Withdraw", false); dock(); - - /* - * Since we are getting restored, it is likely that the application that we - * are interested in has already been started (if we didnt launch it). - * So we scan the list of windows and grab the first one that satisfies us - * This implicitly assumes that if mPid!=0 then we launched it. Wait till - * the application really shows itself up before we do a scan (the reason - * why we have 2s - */ - if (!mPid) TQTimer::singleShot(2000, this, SLOT(scanClients())); - - return true; + scanClients(); // Grab window + if (mWithdrawn) + { + withdraw(); + } + else + { + map(); + } + return true; } // End kicking butt diff --git a/src/qtraylabel.h b/src/qtraylabel.h index 7fb645c..c0a9e72 100644 --- a/src/qtraylabel.h +++ b/src/qtraylabel.h @@ -42,6 +42,7 @@ class TQMouseEvent; class TQDragEnterEvent; class TQPoint; +class TDEConfig; class TQTrayLabel : public TQLabel { @@ -69,8 +70,8 @@ public: bool x11EventFilter(XEvent * event); // Session Management - virtual bool saveState(TQSettings& settings); - virtual bool restoreState(TQSettings& settings); + virtual void saveState(TDEConfig *config); + virtual bool restoreState(TDEConfig *config); public slots: void dock(void); // puts us in the system tray @@ -89,7 +90,7 @@ public slots: protected slots: void scanClients(void); // scans existing client connections - + signals: void clicked(const ButtonState&, const TQPoint&); void docked(TQTrayLabel *); // emitted when we get docked @@ -103,18 +104,18 @@ protected: // reimplement these event handlers in subclass as needed virtual void mouseReleaseEvent(TQMouseEvent *event); virtual void dragEnterEvent(TQDragEnterEvent *event); - + // the events that follow are events of the docked window (NOT TQTrayLabel) virtual void updateIcon(void); // updates the icon virtual void updateTitle(void); // sets the tooltip virtual void balloonText(void); // balloons text virtual void obscureEvent(void) { } virtual void mapEvent(void) { } - virtual void focusLostEvent(void) { } + virtual void focusLostEvent(void) { } virtual void unmapEvent(void) { } virtual void minimizeEvent(void); virtual void destroyEvent(void); - + // needs to return if we can unsubscribe for root virtual bool canUnsubscribeFromRoot(void) { return true; } // needs to return if we can dock a candidate window @@ -136,26 +137,28 @@ private: void initialize(void); void handleTitleChange(void); void handleIconChange(void); +public: const char *me(void) const; +private: // Member variables - long mDesktop; // desktop on which the window is being shown - TQLabel *mBalloon; // tooltip text simulator - TQString mCustomIcon; // CustomIcon of the docked application - Window mDockedWindow; // the window which is being docked - int mBalloonTimeout; + long mDesktop; // desktop on which the window is being shown + TQLabel *mBalloon; // tooltip text simulator + TQString mCustomIcon; // CustomIcon of the docked application + Window mDockedWindow; // the window which is being docked + int mBalloonTimeout; bool mDocked, mWithdrawn, mSkippingTaskbar; bool mDockWhenMinimized; - TQString mTitle, mClass; // Title and hint of mDockedWindow + TQString mTitle, mClass; // Title and hint of mDockedWindow TQPixmap mAppIcon; // The current app icon (may not be same as pixmap()) - XSizeHints mSizeHint; // SizeHint of mDockedWindow + XSizeHints mSizeHint; // SizeHint of mDockedWindow - TQTimer mRealityMonitor; // Helps us sync up with reality - TQStringList mProgName; // The program whose window we are docking + TQTimer mRealityMonitor; // Helps us sync up with reality + TQStringList mProgName; // The program whose window we are docking pid_t mPid; // The PID of program whose window we are docking - Window mSysTray; // System tray window id + Window mSysTray; // System tray window id }; #endif // _QTRAYLABEL_H diff --git a/src/tdedocker.cpp b/src/tdedocker.cpp index 2b404c7..2b24cf5 100644 --- a/src/tdedocker.cpp +++ b/src/tdedocker.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. - * + * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -19,7 +19,6 @@ // $Id: tdedocker.cpp,v 1.24 2005/02/04 10:25:46 cs19713 Exp $ -#include #include #include #include @@ -27,6 +26,8 @@ #include #include +#include +#include #include #include "trace.h" @@ -39,83 +40,37 @@ #include #include -// #define TMPFILE_PREFIX TQString("/tmp/tdedocker.") -#define TMPFILE_PREFIX TQDir::homeDirPath() + "/.tdedocker." +#define TMPFILE_PREFIX TQString("/tmp/tdedocker.") -TDEDocker::TDEDocker(int& argc, char** argv) - :TQApplication(argc, argv), mTrayLabelMgr(0) +TDEDocker::TDEDocker() + : TDEApplication(), mTrayLabelMgr(NULL), firstSaveState(true) { INIT_TRACE(); - - // Attempt doing anything only if the CLI arguments were good - opterr = 0; // suppress the warning - int option; - while ((option = getopt(argc, argv, TrayLabelMgr::options().latin1())) != EOF) - { - if (option == '?') - { - if (optopt == 'v') printVersion(); else printUsage(optopt); - ::exit(0); - } - } - /* * Detect and transfer control to previous instance (if one exists) - * _KDOCKER_RUNNING is a X Selection. We start out by trying to locate the + * _TDEDOCKER_RUNNING is a X Selection. We start out by trying to locate the * selection owner. If someone else owns it, transfer control to that * instance of TDEDocker */ Display *display = TQPaintDevice::x11AppDisplay(); - Atom tdedocker = XInternAtom(display, "_KDOCKER_RUNNING", False); + Atom tdedocker = XInternAtom(display, "_TDEDOCKER_RUNNING", False); Window prev_instance = XGetSelectionOwner(display, tdedocker); if (prev_instance == None) { - mSelectionOwner = XCreateSimpleWindow(display, tqt_xrootwin(), 1, 1, 1, - 1, 1, 1, 1); + 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); XSetSelectionOwner(display, tdedocker, mSelectionOwner, CurrentTime); TRACE("Selection owner set to 0x%x", (unsigned) mSelectionOwner); mTrayLabelMgr = TrayLabelMgr::instance(); } else - notifyPreviousInstance(prev_instance); // does not return -} - -void TDEDocker::printVersion(void) -{ - tqDebug("TQt: %s", tqVersion()); - tqDebug("TDEDocker: %s", KDOCKER_APP_VERSION); -} - -// Prints the CLI arguments. Does not return -void TDEDocker::printUsage(char optopt) -{ - if (optopt != 'h') tqDebug("%s", i18n("tdedocker: invalid option -- %1").arg(optopt).local8Bit().data()); - - tqDebug("%s", i18n("Usage: TDEDocker [options] command\n").local8Bit().data()); - tqDebug("%s", i18n("Docks any application into the system tray\n").local8Bit().data()); - tqDebug("%s", i18n("command \tCommand to execute\n").local8Bit().data()); - tqDebug("%s", i18n("Options").local8Bit().data()); - tqDebug("%s", i18n("-a \tShow author information").local8Bit().data()); - tqDebug("%s", i18n("-b \tDont warn about non-normal windows (blind mode)").local8Bit().data()); - tqDebug("%s", i18n("-d \tDisable session management").local8Bit().data()); - tqDebug("%s", i18n("-e \tEnable session management").local8Bit().data()); - tqDebug("%s", i18n("-f \tDock window that has the focus(active window)").local8Bit().data()); - tqDebug("%s", i18n("-h \tDisplay this help").local8Bit().data()); - tqDebug("%s", i18n("-i icon\tCustom dock Icon").local8Bit().data()); - tqDebug("%s", i18n("-l \tLaunch on startup").local8Bit().data()); - tqDebug("%s", i18n("-m \tKeep application window mapped (dont hide on dock)").local8Bit().data()); - tqDebug("%s", i18n("-o \tDock when obscured").local8Bit().data()); - tqDebug("%s", i18n("-p secs\tSet ballooning timeout (popup time)").local8Bit().data()); - tqDebug("%s", i18n("-q \tDisable ballooning title changes (quiet)").local8Bit().data()); - tqDebug("%s", i18n("-t \tRemove this application from the task bar").local8Bit().data()); - tqDebug("%s", i18n("-v \tDisplay version").local8Bit().data()); - tqDebug("%s", i18n("-w wid \tWindow id of the application to dock\n").local8Bit().data()); - - tqDebug("%s", i18n("NOTE: Use -d for all startup scripts.\n").local8Bit().data()); - - tqDebug("%s", i18n("Bugs and wishes to gramakri@uiuc.edu").local8Bit().data()); - tqDebug("%s", i18n("Project information at http://tdedocker.sourceforge.net").local8Bit().data()); + notifyPreviousInstance(prev_instance); // does not return } void TDEDocker::notifyPreviousInstance(Window prevInstance) @@ -128,18 +83,22 @@ void TDEDocker::notifyPreviousInstance(Window prevInstance) TQFile f(TMPFILE_PREFIX + TQString().setNum(getpid())); if (!f.open(IO_WriteOnly)) return; TQTextStream s(&f); - - /* - * Its normal to use TDEDocker in startup scripts. We could be getting restored - * from a session at the same time. So, if we were getting restored and - * another instance already exists, send across the session id. Remember, qt - * strips out all the arguments that it understands. So need to do it by hand. - */ - if (isSessionRestored()) - s << argv()[0] << " " << "-session" << " " << sessionId(); - else - for (int i = 0; i < argc(); i++) s << argv()[i] << " "; + // Its normal to use TDEDocker in startup scripts. We could be getting restored + // from a session at the same time, so in such case pass along the info. + if (isRestored()) + { + s << TDECmdLineArgs::appName() << " --restore-internal"; + } + else + { + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + s << TDECmdLineArgs::appName(); + for (int i = 0; i < args->count(); i++) + { + s << " " << args->arg(i); + } + } f.close(); /* @@ -154,7 +113,7 @@ void TDEDocker::notifyPreviousInstance(Window prevInstance) dock_event.type = ClientMessage; dock_event.message_type = 0x220679; // it all started this day dock_event.format = 8; - dock_event.data.l[0] = 0xBABE; // love letter ;) + dock_event.data.l[0] = 0xBABE; // love letter ;) dock_event.data.l[1] = getpid(); XSendEvent(display, prevInstance, False, 0, (XEvent *) &dock_event); XSync(display, False); @@ -179,7 +138,7 @@ bool TDEDocker::x11EventFilter(XEvent * event) client->data.l[1], (unsigned) mSelectionOwner); char tmp[50]; struct stat buf; - sprintf(tmp, TQString(TMPFILE_PREFIX "%ld").local8Bit(), client->data.l[1]); + sprintf(tmp, TQString(TMPFILE_PREFIX+"%ld").local8Bit(), client->data.l[1]); if (stat(tmp, &buf) || (getuid()!=buf.st_uid)) { /* @@ -204,30 +163,14 @@ bool TDEDocker::x11EventFilter(XEvent * event) mTrayLabelMgr->processCommand(argv); return TRUE; } - else return mTrayLabelMgr->x11EventFilter(event); -} - -/* - * XSMP Support - */ -void TDEDocker::saveState(TQSessionManager &sm) -{ - TQString sf = mTrayLabelMgr->saveSession(); - - TQStringList discard_command; - discard_command << "rm" << sf; - sm.setDiscardCommand(discard_command); - - sm.setRestartHint(TQSessionManager::RestartIfRunning); - TQStringList restart_command; - restart_command << this->argv()[0] - << "-session" << sm.sessionId(); - sm.setRestartCommand(restart_command); - - TRACE("SessionFile=%s AppName=%s", sf.latin1(), this->argv()[0]); - DUMP_TRACE(TQDir::homeDirPath() + "/tdedocker.trace"); - // sm.setRestartCommand(applicationFilePath()); + else + { + if (mTrayLabelMgr->x11EventFilter(event)) + { + return true; + } + return TDEApplication::x11EventFilter(event); + } } - #include "tdedocker.moc" diff --git a/src/tdedocker.h b/src/tdedocker.h index 46d0e13..c445a36 100644 --- a/src/tdedocker.h +++ b/src/tdedocker.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. - * + * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -19,41 +19,34 @@ // $Id: tdedocker.h,v 1.11 2005/02/09 03:32:26 cs19713 Exp $ -#ifndef _KDOCKER_H -#define _KDOCKER_H +#ifndef _TDEDOCKER_H +#define _TDEDOCKER_H -#include +#include #include -#define KDOCKER_APP_VERSION "1.3" - class TrayLabelMgr; -class TDEDocker : public TQApplication +class TDEDocker : public TDEApplication { Q_OBJECT public: - TDEDocker(int& argc, char** argv); + TDEDocker(); TrayLabelMgr *trayLabelMgr(void) { return mTrayLabelMgr; } void dumpState(const TQString &file); - void printUsage(char optopt = 'h'); protected: bool x11EventFilter(XEvent * event); - void saveState(TQSessionManager &sm); private: - TQString saveSession(); - bool restoreSession(); void notifyPreviousInstance(Window prevInstance); - void printVersion(); - Window mSelectionOwner; TrayLabelMgr *mTrayLabelMgr; + bool firstSaveState; }; -#endif // _KDOCKER_H +#endif // _TDEDOCKER_H diff --git a/src/trace.cpp b/src/trace.cpp index effcd64..9f2d06d 100644 --- a/src/trace.cpp +++ b/src/trace.cpp @@ -11,7 +11,7 @@ void TRACER(TQtMsgType, const char *msg) tracer->append(&msg[*msg == '~' ? 1 : 0]); if (msg[0] != '~') { - fprintf(stderr, msg); + fprintf(stderr, "%s", msg); fprintf(stderr, "\r\n"); } } diff --git a/src/traylabelmgr.cpp b/src/traylabelmgr.cpp index 40c8231..ae32167 100644 --- a/src/traylabelmgr.cpp +++ b/src/traylabelmgr.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. - * + * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -19,17 +19,14 @@ // $Id: traylabelmgr.cpp,v 1.10 2005/02/09 03:38:43 cs19713 Exp $ -#include -#include -#include -#include #include -#include -#include #include -#include +#include +#include +#include #include +#include #include "trace.h" #include "traylabelmgr.h" @@ -40,9 +37,9 @@ #include TrayLabelMgr* TrayLabelMgr::gTrayLabelMgr = NULL; -const char *TrayLabelMgr::mOptionString = "+abdefi:lmop:qtw:"; +const char *TrayLabelMgr::mOptionString = "+bdefi:lmop:qtw:"; -TrayLabelMgr* TrayLabelMgr::instance(void) +TrayLabelMgr* TrayLabelMgr::instance() { if (gTrayLabelMgr) return gTrayLabelMgr; TRACE("Creating new instance"); @@ -51,6 +48,8 @@ TrayLabelMgr* TrayLabelMgr::instance(void) TrayLabelMgr::TrayLabelMgr() : mReady(false), mHiddenLabelsCount(0) { + connect(&restoreSessionTimer, SIGNAL(timeout()), this, SLOT(doRestoreSession())); + // Set ourselves up to be called from the application loop TQTimer::singleShot(0, this, SLOT(startup())); } @@ -60,15 +59,6 @@ TrayLabelMgr::~TrayLabelMgr() undockAll(); } -void TrayLabelMgr::about(void) -{ - if (TQMessageBox::information(NULL, i18n("About TDEDocker"), - i18n("Bugs/wishes to Girish Ramakrishnan (gramakri@uiuc.edu)\n" - "English translation by Girish (gramakri@uiuc.edu)\n\n" - "http://tdedocker.sourceforge.net for updates"), - TQString::null, SHOW_TRACE_TEXT) == 1) SHOW_TRACE(); -} - void TrayLabelMgr::startup(void) { const int WAIT_TIME = 10; @@ -78,7 +68,7 @@ void TrayLabelMgr::startup(void) * stdout is a tty) OR if we are getting restored, wait for WAIT_TIME until * the system tray shows up (before informing the user) */ - static bool do_wait = !isatty(fileno(stdout)) || tqApp->isSessionRestored(); + static bool do_wait = !isatty(fileno(stdout)) || TDEApplication::kApplication()->isRestored(); SysTrayState state = sysTrayStatus(TQPaintDevice::x11AppDisplay()); @@ -91,10 +81,9 @@ void TrayLabelMgr::startup(void) return; } - if (TQMessageBox::warning(NULL, i18n("TDEDocker"), - i18n(state == SysTrayAbsent ? "No system tray found" - : "System tray appears to be hidden"), - TQMessageBox::Abort, TQMessageBox::Ignore) == TQMessageBox::Abort) + if (KMessageBox::warningContinueCancel(NULL, + state == SysTrayAbsent ? i18n("No system tray found") : i18n("System tray appears to be hidden"), + i18n("TDEDocker")) == KMessageBox::Cancel) { tqApp->quit(); return; @@ -104,10 +93,17 @@ void TrayLabelMgr::startup(void) // Things are fine or user with OK with the state of system tray mReady = true; bool ok = false; - if (tqApp->isSessionRestored()) ok = restoreSession(tqApp->sessionId()); - else ok = processCommand(tqApp->argc(), tqApp->argv()); - // Process the request Q from previous instances + if (TDEApplication::kApplication()->isRestored()) + { + restoreSession(); + ok = true; + } + else + { + ok = processCommand(TDECmdLineArgs::parsedArgs()); + } + // Process the request Q from previous instances TRACE("Request queue has %i requests", mRequestQ.count()); for(unsigned i=0; i < mRequestQ.count(); i++) ok |= processCommand(mRequestQ[i]); @@ -117,8 +113,7 @@ void TrayLabelMgr::startup(void) // Initialize a TQTrayLabel after its creation void TrayLabelMgr::manageTrayLabel(TQTrayLabel *t) { - connect(t, SIGNAL(destroyed(TQObject *)), - this, SLOT(trayLabelDestroyed(TQObject *))); + connect(t, SIGNAL(destroyed(TQObject *)), this, SLOT(trayLabelDestroyed(TQObject *))); connect(t, SIGNAL(undocked(TQTrayLabel *)), t, SLOT(deleteLater())); // All TQTrayLabels will emit this signal. We just need one of them @@ -152,7 +147,7 @@ void TrayLabelMgr::undockAll() } // Process the command line -bool TrayLabelMgr::processCommand(const TQStringList& args) +bool TrayLabelMgr::processCommand(const TQStringList &args) { if (!mReady) { @@ -161,19 +156,83 @@ bool TrayLabelMgr::processCommand(const TQStringList& args) return true; } - const int MAX_ARGS = 20; + const int MAX_ARGS = 50; const char *argv[MAX_ARGS]; int argc = args.count(); if (argc >= MAX_ARGS) argc = MAX_ARGS - 1; - for(int i =0 ; i(argv)); } +// Process the command line +bool TrayLabelMgr::processCommand(TDECmdLineArgs *args) +{ + TQStringList argl; + argl.append(TDECmdLineArgs::appName()); + + if (args->isSet("b")) + { + argl.append("-b"); + } + if (args->isSet("d")) + { + argl.append("-d"); + } + if (args->isSet("e")) + { + argl.append("-e"); + } + if (args->isSet("f")) + { + argl.append("-f"); + } + if (args->isSet("i")) + { + argl.append("-i"); + argl.append(args->getOption("i")); + } + if (args->isSet("m")) + { + argl.append("-m"); + } + if (args->isSet("o")) + { + argl.append("-o"); + } + if (args->isSet("p")) + { + argl.append("-p"); + argl.append(args->getOption("p")); + } + if (args->isSet("q")) + { + argl.append("-q"); + } + if (args->isSet("t")) + { + argl.append("-t"); + } + if (args->isSet("w")) + { + argl.append("-w"); + argl.append(args->getOption("w")); + } + + for (int i = 0; i < args->count(); ++i) + { + argl.append(args->arg(i)); + } + + return processCommand(argl); +} + // Process the command line bool TrayLabelMgr::processCommand(int argc, char** argv) { @@ -182,11 +241,12 @@ bool TrayLabelMgr::processCommand(int argc, char** argv) if (argc < 1) return false; - // Restore session (See the comments in TDEDocker::notifyPreviousInstance() - if (qstrcmp(argv[1], "-session") == 0) + // Restore session (see the comments in TDEDocker::notifyPreviousInstance() ) + if (qstrcmp(argv[1], "--restore-internal") == 0) { - TRACE("Restoring session %s (new instance request)", argv[2]); - return restoreSession(TQString(argv[2])); + TRACE("Restoring session (new instance request)"); + restoreSession(); + return true; } int option; @@ -194,8 +254,7 @@ bool TrayLabelMgr::processCommand(int argc, char** argv) const char *icon = NULL; int balloon_timeout = 4000; bool withdraw = true, skip_taskbar = false, - auto_launch = false, dock_obscure = false, check_normality = true, - enable_sm = true; + dock_obscure = false, check_normality = true, enable_sm = true; optind = 0; // initialise the getopt static @@ -205,9 +264,6 @@ bool TrayLabelMgr::processCommand(int argc, char** argv) { case '?': return false; - case 'a': - tqDebug("%s", i18n("Girish Ramakrishnan (gramakri@uiuc.edu)").local8Bit().data()); - return false; case 'b': check_normality = false; break; @@ -224,9 +280,6 @@ bool TrayLabelMgr::processCommand(int argc, char** argv) case 'i': icon = optarg; break; - case 'l': - auto_launch = true; - break; case 'm': withdraw = false; break; @@ -259,7 +312,7 @@ bool TrayLabelMgr::processCommand(int argc, char** argv) // Launch an application if present in command line. else request from user CustomTrayLabel *t = (CustomTrayLabel *) // this should be dynamic_cast ((optind < argc) ? dockApplication(&argv[optind]) - : selectAndDock(w, check_normality)); + : selectAndDock(w, check_normality)); if (t == NULL) return false; // apply settings and add to tray manageTrayLabel(t); @@ -270,7 +323,6 @@ bool TrayLabelMgr::processCommand(int argc, char** argv) if (withdraw) t->withdraw(); else t->map(); t->enableSessionManagement(enable_sm); t->dock(); - t->setLaunchOnStartup(auto_launch); return true; } @@ -285,10 +337,13 @@ TQTrayLabel *TrayLabelMgr::selectAndDock(Window w, bool checkNormality) tqDebug("%s", i18n("Click any other button to abort\n").local8Bit().data()); const char *err = NULL; - + if ((w = selectWindow(TQPaintDevice::x11AppDisplay(), &err)) == None) { - if (err) TQMessageBox::critical(NULL, i18n("TDEDocker"), i18n(err)); + if (err) + { + KMessageBox::error(NULL, err, i18n("TDEDocker")); + } return NULL; } } @@ -299,20 +354,20 @@ TQTrayLabel *TrayLabelMgr::selectAndDock(Window w, bool checkNormality) * Abort should be the only option here really. "Ignore" is provided here * for the curious user who wants to screw himself very badly */ - if (TQMessageBox::warning(NULL, i18n("TDEDocker"), - i18n("The window you are attempting to dock does not seem to be a" - " normal window."), TQMessageBox::Abort, - TQMessageBox::Ignore) == TQMessageBox::Abort) + if (KMessageBox::warningContinueCancel(NULL, + i18n("The window you are attempting to dock does not seem to be a normal window."), + i18n("TDEDocker")) == KMessageBox::Cancel) + { return NULL; + } } if (!isWindowDocked(w)) return new CustomTrayLabel(w); TRACE("0x%x is not docked", (unsigned) w); - TQMessageBox::message(i18n("TDEDocker"), - i18n("This window is already docked.\n" - "Click on system tray icon to toggle docking.")); + KMessageBox::error(NULL, i18n("This window is already docked.\n" + "Click on system tray icon to toggle docking."), i18n("TDEDocker")); return NULL; } @@ -321,7 +376,7 @@ bool TrayLabelMgr::isWindowDocked(Window w) TQPtrListIterator it(mTrayLabels); for(TQTrayLabel *t; (t = it.current()); ++it) if (t->dockedWindow() == w) return true; - + return false; } @@ -349,7 +404,6 @@ TQTrayLabel *TrayLabelMgr::dockApplication(char *argv[]) close(filedes[1]); read(filedes[0], buf, sizeof(buf)); close(filedes[0]); - if (execvp(argv[0], argv) == -1) { tqDebug("%s", i18n("Failed to exec [%1]: %2").arg(argv[0]).arg(strerror(errno)).local8Bit().data()); @@ -360,8 +414,7 @@ TQTrayLabel *TrayLabelMgr::dockApplication(char *argv[]) if (pid == -1) { - TQMessageBox::critical(NULL, "TDEDocker", - i18n("Failed to fork: %1").arg(strerror(errno))); + KMessageBox::error(NULL, i18n("Failed to fork: %1").arg(strerror(errno)), i18n("Ignore")); return NULL; } @@ -427,72 +480,60 @@ void TrayLabelMgr::notifySysTrayAbsence() if (state == SysTrayPresent) return; // So sweet of the systray to come back so soon - if (TQMessageBox::warning(NULL, i18n("TDEDocker"), - i18n("The System tray was hidden or removed"), - i18n("Undock All"), i18n("Ignore")) == 0) - undockAll(); + KMessageBox::error(NULL, i18n("The System tray was hidden or removed. All applications " + "will be undocked."), i18n("TDEDocker")); + undockAll(); } -/* - * Session Management. Always return "true". Atleast, for now - */ -bool TrayLabelMgr::restoreSession(const TQString& sessionId) +void TrayLabelMgr::restoreSession() { - TQString session_file = "tdedocker_" + sessionId; + // After restoring a session, the TDE session manager will relaunch the applications + // that were previously docked before terminating the previous session. To avoid + // launching the same apps twice, wait for a while before restoring the tdedocker + // session, so that we give tdedocker a chance to simply docks the applications + // already launched by TDE session manager. + restoreSessionTimer.start(5000, true); +} - TQSettings settings; - settings.beginGroup(TQString("/" + session_file)); +void TrayLabelMgr::doRestoreSession() +{ + TRACE("Restoring session"); - for(int i = 1;; i++) + TDEConfig *config = TDEApplication::kApplication()->sessionConfig(); + for (int i = 1; ; ++i) { - settings.beginGroup(TQString("/Instance") + TQString("").setNum(i)); - TQString pname = settings.readEntry("/Application"); - TRACE("Restoring Application[%s]", pname.latin1()); - if (pname.isEmpty()) break; - if (settings.readBoolEntry("/LaunchOnStartup")) + if (!config->hasGroup("Instance" + TQString::number(i))) { - TQStringList args("tdedocker"); - args += TQStringList::split(" ", pname); - TRACE("Triggering AutoLaunch"); - if (!processCommand(args)) continue; + return; } - else + config->setGroup("Instance" + TQString::number(i)); + TQString pname = config->readEntry("Application", TQString::null); + if (!pname.isEmpty()) + { + TRACE("Restoring Application[%s]", pname.ascii()); manageTrayLabel(new CustomTrayLabel(TQStringList::split(" ", pname), 0)); - - TQTrayLabel *tl = mTrayLabels.getFirst(); // the one that was created above - tl->restoreState(settings); - settings.endGroup(); + mTrayLabels.getFirst()->restoreState(config); + } } - - return true; } -TQString TrayLabelMgr::saveSession(void) +bool TrayLabelMgr::saveState(TQSessionManager &sm) { - TQString session_file = "tdedocker_" + tqApp->sessionId(); - - TQSettings settings; - settings.beginGroup(TQString("/" + session_file)); - TRACE("Saving session"); - TQPtrListIterator it(mTrayLabels); - TQTrayLabel *t; int i = 1; - while ((t = it.current()) != 0) + TQTrayLabel *t; + TDEConfig *config = TDEApplication::kApplication()->sessionConfig(); + TQPtrListIterator it(mTrayLabels); + for (it.toFirst(); it.current(); ++it) { - ++it; + t = it.current(); TRACE("Saving instance %i", i); - settings.beginGroup(TQString("/Instance") + TQString("").setNum(i)); - bool ok = t->saveState(settings); - settings.endGroup(); - if (ok) ++i; else TRACE("Saving of instance %i was skipped", i); + config->setGroup("Instance" + TQString::number(i)); + t->saveState(config); + ++i; } - - // Aaaaaaaaaaaaaa......... - settings.removeEntry(TQString("/Instance") + TQString("").setNum(i)); - - return TQDir::homeDirPath() + "/.qt/" + session_file + "rc"; + return true; } /* @@ -509,7 +550,7 @@ bool TrayLabelMgr::x11EventFilter(XEvent *ev) { TQPtrListIterator it(mTrayLabels); bool ret = false; - + // We pass on the event to all tray labels for(TQTrayLabel *t; (t = it.current()); ++it) { diff --git a/src/traylabelmgr.h b/src/traylabelmgr.h index 8a27a6c..90ff1ba 100644 --- a/src/traylabelmgr.h +++ b/src/traylabelmgr.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. - * + * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -25,12 +25,16 @@ #include #include #include +#include +#include #include "customtraylabel.h" class CustomTrayLabel; +class TDECmdLineArgs; +class TQSessionManager; -class TrayLabelMgr : public TQObject +class TrayLabelMgr : public TQObject, public KSessionManaged { Q_OBJECT @@ -40,21 +44,21 @@ public: ~TrayLabelMgr(); - TQString saveSession(); + bool saveState(TQSessionManager &sm); bool x11EventFilter(XEvent *); - bool processCommand(const TQStringList& argv); + bool processCommand(const TQStringList &argv); int hiddenLabelsCount(void) const; int dockedLabelsCount(void) const; bool isWindowDocked(Window w); - + public slots: - void about(); void undockAll(); void dockAnother(); private slots: void startup(); + void doRestoreSession(); void trayLabelDestroyed(TQObject *); void sysTrayDestroyed(void); void notifySysTrayAbsence(); @@ -62,17 +66,19 @@ private slots: private: TrayLabelMgr(); bool processCommand(int argc, char** argv); + bool processCommand(TDECmdLineArgs *args); void manageTrayLabel(TQTrayLabel *l); - bool restoreSession(const TQString& sessionId); - + void restoreSession(); + TQTrayLabel *dockApplication(char *argv[]); TQTrayLabel *selectAndDock(Window w = None, bool checkNormality = true); TQPtrList mTrayLabels; TQValueList mRequestQ; + TQTimer restoreSessionTimer; bool mReady; int mHiddenLabelsCount; - + static const char *mOptionString; static TrayLabelMgr *gTrayLabelMgr; }; diff --git a/src/util.cpp b/src/util.cpp index afbb578..541aece 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. - * + * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -54,7 +54,7 @@ bool isNormalWindow(Display *display, Window w) Atom *data = NULL; unsigned long nitems; Window transient_for = None; - + static Atom wmState = XInternAtom(display, "WM_STATE", False); static Atom windowState = XInternAtom(display, "_NET_WM_STATE", False); static Atom modalWindow = @@ -71,11 +71,11 @@ bool isNormalWindow(Display *display, Window w) &nitems, &left, (unsigned char **) &data); TRACE("0x%x (%i)", (unsigned) w, (unsigned) w); - + if (ret != Success || data == NULL) return false; TRACE("\tHas WM_STATE"); if (data) XFree(data); - + ret = XGetWindowProperty(display, w, windowState, 0, 10, False, AnyPropertyType, &type, &format, &nitems, &left, (unsigned char **) &data); @@ -126,9 +126,9 @@ pid_t pid(Display *display, Window w) pid_t pid_return = -1; if (XGetWindowProperty(display, w, - XInternAtom(display, "_NET_WM_PID", False), 0, - 1, False, XA_CARDINAL, &actual_type, - &actual_format, &nitems, &leftover, &pid) == Success) + XInternAtom(display, "_NET_WM_PID", False), 0, + 1, False, XA_CARDINAL, &actual_type, + &actual_format, &nitems, &leftover, &pid) == Success) { if (pid) pid_return = *(pid_t *) pid; XFree(pid); @@ -162,10 +162,13 @@ bool analyzeWindow(Display *display, Window w, pid_t epid, const TQString &ename { XClassHint ch; pid_t apid = pid(display, w); - - TRACE("WID=0x%x PID=%i ExpectedName=%s", (unsigned) w, (unsigned) epid, - ename.latin1()); + + TRACE("WID=0x%x EPID=%i APID=%i ExpectedName=%s", (unsigned) w, (unsigned) epid, (unsigned) apid, + ename.local8Bit()); if (epid == apid) return true; + // Only analyze window name if no process pid was provided, to avoid associating + // the wrong window to a given process + if (epid) return false; // no plans to analyze windows without a name char *window_name = NULL; @@ -256,7 +259,7 @@ Window selectWindow(Display *display, const char **err) if (err) *err = "Failed to grab mouse"; return None; } - + XAllowEvents(display, SyncPointer, CurrentTime); XEvent event; XWindowEvent(display, root, ButtonPressMask, &event); @@ -309,7 +312,7 @@ bool getCardinalProperty(Display *display, Window w, Atom prop, long *data) int format; unsigned long nitems, bytes; unsigned char *d = NULL; - + if (XGetWindowProperty(display, w, prop, 0, 1, False, XA_CARDINAL,&type, &format, &nitems, &bytes, &d) == Success && d) { diff --git a/src/util.h b/src/util.h index f29e58a..9b9afb1 100644 --- a/src/util.h +++ b/src/util.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. - * + * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or diff --git a/tdedocker.desktop b/tdedocker.desktop index 36ba42c..04c0848 100644 --- a/tdedocker.desktop +++ b/tdedocker.desktop @@ -1,6 +1,6 @@ [Desktop Entry] Name=TDEDocker -GenericName=Docking utility +GenericName=Application docking utility Comment=Docks any application into system tray Exec=tdedocker TryExec=tdedocker