KWin
toplevel.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "toplevel.h"
00022
00023 #include <kxerrorhandler.h>
00024
00025 #include "atoms.h"
00026 #include "client.h"
00027 #include "effects.h"
00028
00029 namespace KWin
00030 {
00031
00032 Toplevel::Toplevel( Workspace* ws )
00033 : vis( NULL )
00034 , info( NULL )
00035 , ready_for_painting( true )
00036 , client( None )
00037 , frame( None )
00038 , wspace( ws )
00039 , window_pix( None )
00040 #ifdef HAVE_XDAMAGE
00041 , damage_handle( None )
00042 #endif
00043 , is_shape( false )
00044 , effect_window( NULL )
00045 , wmClientLeaderWin( 0 )
00046 {
00047 }
00048
00049 Toplevel::~Toplevel()
00050 {
00051 #ifdef HAVE_XDAMAGE
00052 assert( damage_handle == None );
00053 #endif
00054 discardWindowPixmap();
00055 delete info;
00056 }
00057
00058 kdbgstream& operator<<( kdbgstream& stream, const Toplevel* cl )
00059 {
00060 if( cl == NULL )
00061 return stream << "\'NULL\'";
00062 cl->debug( stream );
00063 return stream;
00064 }
00065
00066 kdbgstream& operator<<( kdbgstream& stream, const ToplevelList& list )
00067 {
00068 stream << "LIST:(";
00069 bool first = true;
00070 for( ToplevelList::ConstIterator it = list.begin();
00071 it != list.end();
00072 ++it )
00073 {
00074 if( !first )
00075 stream << ":";
00076 first = false;
00077 stream << *it;
00078 }
00079 stream << ")";
00080 return stream;
00081 }
00082
00083 kdbgstream& operator<<( kdbgstream& stream, const ConstToplevelList& list )
00084 {
00085 stream << "LIST:(";
00086 bool first = true;
00087 for( ConstToplevelList::ConstIterator it = list.begin();
00088 it != list.end();
00089 ++it )
00090 {
00091 if( !first )
00092 stream << ":";
00093 first = false;
00094 stream << *it;
00095 }
00096 stream << ")";
00097 return stream;
00098 }
00099
00100 void Toplevel::detectShape( Window id )
00101 {
00102 is_shape = Extensions::hasShape( id );
00103 }
00104
00105
00106 void Toplevel::copyToDeleted( Toplevel* c )
00107 {
00108 geom = c->geom;
00109 vis = c->vis;
00110 bit_depth = c->bit_depth;
00111 info = c->info;
00112 client = c->client;
00113 frame = c->frame;
00114 wspace = c->wspace;
00115 window_pix = c->window_pix;
00116 ready_for_painting = c->ready_for_painting;
00117 #ifdef HAVE_XDAMAGE
00118 damage_handle = None;
00119 #endif
00120 damage_region = c->damage_region;
00121 repaints_region = c->repaints_region;
00122 is_shape = c->is_shape;
00123 effect_window = c->effect_window;
00124 if( effect_window != NULL )
00125 effect_window->setWindow( this );
00126 resource_name = c->resourceName();
00127 resource_class = c->resourceClass();
00128 client_machine = c->wmClientMachine( false );
00129 wmClientLeaderWin = c->wmClientLeader();
00130 window_role = c->windowRole();
00131
00132
00133 c->window_pix = None;
00134 }
00135
00136
00137
00138 void Toplevel::disownDataPassedToDeleted()
00139 {
00140 info = NULL;
00141 }
00142
00143 NET::WindowType Toplevel::windowType( bool direct, int supported_types ) const
00144 {
00145 if( supported_types == 0 )
00146 supported_types = dynamic_cast< const Client* >( this ) != NULL
00147 ? SUPPORTED_MANAGED_WINDOW_TYPES_MASK : SUPPORTED_UNMANAGED_WINDOW_TYPES_MASK;
00148 NET::WindowType wt = info->windowType( supported_types );
00149 if( direct )
00150 return wt;
00151 const Client* cl = dynamic_cast< const Client* >( this );
00152 #warning TODO
00153
00154 NET::WindowType wt2 = wt;
00155 if( wt != wt2 )
00156 {
00157 wt = wt2;
00158 info->setWindowType( wt );
00159 }
00160
00161 if( wt == NET::Menu && cl != NULL )
00162 {
00163
00164
00165
00166 if( x() == 0 && y() < 0 && y() > -10 && height() < 100
00167 && abs( width() - workspace()->clientArea( FullArea, cl ).width()) < 10 )
00168 wt = NET::TopMenu;
00169 }
00170
00171 const char* const oo_prefix = "openoffice.org";
00172
00173 if( qstrncmp( resourceClass(), oo_prefix, strlen( oo_prefix )) == 0 && wt == NET::Dialog )
00174 wt = NET::Normal;
00175 if( wt == NET::Unknown && cl != NULL )
00176 wt = cl->isTransient() ? NET::Dialog : NET::Normal;
00177 return wt;
00178 }
00179
00180 void Toplevel::getWindowRole()
00181 {
00182 window_role = getStringProperty( window(), atoms->wm_window_role).toLower();
00183 }
00184
00188 QByteArray Toplevel::staticSessionId(WId w)
00189 {
00190 return getStringProperty(w, atoms->sm_client_id);
00191 }
00192
00196 QByteArray Toplevel::staticWmCommand(WId w)
00197 {
00198 return getStringProperty(w, XA_WM_COMMAND, ' ');
00199 }
00200
00204 Window Toplevel::staticWmClientLeader(WId w)
00205 {
00206 Atom type;
00207 int format, status;
00208 unsigned long nitems = 0;
00209 unsigned long extra = 0;
00210 unsigned char *data = 0;
00211 Window result = w;
00212 KXErrorHandler err;
00213 status = XGetWindowProperty( display(), w, atoms->wm_client_leader, 0, 10000,
00214 false, XA_WINDOW, &type, &format,
00215 &nitems, &extra, &data );
00216 if (status == Success && !err.error( false ))
00217 {
00218 if (data && nitems > 0)
00219 result = *((Window*) data);
00220 XFree(data);
00221 }
00222 return result;
00223 }
00224
00225
00226 void Toplevel::getWmClientLeader()
00227 {
00228 wmClientLeaderWin = staticWmClientLeader(window());
00229 }
00230
00235 QByteArray Toplevel::sessionId()
00236 {
00237 QByteArray result = staticSessionId(window());
00238 if (result.isEmpty() && wmClientLeaderWin && wmClientLeaderWin!=window())
00239 result = staticSessionId(wmClientLeaderWin);
00240 return result;
00241 }
00242
00247 QByteArray Toplevel::wmCommand()
00248 {
00249 QByteArray result = staticWmCommand(window());
00250 if (result.isEmpty() && wmClientLeaderWin && wmClientLeaderWin!=window())
00251 result = staticWmCommand(wmClientLeaderWin);
00252 return result;
00253 }
00254
00255 void Toplevel::getWmClientMachine()
00256 {
00257 client_machine = getStringProperty(window(), XA_WM_CLIENT_MACHINE);
00258 if( client_machine.isEmpty() && wmClientLeaderWin && wmClientLeaderWin!=window())
00259 client_machine = getStringProperty(wmClientLeaderWin, XA_WM_CLIENT_MACHINE);
00260 if( client_machine.isEmpty())
00261 client_machine = "localhost";
00262 }
00263
00268 QByteArray Toplevel::wmClientMachine( bool use_localhost ) const
00269 {
00270 QByteArray result = client_machine;
00271 if( use_localhost )
00272 {
00273 if( result != "localhost" && isLocalMachine( result ))
00274 result = "localhost";
00275 }
00276 return result;
00277 }
00278
00283 Window Toplevel::wmClientLeader() const
00284 {
00285 if (wmClientLeaderWin)
00286 return wmClientLeaderWin;
00287 return window();
00288 }
00289
00290 void Toplevel::getResourceClass()
00291 {
00292 XClassHint classHint;
00293 if( XGetClassHint( display(), window(), &classHint ) )
00294 {
00295
00296
00297 resource_name = QByteArray( classHint.res_name ).toLower();
00298 resource_class = QByteArray( classHint.res_class ).toLower();
00299 XFree( classHint.res_name );
00300 XFree( classHint.res_class );
00301 }
00302 else
00303 {
00304 resource_name = resource_class = QByteArray();
00305 }
00306 }
00307
00308 double Toplevel::opacity() const
00309 {
00310 if( info->opacity() == 0xffffffff )
00311 return 1.0;
00312 return info->opacity() * 1.0 / 0xffffffff;
00313 }
00314
00315 void Toplevel::setOpacity( double new_opacity )
00316 {
00317 double old_opacity = opacity();
00318 new_opacity = qBound( 0.0, new_opacity, 1.0 );
00319 if( old_opacity == new_opacity )
00320 return;
00321 info->setOpacity( static_cast< unsigned long >( new_opacity * 0xffffffff ));
00322 if( compositing())
00323 {
00324 addRepaintFull();
00325 scene->windowOpacityChanged( this );
00326 if( effects )
00327 static_cast<EffectsHandlerImpl*>(effects)->windowOpacityChanged( effectWindow(), old_opacity );
00328 }
00329 }
00330
00331 void Toplevel::deleteEffectWindow()
00332 {
00333 delete effect_window;
00334 effect_window = NULL;
00335 }
00336
00337 int Toplevel::screen() const
00338 {
00339 if( !options->xineramaEnabled )
00340 return 0;
00341 return workspace()->screenNumber( geometry().center());
00342 }
00343
00344 bool Toplevel::isOnScreen( int screen ) const
00345 {
00346 if( !options->xineramaEnabled )
00347 return screen == 0;
00348 return workspace()->screenGeometry( screen ).intersects( geometry());
00349 }
00350
00351
00352 }
00353
00354 #include "toplevel.moc"