diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-03-16 21:58:44 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-03-16 21:58:44 +0900 |
commit | ab3e99d8ee8ef5b53dcd1e6f90e3cdbbc08322e3 (patch) | |
tree | e622bfddde12ec89c8a84bfefec8dce7140109db /src | |
parent | d9e1d9fa71544a674d213117c0b675a0e874e556 (diff) | |
download | tdedocker-ab3e99d8ee8ef5b53dcd1e6f90e3cdbbc08322e3.tar.gz tdedocker-ab3e99d8ee8ef5b53dcd1e6f90e3cdbbc08322e3.zip |
Conversion to TDE application.
Notable changes:
1) save/restore data are saved in TDE session files.
2) remove -a, -l options. Removed "Launch on startup" option.
3) docked application are restored automatically by the TDE session
manager. After being restored, tdedocker will wait for 5 seconds to let
the various applications be restored, then it will try to grab the
required windows.
4) save/restore of docked applications is now working properly.
5) due to the way TDE manages command line options, at the moment
additional parameters cannot be passed to the application to be
docked. This will be address in a subsequent commit.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/customtraylabel.cpp | 147 | ||||
-rw-r--r-- | src/customtraylabel.h | 20 | ||||
-rw-r--r-- | src/main.cpp | 38 | ||||
-rw-r--r-- | src/qtraylabel.cpp | 130 | ||||
-rw-r--r-- | src/qtraylabel.h | 35 | ||||
-rw-r--r-- | src/tdedocker.cpp | 139 | ||||
-rw-r--r-- | src/tdedocker.h | 23 | ||||
-rw-r--r-- | src/trace.cpp | 2 | ||||
-rw-r--r-- | src/traylabelmgr.cpp | 257 | ||||
-rw-r--r-- | src/traylabelmgr.h | 24 | ||||
-rw-r--r-- | src/util.cpp | 27 | ||||
-rw-r--r-- | src/util.h | 2 |
13 files changed, 406 insertions, 439 deletions
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 <tqsettings.h> #include <tqpopupmenu.h> -#include <tqmessagebox.h> +#include <tdepopupmenu.h> #include <tqfiledialog.h> #include <tqinputdialog.h> -#include <tqaction.h> #include <tqtimer.h> -#include <tqsize.h> #include <stdlib.h> +#include <khelpmenu.h> +#include <kstdaction.h> #include <kiconloader.h> +#include <kstdguiitem.h> +#include <tdeaction.h> +#include <tdeconfig.h> #include <tdeglobal.h> #include <tdelocale.h> +#include <tdemessagebox.h> #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 <unistd.h> #include <signal.h> +#include <tdeaboutdata.h> +#include <tdeapplication.h> +#include <tdecmdlineargs.h> +#include <tdeglobal.h> #include <tdelocale.h> #include <tqdir.h> @@ -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 <args>]", 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 <tqfileinfo.h> #include <tqapplication.h> #include "trace.h" -#include "qtraylabel.h" +#include <tdeconfig.h> #include <kiconloader.h> #include <tdeglobal.h> @@ -43,9 +43,10 @@ #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> - #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; i<nchildren; i++) { Window w = XmuClientWindow(display, children[i]); - TRACE("\t%s checking 0x%x", me(), (unsigned) w); + TRACE("\t%s checking(1) 0x%x", me(), (unsigned) w); if (!isNormalWindow(display, w)) continue; - if (analyzeWindow(display, w, mPid, ename.latin1())) + if (analyzeWindow(display, w, mPid, ename.local8Bit())) { - TRACE("\t%s SOULMATE FOUND", me()); + TRACE("\t%s SOULMATE FOUND (1)", me()); setDockedWindow(w); - break; + return; } - } + } } /* @@ -222,8 +223,8 @@ void TQTrayLabel::dock(void) { TRACE("%s", me()); mDocked = true; - if (mDockedWindow == None) return; // nothing to add - + if (mDockedWindow == None) return; // nothing to add + if (mSysTray == None) // no system tray yet { TRACE("%s starting reality monitor", me()); @@ -243,7 +244,7 @@ void TQTrayLabel::dock(void) Atom tray_atom = XInternAtom(display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False); XChangeProperty(display, wid, tray_atom, XA_WINDOW, 32, - PropModeReplace, (unsigned char *) &wid, 1); + PropModeReplace, (unsigned char *) &wid, 1); // 3. All other KDEs tray_atom = XInternAtom(display, "KWM_DOCKWINDOW", False); @@ -254,8 +255,8 @@ void TQTrayLabel::dock(void) handleTitleChange(); handleIconChange(); - - if (mProgName.count() == 0) setAppName(mClass); + + if (mProgName.count() == 0) setAppName(mClass); /* * For Gnome, a delay is required before we do a show (dont ask me why) @@ -294,7 +295,7 @@ void TQTrayLabel::map(void) TRACE("%s", me()); mWithdrawn = false; if (mDockedWindow == None) return; - + Display *display = TQPaintDevice::x11AppDisplay(); if (mDesktop == -1) @@ -324,12 +325,12 @@ void TQTrayLabel::map(void) } XMapWindow(display, mDockedWindow); - mSizeHint.flags = USPosition; // Obsolete ? + mSizeHint.flags = USPosition; // Obsolete ? XSetWMNormalHints(display, mDockedWindow, &mSizeHint); // make it the active window long l[5] = { None, CurrentTime, None, 0, 0 }; sendMessage(display, tqt_xrootwin(), mDockedWindow, "_NET_ACTIVE_WINDOW", 32, - SubstructureNotifyMask | SubstructureRedirectMask, l, sizeof(l)); + SubstructureNotifyMask | SubstructureRedirectMask, l, sizeof(l)); // skipTaskbar modifies _NET_WM_STATE. Make sure we dont override WMs value TQTimer::singleShot(230, this, SLOT(skipTaskbar())); // disable docking when minized for some time (since we went to Iconic state) @@ -346,7 +347,7 @@ void TQTrayLabel::withdraw(void) Display *display = TQPaintDevice::x11AppDisplay(); int screen = DefaultScreen(display); long dummy; - + XGetWMNormalHints(display, mDockedWindow, &mSizeHint, &dummy); /* @@ -357,7 +358,7 @@ void TQTrayLabel::withdraw(void) * state will remove us from the taskbar. * Reference: ICCCM 4.1.4 Changing Window State */ - XIconifyWindow(display, mDockedWindow, screen); // good for effects too + XIconifyWindow(display, mDockedWindow, screen); // good for effects too XUnmapWindow(display, mDockedWindow); XUnmapEvent ev; memset(&ev, 0, sizeof(ev)); @@ -389,8 +390,8 @@ void TQTrayLabel::skipTaskbar(void) Atom _NET_WM_STATE = XInternAtom(display, "_NET_WM_STATE", True); Atom skip_atom = XInternAtom(display, "_NET_WM_STATE_SKIP_TASKBAR", False); int ret = XGetWindowProperty(display, mDockedWindow, _NET_WM_STATE, 0, - 20, False, AnyPropertyType, &type, &format, - &nitems, &left, (unsigned char **) &data); + 20, False, AnyPropertyType, &type, &format, + &nitems, &left, (unsigned char **) &data); Atom *old_states = (Atom *) data; bool append = true, replace = false; @@ -406,7 +407,7 @@ void TQTrayLabel::skipTaskbar(void) { if (num_states < nitems) { - replace = true; // need to remove skip_atom + replace = true; // need to remove skip_atom for (; num_states < nitems - 1; num_states++) old_states[num_states] = old_states[num_states + 1]; } @@ -442,6 +443,7 @@ void TQTrayLabel::setSkipTaskbar(bool skip) void TQTrayLabel::close(void) { TRACE("%s", me()); + undock(); Display *display = TQPaintDevice::x11AppDisplay(); long l[5] = { 0, 0, 0, 0, 0 }; map(); @@ -457,7 +459,7 @@ void TQTrayLabel::setTrayIcon(const TQString& icon) { mCustomIcon = icon; if (TQPixmap(mCustomIcon).isNull()) mCustomIcon = TQString::null; - TRACE("%s mCustomIcon=%s", me(), mCustomIcon.latin1()); + TRACE("%s mCustomIcon=%s", me(), mCustomIcon.local8Bit()); updateIcon(); } @@ -469,18 +471,17 @@ void TQTrayLabel::setTrayIcon(const TQString& icon) */ void TQTrayLabel::setDockedWindow(Window w) { - TRACE("%s %s reality monitor", me(), + TRACE("%s %s reality monitor", me(), mDockedWindow==None ? "Starting" : "Stopping"); // Check if we are allowed to dock this window (allows custom rules) if (w != None) mDockedWindow = canDockWindow(w) ? w : None; else mDockedWindow = None; - if (mDockedWindow == None) mRealityMonitor.start(500); - else mRealityMonitor.stop(); + if (mDockedWindow == None) mRealityMonitor.start(500); else mRealityMonitor.stop(); Display *d = TQPaintDevice::x11AppDisplay(); - + // Subscribe for window or root window events if (w == None) subscribe(d, None, SubstructureNotifyMask, true); else @@ -488,10 +489,10 @@ void TQTrayLabel::setDockedWindow(Window w) if (canUnsubscribeFromRoot()) subscribe(d, None, ~SubstructureNotifyMask, false); else subscribe(d, None, SubstructureNotifyMask, true); - + subscribe(d, w, StructureNotifyMask | PropertyChangeMask | - VisibilityChangeMask | FocusChangeMask, + VisibilityChangeMask | FocusChangeMask, true); } @@ -515,8 +516,8 @@ void TQTrayLabel::setDockedWindow(Window w) void TQTrayLabel::balloonText() { TRACE("%s BalloonText=%s ToolTipText=%s", me(), - mBalloon->text().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 <tqsessionmanager.h> #include <tqdir.h> #include <tqfile.h> #include <tqtextcodec.h> @@ -27,6 +26,8 @@ #include <tqtimer.h> #include <tqstring.h> +#include <tdecmdlineargs.h> +#include <tdeconfig.h> #include <tdelocale.h> #include "trace.h" @@ -39,83 +40,37 @@ #include <stdio.h> #include <stdlib.h> -// #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 <tqapplication.h> +#include <tdeapplication.h> #include <X11/Xlib.h> -#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 <tqdir.h> -#include <tqapplication.h> -#include <tqmessagebox.h> -#include <tqtimer.h> #include <tqfile.h> -#include <tqaction.h> -#include <tqpopupmenu.h> #include <tqtextstream.h> -#include <tqfiledialog.h> +#include <tdeapplication.h> +#include <tdecmdlineargs.h> +#include <tdeconfig.h> #include <tdelocale.h> +#include <tdemessagebox.h> #include "trace.h" #include "traylabelmgr.h" @@ -40,9 +37,9 @@ #include <stdlib.h> 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,13 +156,15 @@ 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<argc; i++) - argv[i] = args[i].latin1(); + for(int i = 0; i < argc; i++) + { + argv[i] = args[i].local8Bit(); + } argv[argc] = NULL; // null terminate the array @@ -175,6 +172,68 @@ bool TrayLabelMgr::processCommand(const TQStringList& args) } // 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) { TRACE("CommandLine arguments"); @@ -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<TQTrayLabel> 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 <TQTrayLabel> it(mTrayLabels); - TQTrayLabel *t; int i = 1; - while ((t = it.current()) != 0) + TQTrayLabel *t; + TDEConfig *config = TDEApplication::kApplication()->sessionConfig(); + TQPtrListIterator <TQTrayLabel> 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<TQTrayLabel> 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 <tqptrlist.h> #include <tqvaluelist.h> #include <tqstringlist.h> +#include <tqtimer.h> +#include <tdeapplication.h> #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<TQTrayLabel> mTrayLabels; TQValueList<TQStringList> 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) { @@ -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 |