From 8b702ef6224099a9ec4ebf486f245948a650362a Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Wed, 18 Oct 2006 19:53:54 +0000 Subject: [PATCH] - Based on Qt 4.2 - Brand new trayicon from Qt 4.2 - Updated Changelog - Updated configure file --- Changelog | 4 + configure | 16 +- qbittorrent.qc | 2 +- qcm/qt41.qcm | 16 -- qcm/qt42.qcm | 16 ++ src/GUI.cpp | 36 ++- src/GUI.h | 7 +- src/about_imp.h | 2 +- src/src.pro | 3 - src/trayicon/trayicon.cpp | 292 ---------------------- src/trayicon/trayicon.h | 98 -------- src/trayicon/trayicon.pri | 21 -- src/trayicon/trayicon_mac.cpp | 17 -- src/trayicon/trayicon_win.cpp | 243 ------------------ src/trayicon/trayicon_x11.cpp | 458 ---------------------------------- 15 files changed, 51 insertions(+), 1180 deletions(-) delete mode 100644 qcm/qt41.qcm create mode 100644 qcm/qt42.qcm delete mode 100644 src/trayicon/trayicon.cpp delete mode 100644 src/trayicon/trayicon.h delete mode 100644 src/trayicon/trayicon.pri delete mode 100644 src/trayicon/trayicon_mac.cpp delete mode 100644 src/trayicon/trayicon_win.cpp delete mode 100644 src/trayicon/trayicon_x11.cpp diff --git a/Changelog b/Changelog index a9814abbf..8d0bd334d 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,7 @@ +* Unknown - Christophe Dumez - v0.8.0 + - FEATURE: Based on Qt 4.2 + - FEATURE: Brand new trayicon from Qt 4.2 + * Mon Oct 16 2006 - Christophe Dumez - v0.7.1 - I18N: Updated French, Polish, Dutch, Swedish, Slovak translations - BUGFIX: Fixed Seeds/Leechers display in torrent properties diff --git a/configure b/configure index 2bdacfd21..0004ee822 100755 --- a/configure +++ b/configure @@ -229,21 +229,21 @@ fi gen_files() { cat >$1/modules.cpp <= 4.1 +name: Qt >= 4.2 -----END QCMOD----- */ -class qc_qt41 : public ConfObj +class qc_qt42 : public ConfObj { public: - qc_qt41(Conf *c) : ConfObj(c) {} - QString name() const { return "Qt >= 4.1"; } - QString shortname() const { return "qt41"; } + qc_qt42(Conf *c) : ConfObj(c) {} + QString name() const { return "Qt >= 4.2"; } + QString shortname() const { return "qt42"; } bool exec() { - return(QT_VERSION >= 0x040100); + return(QT_VERSION >= 0x040200); } }; #line 1 "libtorrent.qcm" @@ -362,7 +362,7 @@ public: EOT cat >$1/modules_new.cpp <required = true; o->disabled = false; o = new qc_libtorrent(conf); diff --git a/qbittorrent.qc b/qbittorrent.qc index 8d7214778..fa50072f1 100644 --- a/qbittorrent.qc +++ b/qbittorrent.qc @@ -2,7 +2,7 @@ qbittorrent qbittorrent.pro qcm - + diff --git a/qcm/qt41.qcm b/qcm/qt41.qcm deleted file mode 100644 index dc1a9d9f5..000000000 --- a/qcm/qt41.qcm +++ /dev/null @@ -1,16 +0,0 @@ -/* ------BEGIN QCMOD----- -name: Qt >= 4.1 ------END QCMOD----- -*/ -class qc_qt41 : public ConfObj -{ -public: - qc_qt41(Conf *c) : ConfObj(c) {} - QString name() const { return "Qt >= 4.1"; } - QString shortname() const { return "qt41"; } - bool exec() - { - return(QT_VERSION >= 0x040100); - } -}; diff --git a/qcm/qt42.qcm b/qcm/qt42.qcm new file mode 100644 index 000000000..77db1ab9e --- /dev/null +++ b/qcm/qt42.qcm @@ -0,0 +1,16 @@ +/* +-----BEGIN QCMOD----- +name: Qt >= 4.2 +-----END QCMOD----- +*/ +class qc_qt42 : public ConfObj +{ +public: + qc_qt42(Conf *c) : ConfObj(c) {} + QString name() const { return "Qt >= 4.2"; } + QString shortname() const { return "qt42"; } + bool exec() + { + return(QT_VERSION >= 0x040200); + } +}; diff --git a/src/GUI.cpp b/src/GUI.cpp index 362266d40..314fa50f0 100644 --- a/src/GUI.cpp +++ b/src/GUI.cpp @@ -42,7 +42,6 @@ #include "misc.h" #include "createtorrent_imp.h" #include "properties_imp.h" -#include "trayicon/trayicon.h" #include "DLListDelegate.h" #include "SearchListDelegate.h" #include "downloadThread.h" @@ -153,16 +152,13 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent){ connect(actionPreview_file, SIGNAL(triggered()), this, SLOT(previewFileSelection())); connect(infoBar, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayInfoBarMenu(const QPoint&))); // Create tray icon - myTrayIcon = new TrayIcon(this); + myTrayIcon = new QSystemTrayIcon(QIcon(":/Icons/qbittorrent22.png"), this); // Start download list refresher refresher = new QTimer(this); connect(refresher, SIGNAL(timeout()), this, SLOT(updateDlList())); refresher->start(2000); // Center window centerWindow(); - // Add tray icon and customize it - myTrayIcon->setWMDock(false); - myTrayIcon->setIcon(QPixmap::QPixmap(":/Icons/qbittorrent22.png")); // Tray icon Menu myTrayIconMenu = new QMenu(this); myTrayIconMenu->addAction(actionOpen); @@ -172,9 +168,9 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent){ myTrayIconMenu->addAction(actionPause_All); myTrayIconMenu->addSeparator(); myTrayIconMenu->addAction(actionExit); - myTrayIcon->setPopup(myTrayIconMenu); + myTrayIcon->setContextMenu(myTrayIconMenu); // End of Icon Menu - connect(myTrayIcon, SIGNAL(clicked(const QPoint &, int)), this, SLOT(toggleVisibility())); + connect(myTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleVisibility(QSystemTrayIcon::ActivationReason))); myTrayIcon->show(); // Use a tcp server to allow only one instance of qBittorrent tcpServer = new QTcpServer(this); @@ -680,20 +676,22 @@ void GUI::sortSearchListString(int index, Qt::SortOrder sortOrder){ } // Toggle Main window visibility -void GUI::toggleVisibility(){ - if(isHidden()){ - show(); - if(isMinimized()){ - if(isMaximized()){ - showMaximized(); - }else{ - showNormal(); +void GUI::toggleVisibility(QSystemTrayIcon::ActivationReason e){ + if(e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick){ + if(isHidden()){ + show(); + if(isMinimized()){ + if(isMaximized()){ + showMaximized(); + }else{ + showNormal(); + } } + raise(); + activateWindow(); + }else{ + hide(); } - raise(); - activateWindow(); - }else{ - hide(); } } diff --git a/src/GUI.h b/src/GUI.h index 1bb378239..c97692322 100644 --- a/src/GUI.h +++ b/src/GUI.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include @@ -45,7 +47,6 @@ class createtorrent; class QTimer; -class TrayIcon; class DLListDelegate; class SearchListDelegate; class downloadThread; @@ -74,7 +75,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{ options_imp *options; createtorrent *createWindow; QTimer *refresher; - TrayIcon *myTrayIcon; + QSystemTrayIcon *myTrayIcon; QMenu *myTrayIconMenu; about *aboutdlg; QStandardItemModel *DLListModel; @@ -102,7 +103,7 @@ class GUI : public QMainWindow, private Ui::MainWindow{ void dropEvent(QDropEvent *event); void dragEnterEvent(QDragEnterEvent *event); void centerWindow(); - void toggleVisibility(); + void toggleVisibility(QSystemTrayIcon::ActivationReason e); void showAbout(); void setInfoBar(const QString& info, const QString& color="black"); void updateDlList(); diff --git a/src/about_imp.h b/src/about_imp.h index 721f58dcb..80968c2d9 100644 --- a/src/about_imp.h +++ b/src/about_imp.h @@ -23,7 +23,7 @@ #define ABOUT_H #include "ui_about.h" -#define VERSION "v0.7.1svn" +#define VERSION "v0.8.0alpha1" class about : public QDialog, private Ui::AboutDlg{ Q_OBJECT diff --git a/src/src.pro b/src/src.pro index 40666f818..6d2747364 100644 --- a/src/src.pro +++ b/src/src.pro @@ -38,9 +38,6 @@ contains(DEBUG_MODE, 0){ CONFIG += release } -# Includes -include($$TRAYICON_CPP/trayicon.pri) - exists(../conf.pri) { include(../conf.pri) } diff --git a/src/trayicon/trayicon.cpp b/src/trayicon/trayicon.cpp deleted file mode 100644 index 27636f24d..000000000 --- a/src/trayicon/trayicon.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* - * trayicon.cpp - system-independent trayicon class (adapted from Qt example) - * Copyright (C) 2003 Justin Karneges - * Qt4 port: Stefan Gehn - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "trayicon.h" - -/*! - \class TrayIcon qtrayicon.h - \brief The TrayIcon class implements an entry in the system tray. -*/ - -/*! - Creates a TrayIcon object. \a parent and \a name are propagated - to the QObject constructor. The icon is initially invisible. - - \sa show -*/ -TrayIcon::TrayIcon( QObject *parent) -: QObject(parent), pop(0), d(0) -{ - v_isWMDock = FALSE; -} - -/*! - Creates a TrayIcon object displaying \a icon and \a tooltip, and opening - \a popup when clicked with the right mousebutton. \a parent and \a name are - propagated to the QObject constructor. The icon is initially invisible. - - \sa show -*/ -TrayIcon::TrayIcon( const QPixmap &icon, const QString &tooltip, QMenu *popup, QObject *parent ) -: QObject(parent), pop(popup), pm(icon), tip(tooltip), d(0) -{ - v_isWMDock = FALSE; - - if ( !pm.width() || !pm.height() ) - pm = QPixmap( 16, 16 ); -} - -/*! - Removes the icon from the system tray and frees all allocated resources. -*/ -TrayIcon::~TrayIcon() -{ - sysRemove(); -} - -/*! - Informs the trayicon that the notification owner has probably been changed; - and that it should attempt to register or re-register. -*/ -void TrayIcon::newTrayOwner() -{ - // detach ourself from any existing notification area. - hide(); - // show ourself on the new notification area - show(); -} - - -/*! - Sets the context menu to \a popup. The context menu will pop up when the - user clicks the system tray entry with the right mouse button. -*/ -void TrayIcon::setPopup( QMenu* popup ) -{ - pop = popup; -} - -/*! - Returns the current popup menu. - - \sa setPopup -*/ -QMenu* TrayIcon::popup() const -{ - return pop; -} - -/*! - \property TrayIcon::icon - \brief the system tray icon. -*/ -void TrayIcon::setIcon( const QPixmap &icon ) -{ - //if(!popup()) { - // tip = ""; - //} - - pm = icon; - sysUpdateIcon(); -} - -QPixmap TrayIcon::icon() const -{ - return pm; -} - -/*! - \property TrayIcon::toolTip - \brief the tooltip for the system tray entry - - On some systems, the tooltip's length is limited and will be truncated as necessary. -*/ -void TrayIcon::setToolTip( const QString &tooltip ) -{ - tip = tooltip; - sysUpdateToolTip(); -} - -QString TrayIcon::toolTip() const -{ - return tip; -} - -/*! - Shows the icon in the system tray. - - \sa hide -*/ -void TrayIcon::show() -{ - sysInstall(); -} - -/*! - Hides the system tray entry. -*/ -void TrayIcon::hide() -{ - sysRemove(); -} - -/*! - \reimp -*/ -bool TrayIcon::event( QEvent *e ) -{ - switch ( e->type() ) { - case QEvent::MouseMove: - mouseMoveEvent( (QMouseEvent*)e ); - break; - - case QEvent::MouseButtonPress: - mousePressEvent( (QMouseEvent*)e ); - break; - - case QEvent::MouseButtonRelease: - mouseReleaseEvent( (QMouseEvent*)e ); - break; - - case QEvent::MouseButtonDblClick: - mouseDoubleClickEvent( (QMouseEvent*)e ); - break; - default: - return QObject::event( e ); - } - - return TRUE; -} - -/*! - This event handler can be reimplemented in a subclass to receive - mouse move events for the system tray entry. - - \sa mousePressEvent(), mouseReleaseEvent(), mouseDoubleClickEvent(), QMouseEvent -*/ -void TrayIcon::mouseMoveEvent( QMouseEvent *e ) -{ - e->ignore(); -} - -/*! - This event handler can be reimplemented in a subclass to receive - mouse press events for the system tray entry. - - \sa mouseReleaseEvent(), mouseDoubleClickEvent(), - mouseMoveEvent(), QMouseEvent -*/ -void TrayIcon::mousePressEvent( QMouseEvent *e ) -{ -#ifndef Q_WS_WIN -// This is for X11, menus appear on mouse press -// I'm not sure whether Mac should be here or below.. Somebody check? - switch ( e->button() ) { - case Qt::RightButton: - if ( pop ) { - pop->popup( e->globalPos() ); - e->accept(); - } - break; - case Qt::LeftButton: - case Qt::MidButton: - emit clicked( e->globalPos(), e->button() ); - break; - default: - break; - } -#endif - e->ignore(); -} - -/*! - This event handler can be reimplemented in a subclass to receive - mouse release events for the system tray entry. - - The default implementations opens the context menu when the entry - has been clicked with the right mouse button. - - \sa setPopup(), mousePressEvent(), mouseDoubleClickEvent(), - mouseMoveEvent(), QMouseEvent -*/ -void TrayIcon::mouseReleaseEvent( QMouseEvent *e ) -{ -#ifdef Q_WS_WIN -// This is for Windows, where menus appear on mouse release - switch ( e->button() ) { - case Qt::RightButton: - if ( pop ) { - // Necessary to make keyboard focus - // and menu closing work on Windows. - pop->activateWindow(); - pop->popup( e->globalPos() ); - pop->activateWindow(); - e->accept(); - } - break; - case Qt::LeftButton: - case Qt::MidButton: - emit clicked( e->globalPos(), e->button() ); - break; - default: - break; - } -#endif - e->ignore(); -} - -/*! - This event handler can be reimplemented in a subclass to receive - mouse double click events for the system tray entry. - - Note that the system tray entry gets a mousePressEvent() and a - mouseReleaseEvent() before the mouseDoubleClickEvent(). - - \sa mousePressEvent(), mouseReleaseEvent(), - mouseMoveEvent(), QMouseEvent -*/ -void TrayIcon::mouseDoubleClickEvent( QMouseEvent *e ) -{ - if ( e->button() == Qt::LeftButton ) - emit doubleClicked( e->globalPos() ); - e->accept(); -} - -/*! - \fn void TrayIcon::clicked( const QPoint &p ) - - This signal is emitted when the user clicks the system tray icon - with the left mouse button, with \a p being the global mouse position - at that moment. -*/ - -/*! - \fn void TrayIcon::doubleClicked( const QPoint &p ) - - This signal is emitted when the user double clicks the system tray - icon with the left mouse button, with \a p being the global mouse position - at that moment. -*/ - -void TrayIcon::gotCloseEvent() -{ - closed(); -} diff --git a/src/trayicon/trayicon.h b/src/trayicon/trayicon.h deleted file mode 100644 index a51874a38..000000000 --- a/src/trayicon/trayicon.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * trayicon.h - system-independent trayicon class (adapted from Qt example) - * Copyright (C) 2003 Justin Karneges - * Qt4 port: Stefan Gehn - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef CS_TRAYICON_H -#define CS_TRAYICON_H - -#include -#include -#include -#include -#include - -class QPopupMenu; - -class TrayIcon : public QObject -{ - Q_OBJECT - - Q_PROPERTY( QString toolTip READ toolTip WRITE setToolTip ) - Q_PROPERTY( QPixmap icon READ icon WRITE setIcon ) - -public: - TrayIcon( QObject *parent = 0 ); - TrayIcon( const QPixmap &, const QString &, QMenu *popup = 0, QObject *parent = 0); - ~TrayIcon(); - - // use WindowMaker dock mode. ignored on non-X11 platforms - void setWMDock(bool use) { v_isWMDock = use; } - bool isWMDock() { return v_isWMDock; } - - // Set a popup menu to handle RMB - void setPopup( QMenu * ); - QMenu* popup() const; - - QPixmap icon() const; - QString toolTip() const; - - void gotCloseEvent(); - -public slots: - void setIcon( const QPixmap &icon ); - void setToolTip( const QString &tip ); - - void show(); - void hide(); - - void newTrayOwner(); - -signals: - void clicked( const QPoint&, int); - void doubleClicked( const QPoint& ); - void closed(); - -protected: - bool event( QEvent * ); - virtual void mouseMoveEvent( QMouseEvent *e ); - virtual void mousePressEvent( QMouseEvent *e ); - virtual void mouseReleaseEvent( QMouseEvent *e ); - virtual void mouseDoubleClickEvent( QMouseEvent *e ); - -private: - QMenu *pop; - QPixmap pm; - QString tip; - bool v_isWMDock; - - // system-dependant part -public: - class TrayIconPrivate; -private: - TrayIconPrivate *d; - void sysInstall(); - void sysRemove(); - void sysUpdateIcon(); - void sysUpdateToolTip(); - - friend class TrayIconPrivate; -}; - -#endif // CS_TRAYICON_H diff --git a/src/trayicon/trayicon.pri b/src/trayicon/trayicon.pri deleted file mode 100644 index ac2ec6f17..000000000 --- a/src/trayicon/trayicon.pri +++ /dev/null @@ -1,21 +0,0 @@ -HEADERS += $$TRAYICON_CPP/trayicon.h -SOURCES += $$TRAYICON_CPP/trayicon.cpp -QT += xml - -unix:!mac { - SOURCES += $$TRAYICON_CPP/trayicon_x11.cpp -} -win32: { - SOURCES += $$TRAYICON_CPP/trayicon_win.cpp - win32-g++: { - # Probably MinGW - LIBS += libgdi32 libuser32 libshell32 - } - else { - # Assume msvc compiler - LIBS += Gdi32.lib User32.lib shell32.lib - } -} -mac: { - SOURCES += $$TRAYICON_CPP/trayicon_mac.cpp -} diff --git a/src/trayicon/trayicon_mac.cpp b/src/trayicon/trayicon_mac.cpp deleted file mode 100644 index 23bf1640d..000000000 --- a/src/trayicon/trayicon_mac.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "trayicon.h" - -void TrayIcon::sysInstall() -{ -} - -void TrayIcon::sysRemove() -{ -} - -void TrayIcon::sysUpdateIcon() -{ -} - -void TrayIcon::sysUpdateToolTip() -{ -} diff --git a/src/trayicon/trayicon_win.cpp b/src/trayicon/trayicon_win.cpp deleted file mode 100644 index 04f26d90e..000000000 --- a/src/trayicon/trayicon_win.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* - * trayicon_win.cpp - Windows trayicon, adapted from Qt example - * Copyright (C) 2003 Justin Karneges - * Qt4 port: Stefan Gehn - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "trayicon.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static uint WM_TASKBARCREATED = 0; -#define WM_NOTIFYICON (WM_APP+101) - -typedef BOOL (WINAPI *PtrShell_NotifyIcon)(DWORD,PNOTIFYICONDATA); -static PtrShell_NotifyIcon ptrShell_NotifyIcon = 0; - -static void resolveLibs() -{ - QLibrary lib("shell32"); - //lib.setAutoUnload( FALSE ); - static bool triedResolve = FALSE; - if ( !ptrShell_NotifyIcon && !triedResolve ) - { - triedResolve = TRUE; - ptrShell_NotifyIcon = (PtrShell_NotifyIcon) lib.resolve( "Shell_NotifyIconW" ); - } -} - - -class TrayIcon::TrayIconPrivate : public QWidget -{ -public: - HICON hIcon; - TrayIcon *iconObject; - - TrayIconPrivate( TrayIcon *object ) : QWidget( 0 ), - hIcon( 0 ), iconObject( object ) - { - if ( !WM_TASKBARCREATED ) - WM_TASKBARCREATED = RegisterWindowMessage( TEXT("TaskbarCreated") ); - } - - ~TrayIconPrivate() - { - if ( hIcon ) - { - DestroyIcon( hIcon ); - hIcon = 0; - } - } - - // the unavoidable A/W versions. Don't forget to keep them in sync! - bool trayMessageA( DWORD msg ) - { - NOTIFYICONDATAA tnd; - ZeroMemory( &tnd, sizeof(NOTIFYICONDATAA) ); - tnd.cbSize = sizeof(NOTIFYICONDATAA); - tnd.hWnd = winId(); - tnd.uID = 1; - - if ( msg != NIM_DELETE ) - { - tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP; - tnd.uCallbackMessage = WM_NOTIFYICON; - tnd.hIcon = hIcon; - - if ( !iconObject->toolTip().isNull() ) - { - // Tip is limited to 63 + NULL; lstrcpyn appends a NULL terminator. - QString tip = iconObject->toolTip().left( 63 ) + QChar(); - lstrcpynA(tnd.szTip, (const char*)tip.toLocal8Bit(), qMin( tip.length()+1, 64 ) ); - } - } - return Shell_NotifyIconA(msg, &tnd); - } // trayMessageA - -#ifdef UNICODE - bool trayMessageW( DWORD msg ) - { - resolveLibs(); - if ( ! (ptrShell_NotifyIcon && QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) ) - return trayMessageA( msg ); - - NOTIFYICONDATAW tnd; - ZeroMemory( &tnd, sizeof(NOTIFYICONDATAW) ); - tnd.cbSize = sizeof(NOTIFYICONDATAW); - tnd.hWnd = winId(); - tnd.uID = 1; - - if ( msg != NIM_DELETE ) - { - tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP; - tnd.uCallbackMessage = WM_NOTIFYICON; - tnd.hIcon = hIcon; - - if ( !iconObject->toolTip().isNull() ) - { - // Tip is limited to 63 + NULL; lstrcpyn appends a NULL terminator. - QString tip = iconObject->toolTip().left( 63 ) + QChar(); - lstrcpynW(tnd.szTip, (TCHAR*)tip.unicode(), qMin( tip.length()+1, 64 ) ); - } - } - return ptrShell_NotifyIcon(msg, &tnd); - } // trayMessageW -#endif - - bool trayMessage( DWORD msg ) - { - QT_WA(return trayMessageW(msg);, return trayMessageA(msg);) - } - - bool iconDrawItem(LPDRAWITEMSTRUCT lpdi) - { - if (!hIcon) - return FALSE; - - DrawIconEx(lpdi->hDC, lpdi->rcItem.left, lpdi->rcItem.top, hIcon, 0, 0, 0, NULL, DI_NORMAL ); - return TRUE; - } - - bool winEvent( MSG * m, long * result ) - { - switch(m->message) - { - case WM_DRAWITEM: - return iconDrawItem( (LPDRAWITEMSTRUCT)m->lParam ); - case WM_NOTIFYICON: - { - QMouseEvent *e = 0; - QPoint gpos = QCursor::pos(); - switch (m->lParam) { - case WM_MOUSEMOVE: e = new QMouseEvent( QEvent::MouseMove, mapFromGlobal( gpos ), gpos, Qt::NoButton, Qt::NoButton, QApplication::keyboardModifiers() ); break; - case WM_LBUTTONDOWN: e = new QMouseEvent( QEvent::MouseButtonPress, mapFromGlobal( gpos ), gpos, Qt::LeftButton, Qt::LeftButton, QApplication::keyboardModifiers() ); break; - case WM_LBUTTONUP: e = new QMouseEvent( QEvent::MouseButtonRelease, mapFromGlobal( gpos ), gpos, Qt::LeftButton, Qt::LeftButton, QApplication::keyboardModifiers() ); break; - case WM_LBUTTONDBLCLK: e = new QMouseEvent( QEvent::MouseButtonDblClick, mapFromGlobal( gpos ), gpos, Qt::LeftButton, Qt::LeftButton, QApplication::keyboardModifiers() ); break; - case WM_RBUTTONDOWN: e = new QMouseEvent( QEvent::MouseButtonPress, mapFromGlobal( gpos ), gpos, Qt::RightButton, Qt::RightButton, QApplication::keyboardModifiers() ); break; - case WM_RBUTTONUP: e = new QMouseEvent( QEvent::MouseButtonRelease, mapFromGlobal( gpos ), gpos, Qt::RightButton, Qt::RightButton, QApplication::keyboardModifiers() ); break; - case WM_RBUTTONDBLCLK: e = new QMouseEvent( QEvent::MouseButtonDblClick, mapFromGlobal( gpos ), gpos, Qt::RightButton, Qt::RightButton, QApplication::keyboardModifiers() ); break; - case WM_MBUTTONDOWN: e = new QMouseEvent( QEvent::MouseButtonPress, mapFromGlobal( gpos ), gpos, Qt::MidButton, Qt::MidButton, QApplication::keyboardModifiers() ); break; - case WM_MBUTTONUP: e = new QMouseEvent( QEvent::MouseButtonRelease, mapFromGlobal( gpos ), gpos, Qt::MidButton, Qt::MidButton, QApplication::keyboardModifiers() ); break; - case WM_MBUTTONDBLCLK: e = new QMouseEvent( QEvent::MouseButtonDblClick, mapFromGlobal( gpos ), gpos, Qt::MidButton, Qt::MidButton, QApplication::keyboardModifiers() ); break; - case WM_CONTEXTMENU: e = new QMouseEvent( QEvent::MouseButtonRelease, mapFromGlobal( gpos ), gpos, Qt::RightButton, Qt::RightButton, QApplication::keyboardModifiers() ); break; - } - - if ( e ) - { - bool res = QApplication::sendEvent( iconObject, e ); - delete e; - return res; - } - } - break; - - default: - if ( m->message == WM_TASKBARCREATED ) - trayMessage( NIM_ADD ); - } - return QWidget::winEvent( m, result ); - } // winEvent -}; // class TrayIcon::TrayIconPrivate - - -static HICON createIcon( const QPixmap &pm ) -{ - ICONINFO iconInfo; - iconInfo.fIcon = true; - iconInfo.hbmMask = pm.createMaskFromColor(Qt::black).toWinHBITMAP(); - iconInfo.hbmColor = pm.toWinHBITMAP(QPixmap::PremultipliedAlpha); - - HICON icon = CreateIconIndirect( &iconInfo ); - - DeleteObject(iconInfo.hbmMask); - iconInfo.hbmMask = 0; - - DeleteObject(iconInfo.hbmColor); - iconInfo.hbmColor = 0; - - return icon; -} - -void TrayIcon::sysInstall() -{ - if ( !d ) - { - d = new TrayIconPrivate( this ); - d->hIcon = createIcon( pm ); - d->trayMessage( NIM_ADD ); - } -} - -void TrayIcon::sysRemove() -{ - if ( d ) - { - d->trayMessage( NIM_DELETE ); - delete d; - d = 0; - } -} - -void TrayIcon::sysUpdateIcon() -{ - if ( d ) - { - if ( d->hIcon ) - { - DestroyIcon( d->hIcon ); - d->hIcon = 0; - } - d->hIcon = createIcon( pm ); - d->trayMessage( NIM_MODIFY ); - } -} - -void TrayIcon::sysUpdateToolTip() -{ - if ( d ) - d->trayMessage( NIM_MODIFY ); -} diff --git a/src/trayicon/trayicon_x11.cpp b/src/trayicon/trayicon_x11.cpp deleted file mode 100644 index 97d50f8d9..000000000 --- a/src/trayicon/trayicon_x11.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/* - * trayicon_x11.cpp - X11 trayicon (for use with KDE and GNOME) - * Copyright (C) 2003 Justin Karneges - * GNOME2 Notification Area support: Tomasz Sterna - * Qt4 port: Stefan Gehn - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "trayicon.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -//---------------------------------------------------------------------------- -// common stuff -//---------------------------------------------------------------------------- - -// for Gnome2 Notification Area -static XErrorHandler old_handler = 0; -static int dock_xerror = 0; -extern "C" int dock_xerrhandler(Display* dpy, XErrorEvent* err) -{ - dock_xerror = err->error_code; - return old_handler(dpy, err); -} - -static void trap_errors() -{ - dock_xerror = 0; - old_handler = XSetErrorHandler(dock_xerrhandler); -} - -static bool untrap_errors() -{ - XSetErrorHandler(old_handler); - return (dock_xerror == 0); -} - -static bool send_message( - Display* dpy, /* display */ - Window w, /* sender (tray icon window) */ - long message, /* message opcode */ - long data1, /* message data 1 */ - long data2, /* message data 2 */ - long data3 /* message data 3 */ -) -{ - XEvent ev; - - memset(&ev, 0, sizeof(ev)); - ev.xclient.type = ClientMessage; - ev.xclient.window = w; - ev.xclient.message_type = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); - ev.xclient.format = 32; - ev.xclient.data.l[0] = CurrentTime; - ev.xclient.data.l[1] = message; - ev.xclient.data.l[2] = data1; - ev.xclient.data.l[3] = data2; - ev.xclient.data.l[4] = data3; - - trap_errors(); - XSendEvent(dpy, w, False, NoEventMask, &ev); - XSync(dpy, False); - return untrap_errors(); -} - -#define SYSTEM_TRAY_REQUEST_DOCK 0 -//#define SYSTEM_TRAY_BEGIN_MESSAGE 1 -//#define SYSTEM_TRAY_CANCEL_MESSAGE 2 - -//---------------------------------------------------------------------------- -// TrayIcon::TrayIconPrivate -//---------------------------------------------------------------------------- - -class TrayIcon::TrayIconPrivate : public QWidget -{ -public: - TrayIconPrivate(TrayIcon *object, int size); - ~TrayIconPrivate() { } - - virtual void initWM(WId icon); - virtual void setPixmap(const QPixmap &pm); - virtual void paintEvent(QPaintEvent *); - virtual void enterEvent(QEvent *); - virtual void mouseMoveEvent(QMouseEvent *e); - virtual void mousePressEvent(QMouseEvent *e); - virtual void mouseReleaseEvent(QMouseEvent *e); - virtual void mouseDoubleClickEvent(QMouseEvent *e); - virtual void closeEvent(QCloseEvent *e); - - void updateMask(); - -private: - TrayIcon *iconObject; - QPixmap pix; - int size; -}; - -TrayIcon::TrayIconPrivate::TrayIconPrivate(TrayIcon *object, int _size) - : QWidget(0/*, Qt::WRepaintNoErase*/) -{ - setObjectName(QCoreApplication::instance()->applicationName() + "dock"); - iconObject = object; - size = _size; - - setFocusPolicy(Qt::NoFocus); - -// setBackgroundMode(Qt::X11ParentRelative); - setAttribute(Qt::WA_NoSystemBackground); - setBackgroundRole(QPalette::NoRole); - - // This resize will not work as expected, - // we will get resized inside the tray later on. - resize(size, size); - setMinimumSize(size, size); - setMaximumSize(size, size); -} - -// This base stuff is required by both FreeDesktop specification and WindowMaker -void TrayIcon::TrayIconPrivate::initWM(WId icon) -{ - Display *dsp = QX11Info::display(); - WId leader = winId(); - char *resName = objectName().toLocal8Bit().data(); - char *resClass = QCoreApplication::instance()->applicationName().toLocal8Bit().data(); - - // set the class hint - XClassHint classhint; - classhint.res_name = resName; - classhint.res_class = resClass; - XSetClassHint(dsp, leader, &classhint); - - // set the Window Manager hints - XWMHints *hints; - hints = XGetWMHints(dsp, leader); // init hints - hints->flags = WindowGroupHint | IconWindowHint | StateHint; - hints->window_group = leader; - hints->initial_state = WithdrawnState; - hints->icon_window = icon; // in WM, this should be winId() of separate widget - hints->icon_x = 0; - hints->icon_y = 0; - XSetWMHints(dsp, leader, hints); // set the window hints for WM to use. - XFree(hints); -} - -void TrayIcon::TrayIconPrivate::setPixmap(const QPixmap &pm) -{ - QBitmap mask( QWidget::size() ); - - if( pm.size() != QWidget::size() ) { - // let's make a new mask - mask.fill(Qt::color0); - QPainter maskPainter(&mask); - - // draw the old mask in the center - maskPainter.drawPixmap((width() - pm.width() ) / 2, - (height() - pm.height()) / 2, pm.mask()); - - QPixmap newPix(QWidget::size()); - QPainter pixPainter( &newPix ); - - // draw the old pixmap in the center - pixPainter.drawPixmap((width() - pm.width())/2, - (height() - pm.height())/2, pm); - newPix.setMask(mask); - pix = newPix; - } else { - pix = pm; - mask = pm.mask(); - } - - setMask(mask); - setWindowIcon(pix); - repaint(); -} - -void TrayIcon::TrayIconPrivate::updateMask() -{ - if (!pix.isNull()) - { - QBitmap mask(width(), height()); - mask.clear(); - QPainter mp(&mask); - mp.drawPixmap((width() - pix.width())/2, (height() - pix.height())/2, pix.mask()); - mp.end(); - setMask(mask); - } -} - -void TrayIcon::TrayIconPrivate::paintEvent(QPaintEvent *) -{ - QPainter p(this); -// p.drawPixmap((width() - pix.width())/2, (height() - pix.height())/2, pix); - p.drawPixmap(0, 0, pix); -} - -void TrayIcon::TrayIconPrivate::enterEvent(QEvent *e) -{ - // Taken from KSystemTray.. -/*#if QT_VERSION < 0x030200 - if ( !qApp->focusWidget() ) - {*/ - XEvent ev; - memset(&ev, 0, sizeof(ev)); - ev.xfocus.display = QX11Info::display(); - ev.xfocus.type = FocusIn; - ev.xfocus.window = winId(); - ev.xfocus.mode = NotifyNormal; - ev.xfocus.detail = NotifyAncestor; - -// unsigned long oldTime = QX11Info::appTime(); -// QX11Info::setAppTime(1); - qApp->x11ProcessEvent( &ev ); -// QX11Info::setAppTime(oldTime); - - /*} -#endif*/ - - QWidget::enterEvent(e); -} - -void TrayIcon::TrayIconPrivate::mouseMoveEvent(QMouseEvent *e) -{ - QApplication::sendEvent(iconObject, e); -} - -void TrayIcon::TrayIconPrivate::mousePressEvent(QMouseEvent *e) -{ - QApplication::sendEvent(iconObject, e); -} - -void TrayIcon::TrayIconPrivate::mouseReleaseEvent(QMouseEvent *e) -{ - QApplication::sendEvent(iconObject, e); -} - -void TrayIcon::TrayIconPrivate::mouseDoubleClickEvent(QMouseEvent *e) -{ - QApplication::sendEvent(iconObject, e); -} - -void TrayIcon::TrayIconPrivate::closeEvent(QCloseEvent *e) -{ - iconObject->gotCloseEvent(); - e->accept(); -} - -//---------------------------------------------------------------------------- -// TrayIconFreeDesktop -//---------------------------------------------------------------------------- - -class TrayIconFreeDesktop : public TrayIcon::TrayIconPrivate -{ -public: - TrayIconFreeDesktop(TrayIcon *object, const QPixmap &pm); -protected: - virtual bool x11Event(XEvent*); -}; - -TrayIconFreeDesktop::TrayIconFreeDesktop(TrayIcon *object, const QPixmap &pm) - : TrayIconPrivate(object, 22) -{ - initWM( winId() ); - - // initialize NetWM - Display *dsp = QX11Info::display(); - - // dock the widget (adapted from SIM-ICQ) - Screen *screen = XDefaultScreenOfDisplay(dsp); // get the screen - int screen_id = XScreenNumberOfScreen(screen); // and it's number - - // tell X that we want to see ClientMessage and Deleted events, which - // are picked up by QApplication::x11EventFilter - Window root_window = QApplication::desktop()->winId(); - XWindowAttributes attr; - - XGetWindowAttributes(dsp, root_window, &attr); - XSelectInput(dsp, root_window, attr.your_event_mask | StructureNotifyMask); - - char buf[32]; - snprintf(buf, sizeof(buf), "_NET_SYSTEM_TRAY_S%d", screen_id); - Atom selection_atom = XInternAtom(dsp, buf, false); - XGrabServer(dsp); - Window manager_window = XGetSelectionOwner(dsp, selection_atom); - if ( manager_window != None ) - XSelectInput(dsp, manager_window, StructureNotifyMask); - XUngrabServer(dsp); - XFlush(dsp); - - if ( manager_window != None ) - { - send_message(dsp, manager_window, SYSTEM_TRAY_REQUEST_DOCK, winId(), 0, 0); - } - else - { - object->hide(); - return; - } - - // some KDE mumbo-jumbo... why is it there? anybody? - Atom kwm_dockwindow_atom = XInternAtom(dsp, "KWM_DOCKWINDOW", false); - Atom kde_net_system_tray_window_for_atom = XInternAtom(dsp, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", false); - - long data = 0; - XChangeProperty(dsp, winId(), kwm_dockwindow_atom, kwm_dockwindow_atom, 32, PropModeReplace, (uchar*)&data, 1); - XChangeProperty(dsp, winId(), kde_net_system_tray_window_for_atom, XA_WINDOW, 32, PropModeReplace, (uchar*)&data, 1); - - setPixmap(pm); -} - -bool TrayIconFreeDesktop::x11Event(XEvent *ev) -{ - switch(ev->type) - { - case ReparentNotify: -// setUpdatesEnabled(false); - show(); -// updateMask(); -// setUpdatesEnabled(true); - } - return false; -} - -//---------------------------------------------------------------------------- -// TrayIconWindowMaker -//---------------------------------------------------------------------------- - -class TrayIconWharf : public TrayIcon::TrayIconPrivate -{ -public: - TrayIconWharf(TrayIcon *object, const QPixmap &pm) - : TrayIconPrivate(object, 44) - { - char *resName = QString(objectName() + "-wharf").toLocal8Bit().data(); - char *resClass = QCoreApplication::instance()->applicationName().toLocal8Bit().data(); - - // set the class hint - XClassHint classhint; - classhint.res_name = resName; - classhint.res_class = resClass; - XSetClassHint(QX11Info::display(), winId(), &classhint); - - setPixmap(pm); - } - - void setPixmap(const QPixmap &_pm){ - QPixmap pm; - QImage i = _pm.toImage(); - i = i.scaled(i.width() * 2, i.height() * 2); - pm.fromImage(i); - - TrayIconPrivate::setPixmap(pm); - - // thanks to Robert Spier for this: - // for some reason the repaint() isn't being honored, or isn't for - // the icon. So force one on the widget behind the icon -// erase(); - QPaintEvent pe( rect() ); - paintEvent(&pe); - } -}; - -class TrayIconWindowMaker : public TrayIcon::TrayIconPrivate -{ -public: - TrayIconWindowMaker(TrayIcon *object, const QPixmap &pm); - ~TrayIconWindowMaker(); - - void setPixmap(const QPixmap &pm); - -private: - TrayIconWharf *wharf; -}; - -TrayIconWindowMaker::TrayIconWindowMaker(TrayIcon *object, const QPixmap &pm) - : TrayIconPrivate(object, 32) -{ - wharf = new TrayIconWharf(object, pm); - initWM( wharf->winId() ); -} - -TrayIconWindowMaker::~TrayIconWindowMaker() -{ - delete wharf; -} - -void TrayIconWindowMaker::setPixmap(const QPixmap &pm) -{ - wharf->setPixmap(pm); -} - -//---------------------------------------------------------------------------- -// TrayIcon -//---------------------------------------------------------------------------- - -void TrayIcon::sysInstall() -{ - if ( d ) - return; - if ( v_isWMDock ) - d = (TrayIconPrivate *)(new TrayIconWindowMaker(this, pm)); - else - d = (TrayIconPrivate *)(new TrayIconFreeDesktop(this, pm)); - - sysUpdateToolTip(); - - if ( v_isWMDock ) - d->show(); -} - -void TrayIcon::sysRemove() -{ - if ( !d ) - return; - delete d; - d = 0; -} - -void TrayIcon::sysUpdateIcon() -{ - if ( !d ) - return; - QPixmap pix = pm; - d->setPixmap(pix); -} - -void TrayIcon::sysUpdateToolTip() -{ - if ( !d ) - return; - if ( tip.isEmpty() ) - d->setToolTip(QString::null); - else - d->setToolTip(tip); -}