1) fixed bug when invoking tdedocker with options, which were not passed

to an existing instance
2) code restructure for tray label object
3) dockWhenLostFocus option is now saved/restored correctly
4) fixed issues with popup menu actions status

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

@ -28,14 +28,8 @@ link_directories(
tde_add_executable( tdedocker AUTOMOC tde_add_executable( tdedocker AUTOMOC
SOURCES SOURCES
customtraylabel.cpp tdedocker.cpp main.cpp tqtraylabel.cpp
tdedocker.cpp trace.cpp traylabelmgr.cpp util.cpp
main.cpp
qtraylabel.cpp
trace.cpp
traylabelmgr.cpp
util.cpp
trace.cpp
LINK LINK
tdecore-shared tdeui-shared DCOP-shared tdecore-shared tdeui-shared DCOP-shared
${XMU_LIBRARIES} ${XPM_LIBRARIES} ${XMU_LIBRARIES} ${XPM_LIBRARIES}

@ -1,300 +0,0 @@
/*
* 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
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
// $Id: customtraylabel.cpp,v 1.14 2005/06/21 10:04:35 cs19713 Exp $
#include <tqsettings.h>
#include <tdepopupmenu.h>
#include <tqfiledialog.h>
#include <tqinputdialog.h>
#include <tqtimer.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 "traylabelmgr.h"
#include "customtraylabel.h"
CustomTrayLabel::CustomTrayLabel(Window w, TQWidget* p, const TQString& t)
: TQTrayLabel(w, p, t), mUndockWhenDead(false)
{
installMenu();
}
CustomTrayLabel::CustomTrayLabel(const TQStringList& argv, pid_t pid, TQWidget* parent)
: TQTrayLabel(argv, pid, parent), mUndockWhenDead(false)
{
installMenu();
}
// Installs a popup menu on the tray label
void CustomTrayLabel::installMenu()
{
TQPixmap tdedocker_png(TDEGlobal::iconLoader()->loadIcon("tdedocker", TDEIcon::NoGroup, TDEIcon::SizeSmall));
setIcon(tdedocker_png);
TrayLabelMgr *tlMgr = TrayLabelMgr::instance();
mOptionsMenu = new TDEPopupMenu(this);
mSessionManagement = new TDEToggleAction(i18n("Dock when session restored"), 0, this);
connect(mSessionManagement, SIGNAL(toggled(bool)), this, SLOT(enableSessionManagement(bool)));
mSessionManagement->plug(mOptionsMenu);
mOptionsMenu->insertItem(i18n("Set Icon"), this, SLOT(setCustomIcon()));
mBalloonTimeout = new TDEAction(i18n("Set balloon timeout"), 0, this);
connect(mBalloonTimeout, SIGNAL(activated()), this, SLOT(slotSetBalloonTimeout()));
mBalloonTimeout->plug(mOptionsMenu);
mDockWhenObscured = new TDEToggleAction(i18n("Dock when obscured"), 0, this);
mDockWhenObscured->plug(mOptionsMenu);
mDockIfMinimized = new TDEToggleAction(i18n("Dock when minimized"), 0, this);
connect(mDockIfMinimized, SIGNAL(toggled(bool)), this, SLOT(setDockWhenMinimized(bool)));
mDockIfMinimized->plug(mOptionsMenu);
mDockWhenFocusLost = new TDEToggleAction(i18n("Dock when focus lost"), 0, this);
mDockWhenFocusLost->plug(mOptionsMenu);
mSkipTaskbar = new TDEToggleAction(i18n("Skip taskbar"), 0, this);
connect(mSkipTaskbar, SIGNAL(toggled(bool)), this, SLOT(setSkipTaskbar(bool)));
mSkipTaskbar->plug(mOptionsMenu);
mMainMenu = new TDEPopupMenu(this);
mMainMenu->insertItem(i18n("Options"), mOptionsMenu);
mMainMenu->insertItem(i18n("Dock Another"), tlMgr, SLOT(dockAnother()));
mMainMenu->insertItem(i18n("Undock All"), tlMgr, SLOT(undockAll()));
mMainMenu->insertItem(i18n("Quit All"), tlMgr, SLOT(quitAll()));
mMainMenu->insertSeparator();
mShowId = mMainMenu->insertItem(TQString("Show/Hide [untitled]"), this, SLOT(toggleShow()));
mMainMenu->insertItem(TQString(i18n("Undock")), this, SLOT(undock()));
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
setDockWhenObscured(false);
enableSessionManagement(true);
mDockIfMinimized->setChecked(isDockWhenMinimized());
mSkipTaskbar->setChecked(isSkippingTaskbar());
setAcceptDrops(true); // and you thought this function only installs the menu
}
void CustomTrayLabel::enableSessionManagement(bool sm)
{
mSessionManagement->setChecked(!appName().isEmpty() && sm);
}
// Session Management
bool CustomTrayLabel::restoreState(TDEConfig *config)
{
setDockWhenObscured(config->readBoolEntry("DockWhenObscured", false));
TRACE("DWM=%i DWO=%i", isDockWhenMinimized(), mDockWhenObscured->isChecked());
return TQTrayLabel::restoreState(config);
}
bool CustomTrayLabel::saveState(TDEConfig *config)
{
if (!mSessionManagement->isChecked())
{
return false;
}
if (!TQTrayLabel::saveState(config))
{
return false;
}
config->writeEntry("DockWhenObscured", mDockWhenObscured->isChecked());
TRACE("WM=%i DWO=%i", isDockWhenMinimized(), mDockWhenObscured->isChecked());
return true;
}
static bool which(const char *app)
{
if (access(app, X_OK) == 0) return true;
// Check if the program exist in the $PATH
char *path = strdup(getenv("PATH"));
char prog[300];
if (path == NULL) return false;
TRACE("PATH=%s", path);
char *p = strtok(path, ":");
while (p != NULL)
{
snprintf(prog, sizeof(prog), "%s/%s", p, app);
if (access(prog, X_OK) == 0) break;
p = strtok(NULL, ":");
}
free(path);
TRACE("Located at (%s)", p);
return p != NULL;
}
void CustomTrayLabel::setAppName(const TQString& name)
{
//FIXME HACK relies on window and application name being the same.
TQTrayLabel::setAppName(name.lower());
}
/*
* This function is called when TQTrayLabel wants to know whether it can
* unsubscribe from root window. This is because it doesnt know if someone
* else is interested in root window events
*/
bool CustomTrayLabel::canUnsubscribeFromRoot(void)
{
return (TrayLabelMgr::instance())->hiddenLabelsCount() == 0;
}
// Get icon from user, load it and if successful load it.
void CustomTrayLabel::setCustomIcon(void)
{
TQString icon;
while (true)
{
// Nag the user to give us a valid icon or press cancel
icon = TQFileDialog::getOpenFileName();
if (icon.isNull()) return; // user cancelled
if (!TQPixmap(icon).isNull()) break;
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);
}
// Get balloon timeout from the user
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);
if (!ok) return;
setBalloonTimeout(timeout * 1000);
}
// Called when we are just about to display the menu
void CustomTrayLabel::updateMenu(void)
{
TQString title = appClass(); // + "(" + appTitle() + ")";
mMainMenu->changeItem(mShowId, TQIconSet(*pixmap()),
TQString((isWithdrawn() ? i18n("Show %1") : i18n("Hide %1")).arg(title)));
}
void CustomTrayLabel::mapEvent(void)
{
TRACE("mapEvent");
if (mDockWhenObscured->isChecked())
{
/*
* We get a obscured event for the time between the map and focus in of
* the window. So we disable it for sometime and reanable.
*/
mDockWhenObscured->setChecked(false);
TQTimer::singleShot(800, mDockWhenObscured, SLOT(toggle()));
TRACE("Turning off DWO for some time");
}
}
void CustomTrayLabel::obscureEvent(void)
{
TRACE("obscureEvent");
if (mDockWhenObscured->isChecked() && !isWithdrawn())
withdraw();
}
void CustomTrayLabel::focusLostEvent()
{
if (mDockWhenFocusLost->isChecked())
{
withdraw();
}
}
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();
}
void CustomTrayLabel::destroyEvent(void)
{
mUndockWhenDead = true;
TQTrayLabel::destroyEvent();
}
void CustomTrayLabel::processDead(void)
{
/*
* This is a ugly hack but worth every but of ugliness IMO ;).
* Lets say, an instance of xmms, already exists. You type tdedocker xmms.
* TDEDocker launches xmms. xmms cowardly exists seeing its previous instance.
* Wouldnt it be nice now to dock the previous instance of xmms automatically.
* This is more common than you think (think of session restoration)
*/
if (!mUndockWhenDead)
{
scanClients();
if (dockedWindow() != None) return;
}
undock();
}
/*
* Can dock this window iff not docked by another one tray label already
*/
bool CustomTrayLabel::canDockWindow(Window w)
{
TRACE("Checking if 0x%x is already docked", (unsigned) w);
return !(TrayLabelMgr::instance()->isWindowDocked(w));
}
void CustomTrayLabel::dropEvent(TQDropEvent *)
{
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"));
}
#include "customtraylabel.moc"

