diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-03-31 22:41:41 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-03-31 22:41:41 +0900 |
commit | 6fcc661ff72af5a957a1a8d2737d2327dba8841e (patch) | |
tree | 284b56632512e37875a8a19a5792551e147402d1 | |
parent | 05add324c22f8fb2d1824a8a6145b2b8821e95bb (diff) | |
download | tdedocker-6fcc661ff72af5a957a1a8d2737d2327dba8841e.tar.gz tdedocker-6fcc661ff72af5a957a1a8d2737d2327dba8841e.zip |
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>
-rw-r--r-- | src/CMakeLists.txt | 10 | ||||
-rw-r--r-- | src/customtraylabel.cpp | 300 | ||||
-rw-r--r-- | src/customtraylabel.h | 82 | ||||
-rw-r--r-- | src/main.cpp | 4 | ||||
-rw-r--r-- | src/tdedocker.cpp | 58 | ||||
-rw-r--r-- | src/tqtraylabel.cpp (renamed from src/qtraylabel.cpp) | 414 | ||||
-rw-r--r-- | src/tqtraylabel.h (renamed from src/qtraylabel.h) | 91 | ||||
-rw-r--r-- | src/traylabelmgr.cpp | 23 | ||||
-rw-r--r-- | src/traylabelmgr.h | 9 |
9 files changed, 455 insertions, 536 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2c55b10..f52b7ba 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,14 +28,8 @@ link_directories( tde_add_executable( tdedocker AUTOMOC SOURCES - customtraylabel.cpp - tdedocker.cpp - main.cpp - qtraylabel.cpp - trace.cpp - traylabelmgr.cpp - util.cpp - trace.cpp + tdedocker.cpp main.cpp tqtraylabel.cpp + trace.cpp traylabelmgr.cpp util.cpp LINK tdecore-shared tdeui-shared DCOP-shared ${XMU_LIBRARIES} ${XPM_LIBRARIES} diff --git a/src/customtraylabel.cpp b/src/customtraylabel.cpp deleted file mode 100644 index a85f540..0000000 --- a/src/customtraylabel.cpp +++ /dev/null @@ -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" diff --git a/src/customtraylabel.h b/src/customtraylabel.h deleted file mode 100644 index 8206a52..0000000 --- a/src/customtraylabel.h +++ /dev/null @@ -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 diff --git a/src/main.cpp b/src/main.cpp index d10215d..437bc42 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,9 +54,9 @@ 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 }, + { "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 }, + { "m", I18N_NOOP("Keep application window mapped (don't 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 }, diff --git a/src/tdedocker.cpp b/src/tdedocker.cpp index 8021e67..f32cea6 100644 --- a/src/tdedocker.cpp +++ b/src/tdedocker.cpp @@ -1,16 +1,16 @@ -/* +/* * 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, @@ -101,6 +101,54 @@ void TDEDocker::notifyPreviousInstance(Window prevInstance) { TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); 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++) { s << " " << args->arg(i); @@ -141,7 +189,7 @@ bool TDEDocker::x11EventFilter(XEvent * event) if (!(client->message_type == 0x220679 && client->data.l[0] == 0xBABE)) return FALSE; - TRACE("ClientMessage from PID=%ld. SelOwn=0x%x", + TRACE("ClientMessage from PID=%ld. SelOwn=0x%x", client->data.l[1], (unsigned) mSelectionOwner); char tmp[50]; struct stat buf; @@ -153,7 +201,7 @@ bool TDEDocker::x11EventFilter(XEvent * event) * are the same. This will prevent someone from executing arbitrary * 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 - * 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. */ TRACE("User %i is trying something fishy...", buf.st_uid); diff --git a/src/qtraylabel.cpp b/src/tqtraylabel.cpp index 13c020d..61ace00 100644 --- a/src/qtraylabel.cpp +++ b/src/tqtraylabel.cpp @@ -22,18 +22,25 @@ // Include all TQt includes before X #include <tqstring.h> #include <tqevent.h> +#include <tqfiledialog.h> +#include <tqfileinfo.h> +#include <tqimage.h> +#include <tqinputdialog.h> +#include <tqpixmap.h> #include <tqpoint.h> #include <tqtooltip.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 <kstdguiitem.h> +#include <tqapplication.h> +#include <tdeconfig.h> #include <tdeglobal.h> +#include <tdelocale.h> +#include <tdemessagebox.h> +#include <tdepopupmenu.h> #include <X11/cursorfont.h> #include <X11/xpm.h> @@ -45,20 +52,21 @@ #include <sys/wait.h> #include "util.h" -#include "qtraylabel.h" +#include "trace.h" +#include "traylabelmgr.h" +#include "tqtraylabel.h" void TQTrayLabel::initialize(void) { mDocked = false; mWithdrawn = true; mBalloonTimeout = 4000; - mSkippingTaskbar = false; - mDockWhenMinimized = true; + mUndockWhenDead = false; mDesktop = 666; // setDockedWindow would set it a saner value // Balloon's properties are set to match a TQt tool tip (see TQt source) mBalloon = new TQLabel(0, "balloon", WType_TopLevel | WStyle_StaysOnTop | - WStyle_Customize | WStyle_NoBorder | + WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WX11BypassWM); mBalloon->setFont(TQToolTip::font()); mBalloon->setPalette(TQToolTip::palette()); @@ -76,32 +84,30 @@ void TQTrayLabel::initialize(void) if (mSysTray != None) subscribe(TQPaintDevice::x11AppDisplay(), mSysTray, StructureNotifyMask, true); + + installMenu(); } // Describe ourselves in a few words const char *TQTrayLabel::me(void) const { 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); return temp; } -TQTrayLabel::TQTrayLabel(Window w, TQWidget* parent, const TQString& text) - :TQLabel(parent, text.utf8(), WStyle_Customize | WStyle_NoBorder | WStyle_Tool), - mDockedWindow(w), mPid(0) +TQTrayLabel::TQTrayLabel(Window w, TQWidget *parent, const TQString &text) + : TQLabel(parent, text.utf8(), WStyle_Customize | WStyle_NoBorder | WStyle_Tool), + mDockedWindow(w), mPid(0) { initialize(); } -TQTrayLabel::TQTrayLabel(const TQStringList& pname, pid_t pid, TQWidget* parent) - :TQLabel(parent, "TrayLabel", WStyle_Customize | WStyle_NoBorder | WStyle_Tool), - mDockedWindow(None), mProgName(pname), mPid(pid) +TQTrayLabel::TQTrayLabel(const TQStringList &pname, pid_t pid, TQWidget *parent) + : TQLabel(parent, "TrayLabel", WStyle_Customize | WStyle_NoBorder | WStyle_Tool), + 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(); } @@ -110,20 +116,18 @@ TQTrayLabel::~TQTrayLabel() TRACE("%s Goodbye", me()); if (mDockedWindow == None) return; // Leave the docked window is some sane state - mSkippingTaskbar = false; + mSkipTaskbar->setChecked(false); skipTaskbar(); map(); } void TQTrayLabel::setAppName(const TQString &prog) { + // FIXME HACK + // using "prog.lower()" relies on window and application name being the same. if (mProgName.count() == 0) { - mProgName.push_front(prog); - } - else - { - mProgName[0] = prog; + mProgName.push_front(prog.lower()); } } @@ -180,18 +184,18 @@ void TQTrayLabel::realityCheck(void) /* * I am not sure when, but TQt at some point in time overwrites our * 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 * 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 - * 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 */ Display *display = TQPaintDevice::x11AppDisplay(); XWindowAttributes attr; XGetWindowAttributes(display, tqt_xrootwin(), &attr); - if (!(attr.your_event_mask & SubstructureNotifyMask)) + if (!(attr.your_event_mask & SubstructureNotifyMask)) { subscribe(display, None, SubstructureNotifyMask, true); TRACE("%s rescanning clients since qt overrode mask", me()); @@ -251,16 +255,16 @@ void TQTrayLabel::dock(void) // 1. GNOME and NET WM Specification 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)); // 2. KDE 3.x and above - Atom tray_atom = + 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); - // 3. All other KDEs + // 3. All other KDEs tray_atom = XInternAtom(display, "KWM_DOCKWINDOW", False); XChangeProperty(display, wid, tray_atom, XA_WINDOW, 32, PropModeReplace, (unsigned char *) &wid, 1); @@ -270,7 +274,12 @@ void TQTrayLabel::dock(void) handleTitleChange(); 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) @@ -319,19 +328,19 @@ void TQTrayLabel::map(void) * _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 * 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())); } /* * 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 * window go through Withdrawn->Iconify->Normal state. */ XWMHints *wm_hint = XGetWMHints(display, mDockedWindow); - if (wm_hint) + if (wm_hint) { wm_hint->initial_state = IconicState; XSetWMHints(display, mDockedWindow, wm_hint); @@ -347,9 +356,11 @@ void TQTrayLabel::map(void) 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) - mDockWhenMinimized = !mDockWhenMinimized; - TQTimer::singleShot(230, this, SLOT(toggleDockWhenMinimized())); + // disable "dock when minized" for a short while since we went to Iconic state + // (when the window is mapped, often an IconicState WM_STATE message is sent too + // just before the NormalState) + toggleDockWhenMinimized(); + TQTimer::singleShot(500, this, SLOT(toggleDockWhenMinimized())); } void TQTrayLabel::withdraw(void) @@ -366,7 +377,7 @@ void TQTrayLabel::withdraw(void) /* * 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. * 2. Next tell the WM, that we would like to go to withdrawn state. Withdrawn * 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 - * have _NET_WM_STATE_SKIP_TASKBAR. NET_WM_STATE needs to be updated + * 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 * carefully since it is a set of states. */ void TQTrayLabel::skipTaskbar(void) @@ -415,8 +426,10 @@ void TQTrayLabel::skipTaskbar(void) for (num_states = 0; num_states < nitems; num_states++) if (old_states[num_states] == skip_atom) break; - if (mSkippingTaskbar) + if (mSkipTaskbar->isChecked()) + { append = (num_states >= nitems); + } else { if (num_states < nitems) @@ -429,29 +442,54 @@ void TQTrayLabel::skipTaskbar(void) XFree(data); } - TRACE("%s SkippingTaskar=%i append=%i replace=%i", me(), mSkippingTaskbar, - append, replace); + TRACE("%s SkippingTaskar=%i append=%i replace=%i", me(), + mSkipTaskbar->isChecked(), append, replace); - if (mSkippingTaskbar) + if (mSkipTaskbar->isChecked()) { 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); + } } 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); + } } void TQTrayLabel::setSkipTaskbar(bool skip) { - TRACE("%s Skip=%i", me(), skip); - mSkippingTaskbar = skip; - if (mDockedWindow != None && !mWithdrawn) skipTaskbar(); + TRACE("%s skip=%i", me(), skip); + if (skip != mSkipTaskbar->isChecked()) + { + // 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. */ void TQTrayLabel::close(void) @@ -462,11 +500,21 @@ void TQTrayLabel::close(void) long l[5] = { 0, 0, 0, 0, 0 }; map(); sendMessage(display, tqt_xrootwin(), mDockedWindow, "_NET_CLOSE_WINDOW", 32, - SubstructureNotifyMask | SubstructureRedirectMask, + SubstructureNotifyMask | SubstructureRedirectMask, 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 */ void TQTrayLabel::setTrayIcon(const TQString& icon) @@ -478,8 +526,8 @@ void TQTrayLabel::setTrayIcon(const TQString& icon) } /* - * Sets the docked window to w. - * A) Start/stop reality timer. + * Sets the docked window to w. + * A) Start/stop reality timer. * B) Subscribe/Unsubscribe for root/w notifications as appropriate * C) And of course, dock the window and apply some settings */ @@ -489,8 +537,14 @@ void TQTrayLabel::setDockedWindow(Window w) 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; + mDockedWindow = None; + if (w != None) + { + if (!(TrayLabelMgr::instance()->isWindowDocked(w))) + { + mDockedWindow = w; + } + } 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); else { - if (canUnsubscribeFromRoot()) + if (canUnsubscribeFromRoot()) subscribe(d, None, ~SubstructureNotifyMask, false); else subscribe(d, None, SubstructureNotifyMask, true); - subscribe(d, w, - StructureNotifyMask | PropertyChangeMask | + subscribe(d, w, + StructureNotifyMask | PropertyChangeMask | VisibilityChangeMask | FocusChangeMask, true); } @@ -513,12 +567,14 @@ void TQTrayLabel::setDockedWindow(Window w) if (mDocked && w!=None) { // store the desktop on which the window is being shown - getCardinalProperty(d, mDockedWindow, + getCardinalProperty(d, mDockedWindow, XInternAtom(d, "_NET_WM_DESKTOP", True), &mDesktop); - if (mWithdrawn) + if (mWithdrawn) + { // show the window for sometime before docking - TQTimer::singleShot(1000, this, SLOT(withdraw())); + TQTimer::singleShot(500, this, SLOT(withdraw())); + } else map(); dock(); } @@ -539,7 +595,7 @@ void TQTrayLabel::balloonText() long l[5] = { CurrentTime, SYSTEM_TRAY_BEGIN_MESSAGE, 2000, mTitle.length(), id++ }; - sendMessage(display, mSystemTray, winId(), "_NET_SYSTEM_TRAY_OPCODE", 32, + sendMessage(display, mSystemTray, winId(), "_NET_SYSTEM_TRAY_OPCODE", 32, SubstructureNotifyMask | SubstructureRedirectMask, l, sizeof(l)); int length = mTitle.length(); @@ -624,7 +680,7 @@ void TQTrayLabel::handleIconChange(void) if (!(wm_hints->flags & IconMaskHint)) 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 * quite a few KDE programs) X-( */ @@ -634,7 +690,7 @@ void TQTrayLabel::handleIconChange(void) XFree(wm_hints); } TQImage image; - if (!window_icon) + if (!window_icon) { 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 */ -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) { - ev->accept(); + ev->accept(); 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 */ @@ -739,17 +810,61 @@ bool TQTrayLabel::x11EventFilter(XEvent *ev) 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) { TRACE("minimizeEvent"); - if (mDockWhenMinimized) withdraw(); + if (mDockWhenMinimized->isChecked()) + { + withdraw(); + } } -void TQTrayLabel::destroyEvent(void) +void TQTrayLabel::obscureEvent(void) { - TRACE("%s destroyEvent", me()); - setDockedWindow(None); - if (!mPid) undock(); + TRACE("obscureEvent"); + if (mDockWhenObscured->isChecked() && !mWithdrawn) + { + withdraw(); + } +} + +void TQTrayLabel::unmapEvent(void) +{ + // NO OP } 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 bool TQTrayLabel::saveState(TDEConfig *config) { - if (appName().isEmpty()) + TRACE("%s saving state", me()); + + if (!mDockWhenRestored->isChecked()) { return false; } - TRACE("%s saving state", me()); config->writeEntry("Application", mProgName.join(" ")); config->writeEntry("BalloonTimeout", mBalloonTimeout); config->writeEntry("CustomIcon", mCustomIcon); - config->writeEntry("DockWhenMinimized", mDockWhenMinimized); - config->writeEntry("SkipTaskbar", mSkippingTaskbar); + config->writeEntry("DockWhenFocusLost", mDockWhenFocusLost->isChecked()); + config->writeEntry("DockWhenMinimized", mDockWhenMinimized->isChecked()); + config->writeEntry("DockWhenObscured", mDockWhenObscured->isChecked()); + config->writeEntry("SkipTaskbar", mSkipTaskbar->isChecked()); config->writeEntry("Withdraw", mWithdrawn); return true; } @@ -813,8 +1061,10 @@ bool TQTrayLabel::restoreState(TDEConfig *config) TRACE("%s restoring state", me()); setBalloonTimeout(config->readNumEntry("BalloonTimeout", 4000)); mCustomIcon = config->readEntry("CustomIcon", TQString::null); - setDockWhenMinimized(config->readBoolEntry("DockWhenMinimized", false)); - setSkipTaskbar(config->readBoolEntry("SkipTaskbar", false)); + mDockWhenFocusLost->setChecked(config->readBoolEntry("DockWhenFocusLost", false)); + mDockWhenMinimized->setChecked(config->readBoolEntry("DockWhenMinimized", true)); + mDockWhenObscured->setChecked(config->readBoolEntry("DockWhenObscured", false)); + mSkipTaskbar->setChecked(config->readBoolEntry("SkipTaskbar", false)); mWithdrawn = config->readBoolEntry("Withdraw", false); dock(); @@ -833,4 +1083,4 @@ bool TQTrayLabel::restoreState(TDEConfig *config) // End kicking butt -#include "qtraylabel.moc" +#include "tqtraylabel.moc" diff --git a/src/qtraylabel.h b/src/tqtraylabel.h index 27d0ce4..462fc61 100644 --- a/src/qtraylabel.h +++ b/src/tqtraylabel.h @@ -31,6 +31,7 @@ #include <tqsettings.h> #include <tqevent.h> #include <tqsize.h> +#include <tdeactionclasses.h> #include <X11/Xlib.h> #include <X11/Xutil.h> @@ -41,52 +42,51 @@ class TQMouseEvent; class TQDragEnterEvent; +class TQDropEvent; class TQPoint; +class TQWidget; class TDEConfig; +class TDEPopupMenu; +class TDEToggleAction; class TQTrayLabel : public TQLabel { Q_OBJECT public: - TQTrayLabel(Window w, TQWidget* p = 0, const TQString& text = TQString::null); - TQTrayLabel(const TQStringList& argv, pid_t pid, TQWidget* parent = 0); + TQTrayLabel(Window w, TQWidget *p = NULL, const TQString &text = TQString::null); + TQTrayLabel(const TQStringList &argv, pid_t pid, TQWidget *parent = NULL); virtual ~TQTrayLabel(); // Accessors Window dockedWindow(void) const { return mDockedWindow; } 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; } - virtual void setAppName(const TQString& prog); - TQString appClass(void) const { return mClass; } - TQString appTitle(void) const { return mTitle; } - TQPixmap appIcon(void) const { return mAppIcon; } + void setAppName(const TQString& prog); // Pass on all events through this interface bool x11EventFilter(XEvent * event); // Session Management - virtual bool saveState(TDEConfig *config); - virtual bool restoreState(TDEConfig *config); + bool saveState(TDEConfig *config); + bool restoreState(TDEConfig *config); public slots: void dock(void); // puts us in the system tray void undock(void); // removes us from the system tray void map(void); // maps the window that we are docking void withdraw(void); // withdraws the window that we are docking - void toggleShow(void) // convenience slot - { if (mWithdrawn) map(); else withdraw(); } + void toggleShow(void); // toggle window show status void close(void); // close the docked window void setTrayIcon(const TQString& icon); // sets custom icon // and some property setters - virtual void setSkipTaskbar(bool skip); // skip the taskbar - virtual void setBalloonTimeout(int msecs) { mBalloonTimeout = msecs; } - virtual void setDockWhenMinimized(bool dwm) { mDockWhenMinimized = dwm; } + void setSkipTaskbar(bool skip); + void setBalloonTimeout(int msecs) { mBalloonTimeout = msecs; } + void setDockWhenObscured(bool dock) { mDockWhenObscured->setChecked(dock); } + void setDockWhenRestored(bool dwr); + void setSessionManagement(bool sm) { mSessionManaged = sm; } protected slots: void scanClients(void); // scans existing client connections @@ -102,25 +102,23 @@ signals: protected: // reimplement these event handlers in subclass as needed - virtual void mouseReleaseEvent(TQMouseEvent *event); - virtual void dragEnterEvent(TQDragEnterEvent *event); + void dropEvent(TQDropEvent *ev); + void mouseReleaseEvent(TQMouseEvent *event); + 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 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 - virtual bool canDockWindow(Window) { return true; } - virtual void processDead(void) { } + void updateIcon(void); // updates the icon + void updateTitle(void); // sets the tooltip + void balloonText(void); // balloons text + void destroyEvent(void); + void focusLostEvent(void); + void mapEvent(void); + void minimizeEvent(void); + void obscureEvent(void); + void unmapEvent(void); + + bool canUnsubscribeFromRoot(void); + void processDead(void); void propertyChangeEvent(Atom); void setDockedWindow(Window w); // set docked window to anything you want @@ -128,27 +126,28 @@ protected: private slots: void realityCheck(void); void showOnAllDesktops(void); - void toggleDockWhenMinimized(void) - { mDockWhenMinimized = !mDockWhenMinimized; } - void skipTaskbar(void); + void toggleDockWhenMinimized(void) { mDockWhenMinimized->setChecked(!mDockWhenMinimized->isChecked()); } + void skipTaskbar(void); + void setCustomIcon(void); + void updateMenu(void); + void slotSetBalloonTimeout(void); private: // Helpers - void initialize(void); void handleTitleChange(void); void handleIconChange(void); -public: + void initialize(void); + void installMenu(); + 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; - bool mDocked, mWithdrawn, mSkippingTaskbar; - bool mDockWhenMinimized; + int mBalloonTimeout, mShowId; + bool mDocked, mWithdrawn, mUndockWhenDead, mSessionManaged; TQString mTitle, mClass; // Title and hint of mDockedWindow 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 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 + + // GUI + TDEAction *mBalloonTimeoutAction; + TDEPopupMenu *mMainMenu, *mOptionsMenu; + TDEToggleAction *mDockWhenRestored, *mDockWhenFocusLost, *mDockWhenMinimized, + *mDockWhenObscured, *mSkipTaskbar; + }; #endif // _QTRAYLABEL_H diff --git a/src/traylabelmgr.cpp b/src/traylabelmgr.cpp index 54e8fbd..54b98bd 100644 --- a/src/traylabelmgr.cpp +++ b/src/traylabelmgr.cpp @@ -327,9 +327,7 @@ bool TrayLabelMgr::processCommand(int argc, char** argv) } // while (getopt) // 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)); + TQTrayLabel *t = (optind < argc) ? dockApplication(&argv[optind]) : selectAndDock(w, check_normality); if (t == NULL) return false; // apply settings and add to tray manageTrayLabel(t); @@ -338,7 +336,7 @@ bool TrayLabelMgr::processCommand(int argc, char** argv) t->setBalloonTimeout(balloon_timeout); t->setDockWhenObscured(dock_obscure); if (withdraw) t->withdraw(); else t->map(); - t->enableSessionManagement(enable_sm); + t->setSessionManagement(enable_sm); t->dock(); 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); @@ -438,10 +439,14 @@ TQTrayLabel *TrayLabelMgr::dockApplication(char *argv[]) } TQStringList cmd_line; - for(int i=0;;i++) - if (argv[i]) cmd_line << argv[i]; else break; + int i = 0; + 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(); write(filedes[1], buf, sizeof(buf)); close(filedes[0]); @@ -537,7 +542,7 @@ void TrayLabelMgr::doRestoreSession() if (!pname.isEmpty()) { TRACE("Restoring Application[%s]", pname.ascii()); - manageTrayLabel(new CustomTrayLabel(TQStringList::split(" ", pname), 0)); + manageTrayLabel(new TQTrayLabel(TQStringList::split(" ", pname), 0)); mTrayLabels.getFirst()->restoreState(config); } } diff --git a/src/traylabelmgr.h b/src/traylabelmgr.h index 3d54cbd..c2a7dbc 100644 --- a/src/traylabelmgr.h +++ b/src/traylabelmgr.h @@ -27,10 +27,9 @@ #include <tqstringlist.h> #include <tqtimer.h> #include <tdeapplication.h> +#include "tqtraylabel.h" -#include "customtraylabel.h" - -class CustomTrayLabel; +class TQTrayLabel; class TDECmdLineArgs; class TQSessionManager; @@ -70,8 +69,8 @@ private: void manageTrayLabel(TQTrayLabel *l); void restoreSession(); - TQTrayLabel *dockApplication(char *argv[]); - TQTrayLabel *selectAndDock(Window w = None, bool checkNormality = true); + TQTrayLabel* dockApplication(char *argv[]); + TQTrayLabel* selectAndDock(Window w = None, bool checkNormality = true); TQPtrList<TQTrayLabel> mTrayLabels; TQValueList<TQStringList> mRequestQ; |