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>
pull/2/head
Michele Calgaro 5 years ago
parent d9e1d9fa71
commit ab3e99d8ee
Signed by: MicheleC
GPG Key ID: 2A75B7CA8ADED5CF

@ -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}

@ -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"));
}

@ -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;
};

@ -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();
}

@ -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

@ -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

@ -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"

@ -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

@ -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");
}
}

@ -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,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<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
return processCommand(argc, const_cast<char **>(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<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)
{

@ -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;
};

@ -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

@ -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

Loading…
Cancel
Save