@ -1,82 +0,0 @@
/*
* 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
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
// $Id: customtraylabel.h,v 1.10 2007/01/02 21:48:37 cs19713 Exp $
#ifndef _CUSTOMTRAYLABEL_H
#define _CUSTOMTRAYLABEL_H
#include <tqobject.h>
#include <tdeactionclasses.h>
#include "qtraylabel.h"
class TDEPopupMenu;
class TDEToggleAction;
class TQStringList;
class TQString;
class TQSettings;
class TQWidget;
class TQDropEvent;
class CustomTrayLabel : public TQTrayLabel
{
Q_OBJECT
public:
CustomTrayLabel(Window w, TQWidget* p = 0, const TQString& t = TQString::null);
CustomTrayLabel(const TQStringList& argv, pid_t pid, TQWidget* parent = 0);
// Session management
bool saveState(TDEConfig *config);
bool restoreState(TDEConfig *config);
void setAppName(const TQString& name);
public slots:
void setDockWhenObscured(bool dock) { mDockWhenObscured->setChecked(dock); }
void enableSessionManagement(bool sm);
protected:
void dropEvent(TQDropEvent *ev);
bool canUnsubscribeFromRoot(void);
void mapEvent(void);
void focusLostEvent();
void obscureEvent(void);
void destroyEvent(void);
void mouseReleaseEvent(TQMouseEvent * ev);
bool canDockWindow(Window w);
void processDead(void);
private slots:
void setCustomIcon(void);
void updateMenu();
void slotSetBalloonTimeout(void);
private:
void installMenu();
bool mUndockWhenDead;
TDEPopupMenu *mMainMenu;
TDEPopupMenu *mOptionsMenu;
TDEToggleAction *mSessionManagement, *mDockWhenObscured, *mDockIfMinimized,
*mDockWhenFocusLost, *mSkipTaskbar;
TDEAction *mBalloonTimeout;
int mShowId;
};
#endif // _CUSTOMTRAYLABEL_H

@ -54,9 +54,9 @@ static const TDECmdLineOptions options[] =
{ "b", I18N_NOOP("Dont warn about non-normal windows (blind mode)"), 0L }, { "b", I18N_NOOP("Dont warn about non-normal windows (blind mode)"), 0L },
{ "d", I18N_NOOP("Disable session management"), 0L }, { "d", I18N_NOOP("Disable session management"), 0L },
{ "e", I18N_NOOP("Enable session management"), 0L }, { "e", I18N_NOOP("Enable session management"), 0L },
{ "f", I18N_NOOP("Dock window that has the focus(active window)"), 0L }, { "f", I18N_NOOP("Dock window that has the focus (active window)"), 0L },
{ "i icon", I18N_NOOP("Custom dock Icon"), 0L }, { "i icon", I18N_NOOP("Custom dock Icon"), 0L },
{ "m", I18N_NOOP("Keep application window mapped (dont hide on dock)"), 0L }, { "m", I18N_NOOP("Keep application window mapped (don't hide on dock)"), 0L },
{ "o", I18N_NOOP("Dock when obscured"), 0L }, { "o", I18N_NOOP("Dock when obscured"), 0L },
{ "p secs", I18N_NOOP("Set ballooning timeout (popup time)"), 0L }, { "p secs", I18N_NOOP("Set ballooning timeout (popup time)"), 0L },
{ "q", I18N_NOOP("Disable ballooning title changes (quiet)"), 0L }, { "q", I18N_NOOP("Disable ballooning title changes (quiet)"), 0L },

@ -1,16 +1,16 @@
/* /*
* Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved.
* *
* This is free software; you can redistribute it and/or modify * This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This software is distributed in the hope that it will be useful, * This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software * along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
@ -101,6 +101,54 @@ void TDEDocker::notifyPreviousInstance(Window prevInstance)
{ {
TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
s << TDECmdLineArgs::appName(); s << TDECmdLineArgs::appName();
// Options
if (args->isSet("b"))
{
s << " -b";
}
if (args->isSet("d"))
{
s << " -d";
}
if (args->isSet("e"))
{
s << " -e";
}
if (args->isSet("f"))
{
s << " -f";
}
if (args->isSet("i"))
{
s << " -i " << args->getOption("i");
}
if (args->isSet("m"))
{
s << " -m";
}
if (args->isSet("o"))
{
s << " -o";
}
if (args->isSet("p"))
{
s << " -p " << args->getOption("p");
}
if (args->isSet("q"))
{
s << " -q";
}
if (args->isSet("t"))
{
s << " -t";
}
if (args->isSet("w"))
{
s << " -w " << args->getOption("w");
}
// Arguments
for (int i = 0; i < args->count(); i++) for (int i = 0; i < args->count(); i++)
{ {
s << " " << args->arg(i); s << " " << args->arg(i);
@ -141,7 +189,7 @@ bool TDEDocker::x11EventFilter(XEvent * event)
if (!(client->message_type == 0x220679 && client->data.l[0] == 0xBABE)) if (!(client->message_type == 0x220679 && client->data.l[0] == 0xBABE))
return FALSE; return FALSE;
TRACE("ClientMessage from PID=%ld. SelOwn=0x%x", TRACE("ClientMessage from PID=%ld. SelOwn=0x%x",
client->data.l[1], (unsigned) mSelectionOwner); client->data.l[1], (unsigned) mSelectionOwner);
char tmp[50]; char tmp[50];
struct stat buf; struct stat buf;
@ -153,7 +201,7 @@ bool TDEDocker::x11EventFilter(XEvent * event)
* are the same. This will prevent someone from executing arbitrary * are the same. This will prevent someone from executing arbitrary
* programs by sending client message. Of course, you can send a message * programs by sending client message. Of course, you can send a message
* only if you are authenticated to the X session and have permission to * only if you are authenticated to the X session and have permission to
* create files in TMPFILE_PREFIX. So this code is there just for the * create files in TMPFILE_PREFIX. So this code is there just for the
* heck of it. * heck of it.
*/ */
TRACE("User %i is trying something fishy...", buf.st_uid); TRACE("User %i is trying something fishy...", buf.st_uid);

@ -22,18 +22,25 @@
// Include all TQt includes before X // Include all TQt includes before X
#include <tqstring.h> #include <tqstring.h>
#include <tqevent.h> #include <tqevent.h>
#include <tqfiledialog.h>
#include <tqfileinfo.h>
#include <tqimage.h>
#include <tqinputdialog.h>
#include <tqpixmap.h>
#include <tqpoint.h> #include <tqpoint.h>
#include <tqtooltip.h> #include <tqtooltip.h>
#include <tqtimer.h> #include <tqtimer.h>
#include <tqimage.h>
#include <tqpixmap.h>
#include <tqfileinfo.h>
#include <tqapplication.h>
#include "trace.h"
#include <tdeconfig.h>
#include <khelpmenu.h>
#include <kstdaction.h>
#include <kiconloader.h> #include <kiconloader.h>
#include <kstdguiitem.h>
#include <tqapplication.h>
#include <tdeconfig.h>
#include <tdeglobal.h> #include <tdeglobal.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <tdepopupmenu.h>
#include <X11/cursorfont.h> #include <X11/cursorfont.h>
#include <X11/xpm.h> #include <X11/xpm.h>
@ -45,20 +52,21 @@
#include <sys/wait.h> #include <sys/wait.h>
#include "util.h" #include "util.h"
#include "qtraylabel.h" #include "trace.h"
#include "traylabelmgr.h"
#include "tqtraylabel.h"
void TQTrayLabel::initialize(void) void TQTrayLabel::initialize(void)
{ {
mDocked = false; mDocked = false;
mWithdrawn = true; mWithdrawn = true;
mBalloonTimeout = 4000; mBalloonTimeout = 4000;
mSkippingTaskbar = false; mUndockWhenDead = false;
mDockWhenMinimized = true;
mDesktop = 666; // setDockedWindow would set it a saner value mDesktop = 666; // setDockedWindow would set it a saner value
// Balloon's properties are set to match a TQt tool tip (see TQt source) // Balloon's properties are set to match a TQt tool tip (see TQt source)
mBalloon = new TQLabel(0, "balloon", WType_TopLevel | WStyle_StaysOnTop | mBalloon = new TQLabel(0, "balloon", WType_TopLevel | WStyle_StaysOnTop |
WStyle_Customize | WStyle_NoBorder | WStyle_Customize | WStyle_NoBorder |
WStyle_Tool | WX11BypassWM); WStyle_Tool | WX11BypassWM);
mBalloon->setFont(TQToolTip::font()); mBalloon->setFont(TQToolTip::font());
mBalloon->setPalette(TQToolTip::palette()); mBalloon->setPalette(TQToolTip::palette());
@ -76,32 +84,30 @@ void TQTrayLabel::initialize(void)
if (mSysTray != None) if (mSysTray != None)
subscribe(TQPaintDevice::x11AppDisplay(), mSysTray, subscribe(TQPaintDevice::x11AppDisplay(), mSysTray,
StructureNotifyMask, true); StructureNotifyMask, true);
installMenu();
} }
// Describe ourselves in a few words // Describe ourselves in a few words
const char *TQTrayLabel::me(void) const const char *TQTrayLabel::me(void) const
{ {
static char temp[100]; static char temp[100];
snprintf(temp, sizeof(temp), "(%s,PID=%i,WID=0x%x)", snprintf(temp, sizeof(temp), "(%s,PID=%i,WID=0x%x)",
appName().local8Bit().data(), mPid, (unsigned) mDockedWindow); appName().local8Bit().data(), mPid, (unsigned) mDockedWindow);
return temp; return temp;
} }
TQTrayLabel::TQTrayLabel(Window w, TQWidget* parent, const TQString& text) TQTrayLabel::TQTrayLabel(Window w, TQWidget *parent, const TQString &text)
:TQLabel(parent, text.utf8(), WStyle_Customize | WStyle_NoBorder | WStyle_Tool), : TQLabel(parent, text.utf8(), WStyle_Customize | WStyle_NoBorder | WStyle_Tool),
mDockedWindow(w), mPid(0) mDockedWindow(w), mPid(0)
{ {
initialize(); initialize();
} }
TQTrayLabel::TQTrayLabel(const TQStringList& pname, pid_t pid, TQWidget* parent) TQTrayLabel::TQTrayLabel(const TQStringList &pname, pid_t pid, TQWidget *parent)
:TQLabel(parent, "TrayLabel", WStyle_Customize | WStyle_NoBorder | WStyle_Tool), : TQLabel(parent, "TrayLabel", WStyle_Customize | WStyle_NoBorder | WStyle_Tool),
mDockedWindow(None), mProgName(pname), mPid(pid) mDockedWindow(None), mProgName(pname), mPid(pid)
{ {
if (pname[0].at(0) != '/' && pname[0].find('/', 1) > 0)
{
mProgName.push_front(TQFileInfo(pname[0]).absFilePath()); // convert to absolute
}
initialize(); initialize();
} }
@ -110,20 +116,18 @@ TQTrayLabel::~TQTrayLabel()
TRACE("%s Goodbye", me()); TRACE("%s Goodbye", me());
if (mDockedWindow == None) return; if (mDockedWindow == None) return;
// Leave the docked window is some sane state // Leave the docked window is some sane state
mSkippingTaskbar = false; mSkipTaskbar->setChecked(false);
skipTaskbar(); skipTaskbar();
map(); map();
} }
void TQTrayLabel::setAppName(const TQString &prog) void TQTrayLabel::setAppName(const TQString &prog)
{ {
// FIXME HACK
// using "prog.lower()" relies on window and application name being the same.
if (mProgName.count() == 0) if (mProgName.count() == 0)
{ {
mProgName.push_front(prog); mProgName.push_front(prog.lower());
}
else
{
mProgName[0] = prog;
} }
} }
@ -180,18 +184,18 @@ void TQTrayLabel::realityCheck(void)
/* /*
* I am not sure when, but TQt at some point in time overwrites our * I am not sure when, but TQt at some point in time overwrites our
* subscription (SubstructureNotifyMask) on the root window. So, we check * subscription (SubstructureNotifyMask) on the root window. So, we check
* the status of root window subscription periodically. Now, from the time * the status of root window subscription periodically. Now, from the time
* TQt overwrote our subscription to the time we discovered it, the * TQt overwrote our subscription to the time we discovered it, the
* window we are looking for could have been mapped and we would have never * window we are looking for could have been mapped and we would have never
* been informed (since TQt overrwrote the subscription). So we have to * been informed (since TQt overrwrote the subscription). So we have to
* scan existing client list and dock. I have never seen this happen * scan existing client list and dock. I have never seen this happen
* but I see it likely to happen during session restoration * but I see it likely to happen during session restoration
*/ */
Display *display = TQPaintDevice::x11AppDisplay(); Display *display = TQPaintDevice::x11AppDisplay();
XWindowAttributes attr; XWindowAttributes attr;
XGetWindowAttributes(display, tqt_xrootwin(), &attr); XGetWindowAttributes(display, tqt_xrootwin(), &attr);
if (!(attr.your_event_mask & SubstructureNotifyMask)) if (!(attr.your_event_mask & SubstructureNotifyMask))
{ {
subscribe(display, None, SubstructureNotifyMask, true); subscribe(display, None, SubstructureNotifyMask, true);
TRACE("%s rescanning clients since qt overrode mask", me()); TRACE("%s rescanning clients since qt overrode mask", me());
@ -251,16 +255,16 @@ void TQTrayLabel::dock(void)
// 1. GNOME and NET WM Specification // 1. GNOME and NET WM Specification
long l[5] = { CurrentTime, SYSTEM_TRAY_REQUEST_DOCK, wid, 0, 0 }; long l[5] = { CurrentTime, SYSTEM_TRAY_REQUEST_DOCK, wid, 0, 0 };
sendMessage(display, mSysTray, mSysTray, "_NET_SYSTEM_TRAY_OPCODE", sendMessage(display, mSysTray, mSysTray, "_NET_SYSTEM_TRAY_OPCODE",
32, 0L, l, sizeof(l)); 32, 0L, l, sizeof(l));
// 2. KDE 3.x and above // 2. KDE 3.x and above
Atom tray_atom = Atom tray_atom =
XInternAtom(display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False); XInternAtom(display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False);
XChangeProperty(display, wid, tray_atom, XA_WINDOW, 32, XChangeProperty(display, wid, tray_atom, XA_WINDOW, 32,
PropModeReplace, (unsigned char *) &wid, 1); PropModeReplace, (unsigned char *) &wid, 1);
// 3. All other KDEs // 3. All other KDEs
tray_atom = XInternAtom(display, "KWM_DOCKWINDOW", False); tray_atom = XInternAtom(display, "KWM_DOCKWINDOW", False);
XChangeProperty(display, wid, tray_atom, XA_WINDOW, 32, XChangeProperty(display, wid, tray_atom, XA_WINDOW, 32,
PropModeReplace, (unsigned char *) &wid, 1); PropModeReplace, (unsigned char *) &wid, 1);
@ -270,7 +274,12 @@ void TQTrayLabel::dock(void)
handleTitleChange(); handleTitleChange();
handleIconChange(); handleIconChange();
if (mProgName.count() == 0) setAppName(mClass); if (mProgName.count() == 0)
{
setAppName(mClass);
}
mDockWhenRestored->setChecked(true);
setDockWhenRestored(true);
/* /*
* For Gnome, a delay is required before we do a show (dont ask me why) * For Gnome, a delay is required before we do a show (dont ask me why)
@ -319,19 +328,19 @@ void TQTrayLabel::map(void)
* _NET_WM_DESKTOP is set by the WM to the active desktop for newly * _NET_WM_DESKTOP is set by the WM to the active desktop for newly
* mapped windows (like this one) at some point in time. We give * mapped windows (like this one) at some point in time. We give
* the WM 200ms to do that. We will override that value to -1 (all * the WM 200ms to do that. We will override that value to -1 (all
* desktops) on showOnAllDesktops(). * desktops) on showOnAllDesktops().
*/ */
TQTimer::singleShot(200, this, SLOT(showOnAllDesktops())); TQTimer::singleShot(200, this, SLOT(showOnAllDesktops()));
} }
/* /*
* A simple XMapWindow would not do. Some applications like xmms wont * A simple XMapWindow would not do. Some applications like xmms wont
* redisplay its other windows (like the playlist, equalizer) since the * redisplay its other windows (like the playlist, equalizer) since the
* Withdrawn->Normal state change code does not map them. So we make the * Withdrawn->Normal state change code does not map them. So we make the
* window go through Withdrawn->Iconify->Normal state. * window go through Withdrawn->Iconify->Normal state.
*/ */
XWMHints *wm_hint = XGetWMHints(display, mDockedWindow); XWMHints *wm_hint = XGetWMHints(display, mDockedWindow);
if (wm_hint) if (wm_hint)
{ {
wm_hint->initial_state = IconicState; wm_hint->initial_state = IconicState;
XSetWMHints(display, mDockedWindow, wm_hint); XSetWMHints(display, mDockedWindow, wm_hint);
@ -347,9 +356,11 @@ void TQTrayLabel::map(void)
SubstructureNotifyMask | SubstructureRedirectMask, l, sizeof(l)); SubstructureNotifyMask | SubstructureRedirectMask, l, sizeof(l));
// skipTaskbar modifies _NET_WM_STATE. Make sure we dont override WMs value // skipTaskbar modifies _NET_WM_STATE. Make sure we dont override WMs value
TQTimer::singleShot(230, this, SLOT(skipTaskbar())); TQTimer::singleShot(230, this, SLOT(skipTaskbar()));
// disable docking when minized for some time (since we went to Iconic state) // disable "dock when minized" for a short while since we went to Iconic state
mDockWhenMinimized = !mDockWhenMinimized; // (when the window is mapped, often an IconicState WM_STATE message is sent too
TQTimer::singleShot(230, this, SLOT(toggleDockWhenMinimized())); // just before the NormalState)
toggleDockWhenMinimized();
TQTimer::singleShot(500, this, SLOT(toggleDockWhenMinimized()));
} }
void TQTrayLabel::withdraw(void) void TQTrayLabel::withdraw(void)
@ -366,7 +377,7 @@ void TQTrayLabel::withdraw(void)
/* /*
* A simple call to XWithdrawWindow wont do. Here is what we do: * A simple call to XWithdrawWindow wont do. Here is what we do:
* 1. Iconify. This will make the application hide all its other windows. For * 1. Iconify. This will make the application hide all its other windows. For
* example, xmms would take off the playlist and equalizer window. * example, xmms would take off the playlist and equalizer window.
* 2. Next tell the WM, that we would like to go to withdrawn state. Withdrawn * 2. Next tell the WM, that we would like to go to withdrawn state. Withdrawn
* state will remove us from the taskbar. * state will remove us from the taskbar.
@ -387,8 +398,8 @@ void TQTrayLabel::withdraw(void)
} }
/* /*
* Skipping the taskbar is a bit painful. Basically, NET_WM_STATE needs to * Skipping the taskbar is a bit painful. Basically, NET_WM_STATE needs to
* have _NET_WM_STATE_SKIP_TASKBAR. NET_WM_STATE needs to be updated * have _NET_WM_STATE_SKIP_TASKBAR. NET_WM_STATE needs to be updated
* carefully since it is a set of states. * carefully since it is a set of states.
*/ */
void TQTrayLabel::skipTaskbar(void) void TQTrayLabel::skipTaskbar(void)
@ -415,8 +426,10 @@ void TQTrayLabel::skipTaskbar(void)
for (num_states = 0; num_states < nitems; num_states++) for (num_states = 0; num_states < nitems; num_states++)
if (old_states[num_states] == skip_atom) break; if (old_states[num_states] == skip_atom) break;
if (mSkippingTaskbar) if (mSkipTaskbar->isChecked())
{
append = (num_states >= nitems); append = (num_states >= nitems);
}
else else
{ {
if (num_states < nitems) if (num_states < nitems)
@ -429,29 +442,54 @@ void TQTrayLabel::skipTaskbar(void)
XFree(data); XFree(data);
} }
TRACE("%s SkippingTaskar=%i append=%i replace=%i", me(), mSkippingTaskbar, TRACE("%s SkippingTaskar=%i append=%i replace=%i", me(),
append, replace); mSkipTaskbar->isChecked(), append, replace);
if (mSkippingTaskbar) if (mSkipTaskbar->isChecked())
{ {
if (append) if (append)
XChangeProperty(display, mDockedWindow, _NET_WM_STATE, XA_ATOM, 32, {
XChangeProperty(display, mDockedWindow, _NET_WM_STATE, XA_ATOM, 32,
PropModeAppend, (unsigned char *) &skip_atom, 1); PropModeAppend, (unsigned char *) &skip_atom, 1);
}
} }
else if (replace) else if (replace)
XChangeProperty(display, mDockedWindow, _NET_WM_STATE, XA_ATOM, 32, {
XChangeProperty(display, mDockedWindow, _NET_WM_STATE, XA_ATOM, 32,
PropModeReplace, (unsigned char *) &old_states, nitems - 1); PropModeReplace, (unsigned char *) &old_states, nitems - 1);
}
} }
void TQTrayLabel::setSkipTaskbar(bool skip) void TQTrayLabel::setSkipTaskbar(bool skip)
{ {
TRACE("%s Skip=%i", me(), skip); TRACE("%s skip=%i", me(), skip);
mSkippingTaskbar = skip; if (skip != mSkipTaskbar->isChecked())
if (mDockedWindow != None && !mWithdrawn) skipTaskbar(); {
// Make sure the toggle action state is updated in case this function
// is called directly from code.
mSkipTaskbar->setChecked(skip);
return;
}
if (mDockedWindow != None && !mWithdrawn)
{
skipTaskbar();
}
}
void TQTrayLabel::toggleShow(void)
{
if (mWithdrawn)
{
map();
}
else
{
withdraw();
}
} }
/* /*
* Closes a window by sending _NET_CLOSE_WINDOW. For reasons best unknown we * Closes a window by sending _NET_CLOSE_WINDOW. For reasons best unknown we
* need to first map and then send the request. * need to first map and then send the request.
*/ */
void TQTrayLabel::close(void) void TQTrayLabel::close(void)
@ -462,10 +500,20 @@ void TQTrayLabel::close(void)
long l[5] = { 0, 0, 0, 0, 0 }; long l[5] = { 0, 0, 0, 0, 0 };
map(); map();
sendMessage(display, tqt_xrootwin(), mDockedWindow, "_NET_CLOSE_WINDOW", 32, sendMessage(display, tqt_xrootwin(), mDockedWindow, "_NET_CLOSE_WINDOW", 32,
SubstructureNotifyMask | SubstructureRedirectMask, SubstructureNotifyMask | SubstructureRedirectMask,
l, sizeof(l)); l, sizeof(l));
} }
/*
* This function is called when TQTrayLabel wants to know whether it can
* unsubscribe from the root window. This is because it doesn't know if someone
* else is interested in root window events
*/
bool TQTrayLabel::canUnsubscribeFromRoot(void)
{
return (TrayLabelMgr::instance())->hiddenLabelsCount() == 0;
}
/* /*
* Sets the tray icon. If the icon failed to load, we revert to application icon * Sets the tray icon. If the icon failed to load, we revert to application icon
*/ */
@ -478,8 +526,8 @@ void TQTrayLabel::setTrayIcon(const TQString& icon)
} }
/* /*
* Sets the docked window to w. * Sets the docked window to w.
* A) Start/stop reality timer. * A) Start/stop reality timer.
* B) Subscribe/Unsubscribe for root/w notifications as appropriate * B) Subscribe/Unsubscribe for root/w notifications as appropriate
* C) And of course, dock the window and apply some settings * C) And of course, dock the window and apply some settings
*/ */
@ -489,8 +537,14 @@ void TQTrayLabel::setDockedWindow(Window w)
mDockedWindow==None ? "Starting" : "Stopping"); mDockedWindow==None ? "Starting" : "Stopping");
// Check if we are allowed to dock this window (allows custom rules) // Check if we are allowed to dock this window (allows custom rules)
if (w != None) mDockedWindow = canDockWindow(w) ? w : None; mDockedWindow = None;
else mDockedWindow = None; if (w != None)
{
if (!(TrayLabelMgr::instance()->isWindowDocked(w)))
{
mDockedWindow = w;
}
}
if (mDockedWindow == None) mRealityMonitor.start(500); else mRealityMonitor.stop(); if (mDockedWindow == None) mRealityMonitor.start(500); else mRealityMonitor.stop();
@ -500,12 +554,12 @@ void TQTrayLabel::setDockedWindow(Window w)
if (w == None) subscribe(d, None, SubstructureNotifyMask, true); if (w == None) subscribe(d, None, SubstructureNotifyMask, true);
else else
{ {
if (canUnsubscribeFromRoot()) if (canUnsubscribeFromRoot())
subscribe(d, None, ~SubstructureNotifyMask, false); subscribe(d, None, ~SubstructureNotifyMask, false);
else subscribe(d, None, SubstructureNotifyMask, true); else subscribe(d, None, SubstructureNotifyMask, true);
subscribe(d, w, subscribe(d, w,
StructureNotifyMask | PropertyChangeMask | StructureNotifyMask | PropertyChangeMask |
VisibilityChangeMask | FocusChangeMask, VisibilityChangeMask | FocusChangeMask,
true); true);
} }
@ -513,12 +567,14 @@ void TQTrayLabel::setDockedWindow(Window w)
if (mDocked && w!=None) if (mDocked && w!=None)
{ {
// store the desktop on which the window is being shown // store the desktop on which the window is being shown
getCardinalProperty(d, mDockedWindow, getCardinalProperty(d, mDockedWindow,
XInternAtom(d, "_NET_WM_DESKTOP", True), &mDesktop); XInternAtom(d, "_NET_WM_DESKTOP", True), &mDesktop);
if (mWithdrawn) if (mWithdrawn)
{
// show the window for sometime before docking // show the window for sometime before docking
TQTimer::singleShot(1000, this, SLOT(withdraw())); TQTimer::singleShot(500, this, SLOT(withdraw()));
}
else map(); else map();
dock(); dock();
} }
@ -539,7 +595,7 @@ void TQTrayLabel::balloonText()
long l[5] = { CurrentTime, SYSTEM_TRAY_BEGIN_MESSAGE, 2000, long l[5] = { CurrentTime, SYSTEM_TRAY_BEGIN_MESSAGE, 2000,
mTitle.length(), id++ mTitle.length(), id++
}; };
sendMessage(display, mSystemTray, winId(), "_NET_SYSTEM_TRAY_OPCODE", 32, sendMessage(display, mSystemTray, winId(), "_NET_SYSTEM_TRAY_OPCODE", 32,
SubstructureNotifyMask | SubstructureRedirectMask, SubstructureNotifyMask | SubstructureRedirectMask,
l, sizeof(l)); l, sizeof(l));
int length = mTitle.length(); int length = mTitle.length();
@ -624,7 +680,7 @@ void TQTrayLabel::handleIconChange(void)
if (!(wm_hints->flags & IconMaskHint)) if (!(wm_hints->flags & IconMaskHint))
wm_hints->icon_mask = None; wm_hints->icon_mask = None;
/* /*
* We act paranoid here. Progams like KSnake has a bug where * We act paranoid here. Progams like KSnake has a bug where
* IconPixmapHint is set but no pixmap (Actually this happens with * IconPixmapHint is set but no pixmap (Actually this happens with
* quite a few KDE programs) X-( * quite a few KDE programs) X-(
*/ */
@ -634,7 +690,7 @@ void TQTrayLabel::handleIconChange(void)
XFree(wm_hints); XFree(wm_hints);
} }
TQImage image; TQImage image;
if (!window_icon) if (!window_icon)
{ {
image = TDEGlobal::iconLoader()->loadIcon("question", TDEIcon::NoGroup, TDEIcon::SizeMedium); image = TDEGlobal::iconLoader()->loadIcon("question", TDEIcon::NoGroup, TDEIcon::SizeMedium);
} }
@ -662,9 +718,18 @@ void TQTrayLabel::updateIcon()
/* /*
* Mouse activity on our label. RightClick = Menu. LeftClick = Toggle Map * Mouse activity on our label. RightClick = Menu. LeftClick = Toggle Map
*/ */
void TQTrayLabel::mouseReleaseEvent(TQMouseEvent * ev) void TQTrayLabel::mouseReleaseEvent(TQMouseEvent *ev)
{ {
emit clicked(ev->button(), ev->globalPos()); if (ev->button() == TQt::RightButton)
{
mMainMenu->popup(ev->globalPos());
/* contextMenuAboutToShow(contextMenu());
contextMenu()->popup(e->globalPos());
e->accept();
return;*/
}
else
toggleShow();
} }
/* /*
@ -672,10 +737,16 @@ void TQTrayLabel::mouseReleaseEvent(TQMouseEvent * ev)
*/ */
void TQTrayLabel::dragEnterEvent(TQDragEnterEvent *ev) void TQTrayLabel::dragEnterEvent(TQDragEnterEvent *ev)
{ {
ev->accept(); ev->accept();
map(); map();
} }
void TQTrayLabel::dropEvent(TQDropEvent *)
{
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"));
}
/* /*
* Event dispatcher * Event dispatcher
*/ */
@ -739,17 +810,61 @@ bool TQTrayLabel::x11EventFilter(XEvent *ev)
return true; return true;
} }
void TQTrayLabel::destroyEvent(void)
{
TRACE("%s destroyEvent", me());
mUndockWhenDead = true;
setDockedWindow(None);
if (!mPid)
{
undock();
}
}
void TQTrayLabel::focusLostEvent()
{
if (mDockWhenFocusLost->isChecked())
{
withdraw();
}
}
void TQTrayLabel::mapEvent(void)
{
TRACE("mapEvent");
if (mDockWhenObscured->isChecked())
{
/*
* We get a obscured event for the time between the map and focus in of
* the window. So we disable it for sometime and reanable.
*/
mDockWhenObscured->setChecked(false);
TQTimer::singleShot(800, mDockWhenObscured, SLOT(toggle()));
TRACE("Turning off DWO for some time");
}
}
void TQTrayLabel::minimizeEvent(void) void TQTrayLabel::minimizeEvent(void)
{ {
TRACE("minimizeEvent"); TRACE("minimizeEvent");
if (mDockWhenMinimized) withdraw(); if (mDockWhenMinimized->isChecked())
{
withdraw();
}
} }
void TQTrayLabel::destroyEvent(void) void TQTrayLabel::obscureEvent(void)
{ {
TRACE("%s destroyEvent", me()); TRACE("obscureEvent");
setDockedWindow(None); if (mDockWhenObscured->isChecked() && !mWithdrawn)
if (!mPid) undock(); {
withdraw();
}
}
void TQTrayLabel::unmapEvent(void)
{
// NO OP
} }
void TQTrayLabel::propertyChangeEvent(Atom property) void TQTrayLabel::propertyChangeEvent(Atom property)
@ -790,20 +905,153 @@ void TQTrayLabel::propertyChangeEvent(Atom property)
} }
} }
void TQTrayLabel::processDead(void)
{
/*
* This is a ugly hack but worth every but of ugliness IMO ;).
* Lets say, an instance of xmms, already exists. You type tdedocker xmms.
* TDEDocker launches xmms. xmms cowardly exists seeing its previous instance.
* Wouldnt it be nice now to dock the previous instance of xmms automatically.
* This is more common than you think (think of session restoration)
*/
if (!mUndockWhenDead)
{
scanClients();
if (dockedWindow() != None) return;
}
undock();
}
void TQTrayLabel::setDockWhenRestored(bool dwr)
{
if (dwr && !mSessionManaged)
{
// Make sure the TDE action is off if session management was initially disabled by command line
mSessionManaged = true;
mDockWhenRestored->setChecked(false);
return;
}
if (dwr && appName().isEmpty())
{
KMessageBox::error(NULL, i18n("No valid application executable file known. \"Dock When Restore\" is not possible."),
i18n("TDEDocker"));
mDockWhenRestored->setChecked(false);
}
}
// Get icon from user, load it and if successful load it.
void TQTrayLabel::setCustomIcon(void)
{
TQString icon;
while (true)
{
// Nag the user to give us a valid icon or press cancel
icon = TQFileDialog::getOpenFileName();
if (icon.isNull()) return; // user cancelled
if (!TQPixmap(icon).isNull()) break;
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);
}
// Get balloon timeout from the user
void TQTrayLabel::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);
if (!ok) return;
setBalloonTimeout(timeout * 1000);
}
// Installs a popup menu on the tray label
void TQTrayLabel::installMenu()
{
TQPixmap tdedocker_png(TDEGlobal::iconLoader()->loadIcon("tdedocker", TDEIcon::NoGroup, TDEIcon::SizeSmall));
setIcon(tdedocker_png);
TrayLabelMgr *tlMgr = TrayLabelMgr::instance();
mOptionsMenu = new TDEPopupMenu(this);
mDockWhenRestored = new TDEToggleAction(i18n("Dock when session restored"), 0, this);
connect(mDockWhenRestored, SIGNAL(toggled(bool)), this, SLOT(setDockWhenRestored(bool)));
mDockWhenRestored->plug(mOptionsMenu);
mOptionsMenu->insertItem(i18n("Set Icon"), this, SLOT(setCustomIcon()));
mBalloonTimeoutAction = new TDEAction(i18n("Set balloon timeout"), 0, this);
connect(mBalloonTimeoutAction, SIGNAL(activated()), this, SLOT(slotSetBalloonTimeout()));
mBalloonTimeoutAction->plug(mOptionsMenu);
mDockWhenObscured = new TDEToggleAction(i18n("Dock when obscured"), 0, this);
mDockWhenObscured->plug(mOptionsMenu);
mDockWhenMinimized = new TDEToggleAction(i18n("Dock when minimized"), 0, this);
mDockWhenMinimized->plug(mOptionsMenu);
mDockWhenFocusLost = new TDEToggleAction(i18n("Dock when focus lost"), 0, this);
mDockWhenFocusLost->plug(mOptionsMenu);
mSkipTaskbar = new TDEToggleAction(i18n("Skip taskbar"), 0, this);
connect(mSkipTaskbar, SIGNAL(toggled(bool)), this, SLOT(setSkipTaskbar(bool)));
mSkipTaskbar->plug(mOptionsMenu);
mMainMenu = new TDEPopupMenu(this);
mMainMenu->insertItem(i18n("Options"), mOptionsMenu);
mMainMenu->insertItem(i18n("Dock Another"), tlMgr, SLOT(dockAnother()));
mMainMenu->insertItem(i18n("Undock All"), tlMgr, SLOT(undockAll()));
mMainMenu->insertItem(i18n("Quit All"), tlMgr, SLOT(quitAll()));
mMainMenu->insertSeparator();
mShowId = mMainMenu->insertItem(TQString("Show/Hide [untitled]"), this, SLOT(toggleShow()));
mMainMenu->insertItem(TQString(i18n("Undock")), this, SLOT(undock()));
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
mDockWhenObscured->setChecked(false);
mSessionManaged = true;
mDockWhenMinimized->setChecked(true);
mSkipTaskbar->setChecked(false);
setAcceptDrops(true); // and you thought this function only installs the menu
}
// Called when we are just about to display the menu
void TQTrayLabel::updateMenu(void)
{
TQString title = mClass; // + "(" + mTitle + ")";
mMainMenu->changeItem(mShowId, TQIconSet(*pixmap()),
TQString((mWithdrawn ? i18n("Show %1") : i18n("Hide %1")).arg(title)));
}
// Session Management // Session Management
bool TQTrayLabel::saveState(TDEConfig *config) bool TQTrayLabel::saveState(TDEConfig *config)
{ {
if (appName().isEmpty()) TRACE("%s saving state", me());
if (!mDockWhenRestored->isChecked())
{ {
return false; return false;
} }
TRACE("%s saving state", me());
config->writeEntry("Application", mProgName.join(" ")); config->writeEntry("Application", mProgName.join(" "));
config->writeEntry("BalloonTimeout", mBalloonTimeout); config->writeEntry("BalloonTimeout", mBalloonTimeout);
config->writeEntry("CustomIcon", mCustomIcon); config->writeEntry("CustomIcon", mCustomIcon);
config->writeEntry("DockWhenMinimized", mDockWhenMinimized); config->writeEntry("DockWhenFocusLost", mDockWhenFocusLost->isChecked());
config->writeEntry("SkipTaskbar", mSkippingTaskbar); config->writeEntry("DockWhenMinimized", mDockWhenMinimized->isChecked());
config->writeEntry("DockWhenObscured", mDockWhenObscured->isChecked());
config->writeEntry("SkipTaskbar", mSkipTaskbar->isChecked());
config->writeEntry("Withdraw", mWithdrawn); config->writeEntry("Withdraw", mWithdrawn);
return true; return true;
} }
@ -813,8 +1061,10 @@ bool TQTrayLabel::restoreState(TDEConfig *config)
TRACE("%s restoring state", me()); TRACE("%s restoring state", me());
setBalloonTimeout(config->readNumEntry("BalloonTimeout", 4000)); setBalloonTimeout(config->readNumEntry("BalloonTimeout", 4000));
mCustomIcon = config->readEntry("CustomIcon", TQString::null); mCustomIcon = config->readEntry("CustomIcon", TQString::null);
setDockWhenMinimized(config->readBoolEntry("DockWhenMinimized", false)); mDockWhenFocusLost->setChecked(config->readBoolEntry("DockWhenFocusLost", false));
setSkipTaskbar(config->readBoolEntry("SkipTaskbar", false)); mDockWhenMinimized->setChecked(config->readBoolEntry("DockWhenMinimized", true));
mDockWhenObscured->setChecked(config->readBoolEntry("DockWhenObscured", false));
mSkipTaskbar->setChecked(config->readBoolEntry("SkipTaskbar", false));
mWithdrawn = config->readBoolEntry("Withdraw", false); mWithdrawn = config->readBoolEntry("Withdraw", false);
dock(); dock();
@ -833,4 +1083,4 @@ bool TQTrayLabel::restoreState(TDEConfig *config)
// End kicking butt // End kicking butt
#include "qtraylabel.moc" #include "tqtraylabel.moc"

@ -31,6 +31,7 @@
#include <tqsettings.h> #include <tqsettings.h>
#include <tqevent.h> #include <tqevent.h>
#include <tqsize.h> #include <tqsize.h>
#include <tdeactionclasses.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
@ -41,52 +42,51 @@
class TQMouseEvent; class TQMouseEvent;
class TQDragEnterEvent; class TQDragEnterEvent;
class TQDropEvent;
class TQPoint; class TQPoint;
class TQWidget;
class TDEConfig; class TDEConfig;
class TDEPopupMenu;
class TDEToggleAction;
class TQTrayLabel : public TQLabel class TQTrayLabel : public TQLabel
{ {
Q_OBJECT Q_OBJECT
public: public:
TQTrayLabel(Window w, TQWidget* p = 0, const TQString& text = TQString::null); TQTrayLabel(Window w, TQWidget *p = NULL, const TQString &text = TQString::null);
TQTrayLabel(const TQStringList& argv, pid_t pid, TQWidget* parent = 0); TQTrayLabel(const TQStringList &argv, pid_t pid, TQWidget *parent = NULL);
virtual ~TQTrayLabel(); virtual ~TQTrayLabel();
// Accessors // Accessors
Window dockedWindow(void) const { return mDockedWindow; } Window dockedWindow(void) const { return mDockedWindow; }
int balloonTimeout(void) const { return mBalloonTimeout; } int balloonTimeout(void) const { return mBalloonTimeout; }
bool isSkippingTaskbar(void) const { return mSkippingTaskbar; }
bool isWithdrawn(void) const { return mWithdrawn; }
bool isDockWhenMinimized(void) const { return mDockWhenMinimized; }
TQString appName(void) const { return (mProgName.count() > 0) ? mProgName[0] : TQString::null; } TQString appName(void) const { return (mProgName.count() > 0) ? mProgName[0] : TQString::null; }
virtual void setAppName(const TQString& prog); void setAppName(const TQString& prog);
TQString appClass(void) const { return mClass; }
TQString appTitle(void) const { return mTitle; }
TQPixmap appIcon(void) const { return mAppIcon; }
// Pass on all events through this interface // Pass on all events through this interface
bool x11EventFilter(XEvent * event); bool x11EventFilter(XEvent * event);
// Session Management // Session Management
virtual bool saveState(TDEConfig *config); bool saveState(TDEConfig *config);
virtual bool restoreState(TDEConfig *config); bool restoreState(TDEConfig *config);
public slots: public slots:
void dock(void); // puts us in the system tray void dock(void); // puts us in the system tray
void undock(void); // removes us from the system tray void undock(void); // removes us from the system tray
void map(void); // maps the window that we are docking void map(void); // maps the window that we are docking
void withdraw(void); // withdraws the window that we are docking void withdraw(void); // withdraws the window that we are docking
void toggleShow(void) // convenience slot void toggleShow(void); // toggle window show status
{ if (mWithdrawn) map(); else withdraw(); }
void close(void); // close the docked window void close(void); // close the docked window
void setTrayIcon(const TQString& icon); // sets custom icon void setTrayIcon(const TQString& icon); // sets custom icon
// and some property setters // and some property setters
virtual void setSkipTaskbar(bool skip); // skip the taskbar void setSkipTaskbar(bool skip);
virtual void setBalloonTimeout(int msecs) { mBalloonTimeout = msecs; } void setBalloonTimeout(int msecs) { mBalloonTimeout = msecs; }
virtual void setDockWhenMinimized(bool dwm) { mDockWhenMinimized = dwm; } void setDockWhenObscured(bool dock) { mDockWhenObscured->setChecked(dock); }
void setDockWhenRestored(bool dwr);
void setSessionManagement(bool sm) { mSessionManaged = sm; }
protected slots: protected slots:
void scanClients(void); // scans existing client connections void scanClients(void); // scans existing client connections
@ -102,25 +102,23 @@ signals:
protected: protected:
// reimplement these event handlers in subclass as needed // reimplement these event handlers in subclass as needed
virtual void mouseReleaseEvent(TQMouseEvent *event); void dropEvent(TQDropEvent *ev);
virtual void dragEnterEvent(TQDragEnterEvent *event); void mouseReleaseEvent(TQMouseEvent *event);
void dragEnterEvent(TQDragEnterEvent *event);
// the events that follow are events of the docked window (NOT TQTrayLabel) // the events that follow are events of the docked window (NOT TQTrayLabel)
virtual void updateIcon(void); // updates the icon void updateIcon(void); // updates the icon
virtual void updateTitle(void); // sets the tooltip void updateTitle(void); // sets the tooltip
virtual void balloonText(void); // balloons text void balloonText(void); // balloons text
virtual void obscureEvent(void) { } void destroyEvent(void);
virtual void mapEvent(void) { } void focusLostEvent(void);
virtual void focusLostEvent(void) { } void mapEvent(void);
virtual void unmapEvent(void) { } void minimizeEvent(void);
virtual void minimizeEvent(void); void obscureEvent(void);
virtual void destroyEvent(void); void unmapEvent(void);
// needs to return if we can unsubscribe for root bool canUnsubscribeFromRoot(void);
virtual bool canUnsubscribeFromRoot(void) { return true; } void processDead(void);
// needs to return if we can dock a candidate window
virtual bool canDockWindow(Window) { return true; }
virtual void processDead(void) { }
void propertyChangeEvent(Atom); void propertyChangeEvent(Atom);
void setDockedWindow(Window w); // set docked window to anything you want void setDockedWindow(Window w); // set docked window to anything you want
@ -128,27 +126,28 @@ protected:
private slots: private slots:
void realityCheck(void); void realityCheck(void);
void showOnAllDesktops(void); void showOnAllDesktops(void);
void toggleDockWhenMinimized(void) void toggleDockWhenMinimized(void) { mDockWhenMinimized->setChecked(!mDockWhenMinimized->isChecked()); }
{ mDockWhenMinimized = !mDockWhenMinimized; } void skipTaskbar(void);
void skipTaskbar(void); void setCustomIcon(void);
void updateMenu(void);
void slotSetBalloonTimeout(void);
private: private:
// Helpers // Helpers
void initialize(void);
void handleTitleChange(void); void handleTitleChange(void);
void handleIconChange(void); void handleIconChange(void);
public: void initialize(void);
void installMenu();
const char *me(void) const; const char *me(void) const;
private:
// Member variables // Member variables
long mDesktop; // desktop on which the window is being shown long mDesktop; // desktop on which the window is being shown
TQLabel *mBalloon; // tooltip text simulator TQLabel *mBalloon; // tooltip text simulator
TQString mCustomIcon; // CustomIcon of the docked application TQString mCustomIcon; // CustomIcon of the docked application
Window mDockedWindow; // the window which is being docked Window mDockedWindow; // the window which is being docked
int mBalloonTimeout; int mBalloonTimeout, mShowId;
bool mDocked, mWithdrawn, mSkippingTaskbar; bool mDocked, mWithdrawn, mUndockWhenDead, mSessionManaged;
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()) TQPixmap mAppIcon; // The current app icon (may not be same as pixmap())
@ -157,8 +156,14 @@ private:
TQTimer mRealityMonitor; // Helps us sync up with reality TQTimer mRealityMonitor; // Helps us sync up with reality
TQStringList mProgName; // The program whose window we are docking TQStringList mProgName; // The program whose window we are docking
pid_t mPid; // The PID of 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
// GUI
TDEAction *mBalloonTimeoutAction;
TDEPopupMenu *mMainMenu, *mOptionsMenu;
TDEToggleAction *mDockWhenRestored, *mDockWhenFocusLost, *mDockWhenMinimized,
*mDockWhenObscured, *mSkipTaskbar;
}; };
#endif // _QTRAYLABEL_H #endif // _QTRAYLABEL_H

