• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KWin

toplevel.cpp

Go to the documentation of this file.
00001 /********************************************************************
00002  KWin - the KDE window manager
00003  This file is part of the KDE project.
00004 
00005 Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
00006 
00007 This program is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 This program is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with this program.  If not, see <http://www.gnu.org/licenses/>.
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 // used only by Deleted::copy()
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     // this needs to be done already here, otherwise 'c' could very likely
00134     // call discardWindowPixmap() in something called during cleanup
00135     c->window_pix = None;
00136     }
00137 
00138 // before being deleted, remove references to everything that's now
00139 // owner by Deleted
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 //    NET::WindowType wt2 = rules()->checkType( wt );
00158     NET::WindowType wt2 = wt;
00159     if( wt != wt2 )
00160         {
00161         wt = wt2;
00162         info->setWindowType( wt ); // force hint change
00163         }
00164     // hacks here
00165     if( wt == NET::Menu && cl != NULL )
00166         {
00167         // ugly hack to support the times when NET::Menu meant NET::TopMenu
00168         // if it's as wide as the screen, not very high and has its upper-left
00169         // corner a bit above the screen's upper-left cornet, it's a topmenu
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     // TODO change this to rule
00175     const char* const oo_prefix = "openoffice.org"; // QByteArray has no startsWith()
00176     // oo_prefix is lowercase, because resourceClass() is forced to be lowercase
00177     if( qstrncmp( resourceClass(), oo_prefix, strlen( oo_prefix )) == 0 && wt == NET::Dialog )
00178         wt = NET::Normal; // see bug #66065
00179     if( wt == NET::Unknown && cl != NULL ) // this is more or less suggested in NETWM spec
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         { // special name for the local machine (localhost)
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         // Qt3.2 and older had this all lowercase, Qt3.3 capitalized resource class.
00300         // Force lowercase, so that workarounds listing resource classes still work.
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 } // namespace
00363 
00364 #include "toplevel.moc"

KWin

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

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal