• Skip to content
  • Skip to link menu
KDE 4.1 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     {
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 // used only by Deleted::copy()
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     // this needs to be done already here, otherwise 'c' could very likely
00132     // call discardWindowPixmap() in something called during cleanup
00133     c->window_pix = None;
00134     }
00135 
00136 // before being deleted, remove references to everything that's now
00137 // owner by Deleted
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 //    NET::WindowType wt2 = rules()->checkType( wt );
00154     NET::WindowType wt2 = wt;
00155     if( wt != wt2 )
00156         {
00157         wt = wt2;
00158         info->setWindowType( wt ); // force hint change
00159         }
00160     // hacks here
00161     if( wt == NET::Menu && cl != NULL )
00162         {
00163         // ugly hack to support the times when NET::Menu meant NET::TopMenu
00164         // if it's as wide as the screen, not very high and has its upper-left
00165         // corner a bit above the screen's upper-left cornet, it's a topmenu
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     // TODO change this to rule
00171     const char* const oo_prefix = "openoffice.org"; // QByteArray has no startsWith()
00172     // oo_prefix is lowercase, because resourceClass() is forced to be lowercase
00173     if( qstrncmp( resourceClass(), oo_prefix, strlen( oo_prefix )) == 0 && wt == NET::Dialog )
00174         wt = NET::Normal; // see bug #66065
00175     if( wt == NET::Unknown && cl != NULL ) // this is more or less suggested in NETWM spec
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         { // special name for the local machine (localhost)
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         // Qt3.2 and older had this all lowercase, Qt3.3 capitalized resource class.
00296         // Force lowercase, so that workarounds listing resource classes still work.
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 } // namespace
00353 
00354 #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
  •   libplasma
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.4
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