@ -327,9 +327,7 @@ bool TrayLabelMgr::processCommand(int argc, char** argv)
} // while (getopt) } // while (getopt)
// Launch an application if present in command line. else request from user // Launch an application if present in command line. else request from user
CustomTrayLabel *t = (CustomTrayLabel *) // this should be dynamic_cast TQTrayLabel *t = (optind < argc) ? dockApplication(&argv[optind]) : selectAndDock(w, check_normality);
((optind < argc) ? dockApplication(&argv[optind])
: selectAndDock(w, check_normality));
if (t == NULL) return false; if (t == NULL) return false;
// apply settings and add to tray // apply settings and add to tray
manageTrayLabel(t); manageTrayLabel(t);
@ -338,7 +336,7 @@ bool TrayLabelMgr::processCommand(int argc, char** argv)
t->setBalloonTimeout(balloon_timeout); t->setBalloonTimeout(balloon_timeout);
t->setDockWhenObscured(dock_obscure); t->setDockWhenObscured(dock_obscure);
if (withdraw) t->withdraw(); else t->map(); if (withdraw) t->withdraw(); else t->map();
t->enableSessionManagement(enable_sm); t->setSessionManagement(enable_sm);
t->dock(); t->dock();
return true; return true;
} }
@ -379,7 +377,10 @@ TQTrayLabel *TrayLabelMgr::selectAndDock(Window w, bool checkNormality)
} }
} }
if (!isWindowDocked(w)) return new CustomTrayLabel(w); if (!isWindowDocked(w))
{
return new TQTrayLabel(w);
}
TRACE("0x%x is alredy docked", (unsigned) w); TRACE("0x%x is alredy docked", (unsigned) w);
@ -438,10 +439,14 @@ TQTrayLabel *TrayLabelMgr::dockApplication(char *argv[])
} }
TQStringList cmd_line; TQStringList cmd_line;
for(int i=0;;i++) int i = 0;
if (argv[i]) cmd_line << argv[i]; else break; while (argv[i])
{
cmd_line.append(argv[i]);
++i;
}
TQTrayLabel *label = new CustomTrayLabel(cmd_line, pid); TQTrayLabel *label = new TQTrayLabel(cmd_line, pid);
TDEApplication::kApplication()->syncX(); TDEApplication::kApplication()->syncX();
write(filedes[1], buf, sizeof(buf)); write(filedes[1], buf, sizeof(buf));
close(filedes[0]); close(filedes[0]);
@ -537,7 +542,7 @@ void TrayLabelMgr::doRestoreSession()
if (!pname.isEmpty()) if (!pname.isEmpty())
{ {
TRACE("Restoring Application[%s]", pname.ascii()); TRACE("Restoring Application[%s]", pname.ascii());
manageTrayLabel(new CustomTrayLabel(TQStringList::split(" ", pname), 0)); manageTrayLabel(new TQTrayLabel(TQStringList::split(" ", pname), 0));
mTrayLabels.getFirst()->restoreState(config); mTrayLabels.getFirst()->restoreState(config);
} }
} }

@ -27,10 +27,9 @@
#include <tqstringlist.h> #include <tqstringlist.h>
#include <tqtimer.h> #include <tqtimer.h>
#include <tdeapplication.h> #include <tdeapplication.h>
#include "tqtraylabel.h"
#include "customtraylabel.h" class TQTrayLabel;
class CustomTrayLabel;
class TDECmdLineArgs; class TDECmdLineArgs;
class TQSessionManager; class TQSessionManager;
@ -70,8 +69,8 @@ private:
void manageTrayLabel(TQTrayLabel *l); void manageTrayLabel(TQTrayLabel *l);
void restoreSession(); void restoreSession();
TQTrayLabel *dockApplication(char *argv[]); TQTrayLabel* dockApplication(char *argv[]);
TQTrayLabel *selectAndDock(Window w = None, bool checkNormality = true); TQTrayLabel* selectAndDock(Window w = None, bool checkNormality = true);
TQPtrList<TQTrayLabel> mTrayLabels; TQPtrList<TQTrayLabel> mTrayLabels;
TQValueList<TQStringList> mRequestQ; TQValueList<TQStringList> mRequestQ;

Loading…
Cancel
Save