From ab3e99d8ee8ef5b53dcd1e6f90e3cdbbc08322e3 Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Mon, 16 Mar 2020 21:58:44 +0900 Subject: 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 --- src/traylabelmgr.cpp | 257 +++++++++++++++++++++++++++++---------------------- 1 file changed, 149 insertions(+), 108 deletions(-) (limited to 'src/traylabelmgr.cpp') 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) { -- cgit v1.2.1