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 , unredirect( false )
00047 , unredirectSuspend( false )
00048 {
00049 }
00050
00051 Toplevel::~Toplevel()
00052 {
00053 #ifdef HAVE_XDAMAGE
00054 assert( damage_handle == None );
00055 #endif
00056 discardWindowPixmap();
00057 delete info;
00058 }
00059
00060 kdbgstream& operator<<( kdbgstream& stream, const Toplevel* cl )
00061 {
00062 if( cl == NULL )
00063 return stream << "\'NULL\'";
00064 cl->debug( stream );
00065 return stream;
00066 }
00067
00068 kdbgstream& operator<<( kdbgstream& stream, const ToplevelList& list )
00069 {
00070 stream << "LIST:(";
00071 bool first = true;
00072 for( ToplevelList::ConstIterator it = list.begin();
00073 it != list.end();
00074 ++it )
00075 {
00076 if( !first )
00077 stream << ":";
00078 first = false;
00079 stream << *it;
00080 }
00081 stream << ")";
00082 return stream;
00083 }
00084
00085 kdbgstream& operator<<( kdbgstream& stream, const ConstToplevelList& list )
00086 {
00087 stream << "LIST:(";
00088 bool first = true;
00089 for( ConstToplevelList::ConstIterator it = list.begin();
00090 it != list.end();
00091 ++it )
00092 {
00093 if( !first )
00094 stream << ":";
00095 first = false;
00096 stream << *it;
00097 }
00098 stream << ")";
00099 return stream;
00100 }
00101
00102 void Toplevel::detectShape( Window id )
00103 {
00104 is_shape = Extensions::hasShape( id );
00105 }
00106
00107
00108 void Toplevel::copyToDeleted( Toplevel* c )
00109 {
00110 geom = c->geom;
00111 vis = c->vis;
00112 bit_depth = c->bit_depth;
00113 info = c->info;
00114 client = c->client;
00115 frame = c->frame;
00116 wspace = c->wspace;
00117 window_pix = c->window_pix;
00118 ready_for_painting = c->ready_for_painting;
00119 #ifdef HAVE_XDAMAGE
00120 damage_handle = None;
00121 #endif
00122 damage_region = c->damage_region;
00123 repaints_region = c->repaints_region;
00124 is_shape = c->is_shape;
00125 effect_window = c->effect_window;
00126 if( effect_window != NULL )
00127 effect_window->setWindow( this );
00128 resource_name = c->resourceName();
00129 resource_class = c->resourceClass();
00130 client_machine = c->wmClientMachine( false );
00131 wmClientLeaderWin = c->wmClientLeader();
00132 window_role = c->windowRole();
00133
00134
00135 c->window_pix = None;
00136 }
00137
00138
00139
00140 void Toplevel::disownDataPassedToDeleted()
00141 {
00142 info = NULL;
00143 }
00144
00145 NET::WindowType Toplevel::windowType( bool direct, int supported_types ) const
00146 {
00147 if( supported_types == 0 )
00148 supported_types = dynamic_cast< const Client* >( this ) != NULL
00149 ? SUPPORTED_MANAGED_WINDOW_TYPES_MASK : SUPPORTED_UNMANAGED_WINDOW_TYPES_MASK;
00150 NET::WindowType wt = info->windowType( supported_types );
00151 if( direct )
00152 return wt;
00153 const Client* cl = dynamic_cast< const Client* >( this );
00154 #ifdef __GNUC__
00155 #warning TODO
00156 #endif
00157
00158 NET::WindowType wt2 = wt;
00159 if( wt != wt2 )
00160 {
00161 wt = wt2;
00162 info->setWindowType( wt );
00163 }
00164
00165 if( wt == NET::Menu && cl != NULL )
00166 {
00167
00168
00169
00170 if( x() == 0 && y() < 0 && y() > -10 && height() < 100
00171 && abs( width() - workspace()->clientArea( FullArea, cl ).width()) < 10 )
00172 wt = NET::TopMenu;
00173 }
00174
00175 const char* const oo_prefix = "openoffice.org";
00176
00177 if( qstrncmp( resourceClass(), oo_prefix, strlen( oo_prefix )) == 0 && wt == NET::Dialog )
00178 wt = NET::Normal;
00179 if( wt == NET::Unknown && cl != NULL )
00180 wt = cl->isTransient() ? NET::Dialog : NET::Normal;
00181 return wt;
00182 }
00183
00184 void Toplevel::getWindowRole()
00185 {
00186 window_role = getStringProperty( window(), atoms->wm_window_role).toLower();
00187 }
00188
00192 QByteArray Toplevel::staticSessionId(WId w)
00193 {
00194 return getStringProperty(w, atoms->sm_client_id);
00195 }
00196
00200 QByteArray Toplevel::staticWmCommand(WId w)
00201 {
00202 return getStringProperty(w, XA_WM_COMMAND, ' ');
00203 }
00204
00208 Window Toplevel::staticWmClientLeader(WId w)
00209 {
00210 Atom type;
00211 int format, status;
00212 unsigned long nitems = 0;
00213 unsigned long extra = 0;
00214 unsigned char *data = 0;
00215 Window result = w;
00216 KXErrorHandler err;
00217 status = XGetWindowProperty( display(), w, atoms->wm_client_leader, 0, 10000,
00218 false, XA_WINDOW, &type, &format,
00219 &nitems, &extra, &data );
00220 if (status == Success && !err.error( false ))
00221 {
00222 if (data && nitems > 0)
00223 result = *((Window*) data);
00224 XFree(data);
00225 }
00226 return result;
00227 }
00228
00229
00230 void Toplevel::getWmClientLeader()
00231 {
00232 wmClientLeaderWin = staticWmClientLeader(window());
00233 }
00234
00239 QByteArray Toplevel::sessionId()
00240 {
00241 QByteArray result = staticSessionId(window());
00242 if (result.isEmpty() && wmClientLeaderWin && wmClientLeaderWin!=window())
00243 result = staticSessionId(wmClientLeaderWin);
00244 return result;
00245 }
00246
00251 QByteArray Toplevel::wmCommand()
00252 {
00253 QByteArray result = staticWmCommand(window());
00254 if (result.isEmpty() && wmClientLeaderWin && wmClientLeaderWin!=window())
00255 result = staticWmCommand(wmClientLeaderWin);
00256 return result;
00257 }
00258
00259 void Toplevel::getWmClientMachine()
00260 {
00261 client_machine = getStringProperty(window(), XA_WM_CLIENT_MACHINE);
00262 if( client_machine.isEmpty() && wmClientLeaderWin && wmClientLeaderWin!=window())
00263 client_machine = getStringProperty(wmClientLeaderWin, XA_WM_CLIENT_MACHINE);
00264 if( client_machine.isEmpty())
00265 client_machine = "localhost";
00266 }
00267
00272 QByteArray Toplevel::wmClientMachine( bool use_localhost ) const
00273 {
00274 QByteArray result = client_machine;
00275 if( use_localhost )
00276 {
00277 if( result != "localhost" && isLocalMachine( result ))
00278 result = "localhost";
00279 }
00280 return result;
00281 }
00282
00287 Window Toplevel::wmClientLeader() const
00288 {
00289 if (wmClientLeaderWin)
00290 return wmClientLeaderWin;
00291 return window();
00292 }
00293
00294 void Toplevel::getResourceClass()
00295 {
00296 XClassHint classHint;
00297 if( XGetClassHint( display(), window(), &classHint ) )
00298 {
00299
00300
00301 resource_name = QByteArray( classHint.res_name ).toLower();
00302 resource_class = QByteArray( classHint.res_class ).toLower();
00303 XFree( classHint.res_name );
00304 XFree( classHint.res_class );
00305 }
00306 else
00307 {
00308 resource_name = resource_class = QByteArray();
00309 }
00310 }
00311
00312 double Toplevel::opacity() const
00313 {
00314 if( info->opacity() == 0xffffffff )
00315 return 1.0;
00316 return info->opacity() * 1.0 / 0xffffffff;
00317 }
00318
00319 void Toplevel::setOpacity( double new_opacity )
00320 {
00321 double old_opacity = opacity();
00322 new_opacity = qBound( 0.0, new_opacity, 1.0 );
00323 if( old_opacity == new_opacity )
00324 return;
00325 info->setOpacity( static_cast< unsigned long >( new_opacity * 0xffffffff ));
00326 if( compositing())
00327 {
00328 addRepaintFull();
00329 scene->windowOpacityChanged( this );
00330 if( effects )
00331 static_cast<EffectsHandlerImpl*>(effects)->windowOpacityChanged( effectWindow(), old_opacity );
00332 }
00333 }
00334
00335 void Toplevel::deleteEffectWindow()
00336 {
00337 delete effect_window;
00338 effect_window = NULL;
00339 }
00340
00341 int Toplevel::screen() const
00342 {
00343 if( !options->xineramaEnabled )
00344 return 0;
00345 int s = workspace()->screenNumber( geometry().center());
00346 if( s < 0 )
00347 {
00348 kDebug(1212) << "Invalid screen: Center" << geometry().center() << ", screen" << s;
00349 return 0;
00350 }
00351 return s;
00352 }
00353
00354 bool Toplevel::isOnScreen( int screen ) const
00355 {
00356 if( !options->xineramaEnabled )
00357 return screen == 0;
00358 return workspace()->screenGeometry( screen ).intersects( geometry());
00359 }
00360
00361
00362 }
00363
00364 #include "toplevel.moc"