• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeui
 

tdeui

  • tdeui
  • kdetrayproxy
kdetrayproxy.cpp
1 /*
2  * Copyright (C) 2004 Lubos Lunak <l.lunak@kde.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  */
19 
20 #include "kdetrayproxy.h"
21 
22 #include <tdeapplication.h>
23 #include <kdebug.h>
24 #include <netwm.h>
25 #include <X11/Xlib.h>
26 #include <sys/select.h>
27 #include <sys/time.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30 #include <assert.h>
31 
32 KDETrayProxy::KDETrayProxy()
33  : selection( makeSelectionAtom())
34  {
35  connect( &selection, TQ_SIGNAL( newOwner( Window )), TQ_SLOT( newOwner( Window )));
36  connect( &module, TQ_SIGNAL( windowAdded( WId )), TQ_SLOT( windowAdded( WId )));
37  selection.owner();
38  for( TQValueList< WId >::ConstIterator it = module.windows().begin();
39  it != module.windows().end();
40  ++it )
41  windowAdded( *it );
42  kapp->installX11EventFilter( this ); // XSelectInput( StructureNotifyMask ) on windows is done by KWinModule
43 // kdDebug() << "Init done" << endl;
44  }
45 
46 Atom KDETrayProxy::makeSelectionAtom()
47  {
48  return XInternAtom( tqt_xdisplay(), "_NET_SYSTEM_TRAY_S" + TQCString().setNum( tqt_xscreen()), False );
49  }
50 
51 void KDETrayProxy::windowAdded( WId w )
52  {
53  NETWinInfo ni( tqt_xdisplay(), w, tqt_xrootwin(), NET::WMKDESystemTrayWinFor );
54  WId trayWinFor = ni.kdeSystemTrayWinFor();
55  if ( !trayWinFor ) // not a KDE tray window
56  return;
57 // kdDebug() << "New tray window:" << w << endl;
58  if( !tray_windows.contains( w ))
59  tray_windows.append( w );
60  withdrawWindow( w );
61  // window will be removed from pending_windows when after docked
62  if( !pending_windows.contains( w ))
63  pending_windows.append( w );
64  docked_windows.remove( w );
65  Window owner = selection.owner();
66  if( owner == None ) // no tray owner, sorry
67  {
68 // kdDebug() << "No owner, left in pending" << endl;
69  return;
70  }
71  dockWindow( w, owner );
72  }
73 
74 void KDETrayProxy::newOwner( Window owner )
75  {
76 // kdDebug() << "New owner:" << owner << endl;
77  for( TQValueList< Window >::ConstIterator it = pending_windows.begin();
78  it != pending_windows.end();
79  ++it )
80  dockWindow( *it, owner );
81  // remove from pending_windows only in windowRemoved(), after it's really docked
82  }
83 
84 bool KDETrayProxy::x11Event( XEvent* e )
85  {
86  if( tray_windows.isEmpty())
87  return false;
88  if( e->type == DestroyNotify && tray_windows.contains( e->xdestroywindow.window ))
89  {
90  tray_windows.remove( e->xdestroywindow.window );
91  pending_windows.remove( e->xdestroywindow.window );
92  docked_windows.remove( e->xdestroywindow.window );
93  }
94  if( e->type == ReparentNotify && tray_windows.contains( e->xreparent.window ))
95  {
96  if( e->xreparent.parent == tqt_xrootwin())
97  {
98  if( !docked_windows.contains( e->xreparent.window ) || e->xreparent.serial >= docked_windows[ e->xreparent.window ] )
99  {
100 // kdDebug() << "Window released:" << e->xreparent.window << endl;
101  docked_windows.remove( e->xreparent.window );
102  if( !pending_windows.contains( e->xreparent.window ))
103  pending_windows.append( e->xreparent.window );
104  }
105  }
106  else
107  {
108 // kdDebug() << "Window away:" << e->xreparent.window << ":" << e->xreparent.parent << endl;
109  pending_windows.remove( e->xreparent.window );
110  }
111  }
112  if( e->type == UnmapNotify && tray_windows.contains( e->xunmap.window ))
113  {
114  if( docked_windows.contains( e->xunmap.window ) && e->xunmap.serial >= docked_windows[ e->xunmap.window ] )
115  {
116 // kdDebug() << "Window unmapped:" << e->xunmap.window << endl;
117  XReparentWindow( tqt_xdisplay(), e->xunmap.window, tqt_xrootwin(), 0, 0 );
118  // ReparentNotify will take care of the rest
119  }
120  }
121  return false;
122  }
123 
124 void KDETrayProxy::dockWindow( Window w, Window owner )
125  {
126 // kdDebug() << "Docking " << w << " into " << owner << endl;
127  docked_windows[ w ] = XNextRequest( tqt_xdisplay());
128  static Atom prop = XInternAtom( tqt_xdisplay(), "_XEMBED_INFO", False );
129  long data[ 2 ] = { 0, 1 };
130  XChangeProperty( tqt_xdisplay(), w, prop, prop, 32, PropModeReplace, (unsigned char*)data, 2 );
131  XSizeHints hints;
132  hints.flags = PMinSize | PMaxSize;
133  hints.min_width = 24;
134  hints.max_width = 24;
135  hints.min_height = 24;
136  hints.max_height = 24;
137  XSetWMNormalHints( tqt_xdisplay(), w, &hints );
138 // kxerrorhandler ?
139  XEvent ev;
140  memset(&ev, 0, sizeof( ev ));
141  static Atom atom = XInternAtom( tqt_xdisplay(), "_NET_SYSTEM_TRAY_OPCODE", False );
142  ev.xclient.type = ClientMessage;
143  ev.xclient.window = owner;
144  ev.xclient.message_type = atom;
145  ev.xclient.format = 32;
146  ev.xclient.data.l[ 0 ] = get_tqt_x_time();
147  ev.xclient.data.l[ 1 ] = 0; // SYSTEM_TRAY_REQUEST_DOCK
148  ev.xclient.data.l[ 2 ] = w;
149  ev.xclient.data.l[ 3 ] = 0; // unused
150  ev.xclient.data.l[ 4 ] = 0; // unused
151  XSendEvent( tqt_xdisplay(), owner, False, NoEventMask, &ev );
152  }
153 
154 void KDETrayProxy::withdrawWindow( Window w )
155  {
156  XWithdrawWindow( tqt_xdisplay(), w, tqt_xscreen());
157  static Atom wm_state = XInternAtom( tqt_xdisplay(), "WM_STATE", False );
158  for(;;)
159  {
160  Atom type;
161  int format;
162  unsigned long length, after;
163  unsigned char *data;
164  int r = XGetWindowProperty( tqt_xdisplay(), w, wm_state, 0, 2,
165  False, AnyPropertyType, &type, &format,
166  &length, &after, &data );
167  bool withdrawn = true;
168  if ( r == Success && data && format == 32 )
169  {
170  withdrawn = ( *( long* )data == WithdrawnState );
171  XFree( (char *)data );
172  }
173  if( withdrawn )
174  return; // --->
175  struct timeval tm;
176  tm.tv_sec = 0;
177  tm.tv_usec = 10 * 1000; // 10ms
178  select(0, NULL, NULL, NULL, &tm);
179  }
180  }
181 
182 #include "kdetrayproxy.moc"
183 
184 #if 0
185 #include <tdecmdlineargs.h>
186 int main( int argc, char* argv[] )
187  {
188  TDECmdLineArgs::init( argc, argv, "a", "b", "c", "d" );
189  TDEApplication app( false ); // no styles
190  app.disableSessionManagement();
191  KDETrayProxy proxy;
192  return app.exec();
193  }
194 #endif
TDEApplication
TDECmdLineArgs::init
static void init(int _argc, char **_argv, const char *_appname, const char *programName, const char *_description, const char *_version, bool noKApp=false)

tdeui

Skip menu "tdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdeui

Skip menu "tdeui"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeui by doxygen 1.9.1
This website is maintained by Timothy Pearson.