~blue-shell/blue-shell/kde-workspace-systemsettings-qml-4.9

« back to all changes in this revision

Viewing changes to ksystraycmd/ksystraycmd.cpp

  • Committer: Richard J. Moore
  • Date: 2001-08-18 00:38:05 UTC
  • Revision ID: git-v1:adc23beb62af921ece4521c9623f19ec9bf4e663
Move ksystrayproxy from kdenonbeta and renamed to ksystraycmd

svn path=/trunk/kdebase/ksystraycmd/; revision=110820

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <qtooltip.h>
 
2
#include <qtextstream.h>
 
3
#include <qimage.h>
 
4
 
 
5
#include <kapp.h>
 
6
#include <kglobal.h>
 
7
#include <kiconloader.h>
 
8
#include <klocale.h>
 
9
#include <kpopupmenu.h>
 
10
#include <kprocess.h>
 
11
#include <kwinmodule.h>
 
12
 
 
13
#include <netwm.h>
 
14
 
 
15
#include <X11/Xlib.h>
 
16
#ifndef KDE_USE_FINAL
 
17
const int XFocusOut = FocusOut;
 
18
const int XFocusIn = FocusIn;
 
19
#endif
 
20
#undef FocusOut
 
21
#undef FocusIn
 
22
#undef KeyPress
 
23
#undef KeyRelease
 
24
 
 
25
extern Time qt_x_time;
 
26
 
 
27
 
 
28
#include "ksystraycmd.h"
 
29
#include "ksystraycmd.moc"
 
30
 
 
31
 
 
32
KSysTrayCmd::KSysTrayCmd()
 
33
  : QLabel( 0, "systray_cmd" ),
 
34
    isVisible(true), lazyStart( false ), noquit( false ),
 
35
    win(0), client(0), kwinmodule(0)
 
36
{
 
37
  setAlignment( AlignCenter );
 
38
  kwinmodule = new KWinModule( this );
 
39
  refresh();
 
40
}
 
41
 
 
42
KSysTrayCmd::~KSysTrayCmd()
 
43
{
 
44
  delete client;
 
45
}
 
46
 
 
47
//
 
48
// Main entry point to the class
 
49
//
 
50
 
 
51
bool KSysTrayCmd::start()
 
52
{
 
53
  if ( window )
 
54
    kwinmodule->doNotManage( window );
 
55
 
 
56
  // If we have no command we must catching an existing window
 
57
  if ( !command ) {
 
58
    checkExistingWindows();
 
59
    if ( win )
 
60
      return true;
 
61
 
 
62
    errStr = i18n( "No window matching pattern '%1' and no command specified.\n" )
 
63
      .arg( window );
 
64
    return false;
 
65
  }
 
66
 
 
67
  // Run the command and watch for its window
 
68
  if ( !startClient() ) {
 
69
    errStr = i18n( "KSysTrayCmd: KShellProcess can't find a shell." );
 
70
    clientExited();
 
71
    return false;
 
72
  }
 
73
 
 
74
  return true;
 
75
}
 
76
 
 
77
//
 
78
// Window related functions.
 
79
//
 
80
 
 
81
void KSysTrayCmd::showWindow()
 
82
{
 
83
  isVisible = true;
 
84
  if ( !win )
 
85
    return;
 
86
  XMapWindow( qt_xdisplay(), win );
 
87
  KWin::setActiveWindow( win );
 
88
}
 
89
 
 
90
void KSysTrayCmd::hideWindow()
 
91
{
 
92
  isVisible = false;
 
93
  if ( !win )
 
94
    return;
 
95
  XUnmapWindow( qt_xdisplay(), win );
 
96
}
 
97
 
 
98
void KSysTrayCmd::setTargetWindow( WId w )
 
99
{
 
100
  setTargetWindow( KWin::info( w ) );
 
101
}
 
102
 
 
103
void KSysTrayCmd::setTargetWindow( const KWin::Info &info )
 
104
{
 
105
  disconnect( kwinmodule, SIGNAL(windowAdded(WId)), this, SLOT(windowAdded(WId)) );
 
106
  connect( kwinmodule, SIGNAL(windowChanged(WId)), SLOT(windowChanged(WId)) );
 
107
  win = info.win;
 
108
  KWin::setSystemTrayWindowFor( winId(), win );
 
109
  refresh();
 
110
  show();
 
111
 
 
112
  if ( isVisible )
 
113
    KWin::setActiveWindow( win );
 
114
  else
 
115
    hideWindow();
 
116
}
 
117
 
 
118
//
 
119
// Refresh the tray icon
 
120
//
 
121
 
 
122
void KSysTrayCmd::refresh()
 
123
{
 
124
  KWin::setSystemTrayWindowFor( winId(), win ? win : winId() );
 
125
 
 
126
  if ( win ) {
 
127
    setPixmap( KWin::icon( win, 20, 20, true ) );
 
128
    QToolTip::add( this, KWin::info( win ).name );
 
129
  }
 
130
  else {
 
131
    if ( tooltip )
 
132
      QToolTip::add( this, tooltip );
 
133
    else if ( command )
 
134
      QToolTip::add( this, command );
 
135
    else
 
136
      QToolTip::add( this, window );
 
137
 
 
138
    QImage img;
 
139
    img = kapp->icon();
 
140
    img = img.smoothScale( 20, 20 );
 
141
    QPixmap pix;
 
142
    pix = img;
 
143
    setPixmap( pix );
 
144
  }
 
145
}
 
146
 
 
147
//
 
148
// Client related functions.
 
149
//
 
150
 
 
151
bool KSysTrayCmd::startClient()
 
152
{
 
153
  client = new KShellProcess();
 
154
  *client << command;
 
155
  connect( kwinmodule, SIGNAL(windowAdded(WId)), SLOT(windowAdded(WId)) );
 
156
  connect( client, SIGNAL( processExited(KProcess *) ),
 
157
           this, SLOT( clientExited() ) );
 
158
 
 
159
  return client->start();
 
160
}
 
161
 
 
162
void KSysTrayCmd::clientExited()
 
163
{
 
164
  delete client;
 
165
  client = 0;
 
166
  win = 0;
 
167
 
 
168
  if ( lazyStart && noquit )
 
169
    refresh();
 
170
  else
 
171
    qApp->quit();
 
172
}
 
173
 
 
174
void KSysTrayCmd::quit()
 
175
{
 
176
  if ( win ) {
 
177
    NETRootInfo ri( qt_xdisplay(), NET::CloseWindow );
 
178
    ri.closeWindowRequest( win );
 
179
    noquit = false;
 
180
  }
 
181
  else {
 
182
    qApp->quit();
 
183
  }
 
184
}
 
185
 
 
186
void KSysTrayCmd::execContextMenu( const QPoint &pos )
 
187
{
 
188
    KPopupMenu *menu = new KPopupMenu();
 
189
    menu->insertTitle( *pixmap(), i18n( "KSysTrayCmd" ) );
 
190
    int hideShowId = menu->insertItem( isVisible ? i18n( "&Hide" ) : i18n( "&Restore" ) );
 
191
    int quitId = menu->insertItem( SmallIcon("exit"), i18n( "&Quit" ) );
 
192
 
 
193
    int cmd = menu->exec( pos );
 
194
 
 
195
    if ( cmd == quitId )
 
196
      quit();
 
197
    else if ( cmd == hideShowId )
 
198
      toggleWindow();
 
199
 
 
200
    delete menu;
 
201
}
 
202
 
 
203
void KSysTrayCmd::checkExistingWindows()
 
204
{
 
205
  QValueList<WId>::ConstIterator it;
 
206
  for ( it = kwinmodule->windows().begin(); it != kwinmodule->windows().end(); ++it ) {
 
207
    windowAdded( *it );
 
208
    if ( win )
 
209
      break;
 
210
  }
 
211
}
 
212
 
 
213
void KSysTrayCmd::windowAdded(WId w)
 
214
{
 
215
  if ( window && ( QRegExp( window ).match( KWin::info(w).name ) == -1 ) )
 
216
    return; // no match
 
217
  setTargetWindow( w );
 
218
}
 
219
 
 
220
void KSysTrayCmd::windowChanged( WId w )
 
221
{
 
222
  if ( w != win )
 
223
    return;
 
224
  refresh();
 
225
}
 
226
 
 
227
//
 
228
// Tray icon event handlers
 
229
//
 
230
 
 
231
void KSysTrayCmd::mousePressEvent( QMouseEvent *e )
 
232
{
 
233
  if ( e->button() == RightButton )
 
234
    execContextMenu( e->globalPos() );
 
235
  else if ( lazyStart && ( !hasRunningClient() ) )
 
236
    start();
 
237
  else
 
238
    toggleWindow();
 
239
}
 
240
 
 
241
void KSysTrayCmd::enterEvent( QEvent * )
 
242
{
 
243
  // Fake a focus event when the mouse points at our tray icon. This is
 
244
  // needed for our tooltips to work.
 
245
  if ( !qApp->focusWidget() ) {
 
246
    XEvent ev;
 
247
    memset(&ev, 0, sizeof(ev));
 
248
    ev.xfocus.display = qt_xdisplay();
 
249
    ev.xfocus.type = XFocusIn;
 
250
    ev.xfocus.window = winId();
 
251
    ev.xfocus.mode = NotifyNormal;
 
252
    ev.xfocus.detail = NotifyAncestor;
 
253
    Time time = qt_x_time;
 
254
    qt_x_time = 1;
 
255
    qApp->x11ProcessEvent( &ev );
 
256
        qt_x_time = time;
 
257
  }
 
258
}
 
259
 
 
260