diff options
author | Michele Calgaro <[email protected]> | 2020-03-31 22:41:41 +0900 |
---|---|---|
committer | Michele Calgaro <[email protected]> | 2020-03-31 22:41:41 +0900 |
commit | 6fcc661ff72af5a957a1a8d2737d2327dba8841e (patch) | |
tree | 284b56632512e37875a8a19a5792551e147402d1 /src/qtraylabel.cpp | |
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 <[email protected]>
Diffstat (limited to 'src/qtraylabel.cpp')
-rw-r--r-- | src/qtraylabel.cpp | 836 |
1 files changed, 0 insertions, 836 deletions
diff --git a/src/qtraylabel.cpp b/src/qtraylabel.cpp deleted file mode 100644 index 13c020d..0000000 --- a/src/qtraylabel.cpp +++ /dev/null @@ -1,836 +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: qtraylabel.cpp,v 1.31 2005/06/21 10:04:36 cs19713 Exp $ - -// Include all TQt includes before X -#include <tqstring.h> -#include <tqevent.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 <kiconloader.h> -#include <tdeglobal.h> - -#include <X11/cursorfont.h> -#include <X11/xpm.h> -#include <X11/Xmu/WinUtil.h> - -#include <string.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/wait.h> -#include "util.h" - -#include "qtraylabel.h" - -void TQTrayLabel::initialize(void) -{ - mDocked = false; - mWithdrawn = true; - mBalloonTimeout = 4000; - mSkippingTaskbar = false; - mDockWhenMinimized = true; - 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_Tool | WX11BypassWM); - mBalloon->setFont(TQToolTip::font()); - mBalloon->setPalette(TQToolTip::palette()); - mBalloon->setAlignment(TQt::AlignLeft | TQt::AlignTop); - mBalloon->setAutoMask(FALSE); - mBalloon->setAutoResize(true); - setAlignment(TQt::AlignCenter); - setBackgroundMode(X11ParentRelative); - - connect(&mRealityMonitor, SIGNAL(timeout()), this, SLOT(realityCheck())); - setDockedWindow(mDockedWindow); - - sysTrayStatus(TQPaintDevice::x11AppDisplay(), &mSysTray); - // Subscribe to system tray window notifications - if (mSysTray != None) - subscribe(TQPaintDevice::x11AppDisplay(), mSysTray, - StructureNotifyMask, true); -} - -// 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)", - 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) -{ - 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) -{ - if (pname[0].at(0) != '/' && pname[0].find('/', 1) > 0) - { - mProgName.push_front(TQFileInfo(pname[0]).absFilePath()); // convert to absolute - } - initialize(); -} - -TQTrayLabel::~TQTrayLabel() -{ - TRACE("%s Goodbye", me()); - if (mDockedWindow == None) return; - // Leave the docked window is some sane state - mSkippingTaskbar = false; - skipTaskbar(); - map(); -} - -void TQTrayLabel::setAppName(const TQString &prog) -{ - if (mProgName.count() == 0) - { - mProgName.push_front(prog); - } - else - { - mProgName[0] = prog; - } -} - -/* - * Scans the windows in the desktop and checks if a window exists that we might - * be interested in - */ -void TQTrayLabel::scanClients() -{ - Window r, parent, *children; - unsigned nchildren = 0; - Display *display = TQPaintDevice::x11AppDisplay(); - TQString ename = TQFileInfo(appName()).fileName(); // strip out the path - - XQueryTree(display, tqt_xrootwin(), &r, &parent, &children, &nchildren); - TRACE("%s nchildren=%i", me(), nchildren); - for(unsigned i=0; i<nchildren; i++) - { - Window w = XmuClientWindow(display, children[i]); - TRACE("\t%s checking(1) 0x%x", me(), (unsigned) w); - if (!isNormalWindow(display, w)) continue; - if (analyzeWindow(display, w, mPid, ename.local8Bit())) - { - TRACE("\t%s SOULMATE FOUND (1)", me()); - setDockedWindow(w); - return; - } - } -} - -/* - * Do a reality check :). Note that this timer runs only when required. Does 3 - * things, - * 1) If the system tray had disappeared, checks for arrival of new system tray - * 2) Check root window subscription since it is overwritten by TQt (see below) - * 3) Checks health of the process whose windows we are docking - */ -void TQTrayLabel::realityCheck(void) -{ - if (mSysTray == None) - { - // Check the system tray status if we were docked - if (sysTrayStatus(TQPaintDevice::x11AppDisplay(), &mSysTray) - != SysTrayPresent) return; // no luck - - TRACE("%s System tray present", me()); - dock(); - subscribe(TQPaintDevice::x11AppDisplay(), mSysTray, - StructureNotifyMask, true); - mRealityMonitor.stop(); - return; - } - - /* - * 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 - * 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 - * 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)) - { - subscribe(display, None, SubstructureNotifyMask, true); - TRACE("%s rescanning clients since qt overrode mask", me()); - scanClients(); - } - - if (mPid) - { - // Check process health - int status; - if (waitpid(mPid, &status, WNOHANG) == 0) return; // still running - TRACE("%s processDead", me()); - mPid = 0; - processDead(); - } -} - -/* - * Sends a message to the WM to show this window on all the desktops - */ -void TQTrayLabel::showOnAllDesktops(void) -{ - TRACE("Showing on all desktops"); - Display *d = TQPaintDevice::x11AppDisplay(); - long l[5] = { -1, 0, 0, 0, 0 }; // -1 = all, 0 = Desktop1, 1 = Desktop2 ... - sendMessage(d, tqt_xrootwin(), mDockedWindow, "_NET_WM_DESKTOP", 32, - SubstructureNotifyMask | SubstructureRedirectMask, l, sizeof(l)); -} - -// System tray messages -const long SYSTEM_TRAY_REQUEST_DOCK = 0; -const long SYSTEM_TRAY_BEGIN_MESSAGE = 1; -const long SYSTEM_TRAY_CANCEL_MESSAGE = 2; - -/* - * Add the window to the system tray. Different WM require different hints to be - * set. We support the following (Google for more information), - * 1. GNOME - SYSTEM_TRAY_REQUEST_DOCK (freedesktop.org) - * 2. KDE 3.x and above - _KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR - * 3. Older KDE - KWM_DOCKWINDOW (Untested) - */ -void TQTrayLabel::dock(void) -{ - TRACE("%s", me()); - mDocked = true; - if (mDockedWindow == None) return; // nothing to add - - if (mSysTray == None) // no system tray yet - { - TRACE("%s starting reality monitor", me()); - mRealityMonitor.start(500); - return; - } - - Display *display = TQPaintDevice::x11AppDisplay(); - Window wid = winId(); - - // 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", - 32, 0L, l, sizeof(l)); - - // 2. KDE 3.x and above - 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 - tray_atom = XInternAtom(display, "KWM_DOCKWINDOW", False); - XChangeProperty(display, wid, tray_atom, XA_WINDOW, 32, - PropModeReplace, (unsigned char *) &wid, 1); - - TRACE("%s ", me()); - - handleTitleChange(); - handleIconChange(); - - if (mProgName.count() == 0) setAppName(mClass); - - /* - * For Gnome, a delay is required before we do a show (dont ask me why) - * If I do a show() without any delay, sometimes the icon has width=1 pixel - * even though the minimumSizeHint = 24, 24. I have successfully got it - * working with with a delay of as little as 50ms. But since I - * dont understand why this delay is required, I am justifiably paranoid - */ - TQTimer::singleShot(500, this, SLOT(show())); - - // let the world know - emit docked(this); - emit docked(); -} - -/* - * Undocks. Removes us from the system tray. The spec doesnt say how an icon - * can be removed from the tray. KDE Spec says XUnmapWindow or XWithdraw should - * be used. It works but the system tray does not fill the void that we left - * in the tray. Looks like the system tray will resize only for DestroyEvents - */ -void TQTrayLabel::undock(void) -{ - TRACE("%s stopping reality monitor", me()); - mRealityMonitor.stop(); - XUnmapWindow(TQPaintDevice::x11AppDisplay(), winId()); - emit undocked(this); - emit undocked(); -} - -/* - * Maps the window from the same place it was withdrawn from - */ -void TQTrayLabel::map(void) -{ - TRACE("%s", me()); - mWithdrawn = false; - if (mDockedWindow == None) return; - - Display *display = TQPaintDevice::x11AppDisplay(); - - if (mDesktop == -1) - { - /* - * We track _NET_WM_DESKTOP changes in the x11EventFilter. Its used here. - * _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(). - */ - 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 - * 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) - { - wm_hint->initial_state = IconicState; - XSetWMHints(display, mDockedWindow, wm_hint); - XFree(wm_hint); - } - - XMapWindow(display, mDockedWindow); - mSizeHint.flags = USPosition; // Obsolete ? - XSetWMNormalHints(display, mDockedWindow, &mSizeHint); - // make it the active window - long l[5] = { None, CurrentTime, None, 0, 0 }; - sendMessage(display, tqt_xrootwin(), mDockedWindow, "_NET_ACTIVE_WINDOW", 32, - SubstructureNotifyMask | SubstructureRedirectMask, l, sizeof(l)); - // 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())); -} - -void TQTrayLabel::withdraw(void) -{ - TRACE("%s", me()); - mWithdrawn = true; - if (mDockedWindow == None) return; - - Display *display = TQPaintDevice::x11AppDisplay(); - int screen = DefaultScreen(display); - long dummy; - - XGetWMNormalHints(display, mDockedWindow, &mSizeHint, &dummy); - - /* - * 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 - * 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. - * Reference: ICCCM 4.1.4 Changing Window State - */ - XIconifyWindow(display, mDockedWindow, screen); // good for effects too - XUnmapWindow(display, mDockedWindow); - XUnmapEvent ev; - memset(&ev, 0, sizeof(ev)); - ev.type = UnmapNotify; - ev.display = display; - ev.event = tqt_xrootwin(); - ev.window = mDockedWindow; - ev.from_configure = false; - XSendEvent(display, tqt_xrootwin(), False, - SubstructureRedirectMask|SubstructureNotifyMask, (XEvent *)&ev); - XSync(display, False); -} - -/* - * 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) -{ - Atom __attribute__ ((unused)) type; - int __attribute__ ((unused)) format; - unsigned long __attribute__ ((unused)) left; - Atom *data = NULL; - unsigned long nitems = 0, num_states = 0; - Display *display = TQPaintDevice::x11AppDisplay(); - - TRACE("%s", me()); - Atom _NET_WM_STATE = XInternAtom(display, "_NET_WM_STATE", True); - Atom skip_atom = XInternAtom(display, "_NET_WM_STATE_SKIP_TASKBAR", False); - int ret = XGetWindowProperty(display, mDockedWindow, _NET_WM_STATE, 0, - 20, False, AnyPropertyType, &type, &format, - &nitems, &left, (unsigned char **) &data); - Atom *old_states = (Atom *) data; - bool append = true, replace = false; - - if ((ret == Success) && data) - { - // Search for the skip_atom. Stop when found - for (num_states = 0; num_states < nitems; num_states++) - if (old_states[num_states] == skip_atom) break; - - if (mSkippingTaskbar) - append = (num_states >= nitems); - else - { - if (num_states < nitems) - { - replace = true; // need to remove skip_atom - for (; num_states < nitems - 1; num_states++) - old_states[num_states] = old_states[num_states + 1]; - } - } - XFree(data); - } - - TRACE("%s SkippingTaskar=%i append=%i replace=%i", me(), mSkippingTaskbar, - append, replace); - - if (mSkippingTaskbar) - { - if (append) - 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, - 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(); -} - -/* - * 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) -{ - TRACE("%s", me()); - undock(); - Display *display = TQPaintDevice::x11AppDisplay(); - long l[5] = { 0, 0, 0, 0, 0 }; - map(); - sendMessage(display, tqt_xrootwin(), mDockedWindow, "_NET_CLOSE_WINDOW", 32, - SubstructureNotifyMask | SubstructureRedirectMask, - l, sizeof(l)); -} - -/* - * Sets the tray icon. If the icon failed to load, we revert to application icon - */ -void TQTrayLabel::setTrayIcon(const TQString& icon) -{ - mCustomIcon = icon; - if (TQPixmap(mCustomIcon).isNull()) mCustomIcon = TQString::null; - TRACE("%s mCustomIcon=%s", me(), mCustomIcon.local8Bit()); - updateIcon(); -} - -/* - * 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 - */ -void TQTrayLabel::setDockedWindow(Window w) -{ - TRACE("%s %s reality monitor", me(), - mDockedWindow==None ? "Starting" : "Stopping"); - - // Check if we are allowed to dock this window (allows custom rules) - if (w != None) mDockedWindow = canDockWindow(w) ? w : None; - else mDockedWindow = None; - - if (mDockedWindow == None) mRealityMonitor.start(500); else mRealityMonitor.stop(); - - Display *d = TQPaintDevice::x11AppDisplay(); - - // Subscribe for window or root window events - if (w == None) subscribe(d, None, SubstructureNotifyMask, true); - else - { - if (canUnsubscribeFromRoot()) - subscribe(d, None, ~SubstructureNotifyMask, false); - else subscribe(d, None, SubstructureNotifyMask, true); - - subscribe(d, w, - StructureNotifyMask | PropertyChangeMask | - VisibilityChangeMask | FocusChangeMask, - true); - } - - if (mDocked && w!=None) - { - // store the desktop on which the window is being shown - getCardinalProperty(d, mDockedWindow, - XInternAtom(d, "_NET_WM_DESKTOP", True), &mDesktop); - - if (mWithdrawn) - // show the window for sometime before docking - TQTimer::singleShot(1000, this, SLOT(withdraw())); - else map(); - dock(); - } -} - -/* - * Balloon text. Overload this if you dont like the way things are ballooned - */ -void TQTrayLabel::balloonText() -{ - TRACE("%s BalloonText=%s ToolTipText=%s", me(), - mBalloon->text().local8Bit(), TQToolTip::textFor(this).local8Bit()); - - if (mBalloon->text() == TQToolTip::textFor(this)) return; -#if 0 // I_GOT_NETWM_BALLOONING_TO_WORK - // if you can get NET WM ballooning to work let me know - static int id = 1; - long l[5] = { CurrentTime, SYSTEM_TRAY_BEGIN_MESSAGE, 2000, - mTitle.length(), id++ - }; - sendMessage(display, mSystemTray, winId(), "_NET_SYSTEM_TRAY_OPCODE", 32, - SubstructureNotifyMask | SubstructureRedirectMask, - l, sizeof(l)); - int length = mTitle.length(); - const char *data = mTitle.local8Bit(); - while (length > 0) - { - sendMessage(display, mSystemTray, winId(), "_NET_SYSTEM_TRAY_MESSAGE_DATA", 8, - SubstructureNotifyMask | SubstructureRedirectMask, - (void *) data, length > 20 ? 20 : length); - length -= 20; - data += 20; - } -#else - // Manually do ballooning. See the TQt ToolTip code - TQString oldText = mBalloon->text(); - mBalloon->setText(TQToolTip::textFor(this)); - if (oldText.isEmpty()) return; // dont tool tip the first time - TQPoint p = mapToGlobal(TQPoint(0, -1 - mBalloon->height())); - if (p.x() + mBalloon->width() > TQApplication::desktop()->width()) - p.setX(p.x() + width() - mBalloon->width()); - - if (p.y() < 0) p.setY(height() + 1); - - mBalloon->move(p); - mBalloon->show(); - TQTimer::singleShot(mBalloonTimeout, mBalloon, SLOT(hide())); -#endif -} - -/* - * Update the title in the menu. Balloon the title change if necessary - */ -void TQTrayLabel::handleTitleChange(void) -{ - Display *display = TQPaintDevice::x11AppDisplay(); - char *window_name = NULL; - - XFetchName(display, mDockedWindow, &window_name); - mTitle = window_name; - TRACE("%s has title [%s]", me(), mTitle.local8Bit()); - if (window_name) XFree(window_name); - - XClassHint ch; - if (XGetClassHint(display, mDockedWindow, &ch)) - { - if (ch.res_class) mClass = TQString(ch.res_class); - else if (ch.res_name) mClass = TQString(ch.res_name); - - if (ch.res_class) XFree(ch.res_class); - if (ch.res_name) XFree(ch.res_name); - } - - updateTitle(); - if (mBalloonTimeout) balloonText(); -} - -/* - * Overload this if you want a tool tip format that is different from the one - * below i.e "Title [Class]". - */ -void TQTrayLabel::updateTitle() -{ - TRACE("%s", me()); - TQString text = mTitle + " [" + mClass + "]"; - TQToolTip::remove(this); - TQToolTip::add(this, text); - - if (mBalloonTimeout) balloonText(); -} - -void TQTrayLabel::handleIconChange(void) -{ - char **window_icon = NULL; - - TRACE("%s", me()); - if (mDockedWindow == None) return; - - Display *display = TQPaintDevice::x11AppDisplay(); - XWMHints *wm_hints = XGetWMHints(display, mDockedWindow); - if (wm_hints != NULL) - { - if (!(wm_hints->flags & IconMaskHint)) - wm_hints->icon_mask = None; - /* - * 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-( - */ - if ((wm_hints->flags & IconPixmapHint) && (wm_hints->icon_pixmap)) - XpmCreateDataFromPixmap(display, &window_icon, wm_hints->icon_pixmap, - wm_hints->icon_mask, NULL); - XFree(wm_hints); - } - TQImage image; - if (!window_icon) - { - image = TDEGlobal::iconLoader()->loadIcon("question", TDEIcon::NoGroup, TDEIcon::SizeMedium); - } - else image = TQPixmap((const char **) window_icon).convertToImage(); - if (window_icon) XpmFree(window_icon); - mAppIcon = image.smoothScale(24, 24); // why? - setMinimumSize(mAppIcon.size()); - setMaximumSize(mAppIcon.size()); - - updateIcon(); -} - -/* - * Overload this to possibly do operations on the pixmap before it is set - */ -void TQTrayLabel::updateIcon() -{ - TRACE("%s", me()); - setPixmap(mCustomIcon.isEmpty() ? mAppIcon : mCustomIcon); - erase(); - TQPaintEvent pe(rect()); - paintEvent(&pe); -} - -/* - * Mouse activity on our label. RightClick = Menu. LeftClick = Toggle Map - */ -void TQTrayLabel::mouseReleaseEvent(TQMouseEvent * ev) -{ - emit clicked(ev->button(), ev->globalPos()); -} - -/* - * Track drag event - */ -void TQTrayLabel::dragEnterEvent(TQDragEnterEvent *ev) -{ - ev->accept(); - map(); -} - -/* - * Event dispatcher - */ -bool TQTrayLabel::x11EventFilter(XEvent *ev) -{ - XAnyEvent *event = (XAnyEvent *)ev; - - if (event->window == mSysTray) - { - if (event->type != DestroyNotify) - { - return false; // not interested in others - } - emit sysTrayDestroyed(); - mSysTray = None; - TRACE("%s SystemTray disappeared. Starting timer", me()); - mRealityMonitor.start(500); - return true; - } - else if (event->window == mDockedWindow) - { - if (event->type == DestroyNotify) - destroyEvent(); - else if (event->type == PropertyNotify) - propertyChangeEvent(((XPropertyEvent *)event)->atom); - else if (event->type == VisibilityNotify) - { - if (((XVisibilityEvent *) event)->state == VisibilityFullyObscured) - obscureEvent(); - } - else if (event->type == MapNotify) - { - mWithdrawn = false; - mapEvent(); - } - else if (event->type == UnmapNotify) - { - mWithdrawn = true; - unmapEvent(); - } - else if (event->type == FocusOut) - { - focusLostEvent(); - } - return true; // Dont process this again - } - - if (mDockedWindow != None || event->type != MapNotify) return FALSE; - - TRACE("%s Will analyze window 0x%x", me(), (int)((XMapEvent *)event)->window); - // Check if this window is the soulmate we are looking for - Display *display = TQPaintDevice::x11AppDisplay(); - Window w = XmuClientWindow(display, ((XMapEvent *) event)->window); - if (!isNormalWindow(display, w)) return FALSE; - if (!analyzeWindow(display, w, mPid, TQFileInfo(appName()).fileName().local8Bit())) - { - return false; - } - // All right. Lets dock this baby - setDockedWindow(w); - return true; -} - -void TQTrayLabel::minimizeEvent(void) -{ - TRACE("minimizeEvent"); - if (mDockWhenMinimized) withdraw(); -} - -void TQTrayLabel::destroyEvent(void) -{ - TRACE("%s destroyEvent", me()); - setDockedWindow(None); - if (!mPid) undock(); -} - -void TQTrayLabel::propertyChangeEvent(Atom property) -{ - Display *display = TQPaintDevice::x11AppDisplay(); - static Atom WM_NAME = XInternAtom(display, "WM_NAME", True); - static Atom WM_ICON = XInternAtom(display, "WM_ICON", True); - static Atom WM_STATE = XInternAtom(display, "WM_STATE", True); - static Atom _NET_WM_STATE = XInternAtom(display, "_NET_WM_STATE", True); - static Atom _NET_WM_DESKTOP = XInternAtom(display, "_NET_WM_DESKTOP", True); - - if (property == WM_NAME) - handleTitleChange(); - else if (property == WM_ICON) - handleIconChange(); - else if (property == _NET_WM_STATE) - ; // skipTaskbar(); - else if (property == _NET_WM_DESKTOP) - { - TRACE("_NET_WM_DESKTOP changed"); - getCardinalProperty(display, mDockedWindow, _NET_WM_DESKTOP, &mDesktop); - } - else if (property == WM_STATE) - { - Atom type = None; - int format; - unsigned long nitems, after; - unsigned char *data = NULL; - int r = XGetWindowProperty(display, mDockedWindow, WM_STATE, - 0, 1, False, AnyPropertyType, &type, - &format, &nitems, &after, &data); - - if ((r == Success) && data && (*(long *) data == IconicState)) - { - minimizeEvent(); - XFree(data); - } - } -} - -// Session Management -bool TQTrayLabel::saveState(TDEConfig *config) -{ - if (appName().isEmpty()) - { - 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("Withdraw", mWithdrawn); - return true; -} - -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)); - mWithdrawn = config->readBoolEntry("Withdraw", false); - - dock(); - scanClients(); // Grab window - if (mWithdrawn) - { - withdraw(); - } - else - { - map(); - } - return true; -} - -// End kicking butt - - -#include "qtraylabel.moc" |