mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 02:42:50 +00:00
ksystraycmd: drop it and use the new tray argument of KApplication
see the following commit in kdelibs repo: 4b632fcae67da3b95e69e954fa2e581a42f4c53c currently enabled only for a few applications until more tests are done Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
69f7efcce1
commit
3f85de5864
11 changed files with 19 additions and 659 deletions
|
@ -293,7 +293,6 @@ endif(Q_WS_X11 AND X11_Xinput_FOUND)
|
||||||
|
|
||||||
add_subdirectory(kcminit)
|
add_subdirectory(kcminit)
|
||||||
add_subdirectory(khotkeys)
|
add_subdirectory(khotkeys)
|
||||||
add_subdirectory(ksystraycmd)
|
|
||||||
|
|
||||||
if (LightDM_FOUND)
|
if (LightDM_FOUND)
|
||||||
add_subdirectory(kgreeter)
|
add_subdirectory(kgreeter)
|
||||||
|
|
|
@ -188,3 +188,4 @@ MimeType=inode/directory;
|
||||||
InitialPreference=10
|
InitialPreference=10
|
||||||
StartupNotify=true
|
StartupNotify=true
|
||||||
X-KDE-MediaPlayer=informationpanel
|
X-KDE-MediaPlayer=informationpanel
|
||||||
|
X-KDE-SysTray=true
|
||||||
|
|
|
@ -121,6 +121,7 @@ MimeType=text/plain;
|
||||||
Exec=kate --icon '%i' --caption '%c' -b %U
|
Exec=kate --icon '%i' --caption '%c' -b %U
|
||||||
StartupNotify=true
|
StartupNotify=true
|
||||||
X-KDE-HasTempFileOption=true
|
X-KDE-HasTempFileOption=true
|
||||||
|
X-KDE-SysTray=true
|
||||||
Icon=kate
|
Icon=kate
|
||||||
X-DocPath=kate/index.html
|
X-DocPath=kate/index.html
|
||||||
Type=Application
|
Type=Application
|
||||||
|
|
|
@ -97,3 +97,4 @@ Name[zh_TW]=尋找檔案/資料夾
|
||||||
StartupNotify=true
|
StartupNotify=true
|
||||||
OnlyShowIn=KDE;
|
OnlyShowIn=KDE;
|
||||||
Categories=Qt;KDE;Core;
|
Categories=Qt;KDE;Core;
|
||||||
|
X-KDE-SysTray=true
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <KDesktopFile>
|
#include <KDesktopFile>
|
||||||
#include <KUrlRequester>
|
#include <KUrlRequester>
|
||||||
#include <KShell>
|
#include <KShell>
|
||||||
|
#include <KDebug>
|
||||||
|
|
||||||
#include "khotkeys.h"
|
#include "khotkeys.h"
|
||||||
|
|
||||||
|
@ -269,7 +270,7 @@ void BasicTab::enableWidgets(bool isDF, bool isDeleted)
|
||||||
_iconButton->setEnabled(!isDeleted);
|
_iconButton->setEnabled(!isDeleted);
|
||||||
_execEdit->setEnabled(isDF && !isDeleted);
|
_execEdit->setEnabled(isDF && !isDeleted);
|
||||||
_launchCB->setEnabled(isDF && !isDeleted);
|
_launchCB->setEnabled(isDF && !isDeleted);
|
||||||
_systrayCB->setEnabled(isDF && !isDeleted);
|
// _systrayCB->setEnabled(isDF && !isDeleted);
|
||||||
_onlyShowInKdeCB->setEnabled(isDF && !isDeleted);
|
_onlyShowInKdeCB->setEnabled(isDF && !isDeleted);
|
||||||
_hiddenEntryCB->setEnabled(isDF && !isDeleted);
|
_hiddenEntryCB->setEnabled(isDF && !isDeleted);
|
||||||
_nameLabel->setEnabled(!isDeleted);
|
_nameLabel->setEnabled(!isDeleted);
|
||||||
|
@ -369,10 +370,11 @@ void BasicTab::setEntryInfo(MenuEntryInfo *entryInfo)
|
||||||
else
|
else
|
||||||
_keyEdit->clearKeySequence();
|
_keyEdit->clearKeySequence();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString temp = df->desktopGroup().readEntry("Exec");
|
QString temp = df->desktopGroup().readEntry("Exec");
|
||||||
if (temp.startsWith(QLatin1String("ksystraycmd ")))
|
if (temp.endsWith(QLatin1String(" -tray")))
|
||||||
{
|
{
|
||||||
_execEdit->lineEdit()->setText(temp.right(temp.length()-12));
|
_execEdit->lineEdit()->setText(temp.left(temp.length()-6));
|
||||||
_systrayCB->setChecked(true);
|
_systrayCB->setChecked(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -380,6 +382,7 @@ void BasicTab::setEntryInfo(MenuEntryInfo *entryInfo)
|
||||||
_execEdit->lineEdit()->setText(temp);
|
_execEdit->lineEdit()->setText(temp);
|
||||||
_systrayCB->setChecked(false);
|
_systrayCB->setChecked(false);
|
||||||
}
|
}
|
||||||
|
_systrayCB->setEnabled(df->desktopGroup().readEntry("X-KDE-SysTray", false));
|
||||||
|
|
||||||
_pathEdit->lineEdit()->setText(df->readPath());
|
_pathEdit->lineEdit()->setText(df->readPath());
|
||||||
_termOptEdit->setText(df->desktopGroup().readEntry("TerminalOptions"));
|
_termOptEdit->setText(df->desktopGroup().readEntry("TerminalOptions"));
|
||||||
|
@ -387,7 +390,8 @@ void BasicTab::setEntryInfo(MenuEntryInfo *entryInfo)
|
||||||
|
|
||||||
_launchCB->setChecked(df->desktopGroup().readEntry("StartupNotify", false));
|
_launchCB->setChecked(df->desktopGroup().readEntry("StartupNotify", false));
|
||||||
|
|
||||||
_onlyShowInKdeCB->setChecked( df->desktopGroup().readXdgListEntry("OnlyShowIn").contains( "KDE" ) ); // or maybe enable only if it contains nothing but KDE?
|
// or maybe enable only if it contains nothing but KDE?
|
||||||
|
_onlyShowInKdeCB->setChecked( df->desktopGroup().readXdgListEntry("OnlyShowIn").contains("KDE"));
|
||||||
|
|
||||||
if ( df->desktopGroup().hasKey("NoDisplay"))
|
if ( df->desktopGroup().hasKey("NoDisplay"))
|
||||||
_hiddenEntryCB->setChecked(df->desktopGroup().readEntry("NoDisplay", true));
|
_hiddenEntryCB->setChecked(df->desktopGroup().readEntry("NoDisplay", true));
|
||||||
|
@ -417,8 +421,8 @@ void BasicTab::apply()
|
||||||
KDesktopFile *df = _menuEntryInfo->desktopFile();
|
KDesktopFile *df = _menuEntryInfo->desktopFile();
|
||||||
KConfigGroup dg = df->desktopGroup();
|
KConfigGroup dg = df->desktopGroup();
|
||||||
dg.writeEntry("Comment", _commentEdit->text());
|
dg.writeEntry("Comment", _commentEdit->text());
|
||||||
if (_systrayCB->isChecked())
|
if (_systrayCB->isEnabled() && _systrayCB->isChecked())
|
||||||
dg.writeEntry("Exec", _execEdit->lineEdit()->text().prepend("ksystraycmd "));
|
dg.writeEntry("Exec", _execEdit->lineEdit()->text().append(" -tray"));
|
||||||
else
|
else
|
||||||
dg.writeEntry("Exec", _execEdit->lineEdit()->text());
|
dg.writeEntry("Exec", _execEdit->lineEdit()->text());
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
set(ksystraycmd_SRCS ksystraycmd.cpp main.cpp )
|
|
||||||
|
|
||||||
add_executable(ksystraycmd ${ksystraycmd_SRCS})
|
|
||||||
target_link_libraries(ksystraycmd
|
|
||||||
KDE4::kdeui
|
|
||||||
${X11_X11_LIB}
|
|
||||||
)
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS ksystraycmd
|
|
||||||
DESTINATION ${KDE4_BIN_INSTALL_DIR}
|
|
||||||
)
|
|
|
@ -1,2 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
$XGETTEXT *.cpp -o $podir/ksystraycmd.pot
|
|
|
@ -1,29 +0,0 @@
|
||||||
README for KSysTrayCmd
|
|
||||||
======================
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
============
|
|
||||||
|
|
||||||
KSysTrayCmd is a utility that allows you to run any application you
|
|
||||||
like in the system tray, not just those designed to use it.
|
|
||||||
|
|
||||||
Examples
|
|
||||||
========
|
|
||||||
|
|
||||||
ksystraycmd --window 'kmail' kmail
|
|
||||||
|
|
||||||
ksystraycmd --startonshow --icon logfile --tooltip 'X Log' --hidden --window 'X Log' \
|
|
||||||
konsole --icon logfile --caption 'X Log' -e 'less -M ~/.xsession-errors'
|
|
||||||
|
|
||||||
More Information
|
|
||||||
================
|
|
||||||
|
|
||||||
I'm currently writing an article for the dot which will describe the
|
|
||||||
usage of both kstart and ksystraycmd in more detail, the text of the
|
|
||||||
article will be used to improve this document.
|
|
||||||
|
|
||||||
Richard Moore
|
|
||||||
rich@kde.org
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,379 +0,0 @@
|
||||||
|
|
||||||
#include <QTextStream>
|
|
||||||
#include <QImage>
|
|
||||||
#include <QRegExp>
|
|
||||||
#include <QtGui/qevent.h>
|
|
||||||
|
|
||||||
#include <kdebug.h>
|
|
||||||
#include <kapplication.h>
|
|
||||||
#include <kglobal.h>
|
|
||||||
#include <kicon.h>
|
|
||||||
#include <klocale.h>
|
|
||||||
#include <kmenu.h>
|
|
||||||
#include <kprocess.h>
|
|
||||||
#include <kwindowsystem.h>
|
|
||||||
#include <kconfig.h>
|
|
||||||
#include <ksystemtrayicon.h>
|
|
||||||
#include <kconfiggroup.h>
|
|
||||||
#include <kaboutdata.h>
|
|
||||||
|
|
||||||
#include <netwm.h>
|
|
||||||
|
|
||||||
#include "ksystraycmd.h"
|
|
||||||
#include "moc_ksystraycmd.cpp"
|
|
||||||
#include <QtGui/qx11info_x11.h>
|
|
||||||
|
|
||||||
|
|
||||||
KSysTrayCmd::KSysTrayCmd()
|
|
||||||
: KSystemTrayIcon( static_cast<QWidget*>(0) ),
|
|
||||||
isVisible(true), lazyStart( false ), noquit( false ),
|
|
||||||
quitOnHide( false ), onTop(false), ownIcon(false),
|
|
||||||
waitingForWindow( false ),
|
|
||||||
win(0), client(0), top(0), left(0)
|
|
||||||
{
|
|
||||||
connect( KWindowSystem::self(), SIGNAL(windowAdded(WId)), this, SLOT(windowAdded(WId)) );
|
|
||||||
|
|
||||||
menu = new KMenu();
|
|
||||||
setContextMenu(menu);
|
|
||||||
connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), SLOT(mousePressEvent(QSystemTrayIcon::ActivationReason)));
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
KSysTrayCmd::~KSysTrayCmd()
|
|
||||||
{
|
|
||||||
delete menu;
|
|
||||||
if( client )
|
|
||||||
{
|
|
||||||
if( client->state() == QProcess::Running )
|
|
||||||
{
|
|
||||||
client->terminate();
|
|
||||||
client->kill();
|
|
||||||
client->waitForFinished( 5000 );
|
|
||||||
}
|
|
||||||
delete client;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Main entry point to the class
|
|
||||||
//
|
|
||||||
|
|
||||||
bool KSysTrayCmd::start()
|
|
||||||
{
|
|
||||||
// If we have no command we must catching an existing window
|
|
||||||
if ( command.isEmpty() ) {
|
|
||||||
if ( win ) {
|
|
||||||
setTargetWindow( win );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
waitingForWindow = true;
|
|
||||||
checkExistingWindows();
|
|
||||||
if ( win ) {
|
|
||||||
// Window always on top
|
|
||||||
if (onTop) {
|
|
||||||
KWindowSystem::setState(win, NET::KeepAbove);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
errStr = i18n( "No window matching pattern '%1' and no command specified.\n" ,
|
|
||||||
window );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the command and watch for its window
|
|
||||||
if ( !startClient() ) {
|
|
||||||
errStr = i18n( "Cannot start client." );
|
|
||||||
clientExited();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Window related functions.
|
|
||||||
//
|
|
||||||
|
|
||||||
void KSysTrayCmd::showWindow()
|
|
||||||
{
|
|
||||||
isVisible = true;
|
|
||||||
if ( !win )
|
|
||||||
return;
|
|
||||||
XMapWindow( QX11Info::display(), win );
|
|
||||||
// We move the window to the memorized position
|
|
||||||
XMoveWindow( QX11Info::display(), win, left, top);
|
|
||||||
|
|
||||||
// Window always on top
|
|
||||||
if (onTop)
|
|
||||||
{
|
|
||||||
KWindowSystem::setState(win, NET::KeepAbove);
|
|
||||||
}
|
|
||||||
|
|
||||||
KWindowSystem::activateWindow( win );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSysTrayCmd::hideWindow()
|
|
||||||
{
|
|
||||||
isVisible = false;
|
|
||||||
if ( !win )
|
|
||||||
return;
|
|
||||||
//We memorize the position of the window
|
|
||||||
left = KWindowSystem::windowInfo(win, NET::WMFrameExtents).frameGeometry().left();
|
|
||||||
top=KWindowSystem::windowInfo(win, NET::WMFrameExtents).frameGeometry().top();
|
|
||||||
|
|
||||||
XUnmapWindow( QX11Info::display(), win );
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSysTrayCmd::setTargetWindow( WId w )
|
|
||||||
{
|
|
||||||
disconnect( KWindowSystem::self(), SIGNAL(windowAdded(WId)), this, SLOT(windowAdded(WId)) );
|
|
||||||
connect( KWindowSystem::self(), SIGNAL(windowChanged(WId)), SLOT(windowChanged(WId)) );
|
|
||||||
win = w;
|
|
||||||
// KWindowSystem::setSystemTrayWindowFor( winId(), win );
|
|
||||||
refresh();
|
|
||||||
show();
|
|
||||||
|
|
||||||
if ( isVisible )
|
|
||||||
KWindowSystem::activateWindow( win );
|
|
||||||
else
|
|
||||||
hideWindow();
|
|
||||||
|
|
||||||
// Always on top ?
|
|
||||||
if (onTop)
|
|
||||||
{
|
|
||||||
KWindowSystem::setState(win, NET::KeepAbove);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Refresh the tray icon
|
|
||||||
//
|
|
||||||
|
|
||||||
void KSysTrayCmd::refresh()
|
|
||||||
{
|
|
||||||
// KWindowSystem::setSystemTrayWindowFor( winId(), win ? win : winId() );
|
|
||||||
|
|
||||||
if ( win ) {
|
|
||||||
if (ownIcon)
|
|
||||||
{
|
|
||||||
setIcon( KApplication::windowIcon() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setIcon( KWindowSystem::icon( win, 22, 22, true ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( tooltip.isEmpty() )
|
|
||||||
this->setToolTip( KWindowSystem::windowInfo( win, NET::WMName ).name() );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( !tooltip.isEmpty() )
|
|
||||||
this->setToolTip( tooltip );
|
|
||||||
else if ( !command.isEmpty() )
|
|
||||||
this->setToolTip( command );
|
|
||||||
else
|
|
||||||
this->setToolTip( window );
|
|
||||||
|
|
||||||
setIcon( KApplication::windowIcon() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Client related functions.
|
|
||||||
//
|
|
||||||
|
|
||||||
bool KSysTrayCmd::startClient()
|
|
||||||
{
|
|
||||||
kDebug() << "startClient()";
|
|
||||||
client = new KProcess();
|
|
||||||
client->setShellCommand( command );
|
|
||||||
//connect( KWindowSystem::self(), SIGNAL(windowAdded(WId)), this, SLOT(windowAdded(WId)) );
|
|
||||||
waitingForWindow = true;
|
|
||||||
connect( client, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(clientExited()) );
|
|
||||||
|
|
||||||
client->start();
|
|
||||||
return client->waitForStarted( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSysTrayCmd::clientExited()
|
|
||||||
{
|
|
||||||
delete client;
|
|
||||||
client = 0;
|
|
||||||
win = 0;
|
|
||||||
waitingForWindow = false;
|
|
||||||
|
|
||||||
if ( lazyStart && noquit )
|
|
||||||
refresh();
|
|
||||||
else
|
|
||||||
qApp->quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSysTrayCmd::quitClient()
|
|
||||||
{
|
|
||||||
if ( win ) {
|
|
||||||
// Before sending the close request we have to show the window
|
|
||||||
XMapWindow( QX11Info::display(), win );
|
|
||||||
NETRootInfo ri( QX11Info::display(), NET::CloseWindow );
|
|
||||||
ri.closeWindowRequest( win );
|
|
||||||
win=0;
|
|
||||||
noquit = false;
|
|
||||||
|
|
||||||
// We didn't give command, so we didn't open an application.
|
|
||||||
// That's why when the application is closed we aren't informed.
|
|
||||||
// So we quit now.
|
|
||||||
|
|
||||||
if ( command.isEmpty() ) {
|
|
||||||
qApp->quit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
qApp->quit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSysTrayCmd::quit()
|
|
||||||
{
|
|
||||||
if ( !isVisible ) {
|
|
||||||
showWindow();
|
|
||||||
}
|
|
||||||
qApp->quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSysTrayCmd::execContextMenu( const QPoint &pos )
|
|
||||||
{
|
|
||||||
menu->clear();
|
|
||||||
menu->addTitle( icon(), i18n( "KSysTrayCmd" ) );
|
|
||||||
QAction * hideShowId = menu->addAction( isVisible ? i18n( "&Hide" ) : i18n( "&Restore" ) );
|
|
||||||
QAction * undockId = menu->addAction( KIcon("dialog-close"), i18n( "&Undock" ) );
|
|
||||||
QAction * quitId = menu->addAction( KIcon("application-exit"), i18n( "&Quit" ) );
|
|
||||||
|
|
||||||
QAction * cmd = menu->exec( pos );
|
|
||||||
|
|
||||||
if ( cmd == quitId )
|
|
||||||
quitClient();
|
|
||||||
else if ( cmd == undockId )
|
|
||||||
quit();
|
|
||||||
else if ( cmd == hideShowId )
|
|
||||||
{
|
|
||||||
if ( lazyStart && ( !hasRunningClient() ) )
|
|
||||||
{
|
|
||||||
start();
|
|
||||||
isVisible=true;
|
|
||||||
}
|
|
||||||
else if ( quitOnHide && ( hasRunningClient() ) && isVisible )
|
|
||||||
{
|
|
||||||
NETRootInfo ri( QX11Info::display(), NET::CloseWindow );
|
|
||||||
ri.closeWindowRequest( win );
|
|
||||||
isVisible=false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
toggleWindow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSysTrayCmd::checkExistingWindows()
|
|
||||||
{
|
|
||||||
kDebug() << "checkExistingWindows()";
|
|
||||||
QList<WId>::ConstIterator it;
|
|
||||||
for ( it = KWindowSystem::windows().begin(); it != KWindowSystem::windows().end(); ++it ) {
|
|
||||||
windowAdded( *it );
|
|
||||||
if ( win )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const int SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
|
|
||||||
| NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::UtilityMask | NET::SplashMask;
|
|
||||||
|
|
||||||
void KSysTrayCmd::windowAdded(WId w)
|
|
||||||
{
|
|
||||||
if ( !waitingForWindow )
|
|
||||||
return;
|
|
||||||
|
|
||||||
KWindowInfo info = KWindowSystem::windowInfo( w, NET::WMWindowType | NET::WMName );
|
|
||||||
kDebug() << "windowAdded, id" << w << "pattern is " << window << " window is " << info.name();
|
|
||||||
|
|
||||||
// always ignore these window types
|
|
||||||
if( info.windowType( SUPPORTED_WINDOW_TYPES_MASK ) == NET::Toolbar
|
|
||||||
|| info.windowType( SUPPORTED_WINDOW_TYPES_MASK ) == NET::Desktop )
|
|
||||||
return;
|
|
||||||
|
|
||||||
// If we're grabbing the first window we see
|
|
||||||
if( window.isEmpty() ) {
|
|
||||||
// accept only "normal" windows
|
|
||||||
if( info.windowType( SUPPORTED_WINDOW_TYPES_MASK ) != NET::Unknown
|
|
||||||
&& info.windowType( SUPPORTED_WINDOW_TYPES_MASK ) != NET::Normal
|
|
||||||
&& info.windowType( SUPPORTED_WINDOW_TYPES_MASK ) != NET::Dialog )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( QRegExp( window ).indexIn( info.name() ) == -1 ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
kDebug() << "windowAdded, setting target " << (int) w;
|
|
||||||
setTargetWindow( w );
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSysTrayCmd::windowChanged( WId w )
|
|
||||||
{
|
|
||||||
if ( w != win )
|
|
||||||
return;
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Tray icon event handlers
|
|
||||||
//
|
|
||||||
|
|
||||||
void KSysTrayCmd::mousePressEvent( QSystemTrayIcon::ActivationReason reason )
|
|
||||||
{
|
|
||||||
if ( reason == QSystemTrayIcon::Context )
|
|
||||||
execContextMenu( QCursor::pos() );
|
|
||||||
else if ( lazyStart && ( !hasRunningClient() ) )
|
|
||||||
{
|
|
||||||
start();
|
|
||||||
isVisible=true;
|
|
||||||
}
|
|
||||||
else if ( quitOnHide && ( hasRunningClient() ) && isVisible )
|
|
||||||
{
|
|
||||||
NETRootInfo ri( QX11Info::display(), NET::CloseWindow );
|
|
||||||
ri.closeWindowRequest( win );
|
|
||||||
isVisible=false;
|
|
||||||
}
|
|
||||||
else if ( reason == QSystemTrayIcon::Trigger )
|
|
||||||
toggleWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
WId KSysTrayCmd::findRealWindow( WId w, int depth )
|
|
||||||
{
|
|
||||||
if( depth > 5 )
|
|
||||||
return None;
|
|
||||||
static Atom wm_state = XInternAtom( QX11Info::display(), "WM_STATE", False );
|
|
||||||
Atom type;
|
|
||||||
int format;
|
|
||||||
unsigned long nitems, after;
|
|
||||||
unsigned char* prop;
|
|
||||||
if( XGetWindowProperty( QX11Info::display(), w, wm_state, 0, 0, False, AnyPropertyType,
|
|
||||||
&type, &format, &nitems, &after, &prop ) == Success ) {
|
|
||||||
if( prop != NULL )
|
|
||||||
XFree( prop );
|
|
||||||
if( type != None )
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
Window root, parent;
|
|
||||||
Window* children;
|
|
||||||
unsigned int nchildren;
|
|
||||||
Window ret = None;
|
|
||||||
if( XQueryTree( QX11Info::display(), w, &root, &parent, &children, &nchildren ) != 0 ) {
|
|
||||||
for( unsigned int i = 0;
|
|
||||||
i < nchildren && ret == None;
|
|
||||||
++i )
|
|
||||||
ret = findRealWindow( children[ i ], depth + 1 );
|
|
||||||
if( children != NULL )
|
|
||||||
XFree( children );
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -1,87 +0,0 @@
|
||||||
// -*- c++ -*-
|
|
||||||
|
|
||||||
#ifndef KSYSTRAYCMD_H
|
|
||||||
#define KSYSTRAYCMD_H
|
|
||||||
|
|
||||||
#include <KSystemTrayIcon>
|
|
||||||
|
|
||||||
class KProcess;
|
|
||||||
class KMenu;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides a system tray icon for a normal window.
|
|
||||||
*
|
|
||||||
* @author Richard Moore, rich@kde.org
|
|
||||||
*/
|
|
||||||
class KSysTrayCmd : public KSystemTrayIcon
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
KSysTrayCmd();
|
|
||||||
~KSysTrayCmd();
|
|
||||||
|
|
||||||
void setWindow( WId w ) { win = w; }
|
|
||||||
void setCommand( const QString &cmd ) { command = cmd; }
|
|
||||||
void setPattern( const QString ®exp ) { window = regexp; }
|
|
||||||
void setStartOnShow( bool enable ) { lazyStart = enable; isVisible = !enable; }
|
|
||||||
void setNoQuit( bool enable ) { noquit = enable; }
|
|
||||||
void setQuitOnHide( bool enable ) { quitOnHide = enable; }
|
|
||||||
void setOnTop( bool enable ) { onTop = enable; }
|
|
||||||
void setOwnIcon( bool enable ) { ownIcon = enable; }
|
|
||||||
void setDefaultTip( const QString &tip ) { tooltip = tip; }
|
|
||||||
bool hasTargetWindow() const { return (win != 0); }
|
|
||||||
bool hasRunningClient() const { return (client != 0); }
|
|
||||||
const QString &errorMsg() const { return errStr; }
|
|
||||||
|
|
||||||
bool start();
|
|
||||||
|
|
||||||
static WId findRealWindow( WId w, int depth = 0 );
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
void refresh();
|
|
||||||
|
|
||||||
void showWindow();
|
|
||||||
void hideWindow();
|
|
||||||
void toggleWindow() { if ( isVisible ) hideWindow(); else showWindow(); }
|
|
||||||
|
|
||||||
void setTargetWindow( WId w );
|
|
||||||
void execContextMenu( const QPoint &pos );
|
|
||||||
|
|
||||||
void quit();
|
|
||||||
void quitClient();
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
void clientExited();
|
|
||||||
|
|
||||||
void windowAdded(WId w);
|
|
||||||
void windowChanged(WId w);
|
|
||||||
void mousePressEvent(QSystemTrayIcon::ActivationReason reason);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool startClient();
|
|
||||||
void checkExistingWindows();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString command;
|
|
||||||
QString window;
|
|
||||||
QString tooltip;
|
|
||||||
bool isVisible;
|
|
||||||
bool lazyStart;
|
|
||||||
bool noquit;
|
|
||||||
bool quitOnHide;
|
|
||||||
bool onTop; ///< tells if window must stay on top or not
|
|
||||||
bool ownIcon; ///< tells if the ksystraycmd icon must be used in systray
|
|
||||||
bool waitingForWindow;
|
|
||||||
KMenu * menu;
|
|
||||||
|
|
||||||
WId win;
|
|
||||||
KProcess *client;
|
|
||||||
QString errStr;
|
|
||||||
|
|
||||||
/** Memorized 'top' position of the window*/
|
|
||||||
int top;
|
|
||||||
/** Memorized 'left' position of the window*/
|
|
||||||
int left;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // KSYSTRAYCMD_H
|
|
|
@ -1,137 +0,0 @@
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include <kapplication.h>
|
|
||||||
#include <kaboutdata.h>
|
|
||||||
#include <kcmdlineargs.h>
|
|
||||||
#include <kdebug.h>
|
|
||||||
#include <klocale.h>
|
|
||||||
#include <kshell.h>
|
|
||||||
|
|
||||||
#include "ksystraycmd.h"
|
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <QtGui/qx11info_x11.h>
|
|
||||||
#include <fixx11h.h>
|
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, char *argv[] )
|
|
||||||
{
|
|
||||||
KAboutData aboutData( "ksystraycmd", 0, ki18n( "KSysTrayCmd" ),
|
|
||||||
"0.1",
|
|
||||||
ki18n( "Allows any application to be kept in the system tray" ),
|
|
||||||
KAboutData::License_GPL,
|
|
||||||
ki18n("(C) 2001-2002 Richard Moore (rich@kde.org)") );
|
|
||||||
aboutData.addAuthor( ki18n("Richard Moore"), KLocalizedString(), "rich@kde.org" );
|
|
||||||
|
|
||||||
KCmdLineArgs::init( argc, argv, &aboutData );
|
|
||||||
|
|
||||||
KCmdLineOptions options;
|
|
||||||
options.add("!+command", ki18n("Command to execute"));
|
|
||||||
// "!" means: all options after command are treated as arguments to the command
|
|
||||||
options.add("window <regexp>", ki18n("A regular expression matching the window title\n"
|
|
||||||
"If you do not specify one, then the very first window\n"
|
|
||||||
"to appear will be taken - not recommended."));
|
|
||||||
options.add("wid <int>", ki18n("The window id of the target window\n"
|
|
||||||
"Specifies the id of the window to use. If the id starts with 0x\n"
|
|
||||||
"it is assumed to be in hex."));
|
|
||||||
options.add("hidden", ki18n( "Hide the window to the tray on startup" ));
|
|
||||||
options.add("startonshow", ki18n( "Wait until we are told to show the window before\n"
|
|
||||||
"executing the command" ));
|
|
||||||
options.add("tooltip <text>", ki18n( "Sets the initial tooltip for the tray icon" ));
|
|
||||||
options.add("keeprunning", ki18n( "Keep the tray icon even if the client exits. This option\n"
|
|
||||||
"has no effect unless startonshow is specified." ));
|
|
||||||
options.add("ownicon", ki18n( "Use ksystraycmd's icon instead of the window's icon in the systray\n"
|
|
||||||
"(should be used with --icon to specify ksystraycmd icon)" ));
|
|
||||||
options.add("ontop", ki18n( "Try to keep the window above other windows"));
|
|
||||||
options.add("quitonhide", ki18n( "Quit the client when we are told to hide the window.\n"
|
|
||||||
"This has no effect unless startonshow is specified and implies keeprunning." ));
|
|
||||||
/*options.add("menuitem <item>", ki18n( "Adds a custom entry to the tray icon menu\n"
|
|
||||||
"The item should have the form text:command." ));*/
|
|
||||||
KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
|
|
||||||
|
|
||||||
KApplication app;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Setup the tray icon from the arguments.
|
|
||||||
//
|
|
||||||
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
|
|
||||||
KSysTrayCmd cmd;
|
|
||||||
|
|
||||||
// Read the window id
|
|
||||||
QString wid = args->getOption( "wid" );
|
|
||||||
if ( !wid.isEmpty() ) {
|
|
||||||
int base = 10;
|
|
||||||
if ( wid.startsWith( "0x" ) ) {
|
|
||||||
base = 16;
|
|
||||||
wid = wid.right( wid.length() - 2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ok=true;
|
|
||||||
ulong w = wid.toULong( &ok, base );
|
|
||||||
if ( ok )
|
|
||||||
cmd.setTargetWindow( w );
|
|
||||||
else {
|
|
||||||
kWarning() << "KSysTrayCmd: Got bad win id" ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read window title regexp
|
|
||||||
QString title = args->getOption( "window" );
|
|
||||||
if ( !title.isEmpty() )
|
|
||||||
cmd.setPattern( title );
|
|
||||||
|
|
||||||
if ( title.isEmpty() && wid.isEmpty() && (args->count() == 0) )
|
|
||||||
KCmdLineArgs::usageError(i18n("No command or window specified"));
|
|
||||||
|
|
||||||
// Read the command
|
|
||||||
QString command;
|
|
||||||
for ( int i = 0; i < args->count(); i++ )
|
|
||||||
command += KShell::quoteArg(args->arg(i)) + ' ';
|
|
||||||
if ( !command.isEmpty() )
|
|
||||||
cmd.setCommand( command );
|
|
||||||
|
|
||||||
// Tooltip
|
|
||||||
QString tip = args->getOption( "tooltip" );
|
|
||||||
if ( !tip.isEmpty() )
|
|
||||||
cmd.setDefaultTip( tip );
|
|
||||||
|
|
||||||
// Apply icon and tooltip
|
|
||||||
cmd.refresh();
|
|
||||||
|
|
||||||
// Keep running flag
|
|
||||||
if ( args->isSet( "keeprunning" ) )
|
|
||||||
cmd.setNoQuit( true );
|
|
||||||
|
|
||||||
if ( args->isSet( "quitonhide" ) ) {
|
|
||||||
cmd.setNoQuit( true );
|
|
||||||
cmd.setQuitOnHide( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start hidden
|
|
||||||
if ( args->isSet( "hidden" ) )
|
|
||||||
cmd.hideWindow();
|
|
||||||
|
|
||||||
// On top
|
|
||||||
if ( args->isSet( "ontop" ) )
|
|
||||||
cmd.setOnTop(true);
|
|
||||||
|
|
||||||
// Use ksystraycmd icon
|
|
||||||
if ( args->isSet( "ownicon" ) )
|
|
||||||
cmd.setOwnIcon(true);
|
|
||||||
|
|
||||||
// Lazy invocation flag
|
|
||||||
if ( args->isSet( "startonshow" ) ) {
|
|
||||||
cmd.setStartOnShow( true );
|
|
||||||
cmd.show();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( !cmd.start() )
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fcntl(ConnectionNumber(QX11Info::display()), F_SETFD, 1);
|
|
||||||
args->clear();
|
|
||||||
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue